mirror of https://github.com/docker/cli.git
Merge pull request #2110 from tiborvass/update-vendor
vendor: align with engine at b6684a403c99aaf6be5b8ce0bef3c6650fcdcd12
This commit is contained in:
commit
3e07fa728a
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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="],"Warnings":null,"ServerErrors":["an error happened"],"ClientInfo":{"Debug":false,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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="],"Warnings":null,"ServerErrors":["an error happened"],"ClientInfo":{"Debug":false,"Plugins":[],"Warnings":null}}
|
||||||
|
|
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No kernel memory 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,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No kernel memory 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,"Plugins":[],"Warnings":null}}
|
||||||
|
|
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":true,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":true,"Plugins":[],"Warnings":null}}
|
||||||
|
|
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":true,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":true,"Plugins":[],"Warnings":null}}
|
||||||
|
|
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":false,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":false,"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}}
|
||||||
|
|
|
@ -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"]],"SystemStatus":null,"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","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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":false,"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"]],"SystemStatus":null,"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","ClusterStore":"","ClusterAdvertise":"","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"],"Warnings":null,"ClientInfo":{"Debug":false,"Plugins":[],"Warnings":null}}
|
||||||
|
|
12
vendor.conf
12
vendor.conf
|
@ -4,10 +4,10 @@ github.com/asaskevich/govalidator f9ffefc3facfbe0caee3fea233cb
|
||||||
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
||||||
github.com/beorn7/perks e7f67b54abbeac9c40a31de0f81159e4cafebd6a
|
github.com/beorn7/perks e7f67b54abbeac9c40a31de0f81159e4cafebd6a
|
||||||
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
||||||
github.com/containerd/containerd 3a3f0aac8819165839a41fee77a4f4ac8b103097
|
github.com/containerd/containerd 7c1e88399ec0b0b077121d9d5ad97e647b11c870
|
||||||
github.com/containerd/continuity aaeac12a7ffcd198ae25440a9dff125c2e2703a7
|
github.com/containerd/continuity aaeac12a7ffcd198ae25440a9dff125c2e2703a7
|
||||||
github.com/containerd/fifo a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c
|
github.com/containerd/fifo a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c
|
||||||
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
||||||
github.com/containerd/typeurl 2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d
|
github.com/containerd/typeurl 2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d
|
||||||
github.com/coreos/etcd d57e8b8d97adfc4a6c224fe116714bf1a1f3beb9 # v3.3.12
|
github.com/coreos/etcd d57e8b8d97adfc4a6c224fe116714bf1a1f3beb9 # v3.3.12
|
||||||
github.com/cpuguy83/go-md2man 20f5889cbdc3c73dbd2862796665e7c465ade7d1 # v1.0.8
|
github.com/cpuguy83/go-md2man 20f5889cbdc3c73dbd2862796665e7c465ade7d1 # v1.0.8
|
||||||
|
@ -16,7 +16,7 @@ github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff7826
|
||||||
github.com/dgrijalva/jwt-go a2c85815a77d0f951e33ba4db5ae93629a1530af
|
github.com/dgrijalva/jwt-go a2c85815a77d0f951e33ba4db5ae93629a1530af
|
||||||
github.com/docker/compose-on-kubernetes cc4914dfd1b6684a9750a59f3613fc0a95291824 # v0.4.23
|
github.com/docker/compose-on-kubernetes cc4914dfd1b6684a9750a59f3613fc0a95291824 # v0.4.23
|
||||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||||
github.com/docker/docker 3998dffb806f3887f804b813069f59bc14a7f3c1
|
github.com/docker/docker b6684a403c99aaf6be5b8ce0bef3c6650fcdcd12
|
||||||
github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3
|
github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3
|
||||||
github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions.
|
github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions.
|
||||||
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
||||||
|
@ -25,7 +25,7 @@ github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a
|
||||||
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
||||||
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
||||||
github.com/docker/licensing 9781369abdb5281cdc07a2a446c6df01347ec793
|
github.com/docker/licensing 9781369abdb5281cdc07a2a446c6df01347ec793
|
||||||
github.com/docker/swarmkit 59163bf75df38489d4a10392265d27156dc473c5
|
github.com/docker/swarmkit 7dded76ec532741c1ad9736cd2bb6d6661f0a386
|
||||||
github.com/evanphx/json-patch 72bf35d0ff611848c1dc9df0f976c81192392fa5 # v4.1.0
|
github.com/evanphx/json-patch 72bf35d0ff611848c1dc9df0f976c81192392fa5 # v4.1.0
|
||||||
github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0d3388b300c53 # v0.7.0
|
github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0d3388b300c53 # v0.7.0
|
||||||
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
||||||
|
@ -49,7 +49,7 @@ github.com/json-iterator/go 0ff49de124c6f76f8494e194af75
|
||||||
github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d86a2c9b5b50e # v1.0.2
|
github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d86a2c9b5b50e # v1.0.2
|
||||||
github.com/mattn/go-shellwords a72fbe27a1b0ed0df2f02754945044ce1456608b # v1.0.5
|
github.com/mattn/go-shellwords a72fbe27a1b0ed0df2f02754945044ce1456608b # v1.0.5
|
||||||
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
|
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
|
||||||
github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5205c12027fac
|
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
|
||||||
github.com/Microsoft/hcsshim 672e52e9209d1e53718c1b6a7d68cc9272654ab5
|
github.com/Microsoft/hcsshim 672e52e9209d1e53718c1b6a7d68cc9272654ab5
|
||||||
github.com/miekg/pkcs11 cb39313ec884f2cd77f4762875fe96aecf68f8e3 # v1.0.2
|
github.com/miekg/pkcs11 cb39313ec884f2cd77f4762875fe96aecf68f8e3 # v1.0.2
|
||||||
github.com/mitchellh/mapstructure f15292f7a699fcc1a38a80977f80a046874ba8ac
|
github.com/mitchellh/mapstructure f15292f7a699fcc1a38a80977f80a046874ba8ac
|
||||||
|
@ -87,7 +87,7 @@ golang.org/x/sys 9eafafc0a87e0fd0aeeba439a457
|
||||||
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
|
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
|
||||||
golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
|
golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
|
||||||
google.golang.org/genproto 02b4e95473316948020af0b7a4f0f22c73929b0e
|
google.golang.org/genproto 02b4e95473316948020af0b7a4f0f22c73929b0e
|
||||||
google.golang.org/grpc 25c4f928eaa6d96443009bd842389fb4fa48664e # v1.20.1
|
google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
|
||||||
gopkg.in/inf.v0 d2d2541c53f18d2a059457998ce2876cc8e67cbf # v0.9.1
|
gopkg.in/inf.v0 d2d2541c53f18d2a059457998ce2876cc8e67cbf # v0.9.1
|
||||||
gopkg.in/yaml.v2 bb4e33bf68bf89cad44d386192cbed201f35b241 # v2.2.3
|
gopkg.in/yaml.v2 bb4e33bf68bf89cad44d386192cbed201f35b241 # v2.2.3
|
||||||
gotest.tools 1083505acf35a0bd8a696b26837e1fb3187a7a83 # v2.3.0
|
gotest.tools 1083505acf35a0bd8a696b26837e1fb3187a7a83 # v2.3.0
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
||||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||||
|
//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
|
||||||
|
|
||||||
type atomicBool int32
|
type atomicBool int32
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ type win32File struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
wgLock sync.RWMutex
|
wgLock sync.RWMutex
|
||||||
closing atomicBool
|
closing atomicBool
|
||||||
|
socket bool
|
||||||
readDeadline deadlineHandler
|
readDeadline deadlineHandler
|
||||||
writeDeadline deadlineHandler
|
writeDeadline deadlineHandler
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,13 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||||
return makeWin32File(h)
|
// If we return the result of makeWin32File directly, it can result in an
|
||||||
|
// interface-wrapped nil, rather than a nil interface value.
|
||||||
|
f, err := makeWin32File(h)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeHandle closes the resources associated with a Win32 handle
|
// closeHandle closes the resources associated with a Win32 handle
|
||||||
|
@ -190,6 +198,10 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
|
||||||
if f.closing.isSet() {
|
if f.closing.isSet() {
|
||||||
err = ErrFileClosed
|
err = ErrFileClosed
|
||||||
}
|
}
|
||||||
|
} else if err != nil && f.socket {
|
||||||
|
// err is from Win32. Query the overlapped structure to get the winsock error.
|
||||||
|
var bytes, flags uint32
|
||||||
|
err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
|
||||||
}
|
}
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
cancelIoEx(f.handle, &c.o)
|
cancelIoEx(f.handle, &c.o)
|
||||||
|
@ -265,6 +277,10 @@ func (f *win32File) Flush() error {
|
||||||
return syscall.FlushFileBuffers(f.handle)
|
return syscall.FlushFileBuffers(f.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *win32File) Fd() uintptr {
|
||||||
|
return uintptr(f.handle)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *deadlineHandler) set(deadline time.Time) error {
|
func (d *deadlineHandler) set(deadline time.Time) error {
|
||||||
d.setLock.Lock()
|
d.setLock.Lock()
|
||||||
defer d.setLock.Unlock()
|
defer d.setLock.Unlock()
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
module github.com/Microsoft/go-winio
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/pkg/errors v0.8.1
|
||||||
|
github.com/sirupsen/logrus v1.4.1
|
||||||
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
|
||||||
|
)
|
|
@ -0,0 +1,305 @@
|
||||||
|
package winio
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
|
)
|
||||||
|
|
||||||
|
//sys bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
|
||||||
|
|
||||||
|
const (
|
||||||
|
afHvSock = 34 // AF_HYPERV
|
||||||
|
|
||||||
|
socketError = ^uintptr(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// An HvsockAddr is an address for a AF_HYPERV socket.
|
||||||
|
type HvsockAddr struct {
|
||||||
|
VMID guid.GUID
|
||||||
|
ServiceID guid.GUID
|
||||||
|
}
|
||||||
|
|
||||||
|
type rawHvsockAddr struct {
|
||||||
|
Family uint16
|
||||||
|
_ uint16
|
||||||
|
VMID guid.GUID
|
||||||
|
ServiceID guid.GUID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network returns the address's network name, "hvsock".
|
||||||
|
func (addr *HvsockAddr) Network() string {
|
||||||
|
return "hvsock"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (addr *HvsockAddr) String() string {
|
||||||
|
return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
|
||||||
|
func VsockServiceID(port uint32) guid.GUID {
|
||||||
|
g, _ := guid.FromString("00000000-facb-11e6-bd58-64006a7986d3")
|
||||||
|
g.Data1 = port
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
|
func (addr *HvsockAddr) raw() rawHvsockAddr {
|
||||||
|
return rawHvsockAddr{
|
||||||
|
Family: afHvSock,
|
||||||
|
VMID: addr.VMID,
|
||||||
|
ServiceID: addr.ServiceID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
|
||||||
|
addr.VMID = raw.VMID
|
||||||
|
addr.ServiceID = raw.ServiceID
|
||||||
|
}
|
||||||
|
|
||||||
|
// HvsockListener is a socket listener for the AF_HYPERV address family.
|
||||||
|
type HvsockListener struct {
|
||||||
|
sock *win32File
|
||||||
|
addr HvsockAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// HvsockConn is a connected socket of the AF_HYPERV address family.
|
||||||
|
type HvsockConn struct {
|
||||||
|
sock *win32File
|
||||||
|
local, remote HvsockAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func newHvSocket() (*win32File, error) {
|
||||||
|
fd, err := syscall.Socket(afHvSock, syscall.SOCK_STREAM, 1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.NewSyscallError("socket", err)
|
||||||
|
}
|
||||||
|
f, err := makeWin32File(fd)
|
||||||
|
if err != nil {
|
||||||
|
syscall.Close(fd)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.socket = true
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenHvsock listens for connections on the specified hvsock address.
|
||||||
|
func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
|
||||||
|
l := &HvsockListener{addr: *addr}
|
||||||
|
sock, err := newHvSocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("listen", err)
|
||||||
|
}
|
||||||
|
sa := addr.raw()
|
||||||
|
err = bind(sock.handle, unsafe.Pointer(&sa), int32(unsafe.Sizeof(sa)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("listen", os.NewSyscallError("socket", err))
|
||||||
|
}
|
||||||
|
err = syscall.Listen(sock.handle, 16)
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("listen", os.NewSyscallError("listen", err))
|
||||||
|
}
|
||||||
|
return &HvsockListener{sock: sock, addr: *addr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *HvsockListener) opErr(op string, err error) error {
|
||||||
|
return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr returns the listener's network address.
|
||||||
|
func (l *HvsockListener) Addr() net.Addr {
|
||||||
|
return &l.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept waits for the next connection and returns it.
|
||||||
|
func (l *HvsockListener) Accept() (_ net.Conn, err error) {
|
||||||
|
sock, err := newHvSocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("accept", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if sock != nil {
|
||||||
|
sock.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c, err := l.sock.prepareIo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("accept", err)
|
||||||
|
}
|
||||||
|
defer l.sock.wg.Done()
|
||||||
|
|
||||||
|
// AcceptEx, per documentation, requires an extra 16 bytes per address.
|
||||||
|
const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
|
||||||
|
var addrbuf [addrlen * 2]byte
|
||||||
|
|
||||||
|
var bytes uint32
|
||||||
|
err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0, addrlen, addrlen, &bytes, &c.o)
|
||||||
|
_, err = l.sock.asyncIo(c, nil, bytes, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
|
||||||
|
}
|
||||||
|
conn := &HvsockConn{
|
||||||
|
sock: sock,
|
||||||
|
}
|
||||||
|
conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
|
||||||
|
conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
|
||||||
|
sock = nil
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the listener, causing any pending Accept calls to fail.
|
||||||
|
func (l *HvsockListener) Close() error {
|
||||||
|
return l.sock.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to finish ConnectEx handling
|
||||||
|
func DialHvsock(ctx context.Context, addr *HvsockAddr) (*HvsockConn, error) {
|
||||||
|
sock, err := newHvSocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if sock != nil {
|
||||||
|
sock.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c, err := sock.prepareIo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer sock.wg.Done()
|
||||||
|
var bytes uint32
|
||||||
|
err = windows.ConnectEx(windows.Handle(sock.handle), sa, nil, 0, &bytes, &c.o)
|
||||||
|
_, err = sock.asyncIo(ctx, c, nil, bytes, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conn := &HvsockConn{
|
||||||
|
sock: sock,
|
||||||
|
remote: *addr,
|
||||||
|
}
|
||||||
|
sock = nil
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (conn *HvsockConn) opErr(op string, err error) error {
|
||||||
|
return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *HvsockConn) Read(b []byte) (int, error) {
|
||||||
|
c, err := conn.sock.prepareIo()
|
||||||
|
if err != nil {
|
||||||
|
return 0, conn.opErr("read", err)
|
||||||
|
}
|
||||||
|
defer conn.sock.wg.Done()
|
||||||
|
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||||
|
var flags, bytes uint32
|
||||||
|
err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
|
||||||
|
n, err := conn.sock.asyncIo(c, &conn.sock.readDeadline, bytes, err)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(syscall.Errno); ok {
|
||||||
|
err = os.NewSyscallError("wsarecv", err)
|
||||||
|
}
|
||||||
|
return 0, conn.opErr("read", err)
|
||||||
|
} else if n == 0 {
|
||||||
|
err = io.EOF
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *HvsockConn) Write(b []byte) (int, error) {
|
||||||
|
t := 0
|
||||||
|
for len(b) != 0 {
|
||||||
|
n, err := conn.write(b)
|
||||||
|
if err != nil {
|
||||||
|
return t + n, err
|
||||||
|
}
|
||||||
|
t += n
|
||||||
|
b = b[n:]
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *HvsockConn) write(b []byte) (int, error) {
|
||||||
|
c, err := conn.sock.prepareIo()
|
||||||
|
if err != nil {
|
||||||
|
return 0, conn.opErr("write", err)
|
||||||
|
}
|
||||||
|
defer conn.sock.wg.Done()
|
||||||
|
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||||
|
var bytes uint32
|
||||||
|
err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
|
||||||
|
n, err := conn.sock.asyncIo(c, &conn.sock.writeDeadline, bytes, err)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(syscall.Errno); ok {
|
||||||
|
err = os.NewSyscallError("wsasend", err)
|
||||||
|
}
|
||||||
|
return 0, conn.opErr("write", err)
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the socket connection, failing any pending read or write calls.
|
||||||
|
func (conn *HvsockConn) Close() error {
|
||||||
|
return conn.sock.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *HvsockConn) shutdown(how int) error {
|
||||||
|
err := syscall.Shutdown(conn.sock.handle, syscall.SHUT_RD)
|
||||||
|
if err != nil {
|
||||||
|
return os.NewSyscallError("shutdown", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseRead shuts down the read end of the socket.
|
||||||
|
func (conn *HvsockConn) CloseRead() error {
|
||||||
|
err := conn.shutdown(syscall.SHUT_RD)
|
||||||
|
if err != nil {
|
||||||
|
return conn.opErr("close", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseWrite shuts down the write end of the socket, notifying the other endpoint that
|
||||||
|
// no more data will be written.
|
||||||
|
func (conn *HvsockConn) CloseWrite() error {
|
||||||
|
err := conn.shutdown(syscall.SHUT_WR)
|
||||||
|
if err != nil {
|
||||||
|
return conn.opErr("close", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalAddr returns the local address of the connection.
|
||||||
|
func (conn *HvsockConn) LocalAddr() net.Addr {
|
||||||
|
return &conn.local
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteAddr returns the remote address of the connection.
|
||||||
|
func (conn *HvsockConn) RemoteAddr() net.Addr {
|
||||||
|
return &conn.remote
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDeadline implements the net.Conn SetDeadline method.
|
||||||
|
func (conn *HvsockConn) SetDeadline(t time.Time) error {
|
||||||
|
conn.SetReadDeadline(t)
|
||||||
|
conn.SetWriteDeadline(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReadDeadline implements the net.Conn SetReadDeadline method.
|
||||||
|
func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
|
||||||
|
return conn.sock.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
|
||||||
|
func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
|
||||||
|
return conn.sock.SetWriteDeadline(t)
|
||||||
|
}
|
|
@ -0,0 +1,235 @@
|
||||||
|
// Package guid provides a GUID type. The backing structure for a GUID is
|
||||||
|
// identical to that used by the golang.org/x/sys/windows GUID type.
|
||||||
|
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
||||||
|
// and the Windows (mixed-endian) encoding. See here for details:
|
||||||
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
|
||||||
|
package guid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Variant specifies which GUID variant (or "type") of the GUID. It determines
|
||||||
|
// how the entirety of the rest of the GUID is interpreted.
|
||||||
|
type Variant uint8
|
||||||
|
|
||||||
|
// The variants specified by RFC 4122.
|
||||||
|
const (
|
||||||
|
// VariantUnknown specifies a GUID variant which does not conform to one of
|
||||||
|
// the variant encodings specified in RFC 4122.
|
||||||
|
VariantUnknown Variant = iota
|
||||||
|
VariantNCS
|
||||||
|
VariantRFC4122
|
||||||
|
VariantMicrosoft
|
||||||
|
VariantFuture
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version specifies how the bits in the GUID were generated. For instance, a
|
||||||
|
// version 4 GUID is randomly generated, and a version 5 is generated from the
|
||||||
|
// hash of an input string.
|
||||||
|
type Version uint8
|
||||||
|
|
||||||
|
var _ = (encoding.TextMarshaler)(GUID{})
|
||||||
|
var _ = (encoding.TextUnmarshaler)(&GUID{})
|
||||||
|
|
||||||
|
// GUID represents a GUID/UUID. It has the same structure as
|
||||||
|
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||||
|
// that type. It is defined as its own type so that stringification and
|
||||||
|
// marshaling can be supported. The representation matches that used by native
|
||||||
|
// Windows code.
|
||||||
|
type GUID windows.GUID
|
||||||
|
|
||||||
|
// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
|
||||||
|
func NewV4() (GUID, error) {
|
||||||
|
var b [16]byte
|
||||||
|
if _, err := rand.Read(b[:]); err != nil {
|
||||||
|
return GUID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
g := FromArray(b)
|
||||||
|
g.setVersion(4) // Version 4 means randomly generated.
|
||||||
|
g.setVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
|
||||||
|
// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
|
||||||
|
// and the sample code treats it as a series of bytes, so we do the same here.
|
||||||
|
//
|
||||||
|
// Some implementations, such as those found on Windows, treat the name as a
|
||||||
|
// big-endian UTF16 stream of bytes. If that is desired, the string can be
|
||||||
|
// encoded as such before being passed to this function.
|
||||||
|
func NewV5(namespace GUID, name []byte) (GUID, error) {
|
||||||
|
b := sha1.New()
|
||||||
|
namespaceBytes := namespace.ToArray()
|
||||||
|
b.Write(namespaceBytes[:])
|
||||||
|
b.Write(name)
|
||||||
|
|
||||||
|
a := [16]byte{}
|
||||||
|
copy(a[:], b.Sum(nil))
|
||||||
|
|
||||||
|
g := FromArray(a)
|
||||||
|
g.setVersion(5) // Version 5 means generated from a string.
|
||||||
|
g.setVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromArray(b [16]byte, order binary.ByteOrder) GUID {
|
||||||
|
var g GUID
|
||||||
|
g.Data1 = order.Uint32(b[0:4])
|
||||||
|
g.Data2 = order.Uint16(b[4:6])
|
||||||
|
g.Data3 = order.Uint16(b[6:8])
|
||||||
|
copy(g.Data4[:], b[8:16])
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GUID) toArray(order binary.ByteOrder) [16]byte {
|
||||||
|
b := [16]byte{}
|
||||||
|
order.PutUint32(b[0:4], g.Data1)
|
||||||
|
order.PutUint16(b[4:6], g.Data2)
|
||||||
|
order.PutUint16(b[6:8], g.Data3)
|
||||||
|
copy(b[8:16], g.Data4[:])
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
|
||||||
|
func FromArray(b [16]byte) GUID {
|
||||||
|
return fromArray(b, binary.BigEndian)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToArray returns an array of 16 bytes representing the GUID in big-endian
|
||||||
|
// encoding.
|
||||||
|
func (g GUID) ToArray() [16]byte {
|
||||||
|
return g.toArray(binary.BigEndian)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
|
||||||
|
func FromWindowsArray(b [16]byte) GUID {
|
||||||
|
return fromArray(b, binary.LittleEndian)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
|
||||||
|
// encoding.
|
||||||
|
func (g GUID) ToWindowsArray() [16]byte {
|
||||||
|
return g.toArray(binary.LittleEndian)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GUID) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"%08x-%04x-%04x-%04x-%012x",
|
||||||
|
g.Data1,
|
||||||
|
g.Data2,
|
||||||
|
g.Data3,
|
||||||
|
g.Data4[:2],
|
||||||
|
g.Data4[2:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString parses a string containing a GUID and returns the GUID. The only
|
||||||
|
// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||||
|
// format.
|
||||||
|
func FromString(s string) (GUID, error) {
|
||||||
|
if len(s) != 36 {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
var g GUID
|
||||||
|
|
||||||
|
data1, err := strconv.ParseUint(s[0:8], 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
g.Data1 = uint32(data1)
|
||||||
|
|
||||||
|
data2, err := strconv.ParseUint(s[9:13], 16, 16)
|
||||||
|
if err != nil {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
g.Data2 = uint16(data2)
|
||||||
|
|
||||||
|
data3, err := strconv.ParseUint(s[14:18], 16, 16)
|
||||||
|
if err != nil {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
g.Data3 = uint16(data3)
|
||||||
|
|
||||||
|
for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
|
||||||
|
v, err := strconv.ParseUint(s[x:x+2], 16, 8)
|
||||||
|
if err != nil {
|
||||||
|
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||||
|
}
|
||||||
|
g.Data4[i] = uint8(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GUID) setVariant(v Variant) {
|
||||||
|
d := g.Data4[0]
|
||||||
|
switch v {
|
||||||
|
case VariantNCS:
|
||||||
|
d = (d & 0x7f)
|
||||||
|
case VariantRFC4122:
|
||||||
|
d = (d & 0x3f) | 0x80
|
||||||
|
case VariantMicrosoft:
|
||||||
|
d = (d & 0x1f) | 0xc0
|
||||||
|
case VariantFuture:
|
||||||
|
d = (d & 0x0f) | 0xe0
|
||||||
|
case VariantUnknown:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid variant: %d", v))
|
||||||
|
}
|
||||||
|
g.Data4[0] = d
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant returns the GUID variant, as defined in RFC 4122.
|
||||||
|
func (g GUID) Variant() Variant {
|
||||||
|
b := g.Data4[0]
|
||||||
|
if b&0x80 == 0 {
|
||||||
|
return VariantNCS
|
||||||
|
} else if b&0xc0 == 0x80 {
|
||||||
|
return VariantRFC4122
|
||||||
|
} else if b&0xe0 == 0xc0 {
|
||||||
|
return VariantMicrosoft
|
||||||
|
} else if b&0xe0 == 0xe0 {
|
||||||
|
return VariantFuture
|
||||||
|
}
|
||||||
|
return VariantUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GUID) setVersion(v Version) {
|
||||||
|
g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns the GUID version, as defined in RFC 4122.
|
||||||
|
func (g GUID) Version() Version {
|
||||||
|
return Version((g.Data3 & 0xF000) >> 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText returns the textual representation of the GUID.
|
||||||
|
func (g GUID) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(g.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText takes the textual representation of a GUID, and unmarhals it
|
||||||
|
// into this GUID.
|
||||||
|
func (g *GUID) UnmarshalText(text []byte) error {
|
||||||
|
g2, err := FromString(string(text))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*g = g2
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
package winio
|
package winio
|
||||||
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go
|
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
||||||
|
|
|
@ -38,6 +38,7 @@ func errnoErr(e syscall.Errno) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ var (
|
||||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||||
|
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||||
|
@ -73,6 +75,7 @@ var (
|
||||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||||
|
procbind = modws2_32.NewProc("bind")
|
||||||
)
|
)
|
||||||
|
|
||||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||||
|
@ -124,6 +127,24 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||||
|
var _p0 uint32
|
||||||
|
if wait {
|
||||||
|
_p0 = 1
|
||||||
|
} else {
|
||||||
|
_p0 = 0
|
||||||
|
}
|
||||||
|
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
} else {
|
||||||
|
err = syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
|
@ -527,3 +548,15 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||||
|
if r1 == socketError {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
} else {
|
||||||
|
err = syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
![containerd banner](https://raw.githubusercontent.com/cncf/artwork/master/containerd/horizontal/color/containerd-horizontal-color.png)
|
![containerd banner](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/color/containerd-horizontal-color.png)
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/containerd/containerd?status.svg)](https://godoc.org/github.com/containerd/containerd)
|
[![GoDoc](https://godoc.org/github.com/containerd/containerd?status.svg)](https://godoc.org/github.com/containerd/containerd)
|
||||||
[![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd)
|
[![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd)
|
||||||
|
|
|
@ -197,10 +197,7 @@ func onUntarJSON(r io.Reader, j interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, j); err != nil {
|
return json.Unmarshal(b, j)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) {
|
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) {
|
||||||
|
|
|
@ -111,7 +111,18 @@ func unmount(target string, flags int) error {
|
||||||
// UnmountAll repeatedly unmounts the given mount point until there
|
// UnmountAll repeatedly unmounts the given mount point until there
|
||||||
// are no mounts remaining (EINVAL is returned by mount), which is
|
// are no mounts remaining (EINVAL is returned by mount), which is
|
||||||
// useful for undoing a stack of mounts on the same mount point.
|
// useful for undoing a stack of mounts on the same mount point.
|
||||||
|
// UnmountAll all is noop when the first argument is an empty string.
|
||||||
|
// This is done when the containerd client did not specify any rootfs
|
||||||
|
// mounts (e.g. because the rootfs is managed outside containerd)
|
||||||
|
// UnmountAll is noop when the mount path does not exist.
|
||||||
func UnmountAll(mount string, flags int) error {
|
func UnmountAll(mount string, flags int) error {
|
||||||
|
if mount == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(mount); os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if err := unmount(mount, flags); err != nil {
|
if err := unmount(mount, flags); err != nil {
|
||||||
// EINVAL is returned if the target is not a
|
// EINVAL is returned if the target is not a
|
||||||
|
|
|
@ -88,7 +88,7 @@ func appendDistributionSourceLabel(originLabel, repo string) string {
|
||||||
}
|
}
|
||||||
repos = append(repos, repo)
|
repos = append(repos, repo)
|
||||||
|
|
||||||
// use emtpy string to present duplicate items
|
// use empty string to present duplicate items
|
||||||
for i := 1; i < len(repos); i++ {
|
for i := 1; i < len(repos); i++ {
|
||||||
tmp, j := repos[i], i-1
|
tmp, j := repos[i], i-1
|
||||||
for ; j >= 0 && repos[j] >= tmp; j-- {
|
for ; j >= 0 && repos[j] >= tmp; j-- {
|
||||||
|
|
|
@ -18,10 +18,10 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/reference"
|
"github.com/containerd/containerd/reference"
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
|
"github.com/containerd/containerd/remotes/docker/schema1"
|
||||||
"github.com/containerd/containerd/version"
|
"github.com/containerd/containerd/version"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
@ -150,6 +151,32 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getManifestMediaType(resp *http.Response) string {
|
||||||
|
// Strip encoding data (manifests should always be ascii JSON)
|
||||||
|
contentType := resp.Header.Get("Content-Type")
|
||||||
|
if sp := strings.IndexByte(contentType, ';'); sp != -1 {
|
||||||
|
contentType = contentType[0:sp]
|
||||||
|
}
|
||||||
|
|
||||||
|
// As of Apr 30 2019 the registry.access.redhat.com registry does not specify
|
||||||
|
// the content type of any data but uses schema1 manifests.
|
||||||
|
if contentType == "text/plain" {
|
||||||
|
contentType = images.MediaTypeDockerSchema1Manifest
|
||||||
|
}
|
||||||
|
return contentType
|
||||||
|
}
|
||||||
|
|
||||||
|
type countingReader struct {
|
||||||
|
reader io.Reader
|
||||||
|
bytesRead int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *countingReader) Read(p []byte) (int, error) {
|
||||||
|
n, err := r.reader.Read(p)
|
||||||
|
r.bytesRead += int64(n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
var _ remotes.Resolver = &dockerResolver{}
|
var _ remotes.Resolver = &dockerResolver{}
|
||||||
|
|
||||||
func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocispec.Descriptor, error) {
|
func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocispec.Descriptor, error) {
|
||||||
|
@ -220,40 +247,56 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||||
}
|
}
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
|
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
|
||||||
}
|
}
|
||||||
|
size := resp.ContentLength
|
||||||
|
|
||||||
// this is the only point at which we trust the registry. we use the
|
// this is the only point at which we trust the registry. we use the
|
||||||
// content headers to assemble a descriptor for the name. when this becomes
|
// content headers to assemble a descriptor for the name. when this becomes
|
||||||
// more robust, we mostly get this information from a secure trust store.
|
// more robust, we mostly get this information from a secure trust store.
|
||||||
dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest"))
|
dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest"))
|
||||||
|
contentType := getManifestMediaType(resp)
|
||||||
|
|
||||||
if dgstHeader != "" {
|
if dgstHeader != "" && size != -1 {
|
||||||
if err := dgstHeader.Validate(); err != nil {
|
if err := dgstHeader.Validate(); err != nil {
|
||||||
return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader)
|
return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader)
|
||||||
}
|
}
|
||||||
dgst = dgstHeader
|
dgst = dgstHeader
|
||||||
}
|
} else {
|
||||||
|
log.G(ctx).Debug("no Docker-Content-Digest header, fetching manifest instead")
|
||||||
|
|
||||||
if dgst == "" {
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("could not resolve digest for %v", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
size int64
|
|
||||||
sizeHeader = resp.Header.Get("Content-Length")
|
|
||||||
)
|
|
||||||
|
|
||||||
size, err = strconv.ParseInt(sizeHeader, 10, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
return "", ocispec.Descriptor{}, errors.Wrapf(err, "invalid size header: %q", sizeHeader)
|
|
||||||
}
|
}
|
||||||
if size < 0 {
|
req.Header = r.headers
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("%q in header not a valid size", sizeHeader)
|
|
||||||
|
resp, err := fetcher.doRequestWithRetries(ctx, req, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
bodyReader := countingReader{reader: resp.Body}
|
||||||
|
|
||||||
|
contentType = getManifestMediaType(resp)
|
||||||
|
if contentType == images.MediaTypeDockerSchema1Manifest {
|
||||||
|
b, err := schema1.ReadStripSignature(&bodyReader)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dgst = digest.FromBytes(b)
|
||||||
|
} else {
|
||||||
|
dgst, err = digest.FromReader(&bodyReader)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = bodyReader.bytesRead
|
||||||
}
|
}
|
||||||
|
|
||||||
desc := ocispec.Descriptor{
|
desc := ocispec.Descriptor{
|
||||||
Digest: dgst,
|
Digest: dgst,
|
||||||
MediaType: resp.Header.Get("Content-Type"), // need to strip disposition?
|
MediaType: contentType,
|
||||||
Size: size,
|
Size: size,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,17 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
||||||
return desc, nil
|
return desc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadStripSignature reads in a schema1 manifest and returns a byte array
|
||||||
|
// with the "signatures" field stripped
|
||||||
|
func ReadStripSignature(schema1Blob io.Reader) ([]byte, error) {
|
||||||
|
b, err := ioutil.ReadAll(io.LimitReader(schema1Blob, manifestSizeLimit)) // limit to 8MB
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return stripSignature(b)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) error {
|
func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) error {
|
||||||
log.G(ctx).Debug("fetch schema 1")
|
log.G(ctx).Debug("fetch schema 1")
|
||||||
|
|
||||||
|
@ -235,17 +246,12 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(io.LimitReader(rc, manifestSizeLimit)) // limit to 8MB
|
b, err := ReadStripSignature(rc)
|
||||||
rc.Close()
|
rc.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err = stripSignature(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var m manifest
|
var m manifest
|
||||||
if err := json.Unmarshal(b, &m); err != nil {
|
if err := json.Unmarshal(b, &m); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -20,7 +20,7 @@ github.com/gogo/protobuf v1.2.1
|
||||||
github.com/gogo/googleapis v1.2.0
|
github.com/gogo/googleapis v1.2.0
|
||||||
github.com/golang/protobuf v1.2.0
|
github.com/golang/protobuf v1.2.0
|
||||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||||
github.com/opencontainers/runc 029124da7af7360afa781a0234d1b083550f797c
|
github.com/opencontainers/runc v1.0.0-rc8
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
|
@ -37,15 +37,15 @@ github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5205c12027fac
|
||||||
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
github.com/containerd/ttrpc 699c4e40d1e7416e08bf7019c7ce2e9beced4636
|
||||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||||
gotest.tools v2.3.0
|
gotest.tools v2.3.0
|
||||||
github.com/google/go-cmp v0.2.0
|
github.com/google/go-cmp v0.2.0
|
||||||
go.etcd.io/bbolt v1.3.2
|
go.etcd.io/bbolt v1.3.2
|
||||||
|
|
||||||
# cri dependencies
|
# cri dependencies
|
||||||
github.com/containerd/cri 6d353571e64417d80c9478ffaea793714dd539d0 # master
|
github.com/containerd/cri 2fc62db8146ce66f27b37306ad5fda34207835f3 # master
|
||||||
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
github.com/containerd/go-cni 891c2a41e18144b2d7921f971d6c9789a68046b2
|
||||||
github.com/containernetworking/cni v0.6.0
|
github.com/containernetworking/cni v0.6.0
|
||||||
github.com/containernetworking/plugins v0.7.0
|
github.com/containernetworking/plugins v0.7.0
|
||||||
github.com/davecgh/go-spew v1.1.0
|
github.com/davecgh/go-spew v1.1.0
|
||||||
|
@ -59,7 +59,7 @@ github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
||||||
github.com/json-iterator/go 1.1.5
|
github.com/json-iterator/go 1.1.5
|
||||||
github.com/modern-go/reflect2 1.0.1
|
github.com/modern-go/reflect2 1.0.1
|
||||||
github.com/modern-go/concurrent 1.0.3
|
github.com/modern-go/concurrent 1.0.3
|
||||||
github.com/opencontainers/selinux v1.2.1
|
github.com/opencontainers/selinux v1.2.2
|
||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
||||||
|
|
|
@ -18,7 +18,6 @@ package ttrpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -98,7 +97,7 @@ func newChannel(conn net.Conn) *channel {
|
||||||
// returned will be valid and caller should send that along to
|
// returned will be valid and caller should send that along to
|
||||||
// the correct consumer. The bytes on the underlying channel
|
// the correct consumer. The bytes on the underlying channel
|
||||||
// will be discarded.
|
// will be discarded.
|
||||||
func (ch *channel) recv(ctx context.Context) (messageHeader, []byte, error) {
|
func (ch *channel) recv() (messageHeader, []byte, error) {
|
||||||
mh, err := readMessageHeader(ch.hrbuf[:], ch.br)
|
mh, err := readMessageHeader(ch.hrbuf[:], ch.br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return messageHeader{}, nil, err
|
return messageHeader{}, nil, err
|
||||||
|
@ -120,7 +119,7 @@ func (ch *channel) recv(ctx context.Context) (messageHeader, []byte, error) {
|
||||||
return mh, p, nil
|
return mh, p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch *channel) send(ctx context.Context, streamID uint32, t messageType, p []byte) error {
|
func (ch *channel) send(streamID uint32, t messageType, p []byte) error {
|
||||||
if err := writeMessageHeader(ch.bw, ch.hwbuf[:], messageHeader{Length: uint32(len(p)), StreamID: streamID, Type: t}); err != nil {
|
if err := writeMessageHeader(ch.bw, ch.hwbuf[:], messageHeader{Length: uint32(len(p)), StreamID: streamID, Type: t}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,28 +37,56 @@ import (
|
||||||
// closed.
|
// closed.
|
||||||
var ErrClosed = errors.New("ttrpc: closed")
|
var ErrClosed = errors.New("ttrpc: closed")
|
||||||
|
|
||||||
|
// Client for a ttrpc server
|
||||||
type Client struct {
|
type Client struct {
|
||||||
codec codec
|
codec codec
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
channel *channel
|
channel *channel
|
||||||
calls chan *callRequest
|
calls chan *callRequest
|
||||||
|
|
||||||
closed chan struct{}
|
ctx context.Context
|
||||||
|
closed func()
|
||||||
|
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
closeFunc func()
|
userCloseFunc func()
|
||||||
done chan struct{}
|
|
||||||
|
errOnce sync.Once
|
||||||
err error
|
err error
|
||||||
|
interceptor UnaryClientInterceptor
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(conn net.Conn) *Client {
|
// ClientOpts configures a client
|
||||||
|
type ClientOpts func(c *Client)
|
||||||
|
|
||||||
|
// WithOnClose sets the close func whenever the client's Close() method is called
|
||||||
|
func WithOnClose(onClose func()) ClientOpts {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.userCloseFunc = onClose
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUnaryClientInterceptor sets the provided client interceptor
|
||||||
|
func WithUnaryClientInterceptor(i UnaryClientInterceptor) ClientOpts {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.interceptor = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(conn net.Conn, opts ...ClientOpts) *Client {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
c := &Client{
|
c := &Client{
|
||||||
codec: codec{},
|
codec: codec{},
|
||||||
conn: conn,
|
conn: conn,
|
||||||
channel: newChannel(conn),
|
channel: newChannel(conn),
|
||||||
calls: make(chan *callRequest),
|
calls: make(chan *callRequest),
|
||||||
closed: make(chan struct{}),
|
closed: cancel,
|
||||||
done: make(chan struct{}),
|
ctx: ctx,
|
||||||
closeFunc: func() {},
|
userCloseFunc: func() {},
|
||||||
|
interceptor: defaultClientInterceptor,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
go c.run()
|
go c.run()
|
||||||
|
@ -87,11 +116,18 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int
|
||||||
cresp = &Response{}
|
cresp = &Response{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if metadata, ok := GetMetadata(ctx); ok {
|
||||||
|
metadata.setRequest(creq)
|
||||||
|
}
|
||||||
|
|
||||||
if dl, ok := ctx.Deadline(); ok {
|
if dl, ok := ctx.Deadline(); ok {
|
||||||
creq.TimeoutNano = dl.Sub(time.Now()).Nanoseconds()
|
creq.TimeoutNano = dl.Sub(time.Now()).Nanoseconds()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.dispatch(ctx, creq, cresp); err != nil {
|
info := &UnaryClientInfo{
|
||||||
|
FullMethod: fullPath(service, method),
|
||||||
|
}
|
||||||
|
if err := c.interceptor(ctx, creq, cresp, info, c.dispatch); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,11 +135,10 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cresp.Status == nil {
|
if cresp.Status != nil && cresp.Status.Code != int32(codes.OK) {
|
||||||
return errors.New("no status provided on response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return status.ErrorProto(cresp.Status)
|
return status.ErrorProto(cresp.Status)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) error {
|
func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) error {
|
||||||
|
@ -119,8 +154,8 @@ func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) err
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case c.calls <- call:
|
case c.calls <- call:
|
||||||
case <-c.done:
|
case <-c.ctx.Done():
|
||||||
return c.err
|
return c.error()
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
@ -128,75 +163,100 @@ func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) err
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case err := <-errs:
|
case err := <-errs:
|
||||||
return filterCloseErr(err)
|
return filterCloseErr(err)
|
||||||
case <-c.done:
|
case <-c.ctx.Done():
|
||||||
return c.err
|
return c.error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Close() error {
|
func (c *Client) Close() error {
|
||||||
c.closeOnce.Do(func() {
|
c.closeOnce.Do(func() {
|
||||||
close(c.closed)
|
c.closed()
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnClose allows a close func to be called when the server is closed
|
|
||||||
func (c *Client) OnClose(closer func()) {
|
|
||||||
c.closeFunc = closer
|
|
||||||
}
|
|
||||||
|
|
||||||
type message struct {
|
type message struct {
|
||||||
messageHeader
|
messageHeader
|
||||||
p []byte
|
p []byte
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type receiver struct {
|
||||||
|
wg *sync.WaitGroup
|
||||||
|
messages chan *message
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *receiver) run(ctx context.Context, c *channel) {
|
||||||
|
defer r.wg.Done()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
r.err = ctx.Err()
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
mh, p, err := c.recv()
|
||||||
|
if err != nil {
|
||||||
|
_, ok := status.FromError(err)
|
||||||
|
if !ok {
|
||||||
|
// treat all errors that are not an rpc status as terminal.
|
||||||
|
// all others poison the connection.
|
||||||
|
r.err = filterCloseErr(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case r.messages <- &message{
|
||||||
|
messageHeader: mh,
|
||||||
|
p: p[:mh.Length],
|
||||||
|
err: err,
|
||||||
|
}:
|
||||||
|
case <-ctx.Done():
|
||||||
|
r.err = ctx.Err()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) run() {
|
func (c *Client) run() {
|
||||||
var (
|
var (
|
||||||
streamID uint32 = 1
|
streamID uint32 = 1
|
||||||
waiters = make(map[uint32]*callRequest)
|
waiters = make(map[uint32]*callRequest)
|
||||||
calls = c.calls
|
calls = c.calls
|
||||||
incoming = make(chan *message)
|
incoming = make(chan *message)
|
||||||
shutdown = make(chan struct{})
|
receiversDone = make(chan struct{})
|
||||||
shutdownErr error
|
wg sync.WaitGroup
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// broadcast the shutdown error to the remaining waiters.
|
||||||
|
abortWaiters := func(wErr error) {
|
||||||
|
for _, waiter := range waiters {
|
||||||
|
waiter.errs <- wErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recv := &receiver{
|
||||||
|
wg: &wg,
|
||||||
|
messages: incoming,
|
||||||
|
}
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(shutdown)
|
wg.Wait()
|
||||||
|
close(receiversDone)
|
||||||
// start one more goroutine to recv messages without blocking.
|
|
||||||
for {
|
|
||||||
mh, p, err := c.channel.recv(context.TODO())
|
|
||||||
if err != nil {
|
|
||||||
_, ok := status.FromError(err)
|
|
||||||
if !ok {
|
|
||||||
// treat all errors that are not an rpc status as terminal.
|
|
||||||
// all others poison the connection.
|
|
||||||
shutdownErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case incoming <- &message{
|
|
||||||
messageHeader: mh,
|
|
||||||
p: p[:mh.Length],
|
|
||||||
err: err,
|
|
||||||
}:
|
|
||||||
case <-c.done:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
go recv.run(c.ctx, c.channel)
|
||||||
|
|
||||||
defer c.conn.Close()
|
defer func() {
|
||||||
defer close(c.done)
|
c.conn.Close()
|
||||||
defer c.closeFunc()
|
c.userCloseFunc()
|
||||||
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case call := <-calls:
|
case call := <-calls:
|
||||||
if err := c.send(call.ctx, streamID, messageTypeRequest, call.req); err != nil {
|
if err := c.send(streamID, messageTypeRequest, call.req); err != nil {
|
||||||
call.errs <- err
|
call.errs <- err
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -212,41 +272,42 @@ func (c *Client) run() {
|
||||||
|
|
||||||
call.errs <- c.recv(call.resp, msg)
|
call.errs <- c.recv(call.resp, msg)
|
||||||
delete(waiters, msg.StreamID)
|
delete(waiters, msg.StreamID)
|
||||||
case <-shutdown:
|
case <-receiversDone:
|
||||||
if shutdownErr != nil {
|
// all the receivers have exited
|
||||||
shutdownErr = filterCloseErr(shutdownErr)
|
if recv.err != nil {
|
||||||
} else {
|
c.setError(recv.err)
|
||||||
shutdownErr = ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
shutdownErr = errors.Wrapf(shutdownErr, "ttrpc: client shutting down")
|
|
||||||
|
|
||||||
c.err = shutdownErr
|
|
||||||
for _, waiter := range waiters {
|
|
||||||
waiter.errs <- shutdownErr
|
|
||||||
}
|
}
|
||||||
|
// don't return out, let the close of the context trigger the abort of waiters
|
||||||
c.Close()
|
c.Close()
|
||||||
return
|
case <-c.ctx.Done():
|
||||||
case <-c.closed:
|
abortWaiters(c.error())
|
||||||
if c.err == nil {
|
|
||||||
c.err = ErrClosed
|
|
||||||
}
|
|
||||||
// broadcast the shutdown error to the remaining waiters.
|
|
||||||
for _, waiter := range waiters {
|
|
||||||
waiter.errs <- c.err
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) send(ctx context.Context, streamID uint32, mtype messageType, msg interface{}) error {
|
func (c *Client) error() error {
|
||||||
|
c.errOnce.Do(func() {
|
||||||
|
if c.err == nil {
|
||||||
|
c.err = ErrClosed
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return c.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) setError(err error) {
|
||||||
|
c.errOnce.Do(func() {
|
||||||
|
c.err = err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) send(streamID uint32, mtype messageType, msg interface{}) error {
|
||||||
p, err := c.codec.Marshal(msg)
|
p, err := c.codec.Marshal(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.channel.send(ctx, streamID, mtype, p)
|
return c.channel.send(streamID, mtype, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) recv(resp *Response, msg *message) error {
|
func (c *Client) recv(resp *Response, msg *message) error {
|
||||||
|
@ -255,7 +316,7 @@ func (c *Client) recv(resp *Response, msg *message) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.Type != messageTypeResponse {
|
if msg.Type != messageTypeResponse {
|
||||||
return errors.New("unkown message type received")
|
return errors.New("unknown message type received")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer c.channel.putmbuf(msg.p)
|
defer c.channel.putmbuf(msg.p)
|
||||||
|
@ -267,24 +328,23 @@ func (c *Client) recv(resp *Response, msg *message) error {
|
||||||
//
|
//
|
||||||
// This purposely ignores errors with a wrapped cause.
|
// This purposely ignores errors with a wrapped cause.
|
||||||
func filterCloseErr(err error) error {
|
func filterCloseErr(err error) error {
|
||||||
if err == nil {
|
switch {
|
||||||
|
case err == nil:
|
||||||
return nil
|
return nil
|
||||||
}
|
case err == io.EOF:
|
||||||
|
|
||||||
if err == io.EOF {
|
|
||||||
return ErrClosed
|
return ErrClosed
|
||||||
}
|
case errors.Cause(err) == io.EOF:
|
||||||
|
|
||||||
if strings.Contains(err.Error(), "use of closed network connection") {
|
|
||||||
return ErrClosed
|
return ErrClosed
|
||||||
}
|
case strings.Contains(err.Error(), "use of closed network connection"):
|
||||||
|
return ErrClosed
|
||||||
|
default:
|
||||||
// if we have an epipe on a write, we cast to errclosed
|
// if we have an epipe on a write, we cast to errclosed
|
||||||
if oerr, ok := err.(*net.OpError); ok && oerr.Op == "write" {
|
if oerr, ok := err.(*net.OpError); ok && oerr.Op == "write" {
|
||||||
if serr, ok := oerr.Err.(*os.SyscallError); ok && serr.Err == syscall.EPIPE {
|
if serr, ok := oerr.Err.(*os.SyscallError); ok && serr.Err == syscall.EPIPE {
|
||||||
return ErrClosed
|
return ErrClosed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,10 @@ import "github.com/pkg/errors"
|
||||||
|
|
||||||
type serverConfig struct {
|
type serverConfig struct {
|
||||||
handshaker Handshaker
|
handshaker Handshaker
|
||||||
|
interceptor UnaryServerInterceptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServerOpt for configuring a ttrpc server
|
||||||
type ServerOpt func(*serverConfig) error
|
type ServerOpt func(*serverConfig) error
|
||||||
|
|
||||||
// WithServerHandshaker can be passed to NewServer to ensure that the
|
// WithServerHandshaker can be passed to NewServer to ensure that the
|
||||||
|
@ -37,3 +39,14 @@ func WithServerHandshaker(handshaker Handshaker) ServerOpt {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithUnaryServerInterceptor sets the provided interceptor on the server
|
||||||
|
func WithUnaryServerInterceptor(i UnaryServerInterceptor) ServerOpt {
|
||||||
|
return func(c *serverConfig) error {
|
||||||
|
if c.interceptor != nil {
|
||||||
|
return errors.New("only one interceptor allowed per server")
|
||||||
|
}
|
||||||
|
c.interceptor = i
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ttrpc
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// UnaryServerInfo provides information about the server request
|
||||||
|
type UnaryServerInfo struct {
|
||||||
|
FullMethod string
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnaryClientInfo provides information about the client request
|
||||||
|
type UnaryClientInfo struct {
|
||||||
|
FullMethod string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshaler contains the server request data and allows it to be unmarshaled
|
||||||
|
// into a concrete type
|
||||||
|
type Unmarshaler func(interface{}) error
|
||||||
|
|
||||||
|
// Invoker invokes the client's request and response from the ttrpc server
|
||||||
|
type Invoker func(context.Context, *Request, *Response) error
|
||||||
|
|
||||||
|
// UnaryServerInterceptor specifies the interceptor function for server request/response
|
||||||
|
type UnaryServerInterceptor func(context.Context, Unmarshaler, *UnaryServerInfo, Method) (interface{}, error)
|
||||||
|
|
||||||
|
// UnaryClientInterceptor specifies the interceptor function for client request/response
|
||||||
|
type UnaryClientInterceptor func(context.Context, *Request, *Response, *UnaryClientInfo, Invoker) error
|
||||||
|
|
||||||
|
func defaultServerInterceptor(ctx context.Context, unmarshal Unmarshaler, info *UnaryServerInfo, method Method) (interface{}, error) {
|
||||||
|
return method(ctx, unmarshal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultClientInterceptor(ctx context.Context, req *Request, resp *Response, _ *UnaryClientInfo, invoker Invoker) error {
|
||||||
|
return invoker(ctx, req, resp)
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ttrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MD is the user type for ttrpc metadata
|
||||||
|
type MD map[string][]string
|
||||||
|
|
||||||
|
// Get returns the metadata for a given key when they exist.
|
||||||
|
// If there is no metadata, a nil slice and false are returned.
|
||||||
|
func (m MD) Get(key string) ([]string, bool) {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
list, ok := m[key]
|
||||||
|
if !ok || len(list) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return list, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the provided values for a given key.
|
||||||
|
// The values will overwrite any existing values.
|
||||||
|
// If no values provided, a key will be deleted.
|
||||||
|
func (m MD) Set(key string, values ...string) {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
if len(values) == 0 {
|
||||||
|
delete(m, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m[key] = values
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append appends additional values to the given key.
|
||||||
|
func (m MD) Append(key string, values ...string) {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
if len(values) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
current, ok := m[key]
|
||||||
|
if ok {
|
||||||
|
m.Set(key, append(current, values...)...)
|
||||||
|
} else {
|
||||||
|
m.Set(key, values...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MD) setRequest(r *Request) {
|
||||||
|
for k, values := range m {
|
||||||
|
for _, v := range values {
|
||||||
|
r.Metadata = append(r.Metadata, &KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: v,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MD) fromRequest(r *Request) {
|
||||||
|
for _, kv := range r.Metadata {
|
||||||
|
m[kv.Key] = append(m[kv.Key], kv.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type metadataKey struct{}
|
||||||
|
|
||||||
|
// GetMetadata retrieves metadata from context.Context (previously attached with WithMetadata)
|
||||||
|
func GetMetadata(ctx context.Context) (MD, bool) {
|
||||||
|
metadata, ok := ctx.Value(metadataKey{}).(MD)
|
||||||
|
return metadata, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMetadataValue gets a specific metadata value by name from context.Context
|
||||||
|
func GetMetadataValue(ctx context.Context, name string) (string, bool) {
|
||||||
|
metadata, ok := GetMetadata(ctx)
|
||||||
|
if !ok {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
if list, ok := metadata.Get(name); ok {
|
||||||
|
return list[0], true
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMetadata attaches metadata map to a context.Context
|
||||||
|
func WithMetadata(ctx context.Context, md MD) context.Context {
|
||||||
|
return context.WithValue(ctx, metadataKey{}, md)
|
||||||
|
}
|
|
@ -53,10 +53,13 @@ func NewServer(opts ...ServerOpt) (*Server, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if config.interceptor == nil {
|
||||||
|
config.interceptor = defaultServerInterceptor
|
||||||
|
}
|
||||||
|
|
||||||
return &Server{
|
return &Server{
|
||||||
config: config,
|
config: config,
|
||||||
services: newServiceSet(),
|
services: newServiceSet(config.interceptor),
|
||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
listeners: make(map[net.Listener]struct{}),
|
listeners: make(map[net.Listener]struct{}),
|
||||||
connections: make(map[*serverConn]struct{}),
|
connections: make(map[*serverConn]struct{}),
|
||||||
|
@ -341,7 +344,7 @@ func (c *serverConn) run(sctx context.Context) {
|
||||||
default: // proceed
|
default: // proceed
|
||||||
}
|
}
|
||||||
|
|
||||||
mh, p, err := ch.recv(ctx)
|
mh, p, err := ch.recv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
status, ok := status.FromError(err)
|
status, ok := status.FromError(err)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -438,7 +441,7 @@ func (c *serverConn) run(sctx context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ch.send(ctx, response.id, messageTypeResponse, p); err != nil {
|
if err := ch.send(response.id, messageTypeResponse, p); err != nil {
|
||||||
logrus.WithError(err).Error("failed sending message on channel")
|
logrus.WithError(err).Error("failed sending message on channel")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -449,7 +452,12 @@ func (c *serverConn) run(sctx context.Context) {
|
||||||
// branch. Basically, it means that we are no longer receiving
|
// branch. Basically, it means that we are no longer receiving
|
||||||
// requests due to a terminal error.
|
// requests due to a terminal error.
|
||||||
recvErr = nil // connection is now "closing"
|
recvErr = nil // connection is now "closing"
|
||||||
if err != nil && err != io.EOF {
|
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||||
|
// The client went away and we should stop processing
|
||||||
|
// requests, so that the client connection is closed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
logrus.WithError(err).Error("error receiving message")
|
logrus.WithError(err).Error("error receiving message")
|
||||||
}
|
}
|
||||||
case <-shutdown:
|
case <-shutdown:
|
||||||
|
@ -461,6 +469,12 @@ func (c *serverConn) run(sctx context.Context) {
|
||||||
var noopFunc = func() {}
|
var noopFunc = func() {}
|
||||||
|
|
||||||
func getRequestContext(ctx context.Context, req *Request) (retCtx context.Context, cancel func()) {
|
func getRequestContext(ctx context.Context, req *Request) (retCtx context.Context, cancel func()) {
|
||||||
|
if len(req.Metadata) > 0 {
|
||||||
|
md := MD{}
|
||||||
|
md.fromRequest(req)
|
||||||
|
ctx = WithMetadata(ctx, md)
|
||||||
|
}
|
||||||
|
|
||||||
cancel = noopFunc
|
cancel = noopFunc
|
||||||
if req.TimeoutNano == 0 {
|
if req.TimeoutNano == 0 {
|
||||||
return ctx, cancel
|
return ctx, cancel
|
||||||
|
|
|
@ -38,11 +38,13 @@ type ServiceDesc struct {
|
||||||
|
|
||||||
type serviceSet struct {
|
type serviceSet struct {
|
||||||
services map[string]ServiceDesc
|
services map[string]ServiceDesc
|
||||||
|
interceptor UnaryServerInterceptor
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServiceSet() *serviceSet {
|
func newServiceSet(interceptor UnaryServerInterceptor) *serviceSet {
|
||||||
return &serviceSet{
|
return &serviceSet{
|
||||||
services: make(map[string]ServiceDesc),
|
services: make(map[string]ServiceDesc),
|
||||||
|
interceptor: interceptor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ func (s *serviceSet) dispatch(ctx context.Context, serviceName, methodName strin
|
||||||
switch v := obj.(type) {
|
switch v := obj.(type) {
|
||||||
case proto.Message:
|
case proto.Message:
|
||||||
if err := proto.Unmarshal(p, v); err != nil {
|
if err := proto.Unmarshal(p, v); err != nil {
|
||||||
return status.Errorf(codes.Internal, "ttrpc: error unmarshaling payload: %v", err.Error())
|
return status.Errorf(codes.Internal, "ttrpc: error unmarshalling payload: %v", err.Error())
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return status.Errorf(codes.Internal, "ttrpc: error unsupported request type: %T", v)
|
return status.Errorf(codes.Internal, "ttrpc: error unsupported request type: %T", v)
|
||||||
|
@ -84,7 +86,11 @@ func (s *serviceSet) dispatch(ctx context.Context, serviceName, methodName strin
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := method(ctx, unmarshal)
|
info := &UnaryServerInfo{
|
||||||
|
FullMethod: fullPath(serviceName, methodName),
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.interceptor(ctx, unmarshal, info, method)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -146,5 +152,5 @@ func convertCode(err error) codes.Code {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fullPath(service, method string) string {
|
func fullPath(service, method string) string {
|
||||||
return "/" + path.Join("/", service, method)
|
return "/" + path.Join(service, method)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ type Request struct {
|
||||||
Method string `protobuf:"bytes,2,opt,name=method,proto3"`
|
Method string `protobuf:"bytes,2,opt,name=method,proto3"`
|
||||||
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"`
|
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"`
|
||||||
TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,proto3"`
|
TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,proto3"`
|
||||||
|
Metadata []*KeyValue `protobuf:"bytes,5,rep,name=metadata,proto3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) Reset() { *r = Request{} }
|
func (r *Request) Reset() { *r = Request{} }
|
||||||
|
@ -41,3 +42,22 @@ type Response struct {
|
||||||
func (r *Response) Reset() { *r = Response{} }
|
func (r *Response) Reset() { *r = Response{} }
|
||||||
func (r *Response) String() string { return fmt.Sprintf("%+#v", r) }
|
func (r *Response) String() string { return fmt.Sprintf("%+#v", r) }
|
||||||
func (r *Response) ProtoMessage() {}
|
func (r *Response) ProtoMessage() {}
|
||||||
|
|
||||||
|
type StringList struct {
|
||||||
|
List []string `protobuf:"bytes,1,rep,name=list,proto3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *StringList) Reset() { *r = StringList{} }
|
||||||
|
func (r *StringList) String() string { return fmt.Sprintf("%+#v", r) }
|
||||||
|
func (r *StringList) ProtoMessage() {}
|
||||||
|
|
||||||
|
func makeStringList(item ...string) StringList { return StringList{List: item} }
|
||||||
|
|
||||||
|
type KeyValue struct {
|
||||||
|
Key string `protobuf:"bytes,1,opt,name=key,proto3"`
|
||||||
|
Value string `protobuf:"bytes,2,opt,name=value,proto3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *KeyValue) Reset() { *m = KeyValue{} }
|
||||||
|
func (*KeyValue) ProtoMessage() {}
|
||||||
|
func (m *KeyValue) String() string { return fmt.Sprintf("%+#v", m) }
|
||||||
|
|
|
@ -3,7 +3,7 @@ Copyright 2012-2017 Docker, Inc.
|
||||||
|
|
||||||
This product includes software developed at Docker, Inc. (https://www.docker.com).
|
This product includes software developed at Docker, Inc. (https://www.docker.com).
|
||||||
|
|
||||||
This product contains software (https://github.com/kr/pty) developed
|
This product contains software (https://github.com/creack/pty) developed
|
||||||
by Keith Rarick, licensed under the MIT License.
|
by Keith Rarick, licensed under the MIT License.
|
||||||
|
|
||||||
The following is courtesy of our legal counsel:
|
The following is courtesy of our legal counsel:
|
||||||
|
|
|
@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
|
||||||
// Common constants for daemon and client.
|
// Common constants for daemon and client.
|
||||||
const (
|
const (
|
||||||
// DefaultVersion of Current REST API
|
// DefaultVersion of Current REST API
|
||||||
DefaultVersion = "1.40"
|
DefaultVersion = "1.41"
|
||||||
|
|
||||||
// NoBaseImageSpecifier is the symbol used by the FROM
|
// NoBaseImageSpecifier is the symbol used by the FROM
|
||||||
// command to specify that no base image is to be used.
|
// command to specify that no base image is to be used.
|
||||||
|
|
|
@ -7,9 +7,32 @@ import (
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/strslice"
|
"github.com/docker/docker/api/types/strslice"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CgroupnsMode represents the cgroup namespace mode of the container
|
||||||
|
type CgroupnsMode string
|
||||||
|
|
||||||
|
// IsPrivate indicates whether the container uses its own private cgroup namespace
|
||||||
|
func (c CgroupnsMode) IsPrivate() bool {
|
||||||
|
return c == "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsHost indicates whether the container shares the host's cgroup namespace
|
||||||
|
func (c CgroupnsMode) IsHost() bool {
|
||||||
|
return c == "host"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty indicates whether the container cgroup namespace mode is unset
|
||||||
|
func (c CgroupnsMode) IsEmpty() bool {
|
||||||
|
return c == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid indicates whether the cgroup namespace mode is valid
|
||||||
|
func (c CgroupnsMode) Valid() bool {
|
||||||
|
return c.IsEmpty() || c.IsPrivate() || c.IsHost()
|
||||||
|
}
|
||||||
|
|
||||||
// Isolation represents the isolation technology of a container. The supported
|
// Isolation represents the isolation technology of a container. The supported
|
||||||
// values are platform specific
|
// values are platform specific
|
||||||
type Isolation string
|
type Isolation string
|
||||||
|
@ -381,6 +404,7 @@ type HostConfig struct {
|
||||||
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
|
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
|
||||||
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
|
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
|
||||||
Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
|
Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
|
||||||
|
CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container
|
||||||
DNS []string `json:"Dns"` // List of DNS server to lookup
|
DNS []string `json:"Dns"` // List of DNS server to lookup
|
||||||
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
||||||
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
// Error returns the error message
|
||||||
|
func (e ErrorResponse) Error() string {
|
||||||
|
return e.Message
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ func ToJSON(a Args) (string, error) {
|
||||||
// then the encoded format will use an older legacy format where the values are a
|
// then the encoded format will use an older legacy format where the values are a
|
||||||
// list of strings, instead of a set.
|
// list of strings, instead of a set.
|
||||||
//
|
//
|
||||||
// Deprecated: Use ToJSON
|
// Deprecated: do not use in any new code; use ToJSON instead
|
||||||
func ToParamWithVersion(version string, a Args) (string, error) {
|
func ToParamWithVersion(version string, a Args) (string, error) {
|
||||||
if a.Len() == 0 {
|
if a.Len() == 0 {
|
||||||
return "", nil
|
return "", nil
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceConfig stores daemon registry services configuration.
|
// ServiceConfig stores daemon registry services configuration.
|
||||||
|
|
|
@ -73,4 +73,5 @@ type ContainerSpec struct {
|
||||||
Configs []*ConfigReference `json:",omitempty"`
|
Configs []*ConfigReference `json:",omitempty"`
|
||||||
Isolation container.Isolation `json:",omitempty"`
|
Isolation container.Isolation `json:",omitempty"`
|
||||||
Sysctls map[string]string `json:",omitempty"`
|
Sysctls map[string]string `json:",omitempty"`
|
||||||
|
Capabilities []string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Code generated by protoc-gen-gogo.
|
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||||
// source: plugin.proto
|
// source: plugin.proto
|
||||||
// DO NOT EDIT!
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package runtime is a generated protocol buffer package.
|
Package runtime is a generated protocol buffer package.
|
||||||
|
@ -38,6 +37,7 @@ type PluginSpec struct {
|
||||||
Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
|
Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
|
||||||
Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
|
Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
|
||||||
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
|
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
|
||||||
|
Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PluginSpec) Reset() { *m = PluginSpec{} }
|
func (m *PluginSpec) Reset() { *m = PluginSpec{} }
|
||||||
|
@ -73,6 +73,13 @@ func (m *PluginSpec) GetDisabled() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *PluginSpec) GetEnv() []string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Env
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// PluginPrivilege describes a permission the user has to accept
|
// PluginPrivilege describes a permission the user has to accept
|
||||||
// upon installing a plugin.
|
// upon installing a plugin.
|
||||||
type PluginPrivilege struct {
|
type PluginPrivilege struct {
|
||||||
|
@ -160,6 +167,21 @@ func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
if len(m.Env) > 0 {
|
||||||
|
for _, s := range m.Env {
|
||||||
|
dAtA[i] = 0x2a
|
||||||
|
i++
|
||||||
|
l = len(s)
|
||||||
|
for l >= 1<<7 {
|
||||||
|
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||||
|
l >>= 7
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
dAtA[i] = uint8(l)
|
||||||
|
i++
|
||||||
|
i += copy(dAtA[i:], s)
|
||||||
|
}
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,24 +230,6 @@ func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int {
|
|
||||||
dAtA[offset] = uint8(v)
|
|
||||||
dAtA[offset+1] = uint8(v >> 8)
|
|
||||||
dAtA[offset+2] = uint8(v >> 16)
|
|
||||||
dAtA[offset+3] = uint8(v >> 24)
|
|
||||||
dAtA[offset+4] = uint8(v >> 32)
|
|
||||||
dAtA[offset+5] = uint8(v >> 40)
|
|
||||||
dAtA[offset+6] = uint8(v >> 48)
|
|
||||||
dAtA[offset+7] = uint8(v >> 56)
|
|
||||||
return offset + 8
|
|
||||||
}
|
|
||||||
func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int {
|
|
||||||
dAtA[offset] = uint8(v)
|
|
||||||
dAtA[offset+1] = uint8(v >> 8)
|
|
||||||
dAtA[offset+2] = uint8(v >> 16)
|
|
||||||
dAtA[offset+3] = uint8(v >> 24)
|
|
||||||
return offset + 4
|
|
||||||
}
|
|
||||||
func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
|
func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
|
||||||
for v >= 1<<7 {
|
for v >= 1<<7 {
|
||||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||||
|
@ -255,6 +259,12 @@ func (m *PluginSpec) Size() (n int) {
|
||||||
if m.Disabled {
|
if m.Disabled {
|
||||||
n += 2
|
n += 2
|
||||||
}
|
}
|
||||||
|
if len(m.Env) > 0 {
|
||||||
|
for _, s := range m.Env {
|
||||||
|
l = len(s)
|
||||||
|
n += 1 + l + sovPlugin(uint64(l))
|
||||||
|
}
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +439,35 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.Disabled = bool(v != 0)
|
m.Disabled = bool(v != 0)
|
||||||
|
case 5:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowPlugin
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthPlugin
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipPlugin(dAtA[iNdEx:])
|
skippy, err := skipPlugin(dAtA[iNdEx:])
|
||||||
|
@ -695,18 +734,21 @@ var (
|
||||||
func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
|
func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
|
||||||
|
|
||||||
var fileDescriptorPlugin = []byte{
|
var fileDescriptorPlugin = []byte{
|
||||||
// 196 bytes of a gzipped FileDescriptorProto
|
// 256 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30,
|
||||||
0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b,
|
0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a,
|
||||||
0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30,
|
0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17,
|
||||||
0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12,
|
0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64,
|
||||||
0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35,
|
0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e,
|
||||||
0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c,
|
0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64,
|
||||||
0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a,
|
0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4,
|
||||||
0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab,
|
0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec,
|
||||||
0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
|
0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9,
|
||||||
0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33,
|
0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9,
|
||||||
0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
|
0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6,
|
||||||
0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79,
|
0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb,
|
||||||
0x0c, 0x01, 0x00, 0x00,
|
0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8,
|
||||||
|
0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb,
|
||||||
|
0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38,
|
||||||
|
0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ message PluginSpec {
|
||||||
string remote = 2;
|
string remote = 2;
|
||||||
repeated PluginPrivilege privileges = 3;
|
repeated PluginPrivilege privileges = 3;
|
||||||
bool disabled = 4;
|
bool disabled = 4;
|
||||||
|
repeated string env = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginPrivilege describes a permission the user has to accept
|
// PluginPrivilege describes a permission the user has to accept
|
||||||
|
|
|
@ -39,6 +39,7 @@ type ImageInspect struct {
|
||||||
Author string
|
Author string
|
||||||
Config *container.Config
|
Config *container.Config
|
||||||
Architecture string
|
Architecture string
|
||||||
|
Variant string `json:",omitempty"`
|
||||||
Os string
|
Os string
|
||||||
OsVersion string `json:",omitempty"`
|
OsVersion string `json:",omitempty"`
|
||||||
Size int64
|
Size int64
|
||||||
|
@ -177,6 +178,7 @@ type Info struct {
|
||||||
NEventsListener int
|
NEventsListener int
|
||||||
KernelVersion string
|
KernelVersion string
|
||||||
OperatingSystem string
|
OperatingSystem string
|
||||||
|
OSVersion string
|
||||||
OSType string
|
OSType string
|
||||||
Architecture string
|
Architecture string
|
||||||
IndexServerAddress string
|
IndexServerAddress string
|
||||||
|
|
|
@ -142,9 +142,9 @@ func supportsShallowClone(remoteURL string) bool {
|
||||||
serviceURL := remoteURL + "/info/refs?service=git-upload-pack"
|
serviceURL := remoteURL + "/info/refs?service=git-upload-pack"
|
||||||
|
|
||||||
// Try a HEAD request and fallback to a Get request on error
|
// Try a HEAD request and fallback to a Get request on error
|
||||||
res, err := http.Head(serviceURL)
|
res, err := http.Head(serviceURL) // #nosec G107
|
||||||
if err != nil || res.StatusCode != http.StatusOK {
|
if err != nil || res.StatusCode != http.StatusOK {
|
||||||
res, err = http.Get(serviceURL)
|
res, err = http.Get(serviceURL) // #nosec G107
|
||||||
if err == nil {
|
if err == nil {
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,8 @@ func (cli *Client) DaemonHost() string {
|
||||||
|
|
||||||
// HTTPClient returns a copy of the HTTP client bound to the server
|
// HTTPClient returns a copy of the HTTP client bound to the server
|
||||||
func (cli *Client) HTTPClient() *http.Client {
|
func (cli *Client) HTTPClient() *http.Client {
|
||||||
return &*cli.client
|
c := *cli.client
|
||||||
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHostURL parses a url string, validates the string is a host url, and
|
// ParseHostURL parses a url string, validates the string is a host url, and
|
||||||
|
|
|
@ -35,6 +35,7 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Filters.Len() > 0 {
|
if options.Filters.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -90,6 +90,7 @@ func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Filters.Len() > 0 {
|
if options.Filters.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters)
|
filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -87,6 +87,8 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
||||||
|
|
||||||
// Server hijacks the connection, error 'connection closed' expected
|
// Server hijacks the connection, error 'connection closed' expected
|
||||||
resp, err := clientconn.Do(req)
|
resp, err := clientconn.Do(req)
|
||||||
|
|
||||||
|
//lint:ignore SA1019 for connecting to old (pre go1.8) daemons
|
||||||
if err != httputil.ErrPersistEOF {
|
if err != httputil.ErrPersistEOF {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -24,6 +24,7 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if optionFilters.Len() > 0 {
|
if optionFilters.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return images, err
|
return images, err
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
if options.Filters.Len() > 0 {
|
if options.Filters.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -31,6 +31,8 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
// Server handled the request, so parse the response
|
// Server handled the request, so parse the response
|
||||||
return parsePingResponse(cli, serverResp)
|
return parsePingResponse(cli, serverResp)
|
||||||
}
|
}
|
||||||
|
} else if IsErrConnectionFailed(err) {
|
||||||
|
return ping, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||||
|
|
|
@ -15,6 +15,7 @@ func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.P
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
|
||||||
if filter.Len() > 0 {
|
if filter.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cli.version, filter)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return plugins, err
|
return plugins, err
|
||||||
|
|
|
@ -50,15 +50,6 @@ func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, b
|
||||||
return cli.sendRequest(ctx, "POST", path, query, body, headers)
|
return cli.sendRequest(ctx, "POST", path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// put sends an http request to the docker API using the method PUT.
|
|
||||||
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
|
||||||
body, headers, err := encodeBody(obj, headers)
|
|
||||||
if err != nil {
|
|
||||||
return serverResponse{}, err
|
|
||||||
}
|
|
||||||
return cli.sendRequest(ctx, "PUT", path, query, body, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// putRaw sends an http request to the docker API using the method PUT.
|
// putRaw sends an http request to the docker API using the method PUT.
|
||||||
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "PUT", path, query, body, headers)
|
return cli.sendRequest(ctx, "PUT", path, query, body, headers)
|
||||||
|
@ -178,7 +169,13 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
|
||||||
// this is localised - for example in French the error would be
|
// this is localised - for example in French the error would be
|
||||||
// `open //./pipe/docker_engine: Le fichier spécifié est introuvable.`
|
// `open //./pipe/docker_engine: Le fichier spécifié est introuvable.`
|
||||||
if strings.Contains(err.Error(), `open //./pipe/docker_engine`) {
|
if strings.Contains(err.Error(), `open //./pipe/docker_engine`) {
|
||||||
err = errors.New(err.Error() + " In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.")
|
// Checks if client is running with elevated privileges
|
||||||
|
if f, elevatedErr := os.Open("\\\\.\\PHYSICALDRIVE0"); elevatedErr == nil {
|
||||||
|
err = errors.Wrap(err, "In the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect.")
|
||||||
|
} else {
|
||||||
|
f.Close()
|
||||||
|
err = errors.Wrap(err, "This error may indicate that the docker daemon is not running.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return serverResp, errors.Wrap(err, "error during connect")
|
return serverResp, errors.Wrap(err, "error during connect")
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (volumet
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
|
||||||
if filter.Len() > 0 {
|
if filter.Len() > 0 {
|
||||||
|
//lint:ignore SA1019 for old code
|
||||||
filterJSON, err := filters.ToParamWithVersion(cli.version, filter)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return volumes, err
|
return volumes, err
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
containerderrors "github.com/containerd/containerd/errdefs"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
|
@ -47,6 +48,10 @@ func GetHTTPErrorStatusCode(err error) int {
|
||||||
if statusCode != http.StatusInternalServerError {
|
if statusCode != http.StatusInternalServerError {
|
||||||
return statusCode
|
return statusCode
|
||||||
}
|
}
|
||||||
|
statusCode = statusCodeFromContainerdError(err)
|
||||||
|
if statusCode != http.StatusInternalServerError {
|
||||||
|
return statusCode
|
||||||
|
}
|
||||||
statusCode = statusCodeFromDistributionError(err)
|
statusCode = statusCodeFromDistributionError(err)
|
||||||
if statusCode != http.StatusInternalServerError {
|
if statusCode != http.StatusInternalServerError {
|
||||||
return statusCode
|
return statusCode
|
||||||
|
@ -136,9 +141,6 @@ func statusCodeFromGRPCError(err error) int {
|
||||||
case codes.Unavailable: // code 14
|
case codes.Unavailable: // code 14
|
||||||
return http.StatusServiceUnavailable
|
return http.StatusServiceUnavailable
|
||||||
default:
|
default:
|
||||||
if e, ok := err.(causer); ok {
|
|
||||||
return statusCodeFromGRPCError(e.Cause())
|
|
||||||
}
|
|
||||||
// codes.Canceled(1)
|
// codes.Canceled(1)
|
||||||
// codes.Unknown(2)
|
// codes.Unknown(2)
|
||||||
// codes.DeadlineExceeded(4)
|
// codes.DeadlineExceeded(4)
|
||||||
|
@ -163,10 +165,27 @@ func statusCodeFromDistributionError(err error) int {
|
||||||
}
|
}
|
||||||
case errcode.ErrorCoder:
|
case errcode.ErrorCoder:
|
||||||
return errs.ErrorCode().Descriptor().HTTPStatusCode
|
return errs.ErrorCode().Descriptor().HTTPStatusCode
|
||||||
default:
|
|
||||||
if e, ok := err.(causer); ok {
|
|
||||||
return statusCodeFromDistributionError(e.Cause())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return http.StatusInternalServerError
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1134,7 +1134,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
||||||
dst = filepath.Join(dst, filepath.Base(src))
|
dst = filepath.Join(dst, filepath.Base(src))
|
||||||
}
|
}
|
||||||
// Create the holding directory if necessary
|
// Create the holding directory if necessary
|
||||||
if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
|
if err := system.MkdirAll(filepath.Dir(dst), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,6 +1218,9 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure the command has exited before we clean anything up
|
||||||
|
done := make(chan struct{})
|
||||||
|
|
||||||
// Copy stdout to the returned pipe
|
// Copy stdout to the returned pipe
|
||||||
go func() {
|
go func() {
|
||||||
if err := cmd.Wait(); err != nil {
|
if err := cmd.Wait(); err != nil {
|
||||||
|
@ -1225,9 +1228,16 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) {
|
||||||
} else {
|
} else {
|
||||||
pipeW.Close()
|
pipeW.Close()
|
||||||
}
|
}
|
||||||
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return pipeR, nil
|
return ioutils.NewReadCloserWrapper(pipeR, func() error {
|
||||||
|
// Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as
|
||||||
|
// cmd.Wait waits for any non-file stdout/stderr/stdin to close.
|
||||||
|
err := pipeR.Close()
|
||||||
|
<-done
|
||||||
|
return err
|
||||||
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTempArchive reads the content of src into a temporary file, and returns the contents
|
// NewTempArchive reads the content of src into a temporary file, and returns the contents
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/idtools"
|
"github.com/docker/docker/pkg/idtools"
|
||||||
|
@ -26,7 +27,7 @@ func fixVolumePathPrefix(srcPath string) string {
|
||||||
// can't use filepath.Join(srcPath,include) because this will clean away
|
// can't use filepath.Join(srcPath,include) because this will clean away
|
||||||
// a trailing "." or "/" which may be important.
|
// a trailing "." or "/" which may be important.
|
||||||
func getWalkRoot(srcPath string, include string) string {
|
func getWalkRoot(srcPath string, include string) string {
|
||||||
return srcPath + string(filepath.Separator) + include
|
return strings.TrimSuffix(srcPath, string(filepath.Separator)) + string(filepath.Separator) + include
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalTarNameForPath returns platform-specific filepath
|
// CanonicalTarNameForPath returns platform-specific filepath
|
||||||
|
|
|
@ -84,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
||||||
parentPath := filepath.Join(dest, parent)
|
parentPath := filepath.Join(dest, parent)
|
||||||
|
|
||||||
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
||||||
err = system.MkdirAll(parentPath, 0600, "")
|
err = system.MkdirAll(parentPath, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS); err != nil {
|
if err := createTarFile(path, dest, srcHdr, srcData, !options.NoLchown, nil, options.InUserNS); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,24 +5,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/idtools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetStatic returns the home directory for the current user without calling
|
|
||||||
// os/user.Current(). This is useful for static-linked binary on glibc-based
|
|
||||||
// system, because a call to os/user.Current() in a static binary leads to
|
|
||||||
// segfault due to a glibc issue that won't be fixed in a short term.
|
|
||||||
// (#29344, golang/go#13470, https://sourceware.org/bugzilla/show_bug.cgi?id=19341)
|
|
||||||
func GetStatic() (string, error) {
|
|
||||||
uid := os.Getuid()
|
|
||||||
usr, err := idtools.LookupUID(uid)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return usr.Home, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRuntimeDir returns XDG_RUNTIME_DIR.
|
// GetRuntimeDir returns XDG_RUNTIME_DIR.
|
||||||
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
|
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
|
||||||
// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
|
// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
|
||||||
|
|
|
@ -6,12 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetStatic is not needed for non-linux systems.
|
|
||||||
// (Precisely, it is needed only for glibc-based linux systems.)
|
|
||||||
func GetStatic() (string, error) {
|
|
||||||
return "", errors.New("homedir.GetStatic() is not supported on this system")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRuntimeDir is unsupported on non-linux system.
|
// GetRuntimeDir is unsupported on non-linux system.
|
||||||
func GetRuntimeDir() (string, error) {
|
func GetRuntimeDir() (string, error) {
|
||||||
return "", errors.New("homedir.GetRuntimeDir() is not supported on this system")
|
return "", errors.New("homedir.GetRuntimeDir() is not supported on this system")
|
||||||
|
|
|
@ -4,8 +4,7 @@ package homedir // import "github.com/docker/docker/pkg/homedir"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
"github.com/opencontainers/runc/libcontainer/user"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Key returns the env var name for the user's home dir based on
|
// Key returns the env var name for the user's home dir based on
|
||||||
|
@ -17,11 +16,13 @@ func Key() string {
|
||||||
// Get returns the home directory of the current user with the help of
|
// Get returns the home directory of the current user with the help of
|
||||||
// environment variables depending on the target operating system.
|
// environment variables depending on the target operating system.
|
||||||
// Returned path should be used with "path/filepath" to form new paths.
|
// Returned path should be used with "path/filepath" to form new paths.
|
||||||
|
// If compiling statically, ensure the osusergo build tag is used.
|
||||||
|
// If needing to do nss lookups, do not compile statically.
|
||||||
func Get() string {
|
func Get() string {
|
||||||
home := os.Getenv(Key())
|
home := os.Getenv(Key())
|
||||||
if home == "" {
|
if home == "" {
|
||||||
if u, err := user.CurrentUser(); err == nil {
|
if u, err := user.Current(); err == nil {
|
||||||
return u.Home
|
return u.HomeDir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return home
|
return home
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -203,8 +202,6 @@ func (i *IdentityMapping) GIDs() []IDMap {
|
||||||
func createIDMap(subidRanges ranges) []IDMap {
|
func createIDMap(subidRanges ranges) []IDMap {
|
||||||
idMap := []IDMap{}
|
idMap := []IDMap{}
|
||||||
|
|
||||||
// sort the ranges by lowest ID first
|
|
||||||
sort.Sort(subidRanges)
|
|
||||||
containerID := 0
|
containerID := 0
|
||||||
for _, idrange := range subidRanges {
|
for _, idrange := range subidRanges {
|
||||||
idMap = append(idMap, IDMap{
|
idMap = append(idMap, IDMap{
|
||||||
|
|
|
@ -59,7 +59,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting
|
||||||
paths = append(paths, dirPath)
|
paths = append(paths, dirPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := system.MkdirAll(path, mode, ""); err != nil {
|
if err := system.MkdirAll(path, mode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
// Ownership is handled elsewhere, but in the future could be support here
|
// Ownership is handled elsewhere, but in the future could be support here
|
||||||
// too.
|
// too.
|
||||||
func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error {
|
func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error {
|
||||||
if err := system.MkdirAll(path, mode, ""); err != nil {
|
if err := system.MkdirAll(path, mode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -128,8 +128,9 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) {
|
||||||
bp.mu.Lock()
|
bp.mu.Lock()
|
||||||
if bp.bufLen == 0 {
|
if bp.bufLen == 0 {
|
||||||
if bp.closeErr != nil {
|
if bp.closeErr != nil {
|
||||||
|
err := bp.closeErr
|
||||||
bp.mu.Unlock()
|
bp.mu.Unlock()
|
||||||
return 0, bp.closeErr
|
return 0, err
|
||||||
}
|
}
|
||||||
bp.wait.Wait()
|
bp.wait.Wait()
|
||||||
if bp.bufLen == 0 && bp.closeErr != nil {
|
if bp.bufLen == 0 && bp.closeErr != nil {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
"github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
"github.com/morikuni/aec"
|
"github.com/morikuni/aec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -102,13 +102,13 @@ func Mounted(mountpoint string) (bool, error) {
|
||||||
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
|
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
|
||||||
// flags.go for supported option flags.
|
// flags.go for supported option flags.
|
||||||
func Mount(device, target, mType, options string) error {
|
func Mount(device, target, mType, options string) error {
|
||||||
flag, _ := parseOptions(options)
|
flag, data := parseOptions(options)
|
||||||
if flag&REMOUNT != REMOUNT {
|
if flag&REMOUNT != REMOUNT {
|
||||||
if mounted, err := Mounted(target); err != nil || mounted {
|
if mounted, err := Mounted(target); err != nil || mounted {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ForceMount(device, target, mType, options)
|
return mount(device, target, mType, uintptr(flag), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceMount will mount a filesystem according to the specified configuration,
|
// ForceMount will mount a filesystem according to the specified configuration,
|
||||||
|
|
|
@ -13,8 +13,7 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
|
//parseMountTable returns information about mounted filesystems
|
||||||
// bind mounts.
|
|
||||||
func parseMountTable(filter FilterFunc) ([]*Info, error) {
|
func parseMountTable(filter FilterFunc) ([]*Info, error) {
|
||||||
var rawEntries *C.struct_statfs
|
var rawEntries *C.struct_statfs
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) {
|
||||||
|
|
||||||
if filter != nil {
|
if filter != nil {
|
||||||
// filter out entries we're not interested in
|
// filter out entries we're not interested in
|
||||||
skip, stop = filter(p)
|
skip, stop = filter(&mountinfo)
|
||||||
if skip {
|
if skip {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,49 +3,49 @@ package mount // import "github.com/docker/docker/pkg/mount"
|
||||||
// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
|
// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
|
||||||
// See the supported options in flags.go for further reference.
|
// See the supported options in flags.go for further reference.
|
||||||
func MakeShared(mountPoint string) error {
|
func MakeShared(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "shared")
|
return ensureMountedAs(mountPoint, SHARED)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
|
// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
|
||||||
// See the supported options in flags.go for further reference.
|
// See the supported options in flags.go for further reference.
|
||||||
func MakeRShared(mountPoint string) error {
|
func MakeRShared(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "rshared")
|
return ensureMountedAs(mountPoint, RSHARED)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
|
// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
|
||||||
// See the supported options in flags.go for further reference.
|
// See the supported options in flags.go for further reference.
|
||||||
func MakePrivate(mountPoint string) error {
|
func MakePrivate(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "private")
|
return ensureMountedAs(mountPoint, PRIVATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
|
// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
|
||||||
// enabled. See the supported options in flags.go for further reference.
|
// enabled. See the supported options in flags.go for further reference.
|
||||||
func MakeRPrivate(mountPoint string) error {
|
func MakeRPrivate(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "rprivate")
|
return ensureMountedAs(mountPoint, RPRIVATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
|
// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
|
||||||
// See the supported options in flags.go for further reference.
|
// See the supported options in flags.go for further reference.
|
||||||
func MakeSlave(mountPoint string) error {
|
func MakeSlave(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "slave")
|
return ensureMountedAs(mountPoint, SLAVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
|
// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
|
||||||
// See the supported options in flags.go for further reference.
|
// See the supported options in flags.go for further reference.
|
||||||
func MakeRSlave(mountPoint string) error {
|
func MakeRSlave(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "rslave")
|
return ensureMountedAs(mountPoint, RSLAVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
|
// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
|
||||||
// enabled. See the supported options in flags.go for further reference.
|
// enabled. See the supported options in flags.go for further reference.
|
||||||
func MakeUnbindable(mountPoint string) error {
|
func MakeUnbindable(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "unbindable")
|
return ensureMountedAs(mountPoint, UNBINDABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
|
// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
|
||||||
// option enabled. See the supported options in flags.go for further reference.
|
// option enabled. See the supported options in flags.go for further reference.
|
||||||
func MakeRUnbindable(mountPoint string) error {
|
func MakeRUnbindable(mountPoint string) error {
|
||||||
return ensureMountedAs(mountPoint, "runbindable")
|
return ensureMountedAs(mountPoint, RUNBINDABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeMount ensures that the file or directory given is a mount point,
|
// MakeMount ensures that the file or directory given is a mount point,
|
||||||
|
@ -59,13 +59,13 @@ func MakeMount(mnt string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mount(mnt, mnt, "none", "bind")
|
return mount(mnt, mnt, "none", uintptr(BIND), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureMountedAs(mountPoint, options string) error {
|
func ensureMountedAs(mnt string, flags int) error {
|
||||||
if err := MakeMount(mountPoint); err != nil {
|
if err := MakeMount(mnt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ForceMount("", mountPoint, "none", options)
|
return mount("", mnt, "none", uintptr(flags), "")
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ func (bp *bufferPool) Get() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bp *bufferPool) Put(b []byte) {
|
func (bp *bufferPool) Put(b []byte) {
|
||||||
|
//nolint:staticcheck // TODO changing this to a pointer makes tests fail. Investigate if we should change or not (otherwise remove this TODO)
|
||||||
bp.pool.Put(b)
|
bp.pool.Put(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,12 @@
|
||||||
package stringid // import "github.com/docker/docker/pkg/stringid"
|
package stringid // import "github.com/docker/docker/pkg/stringid"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
cryptorand "crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const shortLen = 12
|
const shortLen = 12
|
||||||
|
@ -41,10 +36,11 @@ func TruncateID(id string) string {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateID(r io.Reader) string {
|
// GenerateRandomID returns a unique id.
|
||||||
|
func GenerateRandomID() string {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
for {
|
for {
|
||||||
if _, err := io.ReadFull(r, b); err != nil {
|
if _, err := rand.Read(b); err != nil {
|
||||||
panic(err) // This shouldn't happen
|
panic(err) // This shouldn't happen
|
||||||
}
|
}
|
||||||
id := hex.EncodeToString(b)
|
id := hex.EncodeToString(b)
|
||||||
|
@ -58,18 +54,6 @@ func generateID(r io.Reader) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateRandomID returns a unique id.
|
|
||||||
func GenerateRandomID() string {
|
|
||||||
return generateID(cryptorand.Reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateNonCryptoID generates unique id without using cryptographically
|
|
||||||
// secure sources of random.
|
|
||||||
// It helps you to save entropy.
|
|
||||||
func GenerateNonCryptoID() string {
|
|
||||||
return generateID(readerFunc(rand.Read))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateID checks whether an ID string is a valid image ID.
|
// ValidateID checks whether an ID string is a valid image ID.
|
||||||
func ValidateID(id string) error {
|
func ValidateID(id string) error {
|
||||||
if ok := validHex.MatchString(id); !ok {
|
if ok := validHex.MatchString(id); !ok {
|
||||||
|
@ -77,23 +61,3 @@ func ValidateID(id string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
// safely set the seed globally so we generate random ids. Tries to use a
|
|
||||||
// crypto seed before falling back to time.
|
|
||||||
var seed int64
|
|
||||||
if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
|
|
||||||
// This should not happen, but worst-case fallback to time-based seed.
|
|
||||||
seed = time.Now().UnixNano()
|
|
||||||
} else {
|
|
||||||
seed = cryptoseed.Int64()
|
|
||||||
}
|
|
||||||
|
|
||||||
rand.Seed(seed)
|
|
||||||
}
|
|
||||||
|
|
||||||
type readerFunc func(p []byte) (int, error)
|
|
||||||
|
|
||||||
func (fn readerFunc) Read(p []byte) (int, error) {
|
|
||||||
return fn(p)
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,14 +8,14 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
|
// MkdirAllWithACL is a wrapper for os.MkdirAll on unix systems.
|
||||||
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||||
return MkdirAll(path, perm, sddl)
|
return os.MkdirAll(path, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAll creates a directory named path along with any necessary parents,
|
// MkdirAll creates a directory named path along with any necessary parents,
|
||||||
// with permission specified by attribute perm for all dir created.
|
// with permission specified by attribute perm for all dir created.
|
||||||
func MkdirAll(path string, perm os.FileMode, sddl string) error {
|
func MkdirAll(path string, perm os.FileMode) error {
|
||||||
return os.MkdirAll(path, perm)
|
return os.MkdirAll(path, perm)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,10 @@ func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||||
return mkdirall(path, true, sddl)
|
return mkdirall(path, true, sddl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAll implementation that is volume path aware for Windows.
|
// MkdirAll implementation that is volume path aware for Windows. It can be used
|
||||||
func MkdirAll(path string, _ os.FileMode, sddl string) error {
|
// as a drop-in replacement for os.MkdirAll()
|
||||||
return mkdirall(path, false, sddl)
|
func MkdirAll(path string, _ os.FileMode) error {
|
||||||
|
return mkdirall(path, false, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdirall is a custom version of os.MkdirAll modified for use on Windows
|
// mkdirall is a custom version of os.MkdirAll modified for use on Windows
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||||
|
@ -27,6 +27,7 @@ func ReadMemInfo() (*MemInfo, error) {
|
||||||
func parseMemInfo(reader io.Reader) (*MemInfo, error) {
|
func parseMemInfo(reader io.Reader) (*MemInfo, error) {
|
||||||
meminfo := &MemInfo{}
|
meminfo := &MemInfo{}
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
|
memAvailable := int64(-1)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
// Expected format: ["MemTotal:", "1234", "kB"]
|
// Expected format: ["MemTotal:", "1234", "kB"]
|
||||||
parts := strings.Fields(scanner.Text())
|
parts := strings.Fields(scanner.Text())
|
||||||
|
@ -48,6 +49,8 @@ func parseMemInfo(reader io.Reader) (*MemInfo, error) {
|
||||||
meminfo.MemTotal = bytes
|
meminfo.MemTotal = bytes
|
||||||
case "MemFree:":
|
case "MemFree:":
|
||||||
meminfo.MemFree = bytes
|
meminfo.MemFree = bytes
|
||||||
|
case "MemAvailable:":
|
||||||
|
memAvailable = bytes
|
||||||
case "SwapTotal:":
|
case "SwapTotal:":
|
||||||
meminfo.SwapTotal = bytes
|
meminfo.SwapTotal = bytes
|
||||||
case "SwapFree:":
|
case "SwapFree:":
|
||||||
|
@ -55,6 +58,9 @@ func parseMemInfo(reader io.Reader) (*MemInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if memAvailable != -1 {
|
||||||
|
meminfo.MemFree = memAvailable
|
||||||
|
}
|
||||||
|
|
||||||
// Handle errors that may have occurred during the reading of the file.
|
// Handle errors that may have occurred during the reading of the file.
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/continuity/pathdriver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
@ -27,6 +25,12 @@ func DefaultPathEnv(os string) string {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathVerifier defines the subset of a PathDriver that CheckSystemDriveAndRemoveDriveLetter
|
||||||
|
// actually uses in order to avoid system depending on containerd/continuity.
|
||||||
|
type PathVerifier interface {
|
||||||
|
IsAbs(string) bool
|
||||||
|
}
|
||||||
|
|
||||||
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
||||||
// is the system drive.
|
// is the system drive.
|
||||||
// On Linux: this is a no-op.
|
// On Linux: this is a no-op.
|
||||||
|
@ -42,7 +46,7 @@ func DefaultPathEnv(os string) string {
|
||||||
// a --> a
|
// a --> a
|
||||||
// /a --> \a
|
// /a --> \a
|
||||||
// d:\ --> Fail
|
// d:\ --> Fail
|
||||||
func CheckSystemDriveAndRemoveDriveLetter(path string, driver pathdriver.PathDriver) (string, error) {
|
func CheckSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) {
|
||||||
if runtime.GOOS != "windows" || LCOWSupported() {
|
if runtime.GOOS != "windows" || LCOWSupported() {
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
mode: s.Mode,
|
mode: s.Mode,
|
||||||
uid: s.Uid,
|
uid: s.Uid,
|
||||||
gid: s.Gid,
|
gid: s.Gid,
|
||||||
rdev: s.Rdev,
|
// the type is 32bit on mips
|
||||||
|
rdev: uint64(s.Rdev), // nolint: unconvert
|
||||||
mtim: s.Mtim}, nil
|
mtim: s.Mtim}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
|
||||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|
||||||
return &StatT{size: s.Size,
|
|
||||||
mode: uint32(s.Mode),
|
|
||||||
uid: s.Uid,
|
|
||||||
gid: s.Gid,
|
|
||||||
rdev: uint64(s.Rdev),
|
|
||||||
mtim: s.Mtim}, nil
|
|
||||||
}
|
|
|
@ -55,7 +55,6 @@ var (
|
||||||
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
||||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
||||||
procGetProductInfo = modkernel32.NewProc("GetProductInfo")
|
|
||||||
procSetNamedSecurityInfo = modadvapi32.NewProc("SetNamedSecurityInfoW")
|
procSetNamedSecurityInfo = modadvapi32.NewProc("SetNamedSecurityInfoW")
|
||||||
procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl")
|
procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl")
|
||||||
)
|
)
|
||||||
|
@ -85,7 +84,7 @@ type osVersionInfoEx struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOSVersion gets the operating system version on Windows. Note that
|
// GetOSVersion gets the operating system version on Windows. Note that
|
||||||
// docker.exe must be manifested to get the correct version information.
|
// dockerd.exe must be manifested to get the correct version information.
|
||||||
func GetOSVersion() OSVersion {
|
func GetOSVersion() OSVersion {
|
||||||
var err error
|
var err error
|
||||||
osv := OSVersion{}
|
osv := OSVersion{}
|
||||||
|
@ -118,22 +117,6 @@ func IsWindowsClient() bool {
|
||||||
return osviex.ProductType == verNTWorkstation
|
return osviex.ProductType == verNTWorkstation
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsIoTCore returns true if the currently running image is based off of
|
|
||||||
// Windows 10 IoT Core.
|
|
||||||
// @engine maintainers - this function should not be removed or modified as it
|
|
||||||
// is used to enforce licensing restrictions on Windows.
|
|
||||||
func IsIoTCore() bool {
|
|
||||||
var returnedProductType uint32
|
|
||||||
r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType)))
|
|
||||||
if r1 == 0 {
|
|
||||||
logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const productIoTUAP = 0x0000007B
|
|
||||||
const productIoTUAPCommercial = 0x00000083
|
|
||||||
return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmount is a platform-specific helper function to call
|
// Unmount is a platform-specific helper function to call
|
||||||
// the unmount syscall. Not supported on Windows
|
// the unmount syscall. Not supported on Windows
|
||||||
func Unmount(dest string) error {
|
func Unmount(dest string) error {
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LUtimesNano is used to change access and modification time of the specified path.
|
|
||||||
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
|
||||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
|
||||||
atFdCwd := unix.AT_FDCWD
|
|
||||||
|
|
||||||
var _path *byte
|
|
||||||
_path, err := unix.BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
// +build linux freebsd
|
||||||
|
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
package system // import "github.com/docker/docker/pkg/system"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
@ -10,13 +11,12 @@ import (
|
||||||
// LUtimesNano is used to change access and modification time of the specified path.
|
// LUtimesNano is used to change access and modification time of the specified path.
|
||||||
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||||
var _path *byte
|
uts := []unix.Timespec{
|
||||||
_path, err := unix.BytePtrFromString(path)
|
unix.NsecToTimespec(syscall.TimespecToNsec(ts[0])),
|
||||||
if err != nil {
|
unix.NsecToTimespec(syscall.TimespecToNsec(ts[1])),
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
err := unix.UtimesNanoAt(unix.AT_FDCWD, path, uts, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS {
|
if err != nil && err != unix.ENOSYS {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE
|
"syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE
|
||||||
|
|
||||||
"github.com/Azure/go-ansiterm/winterm"
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
"github.com/docker/docker/pkg/term/windows"
|
windowsconsole "github.com/docker/docker/pkg/term/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
// State holds the console mode for the terminal.
|
// State holds the console mode for the terminal.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// +build windows
|
||||||
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
|
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
|
||||||
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
|
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
|
||||||
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Azure/go-ansiterm"
|
ansiterm "github.com/Azure/go-ansiterm"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,6 @@ func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent strin
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint := newV1Endpoint(*uri, tlsConfig, userAgent, metaHeaders)
|
endpoint := newV1Endpoint(*uri, tlsConfig, userAgent, metaHeaders)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint, nil
|
return endpoint, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/distribution/registry/client/transport"
|
"github.com/docker/distribution/registry/client/transport"
|
||||||
"github.com/docker/go-connections/sockets"
|
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -176,16 +175,12 @@ func NewTransport(tlsConfig *tls.Config) *http.Transport {
|
||||||
|
|
||||||
base := &http.Transport{
|
base := &http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
Dial: direct.Dial,
|
DialContext: direct.DialContext,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
TLSClientConfig: tlsConfig,
|
TLSClientConfig: tlsConfig,
|
||||||
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
||||||
DisableKeepAlives: true,
|
DisableKeepAlives: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyDialer, err := sockets.DialerFromEnvironment(direct)
|
|
||||||
if err == nil {
|
|
||||||
base.Dial = proxyDialer.Dial
|
|
||||||
}
|
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package registry // import "github.com/docker/docker/registry"
|
|
||||||
|
|
||||||
import "net/url"
|
|
||||||
|
|
||||||
func (s *DefaultService) lookupV1Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
|
||||||
if hostname == DefaultNamespace || hostname == DefaultV2Registry.Host || hostname == IndexHostname {
|
|
||||||
return []APIEndpoint{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConfig, err := s.tlsConfig(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoints = []APIEndpoint{
|
|
||||||
{
|
|
||||||
URL: &url.URL{
|
|
||||||
Scheme: "https",
|
|
||||||
Host: hostname,
|
|
||||||
},
|
|
||||||
Version: APIVersion1,
|
|
||||||
TrimHostname: true,
|
|
||||||
TLSConfig: tlsConfig,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if tlsConfig.InsecureSkipVerify {
|
|
||||||
endpoints = append(endpoints, APIEndpoint{ // or this
|
|
||||||
URL: &url.URL{
|
|
||||||
Scheme: "http",
|
|
||||||
Host: hostname,
|
|
||||||
},
|
|
||||||
Version: APIVersion1,
|
|
||||||
TrimHostname: true,
|
|
||||||
// used to check if supposed to be secure via InsecureSkipVerify
|
|
||||||
TLSConfig: tlsConfig,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return endpoints, nil
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ package registry // import "github.com/docker/docker/registry"
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
// this is required for some certificates
|
// this is required for some certificates
|
||||||
_ "crypto/sha512"
|
_ "crypto/sha512"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
||||||
github.com/Microsoft/hcsshim 672e52e9209d1e53718c1b6a7d68cc9272654ab5
|
github.com/Microsoft/hcsshim 672e52e9209d1e53718c1b6a7d68cc9272654ab5
|
||||||
github.com/Microsoft/go-winio 3fe4fa31662f6ede2353d913e93907b8e096e0b6
|
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
|
||||||
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
||||||
github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
|
|
||||||
github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
|
github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
|
||||||
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
|
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
|
||||||
github.com/gorilla/mux a7962380ca08b5a188038c69871b8d3fbdf31e89 # v1.7.0
|
github.com/gorilla/mux ed099d42384823742bba0bf9a72b53b55c9e2e38 # v1.7.2
|
||||||
github.com/Microsoft/opengcs a10967154e143a36014584a6f664344e3bb0aa64
|
github.com/Microsoft/opengcs a10967154e143a36014584a6f664344e3bb0aa64
|
||||||
|
|
||||||
|
github.com/creack/pty 2769f65a3a94eb8f876f44a0459d24ae7ad2e488 # v1.1.7
|
||||||
github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d86a2c9b5b50e # v1.0.2
|
github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d86a2c9b5b50e # v1.0.2
|
||||||
github.com/kr/pty 521317be5ebc228a0f0ede099fa2a0b5ece22e49 # v1.1.4
|
|
||||||
github.com/mattn/go-shellwords a72fbe27a1b0ed0df2f02754945044ce1456608b # v1.0.5
|
github.com/mattn/go-shellwords a72fbe27a1b0ed0df2f02754945044ce1456608b # v1.0.5
|
||||||
github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
|
github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
|
||||||
github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0
|
github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0
|
||||||
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 # v0.1.0
|
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||||
golang.org/x/net eb5bcb51f2a31c7d5141d810b70815c05d9c9146
|
golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7
|
||||||
golang.org/x/sys 4b34438f7a67ee5f45cc6132e2bad873a20324e9
|
|
||||||
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
||||||
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
||||||
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
|
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
|
||||||
|
@ -27,7 +25,7 @@ github.com/imdario/mergo 7c29201646fa3de8506f70121347
|
||||||
golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c
|
golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c
|
||||||
|
|
||||||
# buildkit
|
# buildkit
|
||||||
github.com/moby/buildkit 8c0fa8fdec187d8f259a349d2da16dc2dc5f144a # v0.5.0
|
github.com/moby/buildkit 588c73e1e4f0f3d7d3738abaaa7cf8026064b33e
|
||||||
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b
|
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b
|
||||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||||
|
@ -39,19 +37,20 @@ github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0
|
||||||
# libnetwork
|
# libnetwork
|
||||||
|
|
||||||
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
|
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
|
||||||
github.com/docker/libnetwork 9ff9b57c344df5cd47443ad9e65702ec85c5aeb0
|
github.com/docker/libnetwork 96bcc0dae898308ed659c5095526788a602f4726
|
||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
||||||
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
||||||
github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c
|
github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c
|
||||||
github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
|
github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
|
||||||
github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9
|
github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0
|
||||||
github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
|
github.com/hashicorp/go-sockaddr c7188e74f6acae5a989bdc959aa779f8b9f42faf # v1.0.2
|
||||||
|
github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
|
||||||
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
|
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
|
||||||
github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b
|
github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b
|
||||||
github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
|
github.com/vishvananda/netns 7109fa855b0ff1ebef7fbd2f6aa613e8db7cfbc0
|
||||||
github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e
|
github.com/vishvananda/netlink a2ad57a690f3caf3015351d2d6e1c0b95c349752
|
||||||
|
|
||||||
# When updating, consider updating TOMLV_COMMIT in hack/dockerfile/install/tomlv.installer accordingly
|
# When updating, consider updating TOMLV_COMMIT in hack/dockerfile/install/tomlv.installer accordingly
|
||||||
github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
|
github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
|
||||||
|
@ -62,8 +61,8 @@ github.com/coreos/go-semver 8ab6407b697782a06568d4b7f1db
|
||||||
github.com/ugorji/go b4c50a2b199d93b13dc15e78929cfb23bfdf21ab # v1.1.1
|
github.com/ugorji/go b4c50a2b199d93b13dc15e78929cfb23bfdf21ab # v1.1.1
|
||||||
github.com/hashicorp/consul 9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9 # v0.5.2
|
github.com/hashicorp/consul 9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9 # v0.5.2
|
||||||
github.com/miekg/dns e57bf427e68187a27e22adceac868350d7a7079b # v1.0.7
|
github.com/miekg/dns e57bf427e68187a27e22adceac868350d7a7079b # v1.0.7
|
||||||
github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
|
github.com/ishidawataru/sctp 6e2cb1366111dcf547c13531e3a263a067715847
|
||||||
go.etcd.io/bbolt 7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 # v1.3.1-etcd.8
|
go.etcd.io/bbolt a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3
|
||||||
|
|
||||||
# get graph and distribution packages
|
# get graph and distribution packages
|
||||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||||
|
@ -73,7 +72,7 @@ github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b0
|
||||||
# get go-zfs packages
|
# get go-zfs packages
|
||||||
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
||||||
|
|
||||||
google.golang.org/grpc 7a6a684ca69eb4cae85ad0a484f2e531598c047b # v1.12.2
|
google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
|
||||||
|
|
||||||
# The version of runc should match the version that is used by the containerd
|
# The version of runc should match the version that is used by the containerd
|
||||||
# version that is used. If you need to update runc, open a pull request in
|
# version that is used. If you need to update runc, open a pull request in
|
||||||
|
@ -83,7 +82,7 @@ google.golang.org/grpc 7a6a684ca69eb4cae85ad0a484f2
|
||||||
github.com/opencontainers/runc 425e105d5a03fabd737a126ad93d62a9eeede87f # v1.0.0-rc8
|
github.com/opencontainers/runc 425e105d5a03fabd737a126ad93d62a9eeede87f # v1.0.0-rc8
|
||||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||||
github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
|
github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
|
||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
|
||||||
|
|
||||||
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
|
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
|
||||||
github.com/coreos/go-systemd 39ca1b05acc7ad1220e09f133283b8859a8b71ab # v17
|
github.com/coreos/go-systemd 39ca1b05acc7ad1220e09f133283b8859a8b71ab # v17
|
||||||
|
@ -119,21 +118,21 @@ github.com/googleapis/gax-go 317e0006254c44a0ac427cc52a0e
|
||||||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||||
|
|
||||||
# containerd
|
# containerd
|
||||||
github.com/containerd/containerd 3a3f0aac8819165839a41fee77a4f4ac8b103097
|
github.com/containerd/containerd 7c1e88399ec0b0b077121d9d5ad97e647b11c870
|
||||||
github.com/containerd/fifo a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c
|
github.com/containerd/fifo a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c
|
||||||
github.com/containerd/continuity aaeac12a7ffcd198ae25440a9dff125c2e2703a7
|
github.com/containerd/continuity aaeac12a7ffcd198ae25440a9dff125c2e2703a7
|
||||||
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
||||||
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
||||||
github.com/containerd/go-runc 7d11b49dc0769f6dbb0d1b19f3d48524d1bad9ad
|
github.com/containerd/go-runc 7d11b49dc0769f6dbb0d1b19f3d48524d1bad9ad
|
||||||
github.com/containerd/typeurl 2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d
|
github.com/containerd/typeurl 2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d
|
||||||
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
||||||
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
||||||
|
|
||||||
# cluster
|
# cluster
|
||||||
github.com/docker/swarmkit 59163bf75df38489d4a10392265d27156dc473c5
|
github.com/docker/swarmkit 7dded76ec532741c1ad9736cd2bb6d6661f0a386
|
||||||
github.com/gogo/protobuf ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
|
github.com/gogo/protobuf ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
|
||||||
github.com/cloudflare/cfssl 5d63dbd981b5c408effbb58c442d54761ff94fbd # 1.3.2
|
github.com/cloudflare/cfssl 5d63dbd981b5c408effbb58c442d54761ff94fbd # 1.3.2
|
||||||
github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
|
github.com/fernet/fernet-go 9eac43b88a5efb8651d24de9b68e87567e029736
|
||||||
github.com/google/certificate-transparency-go 37a384cd035e722ea46e55029093e26687138edf # v1.0.20
|
github.com/google/certificate-transparency-go 37a384cd035e722ea46e55029093e26687138edf # v1.0.20
|
||||||
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
||||||
golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
|
golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
RemoveServiceResponse
|
RemoveServiceResponse
|
||||||
ListServicesRequest
|
ListServicesRequest
|
||||||
ListServicesResponse
|
ListServicesResponse
|
||||||
|
ListServiceStatusesRequest
|
||||||
|
ListServiceStatusesResponse
|
||||||
CreateNetworkRequest
|
CreateNetworkRequest
|
||||||
CreateNetworkResponse
|
CreateNetworkResponse
|
||||||
GetNetworkRequest
|
GetNetworkRequest
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -50,6 +50,16 @@ service Control {
|
||||||
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
|
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ListServiceStatuses returns a `ListServiceStatusesResponse` with the
|
||||||
|
// status of the requested services, formed by computing the number of
|
||||||
|
// running vs desired tasks. It is provided as a shortcut or helper method,
|
||||||
|
// which allows a client to avoid having to calculate this value by listing
|
||||||
|
// all Tasks. If any service requested does not exist, it will be returned
|
||||||
|
// but with empty status values.
|
||||||
|
rpc ListServiceStatuses(ListServiceStatusesRequest) returns (ListServiceStatusesResponse) {
|
||||||
|
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
|
||||||
|
};
|
||||||
|
|
||||||
rpc GetNetwork(GetNetworkRequest) returns (GetNetworkResponse) {
|
rpc GetNetwork(GetNetworkRequest) returns (GetNetworkResponse) {
|
||||||
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
|
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
|
||||||
};
|
};
|
||||||
|
@ -397,6 +407,37 @@ message ListServicesResponse {
|
||||||
repeated Service services = 1;
|
repeated Service services = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListServiceStatusesRequest is a request to get the aggregate status of a
|
||||||
|
// service by computing the number of running vs desired tasks. It includes
|
||||||
|
// only a service ID.
|
||||||
|
message ListServiceStatusesRequest {
|
||||||
|
// Services is a list of service IDs to get statuses for.
|
||||||
|
repeated string services = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListServiceStatusesResponse is a response containing the aggregate status of
|
||||||
|
// a service, formed by computing the number of running vs desired tasks. The
|
||||||
|
// values returned are only valid for the point in time at which the request is
|
||||||
|
// made.
|
||||||
|
message ListServiceStatusesResponse {
|
||||||
|
message ServiceStatus {
|
||||||
|
// ServiceID is the ID of the service this status describes
|
||||||
|
string service_id = 1;
|
||||||
|
|
||||||
|
// DesiredTasks is the number of tasks desired to be running according to the
|
||||||
|
// service definition at request time. It is a uint64 because that is what
|
||||||
|
// the replicas field on the service spec is
|
||||||
|
uint64 desired_tasks = 2;
|
||||||
|
|
||||||
|
// RunningTasks is the number of tasks currently in the Running state at
|
||||||
|
// request time. This may be larger than desired tasks if, for example, a
|
||||||
|
// service has been scaled down.
|
||||||
|
uint64 running_tasks = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated ServiceStatus statuses = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message CreateNetworkRequest {
|
message CreateNetworkRequest {
|
||||||
NetworkSpec spec = 1;
|
NetworkSpec spec = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -636,6 +636,8 @@ type ContainerSpec struct {
|
||||||
//
|
//
|
||||||
// https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime
|
// https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime
|
||||||
Sysctls map[string]string `protobuf:"bytes,26,rep,name=sysctls" json:"sysctls,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
Sysctls map[string]string `protobuf:"bytes,26,rep,name=sysctls" json:"sysctls,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
|
// Capabilities is the list of Linux capabilities to be available for container (this overrides the default set of capabilities)
|
||||||
|
Capabilities []string `protobuf:"bytes,27,rep,name=capabilities" json:"capabilities,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ContainerSpec) Reset() { *m = ContainerSpec{} }
|
func (m *ContainerSpec) Reset() { *m = ContainerSpec{} }
|
||||||
|
@ -1197,6 +1199,11 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.Capabilities != nil {
|
||||||
|
m.Capabilities = make([]string, len(o.Capabilities))
|
||||||
|
copy(m.Capabilities, o.Capabilities)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ContainerSpec_PullOptions) Copy() *ContainerSpec_PullOptions {
|
func (m *ContainerSpec_PullOptions) Copy() *ContainerSpec_PullOptions {
|
||||||
|
@ -2104,6 +2111,23 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
|
||||||
i += copy(dAtA[i:], v)
|
i += copy(dAtA[i:], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(m.Capabilities) > 0 {
|
||||||
|
for _, s := range m.Capabilities {
|
||||||
|
dAtA[i] = 0xda
|
||||||
|
i++
|
||||||
|
dAtA[i] = 0x1
|
||||||
|
i++
|
||||||
|
l = len(s)
|
||||||
|
for l >= 1<<7 {
|
||||||
|
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||||
|
l >>= 7
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
dAtA[i] = uint8(l)
|
||||||
|
i++
|
||||||
|
i += copy(dAtA[i:], s)
|
||||||
|
}
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2829,6 +2853,12 @@ func (m *ContainerSpec) Size() (n int) {
|
||||||
n += mapEntrySize + 2 + sovSpecs(uint64(mapEntrySize))
|
n += mapEntrySize + 2 + sovSpecs(uint64(mapEntrySize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(m.Capabilities) > 0 {
|
||||||
|
for _, s := range m.Capabilities {
|
||||||
|
l = len(s)
|
||||||
|
n += 2 + l + sovSpecs(uint64(l))
|
||||||
|
}
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3188,6 +3218,7 @@ func (this *ContainerSpec) String() string {
|
||||||
`Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`,
|
`Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`,
|
||||||
`PidsLimit:` + fmt.Sprintf("%v", this.PidsLimit) + `,`,
|
`PidsLimit:` + fmt.Sprintf("%v", this.PidsLimit) + `,`,
|
||||||
`Sysctls:` + mapStringForSysctls + `,`,
|
`Sysctls:` + mapStringForSysctls + `,`,
|
||||||
|
`Capabilities:` + fmt.Sprintf("%v", this.Capabilities) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
|
@ -5454,6 +5485,35 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
|
||||||
}
|
}
|
||||||
m.Sysctls[mapkey] = mapvalue
|
m.Sysctls[mapkey] = mapvalue
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 27:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Capabilities", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowSpecs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthSpecs
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Capabilities = append(m.Capabilities, string(dAtA[iNdEx:postIndex]))
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipSpecs(dAtA[iNdEx:])
|
skippy, err := skipSpecs(dAtA[iNdEx:])
|
||||||
|
@ -6765,141 +6825,142 @@ var (
|
||||||
func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
|
func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
|
||||||
|
|
||||||
var fileDescriptorSpecs = []byte{
|
var fileDescriptorSpecs = []byte{
|
||||||
// 2166 bytes of a gzipped FileDescriptorProto
|
// 2178 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0x1b, 0xc9,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0x1b, 0xb9,
|
||||||
0xd1, 0x16, 0x25, 0x8a, 0x1f, 0x35, 0x94, 0x4d, 0xf5, 0xda, 0xde, 0x11, 0x6d, 0x4b, 0x34, 0xd7,
|
0x15, 0xb7, 0x6c, 0x59, 0x7f, 0x9e, 0xe4, 0x44, 0xe6, 0x26, 0xd9, 0xb1, 0x92, 0xd8, 0x8a, 0x36,
|
||||||
0xeb, 0x57, 0xbb, 0x8b, 0x97, 0x42, 0x94, 0xc5, 0xc6, 0x6b, 0x67, 0x93, 0x90, 0x22, 0x57, 0x62,
|
0x9b, 0x7a, 0x77, 0x51, 0x19, 0x75, 0x17, 0xdb, 0x6c, 0xd2, 0x6d, 0x2b, 0x59, 0x5a, 0x5b, 0x4d,
|
||||||
0x6c, 0x4b, 0x44, 0x53, 0x56, 0x62, 0x20, 0x00, 0xd1, 0x9a, 0x69, 0x91, 0x03, 0x0d, 0xa7, 0x27,
|
0x62, 0x0b, 0x94, 0xe3, 0x36, 0x40, 0x01, 0x81, 0x9e, 0xa1, 0x25, 0xc2, 0xa3, 0xe1, 0x94, 0xa4,
|
||||||
0xdd, 0x4d, 0x19, 0xbc, 0xe5, 0xb8, 0x50, 0x7e, 0x83, 0x90, 0x43, 0x90, 0x7b, 0xf2, 0x2f, 0x7c,
|
0x1c, 0xe8, 0xd6, 0xe3, 0xc2, 0xfd, 0x0c, 0x46, 0x0f, 0x45, 0xef, 0xed, 0xb7, 0xc8, 0xb1, 0xc7,
|
||||||
0xcc, 0x31, 0xb9, 0x08, 0x59, 0x1d, 0xf2, 0x07, 0x72, 0xcb, 0x25, 0x41, 0xf7, 0xf4, 0xf0, 0x43,
|
0xf6, 0x62, 0x74, 0xfd, 0x15, 0x7a, 0xeb, 0xa5, 0x05, 0x39, 0x1c, 0xfd, 0x71, 0xe4, 0x38, 0x45,
|
||||||
0x1e, 0x59, 0x0e, 0xe2, 0x43, 0x6e, 0xdd, 0x35, 0xcf, 0x53, 0xfd, 0xf5, 0x54, 0x75, 0xf5, 0xc0,
|
0x73, 0xe8, 0x8d, 0x7c, 0xf3, 0xfb, 0x3d, 0xfe, 0xfb, 0xbd, 0xc7, 0xc7, 0x81, 0xcf, 0xbb, 0x4c,
|
||||||
0xe7, 0x3d, 0x4f, 0xf6, 0x87, 0x87, 0x55, 0x87, 0x0d, 0x36, 0x5c, 0xe6, 0x1c, 0x53, 0xbe, 0x21,
|
0xf5, 0x06, 0x87, 0x15, 0x97, 0xf7, 0x37, 0x3c, 0xee, 0x1e, 0x53, 0xb1, 0x21, 0x5f, 0x13, 0xd1,
|
||||||
0x5e, 0x13, 0x3e, 0x38, 0xf6, 0xe4, 0x06, 0x09, 0xbd, 0x0d, 0x11, 0x52, 0x47, 0x54, 0x43, 0xce,
|
0x3f, 0x66, 0x6a, 0x83, 0x84, 0x6c, 0x43, 0x86, 0xd4, 0x95, 0x95, 0x50, 0x70, 0xc5, 0x11, 0x8a,
|
||||||
0x24, 0x43, 0x28, 0x02, 0x54, 0x63, 0x40, 0xf5, 0xe4, 0x07, 0xa5, 0xeb, 0xf8, 0x72, 0x14, 0x52,
|
0x00, 0x95, 0x18, 0x50, 0x39, 0xf9, 0x51, 0xf1, 0x3a, 0xbe, 0x1a, 0x86, 0xd4, 0xf2, 0x8b, 0xb7,
|
||||||
0xc3, 0x2f, 0xdd, 0xea, 0xb1, 0x1e, 0xd3, 0xcd, 0x0d, 0xd5, 0x32, 0xd6, 0xd5, 0x1e, 0x63, 0x3d,
|
0xba, 0xbc, 0xcb, 0x4d, 0x73, 0x43, 0xb7, 0xac, 0x75, 0xb5, 0xcb, 0x79, 0xd7, 0xa7, 0x1b, 0xa6,
|
||||||
0x9f, 0x6e, 0xe8, 0xde, 0xe1, 0xf0, 0x68, 0xc3, 0x1d, 0x72, 0x22, 0x3d, 0x16, 0x98, 0xef, 0x2b,
|
0x77, 0x38, 0x38, 0xda, 0xf0, 0x06, 0x82, 0x28, 0xc6, 0x03, 0xfb, 0x7d, 0xe5, 0xf2, 0x77, 0x12,
|
||||||
0x97, 0xbf, 0x93, 0x60, 0x74, 0x15, 0xf5, 0x35, 0x27, 0x61, 0x48, 0xb9, 0x19, 0xb0, 0x72, 0x96,
|
0x0c, 0xaf, 0xa2, 0xbe, 0x16, 0x24, 0x0c, 0xa9, 0xb0, 0x03, 0x96, 0xcf, 0x92, 0x90, 0xd9, 0xe5,
|
||||||
0x86, 0xdc, 0x2e, 0x73, 0x69, 0x27, 0xa4, 0x0e, 0xda, 0x06, 0x8b, 0x04, 0x01, 0x93, 0xda, 0xb7,
|
0x1e, 0x6d, 0x87, 0xd4, 0x45, 0xdb, 0x90, 0x23, 0x41, 0xc0, 0x95, 0xf1, 0x2d, 0x9d, 0x44, 0x29,
|
||||||
0xb0, 0x53, 0xe5, 0xd4, 0xba, 0xb5, 0xb9, 0x56, 0x7d, 0x7b, 0x4d, 0xd5, 0xda, 0x04, 0x56, 0x4f,
|
0xb1, 0x9e, 0xdb, 0x5c, 0xab, 0xbc, 0xbd, 0xa6, 0x4a, 0x75, 0x0c, 0xab, 0x25, 0xdf, 0x9c, 0xaf,
|
||||||
0xbf, 0x39, 0x5f, 0x9b, 0xc3, 0xd3, 0x4c, 0xf4, 0x53, 0x28, 0xb8, 0x54, 0x78, 0x9c, 0xba, 0x5d,
|
0xcd, 0xe1, 0x49, 0x26, 0xfa, 0x39, 0xe4, 0x3d, 0x2a, 0x99, 0xa0, 0x5e, 0x47, 0x70, 0x9f, 0x3a,
|
||||||
0xce, 0x7c, 0x6a, 0xcf, 0x97, 0x53, 0xeb, 0x37, 0x36, 0xef, 0x25, 0x79, 0x52, 0x83, 0x63, 0xe6,
|
0xf3, 0xa5, 0xc4, 0xfa, 0x8d, 0xcd, 0x7b, 0xb3, 0x3c, 0xe9, 0xc1, 0x31, 0xf7, 0x29, 0xce, 0x59,
|
||||||
0x53, 0x6c, 0x19, 0x86, 0xea, 0xa0, 0x6d, 0x80, 0x01, 0x1d, 0x1c, 0x52, 0x2e, 0xfa, 0x5e, 0x68,
|
0x86, 0xee, 0xa0, 0x6d, 0x80, 0x3e, 0xed, 0x1f, 0x52, 0x21, 0x7b, 0x2c, 0x74, 0x16, 0x0c, 0xfd,
|
||||||
0x2f, 0x68, 0xfa, 0xff, 0x5d, 0x45, 0x57, 0x73, 0xaf, 0xbe, 0x18, 0xc3, 0xf1, 0x14, 0x15, 0xbd,
|
0x07, 0x57, 0xd1, 0xf5, 0xdc, 0x2b, 0x2f, 0x46, 0x70, 0x3c, 0x41, 0x45, 0x2f, 0x20, 0x4f, 0x4e,
|
||||||
0x80, 0x02, 0x39, 0x21, 0x9e, 0x4f, 0x0e, 0x3d, 0xdf, 0x93, 0x23, 0x3b, 0xad, 0x5d, 0x7d, 0xf6,
|
0x08, 0xf3, 0xc9, 0x21, 0xf3, 0x99, 0x1a, 0x3a, 0x49, 0xe3, 0xea, 0xb3, 0x77, 0xba, 0xaa, 0x4e,
|
||||||
0x4e, 0x57, 0xb5, 0x29, 0x02, 0x9e, 0xa1, 0x57, 0x5c, 0x80, 0xc9, 0x40, 0xe8, 0x11, 0x64, 0xdb,
|
0x10, 0xf0, 0x14, 0xbd, 0xec, 0x01, 0x8c, 0x07, 0x42, 0x8f, 0x20, 0xdd, 0x6a, 0xec, 0xd6, 0x9b,
|
||||||
0xcd, 0xdd, 0x46, 0x6b, 0x77, 0xbb, 0x38, 0x57, 0x5a, 0x39, 0x3d, 0x2b, 0xdf, 0x56, 0x3e, 0x26,
|
0xbb, 0xdb, 0x85, 0xb9, 0xe2, 0xca, 0xe9, 0x59, 0xe9, 0xb6, 0xf6, 0x31, 0x06, 0xb4, 0x68, 0xe0,
|
||||||
0x80, 0x36, 0x0d, 0x5c, 0x2f, 0xe8, 0xa1, 0x75, 0xc8, 0xd5, 0xb6, 0xb6, 0x9a, 0xed, 0xfd, 0x66,
|
0xb1, 0xa0, 0x8b, 0xd6, 0x21, 0x53, 0xdd, 0xda, 0x6a, 0xb4, 0xf6, 0x1b, 0xf5, 0x42, 0xa2, 0x58,
|
||||||
0xa3, 0x98, 0x2a, 0x95, 0x4e, 0xcf, 0xca, 0x77, 0x66, 0x81, 0x35, 0xc7, 0xa1, 0xa1, 0xa4, 0x6e,
|
0x3c, 0x3d, 0x2b, 0xdd, 0x99, 0x06, 0x56, 0x5d, 0x97, 0x86, 0x8a, 0x7a, 0xc5, 0xe4, 0x77, 0x7f,
|
||||||
0x29, 0xfd, 0xdd, 0xef, 0x57, 0xe7, 0x2a, 0xdf, 0xa5, 0xa0, 0x30, 0x3d, 0x09, 0xf4, 0x08, 0x32,
|
0x5c, 0x9d, 0x2b, 0x7f, 0x97, 0x80, 0xfc, 0xe4, 0x24, 0xd0, 0x23, 0x48, 0x55, 0xb7, 0xf6, 0x9b,
|
||||||
0xb5, 0xad, 0xfd, 0xd6, 0x41, 0xb3, 0x38, 0x37, 0xa1, 0x4f, 0x23, 0x6a, 0x8e, 0xf4, 0x4e, 0x28,
|
0x07, 0x8d, 0xc2, 0xdc, 0x98, 0x3e, 0x89, 0xa8, 0xba, 0x8a, 0x9d, 0x50, 0xf4, 0x10, 0x16, 0x5b,
|
||||||
0x7a, 0x08, 0x8b, 0xed, 0xda, 0xcb, 0x4e, 0xb3, 0x98, 0x9a, 0x4c, 0x67, 0x1a, 0xd6, 0x26, 0x43,
|
0xd5, 0x97, 0xed, 0x46, 0x21, 0x31, 0x9e, 0xce, 0x24, 0xac, 0x45, 0x06, 0xd2, 0xa0, 0xea, 0xb8,
|
||||||
0xa1, 0x51, 0x0d, 0x5c, 0x6b, 0xed, 0x16, 0xe7, 0x93, 0x51, 0x0d, 0x4e, 0xbc, 0xc0, 0x4c, 0xe5,
|
0xda, 0xdc, 0x2d, 0xcc, 0xcf, 0x46, 0xd5, 0x05, 0x61, 0x81, 0x9d, 0xca, 0x1f, 0x92, 0x90, 0x6b,
|
||||||
0x77, 0x69, 0xb0, 0x3a, 0x94, 0x9f, 0x78, 0xce, 0x07, 0x96, 0xc8, 0x57, 0x90, 0x96, 0x44, 0x1c,
|
0x53, 0x71, 0xc2, 0xdc, 0x0f, 0x2c, 0x91, 0xaf, 0x20, 0xa9, 0x88, 0x3c, 0x36, 0xd2, 0xc8, 0xcd,
|
||||||
0x6b, 0x69, 0x58, 0xc9, 0xd2, 0xd8, 0x27, 0xe2, 0x58, 0x0d, 0x6a, 0xe8, 0x1a, 0xaf, 0x94, 0xc1,
|
0x96, 0xc6, 0x3e, 0x91, 0xc7, 0x7a, 0x50, 0x4b, 0x37, 0x78, 0xad, 0x0c, 0x41, 0x43, 0x9f, 0xb9,
|
||||||
0x69, 0xe8, 0x7b, 0x0e, 0x91, 0xd4, 0xd5, 0xca, 0xb0, 0x36, 0x3f, 0x4d, 0x62, 0xe3, 0x31, 0xca,
|
0x44, 0x51, 0xcf, 0x28, 0x23, 0xb7, 0xf9, 0xe9, 0x2c, 0x36, 0x1e, 0xa1, 0xec, 0xfc, 0x77, 0xe6,
|
||||||
0xcc, 0x7f, 0x67, 0x0e, 0x4f, 0x51, 0xd1, 0x53, 0xc8, 0xf4, 0x7c, 0x76, 0x48, 0x7c, 0xad, 0x09,
|
0xf0, 0x04, 0x15, 0x3d, 0x85, 0x54, 0xd7, 0xe7, 0x87, 0xc4, 0x37, 0x9a, 0xc8, 0x6d, 0x3e, 0x98,
|
||||||
0x6b, 0xf3, 0x41, 0x92, 0x93, 0x6d, 0x8d, 0x98, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x32, 0xc3, 0xd0,
|
0xe5, 0x64, 0xdb, 0x20, 0xc6, 0x0e, 0x2c, 0x05, 0x3d, 0x86, 0xd4, 0x20, 0xf4, 0x88, 0xa2, 0x4e,
|
||||||
0x25, 0x92, 0xda, 0x19, 0x4d, 0x2e, 0x27, 0x91, 0x5f, 0x6a, 0xc4, 0x16, 0x0b, 0x8e, 0xbc, 0x1e,
|
0xca, 0x90, 0x4b, 0xb3, 0xc8, 0x2f, 0x0d, 0x62, 0x8b, 0x07, 0x47, 0xac, 0x8b, 0x2d, 0x1e, 0x3d,
|
||||||
0x36, 0x78, 0xf4, 0x0c, 0x72, 0x01, 0x95, 0xaf, 0x19, 0x3f, 0x16, 0x76, 0xb6, 0xbc, 0xb0, 0x6e,
|
0x83, 0x4c, 0x40, 0xd5, 0x6b, 0x2e, 0x8e, 0xa5, 0x93, 0x2e, 0x2d, 0xac, 0xe7, 0x36, 0xbf, 0x98,
|
||||||
0x6d, 0x7e, 0x91, 0x28, 0xc6, 0x08, 0x53, 0x93, 0x92, 0x38, 0xfd, 0x01, 0x0d, 0x64, 0xe4, 0xa6,
|
0x29, 0xc6, 0x08, 0x53, 0x55, 0x8a, 0xb8, 0xbd, 0x3e, 0x0d, 0x54, 0xe4, 0xa6, 0x36, 0xef, 0x24,
|
||||||
0x3e, 0x6f, 0xa7, 0xf0, 0xd8, 0x01, 0xfa, 0x31, 0xe4, 0x68, 0xe0, 0x86, 0xcc, 0x0b, 0xa4, 0x9d,
|
0xf0, 0xc8, 0x01, 0xfa, 0x29, 0x64, 0x68, 0xe0, 0x85, 0x9c, 0x05, 0xca, 0xc9, 0x5c, 0x3d, 0x91,
|
||||||
0xbb, 0x7a, 0x22, 0x4d, 0x83, 0x51, 0x9b, 0x89, 0xc7, 0x0c, 0xc5, 0xe6, 0xcc, 0xf7, 0x0f, 0x89,
|
0x86, 0xc5, 0xe8, 0xcd, 0xc4, 0x23, 0x86, 0x66, 0x0b, 0xee, 0xfb, 0x87, 0xc4, 0x3d, 0x76, 0xb2,
|
||||||
0x73, 0x6c, 0xe7, 0xdf, 0x73, 0x19, 0x63, 0x46, 0x3d, 0x03, 0xe9, 0x01, 0x73, 0x69, 0x65, 0x03,
|
0xef, 0xb9, 0x8c, 0x11, 0xa3, 0x96, 0x82, 0x64, 0x9f, 0x7b, 0xb4, 0xbc, 0x01, 0xcb, 0x6f, 0x6d,
|
||||||
0x96, 0xdf, 0xda, 0x6a, 0x54, 0x82, 0x9c, 0xd9, 0xea, 0x48, 0x23, 0x69, 0x3c, 0xee, 0x57, 0x6e,
|
0x35, 0x2a, 0x42, 0xc6, 0x6e, 0x75, 0xa4, 0x91, 0x24, 0x1e, 0xf5, 0xcb, 0x37, 0x61, 0x69, 0x6a,
|
||||||
0xc2, 0xd2, 0xcc, 0xb6, 0x56, 0xfe, 0xb8, 0x08, 0xb9, 0xf8, 0xac, 0x51, 0x0d, 0xf2, 0x0e, 0x0b,
|
0x5b, 0xcb, 0x7f, 0x5e, 0x84, 0x4c, 0x7c, 0xd6, 0xa8, 0x0a, 0x59, 0x97, 0x07, 0x8a, 0xb0, 0x80,
|
||||||
0x24, 0xf1, 0x02, 0xca, 0x8d, 0xbc, 0x12, 0x4f, 0x66, 0x2b, 0x06, 0x29, 0xd6, 0xce, 0x1c, 0x9e,
|
0x0a, 0x2b, 0xaf, 0x99, 0x27, 0xb3, 0x15, 0x83, 0x34, 0x6b, 0x67, 0x0e, 0x8f, 0x59, 0xe8, 0x5b,
|
||||||
0xb0, 0xd0, 0xb7, 0x90, 0xe7, 0x54, 0xb0, 0x21, 0x77, 0xa8, 0x30, 0xfa, 0x5a, 0x4f, 0x56, 0x48,
|
0xc8, 0x0a, 0x2a, 0xf9, 0x40, 0xb8, 0x54, 0x5a, 0x7d, 0xad, 0xcf, 0x56, 0x48, 0x04, 0xc2, 0xf4,
|
||||||
0x04, 0xc2, 0xf4, 0xd7, 0x43, 0x8f, 0x53, 0xb5, 0xcb, 0x02, 0x4f, 0xa8, 0xe8, 0x29, 0x64, 0x39,
|
0xb7, 0x03, 0x26, 0xa8, 0xde, 0x65, 0x89, 0xc7, 0x54, 0xf4, 0x14, 0xd2, 0x82, 0x4a, 0x45, 0x84,
|
||||||
0x15, 0x92, 0x70, 0xf9, 0x2e, 0x89, 0xe0, 0x08, 0xd2, 0x66, 0xbe, 0xe7, 0x8c, 0x70, 0xcc, 0x40,
|
0x7a, 0x97, 0x44, 0x70, 0x04, 0x69, 0x71, 0x9f, 0xb9, 0x43, 0x1c, 0x33, 0xd0, 0x53, 0xc8, 0x86,
|
||||||
0x4f, 0x21, 0x1f, 0xfa, 0xc4, 0xd1, 0x5e, 0xed, 0x45, 0x4d, 0xbf, 0x9f, 0x44, 0x6f, 0xc7, 0x20,
|
0x3e, 0x71, 0x8d, 0x57, 0x67, 0xd1, 0xd0, 0xef, 0xcf, 0xa2, 0xb7, 0x62, 0x10, 0x1e, 0xe3, 0xd1,
|
||||||
0x3c, 0xc1, 0xa3, 0xaf, 0x01, 0x7c, 0xd6, 0xeb, 0xba, 0xdc, 0x3b, 0xa1, 0xdc, 0x48, 0xac, 0x94,
|
0xd7, 0x00, 0x3e, 0xef, 0x76, 0x3c, 0xc1, 0x4e, 0xa8, 0xb0, 0x12, 0x2b, 0xce, 0x62, 0xd7, 0x0d,
|
||||||
0xc4, 0x6e, 0x68, 0x04, 0xce, 0xfb, 0xac, 0x17, 0x35, 0xd1, 0xf6, 0x7f, 0xa5, 0xaf, 0x29, 0x6d,
|
0x02, 0x67, 0x7d, 0xde, 0x8d, 0x9a, 0x68, 0xfb, 0x7f, 0xd2, 0xd7, 0x84, 0xb6, 0x9e, 0x01, 0x90,
|
||||||
0x3d, 0x03, 0x20, 0xe3, 0xaf, 0x46, 0x5d, 0x9f, 0xbd, 0x97, 0x2b, 0x73, 0x22, 0x53, 0x74, 0xf4,
|
0xd1, 0x57, 0xab, 0xae, 0xcf, 0xde, 0xcb, 0x95, 0x3d, 0x91, 0x09, 0x3a, 0x7a, 0x00, 0xf9, 0x23,
|
||||||
0x00, 0x0a, 0x47, 0x8c, 0x3b, 0xb4, 0x6b, 0xa2, 0x26, 0xaf, 0x35, 0x61, 0x69, 0x5b, 0xa4, 0x2f,
|
0x2e, 0x5c, 0xda, 0xb1, 0x51, 0x93, 0x35, 0x9a, 0xc8, 0x19, 0x5b, 0xa4, 0x2f, 0x54, 0x83, 0x74,
|
||||||
0x54, 0x87, 0x6c, 0x8f, 0x06, 0x94, 0x7b, 0x8e, 0x0d, 0x7a, 0xb0, 0x47, 0x89, 0x01, 0x19, 0x41,
|
0x97, 0x06, 0x54, 0x30, 0xd7, 0x01, 0x33, 0xd8, 0xa3, 0x99, 0x01, 0x19, 0x41, 0xf0, 0x20, 0x50,
|
||||||
0xf0, 0x30, 0x90, 0xde, 0x80, 0x9a, 0x91, 0x62, 0x22, 0xfa, 0x15, 0x7c, 0x14, 0x1f, 0x5f, 0x97,
|
0xac, 0x4f, 0xed, 0x48, 0x31, 0x11, 0xfd, 0x06, 0x3e, 0x8a, 0x8f, 0xaf, 0x23, 0xe8, 0x11, 0x15,
|
||||||
0xd3, 0x23, 0xca, 0x69, 0xa0, 0x34, 0x60, 0xe9, 0x7d, 0xf8, 0xf4, 0xdd, 0x1a, 0x30, 0x68, 0x93,
|
0x34, 0xd0, 0x1a, 0xc8, 0x99, 0x7d, 0xf8, 0xf4, 0xdd, 0x1a, 0xb0, 0x68, 0x9b, 0x6c, 0x90, 0xb8,
|
||||||
0x6c, 0x10, 0xbf, 0xfc, 0x41, 0xd4, 0xf3, 0x90, 0xe5, 0xd1, 0xb8, 0x95, 0xdf, 0xa6, 0x94, 0xea,
|
0xfc, 0x41, 0xd6, 0xb2, 0x90, 0x16, 0xd1, 0xb8, 0xe5, 0xdf, 0x27, 0xb4, 0xea, 0x2f, 0x21, 0xd0,
|
||||||
0x2f, 0x21, 0xd0, 0x06, 0x58, 0xe3, 0xe1, 0x3d, 0x57, 0xab, 0x37, 0x5f, 0xbf, 0x71, 0x71, 0xbe,
|
0x06, 0xe4, 0x46, 0xc3, 0x33, 0xcf, 0xa8, 0x37, 0x5b, 0xbb, 0x71, 0x71, 0xbe, 0x06, 0x31, 0xb6,
|
||||||
0x06, 0x31, 0xb6, 0xd5, 0x50, 0x39, 0xc8, 0xb4, 0x5d, 0xd4, 0x84, 0xa5, 0x31, 0x41, 0x95, 0x01,
|
0x59, 0xd7, 0x39, 0xc8, 0xb6, 0x3d, 0xd4, 0x80, 0xa5, 0x11, 0x41, 0x97, 0x01, 0xf6, 0xa2, 0x2c,
|
||||||
0xe6, 0xa2, 0x2c, 0xbf, 0x6b, 0xa6, 0xfb, 0xa3, 0x90, 0xe2, 0x02, 0x9f, 0xea, 0x55, 0x7e, 0x09,
|
0xbd, 0x6b, 0xa6, 0xfb, 0xc3, 0x90, 0xe2, 0xbc, 0x98, 0xe8, 0x95, 0x7f, 0x0d, 0xe8, 0xed, 0x7d,
|
||||||
0xe8, 0xed, 0x7d, 0x41, 0x08, 0xd2, 0xc7, 0x5e, 0x60, 0xa6, 0x81, 0x75, 0x1b, 0x55, 0x21, 0x1b,
|
0x41, 0x08, 0x92, 0xc7, 0x2c, 0xb0, 0xd3, 0xc0, 0xa6, 0x8d, 0x2a, 0x90, 0x0e, 0xc9, 0xd0, 0xe7,
|
||||||
0x92, 0x91, 0xcf, 0x88, 0x6b, 0x02, 0xe3, 0x56, 0x35, 0x2a, 0x10, 0xaa, 0x71, 0x81, 0x50, 0xad,
|
0xc4, 0xb3, 0x81, 0x71, 0xab, 0x12, 0x15, 0x08, 0x95, 0xb8, 0x40, 0xa8, 0x54, 0x83, 0x21, 0x8e,
|
||||||
0x05, 0x23, 0x1c, 0x83, 0x2a, 0xcf, 0xe0, 0x76, 0xe2, 0xf1, 0xa2, 0x4d, 0x28, 0x8c, 0x03, 0x6e,
|
0x41, 0xe5, 0x67, 0x70, 0x7b, 0xe6, 0xf1, 0xa2, 0x4d, 0xc8, 0x8f, 0x02, 0x6e, 0xbc, 0xd6, 0x9b,
|
||||||
0xb2, 0xd6, 0x9b, 0x17, 0xe7, 0x6b, 0xd6, 0x38, 0x32, 0x5b, 0x0d, 0x6c, 0x8d, 0x41, 0x2d, 0xb7,
|
0x17, 0xe7, 0x6b, 0xb9, 0x51, 0x64, 0x36, 0xeb, 0x38, 0x37, 0x02, 0x35, 0xbd, 0xf2, 0xe9, 0x12,
|
||||||
0xf2, 0xf7, 0x02, 0x2c, 0xcd, 0x84, 0x2d, 0xba, 0x05, 0x8b, 0xde, 0x80, 0xf4, 0xa8, 0x99, 0x63,
|
0x2c, 0x4d, 0x85, 0x2d, 0xba, 0x05, 0x8b, 0xac, 0x4f, 0xba, 0xd4, 0xce, 0x31, 0xea, 0xa0, 0x06,
|
||||||
0xd4, 0x41, 0x4d, 0xc8, 0xf8, 0xe4, 0x90, 0xfa, 0x2a, 0x78, 0xd5, 0xc1, 0xfd, 0xff, 0xb5, 0xf1,
|
0xa4, 0x7c, 0x72, 0x48, 0x7d, 0x1d, 0xbc, 0xfa, 0xe0, 0x7e, 0x78, 0x6d, 0xfc, 0x57, 0x9e, 0x1b,
|
||||||
0x5f, 0x7d, 0xae, 0xf1, 0xcd, 0x40, 0xf2, 0x11, 0x36, 0x64, 0x64, 0x43, 0xd6, 0x61, 0x83, 0x01,
|
0x7c, 0x23, 0x50, 0x62, 0x88, 0x2d, 0x19, 0x39, 0x90, 0x76, 0x79, 0xbf, 0x4f, 0x02, 0x7d, 0x4d,
|
||||||
0x09, 0xd4, 0x35, 0xb1, 0xb0, 0x9e, 0xc7, 0x71, 0x57, 0xed, 0x0c, 0xe1, 0x3d, 0x61, 0xa7, 0xb5,
|
0x2c, 0xac, 0x67, 0x71, 0xdc, 0xd5, 0x3b, 0x43, 0x44, 0x57, 0x3a, 0x49, 0x63, 0x36, 0x6d, 0x54,
|
||||||
0x59, 0xb7, 0x51, 0x11, 0x16, 0x68, 0x70, 0x62, 0x2f, 0x6a, 0x93, 0x6a, 0x2a, 0x8b, 0xeb, 0x45,
|
0x80, 0x05, 0x1a, 0x9c, 0x38, 0x8b, 0xc6, 0xa4, 0x9b, 0xda, 0xe2, 0xb1, 0x28, 0xfa, 0xb2, 0x58,
|
||||||
0xd1, 0x97, 0xc7, 0xaa, 0xa9, 0x78, 0x43, 0x41, 0xb9, 0x9d, 0x8d, 0x76, 0x54, 0xb5, 0xd1, 0x8f,
|
0x37, 0x35, 0x6f, 0x20, 0xa9, 0x70, 0xd2, 0xd1, 0x8e, 0xea, 0x36, 0xfa, 0x09, 0xa4, 0xfa, 0x7c,
|
||||||
0x20, 0x33, 0x60, 0xc3, 0x40, 0x0a, 0x3b, 0xa7, 0x27, 0xbb, 0x92, 0x34, 0xd9, 0x17, 0x0a, 0x61,
|
0x10, 0x28, 0xe9, 0x64, 0xcc, 0x64, 0x57, 0x66, 0x4d, 0xf6, 0x85, 0x46, 0x58, 0x65, 0x59, 0x38,
|
||||||
0x94, 0x65, 0xe0, 0xa8, 0x09, 0xcb, 0x42, 0xb2, 0xb0, 0xdb, 0xe3, 0xc4, 0xa1, 0xdd, 0x90, 0x72,
|
0x6a, 0xc0, 0xb2, 0x54, 0x3c, 0xec, 0x74, 0x05, 0x71, 0x69, 0x27, 0xa4, 0x82, 0x71, 0xcf, 0xa6,
|
||||||
0x8f, 0xb9, 0x26, 0x0d, 0xaf, 0xbc, 0x75, 0x28, 0x0d, 0x53, 0xf0, 0xe1, 0x9b, 0x8a, 0xb3, 0xad,
|
0xe1, 0x95, 0xb7, 0x0e, 0xa5, 0x6e, 0x0b, 0x3e, 0x7c, 0x53, 0x73, 0xb6, 0x35, 0xa5, 0x65, 0x18,
|
||||||
0x28, 0x6d, 0xcd, 0x40, 0x6d, 0x28, 0x84, 0x43, 0xdf, 0xef, 0xb2, 0x30, 0xba, 0x91, 0xa3, 0xd8,
|
0xa8, 0x05, 0xf9, 0x70, 0xe0, 0xfb, 0x1d, 0x1e, 0x46, 0x37, 0x72, 0x14, 0x3b, 0xef, 0xb1, 0x65,
|
||||||
0x79, 0x8f, 0x2d, 0x6b, 0x0f, 0x7d, 0x7f, 0x2f, 0x22, 0x61, 0x2b, 0x9c, 0x74, 0xd0, 0x1d, 0xc8,
|
0xad, 0x81, 0xef, 0xef, 0x45, 0x24, 0x9c, 0x0b, 0xc7, 0x1d, 0x74, 0x07, 0x52, 0x5d, 0xc1, 0x07,
|
||||||
0xf4, 0x38, 0x1b, 0x86, 0x51, 0xdc, 0xe4, 0xb1, 0xe9, 0xa1, 0x6f, 0x20, 0x2b, 0xa8, 0xc3, 0xa9,
|
0x61, 0x14, 0x37, 0x59, 0x6c, 0x7b, 0xe8, 0x1b, 0x48, 0x4b, 0xea, 0x0a, 0xaa, 0xa4, 0x93, 0x37,
|
||||||
0x14, 0x76, 0x41, 0x2f, 0xf5, 0x93, 0xa4, 0x41, 0x3a, 0x1a, 0x32, 0x8e, 0x09, 0x1c, 0x73, 0xd0,
|
0x4b, 0xfd, 0x64, 0xd6, 0x20, 0x6d, 0x03, 0x19, 0xc5, 0x04, 0x8e, 0x39, 0x68, 0x05, 0x16, 0x94,
|
||||||
0x0a, 0x2c, 0x48, 0x39, 0xb2, 0x97, 0xca, 0xa9, 0xf5, 0x5c, 0x3d, 0x7b, 0x71, 0xbe, 0xb6, 0xb0,
|
0x1a, 0x3a, 0x4b, 0xa5, 0xc4, 0x7a, 0xa6, 0x96, 0xbe, 0x38, 0x5f, 0x5b, 0xd8, 0xdf, 0x7f, 0x85,
|
||||||
0xbf, 0xff, 0x0a, 0x2b, 0x9b, 0xba, 0x2d, 0xfa, 0x4c, 0xc8, 0x80, 0x0c, 0xa8, 0x7d, 0x43, 0xef,
|
0xb5, 0x4d, 0xdf, 0x16, 0x3d, 0x2e, 0x55, 0x40, 0xfa, 0xd4, 0xb9, 0x61, 0xf6, 0x76, 0xd4, 0x47,
|
||||||
0xed, 0xb8, 0x8f, 0x5e, 0x01, 0xb8, 0x81, 0xe8, 0x3a, 0x3a, 0x3d, 0xd9, 0x37, 0xf5, 0xea, 0xbe,
|
0xaf, 0x00, 0xbc, 0x40, 0x76, 0x5c, 0x93, 0x9e, 0x9c, 0x9b, 0x66, 0x75, 0x5f, 0x5c, 0xbf, 0xba,
|
||||||
0xb8, 0x7e, 0x75, 0x8d, 0xdd, 0x8e, 0xb9, 0x31, 0x97, 0x2e, 0xce, 0xd7, 0xf2, 0xe3, 0x2e, 0xce,
|
0xfa, 0x6e, 0xdb, 0xde, 0x98, 0x4b, 0x17, 0xe7, 0x6b, 0xd9, 0x51, 0x17, 0x67, 0xbd, 0x40, 0x46,
|
||||||
0xbb, 0x81, 0x88, 0x9a, 0xa8, 0x0e, 0x56, 0x9f, 0x12, 0x5f, 0xf6, 0x9d, 0x3e, 0x75, 0x8e, 0xed,
|
0x4d, 0x54, 0x83, 0x5c, 0x8f, 0x12, 0x5f, 0xf5, 0xdc, 0x1e, 0x75, 0x8f, 0x9d, 0xc2, 0xd5, 0x57,
|
||||||
0xe2, 0xd5, 0x57, 0xe0, 0x8e, 0x86, 0x19, 0x0f, 0xd3, 0x24, 0xa5, 0x60, 0x35, 0x55, 0x61, 0x2f,
|
0xe0, 0x8e, 0x81, 0x59, 0x0f, 0x93, 0x24, 0xad, 0x60, 0x3d, 0x55, 0xe9, 0x2c, 0x9b, 0xbd, 0x8a,
|
||||||
0xeb, 0xbd, 0x8a, 0x3a, 0xe8, 0x3e, 0x00, 0x0b, 0x69, 0xd0, 0x15, 0xd2, 0xf5, 0x02, 0x1b, 0xa9,
|
0x3a, 0xe8, 0x3e, 0x00, 0x0f, 0x69, 0xd0, 0x91, 0xca, 0x63, 0x81, 0x83, 0xf4, 0x92, 0x71, 0x56,
|
||||||
0x25, 0xe3, 0xbc, 0xb2, 0x74, 0x94, 0x01, 0xdd, 0x55, 0x17, 0x14, 0x71, 0xbb, 0x2c, 0xf0, 0x47,
|
0x5b, 0xda, 0xda, 0x80, 0xee, 0xea, 0x0b, 0x8a, 0x78, 0x1d, 0x1e, 0xf8, 0x43, 0xe7, 0x23, 0xf3,
|
||||||
0xf6, 0x47, 0xfa, 0x6b, 0x4e, 0x19, 0xf6, 0x02, 0x7f, 0x84, 0xd6, 0xc0, 0xd2, 0xba, 0x10, 0x5e,
|
0x35, 0xa3, 0x0d, 0x7b, 0x81, 0x3f, 0x44, 0x6b, 0x90, 0x33, 0xba, 0x90, 0xac, 0x1b, 0x10, 0xdf,
|
||||||
0x2f, 0x20, 0xbe, 0x7d, 0x4b, 0xef, 0x07, 0x28, 0x53, 0x47, 0x5b, 0xd4, 0x39, 0x44, 0xbb, 0x21,
|
0xb9, 0x65, 0xf6, 0x03, 0xb4, 0xa9, 0x6d, 0x2c, 0xfa, 0x1c, 0xa2, 0xdd, 0x90, 0xce, 0xed, 0xab,
|
||||||
0xec, 0xdb, 0x57, 0x9f, 0x83, 0x99, 0xec, 0xe4, 0x1c, 0x0c, 0x07, 0xfd, 0x04, 0x20, 0xe4, 0xde,
|
0xcf, 0xc1, 0x4e, 0x76, 0x7c, 0x0e, 0x96, 0x83, 0x7e, 0x06, 0x10, 0x0a, 0x76, 0xc2, 0x7c, 0xda,
|
||||||
0x89, 0xe7, 0xd3, 0x1e, 0x15, 0xf6, 0x1d, 0xbd, 0xe8, 0xd5, 0xc4, 0x9b, 0x69, 0x8c, 0xc2, 0x53,
|
0xa5, 0xd2, 0xb9, 0x63, 0x16, 0xbd, 0x3a, 0xf3, 0x66, 0x1a, 0xa1, 0xf0, 0x04, 0x03, 0x55, 0x20,
|
||||||
0x0c, 0x54, 0x85, 0xb4, 0x17, 0x78, 0xd2, 0xfe, 0xd8, 0xdc, 0x4a, 0x97, 0xa5, 0x5a, 0x67, 0xcc,
|
0xc9, 0x02, 0xa6, 0x9c, 0x8f, 0xed, 0xad, 0x74, 0x59, 0xaa, 0x35, 0xce, 0xfd, 0x03, 0xe2, 0x0f,
|
||||||
0x3f, 0x20, 0xfe, 0x90, 0x62, 0x8d, 0x43, 0x2d, 0xc8, 0x7b, 0x82, 0xf9, 0x5a, 0xbe, 0xb6, 0xad,
|
0x28, 0x36, 0x38, 0xd4, 0x84, 0x2c, 0x93, 0xdc, 0x37, 0xf2, 0x75, 0x1c, 0x93, 0xdf, 0xde, 0xe3,
|
||||||
0xf3, 0xdb, 0x7b, 0x9c, 0x5f, 0x2b, 0xa6, 0xe0, 0x09, 0x1b, 0xdd, 0x83, 0x7c, 0xe8, 0xb9, 0xe2,
|
0xfc, 0x9a, 0x31, 0x05, 0x8f, 0xd9, 0xe8, 0x1e, 0x64, 0x43, 0xe6, 0xc9, 0xe7, 0xac, 0xcf, 0x94,
|
||||||
0xb9, 0x37, 0xf0, 0xa4, 0xbd, 0x52, 0x4e, 0xad, 0x2f, 0xe0, 0x89, 0x01, 0xed, 0x40, 0x56, 0x8c,
|
0xb3, 0x52, 0x4a, 0xac, 0x2f, 0xe0, 0xb1, 0x01, 0xed, 0x40, 0x5a, 0x0e, 0xa5, 0xab, 0x7c, 0xe9,
|
||||||
0x84, 0x23, 0x7d, 0x61, 0x97, 0xf4, 0xbe, 0x54, 0xaf, 0x1f, 0xa6, 0x13, 0x11, 0xa2, 0xc4, 0x11,
|
0x14, 0xcd, 0xbe, 0x54, 0xae, 0x1f, 0xa6, 0x1d, 0x11, 0xa2, 0xc4, 0x11, 0xd3, 0x51, 0x19, 0xf2,
|
||||||
0xd3, 0x4b, 0x5f, 0x83, 0x35, 0x95, 0x50, 0x54, 0x22, 0x38, 0xa6, 0x23, 0x93, 0xa3, 0x54, 0x53,
|
0x2e, 0x09, 0xa3, 0x6a, 0x98, 0x51, 0xe9, 0xdc, 0x35, 0x67, 0x3b, 0x65, 0x2b, 0x7e, 0x0d, 0xb9,
|
||||||
0x9d, 0xfa, 0x89, 0x5a, 0xa2, 0x4e, 0xa2, 0x79, 0x1c, 0x75, 0x9e, 0xcc, 0x3f, 0x4e, 0x95, 0x36,
|
0x89, 0xa4, 0xa3, 0x93, 0xc5, 0x31, 0x1d, 0xda, 0x3c, 0xa6, 0x9b, 0x5a, 0x19, 0x27, 0x7a, 0x1b,
|
||||||
0xc1, 0x9a, 0x0a, 0x2c, 0xf4, 0x89, 0x4a, 0xf0, 0x3d, 0x4f, 0x48, 0x3e, 0xea, 0x92, 0xa1, 0xec,
|
0x4c, 0xa2, 0xcd, 0xe2, 0xa8, 0xf3, 0x64, 0xfe, 0x71, 0xa2, 0xb8, 0x09, 0xb9, 0x89, 0xe0, 0x43,
|
||||||
0xdb, 0x3f, 0xd3, 0x84, 0x42, 0x6c, 0xac, 0x0d, 0x65, 0xbf, 0xd4, 0x85, 0x89, 0x3e, 0x51, 0x19,
|
0x9f, 0xe8, 0x4b, 0xa0, 0xcb, 0xa4, 0x12, 0xc3, 0x0e, 0x19, 0xa8, 0x9e, 0xf3, 0x0b, 0x43, 0xc8,
|
||||||
0x2c, 0xa5, 0x7b, 0x41, 0xf9, 0x09, 0xe5, 0xaa, 0x78, 0x52, 0xb2, 0x9a, 0x36, 0xa9, 0xf8, 0x14,
|
0xc7, 0xc6, 0xea, 0x40, 0xf5, 0x8a, 0x1d, 0x18, 0x6b, 0x18, 0x95, 0x20, 0xa7, 0x63, 0x43, 0x52,
|
||||||
0x94, 0x70, 0xa7, 0xaf, 0xd3, 0x63, 0x1e, 0x9b, 0x9e, 0xca, 0x77, 0x71, 0x12, 0x30, 0xf9, 0xce,
|
0x71, 0x42, 0x85, 0x2e, 0xb0, 0xf4, 0xf4, 0x26, 0x4d, 0x3a, 0x86, 0x25, 0x25, 0xc2, 0xed, 0x99,
|
||||||
0x74, 0x4b, 0x4f, 0xa0, 0x30, 0xbd, 0xd0, 0xff, 0x64, 0x41, 0x95, 0x3f, 0xa5, 0x20, 0x3f, 0x3e,
|
0x14, 0x9a, 0xc5, 0xb6, 0xa7, 0x73, 0x62, 0x9c, 0x28, 0x6c, 0x4e, 0xb4, 0xdd, 0xe2, 0x13, 0xc8,
|
||||||
0x0c, 0xf4, 0x25, 0x2c, 0xb7, 0x3a, 0x7b, 0xcf, 0x6b, 0xfb, 0xad, 0xbd, 0xdd, 0x6e, 0xa3, 0xf9,
|
0x4f, 0x6e, 0xc6, 0x7f, 0xb3, 0xa0, 0xf2, 0x5f, 0x12, 0x90, 0x1d, 0x1d, 0x18, 0xfa, 0x12, 0x96,
|
||||||
0x6d, 0xed, 0xe5, 0xf3, 0xfd, 0xe2, 0x5c, 0xe9, 0xfe, 0xe9, 0x59, 0x79, 0x65, 0x92, 0xf7, 0x63,
|
0x9b, 0xed, 0xbd, 0xe7, 0xd5, 0xfd, 0xe6, 0xde, 0x6e, 0xa7, 0xde, 0xf8, 0xb6, 0xfa, 0xf2, 0xf9,
|
||||||
0x78, 0x83, 0x1e, 0x91, 0xa1, 0x2f, 0x67, 0x59, 0x6d, 0xbc, 0xb7, 0xd5, 0xec, 0x74, 0x8a, 0xa9,
|
0x7e, 0x61, 0xae, 0x78, 0xff, 0xf4, 0xac, 0xb4, 0x32, 0xbe, 0x1b, 0x62, 0x78, 0x9d, 0x1e, 0x91,
|
||||||
0xab, 0x58, 0x6d, 0xce, 0x1c, 0x2a, 0x04, 0xda, 0x84, 0xe2, 0x84, 0xb5, 0xf3, 0xaa, 0xdd, 0xc4,
|
0x81, 0xaf, 0xa6, 0x59, 0x2d, 0xbc, 0xb7, 0xd5, 0x68, 0xb7, 0x0b, 0x89, 0xab, 0x58, 0x2d, 0xc1,
|
||||||
0x07, 0xc5, 0xf9, 0xd2, 0xbd, 0xd3, 0xb3, 0xb2, 0xfd, 0x36, 0x69, 0x67, 0x14, 0x52, 0x7e, 0x60,
|
0x5d, 0x2a, 0x25, 0xda, 0x84, 0xc2, 0x98, 0xb5, 0xf3, 0xaa, 0xd5, 0xc0, 0x07, 0x85, 0xf9, 0xe2,
|
||||||
0x1e, 0x2d, 0xff, 0x48, 0x41, 0x61, 0xba, 0xe6, 0x45, 0x5b, 0x51, 0xad, 0xaa, 0x57, 0x7c, 0x63,
|
0xbd, 0xd3, 0xb3, 0x92, 0xf3, 0x36, 0x69, 0x67, 0x18, 0x52, 0x71, 0x60, 0x1f, 0x36, 0xff, 0x4c,
|
||||||
0x73, 0xe3, 0xba, 0x1a, 0x59, 0xdf, 0xb5, 0xfe, 0x50, 0xf9, 0x7d, 0xa1, 0x9e, 0xa7, 0x9a, 0x8c,
|
0x40, 0x7e, 0xb2, 0x2e, 0x46, 0x5b, 0x51, 0x3d, 0x6b, 0x56, 0x7c, 0x63, 0x73, 0xe3, 0xba, 0x3a,
|
||||||
0xbe, 0x84, 0xc5, 0x90, 0x71, 0x19, 0xdf, 0x4a, 0xc9, 0x31, 0xc3, 0x78, 0x5c, 0x49, 0x45, 0xe0,
|
0xda, 0xdc, 0xc7, 0xfe, 0x40, 0xfb, 0x7d, 0xa1, 0x9f, 0xb0, 0x86, 0x8c, 0xbe, 0x84, 0xc5, 0x90,
|
||||||
0x4a, 0x1f, 0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x61, 0xe1, 0xa0, 0xd5, 0x2e, 0xce, 0x95, 0xee, 0x9e,
|
0x0b, 0x15, 0xdf, 0x5c, 0xb3, 0xe3, 0x8a, 0x8b, 0xb8, 0xda, 0x8a, 0xc0, 0xe5, 0x1e, 0xdc, 0x98,
|
||||||
0x9e, 0x95, 0x3f, 0x9e, 0xfd, 0x78, 0xe0, 0x71, 0x39, 0x24, 0x7e, 0xab, 0x8d, 0x3e, 0x87, 0xc5,
|
0xf6, 0x86, 0x1e, 0xc2, 0xc2, 0x41, 0xb3, 0x55, 0x98, 0x2b, 0xde, 0x3d, 0x3d, 0x2b, 0x7d, 0x3c,
|
||||||
0xc6, 0x6e, 0x07, 0xe3, 0x62, 0xaa, 0xb4, 0x76, 0x7a, 0x56, 0xbe, 0x3b, 0x8b, 0x53, 0x9f, 0xd8,
|
0xfd, 0xf1, 0x80, 0x09, 0x35, 0x20, 0x7e, 0xb3, 0x85, 0x3e, 0x87, 0xc5, 0xfa, 0x6e, 0x1b, 0xe3,
|
||||||
0x30, 0x70, 0x31, 0x3b, 0x1c, 0x3f, 0xd5, 0xfe, 0x39, 0x0f, 0x96, 0xb9, 0xac, 0x3f, 0xf4, 0x6b,
|
0x42, 0xa2, 0xb8, 0x76, 0x7a, 0x56, 0xba, 0x3b, 0x8d, 0xd3, 0x9f, 0xf8, 0x20, 0xf0, 0x30, 0x3f,
|
||||||
0x7e, 0x29, 0xaa, 0x44, 0xe3, 0x2c, 0x3c, 0x7f, 0x6d, 0x41, 0x5a, 0x88, 0x08, 0x46, 0xd3, 0x0f,
|
0x1c, 0x3d, 0xe7, 0xfe, 0x35, 0x0f, 0x39, 0x7b, 0xa1, 0x7f, 0xe8, 0x17, 0xff, 0x52, 0x54, 0xad,
|
||||||
0xa0, 0xe0, 0x85, 0x27, 0x5f, 0x75, 0x69, 0x40, 0x0e, 0x7d, 0xf3, 0x6a, 0xcb, 0x61, 0x4b, 0xd9,
|
0xc6, 0x99, 0x7a, 0xfe, 0xda, 0xa2, 0x35, 0x1f, 0x11, 0xac, 0xa6, 0x1f, 0x40, 0x9e, 0x85, 0x27,
|
||||||
0x9a, 0x91, 0x49, 0x5d, 0x01, 0x5e, 0x20, 0x29, 0x0f, 0xcc, 0x7b, 0x2c, 0x87, 0xc7, 0x7d, 0xf4,
|
0x5f, 0x75, 0x68, 0x40, 0x0e, 0x7d, 0xfb, 0xb2, 0xcb, 0xe0, 0x9c, 0xb6, 0x35, 0x22, 0x93, 0xbe,
|
||||||
0x0d, 0xa4, 0xbd, 0x90, 0x0c, 0x4c, 0x15, 0x9d, 0xb8, 0x82, 0x56, 0xbb, 0xf6, 0xc2, 0xc4, 0x5c,
|
0x26, 0x58, 0xa0, 0xa8, 0x08, 0xec, 0x9b, 0x2d, 0x83, 0x47, 0x7d, 0xf4, 0x0d, 0x24, 0x59, 0x48,
|
||||||
0x3d, 0x77, 0x71, 0xbe, 0x96, 0x56, 0x06, 0xac, 0x69, 0x68, 0x35, 0x2e, 0x64, 0xd5, 0x48, 0xfa,
|
0xfa, 0xb6, 0xd2, 0x9e, 0xb9, 0x82, 0x66, 0xab, 0xfa, 0xc2, 0xc6, 0x5c, 0x2d, 0x73, 0x71, 0xbe,
|
||||||
0x3a, 0xcf, 0xe1, 0x29, 0x8b, 0x8a, 0x1b, 0x2f, 0xe8, 0x71, 0x2a, 0x84, 0xbe, 0xd8, 0x73, 0x38,
|
0x96, 0xd4, 0x06, 0x6c, 0x68, 0x68, 0x35, 0x2e, 0x76, 0xf5, 0x48, 0xe6, 0xca, 0xcf, 0xe0, 0x09,
|
||||||
0xee, 0xa2, 0x12, 0x64, 0x4d, 0x39, 0xac, 0xeb, 0xdf, 0xbc, 0x2a, 0x35, 0x8d, 0xa1, 0xbe, 0x04,
|
0x8b, 0x8e, 0x1b, 0x16, 0x74, 0x05, 0x95, 0xd2, 0x5c, 0xfe, 0x19, 0x1c, 0x77, 0x51, 0x11, 0xd2,
|
||||||
0x56, 0xb4, 0x1b, 0xdd, 0x23, 0xce, 0x06, 0x95, 0x7f, 0xa5, 0xc1, 0xda, 0xf2, 0x87, 0x42, 0x9a,
|
0xb6, 0x64, 0x36, 0x35, 0x72, 0x56, 0x97, 0xa3, 0xd6, 0x50, 0x5b, 0x82, 0x5c, 0xb4, 0x1b, 0x9d,
|
||||||
0xca, 0xe6, 0x83, 0x6d, 0xfe, 0x2b, 0x58, 0x26, 0xfa, 0xef, 0x00, 0x09, 0x54, 0x99, 0xa0, 0x5f,
|
0x23, 0xc1, 0xfb, 0xe5, 0x7f, 0x27, 0x21, 0xb7, 0xe5, 0x0f, 0xa4, 0xb2, 0xd5, 0xcf, 0x07, 0xdb,
|
||||||
0x19, 0xe6, 0x00, 0x1e, 0x26, 0xba, 0x1b, 0x83, 0xa3, 0x17, 0x49, 0x3d, 0xa3, 0x7c, 0xda, 0x29,
|
0xfc, 0x57, 0xb0, 0x4c, 0xcc, 0x1f, 0x04, 0x12, 0xe8, 0x52, 0xc2, 0xbc, 0x44, 0xec, 0x01, 0x3c,
|
||||||
0x5c, 0x24, 0x97, 0xbe, 0xa0, 0x0e, 0x2c, 0x31, 0xee, 0xf4, 0xa9, 0x90, 0x51, 0x71, 0x61, 0x5e,
|
0x9c, 0xe9, 0x6e, 0x04, 0x8e, 0x5e, 0x2d, 0xb5, 0x94, 0xf6, 0xe9, 0x24, 0x70, 0x81, 0x5c, 0xfa,
|
||||||
0xd3, 0x89, 0xff, 0x59, 0xf6, 0xa6, 0x81, 0xe6, 0x66, 0x8d, 0x66, 0x3b, 0xeb, 0x03, 0x3d, 0x86,
|
0x82, 0xda, 0xb0, 0xc4, 0x85, 0xdb, 0xa3, 0x52, 0x45, 0x05, 0x88, 0x7d, 0x71, 0xcf, 0xfc, 0x17,
|
||||||
0x34, 0x27, 0x47, 0xf1, 0x8b, 0x29, 0x31, 0x48, 0x30, 0x39, 0x92, 0x33, 0x2e, 0x34, 0x03, 0xfd,
|
0xb3, 0x37, 0x09, 0xb4, 0xb7, 0x6f, 0x34, 0xdb, 0x69, 0x1f, 0xe8, 0x31, 0x24, 0x05, 0x39, 0x8a,
|
||||||
0x1c, 0xc0, 0xf5, 0x44, 0x48, 0xa4, 0xd3, 0xa7, 0xdc, 0x1c, 0x76, 0xe2, 0x12, 0x1b, 0x63, 0xd4,
|
0x5f, 0x55, 0x33, 0x83, 0x04, 0x93, 0x23, 0x35, 0xe5, 0xc2, 0x30, 0xd0, 0x2f, 0x01, 0x3c, 0x26,
|
||||||
0x8c, 0x97, 0x29, 0x36, 0x7a, 0x06, 0x79, 0x87, 0xc4, 0x72, 0xcd, 0x5c, 0xfd, 0x8b, 0x61, 0xab,
|
0x43, 0xa2, 0xdc, 0x1e, 0x15, 0xf6, 0xb0, 0x67, 0x2e, 0xb1, 0x3e, 0x42, 0x4d, 0x79, 0x99, 0x60,
|
||||||
0x66, 0x5c, 0x14, 0x95, 0x8b, 0x8b, 0xf3, 0xb5, 0x5c, 0x6c, 0xc1, 0x39, 0x87, 0x18, 0xf9, 0x3e,
|
0xa3, 0x67, 0x90, 0x75, 0x49, 0x2c, 0xd7, 0xd4, 0xd5, 0xbf, 0x21, 0xb6, 0xaa, 0xd6, 0x45, 0x41,
|
||||||
0x83, 0x25, 0x49, 0xc4, 0x71, 0xd7, 0x8d, 0xd2, 0x59, 0x24, 0x93, 0x2b, 0x2a, 0x05, 0xf5, 0x8e,
|
0xbb, 0xb8, 0x38, 0x5f, 0xcb, 0xc4, 0x16, 0x9c, 0x71, 0x89, 0x95, 0xef, 0x33, 0x58, 0x52, 0x44,
|
||||||
0x35, 0x69, 0x2f, 0x3e, 0xce, 0x82, 0x9c, 0xb2, 0xa1, 0x5f, 0xc0, 0x32, 0x0d, 0x1c, 0x3e, 0xd2,
|
0x1e, 0x77, 0xbc, 0x28, 0x9d, 0x45, 0x32, 0xb9, 0xa2, 0x9a, 0xd0, 0x6f, 0x5d, 0x9b, 0xf6, 0xe2,
|
||||||
0x62, 0x8d, 0x67, 0x98, 0xbb, 0x7a, 0xb1, 0xcd, 0x31, 0x78, 0x66, 0xb1, 0x45, 0x7a, 0xc9, 0x5e,
|
0xe3, 0xcc, 0xab, 0x09, 0x1b, 0xfa, 0x15, 0x2c, 0xd3, 0xc0, 0x15, 0x43, 0x23, 0xd6, 0x78, 0x86,
|
||||||
0xf9, 0x6b, 0x0a, 0x20, 0x2a, 0xbe, 0x3e, 0xac, 0x00, 0x11, 0xa4, 0x5d, 0x22, 0x89, 0xd6, 0x5c,
|
0x99, 0xab, 0x17, 0xdb, 0x18, 0x81, 0xa7, 0x16, 0x5b, 0xa0, 0x97, 0xec, 0xe5, 0xbf, 0x27, 0x00,
|
||||||
0x01, 0xeb, 0x36, 0x7a, 0x02, 0x20, 0xe9, 0x20, 0x54, 0xa9, 0x37, 0xe8, 0x19, 0xd9, 0xbc, 0x2b,
|
0xa2, 0x02, 0xed, 0xc3, 0x0a, 0x10, 0x41, 0xd2, 0x23, 0x8a, 0x18, 0xcd, 0xe5, 0xb1, 0x69, 0xa3,
|
||||||
0x1d, 0x4c, 0xa1, 0xd1, 0x26, 0x64, 0xcc, 0xbb, 0x36, 0x7d, 0x2d, 0xcf, 0x20, 0x2b, 0x7f, 0x48,
|
0x27, 0x00, 0x8a, 0xf6, 0x43, 0x9d, 0x7a, 0x83, 0xae, 0x95, 0xcd, 0xbb, 0xd2, 0xc1, 0x04, 0x1a,
|
||||||
0x01, 0x44, 0xcb, 0xfc, 0x9f, 0x5e, 0x5b, 0xdd, 0x7e, 0xf3, 0xfd, 0xea, 0xdc, 0x5f, 0xbe, 0x5f,
|
0x6d, 0x42, 0xca, 0xbe, 0x7d, 0x93, 0xd7, 0xf2, 0x2c, 0xb2, 0xfc, 0xa7, 0x04, 0x40, 0xb4, 0xcc,
|
||||||
0x9d, 0xfb, 0xcd, 0xc5, 0x6a, 0xea, 0xcd, 0xc5, 0x6a, 0xea, 0xcf, 0x17, 0xab, 0xa9, 0xbf, 0x5d,
|
0xff, 0xeb, 0xb5, 0xd5, 0x9c, 0x37, 0xdf, 0xaf, 0xce, 0xfd, 0xed, 0xfb, 0xd5, 0xb9, 0xdf, 0x5d,
|
||||||
0xac, 0xa6, 0x0e, 0x33, 0xba, 0x3e, 0xfa, 0xe1, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x32, 0x89,
|
0xac, 0x26, 0xde, 0x5c, 0xac, 0x26, 0xfe, 0x7a, 0xb1, 0x9a, 0xf8, 0xc7, 0xc5, 0x6a, 0xe2, 0x30,
|
||||||
0x54, 0x8a, 0x4d, 0x16, 0x00, 0x00,
|
0x65, 0x6a, 0xa8, 0x1f, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x13, 0x42, 0x73, 0x71, 0x16,
|
||||||
|
0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,6 +333,9 @@ message ContainerSpec {
|
||||||
//
|
//
|
||||||
// https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime
|
// https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime
|
||||||
map<string, string> sysctls = 26;
|
map<string, string> sysctls = 26;
|
||||||
|
|
||||||
|
// Capabilities is the list of Linux capabilities to be available for container (this overrides the default set of capabilities)
|
||||||
|
repeated string capabilities = 27;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointSpec defines the properties that can be configured to
|
// EndpointSpec defines the properties that can be configured to
|
||||||
|
|
|
@ -19,7 +19,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
|
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
|
||||||
|
|
||||||
# etcd/raft
|
# etcd/raft
|
||||||
github.com/coreos/etcd v3.3.9
|
github.com/coreos/etcd d57e8b8d97adfc4a6c224fe116714bf1a1f3beb9 # v3.3.12
|
||||||
github.com/coreos/go-systemd v17
|
github.com/coreos/go-systemd v17
|
||||||
github.com/coreos/pkg v3
|
github.com/coreos/pkg v3
|
||||||
github.com/prometheus/client_golang v0.8.0
|
github.com/prometheus/client_golang v0.8.0
|
||||||
|
@ -27,8 +27,8 @@ github.com/prometheus/client_model 6f3806018612930941127f2a7c6c453ba2c527d2
|
||||||
github.com/prometheus/common 7600349dcfe1abd18d72d3a1770870d9800a7801
|
github.com/prometheus/common 7600349dcfe1abd18d72d3a1770870d9800a7801
|
||||||
github.com/prometheus/procfs 7d6f385de8bea29190f15ba9931442a0eaef9af7
|
github.com/prometheus/procfs 7d6f385de8bea29190f15ba9931442a0eaef9af7
|
||||||
|
|
||||||
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
|
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||||
github.com/docker/docker 5a718ef0f94f605fe4e4885937133c2f76ad2a41
|
github.com/docker/docker 827cb09f87964ed38b46502f22a585f2ed4a78e1
|
||||||
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||||
|
@ -45,7 +45,7 @@ github.com/sirupsen/logrus v1.0.6
|
||||||
github.com/beorn7/perks 3a771d992973f24aa725d07868b467d1ddfceaf
|
github.com/beorn7/perks 3a771d992973f24aa725d07868b467d1ddfceaf
|
||||||
github.com/cloudflare/cfssl 1.3.2
|
github.com/cloudflare/cfssl 1.3.2
|
||||||
github.com/dustin/go-humanize 8929fe90cee4b2cb9deb468b51fb34eba64d1bf0
|
github.com/dustin/go-humanize 8929fe90cee4b2cb9deb468b51fb34eba64d1bf0
|
||||||
github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
|
github.com/fernet/fernet-go 9eac43b88a5efb8651d24de9b68e87567e029736
|
||||||
github.com/google/certificate-transparency-go v1.0.20
|
github.com/google/certificate-transparency-go v1.0.20
|
||||||
github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git
|
github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git
|
||||||
github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
|
github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
|
||||||
|
|
|
@ -1,42 +1,96 @@
|
||||||
# gRPC-Go
|
# gRPC-Go
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) [![GoReportCard](https://goreportcard.com/badge/grpc/grpc-go)](https://goreportcard.com/report/github.com/grpc/grpc-go)
|
[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go)
|
||||||
|
[![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc)
|
||||||
|
[![GoReportCard](https://goreportcard.com/badge/grpc/grpc-go)](https://goreportcard.com/report/github.com/grpc/grpc-go)
|
||||||
|
|
||||||
The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: Go](https://grpc.io/docs/quickstart/go.html) guide.
|
The Go implementation of [gRPC](https://grpc.io/): A high performance, open
|
||||||
|
source, general RPC framework that puts mobile and HTTP/2 first. For more
|
||||||
|
information see the [gRPC Quick Start:
|
||||||
|
Go](https://grpc.io/docs/quickstart/go.html) guide.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run:
|
To install this package, you need to install Go and setup your Go workspace on
|
||||||
|
your computer. The simplest way to install the library is to run:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ go get -u google.golang.org/grpc
|
$ go get -u google.golang.org/grpc
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With Go module support (Go 1.11+), simply `import "google.golang.org/grpc"` in
|
||||||
|
your source code and `go [build|run|test]` will automatically download the
|
||||||
|
necessary dependencies ([Go modules
|
||||||
|
ref](https://github.com/golang/go/wiki/Modules)).
|
||||||
|
|
||||||
|
If you are trying to access grpc-go from within China, please see the
|
||||||
|
[FAQ](#FAQ) below.
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
gRPC-Go requires Go 1.9 or later.
|
gRPC-Go requires Go 1.9 or later.
|
||||||
|
|
||||||
Constraints
|
|
||||||
-----------
|
|
||||||
The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants.
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
See [API documentation](https://godoc.org/google.golang.org/grpc) for package and API descriptions and find examples in the [examples directory](examples/).
|
- See [godoc](https://godoc.org/google.golang.org/grpc) for package and API
|
||||||
|
descriptions.
|
||||||
|
- Documentation on specific topics can be found in the [Documentation
|
||||||
|
directory](Documentation/).
|
||||||
|
- Examples can be found in the [examples directory](examples/).
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
-----------
|
-----------
|
||||||
See the current benchmarks for some of the languages supported in [this dashboard](https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5652536396611584&widget=490377658&container=1286539696).
|
Performance benchmark data for grpc-go and other languages is maintained in
|
||||||
|
[this
|
||||||
|
dashboard](https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5652536396611584&widget=490377658&container=1286539696).
|
||||||
|
|
||||||
Status
|
Status
|
||||||
------
|
------
|
||||||
General Availability [Google Cloud Platform Launch Stages](https://cloud.google.com/terms/launch-stages).
|
General Availability [Google Cloud Platform Launch
|
||||||
|
Stages](https://cloud.google.com/terms/launch-stages).
|
||||||
|
|
||||||
FAQ
|
FAQ
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### I/O Timeout Errors
|
||||||
|
|
||||||
|
The `golang.org` domain may be blocked from some countries. `go get` usually
|
||||||
|
produces an error like the following when this happens:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ go get -u google.golang.org/grpc
|
||||||
|
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
|
||||||
|
```
|
||||||
|
|
||||||
|
To build Go code, there are several options:
|
||||||
|
|
||||||
|
- Set up a VPN and access google.golang.org through that.
|
||||||
|
|
||||||
|
- Without Go module support: `git clone` the repo manually:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
|
||||||
|
```
|
||||||
|
|
||||||
|
You will need to do the same for all of grpc's dependencies in `golang.org`,
|
||||||
|
e.g. `golang.org/x/net`.
|
||||||
|
|
||||||
|
- With Go module support: it is possible to use the `replace` feature of `go
|
||||||
|
mod` to create aliases for golang.org packages. In your project's directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
go mod edit -replace=google.golang.org/grpc=github.com/grpc/grpc-go@latest
|
||||||
|
go mod tidy
|
||||||
|
go mod vendor
|
||||||
|
go build -mod=vendor
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, this will need to be done for all transitive dependencies hosted on
|
||||||
|
golang.org as well. Please refer to [this
|
||||||
|
issue](https://github.com/golang/go/issues/28652) in the golang repo regarding
|
||||||
|
this concern.
|
||||||
|
|
||||||
#### Compiling error, undefined: grpc.SupportPackageIsVersion
|
#### Compiling error, undefined: grpc.SupportPackageIsVersion
|
||||||
|
|
||||||
Please update proto package, gRPC package and rebuild the proto files:
|
Please update proto package, gRPC package and rebuild the proto files:
|
||||||
|
|
|
@ -43,7 +43,7 @@ type Address struct {
|
||||||
|
|
||||||
// BalancerConfig specifies the configurations for Balancer.
|
// BalancerConfig specifies the configurations for Balancer.
|
||||||
//
|
//
|
||||||
// Deprecated: please use package balancer.
|
// Deprecated: please use package balancer. May be removed in a future 1.x release.
|
||||||
type BalancerConfig struct {
|
type BalancerConfig struct {
|
||||||
// DialCreds is the transport credential the Balancer implementation can
|
// DialCreds is the transport credential the Balancer implementation can
|
||||||
// use to dial to a remote load balancer server. The Balancer implementations
|
// use to dial to a remote load balancer server. The Balancer implementations
|
||||||
|
@ -57,7 +57,7 @@ type BalancerConfig struct {
|
||||||
|
|
||||||
// BalancerGetOptions configures a Get call.
|
// BalancerGetOptions configures a Get call.
|
||||||
//
|
//
|
||||||
// Deprecated: please use package balancer.
|
// Deprecated: please use package balancer. May be removed in a future 1.x release.
|
||||||
type BalancerGetOptions struct {
|
type BalancerGetOptions struct {
|
||||||
// BlockingWait specifies whether Get should block when there is no
|
// BlockingWait specifies whether Get should block when there is no
|
||||||
// connected address.
|
// connected address.
|
||||||
|
@ -66,7 +66,7 @@ type BalancerGetOptions struct {
|
||||||
|
|
||||||
// Balancer chooses network addresses for RPCs.
|
// Balancer chooses network addresses for RPCs.
|
||||||
//
|
//
|
||||||
// Deprecated: please use package balancer.
|
// Deprecated: please use package balancer. May be removed in a future 1.x release.
|
||||||
type Balancer interface {
|
type Balancer interface {
|
||||||
// Start does the initialization work to bootstrap a Balancer. For example,
|
// Start does the initialization work to bootstrap a Balancer. For example,
|
||||||
// this function may start the name resolution and watch the updates. It will
|
// this function may start the name resolution and watch the updates. It will
|
||||||
|
@ -120,7 +120,7 @@ type Balancer interface {
|
||||||
// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch
|
// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch
|
||||||
// the name resolution updates and updates the addresses available correspondingly.
|
// the name resolution updates and updates the addresses available correspondingly.
|
||||||
//
|
//
|
||||||
// Deprecated: please use package balancer/roundrobin.
|
// Deprecated: please use package balancer/roundrobin. May be removed in a future 1.x release.
|
||||||
func RoundRobin(r naming.Resolver) Balancer {
|
func RoundRobin(r naming.Resolver) Balancer {
|
||||||
return &roundRobin{r: r}
|
return &roundRobin{r: r}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package balancer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -31,6 +32,7 @@ import (
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
|
"google.golang.org/grpc/serviceconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -39,7 +41,10 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Register registers the balancer builder to the balancer map. b.Name
|
// Register registers the balancer builder to the balancer map. b.Name
|
||||||
// (lowercased) will be used as the name registered with this builder.
|
// (lowercased) will be used as the name registered with this builder. If the
|
||||||
|
// Builder implements ConfigParser, ParseConfig will be called when new service
|
||||||
|
// configs are received by the resolver, and the result will be provided to the
|
||||||
|
// Balancer in UpdateClientConnState.
|
||||||
//
|
//
|
||||||
// NOTE: this function must only be called during initialization time (i.e. in
|
// NOTE: this function must only be called during initialization time (i.e. in
|
||||||
// an init() function), and is not thread-safe. If multiple Balancers are
|
// an init() function), and is not thread-safe. If multiple Balancers are
|
||||||
|
@ -138,6 +143,8 @@ type ClientConn interface {
|
||||||
ResolveNow(resolver.ResolveNowOption)
|
ResolveNow(resolver.ResolveNowOption)
|
||||||
|
|
||||||
// Target returns the dial target for this ClientConn.
|
// Target returns the dial target for this ClientConn.
|
||||||
|
//
|
||||||
|
// Deprecated: Use the Target field in the BuildOptions instead.
|
||||||
Target() string
|
Target() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +162,10 @@ type BuildOptions struct {
|
||||||
Dialer func(context.Context, string) (net.Conn, error)
|
Dialer func(context.Context, string) (net.Conn, error)
|
||||||
// ChannelzParentID is the entity parent's channelz unique identification number.
|
// ChannelzParentID is the entity parent's channelz unique identification number.
|
||||||
ChannelzParentID int64
|
ChannelzParentID int64
|
||||||
|
// Target contains the parsed address info of the dial target. It is the same resolver.Target as
|
||||||
|
// passed to the resolver.
|
||||||
|
// See the documentation for the resolver.Target type for details about what it contains.
|
||||||
|
Target resolver.Target
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builder creates a balancer.
|
// Builder creates a balancer.
|
||||||
|
@ -166,6 +177,14 @@ type Builder interface {
|
||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigParser parses load balancer configs.
|
||||||
|
type ConfigParser interface {
|
||||||
|
// ParseConfig parses the JSON load balancer config provided into an
|
||||||
|
// internal form or returns an error if the config is invalid. For future
|
||||||
|
// compatibility reasons, unknown fields in the config should be ignored.
|
||||||
|
ParseConfig(LoadBalancingConfigJSON json.RawMessage) (serviceconfig.LoadBalancingConfig, error)
|
||||||
|
}
|
||||||
|
|
||||||
// PickOptions contains addition information for the Pick operation.
|
// PickOptions contains addition information for the Pick operation.
|
||||||
type PickOptions struct {
|
type PickOptions struct {
|
||||||
// FullMethodName is the method name that NewClientStream() is called
|
// FullMethodName is the method name that NewClientStream() is called
|
||||||
|
@ -264,7 +283,7 @@ type Balancer interface {
|
||||||
// non-nil error to gRPC.
|
// non-nil error to gRPC.
|
||||||
//
|
//
|
||||||
// Deprecated: if V2Balancer is implemented by the Balancer,
|
// Deprecated: if V2Balancer is implemented by the Balancer,
|
||||||
// UpdateResolverState will be called instead.
|
// UpdateClientConnState will be called instead.
|
||||||
HandleResolvedAddrs([]resolver.Address, error)
|
HandleResolvedAddrs([]resolver.Address, error)
|
||||||
// Close closes the balancer. The balancer is not required to call
|
// Close closes the balancer. The balancer is not required to call
|
||||||
// ClientConn.RemoveSubConn for its existing SubConns.
|
// ClientConn.RemoveSubConn for its existing SubConns.
|
||||||
|
@ -277,14 +296,23 @@ type SubConnState struct {
|
||||||
// TODO: add last connection error
|
// TODO: add last connection error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientConnState describes the state of a ClientConn relevant to the
|
||||||
|
// balancer.
|
||||||
|
type ClientConnState struct {
|
||||||
|
ResolverState resolver.State
|
||||||
|
// The parsed load balancing configuration returned by the builder's
|
||||||
|
// ParseConfig method, if implemented.
|
||||||
|
BalancerConfig serviceconfig.LoadBalancingConfig
|
||||||
|
}
|
||||||
|
|
||||||
// V2Balancer is defined for documentation purposes. If a Balancer also
|
// V2Balancer is defined for documentation purposes. If a Balancer also
|
||||||
// implements V2Balancer, its UpdateResolverState method will be called instead
|
// implements V2Balancer, its UpdateClientConnState method will be called
|
||||||
// of HandleResolvedAddrs and its UpdateSubConnState will be called instead of
|
// instead of HandleResolvedAddrs and its UpdateSubConnState will be called
|
||||||
// HandleSubConnStateChange.
|
// instead of HandleSubConnStateChange.
|
||||||
type V2Balancer interface {
|
type V2Balancer interface {
|
||||||
// UpdateResolverState is called by gRPC when the state of the resolver
|
// UpdateClientConnState is called by gRPC when the state of the ClientConn
|
||||||
// changes.
|
// changes.
|
||||||
UpdateResolverState(resolver.State)
|
UpdateClientConnState(ClientConnState)
|
||||||
// UpdateSubConnState is called by gRPC when the state of a SubConn
|
// UpdateSubConnState is called by gRPC when the state of a SubConn
|
||||||
// changes.
|
// changes.
|
||||||
UpdateSubConnState(SubConn, SubConnState)
|
UpdateSubConnState(SubConn, SubConnState)
|
||||||
|
|
|
@ -70,13 +70,15 @@ func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error)
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *baseBalancer) UpdateResolverState(s resolver.State) {
|
func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) {
|
||||||
// TODO: handle s.Err (log if not nil) once implemented.
|
// TODO: handle s.ResolverState.Err (log if not nil) once implemented.
|
||||||
// TODO: handle s.ServiceConfig?
|
// TODO: handle s.ResolverState.ServiceConfig?
|
||||||
grpclog.Infoln("base.baseBalancer: got new resolver state: ", s)
|
if grpclog.V(2) {
|
||||||
|
grpclog.Infoln("base.baseBalancer: got new ClientConn state: ", s)
|
||||||
|
}
|
||||||
// addrsSet is the set converted from addrs, it's used for quick lookup of an address.
|
// addrsSet is the set converted from addrs, it's used for quick lookup of an address.
|
||||||
addrsSet := make(map[resolver.Address]struct{})
|
addrsSet := make(map[resolver.Address]struct{})
|
||||||
for _, a := range s.Addresses {
|
for _, a := range s.ResolverState.Addresses {
|
||||||
addrsSet[a] = struct{}{}
|
addrsSet[a] = struct{}{}
|
||||||
if _, ok := b.subConns[a]; !ok {
|
if _, ok := b.subConns[a]; !ok {
|
||||||
// a is a new address (not existing in b.subConns).
|
// a is a new address (not existing in b.subConns).
|
||||||
|
@ -127,10 +129,14 @@ func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectiv
|
||||||
|
|
||||||
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
s := state.ConnectivityState
|
s := state.ConnectivityState
|
||||||
|
if grpclog.V(2) {
|
||||||
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
|
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
|
||||||
|
}
|
||||||
oldS, ok := b.scStates[sc]
|
oldS, ok := b.scStates[sc]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
if grpclog.V(2) {
|
||||||
grpclog.Infof("base.baseBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
|
grpclog.Infof("base.baseBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.scStates[sc] = s
|
b.scStates[sc] = s
|
||||||
|
|
|
@ -88,7 +88,7 @@ type ccBalancerWrapper struct {
|
||||||
cc *ClientConn
|
cc *ClientConn
|
||||||
balancer balancer.Balancer
|
balancer balancer.Balancer
|
||||||
stateChangeQueue *scStateUpdateBuffer
|
stateChangeQueue *scStateUpdateBuffer
|
||||||
resolverUpdateCh chan *resolver.State
|
ccUpdateCh chan *balancer.ClientConnState
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
@ -99,7 +99,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui
|
||||||
ccb := &ccBalancerWrapper{
|
ccb := &ccBalancerWrapper{
|
||||||
cc: cc,
|
cc: cc,
|
||||||
stateChangeQueue: newSCStateUpdateBuffer(),
|
stateChangeQueue: newSCStateUpdateBuffer(),
|
||||||
resolverUpdateCh: make(chan *resolver.State, 1),
|
ccUpdateCh: make(chan *balancer.ClientConnState, 1),
|
||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
subConns: make(map[*acBalancerWrapper]struct{}),
|
subConns: make(map[*acBalancerWrapper]struct{}),
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ func (ccb *ccBalancerWrapper) watcher() {
|
||||||
} else {
|
} else {
|
||||||
ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
|
ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
|
||||||
}
|
}
|
||||||
case s := <-ccb.resolverUpdateCh:
|
case s := <-ccb.ccUpdateCh:
|
||||||
select {
|
select {
|
||||||
case <-ccb.done:
|
case <-ccb.done:
|
||||||
ccb.balancer.Close()
|
ccb.balancer.Close()
|
||||||
|
@ -134,9 +134,9 @@ func (ccb *ccBalancerWrapper) watcher() {
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if ub, ok := ccb.balancer.(balancer.V2Balancer); ok {
|
if ub, ok := ccb.balancer.(balancer.V2Balancer); ok {
|
||||||
ub.UpdateResolverState(*s)
|
ub.UpdateClientConnState(*s)
|
||||||
} else {
|
} else {
|
||||||
ccb.balancer.HandleResolvedAddrs(s.Addresses, nil)
|
ccb.balancer.HandleResolvedAddrs(s.ResolverState.Addresses, nil)
|
||||||
}
|
}
|
||||||
case <-ccb.done:
|
case <-ccb.done:
|
||||||
}
|
}
|
||||||
|
@ -151,9 +151,11 @@ func (ccb *ccBalancerWrapper) watcher() {
|
||||||
for acbw := range scs {
|
for acbw := range scs {
|
||||||
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
|
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
|
||||||
}
|
}
|
||||||
|
ccb.UpdateBalancerState(connectivity.Connecting, nil)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
ccb.cc.firstResolveEvent.Fire()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,9 +180,10 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) updateResolverState(s resolver.State) {
|
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) {
|
||||||
if ccb.cc.curBalancerName != grpclbName {
|
if ccb.cc.curBalancerName != grpclbName {
|
||||||
// Filter any grpclb addresses since we don't have the grpclb balancer.
|
// Filter any grpclb addresses since we don't have the grpclb balancer.
|
||||||
|
s := &ccs.ResolverState
|
||||||
for i := 0; i < len(s.Addresses); {
|
for i := 0; i < len(s.Addresses); {
|
||||||
if s.Addresses[i].Type == resolver.GRPCLB {
|
if s.Addresses[i].Type == resolver.GRPCLB {
|
||||||
copy(s.Addresses[i:], s.Addresses[i+1:])
|
copy(s.Addresses[i:], s.Addresses[i+1:])
|
||||||
|
@ -191,10 +194,10 @@ func (ccb *ccBalancerWrapper) updateResolverState(s resolver.State) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case <-ccb.resolverUpdateCh:
|
case <-ccb.ccUpdateCh:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
ccb.resolverUpdateCh <- &s
|
ccb.ccUpdateCh <- ccs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package grpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
|
@ -34,13 +33,7 @@ type balancerWrapperBuilder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
|
func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
|
||||||
targetAddr := cc.Target()
|
bwb.b.Start(opts.Target.Endpoint, BalancerConfig{
|
||||||
targetSplitted := strings.Split(targetAddr, ":///")
|
|
||||||
if len(targetSplitted) >= 2 {
|
|
||||||
targetAddr = targetSplitted[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
bwb.b.Start(targetAddr, BalancerConfig{
|
|
||||||
DialCreds: opts.DialCreds,
|
DialCreds: opts.DialCreds,
|
||||||
Dialer: opts.Dialer,
|
Dialer: opts.Dialer,
|
||||||
})
|
})
|
||||||
|
@ -49,7 +42,7 @@ func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.B
|
||||||
balancer: bwb.b,
|
balancer: bwb.b,
|
||||||
pickfirst: pickfirst,
|
pickfirst: pickfirst,
|
||||||
cc: cc,
|
cc: cc,
|
||||||
targetAddr: targetAddr,
|
targetAddr: opts.Target.Endpoint,
|
||||||
startCh: make(chan struct{}),
|
startCh: make(chan struct{}),
|
||||||
conns: make(map[resolver.Address]balancer.SubConn),
|
conns: make(map[resolver.Address]balancer.SubConn),
|
||||||
connSt: make(map[balancer.SubConn]*scState),
|
connSt: make(map[balancer.SubConn]*scState),
|
||||||
|
@ -120,7 +113,7 @@ func (bw *balancerWrapper) lbWatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for addrs := range notifyCh {
|
for addrs := range notifyCh {
|
||||||
grpclog.Infof("balancerWrapper: got update addr from Notify: %v\n", addrs)
|
grpclog.Infof("balancerWrapper: got update addr from Notify: %v", addrs)
|
||||||
if bw.pickfirst {
|
if bw.pickfirst {
|
||||||
var (
|
var (
|
||||||
oldA resolver.Address
|
oldA resolver.Address
|
||||||
|
|
|
@ -38,13 +38,13 @@ import (
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/internal/backoff"
|
"google.golang.org/grpc/internal/backoff"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/internal/envconfig"
|
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
"google.golang.org/grpc/internal/transport"
|
"google.golang.org/grpc/internal/transport"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
_ "google.golang.org/grpc/resolver/dns" // To register dns resolver.
|
_ "google.golang.org/grpc/resolver/dns" // To register dns resolver.
|
||||||
_ "google.golang.org/grpc/resolver/passthrough" // To register passthrough resolver.
|
_ "google.golang.org/grpc/resolver/passthrough" // To register passthrough resolver.
|
||||||
|
"google.golang.org/grpc/serviceconfig"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -137,6 +137,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
||||||
opt.apply(&cc.dopts)
|
opt.apply(&cc.dopts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chainUnaryClientInterceptors(cc)
|
||||||
|
chainStreamClientInterceptors(cc)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cc.Close()
|
cc.Close()
|
||||||
|
@ -290,6 +293,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
||||||
CredsBundle: cc.dopts.copts.CredsBundle,
|
CredsBundle: cc.dopts.copts.CredsBundle,
|
||||||
Dialer: cc.dopts.copts.Dialer,
|
Dialer: cc.dopts.copts.Dialer,
|
||||||
ChannelzParentID: cc.channelzID,
|
ChannelzParentID: cc.channelzID,
|
||||||
|
Target: cc.parsedTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the resolver.
|
// Build the resolver.
|
||||||
|
@ -327,6 +331,68 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chainUnaryClientInterceptors chains all unary client interceptors into one.
|
||||||
|
func chainUnaryClientInterceptors(cc *ClientConn) {
|
||||||
|
interceptors := cc.dopts.chainUnaryInts
|
||||||
|
// Prepend dopts.unaryInt to the chaining interceptors if it exists, since unaryInt will
|
||||||
|
// be executed before any other chained interceptors.
|
||||||
|
if cc.dopts.unaryInt != nil {
|
||||||
|
interceptors = append([]UnaryClientInterceptor{cc.dopts.unaryInt}, interceptors...)
|
||||||
|
}
|
||||||
|
var chainedInt UnaryClientInterceptor
|
||||||
|
if len(interceptors) == 0 {
|
||||||
|
chainedInt = nil
|
||||||
|
} else if len(interceptors) == 1 {
|
||||||
|
chainedInt = interceptors[0]
|
||||||
|
} else {
|
||||||
|
chainedInt = func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error {
|
||||||
|
return interceptors[0](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, 0, invoker), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc.dopts.unaryInt = chainedInt
|
||||||
|
}
|
||||||
|
|
||||||
|
// getChainUnaryInvoker recursively generate the chained unary invoker.
|
||||||
|
func getChainUnaryInvoker(interceptors []UnaryClientInterceptor, curr int, finalInvoker UnaryInvoker) UnaryInvoker {
|
||||||
|
if curr == len(interceptors)-1 {
|
||||||
|
return finalInvoker
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error {
|
||||||
|
return interceptors[curr+1](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, curr+1, finalInvoker), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// chainStreamClientInterceptors chains all stream client interceptors into one.
|
||||||
|
func chainStreamClientInterceptors(cc *ClientConn) {
|
||||||
|
interceptors := cc.dopts.chainStreamInts
|
||||||
|
// Prepend dopts.streamInt to the chaining interceptors if it exists, since streamInt will
|
||||||
|
// be executed before any other chained interceptors.
|
||||||
|
if cc.dopts.streamInt != nil {
|
||||||
|
interceptors = append([]StreamClientInterceptor{cc.dopts.streamInt}, interceptors...)
|
||||||
|
}
|
||||||
|
var chainedInt StreamClientInterceptor
|
||||||
|
if len(interceptors) == 0 {
|
||||||
|
chainedInt = nil
|
||||||
|
} else if len(interceptors) == 1 {
|
||||||
|
chainedInt = interceptors[0]
|
||||||
|
} else {
|
||||||
|
chainedInt = func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error) {
|
||||||
|
return interceptors[0](ctx, desc, cc, method, getChainStreamer(interceptors, 0, streamer), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc.dopts.streamInt = chainedInt
|
||||||
|
}
|
||||||
|
|
||||||
|
// getChainStreamer recursively generate the chained client stream constructor.
|
||||||
|
func getChainStreamer(interceptors []StreamClientInterceptor, curr int, finalStreamer Streamer) Streamer {
|
||||||
|
if curr == len(interceptors)-1 {
|
||||||
|
return finalStreamer
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
|
return interceptors[curr+1](ctx, desc, cc, method, getChainStreamer(interceptors, curr+1, finalStreamer), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// connectivityStateManager keeps the connectivity.State of ClientConn.
|
// connectivityStateManager keeps the connectivity.State of ClientConn.
|
||||||
// This struct will eventually be exported so the balancers can access it.
|
// This struct will eventually be exported so the balancers can access it.
|
||||||
type connectivityStateManager struct {
|
type connectivityStateManager struct {
|
||||||
|
@ -466,24 +532,6 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// gRPC should resort to default service config when:
|
|
||||||
// * resolver service config is disabled
|
|
||||||
// * or, resolver does not return a service config or returns an invalid one.
|
|
||||||
func (cc *ClientConn) fallbackToDefaultServiceConfig(sc string) bool {
|
|
||||||
if cc.dopts.disableServiceConfig {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// The logic below is temporary, will be removed once we change the resolver.State ServiceConfig field type.
|
|
||||||
// Right now, we assume that empty service config string means resolver does not return a config.
|
|
||||||
if sc == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// TODO: the logic below is temporary. Once we finish the logic to validate service config
|
|
||||||
// in resolver, we will replace the logic below.
|
|
||||||
_, err := parseServiceConfig(sc)
|
|
||||||
return err != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
|
@ -494,29 +542,23 @@ func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if cc.fallbackToDefaultServiceConfig(s.ServiceConfig) {
|
if cc.dopts.disableServiceConfig || s.ServiceConfig == nil {
|
||||||
if cc.dopts.defaultServiceConfig != nil && cc.sc == nil {
|
if cc.dopts.defaultServiceConfig != nil && cc.sc == nil {
|
||||||
cc.applyServiceConfig(cc.dopts.defaultServiceConfig)
|
cc.applyServiceConfig(cc.dopts.defaultServiceConfig)
|
||||||
}
|
}
|
||||||
} else {
|
} else if sc, ok := s.ServiceConfig.(*ServiceConfig); ok {
|
||||||
// TODO: the parsing logic below will be moved inside resolver.
|
|
||||||
sc, err := parseServiceConfig(s.ServiceConfig)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if cc.sc == nil || cc.sc.rawJSONString != s.ServiceConfig {
|
|
||||||
cc.applyServiceConfig(sc)
|
cc.applyServiceConfig(sc)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// update the service config that will be sent to balancer.
|
|
||||||
if cc.sc != nil {
|
|
||||||
s.ServiceConfig = cc.sc.rawJSONString
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var balCfg serviceconfig.LoadBalancingConfig
|
||||||
if cc.dopts.balancerBuilder == nil {
|
if cc.dopts.balancerBuilder == nil {
|
||||||
// Only look at balancer types and switch balancer if balancer dial
|
// Only look at balancer types and switch balancer if balancer dial
|
||||||
// option is not set.
|
// option is not set.
|
||||||
|
var newBalancerName string
|
||||||
|
if cc.sc != nil && cc.sc.lbConfig != nil {
|
||||||
|
newBalancerName = cc.sc.lbConfig.name
|
||||||
|
balCfg = cc.sc.lbConfig.cfg
|
||||||
|
} else {
|
||||||
var isGRPCLB bool
|
var isGRPCLB bool
|
||||||
for _, a := range s.Addresses {
|
for _, a := range s.Addresses {
|
||||||
if a.Type == resolver.GRPCLB {
|
if a.Type == resolver.GRPCLB {
|
||||||
|
@ -524,8 +566,6 @@ func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var newBalancerName string
|
|
||||||
// TODO: use new loadBalancerConfig field with appropriate priority.
|
|
||||||
if isGRPCLB {
|
if isGRPCLB {
|
||||||
newBalancerName = grpclbName
|
newBalancerName = grpclbName
|
||||||
} else if cc.sc != nil && cc.sc.LB != nil {
|
} else if cc.sc != nil && cc.sc.LB != nil {
|
||||||
|
@ -533,15 +573,16 @@ func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||||
} else {
|
} else {
|
||||||
newBalancerName = PickFirstBalancerName
|
newBalancerName = PickFirstBalancerName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cc.switchBalancer(newBalancerName)
|
cc.switchBalancer(newBalancerName)
|
||||||
} else if cc.balancerWrapper == nil {
|
} else if cc.balancerWrapper == nil {
|
||||||
// Balancer dial option was set, and this is the first time handling
|
// Balancer dial option was set, and this is the first time handling
|
||||||
// resolved addresses. Build a balancer with dopts.balancerBuilder.
|
// resolved addresses. Build a balancer with dopts.balancerBuilder.
|
||||||
|
cc.curBalancerName = cc.dopts.balancerBuilder.Name()
|
||||||
cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts)
|
cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.balancerWrapper.updateResolverState(s)
|
cc.balancerWrapper.updateClientConnState(&balancer.ClientConnState{ResolverState: s, BalancerConfig: balCfg})
|
||||||
cc.firstResolveEvent.Fire()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +595,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||||
//
|
//
|
||||||
// Caller must hold cc.mu.
|
// Caller must hold cc.mu.
|
||||||
func (cc *ClientConn) switchBalancer(name string) {
|
func (cc *ClientConn) switchBalancer(name string) {
|
||||||
if strings.ToLower(cc.curBalancerName) == strings.ToLower(name) {
|
if strings.EqualFold(cc.curBalancerName, name) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +734,8 @@ func (ac *addrConn) connect() error {
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Update connectivity state within the lock to prevent subsequent or
|
||||||
|
// concurrent calls from resetting the transport more than once.
|
||||||
ac.updateConnectivityState(connectivity.Connecting)
|
ac.updateConnectivityState(connectivity.Connecting)
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
|
|
||||||
|
@ -703,7 +746,16 @@ func (ac *addrConn) connect() error {
|
||||||
|
|
||||||
// tryUpdateAddrs tries to update ac.addrs with the new addresses list.
|
// tryUpdateAddrs tries to update ac.addrs with the new addresses list.
|
||||||
//
|
//
|
||||||
// It checks whether current connected address of ac is in the new addrs list.
|
// If ac is Connecting, it returns false. The caller should tear down the ac and
|
||||||
|
// create a new one. Note that the backoff will be reset when this happens.
|
||||||
|
//
|
||||||
|
// If ac is TransientFailure, it updates ac.addrs and returns true. The updated
|
||||||
|
// addresses will be picked up by retry in the next iteration after backoff.
|
||||||
|
//
|
||||||
|
// If ac is Shutdown or Idle, it updates ac.addrs and returns true.
|
||||||
|
//
|
||||||
|
// If ac is Ready, it checks whether current connected address of ac is in the
|
||||||
|
// new addrs list.
|
||||||
// - If true, it updates ac.addrs and returns true. The ac will keep using
|
// - If true, it updates ac.addrs and returns true. The ac will keep using
|
||||||
// the existing connection.
|
// the existing connection.
|
||||||
// - If false, it does nothing and returns false.
|
// - If false, it does nothing and returns false.
|
||||||
|
@ -711,17 +763,18 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool {
|
||||||
ac.mu.Lock()
|
ac.mu.Lock()
|
||||||
defer ac.mu.Unlock()
|
defer ac.mu.Unlock()
|
||||||
grpclog.Infof("addrConn: tryUpdateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs)
|
grpclog.Infof("addrConn: tryUpdateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs)
|
||||||
if ac.state == connectivity.Shutdown {
|
if ac.state == connectivity.Shutdown ||
|
||||||
|
ac.state == connectivity.TransientFailure ||
|
||||||
|
ac.state == connectivity.Idle {
|
||||||
ac.addrs = addrs
|
ac.addrs = addrs
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unless we're busy reconnecting already, let's reconnect from the top of
|
if ac.state == connectivity.Connecting {
|
||||||
// the list.
|
|
||||||
if ac.state != connectivity.Ready {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ac.state is Ready, try to find the connected address.
|
||||||
var curAddrFound bool
|
var curAddrFound bool
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
if reflect.DeepEqual(ac.curAddr, a) {
|
if reflect.DeepEqual(ac.curAddr, a) {
|
||||||
|
@ -970,6 +1023,9 @@ func (ac *addrConn) resetTransport() {
|
||||||
// The spec doesn't mention what should be done for multiple addresses.
|
// The spec doesn't mention what should be done for multiple addresses.
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm
|
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm
|
||||||
connectDeadline := time.Now().Add(dialDuration)
|
connectDeadline := time.Now().Add(dialDuration)
|
||||||
|
|
||||||
|
ac.updateConnectivityState(connectivity.Connecting)
|
||||||
|
ac.transport = nil
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
|
|
||||||
newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline)
|
newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline)
|
||||||
|
@ -1004,55 +1060,32 @@ func (ac *addrConn) resetTransport() {
|
||||||
|
|
||||||
ac.mu.Lock()
|
ac.mu.Lock()
|
||||||
if ac.state == connectivity.Shutdown {
|
if ac.state == connectivity.Shutdown {
|
||||||
newTr.Close()
|
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
|
newTr.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.curAddr = addr
|
ac.curAddr = addr
|
||||||
ac.transport = newTr
|
ac.transport = newTr
|
||||||
ac.backoffIdx = 0
|
ac.backoffIdx = 0
|
||||||
|
|
||||||
healthCheckConfig := ac.cc.healthCheckConfig()
|
|
||||||
// LB channel health checking is only enabled when all the four requirements below are met:
|
|
||||||
// 1. it is not disabled by the user with the WithDisableHealthCheck DialOption,
|
|
||||||
// 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package,
|
|
||||||
// 3. a service config with non-empty healthCheckConfig field is provided,
|
|
||||||
// 4. the current load balancer allows it.
|
|
||||||
hctx, hcancel := context.WithCancel(ac.ctx)
|
hctx, hcancel := context.WithCancel(ac.ctx)
|
||||||
healthcheckManagingState := false
|
ac.startHealthCheck(hctx)
|
||||||
if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled {
|
|
||||||
if ac.cc.dopts.healthCheckFunc == nil {
|
|
||||||
// TODO: add a link to the health check doc in the error message.
|
|
||||||
grpclog.Error("the client side LB channel health check function has not been set.")
|
|
||||||
} else {
|
|
||||||
// TODO(deklerk) refactor to just return transport
|
|
||||||
go ac.startHealthCheck(hctx, newTr, addr, healthCheckConfig.ServiceName)
|
|
||||||
healthcheckManagingState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !healthcheckManagingState {
|
|
||||||
ac.updateConnectivityState(connectivity.Ready)
|
|
||||||
}
|
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
|
|
||||||
// Block until the created transport is down. And when this happens,
|
// Block until the created transport is down. And when this happens,
|
||||||
// we restart from the top of the addr list.
|
// we restart from the top of the addr list.
|
||||||
<-reconnect.Done()
|
<-reconnect.Done()
|
||||||
hcancel()
|
hcancel()
|
||||||
|
// restart connecting - the top of the loop will set state to
|
||||||
// Need to reconnect after a READY, the addrConn enters
|
// CONNECTING. This is against the current connectivity semantics doc,
|
||||||
// TRANSIENT_FAILURE.
|
// however it allows for graceful behavior for RPCs not yet dispatched
|
||||||
|
// - unfortunate timing would otherwise lead to the RPC failing even
|
||||||
|
// though the TRANSIENT_FAILURE state (called for by the doc) would be
|
||||||
|
// instantaneous.
|
||||||
//
|
//
|
||||||
// This will set addrConn to TRANSIENT_FAILURE for a very short period
|
// Ideally we should transition to Idle here and block until there is
|
||||||
// of time, and turns CONNECTING. It seems reasonable to skip this, but
|
// RPC activity that leads to the balancer requesting a reconnect of
|
||||||
// READY-CONNECTING is not a valid transition.
|
// the associated SubConn.
|
||||||
ac.mu.Lock()
|
|
||||||
if ac.state == connectivity.Shutdown {
|
|
||||||
ac.mu.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ac.updateConnectivityState(connectivity.TransientFailure)
|
|
||||||
ac.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,8 +1099,6 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
return nil, resolver.Address{}, nil, errConnClosing
|
return nil, resolver.Address{}, nil, errConnClosing
|
||||||
}
|
}
|
||||||
ac.updateConnectivityState(connectivity.Connecting)
|
|
||||||
ac.transport = nil
|
|
||||||
|
|
||||||
ac.cc.mu.RLock()
|
ac.cc.mu.RLock()
|
||||||
ac.dopts.copts.KeepaliveParams = ac.cc.mkp
|
ac.dopts.copts.KeepaliveParams = ac.cc.mkp
|
||||||
|
@ -1111,14 +1142,35 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
||||||
Authority: ac.cc.authority,
|
Authority: ac.cc.authority,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
once := sync.Once{}
|
||||||
onGoAway := func(r transport.GoAwayReason) {
|
onGoAway := func(r transport.GoAwayReason) {
|
||||||
ac.mu.Lock()
|
ac.mu.Lock()
|
||||||
ac.adjustParams(r)
|
ac.adjustParams(r)
|
||||||
|
once.Do(func() {
|
||||||
|
if ac.state == connectivity.Ready {
|
||||||
|
// Prevent this SubConn from being used for new RPCs by setting its
|
||||||
|
// state to Connecting.
|
||||||
|
//
|
||||||
|
// TODO: this should be Idle when grpc-go properly supports it.
|
||||||
|
ac.updateConnectivityState(connectivity.Connecting)
|
||||||
|
}
|
||||||
|
})
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
reconnect.Fire()
|
reconnect.Fire()
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose := func() {
|
onClose := func() {
|
||||||
|
ac.mu.Lock()
|
||||||
|
once.Do(func() {
|
||||||
|
if ac.state == connectivity.Ready {
|
||||||
|
// Prevent this SubConn from being used for new RPCs by setting its
|
||||||
|
// state to Connecting.
|
||||||
|
//
|
||||||
|
// TODO: this should be Idle when grpc-go properly supports it.
|
||||||
|
ac.updateConnectivityState(connectivity.Connecting)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ac.mu.Unlock()
|
||||||
close(onCloseCalled)
|
close(onCloseCalled)
|
||||||
reconnect.Fire()
|
reconnect.Fire()
|
||||||
}
|
}
|
||||||
|
@ -1140,7 +1192,6 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn {
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(connectDeadline.Sub(time.Now())):
|
case <-time.After(connectDeadline.Sub(time.Now())):
|
||||||
// We didn't get the preface in time.
|
// We didn't get the preface in time.
|
||||||
|
@ -1154,33 +1205,72 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
||||||
return nil, nil, errors.New("connection closed")
|
return nil, nil, errors.New("connection closed")
|
||||||
// TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix.
|
// TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix.
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return newTr, reconnect, nil
|
return newTr, reconnect, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.ClientTransport, addr resolver.Address, serviceName string) {
|
// startHealthCheck starts the health checking stream (RPC) to watch the health
|
||||||
// Set up the health check helper functions
|
// stats of this connection if health checking is requested and configured.
|
||||||
newStream := func() (interface{}, error) {
|
//
|
||||||
return ac.newClientStream(ctx, &StreamDesc{ServerStreams: true}, "/grpc.health.v1.Health/Watch", newTr)
|
// LB channel health checking is enabled when all requirements below are met:
|
||||||
|
// 1. it is not disabled by the user with the WithDisableHealthCheck DialOption
|
||||||
|
// 2. internal.HealthCheckFunc is set by importing the grpc/healthcheck package
|
||||||
|
// 3. a service config with non-empty healthCheckConfig field is provided
|
||||||
|
// 4. the load balancer requests it
|
||||||
|
//
|
||||||
|
// It sets addrConn to READY if the health checking stream is not started.
|
||||||
|
//
|
||||||
|
// Caller must hold ac.mu.
|
||||||
|
func (ac *addrConn) startHealthCheck(ctx context.Context) {
|
||||||
|
var healthcheckManagingState bool
|
||||||
|
defer func() {
|
||||||
|
if !healthcheckManagingState {
|
||||||
|
ac.updateConnectivityState(connectivity.Ready)
|
||||||
}
|
}
|
||||||
firstReady := true
|
}()
|
||||||
reportHealth := func(ok bool) {
|
|
||||||
ac.mu.Lock()
|
if ac.cc.dopts.disableHealthCheck {
|
||||||
defer ac.mu.Unlock()
|
|
||||||
if ac.transport != newTr {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok {
|
healthCheckConfig := ac.cc.healthCheckConfig()
|
||||||
if firstReady {
|
if healthCheckConfig == nil {
|
||||||
firstReady = false
|
return
|
||||||
ac.curAddr = addr
|
|
||||||
}
|
}
|
||||||
ac.updateConnectivityState(connectivity.Ready)
|
if !ac.scopts.HealthCheckEnabled {
|
||||||
} else {
|
return
|
||||||
ac.updateConnectivityState(connectivity.TransientFailure)
|
|
||||||
}
|
}
|
||||||
|
healthCheckFunc := ac.cc.dopts.healthCheckFunc
|
||||||
|
if healthCheckFunc == nil {
|
||||||
|
// The health package is not imported to set health check function.
|
||||||
|
//
|
||||||
|
// TODO: add a link to the health check doc in the error message.
|
||||||
|
grpclog.Error("Health check is requested but health check function is not set.")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
err := ac.cc.dopts.healthCheckFunc(ctx, newStream, reportHealth, serviceName)
|
|
||||||
|
healthcheckManagingState = true
|
||||||
|
|
||||||
|
// Set up the health check helper functions.
|
||||||
|
currentTr := ac.transport
|
||||||
|
newStream := func(method string) (interface{}, error) {
|
||||||
|
ac.mu.Lock()
|
||||||
|
if ac.transport != currentTr {
|
||||||
|
ac.mu.Unlock()
|
||||||
|
return nil, status.Error(codes.Canceled, "the provided transport is no longer valid to use")
|
||||||
|
}
|
||||||
|
ac.mu.Unlock()
|
||||||
|
return newNonRetryClientStream(ctx, &StreamDesc{ServerStreams: true}, method, currentTr, ac)
|
||||||
|
}
|
||||||
|
setConnectivityState := func(s connectivity.State) {
|
||||||
|
ac.mu.Lock()
|
||||||
|
defer ac.mu.Unlock()
|
||||||
|
if ac.transport != currentTr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ac.updateConnectivityState(s)
|
||||||
|
}
|
||||||
|
// Start the health checking stream.
|
||||||
|
go func() {
|
||||||
|
err := ac.cc.dopts.healthCheckFunc(ctx, newStream, setConnectivityState, healthCheckConfig.ServiceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if status.Code(err) == codes.Unimplemented {
|
if status.Code(err) == codes.Unimplemented {
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
|
@ -1194,6 +1284,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.Client
|
||||||
grpclog.Errorf("HealthCheckFunc exits with unexpected error %v", err)
|
grpclog.Errorf("HealthCheckFunc exits with unexpected error %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *addrConn) resetConnectBackoff() {
|
func (ac *addrConn) resetConnectBackoff() {
|
||||||
|
|
|
@ -132,7 +132,8 @@ const (
|
||||||
|
|
||||||
// Unavailable indicates the service is currently unavailable.
|
// Unavailable indicates the service is currently unavailable.
|
||||||
// This is a most likely a transient condition and may be corrected
|
// This is a most likely a transient condition and may be corrected
|
||||||
// by retrying with a backoff.
|
// by retrying with a backoff. Note that it is not always safe to retry
|
||||||
|
// non-idempotent operations.
|
||||||
//
|
//
|
||||||
// See litmus test above for deciding between FailedPrecondition,
|
// See litmus test above for deciding between FailedPrecondition,
|
||||||
// Aborted, and Unavailable.
|
// Aborted, and Unavailable.
|
||||||
|
|
|
@ -278,24 +278,22 @@ type ChannelzSecurityValue interface {
|
||||||
// TLSChannelzSecurityValue defines the struct that TLS protocol should return
|
// TLSChannelzSecurityValue defines the struct that TLS protocol should return
|
||||||
// from GetSecurityValue(), containing security info like cipher and certificate used.
|
// from GetSecurityValue(), containing security info like cipher and certificate used.
|
||||||
type TLSChannelzSecurityValue struct {
|
type TLSChannelzSecurityValue struct {
|
||||||
|
ChannelzSecurityValue
|
||||||
StandardName string
|
StandardName string
|
||||||
LocalCertificate []byte
|
LocalCertificate []byte
|
||||||
RemoteCertificate []byte
|
RemoteCertificate []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*TLSChannelzSecurityValue) isChannelzSecurityValue() {}
|
|
||||||
|
|
||||||
// OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
|
// OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
|
||||||
// from GetSecurityValue(), which contains protocol specific security info. Note
|
// from GetSecurityValue(), which contains protocol specific security info. Note
|
||||||
// the Value field will be sent to users of channelz requesting channel info, and
|
// the Value field will be sent to users of channelz requesting channel info, and
|
||||||
// thus sensitive info should better be avoided.
|
// thus sensitive info should better be avoided.
|
||||||
type OtherChannelzSecurityValue struct {
|
type OtherChannelzSecurityValue struct {
|
||||||
|
ChannelzSecurityValue
|
||||||
Name string
|
Name string
|
||||||
Value proto.Message
|
Value proto.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*OtherChannelzSecurityValue) isChannelzSecurityValue() {}
|
|
||||||
|
|
||||||
var cipherSuiteLookup = map[uint16]string{
|
var cipherSuiteLookup = map[uint16]string{
|
||||||
tls.TLS_RSA_WITH_RC4_128_SHA: "TLS_RSA_WITH_RC4_128_SHA",
|
tls.TLS_RSA_WITH_RC4_128_SHA: "TLS_RSA_WITH_RC4_128_SHA",
|
||||||
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
|
|
@ -41,6 +41,10 @@ import (
|
||||||
type dialOptions struct {
|
type dialOptions struct {
|
||||||
unaryInt UnaryClientInterceptor
|
unaryInt UnaryClientInterceptor
|
||||||
streamInt StreamClientInterceptor
|
streamInt StreamClientInterceptor
|
||||||
|
|
||||||
|
chainUnaryInts []UnaryClientInterceptor
|
||||||
|
chainStreamInts []StreamClientInterceptor
|
||||||
|
|
||||||
cp Compressor
|
cp Compressor
|
||||||
dc Decompressor
|
dc Decompressor
|
||||||
bs backoff.Strategy
|
bs backoff.Strategy
|
||||||
|
@ -56,7 +60,6 @@ type dialOptions struct {
|
||||||
balancerBuilder balancer.Builder
|
balancerBuilder balancer.Builder
|
||||||
// This is to support grpclb.
|
// This is to support grpclb.
|
||||||
resolverBuilder resolver.Builder
|
resolverBuilder resolver.Builder
|
||||||
reqHandshake envconfig.RequireHandshakeSetting
|
|
||||||
channelzParentID int64
|
channelzParentID int64
|
||||||
disableServiceConfig bool
|
disableServiceConfig bool
|
||||||
disableRetry bool
|
disableRetry bool
|
||||||
|
@ -96,17 +99,6 @@ func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithWaitForHandshake blocks until the initial settings frame is received from
|
|
||||||
// the server before assigning RPCs to the connection.
|
|
||||||
//
|
|
||||||
// Deprecated: this is the default behavior, and this option will be removed
|
|
||||||
// after the 1.18 release.
|
|
||||||
func WithWaitForHandshake() DialOption {
|
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
|
||||||
o.reqHandshake = envconfig.RequireHandshakeOn
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWriteBufferSize determines how much data can be batched before doing a
|
// WithWriteBufferSize determines how much data can be batched before doing a
|
||||||
// write on the wire. The corresponding memory allocation for this buffer will
|
// write on the wire. The corresponding memory allocation for this buffer will
|
||||||
// be twice the size to keep syscalls low. The default value for this buffer is
|
// be twice the size to keep syscalls low. The default value for this buffer is
|
||||||
|
@ -152,7 +144,8 @@ func WithInitialConnWindowSize(s int32) DialOption {
|
||||||
// WithMaxMsgSize returns a DialOption which sets the maximum message size the
|
// WithMaxMsgSize returns a DialOption which sets the maximum message size the
|
||||||
// client can receive.
|
// client can receive.
|
||||||
//
|
//
|
||||||
// Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead.
|
// Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. Will
|
||||||
|
// be supported throughout 1.x.
|
||||||
func WithMaxMsgSize(s int) DialOption {
|
func WithMaxMsgSize(s int) DialOption {
|
||||||
return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
|
return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
|
||||||
}
|
}
|
||||||
|
@ -168,7 +161,8 @@ func WithDefaultCallOptions(cos ...CallOption) DialOption {
|
||||||
// WithCodec returns a DialOption which sets a codec for message marshaling and
|
// WithCodec returns a DialOption which sets a codec for message marshaling and
|
||||||
// unmarshaling.
|
// unmarshaling.
|
||||||
//
|
//
|
||||||
// Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead.
|
// Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. Will be
|
||||||
|
// supported throughout 1.x.
|
||||||
func WithCodec(c Codec) DialOption {
|
func WithCodec(c Codec) DialOption {
|
||||||
return WithDefaultCallOptions(CallCustomCodec(c))
|
return WithDefaultCallOptions(CallCustomCodec(c))
|
||||||
}
|
}
|
||||||
|
@ -177,7 +171,7 @@ func WithCodec(c Codec) DialOption {
|
||||||
// message compression. It has lower priority than the compressor set by the
|
// message compression. It has lower priority than the compressor set by the
|
||||||
// UseCompressor CallOption.
|
// UseCompressor CallOption.
|
||||||
//
|
//
|
||||||
// Deprecated: use UseCompressor instead.
|
// Deprecated: use UseCompressor instead. Will be supported throughout 1.x.
|
||||||
func WithCompressor(cp Compressor) DialOption {
|
func WithCompressor(cp Compressor) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.cp = cp
|
o.cp = cp
|
||||||
|
@ -192,7 +186,8 @@ func WithCompressor(cp Compressor) DialOption {
|
||||||
// message. If no compressor is registered for the encoding, an Unimplemented
|
// message. If no compressor is registered for the encoding, an Unimplemented
|
||||||
// status error will be returned.
|
// status error will be returned.
|
||||||
//
|
//
|
||||||
// Deprecated: use encoding.RegisterCompressor instead.
|
// Deprecated: use encoding.RegisterCompressor instead. Will be supported
|
||||||
|
// throughout 1.x.
|
||||||
func WithDecompressor(dc Decompressor) DialOption {
|
func WithDecompressor(dc Decompressor) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.dc = dc
|
o.dc = dc
|
||||||
|
@ -203,7 +198,7 @@ func WithDecompressor(dc Decompressor) DialOption {
|
||||||
// Name resolver will be ignored if this DialOption is specified.
|
// Name resolver will be ignored if this DialOption is specified.
|
||||||
//
|
//
|
||||||
// Deprecated: use the new balancer APIs in balancer package and
|
// Deprecated: use the new balancer APIs in balancer package and
|
||||||
// WithBalancerName.
|
// WithBalancerName. Will be removed in a future 1.x release.
|
||||||
func WithBalancer(b Balancer) DialOption {
|
func WithBalancer(b Balancer) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.balancerBuilder = &balancerWrapperBuilder{
|
o.balancerBuilder = &balancerWrapperBuilder{
|
||||||
|
@ -219,7 +214,8 @@ func WithBalancer(b Balancer) DialOption {
|
||||||
// The balancer cannot be overridden by balancer option specified by service
|
// The balancer cannot be overridden by balancer option specified by service
|
||||||
// config.
|
// config.
|
||||||
//
|
//
|
||||||
// This is an EXPERIMENTAL API.
|
// Deprecated: use WithDefaultServiceConfig and WithDisableServiceConfig
|
||||||
|
// instead. Will be removed in a future 1.x release.
|
||||||
func WithBalancerName(balancerName string) DialOption {
|
func WithBalancerName(balancerName string) DialOption {
|
||||||
builder := balancer.Get(balancerName)
|
builder := balancer.Get(balancerName)
|
||||||
if builder == nil {
|
if builder == nil {
|
||||||
|
@ -240,9 +236,10 @@ func withResolverBuilder(b resolver.Builder) DialOption {
|
||||||
// WithServiceConfig returns a DialOption which has a channel to read the
|
// WithServiceConfig returns a DialOption which has a channel to read the
|
||||||
// service configuration.
|
// service configuration.
|
||||||
//
|
//
|
||||||
// Deprecated: service config should be received through name resolver, as
|
// Deprecated: service config should be received through name resolver or via
|
||||||
// specified here.
|
// WithDefaultServiceConfig, as specified at
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/service_config.md
|
// https://github.com/grpc/grpc/blob/master/doc/service_config.md. Will be
|
||||||
|
// removed in a future 1.x release.
|
||||||
func WithServiceConfig(c <-chan ServiceConfig) DialOption {
|
func WithServiceConfig(c <-chan ServiceConfig) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.scChan = c
|
o.scChan = c
|
||||||
|
@ -325,7 +322,8 @@ func WithCredentialsBundle(b credentials.Bundle) DialOption {
|
||||||
// WithTimeout returns a DialOption that configures a timeout for dialing a
|
// WithTimeout returns a DialOption that configures a timeout for dialing a
|
||||||
// ClientConn initially. This is valid if and only if WithBlock() is present.
|
// ClientConn initially. This is valid if and only if WithBlock() is present.
|
||||||
//
|
//
|
||||||
// Deprecated: use DialContext and context.WithTimeout instead.
|
// Deprecated: use DialContext and context.WithTimeout instead. Will be
|
||||||
|
// supported throughout 1.x.
|
||||||
func WithTimeout(d time.Duration) DialOption {
|
func WithTimeout(d time.Duration) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.timeout = d
|
o.timeout = d
|
||||||
|
@ -352,7 +350,8 @@ func init() {
|
||||||
// is returned by f, gRPC checks the error's Temporary() method to decide if it
|
// is returned by f, gRPC checks the error's Temporary() method to decide if it
|
||||||
// should try to reconnect to the network address.
|
// should try to reconnect to the network address.
|
||||||
//
|
//
|
||||||
// Deprecated: use WithContextDialer instead
|
// Deprecated: use WithContextDialer instead. Will be supported throughout
|
||||||
|
// 1.x.
|
||||||
func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
|
func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
|
||||||
return WithContextDialer(
|
return WithContextDialer(
|
||||||
func(ctx context.Context, addr string) (net.Conn, error) {
|
func(ctx context.Context, addr string) (net.Conn, error) {
|
||||||
|
@ -414,6 +413,17 @@ func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithChainUnaryInterceptor returns a DialOption that specifies the chained
|
||||||
|
// interceptor for unary RPCs. The first interceptor will be the outer most,
|
||||||
|
// while the last interceptor will be the inner most wrapper around the real call.
|
||||||
|
// All interceptors added by this method will be chained, and the interceptor
|
||||||
|
// defined by WithUnaryInterceptor will always be prepended to the chain.
|
||||||
|
func WithChainUnaryInterceptor(interceptors ...UnaryClientInterceptor) DialOption {
|
||||||
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
|
o.chainUnaryInts = append(o.chainUnaryInts, interceptors...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// WithStreamInterceptor returns a DialOption that specifies the interceptor for
|
// WithStreamInterceptor returns a DialOption that specifies the interceptor for
|
||||||
// streaming RPCs.
|
// streaming RPCs.
|
||||||
func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
|
func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
|
||||||
|
@ -422,6 +432,17 @@ func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithChainStreamInterceptor returns a DialOption that specifies the chained
|
||||||
|
// interceptor for unary RPCs. The first interceptor will be the outer most,
|
||||||
|
// while the last interceptor will be the inner most wrapper around the real call.
|
||||||
|
// All interceptors added by this method will be chained, and the interceptor
|
||||||
|
// defined by WithStreamInterceptor will always be prepended to the chain.
|
||||||
|
func WithChainStreamInterceptor(interceptors ...StreamClientInterceptor) DialOption {
|
||||||
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
|
o.chainStreamInts = append(o.chainStreamInts, interceptors...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// WithAuthority returns a DialOption that specifies the value to be used as the
|
// WithAuthority returns a DialOption that specifies the value to be used as the
|
||||||
// :authority pseudo-header. This value only works with WithInsecure and has no
|
// :authority pseudo-header. This value only works with WithInsecure and has no
|
||||||
// effect if TransportCredentials are present.
|
// effect if TransportCredentials are present.
|
||||||
|
@ -440,12 +461,12 @@ func WithChannelzParentID(id int64) DialOption {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any
|
// WithDisableServiceConfig returns a DialOption that causes gRPC to ignore any
|
||||||
// service config provided by the resolver and provides a hint to the resolver
|
// service config provided by the resolver and provides a hint to the resolver
|
||||||
// to not fetch service configs.
|
// to not fetch service configs.
|
||||||
//
|
//
|
||||||
// Note that, this dial option only disables service config from resolver. If
|
// Note that this dial option only disables service config from resolver. If
|
||||||
// default service config is provided, grpc will use the default service config.
|
// default service config is provided, gRPC will use the default service config.
|
||||||
func WithDisableServiceConfig() DialOption {
|
func WithDisableServiceConfig() DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.disableServiceConfig = true
|
o.disableServiceConfig = true
|
||||||
|
@ -454,8 +475,10 @@ func WithDisableServiceConfig() DialOption {
|
||||||
|
|
||||||
// WithDefaultServiceConfig returns a DialOption that configures the default
|
// WithDefaultServiceConfig returns a DialOption that configures the default
|
||||||
// service config, which will be used in cases where:
|
// service config, which will be used in cases where:
|
||||||
// 1. WithDisableServiceConfig is called.
|
//
|
||||||
// 2. Resolver does not return service config or if the resolver gets and invalid config.
|
// 1. WithDisableServiceConfig is also used.
|
||||||
|
// 2. Resolver does not return a service config or if the resolver returns an
|
||||||
|
// invalid service config.
|
||||||
//
|
//
|
||||||
// This API is EXPERIMENTAL.
|
// This API is EXPERIMENTAL.
|
||||||
func WithDefaultServiceConfig(s string) DialOption {
|
func WithDefaultServiceConfig(s string) DialOption {
|
||||||
|
@ -511,7 +534,6 @@ func withHealthCheckFunc(f internal.HealthChecker) DialOption {
|
||||||
func defaultDialOptions() dialOptions {
|
func defaultDialOptions() dialOptions {
|
||||||
return dialOptions{
|
return dialOptions{
|
||||||
disableRetry: !envconfig.Retry,
|
disableRetry: !envconfig.Retry,
|
||||||
reqHandshake: envconfig.RequireHandshake,
|
|
||||||
healthCheckFunc: internal.HealthCheckFunc,
|
healthCheckFunc: internal.HealthCheckFunc,
|
||||||
copts: transport.ConnectOptions{
|
copts: transport.ConnectOptions{
|
||||||
WriteBufferSize: defaultWriteBufSize,
|
WriteBufferSize: defaultWriteBufSize,
|
||||||
|
|
|
@ -7,13 +7,13 @@ require (
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
github.com/golang/mock v1.1.1
|
github.com/golang/mock v1.1.1
|
||||||
github.com/golang/protobuf v1.2.0
|
github.com/golang/protobuf v1.2.0
|
||||||
|
github.com/google/go-cmp v0.2.0
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135
|
||||||
google.golang.org/appengine v1.1.0 // indirect
|
google.golang.org/appengine v1.1.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc
|
||||||
)
|
)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue