update vendor
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
19a32db84d
commit
94d1cfbfbf
10501 changed files with 2307943 additions and 29279 deletions
23
vendor/github.com/genuinetools/reg/testutils/configs/basicauth.yml
generated
vendored
Normal file
23
vendor/github.com/genuinetools/reg/testutils/configs/basicauth.yml
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
version: 0.1
|
||||
log:
|
||||
level: debug
|
||||
formatter: text
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
delete:
|
||||
enabled: true
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
host: https://localhost:5000
|
||||
tls:
|
||||
certificate: /etc/docker/registry/ssl/cert.pem
|
||||
key: /etc/docker/registry/ssl/key.pem
|
||||
auth:
|
||||
htpasswd:
|
||||
realm: basic-realm
|
||||
path: /etc/docker/registry/htpasswd
|
75
vendor/github.com/genuinetools/reg/testutils/configs/clair.yml
generated
vendored
Normal file
75
vendor/github.com/genuinetools/reg/testutils/configs/clair.yml
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Copyright 2015 clair authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The values specified here are the default values that Clair uses if no configuration file is specified or if the keys are not defined.
|
||||
clair:
|
||||
database:
|
||||
# Database driver
|
||||
type: pgsql
|
||||
options:
|
||||
# PostgreSQL Connection string
|
||||
# https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
source: postgresql://hacker:password@127.0.0.1:5432/clair?sslmode=disable&statement_timeout=60000
|
||||
|
||||
# Number of elements kept in the cache
|
||||
# Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
|
||||
cachesize: 16384
|
||||
|
||||
api:
|
||||
# API server port
|
||||
addr: "0.0.0.0:6060"
|
||||
|
||||
# Health server port
|
||||
# This is an unencrypted endpoint useful for load balancers to check to healthiness of the clair server.
|
||||
healthaddr: "0.0.0.0:6061"
|
||||
|
||||
# Deadline before an API request will respond with a 503
|
||||
timeout: 900s
|
||||
|
||||
# Optional PKI configuration
|
||||
# If you want to easily generate client certificates and CAs, try the following projects:
|
||||
# https://github.com/coreos/etcd-ca
|
||||
# https://github.com/cloudflare/cfssl
|
||||
servername:
|
||||
cafile:
|
||||
keyfile:
|
||||
certfile:
|
||||
|
||||
updater:
|
||||
# Frequency the database will be updated with vulnerabilities from the default data sources
|
||||
# The value 0 disables the updater entirely.
|
||||
interval: 2h
|
||||
|
||||
notifier:
|
||||
# Number of attempts before the notification is marked as failed to be sent
|
||||
attempts: 3
|
||||
|
||||
# Duration before a failed notification is retried
|
||||
renotifyinterval: 2h
|
||||
|
||||
http:
|
||||
# Optional endpoint that will receive notifications via POST requests
|
||||
endpoint:
|
||||
|
||||
# Optional PKI configuration
|
||||
# If you want to easily generate client certificates and CAs, try the following projects:
|
||||
# https://github.com/cloudflare/cfssl
|
||||
# https://github.com/coreos/etcd-ca
|
||||
servername:
|
||||
cafile:
|
||||
keyfile:
|
||||
certfile:
|
||||
|
||||
# Optional HTTP Proxy: must be a valid URL (including the scheme).
|
||||
proxy:
|
1
vendor/github.com/genuinetools/reg/testutils/configs/htpasswd
generated
vendored
Normal file
1
vendor/github.com/genuinetools/reg/testutils/configs/htpasswd
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
admin:$2y$05$TpcLzA8b5hMLptNGRIRWXuOI7KmAOqIuRhHAv15qHNrJaxuyIhCg6
|
19
vendor/github.com/genuinetools/reg/testutils/configs/noauth.yml
generated
vendored
Normal file
19
vendor/github.com/genuinetools/reg/testutils/configs/noauth.yml
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
version: 0.1
|
||||
log:
|
||||
level: debug
|
||||
formatter: text
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
delete:
|
||||
enabled: true
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
host: https://localhost:5000
|
||||
tls:
|
||||
certificate: /etc/docker/registry/ssl/cert.pem
|
||||
key: /etc/docker/registry/ssl/key.pem
|
50
vendor/github.com/genuinetools/reg/testutils/registry.go
generated
vendored
Normal file
50
vendor/github.com/genuinetools/reg/testutils/registry.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
package testutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
)
|
||||
|
||||
// RegistryHelper implements methods to manipulate docker registry from test cases
|
||||
type RegistryHelper struct {
|
||||
dcli *client.Client
|
||||
auth string
|
||||
addr string
|
||||
}
|
||||
|
||||
// NewRegistryHelper returns RegistryHelper
|
||||
func NewRegistryHelper(dcli *client.Client, username, password, addr string) (*RegistryHelper, error) {
|
||||
auth, err := constructRegistryAuth(username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RegistryHelper{dcli: dcli, auth: auth, addr: addr}, nil
|
||||
}
|
||||
|
||||
// RefillRegistry adds images to a registry.
|
||||
func (r *RegistryHelper) RefillRegistry(image string) error {
|
||||
if err := pullDockerImage(r.dcli, image); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := r.dcli.ImageTag(context.Background(), image, r.addr+"/"+image); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := r.dcli.ImagePush(context.Background(), r.addr+"/"+image, types.ImagePushOptions{
|
||||
RegistryAuth: r.auth,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Close()
|
||||
|
||||
fd, isTerm := term.GetFdInfo(os.Stdout)
|
||||
|
||||
return jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerm, nil)
|
||||
}
|
19
vendor/github.com/genuinetools/reg/testutils/snakeoil/cert.pem
generated
vendored
Normal file
19
vendor/github.com/genuinetools/reg/testutils/snakeoil/cert.pem
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDAzCCAeugAwIBAgIRAKiO1JljWQroJypQxJGTyQYwDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODA2MDYxNjE4MzFaFw0xOTA2MDYxNjE4
|
||||
MzFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQDIjs9fg/lVbozhiYuu7kswhXGTdLlbvRTpfCX/wNpeVi8AIWRLetsO
|
||||
Q/L/Os3rz+3ejozFREZViqJ5hDODgzMCP93M7lAZhzhrgxwe8+ZYPhj3WHqAc+TK
|
||||
fnW0SNa+gOYPDo98xx1eWQKSLZ8Qj+NjkbBnUu92/zkSKFIvR6RFZwRxrItGZ003
|
||||
OtsSwDn5yVGfcbtJyXMrR1669LvInIRlz9ekumG7cGi8odSKl3xErmGTZYEzozeP
|
||||
MuJLDVM0fh5oOOucsn1sJJXqTNzFXQqvmnXJp62jop9tJcioeyDJvqwWjyVQpwIN
|
||||
ZiqGFFu8LDvba4t+PVwsqrMoUCWEq1yjAgMBAAGjVDBSMA4GA1UdDwEB/wQEAwIC
|
||||
pDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQT
|
||||
MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAbwh3lknBACmn
|
||||
lAm5e/OUpFiGEwV3otRR7tLiQFFPGtQ3hI8kHCjWplDyA9dCiPrH3z84cV/fH5sK
|
||||
4SfG40ucO4r9BVof7dnahl4dejafymxlicD87zUsWRJFIgAlJlpVBkjv9Xd2Fupr
|
||||
PWpbT8fHxeaZ5+Q5vvF7j2qCv+8i3GNgVVFC86HFc0DHRT78a2EW9YkWKdkFUh1W
|
||||
zvuBDwoYv4rVKlhyhrPHMIHGBwdb0meRghqRilSR0qOnLy3fyrKQYpB4WAsBRl+/
|
||||
dFYS9krqSOeqhIZTYkQzI6wlxexZ6vcb7NRhxX33BaFQNmsJnW9oZ2sHkpJ/Ceoe
|
||||
7QaSRcCbtQ==
|
||||
-----END CERTIFICATE-----
|
27
vendor/github.com/genuinetools/reg/testutils/snakeoil/key.pem
generated
vendored
Normal file
27
vendor/github.com/genuinetools/reg/testutils/snakeoil/key.pem
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAyI7PX4P5VW6M4YmLru5LMIVxk3S5W70U6Xwl/8DaXlYvACFk
|
||||
S3rbDkPy/zrN68/t3o6MxURGVYqieYQzg4MzAj/dzO5QGYc4a4McHvPmWD4Y91h6
|
||||
gHPkyn51tEjWvoDmDw6PfMcdXlkCki2fEI/jY5GwZ1Lvdv85EihSL0ekRWcEcayL
|
||||
RmdNNzrbEsA5+clRn3G7SclzK0deuvS7yJyEZc/XpLphu3BovKHUipd8RK5hk2WB
|
||||
M6M3jzLiSw1TNH4eaDjrnLJ9bCSV6kzcxV0Kr5p1yaeto6KfbSXIqHsgyb6sFo8l
|
||||
UKcCDWYqhhRbvCw722uLfj1cLKqzKFAlhKtcowIDAQABAoIBABrnzboqolBrvEql
|
||||
gS++mCeyP0Jg7lz4SM3p8c8VuDXfqf6CfEoD+U84nmjPIsD37BlnVktAlY70Qke7
|
||||
DI4gE7/Bgaf0cJp8IX2K4ULlxYkhC4hjPkvtQExKGtBM1UJJWJO8iFNdAvudRVMG
|
||||
+8flBcRdzySNY8K7CpT9A8mD+u20X1n5yQt4wiBlda2IqEgDmTOJ1pxq99bR+nVu
|
||||
Z1jglgKvVgSuL0JFR3flT2zcRZlRiF3LESfuTy46VXdRGm5wX8rlQaxntsq3BCIs
|
||||
d5+Sy0ajnESZlr4FlHN4h0aNpchntLGKtU5lmyraomRHiD2pxJ3ZM+A5veDVGx9J
|
||||
Y+hJ+gECgYEA0zhPogEmIYVNl1l9LA2Hz2GXvS2hNCswLL/lxUXSrFrbdpl0lXGE
|
||||
d2hgnIFA8CjdMj3P/3VTY71SiDYROEuGbOB87CRpDGdmkpFueIrxbgW92divamVj
|
||||
7gIV9Jdm4hKKALANPDF3JeF7j4M1nNDnRJPQl8KR2x7c7LniVvJ3fAMCgYEA8xPT
|
||||
n0aZhkZSLueqT1v0IzpE2Vs82o0y4LPBBaxA6Hx5IkQ4Z+D3ifyH0baJfUVOOV7N
|
||||
NbfOGzMzZ0+6IelaC5UZCl6fiSxn2/IgByr52tEHJv/wthfqw1Lskxp8ebS3bszI
|
||||
/ZaZkZ4e3TKRC6M7lP2YG0qH626emzWxf8nvyuECgYATLfbVMCOFQbSE/MRH/saJ
|
||||
R0RfEkikExPhzF8R5cA2lF1/THnwpAkySpETRQ1fgWZsjH5ZpQ64bNWUtswjf4Aq
|
||||
XMwbKUc8sBr5Tilo2r0Hj4/ouytajvBfCWNy/ViDSMmtPE9HWvqFvw7YPkLdBX8q
|
||||
k/2J+koCSrAm8s4htQyyfwKBgQCRcuirIsSUqxlcBbVL/TrNpX0zDjwQjnLGL+ks
|
||||
6tCADJMzJN0Xk26re5cNrosAkWroO0jRfuVuMynsBLHcvtPpoFK2eL4/h3myC2SM
|
||||
xXNyMqdz96viWddY/xKeRzf6X19vhkwyKV5E2vee5jYSX580XLYahnNkNfHj77IB
|
||||
RCUfIQKBgQDHtgkK1nRyh3Vv7IpFFGXVOd4HiJ12nWFyXpS1mjzdQ5ARIrEFNz2Z
|
||||
y13bfrfjbEkVWXeCDBzkICWMnRBDtQc1hb6APfodUlakpLyxvFCA5SzygXvrK+MK
|
||||
aDPwY39N3pu0mvfM2Zs2LEXnAIp9VUvWCP+S4GvmHKbp+2tr6PtgkQ==
|
||||
-----END RSA PRIVATE KEY-----
|
414
vendor/github.com/genuinetools/reg/testutils/testutils.go
generated
vendored
Normal file
414
vendor/github.com/genuinetools/reg/testutils/testutils.go
generated
vendored
Normal file
|
@ -0,0 +1,414 @@
|
|||
package testutils
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
)
|
||||
|
||||
// StartRegistry starts a new registry container.
|
||||
func StartRegistry(dcli *client.Client, config, username, password string) (string, string, error) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", "", errors.New("No caller information")
|
||||
}
|
||||
|
||||
image := "registry:2"
|
||||
|
||||
if err := pullDockerImage(dcli, image); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
r, err := dcli.ContainerCreate(
|
||||
context.Background(),
|
||||
&container.Config{
|
||||
Image: image,
|
||||
},
|
||||
&container.HostConfig{
|
||||
NetworkMode: "host",
|
||||
Binds: []string{
|
||||
filepath.Join(filepath.Dir(filename), "configs", config) + ":" + "/etc/docker/registry/config.yml" + ":ro",
|
||||
filepath.Join(filepath.Dir(filename), "configs", "htpasswd") + ":" + "/etc/docker/registry/htpasswd" + ":ro",
|
||||
filepath.Join(filepath.Dir(filename), "snakeoil") + ":" + "/etc/docker/registry/ssl" + ":ro",
|
||||
},
|
||||
RestartPolicy: container.RestartPolicy{
|
||||
Name: "always",
|
||||
},
|
||||
},
|
||||
nil, "")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// start the container
|
||||
if err := dcli.ContainerStart(context.Background(), r.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return r.ID, "", err
|
||||
}
|
||||
|
||||
port := ":5000"
|
||||
addr := "https://localhost" + port
|
||||
|
||||
if err := waitForConn(addr, filepath.Join(filepath.Dir(filename), "snakeoil", "cert.pem"), filepath.Join(filepath.Dir(filename), "snakeoil", "key.pem")); err != nil {
|
||||
return r.ID, addr, err
|
||||
}
|
||||
|
||||
if err := dockerLogin("localhost"+port, username, password); err != nil {
|
||||
return r.ID, addr, err
|
||||
}
|
||||
|
||||
// Prefill the images.
|
||||
images := []string{"alpine:3.5", "alpine:latest", "busybox:latest", "busybox:musl", "busybox:glibc"}
|
||||
for _, image := range images {
|
||||
if err := prefillRegistry(image, dcli, "localhost"+port, username, password); err != nil {
|
||||
return r.ID, addr, err
|
||||
}
|
||||
}
|
||||
|
||||
return r.ID, addr, nil
|
||||
}
|
||||
|
||||
func startClairDB(dcli *client.Client) (string, error) {
|
||||
image := "postgres:latest"
|
||||
|
||||
if err := pullDockerImage(dcli, image); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
c, err := dcli.ContainerCreate(
|
||||
context.Background(),
|
||||
&container.Config{
|
||||
Image: image,
|
||||
Env: []string{
|
||||
"POSTGRES_PASSWORD=password",
|
||||
"POSTGRES_DB=clair",
|
||||
"POSTGRES_USER=hacker",
|
||||
},
|
||||
},
|
||||
&container.HostConfig{
|
||||
NetworkMode: "host",
|
||||
RestartPolicy: container.RestartPolicy{
|
||||
Name: "always",
|
||||
},
|
||||
},
|
||||
nil, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// start the container
|
||||
return c.ID, dcli.ContainerStart(context.Background(), c.ID, types.ContainerStartOptions{})
|
||||
}
|
||||
|
||||
// StartClair starts a new clair container and accompanying database.
|
||||
func StartClair(dcli *client.Client) (string, string, error) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", "", errors.New("No caller information")
|
||||
}
|
||||
|
||||
// start the database container.
|
||||
dbID, err := startClairDB(dcli)
|
||||
if err != nil {
|
||||
return dbID, "", err
|
||||
}
|
||||
|
||||
image := "clair:dev"
|
||||
|
||||
// build the docker image
|
||||
// create the tar ball
|
||||
ctx := filepath.Dir(filepath.Dir(filename))
|
||||
tw, err := tarit(ctx)
|
||||
if err != nil {
|
||||
return dbID, "", fmt.Errorf("tarit: %v", err)
|
||||
}
|
||||
|
||||
// build the image
|
||||
resp, err := dcli.ImageBuild(context.Background(), tw, types.ImageBuildOptions{
|
||||
Tags: []string{image},
|
||||
Dockerfile: "Dockerfile.clair",
|
||||
ForceRemove: true,
|
||||
Remove: true,
|
||||
SuppressOutput: false,
|
||||
PullParent: true,
|
||||
})
|
||||
if err != nil {
|
||||
return dbID, "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return dbID, "", err
|
||||
}
|
||||
|
||||
fmt.Printf("body: %s\n", string(b))
|
||||
|
||||
c, err := dcli.ContainerCreate(
|
||||
context.Background(),
|
||||
&container.Config{
|
||||
Image: image,
|
||||
},
|
||||
&container.HostConfig{
|
||||
NetworkMode: "host",
|
||||
Binds: []string{
|
||||
filepath.Join(filepath.Dir(filename), "configs", "clair.yml") + ":" + "/etc/clair/config.yaml" + ":ro",
|
||||
},
|
||||
RestartPolicy: container.RestartPolicy{
|
||||
Name: "always",
|
||||
},
|
||||
},
|
||||
nil, "")
|
||||
if err != nil {
|
||||
return dbID, c.ID, err
|
||||
}
|
||||
|
||||
// start the container
|
||||
err = dcli.ContainerStart(context.Background(), c.ID, types.ContainerStartOptions{})
|
||||
|
||||
// wait for clair to start
|
||||
// TODO: make this not a sleep
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
return dbID, c.ID, err
|
||||
}
|
||||
|
||||
// RemoveContainer removes with force a container by it's container ID.
|
||||
func RemoveContainer(dcli *client.Client, ctrs ...string) (err error) {
|
||||
for _, c := range ctrs {
|
||||
err = dcli.ContainerRemove(context.Background(), c,
|
||||
types.ContainerRemoveOptions{
|
||||
RemoveVolumes: true,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// dockerLogin logins via the command line to a docker registry
|
||||
func dockerLogin(addr, username, password string) error {
|
||||
cmd := exec.Command("docker", "login", "--username", username, "--password", password, addr)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("docker login [%s] failed with output %q and error: %v", strings.Join(cmd.Args, " "), string(out), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// prefillRegistry adds images to a registry.
|
||||
func prefillRegistry(image string, dcli *client.Client, addr, username, password string) error {
|
||||
if err := pullDockerImage(dcli, image); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := dcli.ImageTag(context.Background(), image, addr+"/"+image); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
auth, err := constructRegistryAuth(username, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := dcli.ImagePush(context.Background(), addr+"/"+image, types.ImagePushOptions{
|
||||
RegistryAuth: auth,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Close()
|
||||
|
||||
fd, isTerm := term.GetFdInfo(os.Stdout)
|
||||
|
||||
return jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerm, nil)
|
||||
}
|
||||
|
||||
func pullDockerImage(dcli *client.Client, image string) error {
|
||||
exists, err := imageExists(dcli, image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
resp, err := dcli.ImagePull(context.Background(), image, types.ImagePullOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Close()
|
||||
|
||||
fd, isTerm := term.GetFdInfo(os.Stdout)
|
||||
|
||||
return jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerm, nil)
|
||||
}
|
||||
|
||||
func imageExists(dcli *client.Client, image string) (bool, error) {
|
||||
_, _, err := dcli.ImageInspectWithRaw(context.Background(), image)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if client.IsErrNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// waitForConn takes a tcp addr and waits until it is reachable
|
||||
func waitForConn(addr, cert, key string) error {
|
||||
tlsCert, err := tls.LoadX509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not load X509 key pair: %v. Make sure the key is not encrypted", err)
|
||||
}
|
||||
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read system certificates: %v", err)
|
||||
}
|
||||
pem, err := ioutil.ReadFile(cert)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read CA certificate %s: %v", cert, err)
|
||||
}
|
||||
if !certPool.AppendCertsFromPEM(pem) {
|
||||
return fmt.Errorf("failed to append certificates from PEM file: %s", cert)
|
||||
}
|
||||
|
||||
c := http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
MinVersion: tls.VersionTLS12,
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
RootCAs: certPool,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
n := 0
|
||||
max := 10
|
||||
for n < max {
|
||||
if _, err := c.Get(addr + "/v2/"); err != nil {
|
||||
fmt.Printf("try number %d to %s: %v\n", n, addr, err)
|
||||
n++
|
||||
if n != max {
|
||||
fmt.Println("sleeping for 1 second then will try again...")
|
||||
time.Sleep(time.Second)
|
||||
} else {
|
||||
return fmt.Errorf("[WHOOPS]: maximum retries for %s exceeded", addr)
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// constructRegistryAuth serializes the auth configuration as JSON base64 payload.
|
||||
func constructRegistryAuth(identity, secret string) (string, error) {
|
||||
buf, err := json.Marshal(types.AuthConfig{Username: identity, Password: secret})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return base64.URLEncoding.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
func tarit(src string) (io.Reader, error) {
|
||||
s := bytes.NewBuffer(nil)
|
||||
t := bytes.NewBuffer(nil)
|
||||
buf := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(t))
|
||||
tarball := tar.NewWriter(s)
|
||||
|
||||
err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var link string
|
||||
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
if link, err = os.Readlink(path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
header, err := tar.FileInfoHeader(info, link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header.Name = strings.TrimPrefix(path, src)
|
||||
if err := tarball.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !info.Mode().IsRegular() { //nothing more to do for non-regular
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(tarball, file)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := s.WriteTo(buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = buf.Writer.Flush()
|
||||
return t, err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue