diff --git a/cli/command/config/create.go b/cli/command/config/create.go index 3f0a7db05e..437137c160 100644 --- a/cli/command/config/create.go +++ b/cli/command/config/create.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/opts" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/pkg/system" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -65,7 +64,7 @@ func runConfigCreate(dockerCli command.Cli, options createOptions) error { spec := swarm.ConfigSpec{ Annotations: swarm.Annotations{ Name: options.name, - Labels: runconfigopts.ConvertKVStringsToMap(options.labels.GetAll()), + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), }, Data: configData, } diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index b636733815..2b7471b352 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -17,7 +17,6 @@ import ( networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/pkg/signal" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/go-connections/nat" "github.com/pkg/errors" "github.com/spf13/pflag" @@ -409,13 +408,13 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err } // collect all the environment variables for the container - envVariables, err := runconfigopts.ReadKVStrings(copts.envFile.GetAll(), copts.env.GetAll()) + envVariables, err := opts.ReadKVStrings(copts.envFile.GetAll(), copts.env.GetAll()) if err != nil { return nil, err } // collect all the labels for the container - labels, err := runconfigopts.ReadKVStrings(copts.labelsFile.GetAll(), copts.labels.GetAll()) + labels, err := opts.ReadKVStrings(copts.labelsFile.GetAll(), copts.labels.GetAll()) if err != nil { return nil, err } @@ -440,7 +439,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err return nil, errors.Errorf("--userns: invalid USER mode") } - restartPolicy, err := runconfigopts.ParseRestartPolicy(copts.restartPolicy) + restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy) if err != nil { return nil, err } @@ -553,7 +552,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err MacAddress: copts.macAddress, Entrypoint: entrypoint, WorkingDir: copts.workingDir, - Labels: runconfigopts.ConvertKVStringsToMap(labels), + Labels: opts.ConvertKVStringsToMap(labels), Healthcheck: healthConfig, } if flags.Changed("stop-signal") { @@ -666,7 +665,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err } func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) { - loggingOptsMap := runconfigopts.ConvertKVStringsToMap(loggingOpts) + loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts) if loggingDriver == "none" && len(loggingOpts) > 0 { return map[string]string{}, errors.Errorf("invalid logging opts for driver %s", loggingDriver) } diff --git a/cli/command/container/run.go b/cli/command/container/run.go index 722ad22e69..0164219b7f 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -5,6 +5,7 @@ import ( "io" "net/http/httputil" "os" + "regexp" "runtime" "strings" "syscall" @@ -17,7 +18,6 @@ import ( "github.com/docker/docker/pkg/promise" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/term" - "github.com/docker/libnetwork/resolvconf/dns" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -77,13 +77,25 @@ func warnOnOomKillDisable(hostConfig container.HostConfig, stderr io.Writer) { // they are trying to set a DNS to a localhost address func warnOnLocalhostDNS(hostConfig container.HostConfig, stderr io.Writer) { for _, dnsIP := range hostConfig.DNS { - if dns.IsLocalhost(dnsIP) { + if isLocalhost(dnsIP) { fmt.Fprintf(stderr, "WARNING: Localhost DNS setting (--dns=%s) may fail in containers.\n", dnsIP) return } } } +// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range. +const ipLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)` + +var localhostIPRegexp = regexp.MustCompile(ipLocalhost) + +// IsLocalhost returns true if ip matches the localhost IP regular expression. +// Used for determining if nameserver settings are being passed which are +// localhost addresses +func isLocalhost(ip string) bool { + return localhostIPRegexp.MatchString(ip) +} + func runRun(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *runOptions, copts *containerOptions) error { containerConfig, err := parse(flags, copts) // just in case the parse does not exit diff --git a/cli/command/container/update.go b/cli/command/container/update.go index c13c7e6ab1..9cb74aeb76 100644 --- a/cli/command/container/update.go +++ b/cli/command/container/update.go @@ -8,7 +8,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" containertypes "github.com/docker/docker/api/types/container" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -82,7 +81,7 @@ func runUpdate(dockerCli *command.DockerCli, options *updateOptions) error { var restartPolicy containertypes.RestartPolicy if options.restartPolicy != "" { - restartPolicy, err = runconfigopts.ParseRestartPolicy(options.restartPolicy) + restartPolicy, err = opts.ParseRestartPolicy(options.restartPolicy) if err != nil { return err } diff --git a/cli/command/image/build.go b/cli/command/image/build.go index da28e898e9..1a6cb951bc 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -25,7 +25,6 @@ import ( "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/urlutil" - runconfigopts "github.com/docker/docker/runconfig/opts" units "github.com/docker/go-units" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -291,9 +290,9 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error { Dockerfile: relDockerfile, ShmSize: options.shmSize.Value(), Ulimits: options.ulimits.GetList(), - BuildArgs: runconfigopts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()), + BuildArgs: opts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()), AuthConfigs: authConfigs, - Labels: runconfigopts.ConvertKVStringsToMap(options.labels.GetAll()), + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), CacheFrom: options.cacheFrom, SecurityOpt: options.securityOpt, NetworkMode: options.networkMode, diff --git a/cli/command/image/build/context.go b/cli/command/image/build/context.go index e6165aa975..8b47dac026 100644 --- a/cli/command/image/build/context.go +++ b/cli/command/image/build/context.go @@ -1,24 +1,23 @@ package build import ( + "archive/tar" "bufio" + "bytes" "fmt" "io" "io/ioutil" + "net/http" "os" "os/exec" "path/filepath" "runtime" "strings" - - "archive/tar" - "bytes" "time" + "github.com/docker/docker/builder/remotecontext/git" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/fileutils" - "github.com/docker/docker/pkg/gitutils" - "github.com/docker/docker/pkg/httputils" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" @@ -143,7 +142,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error) if _, err := exec.LookPath("git"); err != nil { return "", "", errors.Wrapf(err, "unable to find 'git'") } - absContextDir, err := gitutils.Clone(gitURL) + absContextDir, err := git.Clone(gitURL) if err != nil { return "", "", errors.Wrapf(err, "unable to 'git clone' to temporary context directory") } @@ -161,7 +160,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error) // Returns the tar archive used for the context and a path of the // dockerfile inside the tar. func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.ReadCloser, string, error) { - response, err := httputils.Download(remoteURL) + response, err := getWithStatusError(remoteURL) if err != nil { return nil, "", errors.Errorf("unable to download remote context %s: %v", remoteURL, err) } @@ -173,6 +172,24 @@ func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.Read return GetContextFromReader(ioutils.NewReadCloserWrapper(progReader, func() error { return response.Body.Close() }), dockerfileName) } +// getWithStatusError does an http.Get() and returns an error if the +// status code is 4xx or 5xx. +func getWithStatusError(url string) (resp *http.Response, err error) { + if resp, err = http.Get(url); err != nil { + return nil, err + } + if resp.StatusCode < 400 { + return resp, nil + } + msg := fmt.Sprintf("failed to GET %s with status %s", url, resp.Status) + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return nil, errors.Wrapf(err, msg+": error reading body") + } + return nil, errors.Errorf(msg+": %s", bytes.TrimSpace(body)) +} + // GetContextFromLocalDir uses the given local directory as context for a // `docker build`. Returns the absolute path to the local context directory, // the relative path of the dockerfile in that context directory, and a non-nil diff --git a/cli/command/network/create.go b/cli/command/network/create.go index 88f7a62611..ed6d2de7bd 100644 --- a/cli/command/network/create.go +++ b/cli/command/network/create.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/opts" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -107,7 +106,7 @@ func runCreate(dockerCli *command.DockerCli, options createOptions) error { Ingress: options.ingress, Scope: options.scope, ConfigOnly: options.configOnly, - Labels: runconfigopts.ConvertKVStringsToMap(options.labels.GetAll()), + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), } if from := options.configFrom; from != "" { diff --git a/cli/command/node/update.go b/cli/command/node/update.go index 4ba5f6d38b..017cf7dcb5 100644 --- a/cli/command/node/update.go +++ b/cli/command/node/update.go @@ -7,7 +7,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" "github.com/docker/docker/api/types/swarm" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -95,7 +94,7 @@ func mergeNodeUpdate(flags *pflag.FlagSet) func(*swarm.Node) error { } if flags.Changed(flagLabelAdd) { labels := flags.Lookup(flagLabelAdd).Value.(*opts.ListOpts).GetAll() - for k, v := range runconfigopts.ConvertKVStringsToMap(labels) { + for k, v := range opts.ConvertKVStringsToMap(labels) { spec.Annotations.Labels[k] = v } } diff --git a/cli/command/secret/create.go b/cli/command/secret/create.go index e708f7c591..20efaec752 100644 --- a/cli/command/secret/create.go +++ b/cli/command/secret/create.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/opts" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/pkg/system" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -65,7 +64,7 @@ func runSecretCreate(dockerCli command.Cli, options createOptions) error { spec := swarm.SecretSpec{ Annotations: swarm.Annotations{ Name: options.name, - Labels: runconfigopts.ConvertKVStringsToMap(options.labels.GetAll()), + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), }, Data: secretData, } diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index c173f4f70b..35cdedc70e 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -11,7 +11,6 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/api/defaults" shlex "github.com/flynn-archive/go-shlex" @@ -389,7 +388,7 @@ func (ldo *logDriverOptions) toLogDriver() *swarm.Driver { // set the log driver only if specified. return &swarm.Driver{ Name: ldo.name, - Options: runconfigopts.ConvertKVStringsToMap(ldo.opts.GetAll()), + Options: opts.ConvertKVStringsToMap(ldo.opts.GetAll()), } } @@ -519,36 +518,36 @@ func newServiceOptions() *serviceOptions { } } -func (opts *serviceOptions) ToServiceMode() (swarm.ServiceMode, error) { +func (options *serviceOptions) ToServiceMode() (swarm.ServiceMode, error) { serviceMode := swarm.ServiceMode{} - switch opts.mode { + switch options.mode { case "global": - if opts.replicas.Value() != nil { + if options.replicas.Value() != nil { return serviceMode, errors.Errorf("replicas can only be used with replicated mode") } serviceMode.Global = &swarm.GlobalService{} case "replicated": serviceMode.Replicated = &swarm.ReplicatedService{ - Replicas: opts.replicas.Value(), + Replicas: options.replicas.Value(), } default: - return serviceMode, errors.Errorf("Unknown mode: %s, only replicated and global supported", opts.mode) + return serviceMode, errors.Errorf("Unknown mode: %s, only replicated and global supported", options.mode) } return serviceMode, nil } -func (opts *serviceOptions) ToStopGracePeriod(flags *pflag.FlagSet) *time.Duration { +func (options *serviceOptions) ToStopGracePeriod(flags *pflag.FlagSet) *time.Duration { if flags.Changed(flagStopGracePeriod) { - return opts.stopGrace.Value() + return options.stopGrace.Value() } return nil } -func (opts *serviceOptions) ToService(ctx context.Context, apiClient client.NetworkAPIClient, flags *pflag.FlagSet) (swarm.ServiceSpec, error) { +func (options *serviceOptions) ToService(ctx context.Context, apiClient client.NetworkAPIClient, flags *pflag.FlagSet) (swarm.ServiceSpec, error) { var service swarm.ServiceSpec - envVariables, err := runconfigopts.ReadKVStrings(opts.envFile.GetAll(), opts.env.GetAll()) + envVariables, err := opts.ReadKVStrings(options.envFile.GetAll(), options.env.GetAll()) if err != nil { return service, err } @@ -567,68 +566,68 @@ func (opts *serviceOptions) ToService(ctx context.Context, apiClient client.Netw currentEnv = append(currentEnv, env) } - healthConfig, err := opts.healthcheck.toHealthConfig() + healthConfig, err := options.healthcheck.toHealthConfig() if err != nil { return service, err } - serviceMode, err := opts.ToServiceMode() + serviceMode, err := options.ToServiceMode() if err != nil { return service, err } - networks, err := convertNetworks(ctx, apiClient, opts.networks) + networks, err := convertNetworks(ctx, apiClient, options.networks) if err != nil { return service, err } service = swarm.ServiceSpec{ Annotations: swarm.Annotations{ - Name: opts.name, - Labels: runconfigopts.ConvertKVStringsToMap(opts.labels.GetAll()), + Name: options.name, + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), }, TaskTemplate: swarm.TaskSpec{ ContainerSpec: swarm.ContainerSpec{ - Image: opts.image, - Args: opts.args, - Command: opts.entrypoint.Value(), + Image: options.image, + Args: options.args, + Command: options.entrypoint.Value(), Env: currentEnv, - Hostname: opts.hostname, - Labels: runconfigopts.ConvertKVStringsToMap(opts.containerLabels.GetAll()), - Dir: opts.workdir, - User: opts.user, - Groups: opts.groups.GetAll(), - StopSignal: opts.stopSignal, - TTY: opts.tty, - ReadOnly: opts.readOnly, - Mounts: opts.mounts.Value(), + Hostname: options.hostname, + Labels: opts.ConvertKVStringsToMap(options.containerLabels.GetAll()), + Dir: options.workdir, + User: options.user, + Groups: options.groups.GetAll(), + StopSignal: options.stopSignal, + TTY: options.tty, + ReadOnly: options.readOnly, + Mounts: options.mounts.Value(), DNSConfig: &swarm.DNSConfig{ - Nameservers: opts.dns.GetAll(), - Search: opts.dnsSearch.GetAll(), - Options: opts.dnsOption.GetAll(), + Nameservers: options.dns.GetAll(), + Search: options.dnsSearch.GetAll(), + Options: options.dnsOption.GetAll(), }, - Hosts: convertExtraHostsToSwarmHosts(opts.hosts.GetAll()), - StopGracePeriod: opts.ToStopGracePeriod(flags), + Hosts: convertExtraHostsToSwarmHosts(options.hosts.GetAll()), + StopGracePeriod: options.ToStopGracePeriod(flags), Healthcheck: healthConfig, }, Networks: networks, - Resources: opts.resources.ToResourceRequirements(), - RestartPolicy: opts.restartPolicy.ToRestartPolicy(flags), + Resources: options.resources.ToResourceRequirements(), + RestartPolicy: options.restartPolicy.ToRestartPolicy(flags), Placement: &swarm.Placement{ - Constraints: opts.constraints.GetAll(), - Preferences: opts.placementPrefs.prefs, + Constraints: options.constraints.GetAll(), + Preferences: options.placementPrefs.prefs, }, - LogDriver: opts.logDriver.toLogDriver(), + LogDriver: options.logDriver.toLogDriver(), }, Mode: serviceMode, - UpdateConfig: opts.update.updateConfig(flags), - RollbackConfig: opts.update.rollbackConfig(flags), - EndpointSpec: opts.endpoint.ToEndpointSpec(), + UpdateConfig: options.update.updateConfig(flags), + RollbackConfig: options.update.rollbackConfig(flags), + EndpointSpec: options.endpoint.ToEndpointSpec(), } - if opts.credentialSpec.Value() != nil { + if options.credentialSpec.Value() != nil { service.TaskTemplate.ContainerSpec.Privileges = &swarm.Privileges{ - CredentialSpec: opts.credentialSpec.Value(), + CredentialSpec: options.credentialSpec.Value(), } } diff --git a/cli/command/service/update.go b/cli/command/service/update.go index 5e3bc7c458..48552e2453 100644 --- a/cli/command/service/update.go +++ b/cli/command/service/update.go @@ -15,7 +15,6 @@ import ( "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/swarmkit/api/defaults" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -519,7 +518,7 @@ func updateContainerLabels(flags *pflag.FlagSet, field *map[string]string) { } values := flags.Lookup(flagContainerLabelAdd).Value.(*opts.ListOpts).GetAll() - for key, value := range runconfigopts.ConvertKVStringsToMap(values) { + for key, value := range opts.ConvertKVStringsToMap(values) { (*field)[key] = value } } @@ -539,7 +538,7 @@ func updateLabels(flags *pflag.FlagSet, field *map[string]string) { } values := flags.Lookup(flagLabelAdd).Value.(*opts.ListOpts).GetAll() - for key, value := range runconfigopts.ConvertKVStringsToMap(values) { + for key, value := range opts.ConvertKVStringsToMap(values) { (*field)[key] = value } } @@ -933,7 +932,7 @@ func updateLogDriver(flags *pflag.FlagSet, taskTemplate *swarm.TaskSpec) error { taskTemplate.LogDriver = &swarm.Driver{ Name: name, - Options: runconfigopts.ConvertKVStringsToMap(flags.Lookup(flagLogOpt).Value.(*opts.ListOpts).GetAll()), + Options: opts.ConvertKVStringsToMap(flags.Lookup(flagLogOpt).Value.(*opts.ListOpts).GetAll()), } return nil diff --git a/cli/command/volume/create.go b/cli/command/volume/create.go index bf7f1a72b6..5a1092266f 100644 --- a/cli/command/volume/create.go +++ b/cli/command/volume/create.go @@ -7,7 +7,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" volumetypes "github.com/docker/docker/api/types/volume" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -57,7 +56,7 @@ func runCreate(dockerCli command.Cli, options createOptions) error { Driver: options.driver, DriverOpts: options.driverOpts.GetAll(), Name: options.name, - Labels: runconfigopts.ConvertKVStringsToMap(options.labels.GetAll()), + Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()), } vol, err := client.VolumeCreate(context.Background(), volReq) diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index 233a376293..0fef936a22 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -14,7 +14,6 @@ import ( "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/pkg/errors" ) @@ -404,7 +403,7 @@ func convertHealthcheck(healthcheck *composetypes.HealthCheckConfig) (*container func convertRestartPolicy(restart string, source *composetypes.RestartPolicy) (*swarm.RestartPolicy, error) { // TODO: log if restart is being ignored if source == nil { - policy, err := runconfigopts.ParseRestartPolicy(restart) + policy, err := opts.ParseRestartPolicy(restart) if err != nil { return nil, err } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index f12a7f0eea..8e009e375a 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -14,7 +14,6 @@ import ( "github.com/docker/cli/cli/compose/template" "github.com/docker/cli/cli/compose/types" "github.com/docker/cli/opts" - runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/go-connections/nat" units "github.com/docker/go-units" shellwords "github.com/mattn/go-shellwords" @@ -351,14 +350,14 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, l for _, file := range serviceConfig.EnvFile { filePath := absPath(workingDir, file) - fileVars, err := runconfigopts.ParseEnvFile(filePath) + fileVars, err := opts.ParseEnvFile(filePath) if err != nil { return err } envVars = append(envVars, fileVars...) } updateEnvironment(environment, - runconfigopts.ConvertKVStringsToMapWithNil(envVars), lookupEnv) + opts.ConvertKVStringsToMapWithNil(envVars), lookupEnv) } updateEnvironment(environment, serviceConfig.Environment, lookupEnv) diff --git a/vendor/github.com/docker/docker/runconfig/opts/envfile.go b/opts/envfile.go similarity index 100% rename from vendor/github.com/docker/docker/runconfig/opts/envfile.go rename to opts/envfile.go diff --git a/opts/envfile_test.go b/opts/envfile_test.go new file mode 100644 index 0000000000..f3faabe3c0 --- /dev/null +++ b/opts/envfile_test.go @@ -0,0 +1,141 @@ +package opts + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "reflect" + "strings" + "testing" +) + +func tmpFileWithContent(content string, t *testing.T) string { + tmpFile, err := ioutil.TempFile("", "envfile-test") + if err != nil { + t.Fatal(err) + } + defer tmpFile.Close() + + tmpFile.WriteString(content) + return tmpFile.Name() +} + +// Test ParseEnvFile for a file with a few well formatted lines +func TestParseEnvFileGoodFile(t *testing.T) { + content := `foo=bar + baz=quux +# comment + +_foobar=foobaz +with.dots=working +and_underscore=working too +` + // Adding a newline + a line with pure whitespace. + // This is being done like this instead of the block above + // because it's common for editors to trim trailing whitespace + // from lines, which becomes annoying since that's the + // exact thing we need to test. + content += "\n \t " + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + lines, err := ParseEnvFile(tmpFile) + if err != nil { + t.Fatal(err) + } + + expectedLines := []string{ + "foo=bar", + "baz=quux", + "_foobar=foobaz", + "with.dots=working", + "and_underscore=working too", + } + + if !reflect.DeepEqual(lines, expectedLines) { + t.Fatal("lines not equal to expectedLines") + } +} + +// Test ParseEnvFile for an empty file +func TestParseEnvFileEmptyFile(t *testing.T) { + tmpFile := tmpFileWithContent("", t) + defer os.Remove(tmpFile) + + lines, err := ParseEnvFile(tmpFile) + if err != nil { + t.Fatal(err) + } + + if len(lines) != 0 { + t.Fatal("lines not empty; expected empty") + } +} + +// Test ParseEnvFile for a non existent file +func TestParseEnvFileNonExistentFile(t *testing.T) { + _, err := ParseEnvFile("foo_bar_baz") + if err == nil { + t.Fatal("ParseEnvFile succeeded; expected failure") + } + if _, ok := err.(*os.PathError); !ok { + t.Fatalf("Expected a PathError, got [%v]", err) + } +} + +// Test ParseEnvFile for a badly formatted file +func TestParseEnvFileBadlyFormattedFile(t *testing.T) { + content := `foo=bar + f =quux +` + + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + _, err := ParseEnvFile(tmpFile) + if err == nil { + t.Fatalf("Expected an ErrBadEnvVariable, got nothing") + } + if _, ok := err.(ErrBadEnvVariable); !ok { + t.Fatalf("Expected an ErrBadEnvVariable, got [%v]", err) + } + expectedMessage := "poorly formatted environment: variable 'f ' has white spaces" + if err.Error() != expectedMessage { + t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error()) + } +} + +// Test ParseEnvFile for a file with a line exceeding bufio.MaxScanTokenSize +func TestParseEnvFileLineTooLongFile(t *testing.T) { + content := strings.Repeat("a", bufio.MaxScanTokenSize+42) + content = fmt.Sprint("foo=", content) + + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + _, err := ParseEnvFile(tmpFile) + if err == nil { + t.Fatal("ParseEnvFile succeeded; expected failure") + } +} + +// ParseEnvFile with a random file, pass through +func TestParseEnvFileRandomFile(t *testing.T) { + content := `first line +another invalid line` + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + _, err := ParseEnvFile(tmpFile) + if err == nil { + t.Fatalf("Expected an ErrBadEnvVariable, got nothing") + } + if _, ok := err.(ErrBadEnvVariable); !ok { + t.Fatalf("Expected an ErrBadEnvVariable, got [%v]", err) + } + expectedMessage := "poorly formatted environment: variable 'first line' has white spaces" + if err.Error() != expectedMessage { + t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error()) + } +} diff --git a/vendor/github.com/docker/docker/runconfig/opts/parse.go b/opts/parse.go similarity index 100% rename from vendor/github.com/docker/docker/runconfig/opts/parse.go rename to opts/parse.go diff --git a/vendor.conf b/vendor.conf index 83249b101e..0c506e6618 100644 --- a/vendor.conf +++ b/vendor.conf @@ -7,13 +7,12 @@ github.com/coreos/etcd 824277cb3a577a0e8c829ca9ec557b973fe06d20 github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 -github.com/docker/docker 45c6f4262a865a03adaac291a9ce33c0f2190d77 -github.com/docker/docker-credential-helpers v0.5.0 -github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 +github.com/docker/docker c8141a1fb1ff33b2bfab85a40e5da9a282f36cdc +github.com/docker/docker-credential-helpers v0.5.1 +github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 #? github.com/docker/go-connections e15c02316c12de00874640cd76311849de2aeed5 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 -github.com/docker/libnetwork b13e0604016a4944025aaff521d9c125850b0d04 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/docker/notary v0.4.2 github.com/docker/swarmkit 1a3e510517be82d18ac04380b5f71eddf06c2fc0 @@ -29,7 +28,7 @@ github.com/mitchellh/mapstructure f3009df150dadf309fdee4a54ed65c124afad715 github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe github.com/opencontainers/runc 9c2d8d184e5da67c95d601382adf14862e4f2228 https://github.com/docker/runc.git -github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d +github.com/opencontainers/selinux v1.0.0-rc1 github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9 github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 github.com/russross/blackfriday 1d6b8e9301e720b08a8938b8c25c018285885438 diff --git a/vendor/github.com/docker/docker-credential-helpers/client/client.go b/vendor/github.com/docker/docker-credential-helpers/client/client.go index d0813965b5..d1d0434cb5 100644 --- a/vendor/github.com/docker/docker-credential-helpers/client/client.go +++ b/vendor/github.com/docker/docker-credential-helpers/client/client.go @@ -9,12 +9,27 @@ import ( "github.com/docker/docker-credential-helpers/credentials" ) +// isValidCredsMessage checks if 'msg' contains invalid credentials error message. +// It returns whether the logs are free of invalid credentials errors and the error if it isn't. +// error values can be errCredentialsMissingServerURL or errCredentialsMissingUsername. +func isValidCredsMessage(msg string) error { + if credentials.IsCredentialsMissingServerURLMessage(msg) { + return credentials.NewErrCredentialsMissingServerURL() + } + + if credentials.IsCredentialsMissingUsernameMessage(msg) { + return credentials.NewErrCredentialsMissingUsername() + } + + return nil +} + // Store uses an external program to save credentials. -func Store(program ProgramFunc, credentials *credentials.Credentials) error { +func Store(program ProgramFunc, creds *credentials.Credentials) error { cmd := program("store") buffer := new(bytes.Buffer) - if err := json.NewEncoder(buffer).Encode(credentials); err != nil { + if err := json.NewEncoder(buffer).Encode(creds); err != nil { return err } cmd.Input(buffer) @@ -22,6 +37,11 @@ func Store(program ProgramFunc, credentials *credentials.Credentials) error { out, err := cmd.Output() if err != nil { t := strings.TrimSpace(string(out)) + + if isValidErr := isValidCredsMessage(t); isValidErr != nil { + err = isValidErr + } + return fmt.Errorf("error storing credentials - err: %v, out: `%s`", err, t) } @@ -41,6 +61,10 @@ func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error return nil, credentials.NewErrCredentialsNotFound() } + if isValidErr := isValidCredsMessage(t); isValidErr != nil { + err = isValidErr + } + return nil, fmt.Errorf("error getting credentials - err: %v, out: `%s`", err, t) } @@ -62,6 +86,11 @@ func Erase(program ProgramFunc, serverURL string) error { out, err := cmd.Output() if err != nil { t := strings.TrimSpace(string(out)) + + if isValidErr := isValidCredsMessage(t); isValidErr != nil { + err = isValidErr + } + return fmt.Errorf("error erasing credentials - err: %v, out: `%s`", err, t) } @@ -75,6 +104,11 @@ func List(program ProgramFunc) (map[string]string, error) { out, err := cmd.Output() if err != nil { t := strings.TrimSpace(string(out)) + + if isValidErr := isValidCredsMessage(t); isValidErr != nil { + err = isValidErr + } + return nil, fmt.Errorf("error listing credentials - err: %v, out: `%s`", err, t) } diff --git a/vendor/github.com/docker/docker-credential-helpers/client/command.go b/vendor/github.com/docker/docker-credential-helpers/client/command.go index 8983da6947..a144d5ac18 100644 --- a/vendor/github.com/docker/docker-credential-helpers/client/command.go +++ b/vendor/github.com/docker/docker-credential-helpers/client/command.go @@ -2,6 +2,7 @@ package client import ( "io" + "os" "os/exec" ) @@ -17,10 +18,16 @@ type ProgramFunc func(args ...string) Program // NewShellProgramFunc creates programs that are executed in a Shell. func NewShellProgramFunc(name string) ProgramFunc { return func(args ...string) Program { - return &Shell{cmd: exec.Command(name, args...)} + return &Shell{cmd: newCmdRedirectErr(name, args)} } } +func newCmdRedirectErr(name string, args []string) *exec.Cmd { + newCmd := exec.Command(name, args...) + newCmd.Stderr = os.Stderr + return newCmd +} + // Shell invokes shell commands to talk with a remote credentials helper. type Shell struct { cmd *exec.Cmd diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go index cfe0cb134e..544ab3c4e1 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go @@ -17,6 +17,22 @@ type Credentials struct { Secret string } +// isValid checks the integrity of Credentials object such that no credentials lack +// a server URL or a username. +// It returns whether the credentials are valid and the error if it isn't. +// error values can be errCredentialsMissingServerURL or errCredentialsMissingUsername +func (c *Credentials) isValid() (bool, error) { + if len(c.ServerURL) == 0 { + return false, NewErrCredentialsMissingServerURL() + } + + if len(c.Username) == 0 { + return false, NewErrCredentialsMissingUsername() + } + + return true, nil +} + // Docker credentials should be labeled as such in credentials stores that allow labelling. // That label allows to filter out non-Docker credentials too at lookup/search in macOS keychain, // Windows credentials manager and Linux libsecret. Default value is "Docker Credentials" @@ -81,6 +97,10 @@ func Store(helper Helper, reader io.Reader) error { return err } + if ok, err := creds.isValid(); !ok { + return err + } + return helper.Add(&creds) } @@ -100,6 +120,9 @@ func Get(helper Helper, reader io.Reader, writer io.Writer) error { } serverURL := strings.TrimSpace(buffer.String()) + if len(serverURL) == 0 { + return NewErrCredentialsMissingServerURL() + } username, secret, err := helper.Get(serverURL) if err != nil { @@ -107,6 +130,7 @@ func Get(helper Helper, reader io.Reader, writer io.Writer) error { } resp := Credentials{ + ServerURL: serverURL, Username: username, Secret: secret, } @@ -135,6 +159,9 @@ func Erase(helper Helper, reader io.Reader) error { } serverURL := strings.TrimSpace(buffer.String()) + if len(serverURL) == 0 { + return NewErrCredentialsMissingServerURL() + } return helper.Delete(serverURL) } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go index d24bf16f09..588d4a83d7 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go @@ -1,8 +1,15 @@ package credentials -// ErrCredentialsNotFound standarizes the not found error, so every helper returns -// the same message and docker can handle it properly. -const errCredentialsNotFoundMessage = "credentials not found in native keychain" +const ( + // ErrCredentialsNotFound standardizes the not found error, so every helper returns + // the same message and docker can handle it properly. + errCredentialsNotFoundMessage = "credentials not found in native keychain" + + // ErrCredentialsMissingServerURL and ErrCredentialsMissingUsername standardize + // invalid credentials or credentials management operations + errCredentialsMissingServerURLMessage = "no credentials server URL" + errCredentialsMissingUsernameMessage = "no credentials username" +) // errCredentialsNotFound represents an error // raised when credentials are not in the store. @@ -35,3 +42,64 @@ func IsErrCredentialsNotFound(err error) bool { func IsErrCredentialsNotFoundMessage(err string) bool { return err == errCredentialsNotFoundMessage } + + +// errCredentialsMissingServerURL represents an error raised +// when the credentials object has no server URL or when no +// server URL is provided to a credentials operation requiring +// one. +type errCredentialsMissingServerURL struct{} + +func (errCredentialsMissingServerURL) Error() string { + return errCredentialsMissingServerURLMessage +} + +// errCredentialsMissingUsername represents an error raised +// when the credentials object has no username or when no +// username is provided to a credentials operation requiring +// one. +type errCredentialsMissingUsername struct{} + +func (errCredentialsMissingUsername) Error() string { + return errCredentialsMissingUsernameMessage +} + + +// NewErrCredentialsMissingServerURL creates a new error for +// errCredentialsMissingServerURL. +func NewErrCredentialsMissingServerURL() error { + return errCredentialsMissingServerURL{} +} + +// NewErrCredentialsMissingUsername creates a new error for +// errCredentialsMissingUsername. +func NewErrCredentialsMissingUsername() error { + return errCredentialsMissingUsername{} +} + + +// IsCredentialsMissingServerURL returns true if the error +// was an errCredentialsMissingServerURL. +func IsCredentialsMissingServerURL(err error) bool { + _, ok := err.(errCredentialsMissingServerURL) + return ok +} + +// IsCredentialsMissingServerURLMessage checks for an +// errCredentialsMissingServerURL in the error message. +func IsCredentialsMissingServerURLMessage(err string) bool { + return err == errCredentialsMissingServerURLMessage +} + +// IsCredentialsMissingUsername returns true if the error +// was an errCredentialsMissingUsername. +func IsCredentialsMissingUsername(err error) bool { + _, ok := err.(errCredentialsMissingUsername) + return ok +} + +// IsCredentialsMissingUsernameMessage checks for an +// errCredentialsMissingUsername in the error message. +func IsCredentialsMissingUsernameMessage(err string) bool { + return err == errCredentialsMissingUsernameMessage +} diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/docker/docker/api/types/swarm/task.go index 9fd52e47d0..a598a79d59 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/task.go +++ b/vendor/github.com/docker/docker/api/types/swarm/task.go @@ -67,9 +67,6 @@ type TaskSpec struct { ForceUpdate uint64 Runtime RuntimeType `json:",omitempty"` - // TODO (ehazlett): this should be removed and instead - // use struct tags (proto) for the runtimes - RuntimeData []byte `json:",omitempty"` } // Resources represents resources (CPU/Memory). diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index fa9f1b0de1..c905466e29 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -277,7 +277,7 @@ type Health struct { // ContainerState stores container's running state // it's part of ContainerJSONBase and will return by "inspect" command type ContainerState struct { - Status string + Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead" Running bool Paused bool Restarting bool diff --git a/vendor/github.com/docker/docker/api/types/volume.go b/vendor/github.com/docker/docker/api/types/volume.go index da4f8ebd9c..a69b0cfb17 100644 --- a/vendor/github.com/docker/docker/api/types/volume.go +++ b/vendor/github.com/docker/docker/api/types/volume.go @@ -7,6 +7,9 @@ package types // swagger:model Volume type Volume struct { + // Time volume was created. + CreatedAt string `json:"CreatedAt,omitempty"` + // Name of the volume driver used by the volume. // Required: true Driver string `json:"Driver"` diff --git a/vendor/github.com/docker/docker/pkg/gitutils/gitutils.go b/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go similarity index 99% rename from vendor/github.com/docker/docker/pkg/gitutils/gitutils.go rename to vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go index 4e09e05239..fd8250dbc3 100644 --- a/vendor/github.com/docker/docker/pkg/gitutils/gitutils.go +++ b/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go @@ -1,4 +1,4 @@ -package gitutils +package git import ( "fmt" diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index f8f2fc6ad5..34897b9549 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -247,6 +247,12 @@ func (cli *Client) UpdateClientVersion(v string) { } +// DaemonHost returns the host associated with this instance of the Client. +// This operation doesn't acquire a mutex. +func (cli *Client) DaemonHost() string { + return cli.host +} + // ParseHost verifies that the given host strings is valid. func ParseHost(host string) (string, string, string, error) { protoAddrParts := strings.SplitN(host, "://", 2) diff --git a/vendor/github.com/docker/docker/client/container_wait.go b/vendor/github.com/docker/docker/client/container_wait.go index edfa5d3c85..13b5eea6a9 100644 --- a/vendor/github.com/docker/docker/client/container_wait.go +++ b/vendor/github.com/docker/docker/client/container_wait.go @@ -10,7 +10,7 @@ import ( "github.com/docker/docker/api/types/versions" ) -// ContainerWait waits until the specified continer is in a certain state +// ContainerWait waits until the specified container is in a certain state // indicated by the given condition, either "not-running" (default), // "next-exit", or "removed". // @@ -31,7 +31,7 @@ func (cli *Client) ContainerWait(ctx context.Context, containerID string, condit } resultC := make(chan container.ContainerWaitOKBody) - errC := make(chan error) + errC := make(chan error, 1) query := url.Values{} query.Set("condition", string(condition)) diff --git a/vendor/github.com/docker/docker/client/interface.go b/vendor/github.com/docker/docker/client/interface.go index 678a69ddf7..d5f3a14ec3 100644 --- a/vendor/github.com/docker/docker/client/interface.go +++ b/vendor/github.com/docker/docker/client/interface.go @@ -31,6 +31,7 @@ type CommonAPIClient interface { SystemAPIClient VolumeAPIClient ClientVersion() string + DaemonHost() string ServerVersion(ctx context.Context) (types.Version, error) UpdateClientVersion(v string) } diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go index 73fc68fb33..71a7583e86 100644 --- a/vendor/github.com/docker/docker/client/service_create.go +++ b/vendor/github.com/docker/docker/client/service_create.go @@ -24,14 +24,18 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth} } + // ensure that the image is tagged + if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { + service.TaskTemplate.ContainerSpec.Image = taggedImg + } + // Contact the registry to retrieve digest and platform information if options.QueryRegistry { distributionInspect, err := cli.DistributionInspect(ctx, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth) distErr = err if err == nil { // now pin by digest if the image doesn't already contain a digest - img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest) - if img != "" { + if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" { service.TaskTemplate.ContainerSpec.Image = img } // add platforms that are compatible with the service @@ -55,25 +59,33 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, } // imageWithDigestString takes an image string and a digest, and updates -// the image string if it didn't originally contain a digest. It assumes -// that the image string is not an image ID +// the image string if it didn't originally contain a digest. It returns +// an empty string if there are no updates. func imageWithDigestString(image string, dgst digest.Digest) string { - isCanonical := false - ref, err := reference.ParseAnyReference(image) + namedRef, err := reference.ParseNormalizedNamed(image) if err == nil { - _, isCanonical = ref.(reference.Canonical) - - if !isCanonical { - namedRef, _ := ref.(reference.Named) + if _, isCanonical := namedRef.(reference.Canonical); !isCanonical { + // ensure that image gets a default tag if none is provided img, err := reference.WithDigest(namedRef, dgst) if err == nil { - return img.String() + return reference.FamiliarString(img) } } } return "" } +// imageWithTagString takes an image string, and returns a tagged image +// string, adding a 'latest' tag if one was not provided. It returns an +// emptry string if a canonical reference was provided +func imageWithTagString(image string) string { + namedRef, err := reference.ParseNormalizedNamed(image) + if err == nil { + return reference.FamiliarString(reference.TagNameOnly(namedRef)) + } + return "" +} + // updateServicePlatforms updates the Platforms in swarm.Placement to list // all compatible platforms for the service, as found in distributionInspect // and returns a pointer to the new or updated swarm.Placement struct diff --git a/vendor/github.com/docker/docker/client/service_update.go b/vendor/github.com/docker/docker/client/service_update.go index 0cb35a1991..412790b5dd 100644 --- a/vendor/github.com/docker/docker/client/service_update.go +++ b/vendor/github.com/docker/docker/client/service_update.go @@ -35,6 +35,11 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version query.Set("version", strconv.FormatUint(version.Index, 10)) + // ensure that the image is tagged + if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { + service.TaskTemplate.ContainerSpec.Image = taggedImg + } + // Contact the registry to retrieve digest and platform information // This happens only when the image has changed if options.QueryRegistry { @@ -42,8 +47,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version distErr = err if err == nil { // now pin by digest if the image doesn't already contain a digest - img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest) - if img != "" { + if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" { service.TaskTemplate.ContainerSpec.Image = img } // add platforms that are compatible with the service diff --git a/vendor/github.com/docker/docker/opts/config.go b/vendor/github.com/docker/docker/opts/config.go deleted file mode 100644 index 82fd2bce4e..0000000000 --- a/vendor/github.com/docker/docker/opts/config.go +++ /dev/null @@ -1,98 +0,0 @@ -package opts - -import ( - "encoding/csv" - "fmt" - "os" - "strconv" - "strings" - - swarmtypes "github.com/docker/docker/api/types/swarm" -) - -// ConfigOpt is a Value type for parsing configs -type ConfigOpt struct { - values []*swarmtypes.ConfigReference -} - -// Set a new config value -func (o *ConfigOpt) Set(value string) error { - csvReader := csv.NewReader(strings.NewReader(value)) - fields, err := csvReader.Read() - if err != nil { - return err - } - - options := &swarmtypes.ConfigReference{ - File: &swarmtypes.ConfigReferenceFileTarget{ - UID: "0", - GID: "0", - Mode: 0444, - }, - } - - // support a simple syntax of --config foo - if len(fields) == 1 { - options.File.Name = fields[0] - options.ConfigName = fields[0] - o.values = append(o.values, options) - return nil - } - - for _, field := range fields { - parts := strings.SplitN(field, "=", 2) - key := strings.ToLower(parts[0]) - - if len(parts) != 2 { - return fmt.Errorf("invalid field '%s' must be a key=value pair", field) - } - - value := parts[1] - switch key { - case "source", "src": - options.ConfigName = value - case "target": - options.File.Name = value - case "uid": - options.File.UID = value - case "gid": - options.File.GID = value - case "mode": - m, err := strconv.ParseUint(value, 0, 32) - if err != nil { - return fmt.Errorf("invalid mode specified: %v", err) - } - - options.File.Mode = os.FileMode(m) - default: - return fmt.Errorf("invalid field in config request: %s", key) - } - } - - if options.ConfigName == "" { - return fmt.Errorf("source is required") - } - - o.values = append(o.values, options) - return nil -} - -// Type returns the type of this option -func (o *ConfigOpt) Type() string { - return "config" -} - -// String returns a string repr of this option -func (o *ConfigOpt) String() string { - configs := []string{} - for _, config := range o.values { - repr := fmt.Sprintf("%s -> %s", config.ConfigName, config.File.Name) - configs = append(configs, repr) - } - return strings.Join(configs, ", ") -} - -// Value returns the config requests -func (o *ConfigOpt) Value() []*swarmtypes.ConfigReference { - return o.values -} diff --git a/vendor/github.com/docker/docker/opts/opts.go b/vendor/github.com/docker/docker/opts/opts.go index f76f308051..8d82f76792 100644 --- a/vendor/github.com/docker/docker/opts/opts.go +++ b/vendor/github.com/docker/docker/opts/opts.go @@ -2,13 +2,11 @@ package opts import ( "fmt" - "math/big" "net" "path" "regexp" "strings" - "github.com/docker/docker/api/types/filters" units "github.com/docker/go-units" ) @@ -236,15 +234,6 @@ func ValidateIPAddress(val string) (string, error) { return "", fmt.Errorf("%s is not an ip address", val) } -// ValidateMACAddress validates a MAC address. -func ValidateMACAddress(val string) (string, error) { - _, err := net.ParseMAC(strings.TrimSpace(val)) - if err != nil { - return "", err - } - return val, nil -} - // ValidateDNSSearch validates domain for resolvconf search configuration. // A zero length domain is represented by a dot (.). func ValidateDNSSearch(val string) (string, error) { @@ -274,114 +263,6 @@ func ValidateLabel(val string) (string, error) { return val, nil } -// ValidateSysctl validates a sysctl and returns it. -func ValidateSysctl(val string) (string, error) { - validSysctlMap := map[string]bool{ - "kernel.msgmax": true, - "kernel.msgmnb": true, - "kernel.msgmni": true, - "kernel.sem": true, - "kernel.shmall": true, - "kernel.shmmax": true, - "kernel.shmmni": true, - "kernel.shm_rmid_forced": true, - } - validSysctlPrefixes := []string{ - "net.", - "fs.mqueue.", - } - arr := strings.Split(val, "=") - if len(arr) < 2 { - return "", fmt.Errorf("sysctl '%s' is not whitelisted", val) - } - if validSysctlMap[arr[0]] { - return val, nil - } - - for _, vp := range validSysctlPrefixes { - if strings.HasPrefix(arr[0], vp) { - return val, nil - } - } - return "", fmt.Errorf("sysctl '%s' is not whitelisted", val) -} - -// FilterOpt is a flag type for validating filters -type FilterOpt struct { - filter filters.Args -} - -// NewFilterOpt returns a new FilterOpt -func NewFilterOpt() FilterOpt { - return FilterOpt{filter: filters.NewArgs()} -} - -func (o *FilterOpt) String() string { - repr, err := filters.ToParam(o.filter) - if err != nil { - return "invalid filters" - } - return repr -} - -// Set sets the value of the opt by parsing the command line value -func (o *FilterOpt) Set(value string) error { - var err error - o.filter, err = filters.ParseFlag(value, o.filter) - return err -} - -// Type returns the option type -func (o *FilterOpt) Type() string { - return "filter" -} - -// Value returns the value of this option -func (o *FilterOpt) Value() filters.Args { - return o.filter -} - -// NanoCPUs is a type for fixed point fractional number. -type NanoCPUs int64 - -// String returns the string format of the number -func (c *NanoCPUs) String() string { - if *c == 0 { - return "" - } - return big.NewRat(c.Value(), 1e9).FloatString(3) -} - -// Set sets the value of the NanoCPU by passing a string -func (c *NanoCPUs) Set(value string) error { - cpus, err := ParseCPUs(value) - *c = NanoCPUs(cpus) - return err -} - -// Type returns the type -func (c *NanoCPUs) Type() string { - return "decimal" -} - -// Value returns the value in int64 -func (c *NanoCPUs) Value() int64 { - return int64(*c) -} - -// ParseCPUs takes a string ratio and returns an integer value of nano cpus -func ParseCPUs(value string) (int64, error) { - cpu, ok := new(big.Rat).SetString(value) - if !ok { - return 0, fmt.Errorf("failed to parse %v as a rational number", value) - } - nano := cpu.Mul(cpu, big.NewRat(1e9, 1)) - if !nano.IsInt() { - return 0, fmt.Errorf("value is too precise") - } - return nano.Num().Int64(), nil -} - // ParseLink parses and validates the specified string as a link format (name:alias) func ParseLink(val string) (string, string, error) { if val == "" { @@ -404,12 +285,6 @@ func ParseLink(val string) (string, string, error) { return arr[0], arr[1], nil } -// ValidateLink validates that the specified string has a valid link format (containerName:alias). -func ValidateLink(val string) (string, error) { - _, _, err := ParseLink(val) - return val, err -} - // MemBytes is a type for human readable memory bytes (like 128M, 2g, etc) type MemBytes int64 @@ -450,39 +325,3 @@ func (m *MemBytes) UnmarshalJSON(s []byte) error { *m = MemBytes(val) return err } - -// MemSwapBytes is a type for human readable memory bytes (like 128M, 2g, etc). -// It differs from MemBytes in that -1 is valid and the default. -type MemSwapBytes int64 - -// Set sets the value of the MemSwapBytes by passing a string -func (m *MemSwapBytes) Set(value string) error { - if value == "-1" { - *m = MemSwapBytes(-1) - return nil - } - val, err := units.RAMInBytes(value) - *m = MemSwapBytes(val) - return err -} - -// Type returns the type -func (m *MemSwapBytes) Type() string { - return "bytes" -} - -// Value returns the value in int64 -func (m *MemSwapBytes) Value() int64 { - return int64(*m) -} - -func (m *MemSwapBytes) String() string { - b := MemBytes(*m) - return b.String() -} - -// UnmarshalJSON is the customized unmarshaler for MemSwapBytes -func (m *MemSwapBytes) UnmarshalJSON(s []byte) error { - b := MemBytes(*m) - return b.UnmarshalJSON(s) -} diff --git a/vendor/github.com/docker/docker/opts/throttledevice.go b/vendor/github.com/docker/docker/opts/throttledevice.go deleted file mode 100644 index 65dd3ebf68..0000000000 --- a/vendor/github.com/docker/docker/opts/throttledevice.go +++ /dev/null @@ -1,111 +0,0 @@ -package opts - -import ( - "fmt" - "strconv" - "strings" - - "github.com/docker/docker/api/types/blkiodev" - "github.com/docker/go-units" -) - -// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error. -type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error) - -// ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format. -func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) { - split := strings.SplitN(val, ":", 2) - if len(split) != 2 { - return nil, fmt.Errorf("bad format: %s", val) - } - if !strings.HasPrefix(split[0], "/dev/") { - return nil, fmt.Errorf("bad format for device path: %s", val) - } - rate, err := units.RAMInBytes(split[1]) - if err != nil { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :[]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) - } - if rate < 0 { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :[]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) - } - - return &blkiodev.ThrottleDevice{ - Path: split[0], - Rate: uint64(rate), - }, nil -} - -// ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format. -func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) { - split := strings.SplitN(val, ":", 2) - if len(split) != 2 { - return nil, fmt.Errorf("bad format: %s", val) - } - if !strings.HasPrefix(split[0], "/dev/") { - return nil, fmt.Errorf("bad format for device path: %s", val) - } - rate, err := strconv.ParseUint(split[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) - } - if rate < 0 { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) - } - - return &blkiodev.ThrottleDevice{ - Path: split[0], - Rate: uint64(rate), - }, nil -} - -// ThrottledeviceOpt defines a map of ThrottleDevices -type ThrottledeviceOpt struct { - values []*blkiodev.ThrottleDevice - validator ValidatorThrottleFctType -} - -// NewThrottledeviceOpt creates a new ThrottledeviceOpt -func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt { - values := []*blkiodev.ThrottleDevice{} - return ThrottledeviceOpt{ - values: values, - validator: validator, - } -} - -// Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt -func (opt *ThrottledeviceOpt) Set(val string) error { - var value *blkiodev.ThrottleDevice - if opt.validator != nil { - v, err := opt.validator(val) - if err != nil { - return err - } - value = v - } - (opt.values) = append((opt.values), value) - return nil -} - -// String returns ThrottledeviceOpt values as a string. -func (opt *ThrottledeviceOpt) String() string { - var out []string - for _, v := range opt.values { - out = append(out, v.String()) - } - - return fmt.Sprintf("%v", out) -} - -// GetList returns a slice of pointers to ThrottleDevices. -func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice { - var throttledevice []*blkiodev.ThrottleDevice - throttledevice = append(throttledevice, opt.values...) - - return throttledevice -} - -// Type returns the option type -func (opt *ThrottledeviceOpt) Type() string { - return "list" -} diff --git a/vendor/github.com/docker/docker/pkg/httputils/httputils.go b/vendor/github.com/docker/docker/pkg/httputils/httputils.go deleted file mode 100644 index af86835bd9..0000000000 --- a/vendor/github.com/docker/docker/pkg/httputils/httputils.go +++ /dev/null @@ -1,56 +0,0 @@ -package httputils - -import ( - "errors" - "fmt" - "net/http" - "regexp" - "strings" - - "github.com/docker/docker/pkg/jsonmessage" -) - -var ( - headerRegexp = regexp.MustCompile(`^(?:(.+)/(.+?))\((.+)\).*$`) - errInvalidHeader = errors.New("Bad header, should be in format `docker/version (platform)`") -) - -// Download requests a given URL and returns an io.Reader. -func Download(url string) (resp *http.Response, err error) { - if resp, err = http.Get(url); err != nil { - return nil, err - } - if resp.StatusCode >= 400 { - return nil, fmt.Errorf("Got HTTP status code >= 400: %s", resp.Status) - } - return resp, nil -} - -// NewHTTPRequestError returns a JSON response error. -func NewHTTPRequestError(msg string, res *http.Response) error { - return &jsonmessage.JSONError{ - Message: msg, - Code: res.StatusCode, - } -} - -// ServerHeader contains the server information. -type ServerHeader struct { - App string // docker - Ver string // 1.8.0-dev - OS string // windows or linux -} - -// ParseServerHeader extracts pieces from an HTTP server header -// which is in the format "docker/version (os)" e.g. docker/1.8.0-dev (windows). -func ParseServerHeader(hdr string) (*ServerHeader, error) { - matches := headerRegexp.FindStringSubmatch(hdr) - if len(matches) != 4 { - return nil, errInvalidHeader - } - return &ServerHeader{ - App: strings.TrimSpace(matches[1]), - Ver: strings.TrimSpace(matches[2]), - OS: strings.TrimSpace(matches[3]), - }, nil -} diff --git a/vendor/github.com/docker/docker/pkg/httputils/mimetype.go b/vendor/github.com/docker/docker/pkg/httputils/mimetype.go deleted file mode 100644 index abef9e9e83..0000000000 --- a/vendor/github.com/docker/docker/pkg/httputils/mimetype.go +++ /dev/null @@ -1,29 +0,0 @@ -package httputils - -import ( - "mime" - "net/http" -) - -// MimeTypes stores the MIME content type. -var MimeTypes = struct { - TextPlain string - OctetStream string -}{"text/plain", "application/octet-stream"} - -// DetectContentType returns a best guess representation of the MIME -// content type for the bytes at c. The value detected by -// http.DetectContentType is guaranteed not be nil, defaulting to -// application/octet-stream when a better guess cannot be made. The -// result of this detection is then run through mime.ParseMediaType() -// which separates the actual MIME string from any parameters. -func DetectContentType(c []byte) (string, map[string]string, error) { - - ct := http.DetectContentType(c) - contentType, args, err := mime.ParseMediaType(ct) - if err != nil { - return "", nil, err - } - - return contentType, args, nil -} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/multireader.go b/vendor/github.com/docker/docker/pkg/ioutils/multireader.go deleted file mode 100644 index edb043ddc3..0000000000 --- a/vendor/github.com/docker/docker/pkg/ioutils/multireader.go +++ /dev/null @@ -1,224 +0,0 @@ -package ioutils - -import ( - "bytes" - "fmt" - "io" - "os" -) - -type pos struct { - idx int - offset int64 -} - -type multiReadSeeker struct { - readers []io.ReadSeeker - pos *pos - posIdx map[io.ReadSeeker]int -} - -func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) { - var tmpOffset int64 - switch whence { - case os.SEEK_SET: - for i, rdr := range r.readers { - // get size of the current reader - s, err := rdr.Seek(0, os.SEEK_END) - if err != nil { - return -1, err - } - - if offset > tmpOffset+s { - if i == len(r.readers)-1 { - rdrOffset := s + (offset - tmpOffset) - if _, err := rdr.Seek(rdrOffset, os.SEEK_SET); err != nil { - return -1, err - } - r.pos = &pos{i, rdrOffset} - return offset, nil - } - - tmpOffset += s - continue - } - - rdrOffset := offset - tmpOffset - idx := i - - rdr.Seek(rdrOffset, os.SEEK_SET) - // make sure all following readers are at 0 - for _, rdr := range r.readers[i+1:] { - rdr.Seek(0, os.SEEK_SET) - } - - if rdrOffset == s && i != len(r.readers)-1 { - idx++ - rdrOffset = 0 - } - r.pos = &pos{idx, rdrOffset} - return offset, nil - } - case os.SEEK_END: - for _, rdr := range r.readers { - s, err := rdr.Seek(0, os.SEEK_END) - if err != nil { - return -1, err - } - tmpOffset += s - } - r.Seek(tmpOffset+offset, os.SEEK_SET) - return tmpOffset + offset, nil - case os.SEEK_CUR: - if r.pos == nil { - return r.Seek(offset, os.SEEK_SET) - } - // Just return the current offset - if offset == 0 { - return r.getCurOffset() - } - - curOffset, err := r.getCurOffset() - if err != nil { - return -1, err - } - rdr, rdrOffset, err := r.getReaderForOffset(curOffset + offset) - if err != nil { - return -1, err - } - - r.pos = &pos{r.posIdx[rdr], rdrOffset} - return curOffset + offset, nil - default: - return -1, fmt.Errorf("Invalid whence: %d", whence) - } - - return -1, fmt.Errorf("Error seeking for whence: %d, offset: %d", whence, offset) -} - -func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, int64, error) { - - var offsetTo int64 - - for _, rdr := range r.readers { - size, err := getReadSeekerSize(rdr) - if err != nil { - return nil, -1, err - } - if offsetTo+size > offset { - return rdr, offset - offsetTo, nil - } - if rdr == r.readers[len(r.readers)-1] { - return rdr, offsetTo + offset, nil - } - offsetTo += size - } - - return nil, 0, nil -} - -func (r *multiReadSeeker) getCurOffset() (int64, error) { - var totalSize int64 - for _, rdr := range r.readers[:r.pos.idx+1] { - if r.posIdx[rdr] == r.pos.idx { - totalSize += r.pos.offset - break - } - - size, err := getReadSeekerSize(rdr) - if err != nil { - return -1, fmt.Errorf("error getting seeker size: %v", err) - } - totalSize += size - } - return totalSize, nil -} - -func (r *multiReadSeeker) getOffsetToReader(rdr io.ReadSeeker) (int64, error) { - var offset int64 - for _, r := range r.readers { - if r == rdr { - break - } - - size, err := getReadSeekerSize(rdr) - if err != nil { - return -1, err - } - offset += size - } - return offset, nil -} - -func (r *multiReadSeeker) Read(b []byte) (int, error) { - if r.pos == nil { - // make sure all readers are at 0 - r.Seek(0, os.SEEK_SET) - } - - bLen := int64(len(b)) - buf := bytes.NewBuffer(nil) - var rdr io.ReadSeeker - - for _, rdr = range r.readers[r.pos.idx:] { - readBytes, err := io.CopyN(buf, rdr, bLen) - if err != nil && err != io.EOF { - return -1, err - } - bLen -= readBytes - - if bLen == 0 { - break - } - } - - rdrPos, err := rdr.Seek(0, os.SEEK_CUR) - if err != nil { - return -1, err - } - r.pos = &pos{r.posIdx[rdr], rdrPos} - return buf.Read(b) -} - -func getReadSeekerSize(rdr io.ReadSeeker) (int64, error) { - // save the current position - pos, err := rdr.Seek(0, os.SEEK_CUR) - if err != nil { - return -1, err - } - - // get the size - size, err := rdr.Seek(0, os.SEEK_END) - if err != nil { - return -1, err - } - - // reset the position - if _, err := rdr.Seek(pos, os.SEEK_SET); err != nil { - return -1, err - } - return size, nil -} - -// MultiReadSeeker returns a ReadSeeker that's the logical concatenation of the provided -// input readseekers. After calling this method the initial position is set to the -// beginning of the first ReadSeeker. At the end of a ReadSeeker, Read always advances -// to the beginning of the next ReadSeeker and returns EOF at the end of the last ReadSeeker. -// Seek can be used over the sum of lengths of all readseekers. -// -// When a MultiReadSeeker is used, no Read and Seek operations should be made on -// its ReadSeeker components. Also, users should make no assumption on the state -// of individual readseekers while the MultiReadSeeker is used. -func MultiReadSeeker(readers ...io.ReadSeeker) io.ReadSeeker { - if len(readers) == 1 { - return readers[0] - } - idx := make(map[io.ReadSeeker]int) - for i, rdr := range readers { - idx[rdr] = i - } - return &multiReadSeeker{ - readers: readers, - posIdx: idx, - } -} diff --git a/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go b/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go index ebbded77c8..50234affc0 100644 --- a/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go +++ b/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go @@ -13,7 +13,7 @@ import ( import "C" // Termios is the Unix API for terminal I/O. -// It is passthrough for syscall.Termios in order to make it portable with +// It is passthrough for unix.Termios in order to make it portable with // other platforms where it is not available or handled differently. type Termios unix.Termios @@ -28,11 +28,11 @@ func MakeRaw(fd uintptr) (*State, error) { newState := oldState.termios - newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON | syscall.IXANY) - newState.Oflag &^= syscall.OPOST - newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN) - newState.Cflag &^= (syscall.CSIZE | syscall.PARENB) - newState.Cflag |= syscall.CS8 + newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON | unix.IXANY) + newState.Oflag &^= unix.OPOST + newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) + newState.Cflag &^= (unix.CSIZE | unix.PARENB) + newState.Cflag |= unix.CS8 /* VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned diff --git a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go index c47341e873..9fdc720f25 100644 --- a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go +++ b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go @@ -27,7 +27,7 @@ func MakeRaw(fd uintptr) (*State, error) { newState := oldState.termios newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) - newState.Oflag &^= unix.OPOST + newState.Oflag |= unix.OPOST newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) newState.Cflag &^= (unix.CSIZE | unix.PARENB) newState.Cflag |= unix.CS8 diff --git a/vendor/github.com/docker/docker/pkg/httputils/resumablerequestreader.go b/vendor/github.com/docker/docker/registry/resumable/resumablerequestreader.go similarity index 66% rename from vendor/github.com/docker/docker/pkg/httputils/resumablerequestreader.go rename to vendor/github.com/docker/docker/registry/resumable/resumablerequestreader.go index de488fb531..5403c76847 100644 --- a/vendor/github.com/docker/docker/pkg/httputils/resumablerequestreader.go +++ b/vendor/github.com/docker/docker/registry/resumable/resumablerequestreader.go @@ -1,4 +1,4 @@ -package httputils +package resumable import ( "fmt" @@ -9,7 +9,7 @@ import ( "github.com/Sirupsen/logrus" ) -type resumableRequestReader struct { +type requestReader struct { client *http.Client request *http.Request lastRange int64 @@ -20,22 +20,22 @@ type resumableRequestReader struct { waitDuration time.Duration } -// ResumableRequestReader makes it possible to resume reading a request's body transparently +// NewRequestReader makes it possible to resume reading a request's body transparently // maxfail is the number of times we retry to make requests again (not resumes) // totalsize is the total length of the body; auto detect if not provided -func ResumableRequestReader(c *http.Client, r *http.Request, maxfail uint32, totalsize int64) io.ReadCloser { - return &resumableRequestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize, waitDuration: 5 * time.Second} +func NewRequestReader(c *http.Client, r *http.Request, maxfail uint32, totalsize int64) io.ReadCloser { + return &requestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize, waitDuration: 5 * time.Second} } -// ResumableRequestReaderWithInitialResponse makes it possible to resume +// NewRequestReaderWithInitialResponse makes it possible to resume // reading the body of an already initiated request. -func ResumableRequestReaderWithInitialResponse(c *http.Client, r *http.Request, maxfail uint32, totalsize int64, initialResponse *http.Response) io.ReadCloser { - return &resumableRequestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize, currentResponse: initialResponse, waitDuration: 5 * time.Second} +func NewRequestReaderWithInitialResponse(c *http.Client, r *http.Request, maxfail uint32, totalsize int64, initialResponse *http.Response) io.ReadCloser { + return &requestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize, currentResponse: initialResponse, waitDuration: 5 * time.Second} } -func (r *resumableRequestReader) Read(p []byte) (n int, err error) { +func (r *requestReader) Read(p []byte) (n int, err error) { if r.client == nil || r.request == nil { - return 0, fmt.Errorf("client and request can't be nil\n") + return 0, fmt.Errorf("client and request can't be nil") } isFreshRequest := false if r.lastRange != 0 && r.currentResponse == nil { @@ -81,14 +81,14 @@ func (r *resumableRequestReader) Read(p []byte) (n int, err error) { return n, err } -func (r *resumableRequestReader) Close() error { +func (r *requestReader) Close() error { r.cleanUpResponse() r.client = nil r.request = nil return nil } -func (r *resumableRequestReader) cleanUpResponse() { +func (r *requestReader) cleanUpResponse() { if r.currentResponse != nil { r.currentResponse.Body.Close() r.currentResponse = nil diff --git a/vendor/github.com/docker/docker/registry/session.go b/vendor/github.com/docker/docker/registry/session.go index c71e778037..746b8fb5b5 100644 --- a/vendor/github.com/docker/docker/registry/session.go +++ b/vendor/github.com/docker/docker/registry/session.go @@ -23,10 +23,11 @@ import ( "github.com/docker/distribution/registry/api/errcode" "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/pkg/httputils" "github.com/docker/docker/pkg/ioutils" + "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/tarsum" + "github.com/docker/docker/registry/resumable" ) var ( @@ -226,7 +227,7 @@ func (r *Session) GetRemoteHistory(imgID, registry string) ([]string, error) { if res.StatusCode == 401 { return nil, errcode.ErrorCodeUnauthorized.WithArgs() } - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch remote history for %s", res.StatusCode, imgID), res) + return nil, newJSONError(fmt.Sprintf("Server error: %d trying to fetch remote history for %s", res.StatusCode, imgID), res) } var history []string @@ -246,7 +247,7 @@ func (r *Session) LookupRemoteImage(imgID, registry string) error { } res.Body.Close() if res.StatusCode != 200 { - return httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d", res.StatusCode), res) + return newJSONError(fmt.Sprintf("HTTP code %d", res.StatusCode), res) } return nil } @@ -259,7 +260,7 @@ func (r *Session) GetRemoteImageJSON(imgID, registry string) ([]byte, int64, err } defer res.Body.Close() if res.StatusCode != 200 { - return nil, -1, httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d", res.StatusCode), res) + return nil, -1, newJSONError(fmt.Sprintf("HTTP code %d", res.StatusCode), res) } // if the size header is not present, then set it to '-1' imageSize := int64(-1) @@ -313,7 +314,7 @@ func (r *Session) GetRemoteImageLayer(imgID, registry string, imgSize int64) (io if res.Header.Get("Accept-Ranges") == "bytes" && imgSize > 0 { logrus.Debug("server supports resume") - return httputils.ResumableRequestReaderWithInitialResponse(r.client, req, 5, imgSize, res), nil + return resumable.NewRequestReaderWithInitialResponse(r.client, req, 5, imgSize, res), nil } logrus.Debug("server doesn't support resume") return res.Body, nil @@ -444,13 +445,13 @@ func (r *Session) GetRepositoryData(name reference.Named) (*RepositoryData, erro // TODO: Right now we're ignoring checksums in the response body. // In the future, we need to use them to check image validity. if res.StatusCode == 404 { - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code: %d", res.StatusCode), res) + return nil, newJSONError(fmt.Sprintf("HTTP code: %d", res.StatusCode), res) } else if res.StatusCode != 200 { errBody, err := ioutil.ReadAll(res.Body) if err != nil { logrus.Debugf("Error reading response body: %s", err) } - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Error: Status %d trying to pull repository %s: %q", res.StatusCode, reference.Path(name), errBody), res) + return nil, newJSONError(fmt.Sprintf("Error: Status %d trying to pull repository %s: %q", res.StatusCode, reference.Path(name), errBody), res) } var endpoints []string @@ -537,12 +538,12 @@ func (r *Session) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, regist } defer res.Body.Close() if res.StatusCode == 401 && strings.HasPrefix(registry, "http://") { - return httputils.NewHTTPRequestError("HTTP code 401, Docker will not send auth headers over HTTP.", res) + return newJSONError("HTTP code 401, Docker will not send auth headers over HTTP.", res) } if res.StatusCode != 200 { errBody, err := ioutil.ReadAll(res.Body) if err != nil { - return httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res) + return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res) } var jsonBody map[string]string if err := json.Unmarshal(errBody, &jsonBody); err != nil { @@ -550,7 +551,7 @@ func (r *Session) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, regist } else if jsonBody["error"] == "Image already exists" { return ErrAlreadyExists } - return httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d while uploading metadata: %q", res.StatusCode, errBody), res) + return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata: %q", res.StatusCode, errBody), res) } return nil } @@ -591,9 +592,9 @@ func (r *Session) PushImageLayerRegistry(imgID string, layer io.Reader, registry if res.StatusCode != 200 { errBody, err := ioutil.ReadAll(res.Body) if err != nil { - return "", "", httputils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res) + return "", "", newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res) } - return "", "", httputils.NewHTTPRequestError(fmt.Sprintf("Received HTTP code %d while uploading layer: %q", res.StatusCode, errBody), res) + return "", "", newJSONError(fmt.Sprintf("Received HTTP code %d while uploading layer: %q", res.StatusCode, errBody), res) } checksumPayload = "sha256:" + hex.EncodeToString(h.Sum(nil)) @@ -619,7 +620,7 @@ func (r *Session) PushRegistryTag(remote reference.Named, revision, tag, registr } res.Body.Close() if res.StatusCode != 200 && res.StatusCode != 201 { - return httputils.NewHTTPRequestError(fmt.Sprintf("Internal server error: %d trying to push tag %s on %s", res.StatusCode, tag, reference.Path(remote)), res) + return newJSONError(fmt.Sprintf("Internal server error: %d trying to push tag %s on %s", res.StatusCode, tag, reference.Path(remote)), res) } return nil } @@ -683,7 +684,7 @@ func (r *Session) PushImageJSONIndex(remote reference.Named, imgList []*ImgData, if err != nil { logrus.Debugf("Error reading response body: %s", err) } - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Error: Status %d trying to push repository %s: %q", res.StatusCode, reference.Path(remote), errBody), res) + return nil, newJSONError(fmt.Sprintf("Error: Status %d trying to push repository %s: %q", res.StatusCode, reference.Path(remote), errBody), res) } tokens = res.Header["X-Docker-Token"] logrus.Debugf("Auth token: %v", tokens) @@ -701,7 +702,7 @@ func (r *Session) PushImageJSONIndex(remote reference.Named, imgList []*ImgData, if err != nil { logrus.Debugf("Error reading response body: %s", err) } - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Error: Status %d trying to push checksums %s: %q", res.StatusCode, reference.Path(remote), errBody), res) + return nil, newJSONError(fmt.Sprintf("Error: Status %d trying to push checksums %s: %q", res.StatusCode, reference.Path(remote), errBody), res) } } @@ -750,7 +751,7 @@ func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.Sea } defer res.Body.Close() if res.StatusCode != 200 { - return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Unexpected status code %d", res.StatusCode), res) + return nil, newJSONError(fmt.Sprintf("Unexpected status code %d", res.StatusCode), res) } result := new(registrytypes.SearchResults) return result, json.NewDecoder(res.Body).Decode(result) @@ -781,3 +782,10 @@ func isTimeout(err error) bool { t, ok := e.(timeout) return ok && t.Timeout() } + +func newJSONError(msg string, res *http.Response) error { + return &jsonmessage.JSONError{ + Message: msg, + Code: res.StatusCode, + } +} diff --git a/vendor/github.com/docker/docker/runconfig/hostconfig.go b/vendor/github.com/docker/docker/runconfig/hostconfig.go index e8eede1505..24aed1935e 100644 --- a/vendor/github.com/docker/docker/runconfig/hostconfig.go +++ b/vendor/github.com/docker/docker/runconfig/hostconfig.go @@ -45,7 +45,7 @@ func validateNetContainerMode(c *container.Config, hc *container.HostConfig) err parts := strings.Split(string(hc.NetworkMode), ":") if parts[0] == "container" { if len(parts) < 2 || parts[1] == "" { - return fmt.Errorf("--net: invalid net mode: invalid container format container:") + return fmt.Errorf("Invalid network mode: invalid container format container:") } } diff --git a/vendor/github.com/docker/docker/runconfig/hostconfig_unix.go b/vendor/github.com/docker/docker/runconfig/hostconfig_unix.go index a60daa8787..55df5da3ff 100644 --- a/vendor/github.com/docker/docker/runconfig/hostconfig_unix.go +++ b/vendor/github.com/docker/docker/runconfig/hostconfig_unix.go @@ -55,7 +55,7 @@ func validateIsolation(hc *container.HostConfig) error { return nil } if !hc.Isolation.IsValid() { - return fmt.Errorf("invalid --isolation: %q - %s only supports 'default'", hc.Isolation, runtime.GOOS) + return fmt.Errorf("Invalid isolation: %q - %s only supports 'default'", hc.Isolation, runtime.GOOS) } return nil } @@ -68,11 +68,11 @@ func validateQoS(hc *container.HostConfig) error { } if hc.IOMaximumBandwidth != 0 { - return fmt.Errorf("invalid QoS settings: %s does not support --io-maxbandwidth", runtime.GOOS) + return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum bandwidth", runtime.GOOS) } if hc.IOMaximumIOps != 0 { - return fmt.Errorf("invalid QoS settings: %s does not support --io-maxiops", runtime.GOOS) + return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum IOPs", runtime.GOOS) } return nil } @@ -86,15 +86,15 @@ func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error { } if hc.Resources.CPURealtimePeriod > 0 && !si.CPURealtimePeriod { - return fmt.Errorf("invalid --cpu-rt-period: Your kernel does not support cgroup rt period") + return fmt.Errorf("Your kernel does not support cgroup cpu real-time period") } if hc.Resources.CPURealtimeRuntime > 0 && !si.CPURealtimeRuntime { - return fmt.Errorf("invalid --cpu-rt-runtime: Your kernel does not support cgroup rt runtime") + return fmt.Errorf("Your kernel does not support cgroup cpu real-time runtime") } if hc.Resources.CPURealtimePeriod != 0 && hc.Resources.CPURealtimeRuntime != 0 && hc.Resources.CPURealtimeRuntime > hc.Resources.CPURealtimePeriod { - return fmt.Errorf("invalid --cpu-rt-runtime: rt runtime cannot be higher than rt period") + return fmt.Errorf("cpu real-time runtime cannot be higher than cpu real-time period") } return nil } diff --git a/vendor/github.com/docker/docker/runconfig/hostconfig_windows.go b/vendor/github.com/docker/docker/runconfig/hostconfig_windows.go index 9ca93ae508..5eb956d1b4 100644 --- a/vendor/github.com/docker/docker/runconfig/hostconfig_windows.go +++ b/vendor/github.com/docker/docker/runconfig/hostconfig_windows.go @@ -31,7 +31,7 @@ func validateNetMode(c *container.Config, hc *container.HostConfig) error { } if hc.NetworkMode.IsContainer() && hc.Isolation.IsHyperV() { - return fmt.Errorf("net mode --net=container: unsupported for hyperv isolation") + return fmt.Errorf("Using the network stack of another container is not supported while using Hyper-V Containers") } return nil @@ -46,7 +46,7 @@ func validateIsolation(hc *container.HostConfig) error { return nil } if !hc.Isolation.IsValid() { - return fmt.Errorf("invalid --isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation) + return fmt.Errorf("Invalid isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation) } return nil } @@ -63,10 +63,10 @@ func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error { return nil } if hc.Resources.CPURealtimePeriod != 0 { - return fmt.Errorf("invalid --cpu-rt-period: Windows does not support this feature") + return fmt.Errorf("Windows does not support CPU real-time period") } if hc.Resources.CPURealtimeRuntime != 0 { - return fmt.Errorf("invalid --cpu-rt-runtime: Windows does not support this feature") + return fmt.Errorf("Windows does not support CPU real-time runtime") } return nil } @@ -78,7 +78,7 @@ func validatePrivileged(hc *container.HostConfig) error { return nil } if hc.Privileged { - return fmt.Errorf("invalid --privileged: Windows does not support this feature") + return fmt.Errorf("Windows does not support privileged mode") } return nil } @@ -90,7 +90,7 @@ func validateReadonlyRootfs(hc *container.HostConfig) error { return nil } if hc.ReadonlyRootfs { - return fmt.Errorf("invalid --read-only: Windows does not support this feature") + return fmt.Errorf("Windows does not support root filesystem in read-only mode") } return nil } diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf index df4aa7e1e8..35708e168c 100644 --- a/vendor/github.com/docker/docker/vendor.conf +++ b/vendor/github.com/docker/docker/vendor.conf @@ -1,7 +1,7 @@ # the following lines are in sorted order, FYI github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62 github.com/Microsoft/hcsshim v0.5.17 -github.com/Microsoft/go-winio v0.4.0 +github.com/Microsoft/go-winio v0.4.2 github.com/Sirupsen/logrus v0.11.0 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a @@ -26,7 +26,7 @@ github.com/imdario/mergo 0.2.1 golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0 #get libnetwork packages -github.com/docker/libnetwork b2bc1a68486ccf8ada503162d9f0df7d31bdd8fb +github.com/docker/libnetwork 83e1e49475b88a9f1f8ba89a690a7d5de42e24b9 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec @@ -62,8 +62,8 @@ github.com/miekg/pkcs11 df8ae6ca730422dba20c768ff38ef7d79077a59f # When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly github.com/opencontainers/runc 992a5be178a62e026f4069f443c6164912adbf09 -github.com/opencontainers/runtime-spec v1.0.0-rc5 # specs github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe +github.com/opencontainers/runtime-spec d42f1eb741e6361e858d83fc75aa6893b66292c4 # specs github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 @@ -99,15 +99,12 @@ cloud.google.com/go 9d965e63e8cceb1b5d7977a202f0fcb8866d6525 github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7 google.golang.org/genproto b3e7c2fb04031add52c4817f53f43757ccbf9c18 -# native credentials -github.com/docker/docker-credential-helpers v0.5.0 - # containerd github.com/containerd/containerd 3addd840653146c90a254301d6c3a663c7fd6429 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 # cluster -github.com/docker/swarmkit 1a3e510517be82d18ac04380b5f71eddf06c2fc0 +github.com/docker/swarmkit eb07af52aa2216100cff1ad0b13df48daa8914bf github.com/gogo/protobuf v0.4 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e diff --git a/vendor/github.com/docker/docker/volume/volume.go b/vendor/github.com/docker/docker/volume/volume.go index 5135605281..ef362370e5 100644 --- a/vendor/github.com/docker/docker/volume/volume.go +++ b/vendor/github.com/docker/docker/volume/volume.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" "syscall" + "time" mounttypes "github.com/docker/docker/api/types/mount" "github.com/docker/docker/pkg/idtools" @@ -64,6 +65,8 @@ type Volume interface { Mount(id string) (string, error) // Unmount unmounts the volume when it is no longer in use. Unmount(id string) error + // CreatedAt returns Volume Creation time + CreatedAt() (time.Time, error) // Status returns low-level status information about a volume Status() map[string]interface{} } diff --git a/vendor/github.com/docker/libnetwork/LICENSE b/vendor/github.com/docker/libnetwork/LICENSE deleted file mode 100644 index e06d208186..0000000000 --- a/vendor/github.com/docker/libnetwork/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. - diff --git a/vendor/github.com/docker/libnetwork/README.md b/vendor/github.com/docker/libnetwork/README.md deleted file mode 100644 index 536f8aa2b3..0000000000 --- a/vendor/github.com/docker/libnetwork/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# libnetwork - networking for containers - -[![Circle CI](https://circleci.com/gh/docker/libnetwork/tree/master.svg?style=svg)](https://circleci.com/gh/docker/libnetwork/tree/master) [![Coverage Status](https://coveralls.io/repos/docker/libnetwork/badge.svg)](https://coveralls.io/r/docker/libnetwork) [![GoDoc](https://godoc.org/github.com/docker/libnetwork?status.svg)](https://godoc.org/github.com/docker/libnetwork) - -Libnetwork provides a native Go implementation for connecting containers - -The goal of libnetwork is to deliver a robust Container Network Model that provides a consistent programming interface and the required network abstractions for applications. - -#### Design -Please refer to the [design](docs/design.md) for more information. - -#### Using libnetwork - -There are many networking solutions available to suit a broad range of use-cases. libnetwork uses a driver / plugin model to support all of these solutions while abstracting the complexity of the driver implementations by exposing a simple and consistent Network Model to users. - - -```go -func main() { - if reexec.Init() { - return - } - - // Select and configure the network driver - networkType := "bridge" - - // Create a new controller instance - driverOptions := options.Generic{} - genericOption := make(map[string]interface{}) - genericOption[netlabel.GenericData] = driverOptions - controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption)) - if err != nil { - log.Fatalf("libnetwork.New: %s", err) - } - - // Create a network for containers to join. - // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can use. - network, err := controller.NewNetwork(networkType, "network1", "") - if err != nil { - log.Fatalf("controller.NewNetwork: %s", err) - } - - // For each new container: allocate IP and interfaces. The returned network - // settings will be used for container infos (inspect and such), as well as - // iptables rules for port publishing. This info is contained or accessible - // from the returned endpoint. - ep, err := network.CreateEndpoint("Endpoint1") - if err != nil { - log.Fatalf("network.CreateEndpoint: %s", err) - } - - // Create the sandbox for the container. - // NewSandbox accepts Variadic optional arguments which libnetwork can use. - sbx, err := controller.NewSandbox("container1", - libnetwork.OptionHostname("test"), - libnetwork.OptionDomainname("docker.io")) - if err != nil { - log.Fatalf("controller.NewSandbox: %s", err) - } - - // A sandbox can join the endpoint via the join api. - err = ep.Join(sbx) - if err != nil { - log.Fatalf("ep.Join: %s", err) - } - - // libnetwork client can check the endpoint's operational data via the Info() API - epInfo, err := ep.DriverInfo() - if err != nil { - log.Fatalf("ep.DriverInfo: %s", err) - } - - macAddress, ok := epInfo[netlabel.MacAddress] - if !ok { - log.Fatalf("failed to get mac address from endpoint info") - } - - fmt.Printf("Joined endpoint %s (%s) to sandbox %s (%s)\n", ep.Name(), macAddress, sbx.ContainerID(), sbx.Key()) -} -``` - -## Future -Please refer to [roadmap](ROADMAP.md) for more information. - -## Contributing - -Want to hack on libnetwork? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. - -## Copyright and license -Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons. diff --git a/vendor/github.com/docker/libnetwork/resolvconf/README.md b/vendor/github.com/docker/libnetwork/resolvconf/README.md deleted file mode 100644 index cdda554ba5..0000000000 --- a/vendor/github.com/docker/libnetwork/resolvconf/README.md +++ /dev/null @@ -1 +0,0 @@ -Package resolvconf provides utility code to query and update DNS configuration in /etc/resolv.conf diff --git a/vendor/github.com/docker/libnetwork/resolvconf/dns/resolvconf.go b/vendor/github.com/docker/libnetwork/resolvconf/dns/resolvconf.go deleted file mode 100644 index e348bc57f5..0000000000 --- a/vendor/github.com/docker/libnetwork/resolvconf/dns/resolvconf.go +++ /dev/null @@ -1,26 +0,0 @@ -package dns - -import ( - "regexp" -) - -// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range. -const IPLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)` - -// IPv4Localhost is a regex pattern for IPv4 localhost address range. -const IPv4Localhost = `(127\.([0-9]{1,3}\.){2}[0-9]{1,3})` - -var localhostIPRegexp = regexp.MustCompile(IPLocalhost) -var localhostIPv4Regexp = regexp.MustCompile(IPv4Localhost) - -// IsLocalhost returns true if ip matches the localhost IP regular expression. -// Used for determining if nameserver settings are being passed which are -// localhost addresses -func IsLocalhost(ip string) bool { - return localhostIPRegexp.MatchString(ip) -} - -// IsIPv4Localhost returns true if ip matches the IPv4 localhost regular expression. -func IsIPv4Localhost(ip string) bool { - return localhostIPv4Regexp.MatchString(ip) -} diff --git a/vendor/github.com/docker/libnetwork/vendor.conf b/vendor/github.com/docker/libnetwork/vendor.conf deleted file mode 100644 index 45f2784192..0000000000 --- a/vendor/github.com/docker/libnetwork/vendor.conf +++ /dev/null @@ -1,42 +0,0 @@ -github.com/Azure/go-ansiterm 04b7f292a41fcb5da32dda536c0807fc13e8351c -github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060 -github.com/Microsoft/go-winio ce2922f643c8fd76b46cadc7f404a06282678b34 -github.com/Microsoft/hcsshim e439b7d2b63f036d3a50c93a9e0b154a0d50e788 -github.com/Sirupsen/logrus 4b6ea7319e214d98c938f12692336f7ca9348d6b -github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec -github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 -github.com/boltdb/bolt c6ba97b89e0454fec9aa92e1d33a4e2c5fc1f631 -github.com/codegangsta/cli a65b733b303f0055f8d324d805f393cd3e7a7904 -github.com/coreos/etcd 925d1d74cec8c3b169c52fd4b2dc234a35934fce -github.com/coreos/go-systemd b4a58d95188dd092ae20072bac14cece0e67c388 -github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d - -github.com/docker/docker 9c96768eae4b3a65147b47a55c850c103ab8972d -github.com/docker/go-connections 34b5052da6b11e27f5f2e357b38b571ddddd3928 -github.com/docker/go-events 2e7d352816128aa84f4d29b2a21d400133701a0d -github.com/docker/go-units 8e2d4523730c73120e10d4652f36ad6010998f4e -github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef - -github.com/godbus/dbus 5f6efc7ef2759c81b7ba876593971bfce311eab3 -github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2 -github.com/golang/protobuf/proto f7137ae6b19afbfd61a94b746fda3b3fe0491874 -github.com/gorilla/context 215affda49addc4c8ef7e2534915df2c8c35c6cd -github.com/gorilla/mux 8096f47503459bcc74d1f4c487b7e6e42e5746b5 -github.com/hashicorp/consul/api 954aec66231b79c161a4122b023fbcad13047f79 -github.com/hashicorp/go-msgpack/codec 71c2886f5a673a35f909803f38ece5810165097b -github.com/hashicorp/go-multierror 2167c8ec40776024589f483a6b836489e47e1049 -github.com/hashicorp/memberlist 88ac4de0d1a0ca6def284b571342db3b777a4c37 -github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 -github.com/mattn/go-shellwords 525bedee691b5a8df547cb5cf9f86b7fb1883e24 -github.com/miekg/dns d27455715200c7d3e321a1e5cadb27c9ee0b0f02 -github.com/opencontainers/runc/libcontainer ba1568de399395774ad84c2ace65937814c542ed -github.com/samuel/go-zookeeper/zk d0e0d8e11f318e000a8cc434616d69e329edc374 -github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1 -github.com/stretchr/testify dab07ac62d4905d3e48d17dc549c684ac3b7c15a -github.com/syndtr/gocapability/capability 2c00daeb6c3b45114c80ac44119e7b8801fdd852 -github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065 -github.com/vishvananda/netlink 1e86b2bee5b6a7d377e4c02bb7f98209d6a7297c -github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25 -golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 -golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 -github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9