diff --git a/cli/cobra.go b/cli/cobra.go
index 11d2fdc420..7f35abe50c 100644
--- a/cli/cobra.go
+++ b/cli/cobra.go
@@ -3,12 +3,15 @@ package cli
import (
"fmt"
"os"
+ "path/filepath"
"strings"
pluginmanager "github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
cliflags "github.com/docker/cli/cli/flags"
+ "github.com/docker/docker/pkg/homedir"
+ "github.com/docker/docker/registry"
"github.com/moby/term"
"github.com/morikuni/aec"
"github.com/pkg/errors"
@@ -52,6 +55,13 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *p
rootCmd.Annotations = map[string]string{"additionalHelp": "To get more help with docker, check out our guides at https://docs.docker.com/go/guides/"}
+ // Configure registry.CertsDir() when running in rootless-mode
+ if os.Getenv("ROOTLESSKIT_STATE_DIR") != "" {
+ if configHome, err := homedir.GetConfigHome(); err == nil {
+ registry.SetCertsDir(filepath.Join(configHome, "docker/certs.d"))
+ }
+ }
+
return opts, flags, helpCommand
}
diff --git a/cli/command/registry/search.go b/cli/command/registry/search.go
index 42637ae454..3827424386 100644
--- a/cli/command/registry/search.go
+++ b/cli/command/registry/search.go
@@ -38,7 +38,8 @@ func NewSearchCommand(dockerCli command.Cli) *cobra.Command {
flags.BoolVar(&options.noTrunc, "no-trunc", false, "Don't truncate output")
flags.VarP(&options.filter, "filter", "f", "Filter output based on conditions provided")
- flags.IntVar(&options.limit, "limit", registry.DefaultSearchLimit, "Max number of search results")
+ // TODO(thaJeztah) remove default from client as the daemon already has a default
+ flags.IntVar(&options.limit, "limit", 25, "Max number of search results")
flags.StringVar(&options.format, "format", "", "Pretty-print search using a Go template")
return cmd
diff --git a/cli/command/system/testdata/docker-info-badsec.json.golden b/cli/command/system/testdata/docker-info-badsec.json.golden
index 3fc32aeef3..7eb4e93f6f 100644
--- a/cli/command/system/testdata/docker-info-badsec.json.golden
+++ b/cli/command/system/testdata/docker-info-badsec.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["foo="],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ServerErrors":["a server error occurred"],"ClientInfo":{"Debug":false,"Context":"","Plugins":[],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["foo="],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ServerErrors":["a server error occurred"],"ClientInfo":{"Debug":false,"Context":"","Plugins":[],"Warnings":null}}
diff --git a/cli/command/system/testdata/docker-info-daemon-warnings.json.golden b/cli/command/system/testdata/docker-info-daemon-warnings.json.golden
index 09e1ebd9c5..8bf4523577 100644
--- a/cli/command/system/testdata/docker-info-daemon-warnings.json.golden
+++ b/cli/command/system/testdata/docker-info-daemon-warnings.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
diff --git a/cli/command/system/testdata/docker-info-legacy-warnings.json.golden b/cli/command/system/testdata/docker-info-legacy-warnings.json.golden
index 395624beaa..d06446962d 100644
--- a/cli/command/system/testdata/docker-info-legacy-warnings.json.golden
+++ b/cli/command/system/testdata/docker-info-legacy-warnings.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":false,"SwapLimit":false,"KernelMemory":false,"KernelMemoryTCP":false,"CpuCfsPeriod":false,"CpuCfsQuota":false,"CPUShares":false,"CPUSet":false,"PidsLimit":false,"IPv4Forwarding":false,"BridgeNfIptables":false,"BridgeNfIp6tables":false,"Debug":true,"NFd":33,"OomKillDisable":false,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":false,"SwapLimit":false,"CpuCfsPeriod":false,"CpuCfsQuota":false,"CPUShares":false,"CPUSet":false,"PidsLimit":false,"IPv4Forwarding":false,"BridgeNfIptables":false,"BridgeNfIp6tables":false,"Debug":true,"NFd":33,"OomKillDisable":false,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
diff --git a/cli/command/system/testdata/docker-info-no-swarm.json.golden b/cli/command/system/testdata/docker-info-no-swarm.json.golden
index b48fa06024..d11ef2c2db 100644
--- a/cli/command/system/testdata/docker-info-no-swarm.json.golden
+++ b/cli/command/system/testdata/docker-info-no-swarm.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
diff --git a/cli/command/system/testdata/docker-info-plugins.json.golden b/cli/command/system/testdata/docker-info-plugins.json.golden
index ff41ecc3fb..e1d5123ccf 100644
--- a/cli/command/system/testdata/docker-info-plugins.json.golden
+++ b/cli/command/system/testdata/docker-info-plugins.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","Version":"0.1.0","ShortDescription":"unit test is good","Name":"goodplugin","Path":"/path/to/docker-goodplugin"},{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","ShortDescription":"this plugin has no version","Name":"unversionedplugin","Path":"/path/to/docker-unversionedplugin"},{"Name":"badplugin","Path":"/path/to/docker-badplugin","Err":"something wrong"}],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","Version":"0.1.0","ShortDescription":"unit test is good","Name":"goodplugin","Path":"/path/to/docker-goodplugin"},{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","ShortDescription":"this plugin has no version","Name":"unversionedplugin","Path":"/path/to/docker-unversionedplugin"},{"Name":"badplugin","Path":"/path/to/docker-badplugin","Err":"something wrong"}],"Warnings":null}}
diff --git a/cli/command/system/testdata/docker-info-with-swarm.json.golden b/cli/command/system/testdata/docker-info-with-swarm.json.golden
index bd2a0c363b..bd9a7483ee 100644
--- a/cli/command/system/testdata/docker-info-with-swarm.json.golden
+++ b/cli/command/system/testdata/docker-info-with-swarm.json.golden
@@ -1 +1 @@
-{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"qo2dfdig9mmxqkawulggepdih","NodeAddr":"165.227.107.89","LocalNodeState":"active","ControlAvailable":true,"Error":"","RemoteManagers":[{"NodeID":"qo2dfdig9mmxqkawulggepdih","Addr":"165.227.107.89:2377"}],"Nodes":1,"Managers":1,"Cluster":{"ID":"9vs5ygs0gguyyec4iqf2314c0","Version":{"Index":11},"CreatedAt":"2017-08-24T17:34:19.278062352Z","UpdatedAt":"2017-08-24T17:34:42.398815481Z","Spec":{"Name":"default","Labels":null,"Orchestration":{"TaskHistoryRetentionLimit":5},"Raft":{"SnapshotInterval":10000,"KeepOldSnapshots":0,"LogEntriesForSlowFollowers":500,"ElectionTick":3,"HeartbeatTick":1},"Dispatcher":{"HeartbeatPeriod":5000000000},"CAConfig":{"NodeCertExpiry":7776000000000000},"TaskDefaults":{},"EncryptionConfig":{"AutoLockManagers":true}},"TLSInfo":{"TrustRoot":"\n-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUaFCW5xsq8eyiJ+Pmcv3MCflMLnMwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwODI0MTcyOTAwWhcNMzcwODE5MTcy\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABDy7NebyUJyUjWJDBUdnZoV6GBxEGKO4TZPNDwnxDxJcUdLVaB7WGa4/DLrW\nUfsVgh1JGik2VTiLuTMA1tLlNPOjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQl16XFtaaXiUAwEuJptJlDjfKskDAKBggqhkjO\nPQQDAgNIADBFAiEAo9fTQNM5DP9bHVcTJYfl2Cay1bFu1E+lnpmN+EYJfeACIGKH\n1pCUkZ+D0IB6CiEZGWSHyLuXPM1rlP+I5KuS7sB8\n-----END CERTIFICATE-----\n","CertIssuerSubject":"MBMxETAPBgNVBAMTCHN3YXJtLWNh","CertIssuerPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPLs15vJQnJSNYkMFR2dmhXoYHEQYo7hNk80PCfEPElxR0tVoHtYZrj8MutZR+xWCHUkaKTZVOIu5MwDW0uU08w=="},"RootRotationInProgress":false,"DefaultAddrPool":null,"SubnetSize":0,"DataPathPort":0}},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[],"Warnings":null}}
+{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"qo2dfdig9mmxqkawulggepdih","NodeAddr":"165.227.107.89","LocalNodeState":"active","ControlAvailable":true,"Error":"","RemoteManagers":[{"NodeID":"qo2dfdig9mmxqkawulggepdih","Addr":"165.227.107.89:2377"}],"Nodes":1,"Managers":1,"Cluster":{"ID":"9vs5ygs0gguyyec4iqf2314c0","Version":{"Index":11},"CreatedAt":"2017-08-24T17:34:19.278062352Z","UpdatedAt":"2017-08-24T17:34:42.398815481Z","Spec":{"Name":"default","Labels":null,"Orchestration":{"TaskHistoryRetentionLimit":5},"Raft":{"SnapshotInterval":10000,"KeepOldSnapshots":0,"LogEntriesForSlowFollowers":500,"ElectionTick":3,"HeartbeatTick":1},"Dispatcher":{"HeartbeatPeriod":5000000000},"CAConfig":{"NodeCertExpiry":7776000000000000},"TaskDefaults":{},"EncryptionConfig":{"AutoLockManagers":true}},"TLSInfo":{"TrustRoot":"\n-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUaFCW5xsq8eyiJ+Pmcv3MCflMLnMwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwODI0MTcyOTAwWhcNMzcwODE5MTcy\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABDy7NebyUJyUjWJDBUdnZoV6GBxEGKO4TZPNDwnxDxJcUdLVaB7WGa4/DLrW\nUfsVgh1JGik2VTiLuTMA1tLlNPOjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQl16XFtaaXiUAwEuJptJlDjfKskDAKBggqhkjO\nPQQDAgNIADBFAiEAo9fTQNM5DP9bHVcTJYfl2Cay1bFu1E+lnpmN+EYJfeACIGKH\n1pCUkZ+D0IB6CiEZGWSHyLuXPM1rlP+I5KuS7sB8\n-----END CERTIFICATE-----\n","CertIssuerSubject":"MBMxETAPBgNVBAMTCHN3YXJtLWNh","CertIssuerPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPLs15vJQnJSNYkMFR2dmhXoYHEQYo7hNk80PCfEPElxR0tVoHtYZrj8MutZR+xWCHUkaKTZVOIu5MwDW0uU08w=="},"RootRotationInProgress":false,"DefaultAddrPool":null,"SubnetSize":0,"DataPathPort":0}},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[],"Warnings":null}}
diff --git a/vendor.mod b/vendor.mod
index a1710897eb..3a3bf40a3f 100644
--- a/vendor.mod
+++ b/vendor.mod
@@ -10,7 +10,7 @@ require (
github.com/containerd/containerd v1.6.2
github.com/creack/pty v1.1.11
github.com/docker/distribution v2.8.1+incompatible
- github.com/docker/docker v20.10.7+incompatible // see "replace" for the actual version
+ github.com/docker/docker v20.10.14+incompatible // see "replace" for the actual version
github.com/docker/docker-credential-helpers v0.6.4
github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.4.0
@@ -74,6 +74,6 @@ require (
)
replace (
- github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220309172631-83b51522df43+incompatible // master (v21.xx-dev)
+ github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220326171151-8941dcfcc5db+incompatible // master (v21.xx-dev)
github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
)
diff --git a/vendor.sum b/vendor.sum
index 193cdcf0fc..3b4f31594e 100644
--- a/vendor.sum
+++ b/vendor.sum
@@ -105,8 +105,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xb
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v20.10.3-0.20220309172631-83b51522df43+incompatible h1:bL4hLpxukr5Ls3bzYrn3LCYIwML+XXCktZHaGBIN3og=
-github.com/docker/docker v20.10.3-0.20220309172631-83b51522df43+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v20.10.3-0.20220326171151-8941dcfcc5db+incompatible h1:5DYFLB020CbxyjsxBle60QaEUb4krFjr30O0eLXsNp0=
+github.com/docker/docker v20.10.3-0.20220326171151-8941dcfcc5db+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml
index 28f08cc3a3..f0e463bd16 100644
--- a/vendor/github.com/docker/docker/api/swagger.yaml
+++ b/vendor/github.com/docker/docker/api/swagger.yaml
@@ -577,19 +577,13 @@ definitions:
type: "array"
items:
$ref: "#/definitions/DeviceRequest"
- KernelMemory:
- description: |
- Kernel memory limit in bytes.
-
-
-
- > **Deprecated**: This field is deprecated as the kernel 5.4 deprecated
- > `kmem.limit_in_bytes`.
- type: "integer"
- format: "int64"
- example: 209715200
KernelMemoryTCP:
- description: "Hard limit for kernel TCP buffer memory (in bytes)."
+ description: |
+ Hard limit for kernel TCP buffer memory (in bytes). Depending on the
+ OCI runtime in use, this option may be ignored. It is no longer supported
+ by the default (runc) runtime.
+
+ This field is omitted when empty.
type: "integer"
format: "int64"
MemoryReservation:
@@ -1075,8 +1069,9 @@ definitions:
description: "Mount the container's root filesystem as read only."
SecurityOpt:
type: "array"
- description: "A list of string values to customize labels for MLS
- systems, such as SELinux."
+ description: |
+ A list of string values to customize labels for MLS systems, such
+ as SELinux.
items:
type: "string"
StorageOpt:
@@ -1869,18 +1864,22 @@ definitions:
type: "string"
description: "Name of the volume."
x-nullable: false
+ example: "tardis"
Driver:
type: "string"
description: "Name of the volume driver used by the volume."
x-nullable: false
+ example: "custom"
Mountpoint:
type: "string"
description: "Mount path of the volume on the host."
x-nullable: false
+ example: "/var/lib/docker/volumes/tardis"
CreatedAt:
type: "string"
format: "dateTime"
description: "Date/Time the volume was created."
+ example: "2016-06-07T20:31:11.853781916Z"
Status:
type: "object"
description: |
@@ -1892,12 +1891,17 @@ definitions:
does not support this feature.
additionalProperties:
type: "object"
+ example:
+ hello: "world"
Labels:
type: "object"
description: "User-defined key/value metadata."
x-nullable: false
additionalProperties:
type: "string"
+ example:
+ com.example.some-label: "some-value"
+ com.example.some-other-label: "some-other-value"
Scope:
type: "string"
description: |
@@ -1906,12 +1910,17 @@ definitions:
default: "local"
x-nullable: false
enum: ["local", "global"]
+ example: "local"
Options:
type: "object"
description: |
The driver specific options used when creating the volume.
additionalProperties:
type: "string"
+ example:
+ device: "tmpfs"
+ o: "size=100m,uid=1000"
+ type: "tmpfs"
UsageData:
type: "object"
x-nullable: true
@@ -1937,17 +1946,43 @@ definitions:
is set to `-1` if the reference-count is not available.
x-nullable: false
- example:
- Name: "tardis"
- Driver: "custom"
- Mountpoint: "/var/lib/docker/volumes/tardis"
- Status:
- hello: "world"
+ VolumeCreateOptions:
+ description: "Volume configuration"
+ type: "object"
+ title: "VolumeConfig"
+ x-go-name: "VolumeCreateBody"
+ properties:
+ Name:
+ description: |
+ The new volume's name. If not specified, Docker generates a name.
+ type: "string"
+ x-nullable: false
+ example: "tardis"
+ Driver:
+ description: "Name of the volume driver to use."
+ type: "string"
+ default: "local"
+ x-nullable: false
+ example: "custom"
+ DriverOpts:
+ description: |
+ A mapping of driver options and values. These options are
+ passed directly to the driver and are driver specific.
+ type: "object"
+ additionalProperties:
+ type: "string"
+ example:
+ device: "tmpfs"
+ o: "size=100m,uid=1000"
+ type: "tmpfs"
Labels:
- com.example.some-label: "some-value"
- com.example.some-other-label: "some-other-value"
- Scope: "local"
- CreatedAt: "2016-06-07T20:31:11.853781916Z"
+ description: "User-defined key/value metadata."
+ type: "object"
+ additionalProperties:
+ type: "string"
+ example:
+ com.example.some-label: "some-value"
+ com.example.some-other-label: "some-other-value"
Network:
type: "object"
@@ -2035,15 +2070,27 @@ definitions:
```
type: "array"
items:
- type: "object"
- additionalProperties:
- type: "string"
+ $ref: "#/definitions/IPAMConfig"
Options:
description: "Driver-specific options, specified as a map."
type: "object"
additionalProperties:
type: "string"
+ IPAMConfig:
+ type: "object"
+ properties:
+ Subnet:
+ type: "string"
+ IPRange:
+ type: "string"
+ Gateway:
+ type: "string"
+ AuxiliaryAddresses:
+ type: "object"
+ additionalProperties:
+ type: "string"
+
NetworkContainer:
type: "object"
properties:
@@ -3827,6 +3874,7 @@ definitions:
ServiceSpec:
description: "User modifiable configuration for a service."
+ type: object
properties:
Name:
description: "Name of the service."
@@ -4464,6 +4512,29 @@ definitions:
Health:
$ref: "#/definitions/Health"
+ ContainerWaitResponse:
+ description: "OK response to ContainerWait operation"
+ type: "object"
+ x-go-name: "ContainerWaitOKBody"
+ title: "ContainerWaitResponse"
+ required: [StatusCode, Error]
+ properties:
+ StatusCode:
+ description: "Exit code of the container"
+ type: "integer"
+ x-nullable: false
+ Error:
+ $ref: "#/definitions/ContainerWaitExitError"
+
+ ContainerWaitExitError:
+ description: "container waiting error, if any"
+ type: "object"
+ x-go-name: "ContainerWaitOKBodyError"
+ properties:
+ Message:
+ description: "Details of an error"
+ type: "string"
+
SystemVersion:
type: "object"
description: |
@@ -4644,19 +4715,10 @@ definitions:
description: "Indicates if the host has memory swap limit support enabled."
type: "boolean"
example: true
- KernelMemory:
- description: |
- Indicates if the host has kernel memory limit support enabled.
-
-
-
- > **Deprecated**: This field is deprecated as the kernel 5.4 deprecated
- > `kmem.limit_in_bytes`.
- type: "boolean"
- example: true
KernelMemoryTCP:
description: |
- Indicates if the host has kernel memory TCP limit support enabled.
+ Indicates if the host has kernel memory TCP limit support enabled. This
+ field is omitted if not supported.
Kernel memory TCP limits are not supported when using cgroups v2, which
does not support the corresponding `memory.kmem.tcp.limit_in_bytes` cgroup.
@@ -5369,6 +5431,7 @@ definitions:
PeerNode:
description: "Represents a peer-node in the swarm"
+ type: "object"
properties:
NodeID:
description: "Unique identifier of for this node in the swarm."
@@ -5820,7 +5883,6 @@ paths:
Memory: 0
MemorySwap: 0
MemoryReservation: 0
- KernelMemory: 0
NanoCpus: 500000
CpuPercent: 80
CpuShares: 512
@@ -6112,7 +6174,6 @@ paths:
Memory: 0
MemorySwap: 0
MemoryReservation: 0
- KernelMemory: 0
OomKillDisable: false
OomScoreAdj: 500
NetworkMode: "bridge"
@@ -6857,7 +6918,6 @@ paths:
Memory: 314572800
MemorySwap: 514288000
MemoryReservation: 209715200
- KernelMemory: 52428800
RestartPolicy:
MaximumRetryCount: 4
Name: "on-failure"
@@ -7196,22 +7256,7 @@ paths:
200:
description: "The container has exit."
schema:
- type: "object"
- title: "ContainerWaitResponse"
- description: "OK response to ContainerWait operation"
- required: [StatusCode]
- properties:
- StatusCode:
- description: "Exit code of the container"
- type: "integer"
- x-nullable: false
- Error:
- description: "container waiting error, if any"
- type: "object"
- properties:
- Message:
- description: "Details of an error"
- type: "string"
+ $ref: "#/definitions/ContainerWaitResponse"
400:
description: "bad parameter"
schema:
@@ -7319,17 +7364,7 @@ paths:
400:
description: "Bad parameter"
schema:
- allOf:
- - $ref: "#/definitions/ErrorResponse"
- - type: "object"
- properties:
- message:
- description: |
- The error message. Either "must specify path parameter"
- (path cannot be empty) or "not a directory" (path was
- asserted to be a directory but exists as a file).
- type: "string"
- x-nullable: false
+ $ref: "#/definitions/ErrorResponse"
404:
description: "Container or path does not exist"
schema:
@@ -7364,17 +7399,7 @@ paths:
400:
description: "Bad parameter"
schema:
- allOf:
- - $ref: "#/definitions/ErrorResponse"
- - type: "object"
- properties:
- message:
- description: |
- The error message. Either "must specify path parameter"
- (path cannot be empty) or "not a directory" (path was
- asserted to be a directory but exists as a file).
- type: "string"
- x-nullable: false
+ $ref: "#/definitions/ErrorResponse"
404:
description: "Container or path does not exist"
schema:
@@ -7400,7 +7425,10 @@ paths:
tags: ["Container"]
put:
summary: "Extract an archive of files or folders to a directory in a container"
- description: "Upload a tar archive to be extracted to a path in the filesystem of container id."
+ description: |
+ Upload a tar archive to be extracted to a path in the filesystem of container id.
+ `path` parameter is asserted to be a directory. If it exists as a file, 400 error
+ will be returned with message "not a directory".
operationId: "PutContainerArchive"
consumes: ["application/x-tar", "application/octet-stream"]
responses:
@@ -7410,6 +7438,9 @@ paths:
description: "Bad parameter"
schema:
$ref: "#/definitions/ErrorResponse"
+ examples:
+ application/json:
+ message: "not a directory"
403:
description: "Permission denied, the volume or container rootfs is marked as read-only."
schema:
@@ -8346,6 +8377,13 @@ paths:
Docker-Experimental:
type: "boolean"
description: "If the server is running with experimental mode enabled"
+ Swarm:
+ type: "string"
+ enum: ["inactive", "pending", "error", "locked", "active/worker", "active/manager"]
+ description: |
+ Contains information about Swarm status of the daemon,
+ and if the daemon is acting as a manager or worker node.
+ default: "inactive"
Cache-Control:
type: "string"
default: "no-cache, no-store, must-revalidate"
@@ -8385,6 +8423,13 @@ paths:
Docker-Experimental:
type: "boolean"
description: "If the server is running with experimental mode enabled"
+ Swarm:
+ type: "string"
+ enum: ["inactive", "pending", "error", "locked", "active/worker", "active/manager"]
+ description: |
+ Contains information about Swarm status of the daemon,
+ and if the daemon is acting as a manager or worker node.
+ default: "inactive"
Cache-Control:
type: "string"
default: "no-cache, no-store, must-revalidate"
@@ -9051,23 +9096,6 @@ paths:
Warnings that occurred when fetching the list of volumes.
items:
type: "string"
-
- examples:
- application/json:
- Volumes:
- - CreatedAt: "2017-07-19T12:00:26Z"
- Name: "tardis"
- Driver: "local"
- Mountpoint: "/var/lib/docker/volumes/tardis"
- Labels:
- com.example.some-label: "some-value"
- com.example.some-other-label: "some-other-value"
- Scope: "local"
- Options:
- device: "tmpfs"
- o: "size=100m,uid=1000"
- type: "tmpfs"
- Warnings: []
500:
description: "Server error"
schema:
@@ -9112,38 +9140,7 @@ paths:
required: true
description: "Volume configuration"
schema:
- type: "object"
- description: "Volume configuration"
- title: "VolumeConfig"
- properties:
- Name:
- description: |
- The new volume's name. If not specified, Docker generates a name.
- type: "string"
- x-nullable: false
- Driver:
- description: "Name of the volume driver to use."
- type: "string"
- default: "local"
- x-nullable: false
- DriverOpts:
- description: |
- A mapping of driver options and values. These options are
- passed directly to the driver and are driver specific.
- type: "object"
- additionalProperties:
- type: "string"
- Labels:
- description: "User-defined key/value metadata."
- type: "object"
- additionalProperties:
- type: "string"
- example:
- Name: "tardis"
- Labels:
- com.example.some-label: "some-value"
- com.example.some-other-label: "some-other-value"
- Driver: "custom"
+ $ref: "#/definitions/VolumeCreateOptions"
tags: ["Volume"]
/volumes/{name}:
diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go
deleted file mode 100644
index 49e05ae669..0000000000
--- a/vendor/github.com/docker/docker/api/types/container/container_wait.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package container // import "github.com/docker/docker/api/types/container"
-
-// ----------------------------------------------------------------------------
-// Code generated by `swagger generate operation`. DO NOT EDIT.
-//
-// See hack/generate-swagger-api.sh
-// ----------------------------------------------------------------------------
-
-// ContainerWaitOKBodyError container waiting error, if any
-// swagger:model ContainerWaitOKBodyError
-type ContainerWaitOKBodyError struct {
-
- // Details of an error
- Message string `json:"Message,omitempty"`
-}
-
-// ContainerWaitOKBody OK response to ContainerWait operation
-// swagger:model ContainerWaitOKBody
-type ContainerWaitOKBody struct {
-
- // error
- // Required: true
- Error *ContainerWaitOKBodyError `json:"Error"`
-
- // Exit code of the container
- // Required: true
- StatusCode int64 `json:"StatusCode"`
-}
diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body.go b/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body.go
new file mode 100644
index 0000000000..3219207fbb
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body.go
@@ -0,0 +1,19 @@
+package container
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+// ContainerWaitOKBody ContainerWaitResponse
+//
+// OK response to ContainerWait operation
+// swagger:model ContainerWaitOKBody
+type ContainerWaitOKBody struct {
+
+ // error
+ // Required: true
+ Error *ContainerWaitOKBodyError `json:"Error"`
+
+ // Exit code of the container
+ // Required: true
+ StatusCode int64 `json:"StatusCode"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body_error.go b/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body_error.go
new file mode 100644
index 0000000000..ee598973ec
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/container/container_wait_o_k_body_error.go
@@ -0,0 +1,12 @@
+package container
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+// ContainerWaitOKBodyError container waiting error, if any
+// swagger:model ContainerWaitOKBodyError
+type ContainerWaitOKBodyError struct {
+
+ // Details of an error
+ Message string `json:"Message,omitempty"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go
index dcea6c8a5a..9a5aa28f9a 100644
--- a/vendor/github.com/docker/docker/api/types/container/host_config.go
+++ b/vendor/github.com/docker/docker/api/types/container/host_config.go
@@ -376,14 +376,17 @@ type Resources struct {
Devices []DeviceMapping // List of devices to map inside the container
DeviceCgroupRules []string // List of rule to be added to the device cgroup
DeviceRequests []DeviceRequest // List of device requests for device drivers
- KernelMemory int64 // Kernel memory limit (in bytes), Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
- KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes)
- MemoryReservation int64 // Memory soft limit (in bytes)
- MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
- MemorySwappiness *int64 // Tuning container memory swappiness behaviour
- OomKillDisable *bool // Whether to disable OOM Killer or not
- PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change.
- Ulimits []*units.Ulimit // List of ulimits to be set in the container
+
+ // KernelMemory specifies the kernel memory limit (in bytes) for the container.
+ // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes.
+ KernelMemory int64 `json:",omitempty"`
+ KernelMemoryTCP int64 `json:",omitempty"` // Hard limit for kernel TCP buffer memory (in bytes)
+ MemoryReservation int64 // Memory soft limit (in bytes)
+ MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
+ MemorySwappiness *int64 // Tuning container memory swappiness behaviour
+ OomKillDisable *bool // Whether to disable OOM Killer or not
+ PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change.
+ Ulimits []*units.Ulimit // List of ulimits to be set in the container
// Applicable to Windows
CPUCount int64 `json:"CpuCount"` // CPU count
diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go
index 4bc91cffd6..6a2139adb3 100644
--- a/vendor/github.com/docker/docker/api/types/filters/parse.go
+++ b/vendor/github.com/docker/docker/api/types/filters/parse.go
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/docker/docker/api/types/versions"
+ "github.com/pkg/errors"
)
// Args stores a mapping of keys to a set of multiple values.
@@ -97,7 +98,7 @@ func FromJSON(p string) (Args, error) {
// Fallback to parsing arguments in the legacy slice format
deprecated := map[string][]string{}
if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {
- return args, err
+ return args, invalidFilter{errors.Wrap(err, "invalid filter")}
}
args.fields = deprecatedArgs(deprecated)
@@ -247,10 +248,10 @@ func (args Args) Contains(field string) bool {
return ok
}
-type invalidFilter string
+type invalidFilter struct{ error }
func (e invalidFilter) Error() string {
- return "Invalid filter '" + string(e) + "'"
+ return e.error.Error()
}
func (invalidFilter) InvalidParameter() {}
@@ -260,7 +261,7 @@ func (invalidFilter) InvalidParameter() {}
func (args Args) Validate(accepted map[string]bool) error {
for name := range args.fields {
if !accepted[name] {
- return invalidFilter(name)
+ return invalidFilter{errors.New("invalid filter '" + name + "'")}
}
}
return nil
diff --git a/vendor/github.com/docker/docker/api/types/swarm/swarm.go b/vendor/github.com/docker/docker/api/types/swarm/swarm.go
index b25f999646..3eae4b9b29 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/swarm.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/swarm.go
@@ -213,6 +213,16 @@ type Info struct {
Warnings []string `json:",omitempty"`
}
+// Status provides information about the current swarm status and role,
+// obtained from the "Swarm" header in the API response.
+type Status struct {
+ // NodeState represents the state of the node.
+ NodeState LocalNodeState
+
+ // ControlAvailable indicates if the node is a swarm manager.
+ ControlAvailable bool
+}
+
// Peer represents a peer.
type Peer struct {
NodeID string
diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go
index 1afc4bf9d3..ee52f46212 100644
--- a/vendor/github.com/docker/docker/api/types/types.go
+++ b/vendor/github.com/docker/docker/api/types/types.go
@@ -188,6 +188,15 @@ type Ping struct {
OSType string
Experimental bool
BuilderVersion BuilderVersion
+
+ // SwarmStatus provides information about the current swarm status of the
+ // engine, obtained from the "Swarm" header in the API response.
+ //
+ // It can be a nil struct if the API version does not provide this header
+ // in the ping response, or if an error occurred, in which case the client
+ // should use other ways to get the current swarm status, such as the /swarm
+ // endpoint.
+ SwarmStatus *swarm.Status
}
// ComponentVersion describes the version information for a specific component.
@@ -239,8 +248,8 @@ type Info struct {
Plugins PluginsInfo
MemoryLimit bool
SwapLimit bool
- KernelMemory bool // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
- KernelMemoryTCP bool
+ KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
+ KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2.
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
CPUCfsQuota bool `json:"CpuCfsQuota"`
CPUShares bool
diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_create.go b/vendor/github.com/docker/docker/api/types/volume/volume_create.go
deleted file mode 100644
index 8538078dd6..0000000000
--- a/vendor/github.com/docker/docker/api/types/volume/volume_create.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package volume // import "github.com/docker/docker/api/types/volume"
-
-// ----------------------------------------------------------------------------
-// Code generated by `swagger generate operation`. DO NOT EDIT.
-//
-// See hack/generate-swagger-api.sh
-// ----------------------------------------------------------------------------
-
-// VolumeCreateBody Volume configuration
-// swagger:model VolumeCreateBody
-type VolumeCreateBody struct {
-
- // Name of the volume driver to use.
- // Required: true
- Driver string `json:"Driver"`
-
- // A mapping of driver options and values. These options are
- // passed directly to the driver and are driver specific.
- //
- // Required: true
- DriverOpts map[string]string `json:"DriverOpts"`
-
- // User-defined key/value metadata.
- // Required: true
- Labels map[string]string `json:"Labels"`
-
- // The new volume's name. If not specified, Docker generates a name.
- //
- // Required: true
- Name string `json:"Name"`
-}
diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_create_body.go b/vendor/github.com/docker/docker/api/types/volume/volume_create_body.go
new file mode 100644
index 0000000000..f40fe1377f
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/volume/volume_create_body.go
@@ -0,0 +1,26 @@
+package volume
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+// VolumeCreateBody VolumeConfig
+//
+// Volume configuration
+// swagger:model VolumeCreateBody
+type VolumeCreateBody struct {
+
+ // Name of the volume driver to use.
+ Driver string `json:"Driver,omitempty"`
+
+ // A mapping of driver options and values. These options are
+ // passed directly to the driver and are driver specific.
+ //
+ DriverOpts map[string]string `json:"DriverOpts,omitempty"`
+
+ // User-defined key/value metadata.
+ Labels map[string]string `json:"Labels,omitempty"`
+
+ // The new volume's name. If not specified, Docker generates a name.
+ //
+ Name string `json:"Name,omitempty"`
+}
diff --git a/vendor/github.com/docker/docker/client/checkpoint_list.go b/vendor/github.com/docker/docker/client/checkpoint_list.go
index 66d46dd161..39cfb959ff 100644
--- a/vendor/github.com/docker/docker/client/checkpoint_list.go
+++ b/vendor/github.com/docker/docker/client/checkpoint_list.go
@@ -20,7 +20,7 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return checkpoints, wrapResponseError(err, resp, "container", container)
+ return checkpoints, err
}
err = json.NewDecoder(resp.body).Decode(&checkpoints)
diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go
index 6a8b4d4fea..1412377eab 100644
--- a/vendor/github.com/docker/docker/client/client.go
+++ b/vendor/github.com/docker/docker/client/client.go
@@ -43,7 +43,6 @@ package client // import "github.com/docker/docker/client"
import (
"context"
- "fmt"
"net"
"net/http"
"net/url"
@@ -93,15 +92,18 @@ type Client struct {
}
// CheckRedirect specifies the policy for dealing with redirect responses:
-// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
+// If the request is non-GET return ErrRedirect, otherwise use the last response.
//
-// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client .
-// The Docker client (and by extension docker API client) can be made to send a request
-// like POST /containers//start where what would normally be in the name section of the URL is empty.
-// This triggers an HTTP 301 from the daemon.
-// In go 1.8 this 301 will be converted to a GET request, and ends up getting a 404 from the daemon.
-// This behavior change manifests in the client in that before the 301 was not followed and
-// the client did not generate an error, but now results in a message like Error response from daemon: page not found.
+// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308)
+// in the client. The Docker client (and by extension docker API client) can be
+// made to send a request like POST /containers//start where what would normally
+// be in the name section of the URL is empty. This triggers an HTTP 301 from
+// the daemon.
+//
+// In go 1.8 this 301 will be converted to a GET request, and ends up getting
+// a 404 from the daemon. This behavior change manifests in the client in that
+// before, the 301 was not followed and the client did not generate an error,
+// but now results in a message like Error response from daemon: page not found.
func CheckRedirect(req *http.Request, via []*http.Request) error {
if via[0].Method == http.MethodGet {
return http.ErrUseLastResponse
@@ -109,13 +111,22 @@ func CheckRedirect(req *http.Request, via []*http.Request) error {
return ErrRedirect
}
-// NewClientWithOpts initializes a new API client with default values. It takes functors
-// to modify values when creating it, like `NewClientWithOpts(WithVersion(…))`
-// It also initializes the custom http headers to add to each request.
+// NewClientWithOpts initializes a new API client with a default HTTPClient, and
+// default API host and version. It also initializes the custom HTTP headers to
+// add to each request.
+//
+// It takes an optional list of Opt functional arguments, which are applied in
+// the order they're provided, which allows modifying the defaults when creating
+// the client. For example, the following initializes a client that configures
+// itself with values from environment variables (client.FromEnv), and has
+// automatic API version negotiation enabled (client.WithAPIVersionNegotiation()).
+//
+//
+// cli, err := client.NewClientWithOpts(
+// client.FromEnv,
+// client.WithAPIVersionNegotiation(),
+// )
//
-// It won't send any version information if the version number is empty. It is
-// highly recommended that you set a version or your client may break if the
-// server is upgraded.
func NewClientWithOpts(ops ...Opt) (*Client, error) {
client, err := defaultHTTPClient(DefaultDockerHost)
if err != nil {
@@ -153,12 +164,12 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
}
func defaultHTTPClient(host string) (*http.Client, error) {
- url, err := ParseHostURL(host)
+ hostURL, err := ParseHostURL(host)
if err != nil {
return nil, err
}
- transport := new(http.Transport)
- sockets.ConfigureTransport(transport, url.Scheme, url.Host)
+ transport := &http.Transport{}
+ _ = sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)
return &http.Client{
Transport: transport,
CheckRedirect: CheckRedirect,
@@ -194,11 +205,21 @@ func (cli *Client) ClientVersion() string {
return cli.version
}
-// NegotiateAPIVersion queries the API and updates the version to match the
-// API version. Any errors are silently ignored. If a manual override is in place,
-// either through the `DOCKER_API_VERSION` environment variable, or if the client
-// was initialized with a fixed version (`opts.WithVersion(xx)`), no negotiation
-// will be performed.
+// NegotiateAPIVersion queries the API and updates the version to match the API
+// version. NegotiateAPIVersion downgrades the client's API version to match the
+// APIVersion if the ping version is lower than the default version. If the API
+// version reported by the server is higher than the maximum version supported
+// by the client, it uses the client's maximum version.
+//
+// If a manual override is in place, either through the "DOCKER_API_VERSION"
+// (EnvOverrideAPIVersion) environment variable, or if the client is initialized
+// with a fixed version (WithVersion(xx)), no negotiation is performed.
+//
+// If the API server's ping response does not contain an API version, or if the
+// client did not get a successful ping response, it assumes it is connected with
+// an old daemon that does not support API version negotiation, in which case it
+// downgrades to the latest version of the API before version negotiation was
+// added (1.24).
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
if !cli.manualOverride {
ping, _ := cli.Ping(ctx)
@@ -206,23 +227,31 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
}
}
-// NegotiateAPIVersionPing updates the client version to match the Ping.APIVersion
-// if the ping version is less than the default version. If a manual override is
-// in place, either through the `DOCKER_API_VERSION` environment variable, or if
-// the client was initialized with a fixed version (`opts.WithVersion(xx)`), no
-// negotiation is performed.
-func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
+// NegotiateAPIVersionPing downgrades the client's API version to match the
+// APIVersion in the ping response. If the API version in pingResponse is higher
+// than the maximum version supported by the client, it uses the client's maximum
+// version.
+//
+// If a manual override is in place, either through the "DOCKER_API_VERSION"
+// (EnvOverrideAPIVersion) environment variable, or if the client is initialized
+// with a fixed version (WithVersion(xx)), no negotiation is performed.
+//
+// If the API server's ping response does not contain an API version, we assume
+// we are connected with an old daemon without API version negotiation support,
+// and downgrade to the latest version of the API before version negotiation was
+// added (1.24).
+func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
if !cli.manualOverride {
- cli.negotiateAPIVersionPing(p)
+ cli.negotiateAPIVersionPing(pingResponse)
}
}
// negotiateAPIVersionPing queries the API and updates the version to match the
-// API version. Any errors are silently ignored.
-func (cli *Client) negotiateAPIVersionPing(p types.Ping) {
- // try the latest version before versioning headers existed
- if p.APIVersion == "" {
- p.APIVersion = "1.24"
+// API version from the ping response.
+func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
+ // default to the latest version before versioning headers existed
+ if pingResponse.APIVersion == "" {
+ pingResponse.APIVersion = "1.24"
}
// if the client is not initialized with a version, start with the latest supported version
@@ -231,8 +260,8 @@ func (cli *Client) negotiateAPIVersionPing(p types.Ping) {
}
// if server version is lower than the client version, downgrade
- if versions.LessThan(p.APIVersion, cli.version) {
- cli.version = p.APIVersion
+ if versions.LessThan(pingResponse.APIVersion, cli.version) {
+ cli.version = pingResponse.APIVersion
}
// Store the results, so that automatic API version negotiation (if enabled)
@@ -258,7 +287,7 @@ func (cli *Client) HTTPClient() *http.Client {
func ParseHostURL(host string) (*url.URL, error) {
protoAddrParts := strings.SplitN(host, "://", 2)
if len(protoAddrParts) == 1 {
- return nil, fmt.Errorf("unable to parse docker host `%s`", host)
+ return nil, errors.Errorf("unable to parse docker host `%s`", host)
}
var basePath string
@@ -278,7 +307,9 @@ func ParseHostURL(host string) (*url.URL, error) {
}, nil
}
-// Dialer returns a dialer for a raw stream connection, with HTTP/1.1 header, that can be used for proxying the daemon connection.
+// Dialer returns a dialer for a raw stream connection, with an HTTP/1.1 header,
+// that can be used for proxying the daemon connection.
+//
// Used by `docker dial-stdio` (docker/cli#889).
func (cli *Client) Dialer() func(context.Context) (net.Conn, error) {
return func(ctx context.Context) (net.Conn, error) {
diff --git a/vendor/github.com/docker/docker/client/client_unix.go b/vendor/github.com/docker/docker/client/client_unix.go
index 5846f888fe..f0783f7085 100644
--- a/vendor/github.com/docker/docker/client/client_unix.go
+++ b/vendor/github.com/docker/docker/client/client_unix.go
@@ -3,7 +3,8 @@
package client // import "github.com/docker/docker/client"
-// DefaultDockerHost defines os specific default if DOCKER_HOST is unset
+// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
+// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "unix:///var/run/docker.sock"
const defaultProto = "unix"
diff --git a/vendor/github.com/docker/docker/client/client_windows.go b/vendor/github.com/docker/docker/client/client_windows.go
index c649e54412..5abe60457d 100644
--- a/vendor/github.com/docker/docker/client/client_windows.go
+++ b/vendor/github.com/docker/docker/client/client_windows.go
@@ -1,6 +1,7 @@
package client // import "github.com/docker/docker/client"
-// DefaultDockerHost defines os specific default if DOCKER_HOST is unset
+// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
+// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "npipe:////./pipe/docker_engine"
const defaultProto = "npipe"
diff --git a/vendor/github.com/docker/docker/client/config_inspect.go b/vendor/github.com/docker/docker/client/config_inspect.go
index f1b0d7f753..9be7882c3d 100644
--- a/vendor/github.com/docker/docker/client/config_inspect.go
+++ b/vendor/github.com/docker/docker/client/config_inspect.go
@@ -20,7 +20,7 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C
resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id)
+ return swarm.Config{}, nil, err
}
body, err := io.ReadAll(resp.body)
diff --git a/vendor/github.com/docker/docker/client/config_remove.go b/vendor/github.com/docker/docker/client/config_remove.go
index 93de0d8445..24b94e9c18 100644
--- a/vendor/github.com/docker/docker/client/config_remove.go
+++ b/vendor/github.com/docker/docker/client/config_remove.go
@@ -9,5 +9,5 @@ func (cli *Client) ConfigRemove(ctx context.Context, id string) error {
}
resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "config", id)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/container_copy.go b/vendor/github.com/docker/docker/client/container_copy.go
index c0a47c14e3..d8b7bb6b91 100644
--- a/vendor/github.com/docker/docker/client/container_copy.go
+++ b/vendor/github.com/docker/docker/client/container_copy.go
@@ -23,7 +23,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
response, err := cli.head(ctx, urlStr, query, nil)
defer ensureReaderClosed(response)
if err != nil {
- return types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+path)
+ return types.ContainerPathStat{}, err
}
return getContainerPathStatFromHeader(response.header)
}
@@ -47,7 +47,7 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str
response, err := cli.putRaw(ctx, apiPath, query, content, nil)
defer ensureReaderClosed(response)
if err != nil {
- return wrapResponseError(err, response, "container:path", containerID+":"+dstPath)
+ return err
}
// TODO this code converts non-error status-codes (e.g., "204 No Content") into an error; verify if this is the desired behavior
@@ -67,7 +67,7 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, nil)
if err != nil {
- return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath)
+ return nil, types.ContainerPathStat{}, err
}
// TODO this code converts non-error status-codes (e.g., "204 No Content") into an error; verify if this is the desired behavior
diff --git a/vendor/github.com/docker/docker/client/container_inspect.go b/vendor/github.com/docker/docker/client/container_inspect.go
index 43db32bd97..d48f0d3a68 100644
--- a/vendor/github.com/docker/docker/client/container_inspect.go
+++ b/vendor/github.com/docker/docker/client/container_inspect.go
@@ -18,7 +18,7 @@ func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (ty
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID)
+ return types.ContainerJSON{}, err
}
var response types.ContainerJSON
@@ -38,7 +38,7 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID)
+ return types.ContainerJSON{}, nil, err
}
body, err := io.ReadAll(serverResp.body)
diff --git a/vendor/github.com/docker/docker/client/container_logs.go b/vendor/github.com/docker/docker/client/container_logs.go
index 5b6541f035..e9ae2f680f 100644
--- a/vendor/github.com/docker/docker/client/container_logs.go
+++ b/vendor/github.com/docker/docker/client/container_logs.go
@@ -74,7 +74,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil)
if err != nil {
- return nil, wrapResponseError(err, resp, "container", container)
+ return nil, err
}
return resp.body, nil
}
diff --git a/vendor/github.com/docker/docker/client/container_remove.go b/vendor/github.com/docker/docker/client/container_remove.go
index df81461b88..c21de609b0 100644
--- a/vendor/github.com/docker/docker/client/container_remove.go
+++ b/vendor/github.com/docker/docker/client/container_remove.go
@@ -23,5 +23,5 @@ func (cli *Client) ContainerRemove(ctx context.Context, containerID string, opti
resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "container", containerID)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/envvars.go b/vendor/github.com/docker/docker/client/envvars.go
new file mode 100644
index 0000000000..61dd45c1d7
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/envvars.go
@@ -0,0 +1,90 @@
+package client // import "github.com/docker/docker/client"
+
+const (
+ // EnvOverrideHost is the name of the environment variable that can be used
+ // to override the default host to connect to (DefaultDockerHost).
+ //
+ // This env-var is read by FromEnv and WithHostFromEnv and when set to a
+ // non-empty value, takes precedence over the default host (which is platform
+ // specific), or any host already set.
+ EnvOverrideHost = "DOCKER_HOST"
+
+ // EnvOverrideAPIVersion is the name of the environment variable that can
+ // be used to override the API version to use. Value should be
+ // formatted as MAJOR.MINOR, for example, "1.19".
+ //
+ // This env-var is read by FromEnv and WithVersionFromEnv and when set to a
+ // non-empty value, takes precedence over API version negotiation.
+ //
+ // This environment variable should be used for debugging purposes only, as
+ // it can set the client to use an incompatible (or invalid) API version.
+ EnvOverrideAPIVersion = "DOCKER_API_VERSION"
+
+ // EnvOverrideCertPath is the name of the environment variable that can be
+ // used to specify the directory from which to load the TLS certificates
+ // (ca.pem, cert.pem, key.pem) from. These certificates are used to configure
+ // the Client for a TCP connection protected by TLS client authentication.
+ //
+ // TLS certificate verification is enabled by default if the Client is configured
+ // to use a TLS connection. Refer to EnvTLSVerify below to learn how to
+ // disable verification for testing purposes.
+ //
+ // WARNING: Access to the remote API is equivalent to root access to the
+ // host where the daemon runs. Do not expose the API without protection,
+ // and only if needed. Make sure you are familiar with the "daemon attack
+ // surface" (https://docs.docker.com/go/attack-surface/).
+ //
+ // For local access to the API, it is recommended to connect with the daemon
+ // using the default local socket connection (on Linux), or the named pipe
+ // (on Windows).
+ //
+ // If you need to access the API of a remote daemon, consider using an SSH
+ // (ssh://) connection, which is easier to set up, and requires no additional
+ // configuration if the host is accessible using ssh.
+ //
+ // If you cannot use the alternatives above, and you must expose the API over
+ // a TCP connection, refer to https://docs.docker.com/engine/security/protect-access/
+ // to learn how to configure the daemon and client to use a TCP connection
+ // with TLS client authentication. Make sure you know the differences between
+ // a regular TLS connection and a TLS connection protected by TLS client
+ // authentication, and verify that the API cannot be accessed by other clients.
+ EnvOverrideCertPath = "DOCKER_CERT_PATH"
+
+ // EnvTLSVerify is the name of the environment variable that can be used to
+ // enable or disable TLS certificate verification. When set to a non-empty
+ // value, TLS certificate verification is enabled, and the client is configured
+ // to use a TLS connection, using certificates from the default directories
+ // (within `~/.docker`); refer to EnvOverrideCertPath above for additional
+ // details.
+ //
+ // WARNING: Access to the remote API is equivalent to root access to the
+ // host where the daemon runs. Do not expose the API without protection,
+ // and only if needed. Make sure you are familiar with the "daemon attack
+ // surface" (https://docs.docker.com/go/attack-surface/).
+ //
+ // Before setting up your client and daemon to use a TCP connection with TLS
+ // client authentication, consider using one of the alternatives mentioned
+ // in EnvOverrideCertPath above.
+ //
+ // Disabling TLS certificate verification (for testing purposes)
+ //
+ // TLS certificate verification is enabled by default if the Client is configured
+ // to use a TLS connection, and it is highly recommended to keep verification
+ // enabled to prevent machine-in-the-middle attacks. Refer to the documentation
+ // at https://docs.docker.com/engine/security/protect-access/ and pages linked
+ // from that page to learn how to configure the daemon and client to use a
+ // TCP connection with TLS client authentication enabled.
+ //
+ // Set the "DOCKER_TLS_VERIFY" environment to an empty string ("") to
+ // disable TLS certificate verification. Disabling verification is insecure,
+ // so should only be done for testing purposes. From the Go documentation
+ // (https://pkg.go.dev/crypto/tls#Config):
+ //
+ // InsecureSkipVerify controls whether a client verifies the server's
+ // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
+ // accepts any certificate presented by the server and any host name in that
+ // certificate. In this mode, TLS is susceptible to machine-in-the-middle
+ // attacks unless custom verification is used. This should be used only for
+ // testing or in combination with VerifyConnection or VerifyPeerCertificate.
+ EnvTLSVerify = "DOCKER_TLS_VERIFY"
+)
diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go
index 041bc8d49c..257921cebb 100644
--- a/vendor/github.com/docker/docker/client/errors.go
+++ b/vendor/github.com/docker/docker/client/errors.go
@@ -2,7 +2,6 @@ package client // import "github.com/docker/docker/client"
import (
"fmt"
- "net/http"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
@@ -59,19 +58,6 @@ func (e objectNotFoundError) Error() string {
return fmt.Sprintf("Error: No such %s: %s", e.object, e.id)
}
-func wrapResponseError(err error, resp serverResponse, object, id string) error {
- switch {
- case err == nil:
- return nil
- case resp.statusCode == http.StatusNotFound:
- return objectNotFoundError{object: object, id: id}
- case resp.statusCode == http.StatusNotImplemented:
- return errdefs.NotImplemented(err)
- default:
- return err
- }
-}
-
// unauthorizedError represents an authorization error in a remote registry.
type unauthorizedError struct {
cause error
diff --git a/vendor/github.com/docker/docker/client/image_inspect.go b/vendor/github.com/docker/docker/client/image_inspect.go
index 03aa12d8b4..1de10e5a08 100644
--- a/vendor/github.com/docker/docker/client/image_inspect.go
+++ b/vendor/github.com/docker/docker/client/image_inspect.go
@@ -17,7 +17,7 @@ func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (typ
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return types.ImageInspect{}, nil, wrapResponseError(err, serverResp, "image", imageID)
+ return types.ImageInspect{}, nil, err
}
body, err := io.ReadAll(serverResp.body)
diff --git a/vendor/github.com/docker/docker/client/image_remove.go b/vendor/github.com/docker/docker/client/image_remove.go
index 84a41af0f2..6a9fb3f41f 100644
--- a/vendor/github.com/docker/docker/client/image_remove.go
+++ b/vendor/github.com/docker/docker/client/image_remove.go
@@ -23,7 +23,7 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options type
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return dels, wrapResponseError(err, resp, "image", imageID)
+ return dels, err
}
err = json.NewDecoder(resp.body).Decode(&dels)
diff --git a/vendor/github.com/docker/docker/client/image_search.go b/vendor/github.com/docker/docker/client/image_search.go
index 5f40a22a96..e69fa37225 100644
--- a/vendor/github.com/docker/docker/client/image_search.go
+++ b/vendor/github.com/docker/docker/client/image_search.go
@@ -3,8 +3,8 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
- "fmt"
"net/url"
+ "strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
@@ -18,7 +18,9 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
var results []registry.SearchResult
query := url.Values{}
query.Set("term", term)
- query.Set("limit", fmt.Sprintf("%d", options.Limit))
+ if options.Limit > 0 {
+ query.Set("limit", strconv.Itoa(options.Limit))
+ }
if options.Filters.Len() > 0 {
filterJSON, err := filters.ToJSON(options.Filters)
diff --git a/vendor/github.com/docker/docker/client/network_inspect.go b/vendor/github.com/docker/docker/client/network_inspect.go
index ecf20ceb6e..0f90e2bb90 100644
--- a/vendor/github.com/docker/docker/client/network_inspect.go
+++ b/vendor/github.com/docker/docker/client/network_inspect.go
@@ -36,7 +36,7 @@ func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string,
resp, err = cli.get(ctx, "/networks/"+networkID, query, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return networkResource, nil, wrapResponseError(err, resp, "network", networkID)
+ return networkResource, nil, err
}
body, err := io.ReadAll(resp.body)
diff --git a/vendor/github.com/docker/docker/client/network_remove.go b/vendor/github.com/docker/docker/client/network_remove.go
index e71b16d869..9d6c6cef07 100644
--- a/vendor/github.com/docker/docker/client/network_remove.go
+++ b/vendor/github.com/docker/docker/client/network_remove.go
@@ -6,5 +6,5 @@ import "context"
func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error {
resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "network", networkID)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/node_inspect.go b/vendor/github.com/docker/docker/client/node_inspect.go
index b58db52856..95ab9b1be0 100644
--- a/vendor/github.com/docker/docker/client/node_inspect.go
+++ b/vendor/github.com/docker/docker/client/node_inspect.go
@@ -17,7 +17,7 @@ func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm
serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return swarm.Node{}, nil, wrapResponseError(err, serverResp, "node", nodeID)
+ return swarm.Node{}, nil, err
}
body, err := io.ReadAll(serverResp.body)
diff --git a/vendor/github.com/docker/docker/client/node_remove.go b/vendor/github.com/docker/docker/client/node_remove.go
index 03ab878097..e44436debc 100644
--- a/vendor/github.com/docker/docker/client/node_remove.go
+++ b/vendor/github.com/docker/docker/client/node_remove.go
@@ -16,5 +16,5 @@ func (cli *Client) NodeRemove(ctx context.Context, nodeID string, options types.
resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "node", nodeID)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/options.go b/vendor/github.com/docker/docker/client/options.go
index 77a9abc141..98d96f792e 100644
--- a/vendor/github.com/docker/docker/client/options.go
+++ b/vendor/github.com/docker/docker/client/options.go
@@ -18,11 +18,18 @@ type Opt func(*Client) error
// FromEnv configures the client with values from environment variables.
//
-// Supported environment variables:
-// DOCKER_HOST to set the url to the docker server.
-// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
-// DOCKER_CERT_PATH to load the TLS certificates from.
-// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
+// FromEnv uses the following environment variables:
+//
+// DOCKER_HOST (EnvOverrideHost) to set the URL to the docker server.
+//
+// DOCKER_API_VERSION (EnvOverrideAPIVersion) to set the version of the API to
+// use, leave empty for latest.
+//
+// DOCKER_CERT_PATH (EnvOverrideCertPath) to specify the directory from which to
+// load the TLS certificates (ca.pem, cert.pem, key.pem).
+//
+// DOCKER_TLS_VERIFY (EnvTLSVerify) to enable or disable TLS verification (off by
+// default).
func FromEnv(c *Client) error {
ops := []Opt{
WithTLSClientConfigFromEnv(),
@@ -75,11 +82,11 @@ func WithHost(host string) Opt {
}
// WithHostFromEnv overrides the client host with the host specified in the
-// DOCKER_HOST environment variable. If DOCKER_HOST is not set, the host is
-// not modified.
+// DOCKER_HOST (EnvOverrideHost) environment variable. If DOCKER_HOST is not set,
+// or set to an empty value, the host is not modified.
func WithHostFromEnv() Opt {
return func(c *Client) error {
- if host := os.Getenv("DOCKER_HOST"); host != "" {
+ if host := os.Getenv(EnvOverrideHost); host != "" {
return WithHost(host)(c)
}
return nil
@@ -145,12 +152,16 @@ func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt {
// settings in the DOCKER_CERT_PATH and DOCKER_TLS_VERIFY environment variables.
// If DOCKER_CERT_PATH is not set or empty, TLS configuration is not modified.
//
-// Supported environment variables:
-// DOCKER_CERT_PATH directory to load the TLS certificates (ca.pem, cert.pem, key.pem) from.
-// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
+// WithTLSClientConfigFromEnv uses the following environment variables:
+//
+// DOCKER_CERT_PATH (EnvOverrideCertPath) to specify the directory from which to
+// load the TLS certificates (ca.pem, cert.pem, key.pem).
+//
+// DOCKER_TLS_VERIFY (EnvTLSVerify) to enable or disable TLS verification (off by
+// default).
func WithTLSClientConfigFromEnv() Opt {
return func(c *Client) error {
- dockerCertPath := os.Getenv("DOCKER_CERT_PATH")
+ dockerCertPath := os.Getenv(EnvOverrideCertPath)
if dockerCertPath == "" {
return nil
}
@@ -158,7 +169,7 @@ func WithTLSClientConfigFromEnv() Opt {
CAFile: filepath.Join(dockerCertPath, "ca.pem"),
CertFile: filepath.Join(dockerCertPath, "cert.pem"),
KeyFile: filepath.Join(dockerCertPath, "key.pem"),
- InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "",
+ InsecureSkipVerify: os.Getenv(EnvTLSVerify) == "",
}
tlsc, err := tlsconfig.Client(options)
if err != nil {
@@ -190,10 +201,7 @@ func WithVersion(version string) Opt {
// the version is not modified.
func WithVersionFromEnv() Opt {
return func(c *Client) error {
- if version := os.Getenv("DOCKER_API_VERSION"); version != "" {
- return WithVersion(version)(c)
- }
- return nil
+ return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)
}
}
diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go
index a9af001ef4..27e8695cb5 100644
--- a/vendor/github.com/docker/docker/client/ping.go
+++ b/vendor/github.com/docker/docker/client/ping.go
@@ -4,8 +4,10 @@ import (
"context"
"net/http"
"path"
+ "strings"
"github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/errdefs"
)
@@ -61,6 +63,13 @@ func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) {
if bv := resp.header.Get("Builder-Version"); bv != "" {
ping.BuilderVersion = types.BuilderVersion(bv)
}
+ if si := resp.header.Get("Swarm"); si != "" {
+ parts := strings.SplitN(si, "/", 2)
+ ping.SwarmStatus = &swarm.Status{
+ NodeState: swarm.LocalNodeState(parts[0]),
+ ControlAvailable: len(parts) == 2 && parts[1] == "manager",
+ }
+ }
err := cli.checkResponseErr(resp)
return ping, errdefs.FromStatusCode(err, resp.statusCode)
}
diff --git a/vendor/github.com/docker/docker/client/plugin_inspect.go b/vendor/github.com/docker/docker/client/plugin_inspect.go
index 4a90bec51a..f09e460660 100644
--- a/vendor/github.com/docker/docker/client/plugin_inspect.go
+++ b/vendor/github.com/docker/docker/client/plugin_inspect.go
@@ -17,7 +17,7 @@ func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*type
resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return nil, nil, wrapResponseError(err, resp, "plugin", name)
+ return nil, nil, err
}
body, err := io.ReadAll(resp.body)
diff --git a/vendor/github.com/docker/docker/client/plugin_list.go b/vendor/github.com/docker/docker/client/plugin_list.go
index cf1935e2f5..2091a054d6 100644
--- a/vendor/github.com/docker/docker/client/plugin_list.go
+++ b/vendor/github.com/docker/docker/client/plugin_list.go
@@ -25,7 +25,7 @@ func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.P
resp, err := cli.get(ctx, "/plugins", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return plugins, wrapResponseError(err, resp, "plugin", "")
+ return plugins, err
}
err = json.NewDecoder(resp.body).Decode(&plugins)
diff --git a/vendor/github.com/docker/docker/client/plugin_remove.go b/vendor/github.com/docker/docker/client/plugin_remove.go
index 51ca1040d6..4cd66958c3 100644
--- a/vendor/github.com/docker/docker/client/plugin_remove.go
+++ b/vendor/github.com/docker/docker/client/plugin_remove.go
@@ -16,5 +16,5 @@ func (cli *Client) PluginRemove(ctx context.Context, name string, options types.
resp, err := cli.delete(ctx, "/plugins/"+name, query, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "plugin", name)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/secret_inspect.go b/vendor/github.com/docker/docker/client/secret_inspect.go
index c07c9550d4..5906874b15 100644
--- a/vendor/github.com/docker/docker/client/secret_inspect.go
+++ b/vendor/github.com/docker/docker/client/secret_inspect.go
@@ -20,7 +20,7 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return swarm.Secret{}, nil, wrapResponseError(err, resp, "secret", id)
+ return swarm.Secret{}, nil, err
}
body, err := io.ReadAll(resp.body)
diff --git a/vendor/github.com/docker/docker/client/secret_remove.go b/vendor/github.com/docker/docker/client/secret_remove.go
index f6c69e57f8..f47f68b6e0 100644
--- a/vendor/github.com/docker/docker/client/secret_remove.go
+++ b/vendor/github.com/docker/docker/client/secret_remove.go
@@ -9,5 +9,5 @@ func (cli *Client) SecretRemove(ctx context.Context, id string) error {
}
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "secret", id)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/service_inspect.go b/vendor/github.com/docker/docker/client/service_inspect.go
index c5368bab1e..cee020c98b 100644
--- a/vendor/github.com/docker/docker/client/service_inspect.go
+++ b/vendor/github.com/docker/docker/client/service_inspect.go
@@ -22,7 +22,7 @@ func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string,
serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return swarm.Service{}, nil, wrapResponseError(err, serverResp, "service", serviceID)
+ return swarm.Service{}, nil, err
}
body, err := io.ReadAll(serverResp.body)
diff --git a/vendor/github.com/docker/docker/client/service_remove.go b/vendor/github.com/docker/docker/client/service_remove.go
index 953a2adf5a..2c46326ebc 100644
--- a/vendor/github.com/docker/docker/client/service_remove.go
+++ b/vendor/github.com/docker/docker/client/service_remove.go
@@ -6,5 +6,5 @@ import "context"
func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error {
resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "service", serviceID)
+ return err
}
diff --git a/vendor/github.com/docker/docker/client/task_inspect.go b/vendor/github.com/docker/docker/client/task_inspect.go
index 410fc526e2..dde1f6c59d 100644
--- a/vendor/github.com/docker/docker/client/task_inspect.go
+++ b/vendor/github.com/docker/docker/client/task_inspect.go
@@ -17,7 +17,7 @@ func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm
serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
- return swarm.Task{}, nil, wrapResponseError(err, serverResp, "task", taskID)
+ return swarm.Task{}, nil, err
}
body, err := io.ReadAll(serverResp.body)
diff --git a/vendor/github.com/docker/docker/client/volume_inspect.go b/vendor/github.com/docker/docker/client/volume_inspect.go
index 5c5b3f905c..070209b35e 100644
--- a/vendor/github.com/docker/docker/client/volume_inspect.go
+++ b/vendor/github.com/docker/docker/client/volume_inspect.go
@@ -25,7 +25,7 @@ func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (t
resp, err := cli.get(ctx, "/volumes/"+volumeID, nil, nil)
defer ensureReaderClosed(resp)
if err != nil {
- return volume, nil, wrapResponseError(err, resp, "volume", volumeID)
+ return volume, nil, err
}
body, err := io.ReadAll(resp.body)
diff --git a/vendor/github.com/docker/docker/client/volume_remove.go b/vendor/github.com/docker/docker/client/volume_remove.go
index 79decdafab..1f26438360 100644
--- a/vendor/github.com/docker/docker/client/volume_remove.go
+++ b/vendor/github.com/docker/docker/client/volume_remove.go
@@ -17,5 +17,5 @@ func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool
}
resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil)
defer ensureReaderClosed(resp)
- return wrapResponseError(err, resp, "volume", volumeID)
+ return err
}
diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go
index 73576f1c6e..5afe486779 100644
--- a/vendor/github.com/docker/docker/errdefs/http_helpers.go
+++ b/vendor/github.com/docker/docker/errdefs/http_helpers.go
@@ -1,78 +1,11 @@
package errdefs // import "github.com/docker/docker/errdefs"
import (
- "fmt"
"net/http"
- containerderrors "github.com/containerd/containerd/errdefs"
- "github.com/docker/distribution/registry/api/errcode"
"github.com/sirupsen/logrus"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
)
-// GetHTTPErrorStatusCode retrieves status code from error message.
-func GetHTTPErrorStatusCode(err error) int {
- if err == nil {
- logrus.WithFields(logrus.Fields{"error": err}).Error("unexpected HTTP error handling")
- return http.StatusInternalServerError
- }
-
- var statusCode int
-
- // Stop right there
- // Are you sure you should be adding a new error class here? Do one of the existing ones work?
-
- // Note that the below functions are already checking the error causal chain for matches.
- switch {
- case IsNotFound(err):
- statusCode = http.StatusNotFound
- case IsInvalidParameter(err):
- statusCode = http.StatusBadRequest
- case IsConflict(err):
- statusCode = http.StatusConflict
- case IsUnauthorized(err):
- statusCode = http.StatusUnauthorized
- case IsUnavailable(err):
- statusCode = http.StatusServiceUnavailable
- case IsForbidden(err):
- statusCode = http.StatusForbidden
- case IsNotModified(err):
- statusCode = http.StatusNotModified
- case IsNotImplemented(err):
- statusCode = http.StatusNotImplemented
- case IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) || IsCancelled(err):
- statusCode = http.StatusInternalServerError
- default:
- statusCode = statusCodeFromGRPCError(err)
- if statusCode != http.StatusInternalServerError {
- return statusCode
- }
- statusCode = statusCodeFromContainerdError(err)
- if statusCode != http.StatusInternalServerError {
- return statusCode
- }
- statusCode = statusCodeFromDistributionError(err)
- if statusCode != http.StatusInternalServerError {
- return statusCode
- }
- if e, ok := err.(causer); ok {
- return GetHTTPErrorStatusCode(e.Cause())
- }
-
- logrus.WithFields(logrus.Fields{
- "module": "api",
- "error_type": fmt.Sprintf("%T", err),
- }).Debugf("FIXME: Got an API for which error does not match any expected type!!!: %+v", err)
- }
-
- if statusCode == 0 {
- statusCode = http.StatusInternalServerError
- }
-
- return statusCode
-}
-
// FromStatusCode creates an errdef error, based on the provided HTTP status-code
func FromStatusCode(err error, statusCode int) error {
if err == nil {
@@ -118,74 +51,3 @@ func FromStatusCode(err error, statusCode int) error {
}
return err
}
-
-// statusCodeFromGRPCError returns status code according to gRPC error
-func statusCodeFromGRPCError(err error) int {
- switch status.Code(err) {
- case codes.InvalidArgument: // code 3
- return http.StatusBadRequest
- case codes.NotFound: // code 5
- return http.StatusNotFound
- case codes.AlreadyExists: // code 6
- return http.StatusConflict
- case codes.PermissionDenied: // code 7
- return http.StatusForbidden
- case codes.FailedPrecondition: // code 9
- return http.StatusBadRequest
- case codes.Unauthenticated: // code 16
- return http.StatusUnauthorized
- case codes.OutOfRange: // code 11
- return http.StatusBadRequest
- case codes.Unimplemented: // code 12
- return http.StatusNotImplemented
- case codes.Unavailable: // code 14
- return http.StatusServiceUnavailable
- default:
- // codes.Canceled(1)
- // codes.Unknown(2)
- // codes.DeadlineExceeded(4)
- // codes.ResourceExhausted(8)
- // codes.Aborted(10)
- // codes.Internal(13)
- // codes.DataLoss(15)
- return http.StatusInternalServerError
- }
-}
-
-// statusCodeFromDistributionError returns status code according to registry errcode
-// code is loosely based on errcode.ServeJSON() in docker/distribution
-func statusCodeFromDistributionError(err error) int {
- switch errs := err.(type) {
- case errcode.Errors:
- if len(errs) < 1 {
- return http.StatusInternalServerError
- }
- if _, ok := errs[0].(errcode.ErrorCoder); ok {
- return statusCodeFromDistributionError(errs[0])
- }
- case errcode.ErrorCoder:
- return errs.ErrorCode().Descriptor().HTTPStatusCode
- }
- return http.StatusInternalServerError
-}
-
-// statusCodeFromContainerdError returns status code for containerd errors when
-// consumed directly (not through gRPC)
-func statusCodeFromContainerdError(err error) int {
- switch {
- case containerderrors.IsInvalidArgument(err):
- return http.StatusBadRequest
- case containerderrors.IsNotFound(err):
- return http.StatusNotFound
- case containerderrors.IsAlreadyExists(err):
- return http.StatusConflict
- case containerderrors.IsFailedPrecondition(err):
- return http.StatusPreconditionFailed
- case containerderrors.IsUnavailable(err):
- return http.StatusServiceUnavailable
- case containerderrors.IsNotImplemented(err):
- return http.StatusNotImplemented
- default:
- return http.StatusInternalServerError
- }
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/archive.go b/vendor/github.com/docker/docker/pkg/archive/archive.go
index a9fd1e9552..986f014491 100644
--- a/vendor/github.com/docker/docker/pkg/archive/archive.go
+++ b/vendor/github.com/docker/docker/pkg/archive/archive.go
@@ -40,8 +40,7 @@ type (
ExcludePatterns []string
Compression Compression
NoLchown bool
- UIDMaps []idtools.IDMap
- GIDMaps []idtools.IDMap
+ IDMap idtools.IdentityMapping
ChownOpts *idtools.Identity
IncludeSourceDir bool
// WhiteoutFormat is the expected on disk format for whiteout files.
@@ -63,12 +62,12 @@ type (
// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
type Archiver struct {
Untar func(io.Reader, string, *TarOptions) error
- IDMapping *idtools.IdentityMapping
+ IDMapping idtools.IdentityMapping
}
// NewDefaultArchiver returns a new Archiver without any IdentityMapping
func NewDefaultArchiver() *Archiver {
- return &Archiver{Untar: Untar, IDMapping: &idtools.IdentityMapping{}}
+ return &Archiver{Untar: Untar}
}
// breakoutError is used to differentiate errors related to breaking out
@@ -534,7 +533,7 @@ type tarAppender struct {
// for hardlink mapping
SeenFiles map[uint64]string
- IdentityMapping *idtools.IdentityMapping
+ IdentityMapping idtools.IdentityMapping
ChownOpts *idtools.Identity
// For packing and unpacking whiteout files in the
@@ -544,7 +543,7 @@ type tarAppender struct {
WhiteoutConverter tarWhiteoutConverter
}
-func newTarAppender(idMapping *idtools.IdentityMapping, writer io.Writer, chownOpts *idtools.Identity) *tarAppender {
+func newTarAppender(idMapping idtools.IdentityMapping, writer io.Writer, chownOpts *idtools.Identity) *tarAppender {
return &tarAppender{
SeenFiles: make(map[uint64]string),
TarWriter: tar.NewWriter(writer),
@@ -860,7 +859,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
go func() {
ta := newTarAppender(
- idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
+ options.IDMap,
compressWriter,
options.ChownOpts,
)
@@ -1044,8 +1043,7 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err
defer pools.BufioReader32KPool.Put(trBuf)
var dirs []*tar.Header
- idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
- rootIDs := idMapping.RootPair()
+ rootIDs := options.IDMap.RootPair()
whiteoutConverter, err := getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)
if err != nil {
return err
@@ -1134,7 +1132,7 @@ loop:
}
trBuf.Reset(tr)
- if err := remapIDs(idMapping, hdr); err != nil {
+ if err := remapIDs(options.IDMap, hdr); err != nil {
return err
}
@@ -1221,8 +1219,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
}
defer archive.Close()
options := &TarOptions{
- UIDMaps: archiver.IDMapping.UIDs(),
- GIDMaps: archiver.IDMapping.GIDs(),
+ IDMap: archiver.IDMapping,
}
return archiver.Untar(archive, dst, options)
}
@@ -1235,8 +1232,7 @@ func (archiver *Archiver) UntarPath(src, dst string) error {
}
defer archive.Close()
options := &TarOptions{
- UIDMaps: archiver.IDMapping.UIDs(),
- GIDMaps: archiver.IDMapping.GIDs(),
+ IDMap: archiver.IDMapping,
}
return archiver.Untar(archive, dst, options)
}
@@ -1343,11 +1339,11 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
}
// IdentityMapping returns the IdentityMapping of the archiver.
-func (archiver *Archiver) IdentityMapping() *idtools.IdentityMapping {
+func (archiver *Archiver) IdentityMapping() idtools.IdentityMapping {
return archiver.IDMapping
}
-func remapIDs(idMapping *idtools.IdentityMapping, hdr *tar.Header) error {
+func remapIDs(idMapping idtools.IdentityMapping, hdr *tar.Header) error {
ids, err := idMapping.ToHost(idtools.Identity{UID: hdr.Uid, GID: hdr.Gid})
hdr.Uid, hdr.Gid = ids.UID, ids.GID
return err
diff --git a/vendor/github.com/docker/docker/pkg/archive/changes.go b/vendor/github.com/docker/docker/pkg/archive/changes.go
index a0f25942c1..9ad7d7efb8 100644
--- a/vendor/github.com/docker/docker/pkg/archive/changes.go
+++ b/vendor/github.com/docker/docker/pkg/archive/changes.go
@@ -394,10 +394,10 @@ func ChangesSize(newDir string, changes []Change) int64 {
}
// ExportChanges produces an Archive from the provided changes, relative to dir.
-func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (io.ReadCloser, error) {
+func ExportChanges(dir string, changes []Change, idMap idtools.IdentityMapping) (io.ReadCloser, error) {
reader, writer := io.Pipe()
go func() {
- ta := newTarAppender(idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), writer, nil)
+ ta := newTarAppender(idMap, writer, nil)
// this buffer is needed for the duration of this piped stream
defer pools.BufioWriter32KPool.Put(ta.Buffer)
diff --git a/vendor/github.com/docker/docker/pkg/archive/diff.go b/vendor/github.com/docker/docker/pkg/archive/diff.go
index 6174bc2af4..f83d126faf 100644
--- a/vendor/github.com/docker/docker/pkg/archive/diff.go
+++ b/vendor/github.com/docker/docker/pkg/archive/diff.go
@@ -9,7 +9,6 @@ import (
"runtime"
"strings"
- "github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/pools"
"github.com/docker/docker/pkg/system"
"github.com/sirupsen/logrus"
@@ -32,7 +31,6 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
if options.ExcludePatterns == nil {
options.ExcludePatterns = []string{}
}
- idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
aufsTempdir := ""
aufsHardlinks := make(map[string]*tar.Header)
@@ -192,7 +190,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
srcData = tmpFile
}
- if err := remapIDs(idMapping, srcHdr); err != nil {
+ if err := remapIDs(options.IDMap, srcHdr); err != nil {
return 0, err
}
diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/docker/docker/pkg/idtools/idtools.go
index 25a57b231e..1e0a89004a 100644
--- a/vendor/github.com/docker/docker/pkg/idtools/idtools.go
+++ b/vendor/github.com/docker/docker/pkg/idtools/idtools.go
@@ -108,70 +108,72 @@ type Identity struct {
SID string
}
-// IdentityMapping contains a mappings of UIDs and GIDs
-type IdentityMapping struct {
- uids []IDMap
- gids []IDMap
+// Chown changes the numeric uid and gid of the named file to id.UID and id.GID.
+func (id Identity) Chown(name string) error {
+ return os.Chown(name, id.UID, id.GID)
}
-// NewIDMappingsFromMaps creates a new mapping from two slices
-// Deprecated: this is a temporary shim while transitioning to IDMapping
-func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IdentityMapping {
- return &IdentityMapping{uids: uids, gids: gids}
+// IdentityMapping contains a mappings of UIDs and GIDs.
+// The zero value represents an empty mapping.
+type IdentityMapping struct {
+ UIDMaps []IDMap `json:"UIDMaps"`
+ GIDMaps []IDMap `json:"GIDMaps"`
}
// RootPair returns a uid and gid pair for the root user. The error is ignored
// because a root user always exists, and the defaults are correct when the uid
// and gid maps are empty.
-func (i *IdentityMapping) RootPair() Identity {
- uid, gid, _ := GetRootUIDGID(i.uids, i.gids)
+func (i IdentityMapping) RootPair() Identity {
+ uid, gid, _ := GetRootUIDGID(i.UIDMaps, i.GIDMaps)
return Identity{UID: uid, GID: gid}
}
// ToHost returns the host UID and GID for the container uid, gid.
// Remapping is only performed if the ids aren't already the remapped root ids
-func (i *IdentityMapping) ToHost(pair Identity) (Identity, error) {
+func (i IdentityMapping) ToHost(pair Identity) (Identity, error) {
var err error
target := i.RootPair()
if pair.UID != target.UID {
- target.UID, err = toHost(pair.UID, i.uids)
+ target.UID, err = toHost(pair.UID, i.UIDMaps)
if err != nil {
return target, err
}
}
if pair.GID != target.GID {
- target.GID, err = toHost(pair.GID, i.gids)
+ target.GID, err = toHost(pair.GID, i.GIDMaps)
}
return target, err
}
// ToContainer returns the container UID and GID for the host uid and gid
-func (i *IdentityMapping) ToContainer(pair Identity) (int, int, error) {
- uid, err := toContainer(pair.UID, i.uids)
+func (i IdentityMapping) ToContainer(pair Identity) (int, int, error) {
+ uid, err := toContainer(pair.UID, i.UIDMaps)
if err != nil {
return -1, -1, err
}
- gid, err := toContainer(pair.GID, i.gids)
+ gid, err := toContainer(pair.GID, i.GIDMaps)
return uid, gid, err
}
// Empty returns true if there are no id mappings
-func (i *IdentityMapping) Empty() bool {
- return len(i.uids) == 0 && len(i.gids) == 0
+func (i IdentityMapping) Empty() bool {
+ return len(i.UIDMaps) == 0 && len(i.GIDMaps) == 0
}
-// UIDs return the UID mapping
-// TODO: remove this once everything has been refactored to use pairs
-func (i *IdentityMapping) UIDs() []IDMap {
- return i.uids
+// UIDs returns the mapping for UID.
+//
+// Deprecated: reference the UIDMaps field directly.
+func (i IdentityMapping) UIDs() []IDMap {
+ return i.UIDMaps
}
-// GIDs return the UID mapping
-// TODO: remove this once everything has been refactored to use pairs
-func (i *IdentityMapping) GIDs() []IDMap {
- return i.gids
+// GIDs returns the mapping for GID.
+//
+// Deprecated: reference the GIDMaps field directly.
+func (i IdentityMapping) GIDs() []IDMap {
+ return i.GIDMaps
}
func createIDMap(subidRanges ranges) []IDMap {
diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go
index ceec0339b5..7a7ccc3e42 100644
--- a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go
+++ b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go
@@ -240,24 +240,37 @@ func setPermissions(p string, mode os.FileMode, uid, gid int, stat *system.StatT
// NewIdentityMapping takes a requested username and
// using the data from /etc/sub{uid,gid} ranges, creates the
// proper uid and gid remapping ranges for that user/group pair
+//
+// Deprecated: Use LoadIdentityMapping.
func NewIdentityMapping(name string) (*IdentityMapping, error) {
+ m, err := LoadIdentityMapping(name)
+ if err != nil {
+ return nil, err
+ }
+ return &m, err
+}
+
+// LoadIdentityMapping takes a requested username and
+// using the data from /etc/sub{uid,gid} ranges, creates the
+// proper uid and gid remapping ranges for that user/group pair
+func LoadIdentityMapping(name string) (IdentityMapping, error) {
usr, err := LookupUser(name)
if err != nil {
- return nil, fmt.Errorf("Could not get user for username %s: %v", name, err)
+ return IdentityMapping{}, fmt.Errorf("Could not get user for username %s: %v", name, err)
}
subuidRanges, err := lookupSubUIDRanges(usr)
if err != nil {
- return nil, err
+ return IdentityMapping{}, err
}
subgidRanges, err := lookupSubGIDRanges(usr)
if err != nil {
- return nil, err
+ return IdentityMapping{}, err
}
- return &IdentityMapping{
- uids: subuidRanges,
- gids: subgidRanges,
+ return IdentityMapping{
+ UIDMaps: subuidRanges,
+ GIDMaps: subgidRanges,
}, nil
}
diff --git a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go b/vendor/github.com/docker/docker/pkg/system/syscall_windows.go
deleted file mode 100644
index ef782d7ac8..0000000000
--- a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package system // import "github.com/docker/docker/pkg/system"
-
-import "golang.org/x/sys/windows"
-
-const (
- // Deprecated: use github.com/docker/pkg/idtools.SeTakeOwnershipPrivilege
- SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
- // Deprecated: use github.com/docker/pkg/idtools.ContainerAdministratorSidString
- ContainerAdministratorSidString = "S-1-5-93-2-1"
- // Deprecated: use github.com/docker/pkg/idtools.ContainerUserSidString
- ContainerUserSidString = "S-1-5-93-2-2"
-)
-
-// VER_NT_WORKSTATION, see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
-const verNTWorkstation = 0x00000001 // VER_NT_WORKSTATION
-
-// IsWindowsClient returns true if the SKU is client. It returns false on
-// Windows server, or if an error occurred when making the GetVersionExW
-// syscall.
-func IsWindowsClient() bool {
- ver := windows.RtlGetVersion()
- return ver != nil && ver.ProductType == verNTWorkstation
-}
diff --git a/vendor/github.com/docker/docker/registry/auth.go b/vendor/github.com/docker/docker/registry/auth.go
index 81533d269f..38f41db221 100644
--- a/vendor/github.com/docker/docker/registry/auth.go
+++ b/vendor/github.com/docker/docker/registry/auth.go
@@ -10,15 +10,13 @@ import (
"github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
- registrytypes "github.com/docker/docker/api/types/registry"
+ "github.com/docker/docker/api/types/registry"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
-const (
- // AuthClientID is used the ClientID used for the token server
- AuthClientID = "docker"
-)
+// AuthClientID is used the ClientID used for the token server
+const AuthClientID = "docker"
type loginCredentialStore struct {
authConfig *types.AuthConfig
@@ -65,14 +63,6 @@ func (scs staticCredentialStore) RefreshToken(*url.URL, string) string {
func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) {
}
-type fallbackError struct {
- err error
-}
-
-func (err fallbackError) Error() string {
- return err.err.Error()
-}
-
// loginV2 tries to login to the v2 registry server. The given registry
// endpoint will be pinged to get authorization challenges. These challenges
// will be used to authenticate against the registry to validate credentials.
@@ -80,7 +70,7 @@ func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent strin
var (
endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
modifiers = Headers(userAgent, nil)
- authTransport = transport.NewTransport(NewTransport(endpoint.TLSConfig), modifiers...)
+ authTransport = transport.NewTransport(newTransport(endpoint.TLSConfig), modifiers...)
credentialAuthConfig = *authConfig
creds = loginCredentialStore{authConfig: &credentialAuthConfig}
)
@@ -109,8 +99,7 @@ func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent strin
}
// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
- err = errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
- return "", "", err
+ return "", "", errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
}
func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, error) {
@@ -129,10 +118,9 @@ func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifi
tokenHandler := auth.NewTokenHandlerWithOptions(tokenHandlerOptions)
basicHandler := auth.NewBasicHandler(creds)
modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler))
- tr := transport.NewTransport(authTransport, modifiers...)
return &http.Client{
- Transport: tr,
+ Transport: transport.NewTransport(authTransport, modifiers...),
Timeout: 15 * time.Second,
}, nil
}
@@ -146,14 +134,11 @@ func ConvertToHostname(url string) string {
} else if strings.HasPrefix(url, "https://") {
stripped = strings.TrimPrefix(url, "https://")
}
-
- nameParts := strings.SplitN(stripped, "/", 2)
-
- return nameParts[0]
+ return strings.SplitN(stripped, "/", 2)[0]
}
// ResolveAuthConfig matches an auth configuration to a server address or a URL
-func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registrytypes.IndexInfo) types.AuthConfig {
+func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registry.IndexInfo) types.AuthConfig {
configKey := GetAuthConfigKey(index)
// First try the happy case
if c, found := authConfigs[configKey]; found || index.Official {
diff --git a/vendor/github.com/docker/docker/registry/config.go b/vendor/github.com/docker/docker/registry/config.go
index 977b0fd024..2766306ac2 100644
--- a/vendor/github.com/docker/docker/registry/config.go
+++ b/vendor/github.com/docker/docker/registry/config.go
@@ -1,7 +1,6 @@
package registry // import "github.com/docker/docker/registry"
import (
- "fmt"
"net"
"net/url"
"regexp"
@@ -9,8 +8,7 @@ import (
"strings"
"github.com/docker/distribution/reference"
- registrytypes "github.com/docker/docker/api/types/registry"
- "github.com/pkg/errors"
+ "github.com/docker/docker/api/types/registry"
"github.com/sirupsen/logrus"
)
@@ -22,9 +20,7 @@ type ServiceOptions struct {
}
// serviceConfig holds daemon configuration for the registry service.
-type serviceConfig struct {
- registrytypes.ServiceConfig
-}
+type serviceConfig registry.ServiceConfig
// TODO(thaJeztah) both the "index.docker.io" and "registry-1.docker.io" domains
// are here for historic reasons and backward-compatibility. These domains
@@ -58,70 +54,92 @@ var (
Host: DefaultRegistryHost,
}
- // ErrInvalidRepositoryName is an error returned if the repository name did
- // not have the correct form
- ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")")
-
emptyServiceConfig, _ = newServiceConfig(ServiceOptions{})
validHostPortRegex = regexp.MustCompile(`^` + reference.DomainRegexp.String() + `$`)
// for mocking in unit tests
lookupIP = net.LookupIP
+
+ // certsDir is used to override defaultCertsDir.
+ certsDir string
)
+// SetCertsDir allows the default certs directory to be changed. This function
+// is used at daemon startup to set the correct location when running in
+// rootless mode.
+func SetCertsDir(path string) {
+ certsDir = path
+}
+
+// CertsDir is the directory where certificates are stored.
+func CertsDir() string {
+ if certsDir != "" {
+ return certsDir
+ }
+ return defaultCertsDir
+}
+
// newServiceConfig returns a new instance of ServiceConfig
func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
- config := &serviceConfig{
- ServiceConfig: registrytypes.ServiceConfig{
- InsecureRegistryCIDRs: make([]*registrytypes.NetIPNet, 0),
- IndexConfigs: make(map[string]*registrytypes.IndexInfo),
- // Hack: Bypass setting the mirrors to IndexConfigs since they are going away
- // and Mirrors are only for the official registry anyways.
- },
- }
- if err := config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
+ config := &serviceConfig{}
+ if err := config.loadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
return nil, err
}
- if err := config.LoadMirrors(options.Mirrors); err != nil {
+ if err := config.loadMirrors(options.Mirrors); err != nil {
return nil, err
}
- if err := config.LoadInsecureRegistries(options.InsecureRegistries); err != nil {
+ if err := config.loadInsecureRegistries(options.InsecureRegistries); err != nil {
return nil, err
}
return config, nil
}
-// LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config.
-func (config *serviceConfig) LoadAllowNondistributableArtifacts(registries []string) error {
- cidrs := map[string]*registrytypes.NetIPNet{}
+// copy constructs a new ServiceConfig with a copy of the configuration in config.
+func (config *serviceConfig) copy() *registry.ServiceConfig {
+ ic := make(map[string]*registry.IndexInfo)
+ for key, value := range config.IndexConfigs {
+ ic[key] = value
+ }
+ return ®istry.ServiceConfig{
+ AllowNondistributableArtifactsCIDRs: append([]*registry.NetIPNet(nil), config.AllowNondistributableArtifactsCIDRs...),
+ AllowNondistributableArtifactsHostnames: append([]string(nil), config.AllowNondistributableArtifactsHostnames...),
+ InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...),
+ IndexConfigs: ic,
+ Mirrors: append([]string(nil), config.Mirrors...),
+ }
+}
+
+// loadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config.
+func (config *serviceConfig) loadAllowNondistributableArtifacts(registries []string) error {
+ cidrs := map[string]*registry.NetIPNet{}
hostnames := map[string]bool{}
for _, r := range registries {
if _, err := ValidateIndexName(r); err != nil {
return err
}
- if validateNoScheme(r) != nil {
- return fmt.Errorf("allow-nondistributable-artifacts registry %s should not contain '://'", r)
+ if hasScheme(r) {
+ return invalidParamf("allow-nondistributable-artifacts registry %s should not contain '://'", r)
}
if _, ipnet, err := net.ParseCIDR(r); err == nil {
// Valid CIDR.
- cidrs[ipnet.String()] = (*registrytypes.NetIPNet)(ipnet)
- } else if err := validateHostPort(r); err == nil {
+ cidrs[ipnet.String()] = (*registry.NetIPNet)(ipnet)
+ } else if err = validateHostPort(r); err == nil {
// Must be `host:port` if not CIDR.
hostnames[r] = true
} else {
- return fmt.Errorf("allow-nondistributable-artifacts registry %s is not valid: %v", r, err)
+ return invalidParamWrapf(err, "allow-nondistributable-artifacts registry %s is not valid", r)
}
}
- config.AllowNondistributableArtifactsCIDRs = make([]*(registrytypes.NetIPNet), 0)
+ config.AllowNondistributableArtifactsCIDRs = make([]*registry.NetIPNet, 0, len(cidrs))
for _, c := range cidrs {
config.AllowNondistributableArtifactsCIDRs = append(config.AllowNondistributableArtifactsCIDRs, c)
}
- config.AllowNondistributableArtifactsHostnames = make([]string, 0)
+ config.AllowNondistributableArtifactsHostnames = make([]string, 0, len(hostnames))
for h := range hostnames {
config.AllowNondistributableArtifactsHostnames = append(config.AllowNondistributableArtifactsHostnames, h)
}
@@ -129,9 +147,9 @@ func (config *serviceConfig) LoadAllowNondistributableArtifacts(registries []str
return nil
}
-// LoadMirrors loads mirrors to config, after removing duplicates.
+// loadMirrors loads mirrors to config, after removing duplicates.
// Returns an error if mirrors contains an invalid mirror.
-func (config *serviceConfig) LoadMirrors(mirrors []string) error {
+func (config *serviceConfig) loadMirrors(mirrors []string) error {
mMap := map[string]struct{}{}
unique := []string{}
@@ -149,40 +167,33 @@ func (config *serviceConfig) LoadMirrors(mirrors []string) error {
config.Mirrors = unique
// Configure public registry since mirrors may have changed.
- config.IndexConfigs[IndexName] = ®istrytypes.IndexInfo{
- Name: IndexName,
- Mirrors: config.Mirrors,
- Secure: true,
- Official: true,
+ config.IndexConfigs = map[string]*registry.IndexInfo{
+ IndexName: {
+ Name: IndexName,
+ Mirrors: unique,
+ Secure: true,
+ Official: true,
+ },
}
return nil
}
-// LoadInsecureRegistries loads insecure registries to config
-func (config *serviceConfig) LoadInsecureRegistries(registries []string) error {
- // Localhost is by default considered as an insecure registry
- // This is a stop-gap for people who are running a private registry on localhost (especially on Boot2docker).
- //
- // TODO: should we deprecate this once it is easier for people to set up a TLS registry or change
- // daemon flags on boot2docker?
+// loadInsecureRegistries loads insecure registries to config
+func (config *serviceConfig) loadInsecureRegistries(registries []string) error {
+ // Localhost is by default considered as an insecure registry. This is a
+ // stop-gap for people who are running a private registry on localhost.
registries = append(registries, "127.0.0.0/8")
- // Store original InsecureRegistryCIDRs and IndexConfigs
- // Clean InsecureRegistryCIDRs and IndexConfigs in config, as passed registries has all insecure registry info.
- originalCIDRs := config.ServiceConfig.InsecureRegistryCIDRs
- originalIndexInfos := config.ServiceConfig.IndexConfigs
-
- config.ServiceConfig.InsecureRegistryCIDRs = make([]*registrytypes.NetIPNet, 0)
- config.ServiceConfig.IndexConfigs = make(map[string]*registrytypes.IndexInfo)
+ var (
+ insecureRegistryCIDRs = make([]*registry.NetIPNet, 0)
+ indexConfigs = make(map[string]*registry.IndexInfo)
+ )
skip:
for _, r := range registries {
// validate insecure registry
if _, err := ValidateIndexName(r); err != nil {
- // before returning err, roll back to original data
- config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs
- config.ServiceConfig.IndexConfigs = originalIndexInfos
return err
}
if strings.HasPrefix(strings.ToLower(r), "http://") {
@@ -191,35 +202,27 @@ skip:
} else if strings.HasPrefix(strings.ToLower(r), "https://") {
logrus.Warnf("insecure registry %s should not contain 'https://' and 'https://' has been removed from the insecure registry config", r)
r = r[8:]
- } else if validateNoScheme(r) != nil {
- // Insecure registry should not contain '://'
- // before returning err, roll back to original data
- config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs
- config.ServiceConfig.IndexConfigs = originalIndexInfos
- return fmt.Errorf("insecure registry %s should not contain '://'", r)
+ } else if hasScheme(r) {
+ return invalidParamf("insecure registry %s should not contain '://'", r)
}
// Check if CIDR was passed to --insecure-registry
_, ipnet, err := net.ParseCIDR(r)
if err == nil {
// Valid CIDR. If ipnet is already in config.InsecureRegistryCIDRs, skip.
- data := (*registrytypes.NetIPNet)(ipnet)
- for _, value := range config.InsecureRegistryCIDRs {
+ data := (*registry.NetIPNet)(ipnet)
+ for _, value := range insecureRegistryCIDRs {
if value.IP.String() == data.IP.String() && value.Mask.String() == data.Mask.String() {
continue skip
}
}
// ipnet is not found, add it in config.InsecureRegistryCIDRs
- config.InsecureRegistryCIDRs = append(config.InsecureRegistryCIDRs, data)
-
+ insecureRegistryCIDRs = append(insecureRegistryCIDRs, data)
} else {
if err := validateHostPort(r); err != nil {
- config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs
- config.ServiceConfig.IndexConfigs = originalIndexInfos
- return fmt.Errorf("insecure registry %s is not valid: %v", r, err)
-
+ return invalidParamWrapf(err, "insecure registry %s is not valid", r)
}
// Assume `host:port` if not CIDR.
- config.IndexConfigs[r] = ®istrytypes.IndexInfo{
+ indexConfigs[r] = ®istry.IndexInfo{
Name: r,
Mirrors: make([]string, 0),
Secure: false,
@@ -229,12 +232,14 @@ skip:
}
// Configure public registry.
- config.IndexConfigs[IndexName] = ®istrytypes.IndexInfo{
+ indexConfigs[IndexName] = ®istry.IndexInfo{
Name: IndexName,
Mirrors: config.Mirrors,
Secure: true,
Official: true,
}
+ config.InsecureRegistryCIDRs = insecureRegistryCIDRs
+ config.IndexConfigs = indexConfigs
return nil
}
@@ -248,7 +253,7 @@ skip:
// hostname should be a URL.Host (`host:port` or `host`) where the `host` part can be either a domain name
// or an IP address. If it is a domain name, then it will be resolved to IP addresses for matching. If
// resolution fails, CIDR matching is not performed.
-func allowNondistributableArtifacts(config *serviceConfig, hostname string) bool {
+func (config *serviceConfig) allowNondistributableArtifacts(hostname string) bool {
for _, h := range config.AllowNondistributableArtifactsHostnames {
if h == hostname {
return true
@@ -269,7 +274,7 @@ func allowNondistributableArtifacts(config *serviceConfig, hostname string) bool
// or an IP address. If it is a domain name, then it will be resolved in order to check if the IP is contained
// in a subnet. If the resolving is not successful, isSecureIndex will only try to match hostname to any element
// of insecureRegistries.
-func isSecureIndex(config *serviceConfig, indexName string) bool {
+func (config *serviceConfig) isSecureIndex(indexName string) bool {
// Check for configured index, first. This is needed in case isSecureIndex
// is called from anything besides newIndexInfo, in order to honor per-index configurations.
if index, ok := config.IndexConfigs[indexName]; ok {
@@ -282,7 +287,7 @@ func isSecureIndex(config *serviceConfig, indexName string) bool {
// isCIDRMatch returns true if URLHost matches an element of cidrs. URLHost is a URL.Host (`host:port` or `host`)
// where the `host` part can be either a domain name or an IP address. If it is a domain name, then it will be
// resolved to IP addresses for matching. If resolution fails, false is returned.
-func isCIDRMatch(cidrs []*registrytypes.NetIPNet, URLHost string) bool {
+func isCIDRMatch(cidrs []*registry.NetIPNet, URLHost string) bool {
host, _, err := net.SplitHostPort(URLHost)
if err != nil {
// Assume URLHost is of the form `host` without the port and go on.
@@ -318,18 +323,18 @@ func isCIDRMatch(cidrs []*registrytypes.NetIPNet, URLHost string) bool {
func ValidateMirror(val string) (string, error) {
uri, err := url.Parse(val)
if err != nil {
- return "", fmt.Errorf("invalid mirror: %q is not a valid URI", val)
+ return "", invalidParamWrapf(err, "invalid mirror: %q is not a valid URI", val)
}
if uri.Scheme != "http" && uri.Scheme != "https" {
- return "", fmt.Errorf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri)
+ return "", invalidParamf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri)
}
if (uri.Path != "" && uri.Path != "/") || uri.RawQuery != "" || uri.Fragment != "" {
- return "", fmt.Errorf("invalid mirror: path, query, or fragment at end of the URI %q", uri)
+ return "", invalidParamf("invalid mirror: path, query, or fragment at end of the URI %q", uri)
}
if uri.User != nil {
// strip password from output
uri.User = url.UserPassword(uri.User.Username(), "xxxxx")
- return "", fmt.Errorf("invalid mirror: username/password not allowed in URI %q", uri)
+ return "", invalidParamf("invalid mirror: username/password not allowed in URI %q", uri)
}
return strings.TrimSuffix(val, "/") + "/", nil
}
@@ -341,17 +346,13 @@ func ValidateIndexName(val string) (string, error) {
val = "docker.io"
}
if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") {
- return "", fmt.Errorf("invalid index name (%s). Cannot begin or end with a hyphen", val)
+ return "", invalidParamf("invalid index name (%s). Cannot begin or end with a hyphen", val)
}
return val, nil
}
-func validateNoScheme(reposName string) error {
- if strings.Contains(reposName, "://") {
- // It cannot contain a scheme!
- return ErrInvalidRepositoryName
- }
- return nil
+func hasScheme(reposName string) bool {
+ return strings.Contains(reposName, "://")
}
func validateHostPort(s string) error {
@@ -364,7 +365,7 @@ func validateHostPort(s string) error {
// If match against the `host:port` pattern fails,
// it might be `IPv6:port`, which will be captured by net.ParseIP(host)
if !validHostPortRegex.MatchString(s) && net.ParseIP(host) == nil {
- return fmt.Errorf("invalid host %q", host)
+ return invalidParamf("invalid host %q", host)
}
if port != "" {
v, err := strconv.Atoi(port)
@@ -372,14 +373,14 @@ func validateHostPort(s string) error {
return err
}
if v < 0 || v > 65535 {
- return fmt.Errorf("invalid port %q", port)
+ return invalidParamf("invalid port %q", port)
}
}
return nil
}
// newIndexInfo returns IndexInfo configuration from indexName
-func newIndexInfo(config *serviceConfig, indexName string) (*registrytypes.IndexInfo, error) {
+func newIndexInfo(config *serviceConfig, indexName string) (*registry.IndexInfo, error) {
var err error
indexName, err = ValidateIndexName(indexName)
if err != nil {
@@ -392,18 +393,17 @@ func newIndexInfo(config *serviceConfig, indexName string) (*registrytypes.Index
}
// Construct a non-configured index info.
- index := ®istrytypes.IndexInfo{
+ return ®istry.IndexInfo{
Name: indexName,
Mirrors: make([]string, 0),
+ Secure: config.isSecureIndex(indexName),
Official: false,
- }
- index.Secure = isSecureIndex(config, indexName)
- return index, nil
+ }, nil
}
// GetAuthConfigKey special-cases using the full index address of the official
// index as the AuthConfig key, and uses the (host)name[:port] for private indexes.
-func GetAuthConfigKey(index *registrytypes.IndexInfo) string {
+func GetAuthConfigKey(index *registry.IndexInfo) string {
if index.Official {
return IndexServer
}
@@ -432,7 +432,12 @@ func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
}
// ParseSearchIndexInfo will use repository name to get back an indexInfo.
-func ParseSearchIndexInfo(reposName string) (*registrytypes.IndexInfo, error) {
+//
+// TODO(thaJeztah) this function is only used by the CLI, and used to get
+// information of the registry (to provide credentials if needed). We should
+// move this function (or equivalent) to the CLI, as it's doing too much just
+// for that.
+func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
indexName, _ := splitReposSearchTerm(reposName)
indexInfo, err := newIndexInfo(emptyServiceConfig, indexName)
diff --git a/vendor/github.com/docker/docker/registry/config_unix.go b/vendor/github.com/docker/docker/registry/config_unix.go
index b5bb31cfa6..898c6b8a5b 100644
--- a/vendor/github.com/docker/docker/registry/config_unix.go
+++ b/vendor/github.com/docker/docker/registry/config_unix.go
@@ -3,25 +3,10 @@
package registry // import "github.com/docker/docker/registry"
-import (
- "path/filepath"
-
- "github.com/docker/docker/pkg/homedir"
- "github.com/docker/docker/rootless"
-)
-
-// CertsDir is the directory where certificates are stored
-func CertsDir() string {
- d := "/etc/docker/certs.d"
-
- if rootless.RunningWithRootlessKit() {
- configHome, err := homedir.GetConfigHome()
- if err == nil {
- d = filepath.Join(configHome, "docker/certs.d")
- }
- }
- return d
-}
+// defaultCertsDir is the platform-specific default directory where certificates
+// are stored. On Linux, it may be overridden through certsDir, for example, when
+// running in rootless mode.
+const defaultCertsDir = "/etc/docker/certs.d"
// cleanPath is used to ensure that a directory name is valid on the target
// platform. It will be passed in something *similar* to a URL such as
diff --git a/vendor/github.com/docker/docker/registry/config_windows.go b/vendor/github.com/docker/docker/registry/config_windows.go
index 4ae1e07abf..96f1769c69 100644
--- a/vendor/github.com/docker/docker/registry/config_windows.go
+++ b/vendor/github.com/docker/docker/registry/config_windows.go
@@ -6,10 +6,10 @@ import (
"strings"
)
-// CertsDir is the directory where certificates are stored
-func CertsDir() string {
- return os.Getenv("programdata") + `\docker\certs.d`
-}
+// defaultCertsDir is the platform-specific default directory where certificates
+// are stored. On Linux, it may be overridden through certsDir, for example, when
+// running in rootless mode.
+var defaultCertsDir = os.Getenv("programdata") + `\docker\certs.d`
// cleanPath is used to ensure that a directory name is valid on the target
// platform. It will be passed in something *similar* to a URL such as
diff --git a/vendor/github.com/docker/docker/registry/endpoint_v1.go b/vendor/github.com/docker/docker/registry/endpoint_v1.go
index 684c330dc3..c7e930c8ad 100644
--- a/vendor/github.com/docker/docker/registry/endpoint_v1.go
+++ b/vendor/github.com/docker/docker/registry/endpoint_v1.go
@@ -3,27 +3,39 @@ package registry // import "github.com/docker/docker/registry"
import (
"crypto/tls"
"encoding/json"
- "fmt"
"io"
"net/http"
"net/url"
"strings"
"github.com/docker/distribution/registry/client/transport"
- registrytypes "github.com/docker/docker/api/types/registry"
+ "github.com/docker/docker/api/types/registry"
"github.com/sirupsen/logrus"
)
-// V1Endpoint stores basic information about a V1 registry endpoint.
-type V1Endpoint struct {
+// v1PingResult contains the information returned when pinging a registry. It
+// indicates the registry's version and whether the registry claims to be a
+// standalone registry.
+type v1PingResult struct {
+ // Version is the registry version supplied by the registry in an HTTP
+ // header
+ Version string `json:"version"`
+ // Standalone is set to true if the registry indicates it is a
+ // standalone registry in the X-Docker-Registry-Standalone
+ // header
+ Standalone bool `json:"standalone"`
+}
+
+// v1Endpoint stores basic information about a V1 registry endpoint.
+type v1Endpoint struct {
client *http.Client
URL *url.URL
IsSecure bool
}
-// NewV1Endpoint parses the given address to return a registry endpoint.
+// newV1Endpoint parses the given address to return a registry endpoint.
// TODO: remove. This is only used by search.
-func NewV1Endpoint(index *registrytypes.IndexInfo, userAgent string, metaHeaders http.Header) (*V1Endpoint, error) {
+func newV1Endpoint(index *registry.IndexInfo, userAgent string, metaHeaders http.Header) (*v1Endpoint, error) {
tlsConfig, err := newTLSConfig(index.Name, index.Secure)
if err != nil {
return nil, err
@@ -42,28 +54,28 @@ func NewV1Endpoint(index *registrytypes.IndexInfo, userAgent string, metaHeaders
return endpoint, nil
}
-func validateEndpoint(endpoint *V1Endpoint) error {
+func validateEndpoint(endpoint *v1Endpoint) error {
logrus.Debugf("pinging registry endpoint %s", endpoint)
// Try HTTPS ping to registry
endpoint.URL.Scheme = "https"
- if _, err := endpoint.Ping(); err != nil {
+ if _, err := endpoint.ping(); err != nil {
if endpoint.IsSecure {
// If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry`
// in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fallback to HTTP.
- return fmt.Errorf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host)
+ return invalidParamf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host)
}
// If registry is insecure and HTTPS failed, fallback to HTTP.
- logrus.Debugf("Error from registry %q marked as insecure: %v. Insecurely falling back to HTTP", endpoint, err)
+ logrus.WithError(err).Debugf("error from registry %q marked as insecure - insecurely falling back to HTTP", endpoint)
endpoint.URL.Scheme = "http"
var err2 error
- if _, err2 = endpoint.Ping(); err2 == nil {
+ if _, err2 = endpoint.ping(); err2 == nil {
return nil
}
- return fmt.Errorf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2)
+ return invalidParamf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2)
}
return nil
@@ -72,28 +84,23 @@ func validateEndpoint(endpoint *V1Endpoint) error {
// trimV1Address trims the version off the address and returns the
// trimmed address or an error if there is a non-V1 version.
func trimV1Address(address string) (string, error) {
- var (
- chunks []string
- apiVersionStr string
- )
-
address = strings.TrimSuffix(address, "/")
- chunks = strings.Split(address, "/")
- apiVersionStr = chunks[len(chunks)-1]
+ chunks := strings.Split(address, "/")
+ apiVersionStr := chunks[len(chunks)-1]
if apiVersionStr == "v1" {
return strings.Join(chunks[:len(chunks)-1], "/"), nil
}
for k, v := range apiVersions {
if k != APIVersion1 && apiVersionStr == v {
- return "", fmt.Errorf("unsupported V1 version path %s", apiVersionStr)
+ return "", invalidParamf("unsupported V1 version path %s", apiVersionStr)
}
}
return address, nil
}
-func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*V1Endpoint, error) {
+func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*v1Endpoint, error) {
if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") {
address = "https://" + address
}
@@ -105,69 +112,64 @@ func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent strin
uri, err := url.Parse(address)
if err != nil {
- return nil, err
+ return nil, invalidParam(err)
}
// TODO(tiborvass): make sure a ConnectTimeout transport is used
- tr := NewTransport(tlsConfig)
+ tr := newTransport(tlsConfig)
- return &V1Endpoint{
+ return &v1Endpoint{
IsSecure: tlsConfig == nil || !tlsConfig.InsecureSkipVerify,
URL: uri,
- client: HTTPClient(transport.NewTransport(tr, Headers(userAgent, metaHeaders)...)),
+ client: httpClient(transport.NewTransport(tr, Headers(userAgent, metaHeaders)...)),
}, nil
}
// Get the formatted URL for the root of this registry Endpoint
-func (e *V1Endpoint) String() string {
+func (e *v1Endpoint) String() string {
return e.URL.String() + "/v1/"
}
-// Path returns a formatted string for the URL
-// of this endpoint with the given path appended.
-func (e *V1Endpoint) Path(path string) string {
- return e.URL.String() + "/v1/" + path
-}
-
-// Ping returns a PingResult which indicates whether the registry is standalone or not.
-func (e *V1Endpoint) Ping() (PingResult, error) {
+// ping returns a v1PingResult which indicates whether the registry is standalone or not.
+func (e *v1Endpoint) ping() (v1PingResult, error) {
if e.String() == IndexServer {
// Skip the check, we know this one is valid
// (and we never want to fallback to http in case of error)
- return PingResult{}, nil
+ return v1PingResult{}, nil
}
logrus.Debugf("attempting v1 ping for registry endpoint %s", e)
- req, err := http.NewRequest(http.MethodGet, e.Path("_ping"), nil)
+ pingURL := e.String() + "_ping"
+ req, err := http.NewRequest(http.MethodGet, pingURL, nil)
if err != nil {
- return PingResult{}, err
+ return v1PingResult{}, invalidParam(err)
}
resp, err := e.client.Do(req)
if err != nil {
- return PingResult{}, err
+ return v1PingResult{}, invalidParam(err)
}
defer resp.Body.Close()
jsonString, err := io.ReadAll(resp.Body)
if err != nil {
- return PingResult{}, fmt.Errorf("error while reading the http response: %s", err)
+ return v1PingResult{}, invalidParamWrapf(err, "error while reading response from %s", pingURL)
}
// If the header is absent, we assume true for compatibility with earlier
// versions of the registry. default to true
- info := PingResult{
+ info := v1PingResult{
Standalone: true,
}
if err := json.Unmarshal(jsonString, &info); err != nil {
- logrus.Debugf("Error unmarshaling the _ping PingResult: %s", err)
+ logrus.WithError(err).Debug("error unmarshaling _ping response")
// don't stop here. Just assume sane defaults
}
if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" {
info.Version = hdr
}
- logrus.Debugf("PingResult.Version: %q", info.Version)
+ logrus.Debugf("v1PingResult.Version: %q", info.Version)
standalone := resp.Header.Get("X-Docker-Registry-Standalone")
@@ -178,6 +180,6 @@ func (e *V1Endpoint) Ping() (PingResult, error) {
// there is a header set, and it is not "true" or "1", so assume fails
info.Standalone = false
}
- logrus.Debugf("PingResult.Standalone: %t", info.Standalone)
+ logrus.Debugf("v1PingResult.Standalone: %t", info.Standalone)
return info, nil
}
diff --git a/vendor/github.com/docker/docker/registry/errors.go b/vendor/github.com/docker/docker/registry/errors.go
index 4906303efc..7dc20ad8ff 100644
--- a/vendor/github.com/docker/docker/registry/errors.go
+++ b/vendor/github.com/docker/docker/registry/errors.go
@@ -5,6 +5,7 @@ import (
"github.com/docker/distribution/registry/api/errcode"
"github.com/docker/docker/errdefs"
+ "github.com/pkg/errors"
)
func translateV2AuthError(err error) error {
@@ -21,3 +22,15 @@ func translateV2AuthError(err error) error {
return err
}
+
+func invalidParam(err error) error {
+ return errdefs.InvalidParameter(err)
+}
+
+func invalidParamf(format string, args ...interface{}) error {
+ return errdefs.InvalidParameter(errors.Errorf(format, args...))
+}
+
+func invalidParamWrapf(err error, format string, args ...interface{}) error {
+ return errdefs.InvalidParameter(errors.Wrapf(err, format, args...))
+}
diff --git a/vendor/github.com/docker/docker/registry/registry.go b/vendor/github.com/docker/docker/registry/registry.go
index 42f0f4dc9f..5ff39ce5e7 100644
--- a/vendor/github.com/docker/docker/registry/registry.go
+++ b/vendor/github.com/docker/docker/registry/registry.go
@@ -3,7 +3,6 @@ package registry // import "github.com/docker/docker/registry"
import (
"crypto/tls"
- "fmt"
"net"
"net/http"
"os"
@@ -16,15 +15,12 @@ import (
"github.com/sirupsen/logrus"
)
-// HostCertsDir returns the config directory for a specific host
-func HostCertsDir(hostname string) (string, error) {
- certsDir := CertsDir()
-
- hostDir := filepath.Join(certsDir, cleanPath(hostname))
-
- return hostDir, nil
+// HostCertsDir returns the config directory for a specific host.
+func HostCertsDir(hostname string) string {
+ return filepath.Join(CertsDir(), cleanPath(hostname))
}
+// newTLSConfig constructs a client TLS configuration based on server defaults
func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
// PreferredServerCipherSuites should have no effect
tlsConfig := tlsconfig.ServerDefault()
@@ -32,11 +28,7 @@ func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
tlsConfig.InsecureSkipVerify = !isSecure
if isSecure && CertsDir() != "" {
- hostDir, err := HostCertsDir(hostname)
- if err != nil {
- return nil, err
- }
-
+ hostDir := HostCertsDir(hostname)
logrus.Debugf("hostDir: %s", hostDir)
if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil {
return nil, err
@@ -61,7 +53,7 @@ func hasFile(files []os.DirEntry, name string) bool {
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
fs, err := os.ReadDir(directory)
if err != nil && !os.IsNotExist(err) {
- return err
+ return invalidParam(err)
}
for _, f := range fs {
@@ -69,7 +61,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
if tlsConfig.RootCAs == nil {
systemPool, err := tlsconfig.SystemCertPool()
if err != nil {
- return fmt.Errorf("unable to get system cert pool: %v", err)
+ return invalidParamWrapf(err, "unable to get system cert pool")
}
tlsConfig.RootCAs = systemPool
}
@@ -85,7 +77,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
keyName := certName[:len(certName)-5] + ".key"
logrus.Debugf("cert: %s", filepath.Join(directory, f.Name()))
if !hasFile(fs, keyName) {
- return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName)
+ return invalidParamf("missing key %s for client certificate %s. CA certificates must use the extension .crt", keyName, certName)
}
cert, err := tls.LoadX509KeyPair(filepath.Join(directory, certName), filepath.Join(directory, keyName))
if err != nil {
@@ -98,7 +90,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
certName := keyName[:len(keyName)-4] + ".cert"
logrus.Debugf("key: %s", filepath.Join(directory, f.Name()))
if !hasFile(fs, certName) {
- return fmt.Errorf("Missing client certificate %s for key %s", certName, keyName)
+ return invalidParamf("missing client certificate %s for key %s", certName, keyName)
}
}
}
@@ -120,9 +112,9 @@ func Headers(userAgent string, metaHeaders http.Header) []transport.RequestModif
return modifiers
}
-// HTTPClient returns an HTTP client structure which uses the given transport
+// httpClient returns an HTTP client structure which uses the given transport
// and contains the necessary headers for redirected requests
-func HTTPClient(transport http.RoundTripper) *http.Client {
+func httpClient(transport http.RoundTripper) *http.Client {
return &http.Client{
Transport: transport,
CheckRedirect: addRequiredHeadersToRedirectedRequests,
@@ -165,9 +157,9 @@ func addRequiredHeadersToRedirectedRequests(req *http.Request, via []*http.Reque
return nil
}
-// NewTransport returns a new HTTP transport. If tlsConfig is nil, it uses the
+// newTransport returns a new HTTP transport. If tlsConfig is nil, it uses the
// default TLS configuration.
-func NewTransport(tlsConfig *tls.Config) *http.Transport {
+func newTransport(tlsConfig *tls.Config) *http.Transport {
if tlsConfig == nil {
tlsConfig = tlsconfig.ServerDefault()
}
@@ -177,7 +169,7 @@ func NewTransport(tlsConfig *tls.Config) *http.Transport {
KeepAlive: 30 * time.Second,
}
- base := &http.Transport{
+ return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: direct.DialContext,
TLSHandshakeTimeout: 10 * time.Second,
@@ -185,6 +177,4 @@ func NewTransport(tlsConfig *tls.Config) *http.Transport {
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
DisableKeepAlives: true,
}
-
- return base
}
diff --git a/vendor/github.com/docker/docker/registry/service.go b/vendor/github.com/docker/docker/registry/service.go
index 276b04724a..25b116a279 100644
--- a/vendor/github.com/docker/docker/registry/service.go
+++ b/vendor/github.com/docker/docker/registry/service.go
@@ -11,102 +11,74 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/docker/api/types"
- registrytypes "github.com/docker/docker/api/types/registry"
+ "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
- "github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
-const (
- // DefaultSearchLimit is the default value for maximum number of returned search results.
- DefaultSearchLimit = 25
-)
-
// Service is the interface defining what a registry service should implement.
type Service interface {
Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error)
LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error)
LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error)
ResolveRepository(name reference.Named) (*RepositoryInfo, error)
- Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error)
- ServiceConfig() *registrytypes.ServiceConfig
- TLSConfig(hostname string) (*tls.Config, error)
+ Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error)
+ ServiceConfig() *registry.ServiceConfig
LoadAllowNondistributableArtifacts([]string) error
LoadMirrors([]string) error
LoadInsecureRegistries([]string) error
}
-// DefaultService is a registry service. It tracks configuration data such as a list
+// defaultService is a registry service. It tracks configuration data such as a list
// of mirrors.
-type DefaultService struct {
+type defaultService struct {
config *serviceConfig
- mu sync.Mutex
+ mu sync.RWMutex
}
-// NewService returns a new instance of DefaultService ready to be
+// NewService returns a new instance of defaultService ready to be
// installed into an engine.
-func NewService(options ServiceOptions) (*DefaultService, error) {
+func NewService(options ServiceOptions) (Service, error) {
config, err := newServiceConfig(options)
- return &DefaultService{config: config}, err
+ return &defaultService{config: config}, err
}
-// ServiceConfig returns the public registry service configuration.
-func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- servConfig := registrytypes.ServiceConfig{
- AllowNondistributableArtifactsCIDRs: make([]*(registrytypes.NetIPNet), 0),
- AllowNondistributableArtifactsHostnames: make([]string, 0),
- InsecureRegistryCIDRs: make([]*(registrytypes.NetIPNet), 0),
- IndexConfigs: make(map[string]*(registrytypes.IndexInfo)),
- Mirrors: make([]string, 0),
- }
-
- // construct a new ServiceConfig which will not retrieve s.Config directly,
- // and look up items in s.config with mu locked
- servConfig.AllowNondistributableArtifactsCIDRs = append(servConfig.AllowNondistributableArtifactsCIDRs, s.config.ServiceConfig.AllowNondistributableArtifactsCIDRs...)
- servConfig.AllowNondistributableArtifactsHostnames = append(servConfig.AllowNondistributableArtifactsHostnames, s.config.ServiceConfig.AllowNondistributableArtifactsHostnames...)
- servConfig.InsecureRegistryCIDRs = append(servConfig.InsecureRegistryCIDRs, s.config.ServiceConfig.InsecureRegistryCIDRs...)
-
- for key, value := range s.config.ServiceConfig.IndexConfigs {
- servConfig.IndexConfigs[key] = value
- }
-
- servConfig.Mirrors = append(servConfig.Mirrors, s.config.ServiceConfig.Mirrors...)
-
- return &servConfig
+// ServiceConfig returns a copy of the public registry service's configuration.
+func (s *defaultService) ServiceConfig() *registry.ServiceConfig {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ return s.config.copy()
}
// LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries for Service.
-func (s *DefaultService) LoadAllowNondistributableArtifacts(registries []string) error {
+func (s *defaultService) LoadAllowNondistributableArtifacts(registries []string) error {
s.mu.Lock()
defer s.mu.Unlock()
- return s.config.LoadAllowNondistributableArtifacts(registries)
+ return s.config.loadAllowNondistributableArtifacts(registries)
}
// LoadMirrors loads registry mirrors for Service
-func (s *DefaultService) LoadMirrors(mirrors []string) error {
+func (s *defaultService) LoadMirrors(mirrors []string) error {
s.mu.Lock()
defer s.mu.Unlock()
- return s.config.LoadMirrors(mirrors)
+ return s.config.loadMirrors(mirrors)
}
// LoadInsecureRegistries loads insecure registries for Service
-func (s *DefaultService) LoadInsecureRegistries(registries []string) error {
+func (s *defaultService) LoadInsecureRegistries(registries []string) error {
s.mu.Lock()
defer s.mu.Unlock()
- return s.config.LoadInsecureRegistries(registries)
+ return s.config.loadInsecureRegistries(registries)
}
// Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was successful.
// It can be used to verify the validity of a client's credentials.
-func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) {
+func (s *defaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) {
// TODO Use ctx when searching for repositories
var registryHostName = IndexHostname
@@ -117,7 +89,7 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig,
}
u, err := url.Parse(serverAddress)
if err != nil {
- return "", "", errdefs.InvalidParameter(errors.Errorf("unable to parse server address: %v", err))
+ return "", "", invalidParamWrapf(err, "unable to parse server address")
}
registryHostName = u.Host
}
@@ -127,7 +99,7 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig,
// to a mirror.
endpoints, err := s.LookupPushEndpoints(registryHostName)
if err != nil {
- return "", "", errdefs.InvalidParameter(err)
+ return "", "", invalidParam(err)
}
for _, endpoint := range endpoints {
@@ -159,25 +131,28 @@ func splitReposSearchTerm(reposName string) (string, string) {
// Search queries the public registry for images matching the specified
// search terms, and returns the results.
-func (s *DefaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
+func (s *defaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) {
// TODO Use ctx when searching for repositories
- if err := validateNoScheme(term); err != nil {
- return nil, err
+ if hasScheme(term) {
+ return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)
}
indexName, remoteName := splitReposSearchTerm(term)
// Search is a long-running operation, just lock s.config to avoid block others.
- s.mu.Lock()
+ s.mu.RLock()
index, err := newIndexInfo(s.config, indexName)
- s.mu.Unlock()
+ s.mu.RUnlock()
if err != nil {
return nil, err
}
+ if index.Official {
+ // If pull "library/foo", it's stored locally under "foo"
+ remoteName = strings.TrimPrefix(remoteName, "library/")
+ }
- // *TODO: Search multiple indexes.
- endpoint, err := NewV1Endpoint(index, userAgent, headers)
+ endpoint, err := newV1Endpoint(index, userAgent, headers)
if err != nil {
return nil, err
}
@@ -195,43 +170,30 @@ func (s *DefaultService) Search(ctx context.Context, term string, limit int, aut
modifiers := Headers(userAgent, nil)
v2Client, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes)
if err != nil {
- if fErr, ok := err.(fallbackError); ok {
- logrus.Errorf("Cannot use identity token for search, v2 auth not supported: %v", fErr.err)
- } else {
- return nil, err
- }
- } else {
- // Copy non transport http client features
- v2Client.Timeout = endpoint.client.Timeout
- v2Client.CheckRedirect = endpoint.client.CheckRedirect
- v2Client.Jar = endpoint.client.Jar
-
- logrus.Debugf("using v2 client for search to %s", endpoint.URL)
- client = v2Client
+ return nil, err
}
- }
+ // Copy non transport http client features
+ v2Client.Timeout = endpoint.client.Timeout
+ v2Client.CheckRedirect = endpoint.client.CheckRedirect
+ v2Client.Jar = endpoint.client.Jar
- if client == nil {
+ logrus.Debugf("using v2 client for search to %s", endpoint.URL)
+ client = v2Client
+ } else {
client = endpoint.client
if err := authorizeClient(client, authConfig, endpoint); err != nil {
return nil, err
}
}
- r := newSession(client, authConfig, endpoint)
-
- if index.Official {
- // If pull "library/foo", it's stored locally under "foo"
- remoteName = strings.TrimPrefix(remoteName, "library/")
- }
- return r.SearchRepositories(remoteName, limit)
+ return newSession(client, endpoint).searchRepositories(remoteName, limit)
}
// ResolveRepository splits a repository name into its components
// and configuration of the associated registry.
-func (s *DefaultService) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
- s.mu.Lock()
- defer s.mu.Unlock()
+func (s *defaultService) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
return newRepositoryInfo(s.config, name)
}
@@ -246,33 +208,20 @@ type APIEndpoint struct {
TLSConfig *tls.Config
}
-// TLSConfig constructs a client TLS configuration based on server defaults
-func (s *DefaultService) TLSConfig(hostname string) (*tls.Config, error) {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- return s.tlsConfig(hostname)
-}
-
-// tlsConfig constructs a client TLS configuration based on server defaults
-func (s *DefaultService) tlsConfig(hostname string) (*tls.Config, error) {
- return newTLSConfig(hostname, isSecureIndex(s.config, hostname))
-}
-
// LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference.
// It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP.
-func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
- s.mu.Lock()
- defer s.mu.Unlock()
+func (s *defaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
return s.lookupV2Endpoints(hostname)
}
// LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference.
// It gives preference to HTTPS over plain HTTP. Mirrors are not included.
-func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
- s.mu.Lock()
- defer s.mu.Unlock()
+func (s *defaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
allEndpoints, err := s.lookupV2Endpoints(hostname)
if err == nil {
diff --git a/vendor/github.com/docker/docker/registry/service_v2.go b/vendor/github.com/docker/docker/registry/service_v2.go
index 46f28ebccf..f147af0faa 100644
--- a/vendor/github.com/docker/docker/registry/service_v2.go
+++ b/vendor/github.com/docker/docker/registry/service_v2.go
@@ -7,8 +7,7 @@ import (
"github.com/docker/go-connections/tlsconfig"
)
-func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
- tlsConfig := tlsconfig.ServerDefault()
+func (s *defaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
if hostname == DefaultNamespace || hostname == IndexHostname {
for _, mirror := range s.config.Mirrors {
if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
@@ -16,9 +15,9 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp
}
mirrorURL, err := url.Parse(mirror)
if err != nil {
- return nil, err
+ return nil, invalidParam(err)
}
- mirrorTLSConfig, err := s.tlsConfig(mirrorURL.Host)
+ mirrorTLSConfig, err := newTLSConfig(mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host))
if err != nil {
return nil, err
}
@@ -35,19 +34,18 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp
Version: APIVersion2,
Official: true,
TrimHostname: true,
- TLSConfig: tlsConfig,
+ TLSConfig: tlsconfig.ServerDefault(),
})
return endpoints, nil
}
- ana := allowNondistributableArtifacts(s.config, hostname)
-
- tlsConfig, err = s.tlsConfig(hostname)
+ tlsConfig, err := newTLSConfig(hostname, s.config.isSecureIndex(hostname))
if err != nil {
return nil, err
}
+ ana := s.config.allowNondistributableArtifacts(hostname)
endpoints = []APIEndpoint{
{
URL: &url.URL{
diff --git a/vendor/github.com/docker/docker/registry/session.go b/vendor/github.com/docker/docker/registry/session.go
index d34dc1e58a..fd193e1dd6 100644
--- a/vendor/github.com/docker/docker/registry/session.go
+++ b/vendor/github.com/docker/docker/registry/session.go
@@ -12,7 +12,7 @@ import (
"sync"
"github.com/docker/docker/api/types"
- registrytypes "github.com/docker/docker/api/types/registry"
+ "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonmessage"
@@ -21,13 +21,11 @@ import (
"github.com/sirupsen/logrus"
)
-// A Session is used to communicate with a V1 registry
-type Session struct {
- indexEndpoint *V1Endpoint
+// A session is used to communicate with a V1 registry
+type session struct {
+ indexEndpoint *v1Endpoint
client *http.Client
- // TODO(tiborvass): remove authConfig
- authConfig *types.AuthConfig
- id string
+ id string
}
type authTransport struct {
@@ -41,7 +39,7 @@ type authTransport struct {
modReq map[*http.Request]*http.Request // original -> modified
}
-// AuthTransport handles the auth layer when communicating with a v1 registry (private or official)
+// newAuthTransport handles the auth layer when communicating with a v1 registry (private or official)
//
// For private v1 registries, set alwaysSetBasicAuth to true.
//
@@ -54,7 +52,7 @@ type authTransport struct {
// If the server sends a token without the client having requested it, it is ignored.
//
// This RoundTripper also has a CancelRequest method important for correct timeout handling.
-func AuthTransport(base http.RoundTripper, authConfig *types.AuthConfig, alwaysSetBasicAuth bool) http.RoundTripper {
+func newAuthTransport(base http.RoundTripper, authConfig *types.AuthConfig, alwaysSetBasicAuth bool) *authTransport {
if base == nil {
base = http.DefaultTransport
}
@@ -149,13 +147,13 @@ func (tr *authTransport) CancelRequest(req *http.Request) {
}
}
-func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) error {
+func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint *v1Endpoint) error {
var alwaysSetBasicAuth bool
// If we're working with a standalone private registry over HTTPS, send Basic Auth headers
// alongside all our requests.
if endpoint.String() != IndexServer && endpoint.URL.Scheme == "https" {
- info, err := endpoint.Ping()
+ info, err := endpoint.ping()
if err != nil {
return err
}
@@ -167,47 +165,42 @@ func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint
// Annotate the transport unconditionally so that v2 can
// properly fallback on v1 when an image is not found.
- client.Transport = AuthTransport(client.Transport, authConfig, alwaysSetBasicAuth)
+ client.Transport = newAuthTransport(client.Transport, authConfig, alwaysSetBasicAuth)
jar, err := cookiejar.New(nil)
if err != nil {
- return errors.New("cookiejar.New is not supposed to return an error")
+ return errdefs.System(errors.New("cookiejar.New is not supposed to return an error"))
}
client.Jar = jar
return nil
}
-func newSession(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) *Session {
- return &Session{
- authConfig: authConfig,
+func newSession(client *http.Client, endpoint *v1Endpoint) *session {
+ return &session{
client: client,
indexEndpoint: endpoint,
id: stringid.GenerateRandomID(),
}
}
-// NewSession creates a new session
-// TODO(tiborvass): remove authConfig param once registry client v2 is vendored
-func NewSession(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) (*Session, error) {
- if err := authorizeClient(client, authConfig, endpoint); err != nil {
- return nil, err
+// defaultSearchLimit is the default value for maximum number of returned search results.
+const defaultSearchLimit = 25
+
+// searchRepositories performs a search against the remote repository
+func (r *session) searchRepositories(term string, limit int) (*registry.SearchResults, error) {
+ if limit == 0 {
+ limit = defaultSearchLimit
}
-
- return newSession(client, authConfig, endpoint), nil
-}
-
-// SearchRepositories performs a search against the remote repository
-func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.SearchResults, error) {
if limit < 1 || limit > 100 {
- return nil, errdefs.InvalidParameter(errors.Errorf("Limit %d is outside the range of [1, 100]", limit))
+ return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
}
logrus.Debugf("Index server: %s", r.indexEndpoint)
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
- return nil, errors.Wrap(errdefs.InvalidParameter(err), "Error building request")
+ return nil, invalidParamWrapf(err, "error building request")
}
// Have the AuthTransport send authentication, when logged in.
req.Header.Set("X-Docker-Token", "true")
@@ -222,6 +215,6 @@ func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.Sea
Code: res.StatusCode,
}
}
- result := new(registrytypes.SearchResults)
+ result := new(registry.SearchResults)
return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results")
}
diff --git a/vendor/github.com/docker/docker/registry/types.go b/vendor/github.com/docker/docker/registry/types.go
index 073e244ba8..37094737f2 100644
--- a/vendor/github.com/docker/docker/registry/types.go
+++ b/vendor/github.com/docker/docker/registry/types.go
@@ -2,39 +2,9 @@ package registry // import "github.com/docker/docker/registry"
import (
"github.com/docker/distribution/reference"
- registrytypes "github.com/docker/docker/api/types/registry"
+ "github.com/docker/docker/api/types/registry"
)
-// RepositoryData tracks the image list, list of endpoints for a repository
-type RepositoryData struct {
- // ImgList is a list of images in the repository
- ImgList map[string]*ImgData
- // Endpoints is a list of endpoints returned in X-Docker-Endpoints
- Endpoints []string
-}
-
-// ImgData is used to transfer image checksums to and from the registry
-type ImgData struct {
- // ID is an opaque string that identifies the image
- ID string `json:"id"`
- Checksum string `json:"checksum,omitempty"`
- ChecksumPayload string `json:"-"`
- Tag string `json:",omitempty"`
-}
-
-// PingResult contains the information returned when pinging a registry. It
-// indicates the registry's version and whether the registry claims to be a
-// standalone registry.
-type PingResult struct {
- // Version is the registry version supplied by the registry in an HTTP
- // header
- Version string `json:"version"`
- // Standalone is set to true if the registry indicates it is a
- // standalone registry in the X-Docker-Registry-Standalone
- // header
- Standalone bool `json:"standalone"`
-}
-
// APIVersion is an integral representation of an API version (presently
// either 1 or 2)
type APIVersion int
@@ -58,7 +28,7 @@ var apiVersions = map[APIVersion]string{
type RepositoryInfo struct {
Name reference.Named
// Index points to registry information
- Index *registrytypes.IndexInfo
+ Index *registry.IndexInfo
// Official indicates whether the repository is considered official.
// If the registry is official, and the normalized name does not
// contain a '/' (e.g. "foo"), then it is considered an official repo.
diff --git a/vendor/github.com/docker/docker/rootless/rootless.go b/vendor/github.com/docker/docker/rootless/rootless.go
deleted file mode 100644
index 376d5263de..0000000000
--- a/vendor/github.com/docker/docker/rootless/rootless.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package rootless // import "github.com/docker/docker/rootless"
-
-import (
- "os"
- "sync"
-)
-
-const (
- // RootlessKitDockerProxyBinary is the binary name of rootlesskit-docker-proxy
- RootlessKitDockerProxyBinary = "rootlesskit-docker-proxy"
-)
-
-var (
- runningWithRootlessKit bool
- runningWithRootlessKitOnce sync.Once
-)
-
-// RunningWithRootlessKit returns true if running under RootlessKit namespaces.
-func RunningWithRootlessKit() bool {
- runningWithRootlessKitOnce.Do(func() {
- u := os.Getenv("ROOTLESSKIT_STATE_DIR")
- runningWithRootlessKit = u != ""
- })
- return runningWithRootlessKit
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index efd801a0ad..822b8e43ac 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -39,7 +39,7 @@ github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory
github.com/docker/distribution/uuid
-# github.com/docker/docker v20.10.7+incompatible => github.com/docker/docker v20.10.3-0.20220309172631-83b51522df43+incompatible
+# github.com/docker/docker v20.10.14+incompatible => github.com/docker/docker v20.10.3-0.20220326171151-8941dcfcc5db+incompatible
## explicit
github.com/docker/docker/api
github.com/docker/docker/api/types
@@ -75,7 +75,6 @@ github.com/docker/docker/pkg/stringid
github.com/docker/docker/pkg/system
github.com/docker/docker/pkg/urlutil
github.com/docker/docker/registry
-github.com/docker/docker/rootless
# github.com/docker/docker-credential-helpers v0.6.4
## explicit; go 1.13
github.com/docker/docker-credential-helpers/client
@@ -385,5 +384,5 @@ gotest.tools/v3/internal/format
gotest.tools/v3/internal/source
gotest.tools/v3/poll
gotest.tools/v3/skip
-# github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220309172631-83b51522df43+incompatible
+# github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220326171151-8941dcfcc5db+incompatible
# github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2