Merge pull request #28275 from vieux/1.13.0_changelog
add 1.13.0 CHANGELOG.md
diff --git a/Dockerfile b/Dockerfile
index 5a77439..9d344c8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -236,6 +236,7 @@
# Install tomlv, vndr, runc, containerd, tini, docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy
diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64
index 36302c8..ce03d8d 100644
--- a/Dockerfile.aarch64
+++ b/Dockerfile.aarch64
@@ -164,6 +164,7 @@
# Install tomlv, vndr, runc, containerd, tini, docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy
diff --git a/Dockerfile.armhf b/Dockerfile.armhf
index b162005..7f213f8 100644
--- a/Dockerfile.armhf
+++ b/Dockerfile.armhf
@@ -168,6 +168,7 @@
# Install tomlv, vndr, runc, containerd, tini, docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy
diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le
index ad300c9..3f550d1 100644
--- a/Dockerfile.ppc64le
+++ b/Dockerfile.ppc64le
@@ -187,6 +187,7 @@
# Install tomlv, vndr, runc, containerd, tini, docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy
diff --git a/Dockerfile.s390x b/Dockerfile.s390x
index af9e2cd..6baa3a1 100644
--- a/Dockerfile.s390x
+++ b/Dockerfile.s390x
@@ -179,6 +179,7 @@
# Install tomlv, vndr, runc, containerd, tini, docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy
diff --git a/Dockerfile.simple b/Dockerfile.simple
index bc598ca..4a15a38 100644
--- a/Dockerfile.simple
+++ b/Dockerfile.simple
@@ -60,6 +60,7 @@
# Install runc, containerd, tini and docker-proxy
# Please edit hack/dockerfile/install-binaries.sh to update them.
+COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
RUN /tmp/install-binaries.sh runc containerd tini proxy
diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go
index c5be1df..5209d7e 100644
--- a/api/server/router/image/backend.go
+++ b/api/server/router/image/backend.go
@@ -5,6 +5,7 @@
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
+ "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"golang.org/x/net/context"
)
@@ -25,7 +26,7 @@
type imageBackend interface {
ImageDelete(imageRef string, force, prune bool) ([]types.ImageDelete, error)
ImageHistory(imageName string) ([]*types.ImageHistory, error)
- Images(filterArgs string, filter string, all bool, withExtraAttrs bool) ([]*types.ImageSummary, error)
+ Images(imageFilters filters.Args, all bool, withExtraAttrs bool) ([]*types.ImageSummary, error)
LookupImage(name string) (*types.ImageInspect, error)
TagImage(imageName, repository, tag string) error
ImagesPrune(config *types.ImagesPruneConfig) (*types.ImagesPruneReport, error)
diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go
index bbc2d2b..2b12503 100644
--- a/api/server/router/image/image_routes.go
+++ b/api/server/router/image/image_routes.go
@@ -13,6 +13,7 @@
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
+ "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/streamformatter"
@@ -247,8 +248,18 @@
return err
}
- // FIXME: The filter parameter could just be a match filter
- images, err := s.backend.Images(r.Form.Get("filters"), r.Form.Get("filter"), httputils.BoolValue(r, "all"), false)
+ imageFilters, err := filters.FromParam(r.Form.Get("filters"))
+ if err != nil {
+ return err
+ }
+
+ version := httputils.VersionFromContext(ctx)
+ filterParam := r.Form.Get("filter")
+ if versions.LessThan(version, "1.28") && filterParam != "" {
+ imageFilters.Add("reference", filterParam)
+ }
+
+ images, err := s.backend.Images(imageFilters, httputils.BoolValue(r, "all"), false)
if err != nil {
return err
}
diff --git a/api/server/router/swarm/cluster.go b/api/server/router/swarm/cluster.go
index e31c6ad..e7181a4 100644
--- a/api/server/router/swarm/cluster.go
+++ b/api/server/router/swarm/cluster.go
@@ -5,7 +5,7 @@
"github.com/docker/docker/daemon"
)
-// buildRouter is a router to talk with the build controller
+// swarmRouter is a router to talk with the build controller
type swarmRouter struct {
backend Backend
routes []router.Route
diff --git a/api/types/client.go b/api/types/client.go
index 9167aa6..67e4446 100644
--- a/api/types/client.go
+++ b/api/types/client.go
@@ -202,9 +202,8 @@
// ImageListOptions holds parameters to filter the list of images with.
type ImageListOptions struct {
- MatchName string
- All bool
- Filters filters.Args
+ All bool
+ Filters filters.Args
}
// ImageLoadResponse returns information to the client about a load process.
diff --git a/api/types/swarm/container.go b/api/types/swarm/container.go
index 0db5cbc..4ab476c 100644
--- a/api/types/swarm/container.go
+++ b/api/types/swarm/container.go
@@ -33,6 +33,7 @@
User string `json:",omitempty"`
Groups []string `json:",omitempty"`
TTY bool `json:",omitempty"`
+ OpenStdin bool `json:",omitempty"`
Mounts []mount.Mount `json:",omitempty"`
StopGracePeriod *time.Duration `json:",omitempty"`
Healthcheck *container.HealthConfig `json:",omitempty"`
diff --git a/api/types/swarm/network.go b/api/types/swarm/network.go
index 76b0bea..2ba5339 100644
--- a/api/types/swarm/network.go
+++ b/api/types/swarm/network.go
@@ -31,8 +31,23 @@
TargetPort uint32 `json:",omitempty"`
// PublishedPort is the port on the swarm hosts
PublishedPort uint32 `json:",omitempty"`
+ // PublishMode is the mode in which port is published
+ PublishMode PortConfigPublishMode `json:",omitempty"`
}
+// PortConfigPublishMode represents the mode in which the port is to
+// be published.
+type PortConfigPublishMode string
+
+const (
+ // PortConfigPublishModeIngress is used for ports published
+ // for ingress load balancing using routing mesh.
+ PortConfigPublishModeIngress PortConfigPublishMode = "ingress"
+ // PortConfigPublishModeHost is used for ports published
+ // for direct host level access on the host where the task is running.
+ PortConfigPublishModeHost PortConfigPublishMode = "host"
+)
+
// PortConfigProtocol represents the protocol of a port.
type PortConfigProtocol string
diff --git a/api/types/swarm/task.go b/api/types/swarm/task.go
index bb28eec..ace12cc 100644
--- a/api/types/swarm/task.go
+++ b/api/types/swarm/task.go
@@ -111,6 +111,7 @@
Message string `json:",omitempty"`
Err string `json:",omitempty"`
ContainerStatus ContainerStatus `json:",omitempty"`
+ PortStatus PortStatus `json:",omitempty"`
}
// ContainerStatus represents the status of a container.
@@ -119,3 +120,9 @@
PID int `json:",omitempty"`
ExitCode int `json:",omitempty"`
}
+
+// PortStatus represents the port status of a task's host ports whose
+// service has published host ports
+type PortStatus struct {
+ Ports []PortConfig `json:",omitempty"`
+}
diff --git a/api/types/types.go b/api/types/types.go
index e6668bb..41a902c 100644
--- a/api/types/types.go
+++ b/api/types/types.go
@@ -151,6 +151,13 @@
BuildTime string `json:",omitempty"`
}
+// Commit records a external tool actual commit id version along the
+// one expect by dockerd as set at build time
+type Commit struct {
+ ID string
+ Expected string
+}
+
// InfoBase contains the base response of Remote API:
// GET "/info"
type InfoBase struct {
@@ -208,6 +215,10 @@
// running containers are detected
LiveRestoreEnabled bool
Isolation container.Isolation
+ InitBinary string
+ ContainerdCommit Commit
+ RuncCommit Commit
+ InitCommit Commit
}
// SecurityOpt holds key/value pair about a security option
diff --git a/cli/command/image/list.go b/cli/command/image/list.go
index 587869f..679604f 100644
--- a/cli/command/image/list.go
+++ b/cli/command/image/list.go
@@ -60,10 +60,14 @@
func runImages(dockerCli *command.DockerCli, opts imagesOptions) error {
ctx := context.Background()
+ filters := opts.filter.Value()
+ if opts.matchName != "" {
+ filters.Add("reference", opts.matchName)
+ }
+
options := types.ImageListOptions{
- MatchName: opts.matchName,
- All: opts.all,
- Filters: opts.filter.Value(),
+ All: opts.all,
+ Filters: filters,
}
images, err := dockerCli.Client().ImageList(ctx, options)
diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go
index b8de6a5..d1106b5 100644
--- a/cli/command/image/trust.go
+++ b/cli/command/image/trust.go
@@ -20,6 +20,7 @@
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/registry/client/auth"
+ "github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
@@ -291,7 +292,7 @@
}
fmt.Fprintf(cli.Out(), "Pull (%d of %d): %s%s@%s\n", i+1, len(refs), repoInfo.Name(), displayTag, r.digest)
- ref, err := reference.WithDigest(repoInfo, r.digest)
+ ref, err := reference.WithDigest(reference.TrimNamed(repoInfo), r.digest)
if err != nil {
return err
}
@@ -305,7 +306,7 @@
if err != nil {
return err
}
- trustedRef, err := reference.WithDigest(repoInfo, r.digest)
+ trustedRef, err := reference.WithDigest(reference.TrimNamed(repoInfo), r.digest)
if err != nil {
return err
}
@@ -434,7 +435,7 @@
return nil, err
}
- challengeManager := auth.NewSimpleChallengeManager()
+ challengeManager := challenge.NewSimpleManager()
resp, err := pingClient.Do(req)
if err != nil {
@@ -523,7 +524,7 @@
}
- return reference.WithDigest(ref, r.digest)
+ return reference.WithDigest(reference.TrimNamed(ref), r.digest)
}
func convertTarget(t client.Target) (target, error) {
diff --git a/cli/command/service/create.go b/cli/command/service/create.go
index 17cf196..3358671 100644
--- a/cli/command/service/create.go
+++ b/cli/command/service/create.go
@@ -40,12 +40,14 @@
flags.Var(&opts.constraints, flagConstraint, "Placement constraints")
flags.Var(&opts.networks, flagNetwork, "Network attachments")
flags.Var(&opts.secrets, flagSecret, "Specify secrets to expose to the service")
- flags.VarP(&opts.endpoint.ports, flagPublish, "p", "Publish a port as a node port")
+ flags.VarP(&opts.endpoint.publishPorts, flagPublish, "p", "Publish a port as a node port")
+ flags.MarkHidden(flagPublish)
flags.Var(&opts.groups, flagGroup, "Set one or more supplementary user groups for the container")
flags.Var(&opts.dns, flagDNS, "Set custom DNS servers")
flags.Var(&opts.dnsOption, flagDNSOption, "Set DNS options")
flags.Var(&opts.dnsSearch, flagDNSSearch, "Set custom DNS search domains")
flags.Var(&opts.hosts, flagHost, "Set one or more custom host-to-IP mappings (host:ip)")
+ flags.Var(&opts.endpoint.expandedPorts, flagPort, "Publish a port")
flags.SetInterspersed(false)
return cmd
diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go
index 4ea78c6..7da8338 100644
--- a/cli/command/service/opts.go
+++ b/cli/command/service/opts.go
@@ -287,14 +287,15 @@
}
type endpointOptions struct {
- mode string
- ports opts.ListOpts
+ mode string
+ publishPorts opts.ListOpts
+ expandedPorts opts.PortOpt
}
func (e *endpointOptions) ToEndpointSpec() *swarm.EndpointSpec {
portConfigs := []swarm.PortConfig{}
// We can ignore errors because the format was already validated by ValidatePort
- ports, portBindings, _ := nat.ParsePortSpecs(e.ports.GetAll())
+ ports, portBindings, _ := nat.ParsePortSpecs(e.publishPorts.GetAll())
for port := range ports {
portConfigs = append(portConfigs, ConvertPortToPortConfig(port, portBindings)...)
@@ -302,7 +303,7 @@
return &swarm.EndpointSpec{
Mode: swarm.ResolutionMode(strings.ToLower(e.mode)),
- Ports: portConfigs,
+ Ports: append(portConfigs, e.expandedPorts.Value()...),
}
}
@@ -459,7 +460,7 @@
env: opts.NewListOpts(runconfigopts.ValidateEnv),
envFile: opts.NewListOpts(nil),
endpoint: endpointOptions{
- ports: opts.NewListOpts(ValidatePort),
+ publishPorts: opts.NewListOpts(ValidatePort),
},
groups: opts.NewListOpts(nil),
logDriver: newLogDriverOptions(),
@@ -647,6 +648,9 @@
flagPublish = "publish"
flagPublishRemove = "publish-rm"
flagPublishAdd = "publish-add"
+ flagPort = "port"
+ flagPortAdd = "port-add"
+ flagPortRemove = "port-rm"
flagReplicas = "replicas"
flagReserveCPU = "reserve-cpu"
flagReserveMemory = "reserve-memory"
diff --git a/cli/command/service/update.go b/cli/command/service/update.go
index 1214b03..d2639a6 100644
--- a/cli/command/service/update.go
+++ b/cli/command/service/update.go
@@ -48,6 +48,8 @@
flags.Var(newListOptsVar(), flagContainerLabelRemove, "Remove a container label by its key")
flags.Var(newListOptsVar(), flagMountRemove, "Remove a mount by its target path")
flags.Var(newListOptsVar(), flagPublishRemove, "Remove a published port by its target port")
+ flags.MarkHidden(flagPublishRemove)
+ flags.Var(newListOptsVar(), flagPortRemove, "Remove a port(target-port mandatory)")
flags.Var(newListOptsVar(), flagConstraintRemove, "Remove a constraint")
flags.Var(newListOptsVar(), flagDNSRemove, "Remove a custom DNS server")
flags.Var(newListOptsVar(), flagDNSOptionRemove, "Remove a DNS option")
@@ -60,7 +62,9 @@
flags.Var(&opts.secrets, flagSecretAdd, "Add or update a secret on a service")
flags.Var(&opts.mounts, flagMountAdd, "Add or update a mount on a service")
flags.Var(&opts.constraints, flagConstraintAdd, "Add or update a placement constraint")
- flags.Var(&opts.endpoint.ports, flagPublishAdd, "Add or update a published port")
+ flags.Var(&opts.endpoint.publishPorts, flagPublishAdd, "Add or update a published port")
+ flags.MarkHidden(flagPublishAdd)
+ flags.Var(&opts.endpoint.expandedPorts, flagPortAdd, "Add or update a port")
flags.Var(&opts.groups, flagGroupAdd, "Add an additional supplementary user group to the container")
flags.Var(&opts.dns, flagDNSAdd, "Add or update a custom DNS server")
flags.Var(&opts.dnsOption, flagDNSOptionAdd, "Add or update a DNS option")
@@ -267,7 +271,7 @@
}
}
- if anyChanged(flags, flagPublishAdd, flagPublishRemove) {
+ if anyChanged(flags, flagPublishAdd, flagPublishRemove, flagPortAdd, flagPortRemove) {
if spec.EndpointSpec == nil {
spec.EndpointSpec = &swarm.EndpointSpec{}
}
@@ -627,7 +631,13 @@
if protocol == "" {
protocol = "tcp"
}
- return fmt.Sprintf("%v/%s", portConfig.PublishedPort, protocol)
+
+ mode := portConfig.PublishMode
+ if mode == "" {
+ mode = "ingress"
+ }
+
+ return fmt.Sprintf("%v:%v/%s/%s", portConfig.PublishedPort, portConfig.TargetPort, protocol, mode)
}
func updatePorts(flags *pflag.FlagSet, portConfig *[]swarm.PortConfig) error {
@@ -649,6 +659,15 @@
}
}
+ if flags.Changed(flagPortAdd) {
+ for _, entry := range flags.Lookup(flagPortAdd).Value.(*opts.PortOpt).Value() {
+ if v, ok := portSet[portConfigToString(&entry)]; ok && v != entry {
+ return fmt.Errorf("conflicting port mapping between %v:%v/%s and %v:%v/%s", entry.PublishedPort, entry.TargetPort, entry.Protocol, v.PublishedPort, v.TargetPort, v.Protocol)
+ }
+ portSet[portConfigToString(&entry)] = entry
+ }
+ }
+
// Override previous PortConfig in service if there is any duplicate
for _, entry := range *portConfig {
if _, ok := portSet[portConfigToString(&entry)]; !ok {
@@ -657,6 +676,14 @@
}
toRemove := flags.Lookup(flagPublishRemove).Value.(*opts.ListOpts).GetAll()
+ removePortCSV := flags.Lookup(flagPortRemove).Value.(*opts.ListOpts).GetAll()
+ removePortOpts := &opts.PortOpt{}
+ for _, portCSV := range removePortCSV {
+ if err := removePortOpts.Set(portCSV); err != nil {
+ return err
+ }
+ }
+
newPorts := []swarm.PortConfig{}
portLoop:
for _, port := range portSet {
@@ -666,14 +693,36 @@
continue portLoop
}
}
+
+ for _, pConfig := range removePortOpts.Value() {
+ if equalProtocol(port.Protocol, pConfig.Protocol) &&
+ port.TargetPort == pConfig.TargetPort &&
+ equalPublishMode(port.PublishMode, pConfig.PublishMode) {
+ continue portLoop
+ }
+ }
+
newPorts = append(newPorts, port)
}
+
// Sort the PortConfig to avoid unnecessary updates
sort.Sort(byPortConfig(newPorts))
*portConfig = newPorts
return nil
}
+func equalProtocol(prot1, prot2 swarm.PortConfigProtocol) bool {
+ return prot1 == prot2 ||
+ (prot1 == swarm.PortConfigProtocol("") && prot2 == swarm.PortConfigProtocolTCP) ||
+ (prot2 == swarm.PortConfigProtocol("") && prot1 == swarm.PortConfigProtocolTCP)
+}
+
+func equalPublishMode(mode1, mode2 swarm.PortConfigPublishMode) bool {
+ return mode1 == mode2 ||
+ (mode1 == swarm.PortConfigPublishMode("") && mode2 == swarm.PortConfigPublishModeIngress) ||
+ (mode2 == swarm.PortConfigPublishMode("") && mode1 == swarm.PortConfigPublishModeIngress)
+}
+
func equalPort(targetPort nat.Port, port swarm.PortConfig) bool {
return (string(port.Protocol) == targetPort.Proto() &&
port.TargetPort == uint32(targetPort.Int()))
diff --git a/cli/command/service/update_test.go b/cli/command/service/update_test.go
index a373609..998d06d 100644
--- a/cli/command/service/update_test.go
+++ b/cli/command/service/update_test.go
@@ -238,7 +238,7 @@
func TestUpdatePortsDuplicateKeys(t *testing.T) {
// Test case for #25375
flags := newUpdateCommand(nil).Flags()
- flags.Set("publish-add", "80:20")
+ flags.Set("publish-add", "80:80")
portConfigs := []swarm.PortConfig{
{TargetPort: 80, PublishedPort: 80},
@@ -247,21 +247,7 @@
err := updatePorts(flags, &portConfigs)
assert.Equal(t, err, nil)
assert.Equal(t, len(portConfigs), 1)
- assert.Equal(t, portConfigs[0].TargetPort, uint32(20))
-}
-
-func TestUpdatePortsConflictingFlags(t *testing.T) {
- // Test case for #25375
- flags := newUpdateCommand(nil).Flags()
- flags.Set("publish-add", "80:80")
- flags.Set("publish-add", "80:20")
-
- portConfigs := []swarm.PortConfig{
- {TargetPort: 80, PublishedPort: 80},
- }
-
- err := updatePorts(flags, &portConfigs)
- assert.Error(t, err, "conflicting port mapping")
+ assert.Equal(t, portConfigs[0].TargetPort, uint32(80))
}
func TestUpdateHealthcheckTable(t *testing.T) {
diff --git a/cli/command/stack/deploy.go b/cli/command/stack/deploy.go
index 33dd15e..683f0ca 100644
--- a/cli/command/stack/deploy.go
+++ b/cli/command/stack/deploy.go
@@ -498,12 +498,15 @@
Command: service.Entrypoint,
Args: service.Command,
Hostname: service.Hostname,
+ Hosts: convertExtraHosts(service.ExtraHosts),
Env: convertEnvironment(service.Environment),
Labels: getStackLabels(namespace.name, service.Labels),
Dir: service.WorkingDir,
User: service.User,
Mounts: mounts,
StopGracePeriod: service.StopGracePeriod,
+ TTY: service.Tty,
+ OpenStdin: service.StdinOpen,
},
Resources: resources,
RestartPolicy: restartPolicy,
@@ -520,6 +523,14 @@
return serviceSpec, nil
}
+func convertExtraHosts(extraHosts map[string]string) []string {
+ hosts := []string{}
+ for host, ip := range extraHosts {
+ hosts = append(hosts, fmt.Sprintf("%s %s", host, ip))
+ }
+ return hosts
+}
+
func convertRestartPolicy(restart string, source *composetypes.RestartPolicy) (*swarm.RestartPolicy, error) {
// TODO: log if restart is being ignored
if source == nil {
diff --git a/cli/command/system/info.go b/cli/command/system/info.go
index da5a396..b751bbf 100644
--- a/cli/command/system/info.go
+++ b/cli/command/system/info.go
@@ -2,6 +2,7 @@
import (
"fmt"
+ "sort"
"strings"
"time"
@@ -131,6 +132,17 @@
}
}
fmt.Fprintf(dockerCli.Out(), " Node Address: %s\n", info.Swarm.NodeAddr)
+ managers := []string{}
+ for _, entry := range info.Swarm.RemoteManagers {
+ managers = append(managers, entry.Addr)
+ }
+ if len(managers) > 0 {
+ sort.Strings(managers)
+ fmt.Fprintf(dockerCli.Out(), " Manager Addresses:\n")
+ for _, entry := range managers {
+ fmt.Fprintf(dockerCli.Out(), " %s\n", entry)
+ }
+ }
}
if len(info.Runtimes) > 0 {
@@ -143,6 +155,22 @@
}
if info.OSType == "linux" {
+ fmt.Fprintf(dockerCli.Out(), "Init Binary: %v\n", info.InitBinary)
+
+ for _, ci := range []struct {
+ Name string
+ Commit types.Commit
+ }{
+ {"containerd", info.ContainerdCommit},
+ {"runc", info.RuncCommit},
+ {"init", info.InitCommit},
+ } {
+ fmt.Fprintf(dockerCli.Out(), "%s version: %s", ci.Name, ci.Commit.ID)
+ if ci.Commit.ID != ci.Commit.Expected {
+ fmt.Fprintf(dockerCli.Out(), " (expected: %s)", ci.Commit.Expected)
+ }
+ fmt.Fprintf(dockerCli.Out(), "\n")
+ }
if len(info.SecurityOptions) != 0 {
fmt.Fprintf(dockerCli.Out(), "Security Options:\n")
for _, o := range info.SecurityOptions {
diff --git a/cli/command/task/print.go b/cli/command/task/print.go
index 45af178..2c5b2ee 100644
--- a/cli/command/task/print.go
+++ b/cli/command/task/print.go
@@ -17,10 +17,25 @@
)
const (
- psTaskItemFmt = "%s\t%s\t%s\t%s\t%s %s ago\t%s\n"
+ psTaskItemFmt = "%s\t%s\t%s\t%s\t%s %s ago\t%s\t%s\n"
maxErrLength = 30
)
+type portStatus swarm.PortStatus
+
+func (ps portStatus) String() string {
+ if len(ps.Ports) == 0 {
+ return ""
+ }
+
+ str := fmt.Sprintf("*:%d->%d/%s", ps.Ports[0].PublishedPort, ps.Ports[0].TargetPort, ps.Ports[0].Protocol)
+ for _, pConfig := range ps.Ports[1:] {
+ str += fmt.Sprintf(",*:%d->%d/%s", pConfig.PublishedPort, pConfig.TargetPort, pConfig.Protocol)
+ }
+
+ return str
+}
+
type tasksBySlot []swarm.Task
func (t tasksBySlot) Len() int {
@@ -51,7 +66,7 @@
// Ignore flushing errors
defer writer.Flush()
- fmt.Fprintln(writer, strings.Join([]string{"NAME", "IMAGE", "NODE", "DESIRED STATE", "CURRENT STATE", "ERROR"}, "\t"))
+ fmt.Fprintln(writer, strings.Join([]string{"NAME", "IMAGE", "NODE", "DESIRED STATE", "CURRENT STATE", "ERROR", "PORTS"}, "\t"))
if err := print(writer, ctx, tasks, resolver, noTrunc); err != nil {
return err
@@ -113,6 +128,7 @@
command.PrettyPrint(task.Status.State),
strings.ToLower(units.HumanDuration(time.Since(task.Status.Timestamp))),
taskErr,
+ portStatus(task.Status.PortStatus),
)
}
return nil
diff --git a/client/container_stats.go b/client/container_stats.go
index 3be7a98..4758c66 100644
--- a/client/container_stats.go
+++ b/client/container_stats.go
@@ -21,6 +21,6 @@
return types.ContainerStats{}, err
}
- osType := GetDockerOS(resp.header.Get("Server"))
+ osType := getDockerOS(resp.header.Get("Server"))
return types.ContainerStats{Body: resp.body, OSType: osType}, err
}
diff --git a/client/image_build.go b/client/image_build.go
index 0049e4e..6fde75d 100644
--- a/client/image_build.go
+++ b/client/image_build.go
@@ -6,7 +6,6 @@
"io"
"net/http"
"net/url"
- "regexp"
"strconv"
"golang.org/x/net/context"
@@ -15,8 +14,6 @@
"github.com/docker/docker/api/types/container"
)
-var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`)
-
// ImageBuild sends request to the daemon to build images.
// The Body in the response implement an io.ReadCloser and it's up to the caller to
// close it.
@@ -39,7 +36,7 @@
return types.ImageBuildResponse{}, err
}
- osType := GetDockerOS(serverResp.header.Get("Server"))
+ osType := getDockerOS(serverResp.header.Get("Server"))
return types.ImageBuildResponse{
Body: serverResp.body,
@@ -124,13 +121,3 @@
return query, nil
}
-
-// GetDockerOS returns the operating system based on the server header from the daemon.
-func GetDockerOS(serverHeader string) string {
- var osType string
- matches := headerRegexp.FindStringSubmatch(serverHeader)
- if len(matches) > 0 {
- osType = matches[1]
- }
- return osType
-}
diff --git a/client/image_build_test.go b/client/image_build_test.go
index 53dd933..ec0cbe2 100644
--- a/client/image_build_test.go
+++ b/client/image_build_test.go
@@ -222,7 +222,7 @@
"Foo/v1.22 (bar)": "",
}
for header, os := range cases {
- g := GetDockerOS(header)
+ g := getDockerOS(header)
if g != os {
t.Fatalf("Expected %s, got %s", os, g)
}
diff --git a/client/image_list.go b/client/image_list.go
index 6ebb460..63c71b1 100644
--- a/client/image_list.go
+++ b/client/image_list.go
@@ -21,10 +21,6 @@
}
query.Set("filters", filterJSON)
}
- if options.MatchName != "" {
- // FIXME rename this parameter, to not be confused with the filters flag
- query.Set("filter", options.MatchName)
- }
if options.All {
query.Set("all", "1")
}
diff --git a/client/image_list_test.go b/client/image_list_test.go
index 1ea6f1f..1c9406d 100644
--- a/client/image_list_test.go
+++ b/client/image_list_test.go
@@ -50,17 +50,6 @@
},
{
options: types.ImageListOptions{
- All: true,
- MatchName: "image_name",
- },
- expectedQueryParams: map[string]string{
- "all": "1",
- "filter": "image_name",
- "filters": "",
- },
- },
- {
- options: types.ImageListOptions{
Filters: filters,
},
expectedQueryParams: map[string]string{
diff --git a/client/utils.go b/client/utils.go
new file mode 100644
index 0000000..03bf4c8
--- /dev/null
+++ b/client/utils.go
@@ -0,0 +1,15 @@
+package client
+
+import "regexp"
+
+var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`)
+
+// getDockerOS returns the operating system based on the server header from the daemon.
+func getDockerOS(serverHeader string) string {
+ var osType string
+ matches := headerRegexp.FindStringSubmatch(serverHeader)
+ if len(matches) > 0 {
+ osType = matches[1]
+ }
+ return osType
+}
diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go
index 18cd0e8..1978fc3 100644
--- a/cmd/docker/docker.go
+++ b/cmd/docker/docker.go
@@ -79,7 +79,7 @@
return nil
}
return fmt.Errorf(
- "docker: '%s' is not a docker command.\nSee 'docker --help'%s", args[0], ".")
+ "docker: '%s' is not a docker command.\nSee 'docker --help'.", args[0])
}
func main() {
diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go
index a9fc2ae..866c2ec 100644
--- a/cmd/dockerd/daemon.go
+++ b/cmd/dockerd/daemon.go
@@ -6,6 +6,7 @@
"io"
"os"
"path/filepath"
+ "runtime"
"strings"
"time"
@@ -67,10 +68,15 @@
return &DaemonCli{}
}
-func migrateKey() (err error) {
+func migrateKey(config *daemon.Config) (err error) {
+ // No migration necessary on Windows
+ if runtime.GOOS == "windows" {
+ return nil
+ }
+
// Migrate trust key if exists at ~/.docker/key.json and owned by current user
oldPath := filepath.Join(cliconfig.ConfigDir(), cliflags.DefaultTrustKeyFile)
- newPath := filepath.Join(getDaemonConfDir(), cliflags.DefaultTrustKeyFile)
+ newPath := filepath.Join(getDaemonConfDir(config.Root), cliflags.DefaultTrustKeyFile)
if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) {
defer func() {
// Ensure old path is removed if no error occurred
@@ -82,7 +88,7 @@
}
}()
- if err := system.MkdirAll(getDaemonConfDir(), os.FileMode(0644)); err != nil {
+ if err := system.MkdirAll(getDaemonConfDir(config.Root), os.FileMode(0644)); err != nil {
return fmt.Errorf("Unable to create daemon configuration directory: %s", err)
}
@@ -117,17 +123,18 @@
opts.common.SetDefaultOptions(opts.flags)
- if opts.common.TrustKey == "" {
- opts.common.TrustKey = filepath.Join(
- getDaemonConfDir(),
- cliflags.DefaultTrustKeyFile)
- }
if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
return err
}
cli.configFile = &opts.configFile
cli.flags = opts.flags
+ if opts.common.TrustKey == "" {
+ opts.common.TrustKey = filepath.Join(
+ getDaemonConfDir(cli.Config.Root),
+ cliflags.DefaultTrustKeyFile)
+ }
+
if cli.Config.Debug {
utils.EnableDebug()
}
@@ -151,6 +158,12 @@
}
}
+ // Create the daemon root before we create ANY other files (PID, or migrate keys)
+ // to ensure the appropriate ACL is set (particularly relevant on Windows)
+ if err := daemon.CreateDaemonRoot(cli.Config); err != nil {
+ return err
+ }
+
if cli.Pidfile != "" {
pf, err := pidfile.New(cli.Pidfile)
if err != nil {
@@ -230,9 +243,10 @@
api.Accept(addr, ls...)
}
- if err := migrateKey(); err != nil {
+ if err := migrateKey(cli.Config); err != nil {
return err
}
+
// FIXME: why is this down here instead of with the other TrustKey logic above?
cli.TrustKeyPath = opts.common.TrustKey
diff --git a/cmd/dockerd/daemon_solaris.go b/cmd/dockerd/daemon_solaris.go
index 74dac5d..974ba16 100644
--- a/cmd/dockerd/daemon_solaris.go
+++ b/cmd/dockerd/daemon_solaris.go
@@ -38,7 +38,7 @@
return nil
}
-func getDaemonConfDir() string {
+func getDaemonConfDir(_ string) string {
return "/etc/docker"
}
diff --git a/cmd/dockerd/daemon_unix.go b/cmd/dockerd/daemon_unix.go
index 83156da..bdce98b 100644
--- a/cmd/dockerd/daemon_unix.go
+++ b/cmd/dockerd/daemon_unix.go
@@ -43,7 +43,7 @@
return nil
}
-func getDaemonConfDir() string {
+func getDaemonConfDir(_ string) string {
return "/etc/docker"
}
diff --git a/cmd/dockerd/daemon_windows.go b/cmd/dockerd/daemon_windows.go
index 39d5a87..4cccd32 100644
--- a/cmd/dockerd/daemon_windows.go
+++ b/cmd/dockerd/daemon_windows.go
@@ -4,6 +4,7 @@
"fmt"
"net"
"os"
+ "path/filepath"
"syscall"
"github.com/Sirupsen/logrus"
@@ -11,7 +12,7 @@
"github.com/docker/docker/pkg/system"
)
-var defaultDaemonConfigFile = os.Getenv("programdata") + string(os.PathSeparator) + "docker" + string(os.PathSeparator) + "config" + string(os.PathSeparator) + "daemon.json"
+var defaultDaemonConfigFile = ""
// currentUserIsOwner checks whether the current user is the owner of the given
// file.
@@ -24,8 +25,8 @@
return nil
}
-func getDaemonConfDir() string {
- return os.Getenv("PROGRAMDATA") + `\docker\config`
+func getDaemonConfDir(root string) string {
+ return filepath.Join(root, `\config`)
}
// notifySystem sends a message to the host when the server is ready to be used
diff --git a/cmd/dockerd/docker.go b/cmd/dockerd/docker.go
index 5ce495c..60742ae 100644
--- a/cmd/dockerd/docker.go
+++ b/cmd/dockerd/docker.go
@@ -62,9 +62,14 @@
daemonCli := NewDaemonCli()
- // On Windows, if there's no explicit pidfile set, set to under the daemon root
- if runtime.GOOS == "windows" && opts.daemonConfig.Pidfile == "" {
- opts.daemonConfig.Pidfile = filepath.Join(opts.daemonConfig.Root, "docker.pid")
+ // Windows specific settings as these are not defaulted.
+ if runtime.GOOS == "windows" {
+ if opts.daemonConfig.Pidfile == "" {
+ opts.daemonConfig.Pidfile = filepath.Join(opts.daemonConfig.Root, "docker.pid")
+ }
+ if opts.configFile == "" {
+ opts.configFile = filepath.Join(opts.daemonConfig.Root, `config\daemon.json`)
+ }
}
// On Windows, this may be launching as a service or with an option to
diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker
index 46edab7..1ff570a 100644
--- a/contrib/completion/bash/docker
+++ b/contrib/completion/bash/docker
@@ -1704,6 +1704,7 @@
--oom-score-adjust
--pidfile -p
--registry-mirror
+ --seccomp-profile
--shutdown-timeout
--storage-driver -s
--storage-opt
@@ -1816,6 +1817,10 @@
__docker_complete_log_options
return
;;
+ --seccomp-profile)
+ _filedir json
+ return
+ ;;
--userns-remap)
__docker_complete_user_group
return
diff --git a/daemon/cluster/convert/container.go b/daemon/cluster/convert/container.go
index ebd80d0..eb1a84c 100644
--- a/daemon/cluster/convert/container.go
+++ b/daemon/cluster/convert/container.go
@@ -14,18 +14,19 @@
func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec {
containerSpec := types.ContainerSpec{
- Image: c.Image,
- Labels: c.Labels,
- Command: c.Command,
- Args: c.Args,
- Hostname: c.Hostname,
- Env: c.Env,
- Dir: c.Dir,
- User: c.User,
- Groups: c.Groups,
- TTY: c.TTY,
- Hosts: c.Hosts,
- Secrets: secretReferencesFromGRPC(c.Secrets),
+ Image: c.Image,
+ Labels: c.Labels,
+ Command: c.Command,
+ Args: c.Args,
+ Hostname: c.Hostname,
+ Env: c.Env,
+ Dir: c.Dir,
+ User: c.User,
+ Groups: c.Groups,
+ TTY: c.TTY,
+ OpenStdin: c.OpenStdin,
+ Hosts: c.Hosts,
+ Secrets: secretReferencesFromGRPC(c.Secrets),
}
if c.DNSConfig != nil {
@@ -123,18 +124,19 @@
func containerToGRPC(c types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
containerSpec := &swarmapi.ContainerSpec{
- Image: c.Image,
- Labels: c.Labels,
- Command: c.Command,
- Args: c.Args,
- Hostname: c.Hostname,
- Env: c.Env,
- Dir: c.Dir,
- User: c.User,
- Groups: c.Groups,
- TTY: c.TTY,
- Hosts: c.Hosts,
- Secrets: secretReferencesToGRPC(c.Secrets),
+ Image: c.Image,
+ Labels: c.Labels,
+ Command: c.Command,
+ Args: c.Args,
+ Hostname: c.Hostname,
+ Env: c.Env,
+ Dir: c.Dir,
+ User: c.User,
+ Groups: c.Groups,
+ TTY: c.TTY,
+ OpenStdin: c.OpenStdin,
+ Hosts: c.Hosts,
+ Secrets: secretReferencesToGRPC(c.Secrets),
}
if c.DNSConfig != nil {
diff --git a/daemon/cluster/convert/network.go b/daemon/cluster/convert/network.go
index f643f62..1d9877f 100644
--- a/daemon/cluster/convert/network.go
+++ b/daemon/cluster/convert/network.go
@@ -93,6 +93,7 @@
endpointSpec.Ports = append(endpointSpec.Ports, types.PortConfig{
Name: portState.Name,
Protocol: types.PortConfigProtocol(strings.ToLower(swarmapi.PortConfig_Protocol_name[int32(portState.Protocol)])),
+ PublishMode: types.PortConfigPublishMode(strings.ToLower(swarmapi.PortConfig_PublishMode_name[int32(portState.PublishMode)])),
TargetPort: portState.TargetPort,
PublishedPort: portState.PublishedPort,
})
@@ -112,6 +113,7 @@
endpoint.Ports = append(endpoint.Ports, types.PortConfig{
Name: portState.Name,
Protocol: types.PortConfigProtocol(strings.ToLower(swarmapi.PortConfig_Protocol_name[int32(portState.Protocol)])),
+ PublishMode: types.PortConfigPublishMode(strings.ToLower(swarmapi.PortConfig_PublishMode_name[int32(portState.PublishMode)])),
TargetPort: portState.TargetPort,
PublishedPort: portState.PublishedPort,
})
diff --git a/daemon/cluster/convert/service.go b/daemon/cluster/convert/service.go
index 35718ee..aa68e01 100644
--- a/daemon/cluster/convert/service.go
+++ b/daemon/cluster/convert/service.go
@@ -199,6 +199,7 @@
spec.Endpoint.Ports = append(spec.Endpoint.Ports, &swarmapi.PortConfig{
Name: portConfig.Name,
Protocol: swarmapi.PortConfig_Protocol(swarmapi.PortConfig_Protocol_value[strings.ToUpper(string(portConfig.Protocol))]),
+ PublishMode: swarmapi.PortConfig_PublishMode(swarmapi.PortConfig_PublishMode_value[strings.ToUpper(string(portConfig.PublishMode))]),
TargetPort: portConfig.TargetPort,
PublishedPort: portConfig.PublishedPort,
})
diff --git a/daemon/cluster/convert/task.go b/daemon/cluster/convert/task.go
index 5f3c347..d0cf89c 100644
--- a/daemon/cluster/convert/task.go
+++ b/daemon/cluster/convert/task.go
@@ -63,5 +63,19 @@
task.NetworksAttachments = append(task.NetworksAttachments, networkAttachementFromGRPC(na))
}
+ if t.Status.PortStatus == nil {
+ return task
+ }
+
+ for _, p := range t.Status.PortStatus.Ports {
+ task.Status.PortStatus.Ports = append(task.Status.PortStatus.Ports, types.PortConfig{
+ Name: p.Name,
+ Protocol: types.PortConfigProtocol(strings.ToLower(swarmapi.PortConfig_Protocol_name[int32(p.Protocol)])),
+ PublishMode: types.PortConfigPublishMode(strings.ToLower(swarmapi.PortConfig_PublishMode_name[int32(p.PublishMode)])),
+ TargetPort: p.TargetPort,
+ PublishedPort: p.PublishedPort,
+ })
+ }
+
return task
}
diff --git a/daemon/cluster/executor/backend.go b/daemon/cluster/executor/backend.go
index d0c8af6..e7c058b 100644
--- a/daemon/cluster/executor/backend.go
+++ b/daemon/cluster/executor/backend.go
@@ -50,4 +50,5 @@
UpdateAttachment(string, string, string, *network.NetworkingConfig) error
WaitForDetachment(context.Context, string, string, string, string) error
GetRepository(context.Context, reference.NamedTagged, *types.AuthConfig) (distribution.Repository, bool, error)
+ LookupImage(name string) (*types.ImageInspect, error)
}
diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go
index 29e6d0b..a61ad35 100644
--- a/daemon/cluster/executor/container/adapter.go
+++ b/daemon/cluster/executor/container/adapter.go
@@ -17,6 +17,7 @@
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/versions"
executorpkg "github.com/docker/docker/daemon/cluster/executor"
+ "github.com/docker/docker/reference"
"github.com/docker/libnetwork"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
@@ -51,6 +52,18 @@
func (c *containerAdapter) pullImage(ctx context.Context) error {
spec := c.container.spec()
+ // Skip pulling if the image is referenced by digest and already
+ // exists locally.
+ named, err := reference.ParseNamed(spec.Image)
+ if err == nil {
+ if _, ok := named.(reference.Canonical); ok {
+ _, err := c.backend.LookupImage(spec.Image)
+ if err == nil {
+ return nil
+ }
+ }
+ }
+
// if the image needs to be pulled, the auth config will be retrieved and updated
var encodedAuthConfig string
if spec.PullOptions != nil {
diff --git a/daemon/cluster/executor/container/container.go b/daemon/cluster/executor/container/container.go
index 6cc21ab..88a80e4 100644
--- a/daemon/cluster/executor/container/container.go
+++ b/daemon/cluster/executor/container/container.go
@@ -4,6 +4,7 @@
"errors"
"fmt"
"net"
+ "strconv"
"strings"
"time"
@@ -17,6 +18,7 @@
volumetypes "github.com/docker/docker/api/types/volume"
clustertypes "github.com/docker/docker/daemon/cluster/provider"
"github.com/docker/docker/reference"
+ "github.com/docker/go-connections/nat"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/protobuf/ptypes"
@@ -136,17 +138,62 @@
return reference.WithDefaultTag(ref).String()
}
+func (c *containerConfig) portBindings() nat.PortMap {
+ portBindings := nat.PortMap{}
+ if c.task.Endpoint == nil {
+ return portBindings
+ }
+
+ for _, portConfig := range c.task.Endpoint.Ports {
+ if portConfig.PublishMode != api.PublishModeHost {
+ continue
+ }
+
+ port := nat.Port(fmt.Sprintf("%d/%s", portConfig.TargetPort, strings.ToLower(portConfig.Protocol.String())))
+ binding := []nat.PortBinding{
+ {},
+ }
+
+ if portConfig.PublishedPort != 0 {
+ binding[0].HostPort = strconv.Itoa(int(portConfig.PublishedPort))
+ }
+ portBindings[port] = binding
+ }
+
+ return portBindings
+}
+
+func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
+ exposedPorts := make(map[nat.Port]struct{})
+ if c.task.Endpoint == nil {
+ return exposedPorts
+ }
+
+ for _, portConfig := range c.task.Endpoint.Ports {
+ if portConfig.PublishMode != api.PublishModeHost {
+ continue
+ }
+
+ port := nat.Port(fmt.Sprintf("%d/%s", portConfig.TargetPort, strings.ToLower(portConfig.Protocol.String())))
+ exposedPorts[port] = struct{}{}
+ }
+
+ return exposedPorts
+}
+
func (c *containerConfig) config() *enginecontainer.Config {
config := &enginecontainer.Config{
- Labels: c.labels(),
- Tty: c.spec().TTY,
- User: c.spec().User,
- Env: c.spec().Env,
- Hostname: c.spec().Hostname,
- WorkingDir: c.spec().Dir,
- Image: c.image(),
- Volumes: c.volumes(),
- Healthcheck: c.healthcheck(),
+ Labels: c.labels(),
+ Tty: c.spec().TTY,
+ OpenStdin: c.spec().OpenStdin,
+ User: c.spec().User,
+ Env: c.spec().Env,
+ Hostname: c.spec().Hostname,
+ WorkingDir: c.spec().Dir,
+ Image: c.image(),
+ Volumes: c.volumes(),
+ ExposedPorts: c.exposedPorts(),
+ Healthcheck: c.healthcheck(),
}
if len(c.spec().Command) > 0 {
@@ -333,10 +380,11 @@
func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
hc := &enginecontainer.HostConfig{
- Resources: c.resources(),
- Binds: c.binds(),
- Tmpfs: c.tmpfs(),
- GroupAdd: c.spec().Groups,
+ Resources: c.resources(),
+ Binds: c.binds(),
+ Tmpfs: c.tmpfs(),
+ GroupAdd: c.spec().Groups,
+ PortBindings: c.portBindings(),
}
if c.spec().DNSConfig != nil {
@@ -525,6 +573,10 @@
if c.task.Endpoint != nil {
for _, ePort := range c.task.Endpoint.Ports {
+ if ePort.PublishMode != api.PublishModeIngress {
+ continue
+ }
+
svcCfg.ExposedPorts = append(svcCfg.ExposedPorts, &clustertypes.PortConfig{
Name: ePort.Name,
Protocol: int32(ePort.Protocol),
diff --git a/daemon/cluster/executor/container/controller.go b/daemon/cluster/executor/container/controller.go
index 103f47e..75f286a 100644
--- a/daemon/cluster/executor/container/controller.go
+++ b/daemon/cluster/executor/container/controller.go
@@ -7,11 +7,14 @@
"fmt"
"io"
"os"
+ "strconv"
+ "strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
executorpkg "github.com/docker/docker/daemon/cluster/executor"
+ "github.com/docker/go-connections/nat"
"github.com/docker/libnetwork"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
@@ -69,6 +72,19 @@
return parseContainerStatus(ctnr)
}
+func (r *controller) PortStatus(ctx context.Context) (*api.PortStatus, error) {
+ ctnr, err := r.adapter.inspect(ctx)
+ if err != nil {
+ if isUnknownContainer(err) {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ return parsePortStatus(ctnr)
+}
+
// Update tasks a recent task update and applies it to the container.
func (r *controller) Update(ctx context.Context, t *api.Task) error {
// TODO(stevvooe): While assignment of tasks is idempotent, we do allow
@@ -553,6 +569,64 @@
return status, nil
}
+func parsePortStatus(ctnr types.ContainerJSON) (*api.PortStatus, error) {
+ status := &api.PortStatus{}
+
+ if ctnr.NetworkSettings != nil && len(ctnr.NetworkSettings.Ports) > 0 {
+ exposedPorts, err := parsePortMap(ctnr.NetworkSettings.Ports)
+ if err != nil {
+ return nil, err
+ }
+ status.Ports = exposedPorts
+ }
+
+ return status, nil
+}
+
+func parsePortMap(portMap nat.PortMap) ([]*api.PortConfig, error) {
+ exposedPorts := make([]*api.PortConfig, 0, len(portMap))
+
+ for portProtocol, mapping := range portMap {
+ parts := strings.SplitN(string(portProtocol), "/", 2)
+ if len(parts) != 2 {
+ return nil, fmt.Errorf("invalid port mapping: %s", portProtocol)
+ }
+
+ port, err := strconv.ParseUint(parts[0], 10, 16)
+ if err != nil {
+ return nil, err
+ }
+
+ protocol := api.ProtocolTCP
+ switch strings.ToLower(parts[1]) {
+ case "tcp":
+ protocol = api.ProtocolTCP
+ case "udp":
+ protocol = api.ProtocolUDP
+ default:
+ return nil, fmt.Errorf("invalid protocol: %s", parts[1])
+ }
+
+ for _, binding := range mapping {
+ hostPort, err := strconv.ParseUint(binding.HostPort, 10, 16)
+ if err != nil {
+ return nil, err
+ }
+
+ // TODO(aluzzardi): We're losing the port `name` here since
+ // there's no way to retrieve it back from the Engine.
+ exposedPorts = append(exposedPorts, &api.PortConfig{
+ PublishMode: api.PublishModeHost,
+ Protocol: protocol,
+ TargetPort: uint32(port),
+ PublishedPort: uint32(hostPort),
+ })
+ }
+ }
+
+ return exposedPorts, nil
+}
+
type exitError struct {
code int
cause error
diff --git a/daemon/commit.go b/daemon/commit.go
index d11f011..85d512a 100644
--- a/daemon/commit.go
+++ b/daemon/commit.go
@@ -226,6 +226,7 @@
}
}
+ imageRef := ""
if c.Repo != "" {
newTag, err := reference.WithName(c.Repo) // todo: should move this to API layer
if err != nil {
@@ -239,10 +240,13 @@
if err := daemon.TagImageWithReference(id, newTag); err != nil {
return "", err
}
+ imageRef = newTag.String()
}
attributes := map[string]string{
"comment": c.Comment,
+ "imageID": id.String(),
+ "imageRef": imageRef,
}
daemon.LogContainerEventWithAttributes(container, "commit", attributes)
containerActions.WithValues("commit").UpdateSince(start)
diff --git a/daemon/config_common_unix.go b/daemon/config_common_unix.go
index e03a4f7..ab76fe7 100644
--- a/daemon/config_common_unix.go
+++ b/daemon/config_common_unix.go
@@ -78,3 +78,13 @@
func (config *Config) GetExecRoot() string {
return config.ExecRoot
}
+
+// GetInitPath returns the configure docker-init path
+func (config *Config) GetInitPath() string {
+ config.reloadLock.Lock()
+ defer config.reloadLock.Unlock()
+ if config.InitPath != "" {
+ return config.InitPath
+ }
+ return DefaultInitBinary
+}
diff --git a/daemon/config_windows.go b/daemon/config_windows.go
index 1219dbd..df59dcf 100644
--- a/daemon/config_windows.go
+++ b/daemon/config_windows.go
@@ -46,6 +46,11 @@
return nil
}
+// GetInitPath returns the configure docker-init path
+func (config *Config) GetInitPath() string {
+ return ""
+}
+
// GetDefaultRuntimeName returns the current default runtime
func (config *Config) GetDefaultRuntimeName() string {
return stockRuntimeName
diff --git a/daemon/daemon.go b/daemon/daemon.go
index c9c29e8..44b41be 100644
--- a/daemon/daemon.go
+++ b/daemon/daemon.go
@@ -67,6 +67,9 @@
// containerd if none is specified
DefaultRuntimeBinary = "docker-runc"
+ // DefaultInitBinary is the name of the default init binary
+ DefaultInitBinary = "docker-init"
+
errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
)
@@ -489,21 +492,6 @@
return nil, err
}
- // get the canonical path to the Docker root directory
- var realRoot string
- if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
- realRoot = config.Root
- } else {
- realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
- if err != nil {
- return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
- }
- }
-
- if err := setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
- return nil, err
- }
-
if err := setupDaemonProcess(config); err != nil {
return nil, err
}
@@ -552,7 +540,7 @@
}
if runtime.GOOS == "windows" {
- if err := idtools.MkdirAllAs(filepath.Join(config.Root, "credentialspecs"), 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
+ if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil && !os.IsExist(err) {
return nil, err
}
}
@@ -1281,3 +1269,32 @@
manager.Shutdown()
}
}
+
+// CreateDaemonRoot creates the root for the daemon
+func CreateDaemonRoot(config *Config) error {
+ // get the canonical path to the Docker root directory
+ var realRoot string
+ if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
+ realRoot = config.Root
+ } else {
+ realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
+ if err != nil {
+ return fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
+ }
+ }
+
+ uidMaps, gidMaps, err := setupRemappedRoot(config)
+ if err != nil {
+ return err
+ }
+ rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
+ return err
+ }
+
+ if err := setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go
index 8931f28..2620fc4 100644
--- a/daemon/daemon_windows.go
+++ b/daemon/daemon_windows.go
@@ -432,7 +432,7 @@
func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
config.Root = rootDir
// Create the root directory if it doesn't exists
- if err := system.MkdirAll(config.Root, 0700); err != nil && !os.IsExist(err) {
+ if err := system.MkdirAllWithACL(config.Root, 0); err != nil && !os.IsExist(err) {
return err
}
return nil
diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go
index 53b6a8a..c3b9186 100644
--- a/daemon/disk_usage.go
+++ b/daemon/disk_usage.go
@@ -6,6 +6,7 @@
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/digest"
"github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/directory"
"github.com/docker/docker/volume"
@@ -44,7 +45,7 @@
}
// Get all top images with extra attributes
- allImages, err := daemon.Images("", "", false, true)
+ allImages, err := daemon.Images(filters.NewArgs(), false, true)
if err != nil {
return nil, fmt.Errorf("failed to retrieve image list: %v", err)
}
diff --git a/daemon/image_pull.go b/daemon/image_pull.go
index f0b8f55..7dc1a2d 100644
--- a/daemon/image_pull.go
+++ b/daemon/image_pull.go
@@ -33,7 +33,7 @@
var dgst digest.Digest
dgst, err = digest.ParseDigest(tag)
if err == nil {
- ref, err = reference.WithDigest(ref, dgst)
+ ref, err = reference.WithDigest(reference.TrimNamed(ref), dgst)
} else {
ref, err = reference.WithTag(ref, tag)
}
diff --git a/daemon/images.go b/daemon/images.go
index a011d31..25fad4c 100644
--- a/daemon/images.go
+++ b/daemon/images.go
@@ -3,25 +3,25 @@
import (
"encoding/json"
"fmt"
- "path"
"sort"
"time"
"github.com/pkg/errors"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
- "github.com/docker/docker/reference"
)
var acceptedImageFilterTags = map[string]bool{
- "dangling": true,
- "label": true,
- "before": true,
- "since": true,
+ "dangling": true,
+ "label": true,
+ "before": true,
+ "since": true,
+ "reference": true,
}
// byCreated is a temporary type used to sort a list of images by creation
@@ -42,17 +42,13 @@
// filter is a shell glob string applied to repository names. The argument
// named all controls whether all images in the graph are filtered, or just
// the heads.
-func (daemon *Daemon) Images(filterArgs, filter string, all bool, withExtraAttrs bool) ([]*types.ImageSummary, error) {
+func (daemon *Daemon) Images(imageFilters filters.Args, all bool, withExtraAttrs bool) ([]*types.ImageSummary, error) {
var (
allImages map[image.ID]*image.Image
err error
danglingOnly = false
)
- imageFilters, err := filters.FromParam(filterArgs)
- if err != nil {
- return nil, err
- }
if err := imageFilters.Validate(acceptedImageFilterTags); err != nil {
return nil, err
}
@@ -93,16 +89,6 @@
var allLayers map[layer.ChainID]layer.Layer
var allContainers []*container.Container
- var filterTagged bool
- if filter != "" {
- filterRef, err := reference.ParseNamed(filter)
- if err == nil { // parse error means wildcard repo
- if _, ok := filterRef.(reference.NamedTagged); ok {
- filterTagged = true
- }
- }
- }
-
for id, img := range allImages {
if beforeFilter != nil {
if img.Created.Equal(beforeFilter.Created) || img.Created.After(beforeFilter.Created) {
@@ -145,12 +131,16 @@
newImage := newImage(img, size)
for _, ref := range daemon.referenceStore.References(id.Digest()) {
- if filter != "" { // filter by tag/repo name
- if filterTagged { // filter by tag, require full ref match
- if ref.String() != filter {
- continue
+ if imageFilters.Include("reference") {
+ var found bool
+ var matchErr error
+ for _, pattern := range imageFilters.Get("reference") {
+ found, matchErr = reference.Match(pattern, ref)
+ if matchErr != nil {
+ return nil, matchErr
}
- } else if matched, err := path.Match(filter, ref.Name()); !matched || err != nil { // name only match, FIXME: docs say exact
+ }
+ if !found {
continue
}
}
@@ -168,7 +158,7 @@
//dangling=false case, so dangling image is not needed
continue
}
- if filter != "" { // skip images with no references if filtering by tag
+ if imageFilters.Include("reference") { // skip images with no references if filtering by reference
continue
}
newImage.RepoDigests = []string{"<none>@<none>"}
diff --git a/daemon/info.go b/daemon/info.go
index 7baeedc..474ff52 100644
--- a/daemon/info.go
+++ b/daemon/info.go
@@ -1,8 +1,11 @@
package daemon
import (
+ "context"
"os"
+ "os/exec"
"runtime"
+ "strings"
"sync/atomic"
"time"
@@ -147,6 +150,47 @@
v.CPUSet = sysInfo.Cpuset
v.Runtimes = daemon.configStore.GetAllRuntimes()
v.DefaultRuntime = daemon.configStore.GetDefaultRuntimeName()
+ v.InitBinary = daemon.configStore.GetInitPath()
+
+ v.ContainerdCommit.Expected = dockerversion.ContainerdCommitID
+ if sv, err := daemon.containerd.GetServerVersion(context.Background()); err == nil {
+ v.ContainerdCommit.ID = sv.Revision
+ } else {
+ logrus.Warnf("failed to retrieve containerd version: %v", err)
+ v.ContainerdCommit.ID = "N/A"
+ }
+
+ v.RuncCommit.Expected = dockerversion.RuncCommitID
+ if rv, err := exec.Command(DefaultRuntimeBinary, "--version").Output(); err == nil {
+ parts := strings.Split(strings.TrimSpace(string(rv)), "\n")
+ if len(parts) == 3 {
+ parts = strings.Split(parts[1], ": ")
+ if len(parts) == 2 {
+ v.RuncCommit.ID = strings.TrimSpace(parts[1])
+ }
+ }
+ } else {
+ logrus.Warnf("failed to retrieve %s version: %v", DefaultRuntimeBinary, err)
+ v.RuncCommit.ID = "N/A"
+ }
+ if v.RuncCommit.ID == "" {
+ logrus.Warnf("failed to retrieve %s version: unknown output format", DefaultRuntimeBinary)
+ v.RuncCommit.ID = "N/A"
+ }
+
+ v.InitCommit.Expected = dockerversion.InitCommitID
+ if rv, err := exec.Command(DefaultInitBinary, "--version").Output(); err == nil {
+ parts := strings.Split(string(rv), " ")
+ if len(parts) == 3 {
+ v.InitCommit.ID = strings.TrimSpace(parts[2])
+ } else {
+ logrus.Warnf("failed to retrieve %s version: unknown output format", DefaultInitBinary)
+ v.InitCommit.ID = "N/A"
+ }
+ } else {
+ logrus.Warnf("failed to retrieve %s version", DefaultInitBinary)
+ v.InitCommit.ID = "N/A"
+ }
}
hostname := ""
diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go
index 3ce21df..5a2158c 100644
--- a/daemon/oci_linux.go
+++ b/daemon/oci_linux.go
@@ -596,7 +596,7 @@
s.Process.Args = append([]string{"/dev/init", c.Path}, c.Args...)
var path string
if daemon.configStore.InitPath == "" && c.HostConfig.InitPath == "" {
- path, err = exec.LookPath("docker-init")
+ path, err = exec.LookPath(DefaultInitBinary)
if err != nil {
return err
}
diff --git a/distribution/errors.go b/distribution/errors.go
index 1e7630e..ed8c3c0 100644
--- a/distribution/errors.go
+++ b/distribution/errors.go
@@ -5,11 +5,14 @@
"strings"
"syscall"
+ "github.com/Sirupsen/logrus"
"github.com/docker/distribution/registry/api/errcode"
"github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/client"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/docker/distribution/xfer"
+ "github.com/docker/docker/reference"
+ "github.com/pkg/errors"
)
// ErrNoSupport is an error type used for errors indicating that an operation
@@ -56,6 +59,37 @@
return false
}
+func translatePullError(err error, ref reference.Named) error {
+ switch v := err.(type) {
+ case errcode.Errors:
+ if len(v) != 0 {
+ for _, extra := range v[1:] {
+ logrus.Infof("Ignoring extra error returned from registry: %v", extra)
+ }
+ return translatePullError(v[0], ref)
+ }
+ case errcode.Error:
+ var newErr error
+ switch v.Code {
+ case errcode.ErrorCodeDenied:
+ // ErrorCodeDenied is used when access to the repository was denied
+ newErr = errors.Errorf("repository %s not found: does not exist or no read access", ref.Name())
+ case v2.ErrorCodeManifestUnknown:
+ newErr = errors.Errorf("manifest for %s not found", ref.String())
+ case v2.ErrorCodeNameUnknown:
+ newErr = errors.Errorf("repository %s not found", ref.Name())
+ }
+ if newErr != nil {
+ logrus.Infof("Translating %q to %q", err, newErr)
+ return newErr
+ }
+ case xfer.DoNotRetry:
+ return translatePullError(v.Err, ref)
+ }
+
+ return err
+}
+
// continueOnError returns true if we should fallback to the next endpoint
// as a result of this error.
func continueOnError(err error) bool {
diff --git a/distribution/pull.go b/distribution/pull.go
index ea630f0..5307d4c 100644
--- a/distribution/pull.go
+++ b/distribution/pull.go
@@ -168,7 +168,7 @@
continue
}
logrus.Errorf("Not continuing with pull after error: %v", err)
- return err
+ return translatePullError(err, ref)
}
imagePullConfig.ImageEventLogger(ref.String(), repoInfo.Name(), "pull")
@@ -179,7 +179,7 @@
lastErr = fmt.Errorf("no endpoints found for %s", ref.String())
}
- return lastErr
+ return translatePullError(lastErr, ref)
}
// writeStatus writes a status message to out. If layersDownloaded is true, the
@@ -206,7 +206,7 @@
}
func addDigestReference(store reference.Store, ref reference.Named, dgst digest.Digest, id digest.Digest) error {
- dgstRef, err := reference.WithDigest(ref, dgst)
+ dgstRef, err := reference.WithDigest(reference.TrimNamed(ref), dgst)
if err != nil {
return err
}
diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go
index 3a2015a..d62200d 100644
--- a/distribution/pull_v2.go
+++ b/distribution/pull_v2.go
@@ -671,7 +671,7 @@
return "", "", err
}
- manifestRef, err := reference.WithDigest(ref, manifestDigest)
+ manifestRef, err := reference.WithDigest(reference.TrimNamed(ref), manifestDigest)
if err != nil {
return "", "", err
}
diff --git a/distribution/push_v2.go b/distribution/push_v2.go
index 2362f1f..f2a1f02 100644
--- a/distribution/push_v2.go
+++ b/distribution/push_v2.go
@@ -331,7 +331,7 @@
continue
}
- canonicalRef, err := distreference.WithDigest(remoteRef, mountCandidate.Digest)
+ canonicalRef, err := distreference.WithDigest(distreference.TrimNamed(remoteRef), mountCandidate.Digest)
if err != nil {
logrus.Errorf("failed to make canonical reference: %v", err)
continue
diff --git a/docs/deprecated.md b/docs/deprecated.md
index c7d3611..3386b46 100644
--- a/docs/deprecated.md
+++ b/docs/deprecated.md
@@ -20,29 +20,61 @@
To learn more about Docker Engine's deprecation policy,
see [Feature Deprecation Policy](https://docs.docker.com/engine/#feature-deprecation-policy).
+## `filter` param for `/images/json` endpoint
+**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/tag/v1.13.0)**
+
+**Target For Removal In Release: v1.16**
+
+The `filter` param to filter the list of image by reference (name or name:tag) is now implemented as a regular filter, named `reference`.
### `repository:shortid` image references
-**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/)**
+**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/tag/v1.13.0)**
**Target For Removal In Release: v1.16**
`repository:shortid` syntax for referencing images is very little used, collides with with tag references can be confused with digest references.
### `docker daemon` subcommand
-**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/)**
+**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/tag/v1.13.0)**
**Target For Removal In Release: v1.16**
The daemon is moved to a separate binary (`dockerd`), and should be used instead.
### Duplicate keys with conflicting values in engine labels
-**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/)**
+**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/tag/v1.13.0)**
**Target For Removal In Release: v1.16**
Duplicate keys with conflicting values have been deprecated. A warning is displayed
in the output, and an error will be returned in the future.
+### `MAINTAINER` in Dockerfile
+**Deprecated In Release: v1.13.0**
+
+`MAINTAINER` was an early very limited form of `LABEL` which should be used instead.
+
+### API calls without a version
+**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/)**
+
+**Target For Removal In Release: v1.16**
+
+API versions should be supplied to all API calls to ensure compatibility with
+future Engine versions. Instead of just requesting, for example, the URL
+`/containers/json`, you must now request `/v1.25/containers/json`.
+
+### Backing filesystem without `d_type` support for overlay/overlay2
+**Deprecated In Release: v1.13.0**
+
+**Target For Removal In Release: v1.16**
+
+The overlay and overlay2 storage driver does not work as expected if the backing
+filesystem does not support `d_type`. For example, XFS does not support `d_type`
+if it is formatted with the `ftype=0` option.
+
+Please also refer to [#27358](https://github.com/docker/docker/issues/27358) for
+futher information.
+
### Three argument form in `docker import`
**Deprecated In Release: [v0.6.7](https://github.com/docker/docker/releases/tag/v0.6.7)**
@@ -221,17 +253,3 @@
- DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE is now named DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE
- DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE is now named DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE
-
-### `MAINTAINER` in Dockerfile
-**Deprecated In Release: v1.13.0**
-
-`MAINTAINER` was an early very limited form of `LABEL` which should be used instead.
-
-### API calls without a version
-**Deprecated In Release: [v1.13](https://github.com/docker/docker/releases/)**
-
-**Target For Removal In Release: v1.16**
-
-API versions should be supplied to all API calls to ensure compatibility with
-future Engine versions. Instead of just requesting, for example, the URL
-`/containers/json`, you must now request `/v1.25/containers/json`.
diff --git a/docs/reference/api/docker_remote_api_v1.25.md b/docs/reference/api/docker_remote_api_v1.25.md
index a3b0268..6e0e153 100644
--- a/docs/reference/api/docker_remote_api_v1.25.md
+++ b/docs/reference/api/docker_remote_api_v1.25.md
@@ -1733,7 +1733,7 @@
- `label=key` or `label="key=value"` of an image label
- `before`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
- `since`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
-- **filter** - only return images with the specified name
+ - `reference`=(`<image-name>[:<tag>]`)
### Build image from a Dockerfile
diff --git a/docs/reference/commandline/stack_deploy.md b/docs/reference/commandline/stack_deploy.md
index 8b0a4db..93784a3 100644
--- a/docs/reference/commandline/stack_deploy.md
+++ b/docs/reference/commandline/stack_deploy.md
@@ -25,8 +25,9 @@
deploy, up
Options:
- --file string Path to a Distributed Application Bundle file (Default: STACK.dab)
- --help Print usage
+ --file string Path to a Distributed Application Bundle file (Default: STACK.dab)
+ --help Print usage
+ --with-registry-auth Send registry authentication details to swarm agents
```
Create and update a stack from a `dab` file on the swarm. This command
diff --git a/hack/dockerfile/binaries-commits b/hack/dockerfile/binaries-commits
new file mode 100644
index 0000000..4d118e3
--- /dev/null
+++ b/hack/dockerfile/binaries-commits
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
+RUNC_COMMIT=ac031b5bf1cc92239461125f4c1ffb760522bbf2
+CONTAINERD_COMMIT=8517738ba4b82aff5662c97ca4627e7e4d03b531
+TINI_COMMIT=v0.13.0
+LIBNETWORK_COMMIT=0f534354b813003a754606689722fe253101bc4e
+VNDR_COMMIT=f56bd4504b4fad07a357913687fb652ee54bb3b0
diff --git a/hack/dockerfile/install-binaries.sh b/hack/dockerfile/install-binaries.sh
index 0a29536..bd4c63c 100755
--- a/hack/dockerfile/install-binaries.sh
+++ b/hack/dockerfile/install-binaries.sh
@@ -2,12 +2,7 @@
set -e
set -x
-TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
-RUNC_COMMIT=ac031b5bf1cc92239461125f4c1ffb760522bbf2
-CONTAINERD_COMMIT=8517738ba4b82aff5662c97ca4627e7e4d03b531
-TINI_COMMIT=v0.13.0
-LIBNETWORK_COMMIT=0f534354b813003a754606689722fe253101bc4e
-VNDR_COMMIT=f56bd4504b4fad07a357913687fb652ee54bb3b0
+. $(dirname "$0")/binaries-commits
RM_GOPATH=0
diff --git a/hack/make/.go-autogen b/hack/make/.go-autogen
index 582cd7c..e954778 100644
--- a/hack/make/.go-autogen
+++ b/hack/make/.go-autogen
@@ -2,6 +2,8 @@
rm -rf autogen
+source hack/dockerfile/binaries-commits
+
cat > dockerversion/version_autogen.go <<DVEOF
// +build autogen
@@ -11,12 +13,16 @@
// Default build-time variable for library-import.
// This file is overridden on build with build-time informations.
const (
- GitCommit string = "$GITCOMMIT"
- Version string = "$VERSION"
- BuildTime string = "$BUILDTIME"
- IAmStatic string = "${IAMSTATIC:-true}"
+ GitCommit string = "$GITCOMMIT"
+ Version string = "$VERSION"
+ BuildTime string = "$BUILDTIME"
+ IAmStatic string = "${IAMSTATIC:-true}"
+ ContainerdCommitID string = "${CONTAINERD_COMMIT}"
+ RuncCommitID string = "${RUNC_COMMIT}"
+ InitCommitID string = "${TINI_COMMIT}"
)
-// AUTOGENERATED FILE; see $BASH_SOURCE
+
+// AUTOGENERATED FILE; see /go/src/github.com/docker/docker/hack/make/.go-autogen
DVEOF
# Compile the Windows resources into the sources
diff --git a/integration-cli/docker_cli_by_digest_test.go b/integration-cli/docker_cli_by_digest_test.go
index a04b049..c2d8546 100644
--- a/integration-cli/docker_cli_by_digest_test.go
+++ b/integration-cli/docker_cli_by_digest_test.go
@@ -114,7 +114,7 @@
imageReference := fmt.Sprintf("%s@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", repoName)
out, _, err := dockerCmdWithError("pull", imageReference)
c.Assert(err, checker.NotNil, check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
- c.Assert(out, checker.Contains, "manifest unknown", check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
+ c.Assert(out, checker.Contains, fmt.Sprintf("manifest for %s not found", imageReference), check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
}
func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go
index 450c725..62ce7e2 100644
--- a/integration-cli/docker_cli_info_test.go
+++ b/integration-cli/docker_cli_info_test.go
@@ -36,7 +36,7 @@
}
if daemonPlatform == "linux" {
- stringsToCheck = append(stringsToCheck, "Security Options:")
+ stringsToCheck = append(stringsToCheck, "Init Binary:", "Security Options:", "containerd version:", "runc version:", "init version:")
}
if DaemonIsLinux.Condition() {
diff --git a/integration-cli/docker_cli_pull_test.go b/integration-cli/docker_cli_pull_test.go
index 8a86cd3..c89adae 100644
--- a/integration-cli/docker_cli_pull_test.go
+++ b/integration-cli/docker_cli_pull_test.go
@@ -48,12 +48,12 @@
}
entries := []entry{
- {"library/asdfasdf", "asdfasdf", "foobar"},
- {"library/asdfasdf", "library/asdfasdf", "foobar"},
- {"library/asdfasdf", "asdfasdf", ""},
- {"library/asdfasdf", "asdfasdf", "latest"},
- {"library/asdfasdf", "library/asdfasdf", ""},
- {"library/asdfasdf", "library/asdfasdf", "latest"},
+ {"asdfasdf", "asdfasdf", "foobar"},
+ {"asdfasdf", "library/asdfasdf", "foobar"},
+ {"asdfasdf", "asdfasdf", ""},
+ {"asdfasdf", "asdfasdf", "latest"},
+ {"asdfasdf", "library/asdfasdf", ""},
+ {"asdfasdf", "library/asdfasdf", "latest"},
}
// The option field indicates "-a" or not.
@@ -98,18 +98,11 @@
for record := range recordChan {
if len(record.option) == 0 {
c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
- // Hub returns 401 rather than 404 for nonexistent repos over
- // the v2 protocol - but we should end up falling back to v1,
- // which does return a 404.
- tag := record.e.tag
- if tag == "" {
- tag = "latest"
- }
- c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s:%s not found", record.e.repo, tag), check.Commentf("expected image not found error messages"))
+ c.Assert(record.out, checker.Contains, fmt.Sprintf("repository %s not found: does not exist or no read access", record.e.repo), check.Commentf("expected image not found error messages"))
} else {
// pull -a on a nonexistent registry should fall back as well
c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
- c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s not found", record.e.repo), check.Commentf("expected image not found error messages"))
+ c.Assert(record.out, checker.Contains, fmt.Sprintf("repository %s not found", record.e.repo), check.Commentf("expected image not found error messages"))
c.Assert(record.out, checker.Not(checker.Contains), "unauthorized", check.Commentf(`message should not contain "unauthorized"`))
}
}
diff --git a/integration-cli/docker_cli_service_update_test.go b/integration-cli/docker_cli_service_update_test.go
index 548f8e6..27fa2d0 100644
--- a/integration-cli/docker_cli_service_update_test.go
+++ b/integration-cli/docker_cli_service_update_test.go
@@ -32,6 +32,7 @@
Protocol: "tcp",
PublishedPort: 8082,
TargetPort: 8083,
+ PublishMode: "ingress",
},
}
@@ -103,7 +104,7 @@
c.Assert(err, checker.IsNil, check.Commentf(out))
// add secret
- out, err = d.Cmd("service", "update", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
+ out, err = d.cmdRetryOutOfSequence("service", "update", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
c.Assert(err, checker.IsNil, check.Commentf(out))
out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
@@ -118,7 +119,7 @@
c.Assert(refs[0].Target.Name, checker.Equals, testTarget)
// remove
- out, err = d.Cmd("service", "update", "test", "--secret-rm", testName)
+ out, err = d.cmdRetryOutOfSequence("service", "update", "test", "--secret-rm", testName)
c.Assert(err, checker.IsNil, check.Commentf(out))
out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go
index 1c5d059..d53b219 100644
--- a/integration-cli/docker_cli_swarm_test.go
+++ b/integration-cli/docker_cli_swarm_test.go
@@ -321,12 +321,9 @@
out, err = d.cmdRetryOutOfSequence("service", "update", "--publish-add", "80:80", "--publish-add", "80:20", name)
c.Assert(err, checker.NotNil)
- out, err = d.cmdRetryOutOfSequence("service", "update", "--publish-add", "80:20", name)
- c.Assert(err, checker.IsNil)
-
out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name)
c.Assert(err, checker.IsNil)
- c.Assert(strings.TrimSpace(out), checker.Equals, "[{ tcp 20 80}]")
+ c.Assert(strings.TrimSpace(out), checker.Equals, "[{ tcp 80 80 ingress}]")
}
func (s *DockerSwarmSuite) TestSwarmServiceWithGroup(c *check.C) {
@@ -1054,3 +1051,24 @@
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
}
+
+func (s *DockerSwarmSuite) TestSwarmManagerAddress(c *check.C) {
+ d1 := s.AddDaemon(c, true, true)
+ d2 := s.AddDaemon(c, true, false)
+ d3 := s.AddDaemon(c, true, false)
+
+ // Manager Addresses will always show Node 1's address
+ expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.port)
+
+ out, err := d1.Cmd("info")
+ c.Assert(err, checker.IsNil)
+ c.Assert(out, checker.Contains, expectedOutput)
+
+ out, err = d2.Cmd("info")
+ c.Assert(err, checker.IsNil)
+ c.Assert(out, checker.Contains, expectedOutput)
+
+ out, err = d3.Cmd("info")
+ c.Assert(err, checker.IsNil)
+ c.Assert(out, checker.Contains, expectedOutput)
+}
diff --git a/libcontainerd/client_linux.go b/libcontainerd/client_linux.go
index 9875d15..b67690b 100644
--- a/libcontainerd/client_linux.go
+++ b/libcontainerd/client_linux.go
@@ -28,6 +28,20 @@
liveRestore bool
}
+// GetServerVersion returns the connected server version information
+func (clnt *client) GetServerVersion(ctx context.Context) (*ServerVersion, error) {
+ resp, err := clnt.remote.apiClient.GetServerVersion(ctx, &containerd.GetServerVersionRequest{})
+ if err != nil {
+ return nil, err
+ }
+
+ sv := &ServerVersion{
+ GetServerVersionResponse: *resp,
+ }
+
+ return sv, nil
+}
+
// AddProcess is the handler for adding a process to an already running
// container. It's called through docker exec. It returns the system pid of the
// exec'd process.
diff --git a/libcontainerd/client_solaris.go b/libcontainerd/client_solaris.go
index 8bfb048..cb93997 100644
--- a/libcontainerd/client_solaris.go
+++ b/libcontainerd/client_solaris.go
@@ -12,6 +12,20 @@
liveRestore bool
}
+// GetServerVersion returns the connected server version information
+func (clnt *client) GetServerVersion(ctx context.Context) (*ServerVersion, error) {
+ resp, err := clnt.remote.apiClient.GetServerVersion(ctx, &containerd.GetServerVersionRequest{})
+ if err != nil {
+ return nil, err
+ }
+
+ sv := &ServerVersion{
+ GetServerVersionResponse: *resp,
+ }
+
+ return sv, nil
+}
+
func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, specp Process, attachStdio StdioCallback) (int, error) {
return -1, nil
}
diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go
index 61c50e4..ddcf321 100644
--- a/libcontainerd/client_windows.go
+++ b/libcontainerd/client_windows.go
@@ -625,3 +625,7 @@
func (clnt *client) ListCheckpoints(containerID string, checkpointDir string) (*Checkpoints, error) {
return nil, errors.New("Windows: Containers do not support checkpoints")
}
+
+func (clnt *client) GetServerVersion(ctx context.Context) (*ServerVersion, error) {
+ return &ServerVersion{}, nil
+}
diff --git a/libcontainerd/types.go b/libcontainerd/types.go
index b1d02d8..3d981e3 100644
--- a/libcontainerd/types.go
+++ b/libcontainerd/types.go
@@ -3,6 +3,7 @@
import (
"io"
+ containerd "github.com/docker/containerd/api/grpc/types"
"github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/net/context"
)
@@ -33,6 +34,7 @@
// Client provides access to containerd features.
type Client interface {
+ GetServerVersion(ctx context.Context) (*ServerVersion, error)
Create(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error
Signal(containerID string, sig int) error
SignalProcess(containerID string, processFriendlyName string, sig int) error
@@ -65,3 +67,9 @@
Stderr io.ReadCloser
Terminal bool // Whether stderr is connected on Windows
}
+
+// ServerVersion contains version information as retrieved from the
+// server
+type ServerVersion struct {
+ containerd.GetServerVersionResponse
+}
diff --git a/migrate/v1/migratev1.go b/migrate/v1/migratev1.go
index 90bf627..bc42dd2 100644
--- a/migrate/v1/migratev1.go
+++ b/migrate/v1/migratev1.go
@@ -331,7 +331,7 @@
continue
}
if dgst, err := digest.ParseDigest(tag); err == nil {
- canonical, err := reference.WithDigest(ref, dgst)
+ canonical, err := reference.WithDigest(reference.TrimNamed(ref), dgst)
if err != nil {
logrus.Errorf("migrate tags: invalid digest %q, %q", dgst, err)
continue
diff --git a/opts/port.go b/opts/port.go
new file mode 100644
index 0000000..ef3f12a
--- /dev/null
+++ b/opts/port.go
@@ -0,0 +1,99 @@
+package opts
+
+import (
+ "encoding/csv"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/docker/docker/api/types/swarm"
+)
+
+const (
+ portOptTargetPort = "target"
+ portOptPublishedPort = "published"
+ portOptProtocol = "protocol"
+ portOptMode = "mode"
+)
+
+type PortOpt struct {
+ ports []swarm.PortConfig
+}
+
+// Set a new port value
+func (p *PortOpt) Set(value string) error {
+ csvReader := csv.NewReader(strings.NewReader(value))
+ fields, err := csvReader.Read()
+ if err != nil {
+ return err
+ }
+
+ pConfig := swarm.PortConfig{}
+ for _, field := range fields {
+ parts := strings.SplitN(field, "=", 2)
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid field %s", field)
+ }
+
+ key := strings.ToLower(parts[0])
+ value := strings.ToLower(parts[1])
+
+ switch key {
+ case portOptProtocol:
+ if value != string(swarm.PortConfigProtocolTCP) && value != string(swarm.PortConfigProtocolUDP) {
+ return fmt.Errorf("invalid protocol value %s", value)
+ }
+
+ pConfig.Protocol = swarm.PortConfigProtocol(value)
+ case portOptMode:
+ if value != string(swarm.PortConfigPublishModeIngress) && value != string(swarm.PortConfigPublishModeHost) {
+ return fmt.Errorf("invalid publish mode value %s", value)
+ }
+
+ pConfig.PublishMode = swarm.PortConfigPublishMode(value)
+ case portOptTargetPort:
+ tPort, err := strconv.ParseUint(value, 10, 16)
+ if err != nil {
+ return err
+ }
+
+ pConfig.TargetPort = uint32(tPort)
+ case portOptPublishedPort:
+ pPort, err := strconv.ParseUint(value, 10, 16)
+ if err != nil {
+ return err
+ }
+
+ pConfig.PublishedPort = uint32(pPort)
+ default:
+ return fmt.Errorf("invalid field key %s", key)
+ }
+ }
+
+ if pConfig.TargetPort == 0 {
+ return fmt.Errorf("missing mandatory field %q", portOptTargetPort)
+ }
+
+ p.ports = append(p.ports, pConfig)
+ return nil
+}
+
+// Type returns the type of this option
+func (p *PortOpt) Type() string {
+ return "port"
+}
+
+// String returns a string repr of this option
+func (p *PortOpt) String() string {
+ ports := []string{}
+ for _, port := range p.ports {
+ repr := fmt.Sprintf("%v:%v/%s/%s", port.PublishedPort, port.TargetPort, port.Protocol, port.PublishMode)
+ ports = append(ports, repr)
+ }
+ return strings.Join(ports, ", ")
+}
+
+// Value returns the ports
+func (p *PortOpt) Value() []swarm.PortConfig {
+ return p.ports
+}
diff --git a/pkg/system/filesys.go b/pkg/system/filesys.go
index c14feb8..82bcaa6 100644
--- a/pkg/system/filesys.go
+++ b/pkg/system/filesys.go
@@ -7,6 +7,12 @@
"path/filepath"
)
+// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
+// ACL'd for Builtin Administrators and Local System.
+func MkdirAllWithACL(path string, perm os.FileMode) error {
+ return MkdirAll(path, perm)
+}
+
// MkdirAll creates a directory named path along with any necessary parents,
// with permission specified by attribute perm for all dir created.
func MkdirAll(path string, perm os.FileMode) error {
diff --git a/pkg/system/filesys_windows.go b/pkg/system/filesys_windows.go
index 16823d5..97f1c7c 100644
--- a/pkg/system/filesys_windows.go
+++ b/pkg/system/filesys_windows.go
@@ -8,15 +8,31 @@
"regexp"
"strings"
"syscall"
+ "unsafe"
+
+ winio "github.com/Microsoft/go-winio"
)
+// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
+// ACL'd for Builtin Administrators and Local System.
+func MkdirAllWithACL(path string, perm os.FileMode) error {
+ return mkdirall(path, true)
+}
+
// MkdirAll implementation that is volume path aware for Windows.
-func MkdirAll(path string, perm os.FileMode) error {
+func MkdirAll(path string, _ os.FileMode) error {
+ return mkdirall(path, false)
+}
+
+// mkdirall is a custom version of os.MkdirAll modified for use on Windows
+// so that it is both volume path aware, and can create a directory with
+// a DACL.
+func mkdirall(path string, adminAndLocalSystem bool) error {
if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
return nil
}
- // The rest of this method is copied from os.MkdirAll and should be kept
+ // The rest of this method is largely copied from os.MkdirAll and should be kept
// as-is to ensure compatibility.
// Fast path: if we can tell whether path is a directory or file, stop with success or error.
@@ -45,14 +61,19 @@
if j > 1 {
// Create parent
- err = MkdirAll(path[0:j-1], perm)
+ err = mkdirall(path[0:j-1], false)
if err != nil {
return err
}
}
- // Parent now exists; invoke Mkdir and use its result.
- err = os.Mkdir(path, perm)
+ // Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
+ if adminAndLocalSystem {
+ err = mkdirWithACL(path)
+ } else {
+ err = os.Mkdir(path, 0)
+ }
+
if err != nil {
// Handle arguments like "foo/." by
// double-checking that directory doesn't exist.
@@ -65,6 +86,36 @@
return nil
}
+// mkdirWithACL creates a new directory. If there is an error, it will be of
+// type *PathError. .
+//
+// This is a modified and combined version of os.Mkdir and syscall.Mkdir
+// in golang to cater for creating a directory am ACL permitting full
+// access, with inheritance, to any subfolder/file for Built-in Administrators
+// and Local System.
+func mkdirWithACL(name string) error {
+ sa := syscall.SecurityAttributes{Length: 0}
+ sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
+ sd, err := winio.SddlToSecurityDescriptor(sddl)
+ if err != nil {
+ return &os.PathError{"mkdir", name, err}
+ }
+ sa.Length = uint32(unsafe.Sizeof(sa))
+ sa.InheritHandle = 1
+ sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
+
+ namep, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return &os.PathError{"mkdir", name, err}
+ }
+
+ e := syscall.CreateDirectory(namep, &sa)
+ if e != nil {
+ return &os.PathError{"mkdir", name, e}
+ }
+ return nil
+}
+
// IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows,
// golang filepath.IsAbs does not consider a path \windows\system32 as absolute
// as it doesn't start with a drive-letter/colon combination. However, in
diff --git a/reference/reference.go b/reference/reference.go
index b22961b..996fc50 100644
--- a/reference/reference.go
+++ b/reference/reference.go
@@ -70,6 +70,11 @@
return r, nil
}
+// TrimNamed removes any tag or digest from the named reference
+func TrimNamed(ref Named) Named {
+ return &namedRef{distreference.TrimNamed(ref)}
+}
+
// WithName returns a named object representing the given string. If the input
// is invalid ErrReferenceInvalidFormat will be returned.
func WithName(name string) (Named, error) {
diff --git a/registry/auth.go b/registry/auth.go
index 0bf0450..5da3563 100644
--- a/registry/auth.go
+++ b/registry/auth.go
@@ -10,6 +10,7 @@
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/registry/client/auth"
+ "github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
@@ -255,7 +256,7 @@
// challenge manager for the supported authentication types and
// whether v2 was confirmed by the response. If a response is received but
// cannot be interpreted a PingResponseError will be returned.
-func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (auth.ChallengeManager, bool, error) {
+func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (challenge.Manager, bool, error) {
var (
foundV2 = false
v2Version = auth.APIVersion{
@@ -291,7 +292,7 @@
}
}
- challengeManager := auth.NewSimpleChallengeManager()
+ challengeManager := challenge.NewSimpleManager()
if err := challengeManager.AddResponse(resp); err != nil {
return nil, foundV2, PingResponseError{
Err: err,
diff --git a/vendor.conf b/vendor.conf
index ace73b3..5ea45b3 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -23,7 +23,7 @@
github.com/imdario/mergo 0.2.1
#get libnetwork packages
-github.com/docker/libnetwork 1861587d0fe7cdf85b89160ed36f20b81e96528d
+github.com/docker/libnetwork 57be722e077059d1ee0539be31743a3642ccbeb3
github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
@@ -44,7 +44,7 @@
github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
# get graph and distribution packages
-github.com/docker/distribution c04791f441f98bcf073353d7317db83663cf3ea2
+github.com/docker/distribution 8016d2d8903e378edacac11e4d809efbc987ad61
github.com/vbatts/tar-split v0.10.1
# get go-zfs packages
@@ -100,7 +100,7 @@
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
# cluster
-github.com/docker/swarmkit 0be0da2c1f88aec55dc0880f2057f76f77039430
+github.com/docker/swarmkit efd44df04cc0fd828de5947263858c3a5a2729b1
github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
github.com/gogo/protobuf v0.3
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
@@ -132,7 +132,7 @@
github.com/docker/go-metrics 86138d05f285fd9737a99bee2d9be30866b59d72
# composefile
-github.com/aanand/compose-file 480a79677acccb83b52c41161c22eaf4358460cc
+github.com/aanand/compose-file 8cff34df885ef07824138236bc4d27d359888b17
github.com/mitchellh/mapstructure f3009df150dadf309fdee4a54ed65c124afad715
github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
diff --git a/vendor/github.com/aanand/compose-file/loader/loader.go b/vendor/github.com/aanand/compose-file/loader/loader.go
index fe8ebba..0de4991 100644
--- a/vendor/github.com/aanand/compose-file/loader/loader.go
+++ b/vendor/github.com/aanand/compose-file/loader/loader.go
@@ -68,8 +68,8 @@
cfg := types.Config{}
version := configDict["version"].(string)
- if version != "3" {
- return nil, fmt.Errorf("Unsupported version: %#v. The only supported version is 3", version)
+ if version != "3" && version != "3.0" {
+ return nil, fmt.Errorf(`Unsupported Compose file version: %#v. The only version supported is "3" (or "3.0")`, version)
}
if services, ok := configDict["services"]; ok {
diff --git a/vendor/github.com/aanand/compose-file/schema/bindata.go b/vendor/github.com/aanand/compose-file/schema/bindata.go
index a059c23..1b4ee46 100644
--- a/vendor/github.com/aanand/compose-file/schema/bindata.go
+++ b/vendor/github.com/aanand/compose-file/schema/bindata.go
@@ -68,7 +68,7 @@
return nil
}
-var _dataConfig_schema_v3Json = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x5a\xcd\x8e\xdb\x36\x10\xbe\xfb\x29\x16\x4a\x6e\xf1\xae\x03\x34\x28\xd0\xdc\x7a\xec\xa9\x3d\xd7\x50\x04\x5a\xa2\x6d\x26\x92\xc8\x90\x94\x13\x27\xf0\xbb\x97\x14\x25\x99\xa4\xf8\x67\x5b\x69\x7a\xe8\x1e\x16\xbb\xe2\xcc\x70\x7e\x3e\xce\x0c\x47\xfa\xbe\x7a\x7a\xca\x5e\xb3\xf2\x08\x1b\x90\xbd\x7f\xca\x8e\x9c\x93\xf7\x9b\xcd\x47\x86\xdb\x67\xf5\xf4\x05\xd3\xc3\xa6\xa2\x60\xcf\x9f\xdf\xbe\xdb\xa8\x67\xaf\xb2\xb5\xe4\x43\x95\x64\x29\x71\xbb\x47\x87\x42\xad\x14\xa7\x5f\x5e\x24\xb3\x22\xe0\x67\x02\x25\x09\xde\x7d\x84\x25\x57\xcf\x28\xfc\xdc\x21\x0a\x25\xeb\x36\x3b\x41\xca\x90\xa0\xce\xd7\x2b\xb9\x46\x28\x26\x90\x72\x04\x99\x58\x95\xaa\x89\x67\x23\xc9\xf8\x40\x13\xcb\x38\x45\xed\x21\xeb\x1f\x5f\x7a\x09\x62\x91\x41\x7a\x42\xa5\x26\x61\x52\xf4\xd5\xe6\x2a\x7f\x33\x91\xad\x6d\xa9\x9a\xb2\xfd\x73\x02\x38\x87\xb4\xfd\x6b\xae\x5b\xbf\xfc\x61\x0b\x9e\xbf\xfd\xfe\xfc\xf7\xdb\xe7\xdf\x5e\x8a\xe7\xfc\xcd\x6b\x63\x59\x7a\x97\xc2\xbd\xda\xbe\x82\x7b\xd4\x22\x2e\xac\x99\xf6\xcf\x26\xca\xcb\xf0\xd7\x65\xda\x18\x54\x55\x4f\x0c\x6a\x63\xef\x3d\xa8\x19\x34\x6d\x6e\x21\xff\x82\xe9\xa7\x98\xcd\x13\xd9\x4f\xb2\x79\xd8\xdf\x61\xb3\x69\xce\x09\xd7\x5d\x13\x8d\xe0\x48\xf5\x93\x8c\x51\xdb\x3f\x16\xbf\xd5\x68\x74\x90\x56\x51\x68\x7b\xf7\x0a\x1a\x68\x77\xb9\xca\x85\x36\xbf\xaf\x26\x67\x79\xbc\x54\x41\x52\xe3\xb3\x7c\xe6\xf1\x87\x22\x68\x60\xcb\xb3\xc9\x05\x82\x6f\xd7\xa1\xba\xb2\x3d\x8a\x5b\xf8\xa7\x14\xb1\xd5\x1e\x3e\x09\xc9\xd6\xc1\xd6\xe4\xf4\xeb\xc6\x7f\xfe\x80\x4f\xeb\x1e\x5b\xa6\x75\x91\xb9\x38\xfc\xca\x7b\xa3\xc2\x5b\x2b\x17\xe0\xf2\x13\xa4\x7b\x54\xc3\x54\x0e\x40\x0f\x2c\xe0\xb2\x1a\x31\x5e\x60\x5a\x54\x48\x68\x7f\xb1\xd8\x67\xf2\xe2\x78\x9a\x58\xb5\xff\xf2\x95\x43\x60\x56\x02\x52\x08\x71\x86\x1d\x80\x52\x70\xce\xd6\x02\x40\x1c\x36\xcc\x6d\xe2\x53\xd6\xb5\xe8\x73\x07\xff\x18\x48\x38\xed\xa0\x2d\xb7\x12\xca\x2d\x2f\xf8\x40\x71\x47\x0a\x02\xa8\x04\x58\xd8\xfd\x22\xae\x4d\x03\xda\xa5\x50\x77\x8b\x1d\x09\x9e\x17\x98\x03\xa8\x85\xb4\x68\x41\x13\x03\x92\x3c\x75\xb0\xad\x58\xa1\xea\x5f\x10\x46\xfb\x42\xf1\x33\x4b\xc0\x54\x0c\x17\x8d\x47\xd5\x86\x80\xad\xc4\x48\x68\x4b\xdd\x32\x8b\xb1\x60\x10\xd0\xf2\x78\x27\x3f\x6e\x84\xfb\x52\x7c\x27\x80\x42\xcf\x04\x23\x85\x97\xff\x1c\x10\x60\x7b\x2a\xa6\x5c\x72\xb3\x1b\x04\x37\xa2\xb8\x6d\xc6\xd3\x90\x92\x60\xa6\x24\x2f\xf9\xbf\x12\xcc\xa0\xed\x18\xcb\x40\x7d\x69\x32\xd5\xf0\xc9\xc8\xb1\x1d\x0d\x17\x4e\x69\xbb\x66\x07\xa9\x6c\xe9\x0c\xca\x3d\xa6\x0d\x90\xca\x8e\x7b\x6b\xcb\x86\xa7\x1d\xc8\xd3\x1d\xa8\xdb\x20\xcb\x3a\xa8\x85\x77\xda\x4f\xcb\x43\x5c\x88\xa7\xa0\x38\x62\xc6\xd3\x73\xb8\xc6\x2e\x19\x53\x60\x8a\x1a\x70\x88\x13\x91\x32\x46\x52\x83\x1d\xac\xef\xd2\x74\x51\xf7\x69\x62\xf1\xe1\x20\x49\x7d\x98\x99\xf5\x1e\xc3\x72\xac\x6a\x57\x14\x89\x3b\x41\x6a\x09\xc6\xe4\xda\x32\xd9\x8b\xf1\x16\x42\x29\x14\xec\x1f\x0d\xd2\x0f\x2f\xaa\x7d\x0c\x9c\x8b\xfe\xaf\xba\xce\x72\xbb\xe0\xcb\x9f\xf9\x33\xf3\x89\x65\x61\x5a\x4b\x60\x44\xa5\x01\xa5\xac\xfc\x14\x32\x4f\x5c\xaf\xa4\x43\xbb\x5e\x34\xb8\xf2\x01\x74\x46\x6c\xfb\xc6\x9b\x6b\x6f\x2e\x65\x3d\xdb\xcd\x1d\x60\x52\xe8\xa2\x57\x80\x88\x35\x3e\xf5\x52\xd5\xbc\xaa\x1b\x87\x58\x4f\x07\x6a\x04\x18\x8c\x1f\x76\xaf\x23\x0d\x69\x88\x9c\xde\x25\x62\xc2\xc5\xfb\x6b\x90\xd7\xc3\xea\x95\x99\xde\xe5\x46\x44\x5d\x55\xe9\x8f\x9b\x4b\x91\x3c\x72\xda\x7e\x70\x13\x4e\x50\xe5\xcf\x15\x7d\x86\xd0\x0f\x18\xc1\x94\xcf\x4e\xd7\xbf\x53\xb0\xd5\xd6\x0f\xd7\x6b\x22\x12\xb7\x68\x78\x0e\xd0\xbc\x77\xec\x30\xae\x21\x68\x8d\xd4\x43\x21\xa8\x44\xd3\x5b\x9f\x13\x28\x19\x07\x34\x7a\x25\x60\xb0\xec\x28\xe2\xe7\x42\xd4\x83\xc5\x3b\x05\x76\x6c\x0a\x86\xbe\x41\x33\x9a\xd7\x7c\x3f\x08\xca\x0d\x1e\x5e\xa1\x56\x68\x03\xdb\xa8\x89\x8c\x63\x22\xe4\x1f\x04\xe6\xa2\x66\x4a\xd2\x03\x05\x25\x2c\x04\x36\x11\xae\x5c\x0c\x6b\x3d\xb6\x55\x47\x81\xc4\xb3\x21\x86\x37\x64\x7f\x67\x7f\xcf\x79\x3c\x66\x5d\x8d\x1a\xe4\x07\xb3\x23\x4b\x26\x24\x72\x95\xc4\xdd\xb9\x3b\x90\xb7\xaf\x9a\x8a\x8b\x82\xc0\x26\x75\xa5\xbb\x40\xeb\x10\xee\x1c\x12\x5a\x86\x23\xa0\x66\x94\x02\x7a\xf4\x0c\x0c\xef\xb9\x9b\xc1\xd5\x50\x38\xf5\x32\x66\xb0\xbd\xbc\xf5\xa0\x48\xee\xa4\xbf\x29\x27\xdb\x6a\xe4\xde\xb4\x78\x71\xa6\xc5\x8e\x45\xbb\x3b\x7d\x42\xb8\xe8\x49\x96\x2d\x8c\x44\x76\x85\xdc\x2a\xac\x2c\x75\x6f\x98\xd1\x6a\xf3\xb1\xc8\xb0\x4e\xa3\xb4\xe7\x75\xdb\x09\x6e\x63\x8d\xb8\x4e\x39\x3d\x83\xbb\x40\xf7\xa6\xe1\x81\xd4\xa8\x04\x2c\x86\xc3\x07\x2e\x19\x1d\xa9\x00\x87\x85\x7a\x59\x70\xd3\xc9\x0f\x1c\x79\x02\x28\xa8\x6b\x28\x36\x6d\x52\x8e\x90\x88\x41\x0d\xce\x77\xa5\xc4\x9e\x7d\x0f\x50\xdd\x51\x58\x80\x92\x0f\x6f\x24\x22\xad\x92\x70\xbe\x70\x0c\x76\x62\x29\x6d\xcb\x06\x7c\x2d\xc6\x6d\x7b\x12\x43\xd4\x50\x62\x2e\xde\xd2\x9c\x7a\x3f\xd0\x90\xc0\x70\x47\xcb\x99\xb3\xef\x0e\xd1\x35\xd5\x7b\x10\x33\xee\x38\x33\x5d\x2c\x40\x7a\x02\xd3\xf5\x2d\xca\x1f\xcd\x2c\x43\xaf\x50\x10\x2c\xd0\x7e\x5e\xca\x42\x01\x69\xe5\xe4\x14\x40\x3c\x88\x40\x09\x07\x59\x09\x1b\xc2\xa3\x87\xb5\x67\xf8\x82\xda\x0a\x7f\xb9\x61\xc3\xe5\xa0\x44\x6a\xd1\x86\x58\xf9\xee\x51\x47\x0b\xdd\x81\x30\xf5\xe6\xc4\xff\xa8\x59\x0f\xe4\xfd\x09\x9f\x91\xac\x3f\xd1\xc5\xdf\x67\x79\x32\x7d\x49\xba\xe8\x9d\xbe\x81\x0d\xa6\x4e\x00\x06\x6c\x4c\x7c\xfd\x18\xb3\x70\x24\x5b\xa0\xa8\x25\xcd\x80\x06\x2a\xd9\xf2\x2f\xde\x6b\xc6\xe7\x3c\x79\x3c\x1f\x21\x02\x9a\xa5\x0e\x47\xf2\x54\x2c\x73\x96\x60\x63\xef\xf9\x6d\x52\xa9\xeb\xbc\x51\xc6\xb4\x8e\xeb\x3e\x50\xb0\x6e\x27\x10\x12\x82\xe6\xf5\xc7\xf9\xb2\x2d\xbd\x49\xbd\xf8\x5b\xd2\xc7\x72\xde\x38\x92\xf6\x44\x75\x3b\x5d\x87\xd6\x93\xaf\xf2\xe4\x10\x7b\xa7\xc9\xcb\xe9\x7f\x63\x7f\xf7\x40\x5a\x1c\x5e\x9f\x47\x52\xc6\x40\xf5\x7f\xc6\x18\xa4\xfc\x7c\x7c\x05\x6a\xe2\x9d\x97\x83\x1b\x40\x63\xcd\x1d\x34\xf0\xcc\x2f\xf8\xa1\x38\x27\x4f\x4d\x07\x8e\xdc\x54\xc3\x26\x7b\x3f\xff\x34\xc9\x4c\xa1\xa1\x2b\xe9\x48\xe2\x99\xa2\x59\x9b\x0e\xce\x0b\x5b\xbe\x20\x6c\x5f\xde\x04\x0a\x45\xe8\xed\xc6\x0f\xca\xb0\x0b\x5c\xf7\xdd\x31\xb5\x9a\xcb\xd1\xbb\xf3\xef\x6b\x3c\x99\x4a\xe3\x9f\x7d\x6d\x23\xed\x6c\xcf\xb3\x01\xd4\x77\x73\x0e\xa3\xbe\x94\xc9\x0d\xff\x58\x24\xea\x5d\xa1\x96\x27\x72\xbd\xdf\xf6\x85\xd1\xf9\x0d\x8e\x3d\x05\x1a\xbf\x85\xc9\xc3\x87\x7d\x35\xfe\xbe\xac\x2e\xab\x7f\x02\x00\x00\xff\xff\xe9\x77\x87\x68\x3d\x28\x00\x00")
+var _dataConfig_schema_v3Json = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x5a\x4b\x93\xdb\xa8\x13\xbf\xfb\x53\x4c\x29\xb9\xc5\x33\x93\xaa\x7f\xea\x5f\xb5\xb9\xed\x71\x4f\xbb\xe7\x75\x29\x2a\x2c\x61\x9b\x8c\x10\x04\x90\x13\x27\xe5\xef\xbe\xa0\x97\x01\xf1\xb2\xad\xec\xe4\xb0\x73\x98\x9a\x81\xee\xa6\x1f\x3f\x9a\xa6\xd1\x8f\xd5\xc3\x43\xf6\x96\x97\x07\x88\x41\xf6\xf1\x21\x3b\x08\x41\x3f\x3e\x3f\x7f\xe6\xa4\x79\xec\x47\x9f\x08\xdb\x3f\x57\x0c\xec\xc4\xe3\xfb\x0f\xcf\xfd\xd8\x9b\x6c\xad\xf8\x50\xa5\x58\x4a\xd2\xec\xd0\xbe\xe8\x67\x8a\xe3\xff\x9e\x14\x73\x4f\x20\x4e\x14\x2a\x12\xb2\xfd\x0c\x4b\xd1\x8f\x31\xf8\xa5\x45\x0c\x2a\xd6\x4d\x76\x84\x8c\x23\x49\x9d\xaf\x57\x6a\x8e\x32\x42\x21\x13\x08\x72\x39\xab\x54\x93\x63\x23\xc9\x38\xa0\x89\xe5\x82\xa1\x66\x9f\x75\xc3\xe7\x4e\x82\x9c\xe4\x90\x1d\x51\xa9\x49\x98\x14\x7d\xf3\x7c\x91\xff\x3c\x91\xad\x6d\xa9\x9a\xb2\xdd\x38\x05\x42\x40\xd6\xfc\x35\xd7\xad\x9b\xfe\xb4\x01\x8f\xdf\x7f\x7f\xfc\xfb\xfd\xe3\x6f\x4f\xc5\x63\xfe\xee\xad\x31\xad\xbc\xcb\xe0\xae\x5f\xbe\x82\x3b\xd4\x20\x21\xad\x99\xd6\xcf\x26\xca\xf3\xf0\xd7\x79\x5a\x18\x54\x55\x47\x0c\x6a\x63\xed\x1d\xa8\x39\x34\x6d\x6e\xa0\xf8\x4a\xd8\x4b\xcc\xe6\x89\xec\x95\x6c\x1e\xd6\x77\xd8\x6c\x9a\x73\x24\x75\x8b\xa3\x11\x1c\xa9\x5e\xc9\x98\x7e\xf9\xfb\xe2\xb7\x1a\x8d\x0e\xd2\xf6\x14\xda\xda\x9d\x82\x06\xda\x5d\xae\x72\xa1\xcd\xef\xab\xc9\x59\x1e\x2f\x55\x90\xd6\xe4\xa4\xc6\x3c\xfe\xe8\x09\x30\x6c\x44\x36\xb9\x40\xf2\x6d\x5b\x54\x57\xb6\x47\x49\x03\xff\x54\x22\x36\xda\xe0\x83\x94\x6c\x6d\x6c\x4d\x4e\x37\x6f\xfc\xe7\x0f\xf8\x34\xef\xb1\x65\x9a\x97\x99\x4b\xc0\x6f\xa2\x33\x2a\xbc\x74\xef\x02\x52\xbe\x40\xb6\x43\x35\x4c\xe5\x00\x6c\xcf\x03\x2e\xab\x11\x17\x05\x61\x45\x85\xa4\xf6\x67\x8b\x7d\x26\x2f\x8e\xa7\x89\x55\xfb\x2f\x5f\x39\x04\x66\x25\xa0\x85\x14\x67\xd8\x01\x18\x03\xa7\x6c\x2d\x01\x24\x20\xe6\x6e\x13\x1f\xb2\xb6\x41\x5f\x5a\xf8\xc7\x40\x22\x58\x0b\x6d\xb9\x95\x54\x6e\x79\xc1\x7b\x46\x5a\x5a\x50\xc0\x14\xc0\xc2\xee\x97\x71\xc5\x18\x34\x4b\xa1\xee\x1a\x3b\x12\x3c\x2f\x31\x07\x50\x03\x59\xd1\x00\x1c\x03\x92\xda\x75\xb0\xa9\x78\xd1\x9f\x7f\x41\x18\xed\x8a\x9e\x9f\x5b\x02\xa6\xc3\x70\xd1\x78\x54\x4d\x08\xd8\xbd\x18\x05\x6d\xa5\x5b\x66\x31\x16\x1c\x02\x56\x1e\x6e\xe4\x27\x58\xba\x2f\xc5\x77\x12\x28\xec\x44\x09\xea\xf1\xf2\xcb\x01\x01\x36\xc7\x62\xca\x25\x57\xbb\x41\x72\x23\x46\x1a\x3c\xee\x86\x94\x04\x33\x25\x79\xc5\xff\x8d\x12\x0e\x6d\xc7\x58\x06\xea\x53\x93\xa9\x86\x4f\x46\x8e\xcd\x68\xb8\x74\x4a\xd3\xe2\x2d\x64\xaa\xa4\x33\x28\x77\x84\x61\xa0\x94\x1d\xd7\xd6\xa6\x0d\x4f\x3b\x90\xa7\x3b\x50\xb7\x41\x1d\xeb\xa0\x96\xde\x69\x5e\x96\x87\xb8\x14\xcf\x40\x71\x20\x5c\xa4\xe7\x70\x8d\xfd\x00\x41\x2d\x0e\xb2\x28\x2e\x5f\x02\xec\x3a\x95\xc1\x2d\x97\x4d\x01\x39\xc2\x60\x1f\x27\xa2\x65\x8c\xa4\x06\x5b\x58\xdf\x64\xe7\xa2\xce\xd7\xc4\x92\xfd\x5e\x91\xfa\x10\x37\xab\x5c\x86\xe9\xd8\x99\x5f\x31\x24\x6f\x14\xa9\x07\x38\xa1\x97\x82\xcb\x9e\x8c\x17\x20\xbd\x42\xc1\xea\xd3\x20\xfd\xf4\xd4\x17\x9f\x81\x5d\xd5\xfd\x55\xd7\x59\x6e\x97\x0b\xea\x67\x3e\x66\x8e\x58\x16\xa6\x15\x14\x46\x54\x30\x28\x55\xdd\xc0\x20\xf7\xc4\xf5\x42\x3a\x14\xfb\x05\x26\x95\x0f\xa0\x33\x62\xdb\x37\xde\x4c\x7d\xf5\x41\xd8\xb1\x5d\x5d\x3f\x26\x85\x2e\x7a\x81\x88\x58\xe3\x53\x2f\x55\xcd\x8b\xba\x71\x88\x75\x74\xa0\x46\x80\xc3\xf8\x66\xf7\x3a\xd2\x90\x86\xe8\xf1\x43\x22\x26\x5c\xbc\xff\x0f\xf2\x7a\x58\xbd\x32\xd3\x6b\xe4\x88\xa8\x8b\x2a\xdd\x76\x73\x29\x92\x47\x76\xdb\x4f\x2e\xe1\x29\xaa\xfc\xb9\xa2\xcb\x10\xfa\x06\xa3\x84\x89\xd9\xee\xfa\x77\x8e\xfb\x7e\xe9\xbb\x4f\x7b\x2a\x13\xb7\x2c\x97\xf6\xd0\xbc\xb5\x6c\x09\xa9\x21\x68\x8c\xd4\xc3\x20\xa8\x64\xc9\x5c\x9f\x12\x28\xb9\x00\x2c\x7a\xa1\xe0\xb0\x6c\x19\x12\xa7\x42\x9e\x07\x8b\xd7\x19\xfc\x80\x0b\x8e\xbe\x43\x33\x9a\x97\x7c\x3f\x08\xca\x0d\x1e\x51\xa1\x46\x6a\x03\x9b\xa8\x89\x5c\x10\x2a\xe5\xef\x25\xe6\xa2\x66\x2a\xd2\x3d\x03\x25\x2c\x24\x36\x11\xa9\x5c\x0c\x6b\x3d\xb6\x55\xcb\x80\xc2\xb3\x21\x46\x60\xba\xbb\xf1\x76\x20\x44\x3c\x66\x6d\x8d\x30\xf2\x83\xd9\x91\x25\x13\x12\x79\x9f\xc4\xdd\xb9\x3b\x90\xb7\x2f\x9a\xca\x6b\x86\xc4\x26\x73\xa5\xbb\x40\xe9\x10\xae\x1c\x12\x4a\x86\x03\x60\x66\x94\x02\x7a\x74\x0c\x9c\xec\x84\x9b\xc1\x55\x50\x38\xf5\x32\x3a\xb8\x9d\xbc\xf5\xa0\x48\xee\xa4\xbf\x2a\x27\xdb\x6a\xe4\xde\xb4\x78\x76\xa6\xc5\x96\x47\xab\x3b\xbd\xbf\xb8\xe8\x4e\x56\x25\x8c\x42\x76\x85\xdc\x2a\xac\x2c\x75\xaf\xe8\xf0\x5a\xb7\x89\x51\x80\xab\xd7\xa7\x93\xda\xfd\xbe\xcd\x04\xb8\xf1\x94\xb8\x74\x49\x3d\x8d\x3f\x85\x0f\x76\x34\x92\x87\xcb\xa7\x02\x61\x48\x5a\x11\xa1\x62\x50\x8e\x59\x9e\x1f\x32\xdd\x2f\xdd\xc0\xb9\x29\x72\x1d\xa1\xd6\x16\x8d\xc4\x4d\xa3\x5c\x20\x6c\x81\xb2\x5b\x8b\x06\xad\x51\x09\x78\x2c\x81\xdc\x71\x3b\x6c\x69\x05\x04\x2c\xfa\x37\xa2\xab\x52\x76\x20\x57\x53\xc0\x40\x5d\x43\xb9\x28\x4e\xc9\x7d\x32\x06\x35\x38\xdd\x74\x96\x75\xec\x3b\x80\xea\x96\xc1\x02\x94\x62\x78\x88\x8a\x20\x4e\x3a\x5f\x3a\x86\x38\x93\x40\xda\x92\x18\x7c\x2b\xc6\x65\x3b\x12\xe7\x8e\xf1\xd6\x54\xa9\x17\x3b\x0d\x09\x9c\xb4\xac\x9c\x39\xfb\xe6\x10\x5d\xce\x68\x0f\x62\xc6\x15\x67\xa6\xcb\x09\x95\x6f\xa6\x7b\x77\x94\x3f\x7a\x24\x0c\x45\x5e\x41\x89\x44\xfb\x69\x29\x0b\x25\xa4\x7b\x27\xa7\x00\xe2\x4e\x04\x2a\x38\xa8\x12\x06\x53\x11\xdd\xac\x1d\xc3\x57\xd4\x54\xe4\xeb\x15\x0b\x2e\x07\x25\x5a\xcb\xfa\xd1\xca\x77\xf7\x3a\x5a\xea\x0e\xa4\xa9\x57\x9f\xd8\xf7\x9a\x75\xc7\x81\x3d\xe1\x33\x92\xf5\x27\xba\xf8\x33\xa6\x27\xd3\x97\xb4\x8d\x36\x63\x30\xc4\x84\x39\x01\x18\xb0\x31\xf1\xd5\x39\x66\xe1\x48\xb6\xc0\xa1\x96\xd4\xbc\x1b\xa8\xd4\x5d\x6d\xf1\x4b\x42\xbc\x41\x97\xc7\xf3\x11\xa2\x00\x2f\xb5\x39\x92\xdb\x99\x99\xf3\x08\x36\xd6\x9e\xb7\x01\x7a\x75\x9d\xad\x80\x98\xd6\x71\xdd\x07\x0a\xde\x6e\x25\x42\x42\xd0\xbc\xfc\x38\xdf\x58\xd3\x6f\x17\x67\xff\x5d\xe2\xbe\x9c\x37\xbe\x44\x78\xa2\xba\x99\xee\xb1\xeb\xc9\x57\x79\x72\x88\xbd\xcf\x00\xcb\xe9\x7f\x65\x7d\x77\x47\x5a\x1c\xbe\x9a\x88\xa4\x8c\x81\xea\xbf\x8c\x31\x48\x79\x7d\x7c\x05\xce\xc4\x1b\x2f\x07\x57\x80\xc6\x6a\x18\x69\xe0\x99\xdf\x08\x43\x71\x4e\x6e\x77\x0f\x1c\xb9\xa9\x86\x4d\xf6\x71\xfe\x45\x9a\x99\x42\x43\xbd\x84\x91\xc4\xd3\xfe\xb4\x16\x1d\x9c\x17\xb6\x7c\x41\xd8\x3e\xbd\x0b\x1c\x14\xa1\x67\xa9\x9f\x94\x61\x17\xe8\xd3\xb8\x63\x6a\x15\x97\xa3\x77\xe7\x9f\x55\x79\x32\x95\xc6\x3f\xfb\xc8\x4a\xd9\xd9\x9c\x66\x1d\x8b\x1f\x66\x03\xad\xff\x40\x2a\x37\xfc\x63\x91\xf4\x8f\xbc\x5a\x9e\xc8\xf5\x7a\xdb\x17\x46\xe7\xa7\x57\x76\xfb\x6e\xfc\x04\x2a\x0f\x6f\xf6\xd5\xf8\xfb\xbc\x3a\xaf\xfe\x09\x00\x00\xff\xff\xa9\x28\xf2\x96\x34\x2a\x00\x00")
func dataConfig_schema_v3JsonBytes() ([]byte, error) {
return bindataRead(
@@ -83,7 +83,7 @@
return nil, err
}
- info := bindataFileInfo{name: "data/config_schema_v3.json", size: 10301, mode: os.FileMode(436), modTime: time.Unix(1478109572, 0)}
+ info := bindataFileInfo{name: "data/config_schema_v3.json", size: 10804, mode: os.FileMode(420), modTime: time.Unix(1478512187, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -182,10 +182,9 @@
Func func() (*asset, error)
Children map[string]*bintree
}
-
var _bintree = &bintree{nil, map[string]*bintree{
- "data": {nil, map[string]*bintree{
- "config_schema_v3.json": {dataConfig_schema_v3Json, map[string]*bintree{}},
+ "data": &bintree{nil, map[string]*bintree{
+ "config_schema_v3.json": &bintree{dataConfig_schema_v3Json, map[string]*bintree{}},
}},
}}
@@ -235,3 +234,4 @@
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
+
diff --git a/vendor/github.com/aanand/compose-file/types/types.go b/vendor/github.com/aanand/compose-file/types/types.go
index 7f8c212..55ee177 100644
--- a/vendor/github.com/aanand/compose-file/types/types.go
+++ b/vendor/github.com/aanand/compose-file/types/types.go
@@ -14,7 +14,6 @@
"dns_search",
"domainname",
"external_links",
- "extra_hosts",
"ipc",
"links",
"mac_address",
@@ -24,7 +23,6 @@
"restart",
"security_opt",
"shm_size",
- "stdin_open",
"stop_signal",
"tmpfs",
}
@@ -84,6 +82,7 @@
ExternalLinks []string `mapstructure:"external_links"`
ExtraHosts map[string]string `mapstructure:"extra_hosts" compose:"list_or_dict_colon"`
Hostname string
+ HealthCheck *HealthCheckConfig
Image string
Ipc string
Labels map[string]string `compose:"list_or_dict_equals"`
@@ -124,6 +123,13 @@
Placement Placement
}
+type HealthCheckConfig struct {
+ Command []string `compose:"shell_command"`
+ Timeout string
+ Interval string
+ Retries *uint64
+}
+
type UpdateConfig struct {
Parallelism uint64
Delay time.Duration
diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go
index dc3af16..0278662 100644
--- a/vendor/github.com/docker/distribution/reference/reference.go
+++ b/vendor/github.com/docker/distribution/reference/reference.go
@@ -24,6 +24,7 @@
import (
"errors"
"fmt"
+ "path"
"strings"
"github.com/docker/distribution/digest"
@@ -218,6 +219,13 @@
if !anchoredTagRegexp.MatchString(tag) {
return nil, ErrTagInvalidFormat
}
+ if canonical, ok := name.(Canonical); ok {
+ return reference{
+ name: name.Name(),
+ tag: tag,
+ digest: canonical.Digest(),
+ }, nil
+ }
return taggedReference{
name: name.Name(),
tag: tag,
@@ -230,12 +238,34 @@
if !anchoredDigestRegexp.MatchString(digest.String()) {
return nil, ErrDigestInvalidFormat
}
+ if tagged, ok := name.(Tagged); ok {
+ return reference{
+ name: name.Name(),
+ tag: tagged.Tag(),
+ digest: digest,
+ }, nil
+ }
return canonicalReference{
name: name.Name(),
digest: digest,
}, nil
}
+// Match reports whether ref matches the specified pattern.
+// See https://godoc.org/path#Match for supported patterns.
+func Match(pattern string, ref Reference) (bool, error) {
+ matched, err := path.Match(pattern, ref.String())
+ if namedRef, isNamed := ref.(Named); isNamed && !matched {
+ matched, _ = path.Match(pattern, namedRef.Name())
+ }
+ return matched, err
+}
+
+// TrimNamed removes any tag or digest from the named reference.
+func TrimNamed(ref Named) Named {
+ return repository(ref.Name())
+}
+
func getBestReferenceType(ref reference) Reference {
if ref.name == "" {
// Allow digest only references
diff --git a/vendor/github.com/docker/distribution/registry/api/v2/headerparser.go b/vendor/github.com/docker/distribution/registry/api/v2/headerparser.go
new file mode 100644
index 0000000..9bc41a3
--- /dev/null
+++ b/vendor/github.com/docker/distribution/registry/api/v2/headerparser.go
@@ -0,0 +1,161 @@
+package v2
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+ "unicode"
+)
+
+var (
+ // according to rfc7230
+ reToken = regexp.MustCompile(`^[^"(),/:;<=>?@[\]{}[:space:][:cntrl:]]+`)
+ reQuotedValue = regexp.MustCompile(`^[^\\"]+`)
+ reEscapedCharacter = regexp.MustCompile(`^[[:blank:][:graph:]]`)
+)
+
+// parseForwardedHeader is a benevolent parser of Forwarded header defined in rfc7239. The header contains
+// a comma-separated list of forwarding key-value pairs. Each list element is set by single proxy. The
+// function parses only the first element of the list, which is set by the very first proxy. It returns a map
+// of corresponding key-value pairs and an unparsed slice of the input string.
+//
+// Examples of Forwarded header values:
+//
+// 1. Forwarded: For=192.0.2.43; Proto=https,For="[2001:db8:cafe::17]",For=unknown
+// 2. Forwarded: for="192.0.2.43:443"; host="registry.example.org", for="10.10.05.40:80"
+//
+// The first will be parsed into {"for": "192.0.2.43", "proto": "https"} while the second into
+// {"for": "192.0.2.43:443", "host": "registry.example.org"}.
+func parseForwardedHeader(forwarded string) (map[string]string, string, error) {
+ // Following are states of forwarded header parser. Any state could transition to a failure.
+ const (
+ // terminating state; can transition to Parameter
+ stateElement = iota
+ // terminating state; can transition to KeyValueDelimiter
+ stateParameter
+ // can transition to Value
+ stateKeyValueDelimiter
+ // can transition to one of { QuotedValue, PairEnd }
+ stateValue
+ // can transition to one of { EscapedCharacter, PairEnd }
+ stateQuotedValue
+ // can transition to one of { QuotedValue }
+ stateEscapedCharacter
+ // terminating state; can transition to one of { Parameter, Element }
+ statePairEnd
+ )
+
+ var (
+ parameter string
+ value string
+ parse = forwarded[:]
+ res = map[string]string{}
+ state = stateElement
+ )
+
+Loop:
+ for {
+ // skip spaces unless in quoted value
+ if state != stateQuotedValue && state != stateEscapedCharacter {
+ parse = strings.TrimLeftFunc(parse, unicode.IsSpace)
+ }
+
+ if len(parse) == 0 {
+ if state != stateElement && state != statePairEnd && state != stateParameter {
+ return nil, parse, fmt.Errorf("unexpected end of input")
+ }
+ // terminating
+ break
+ }
+
+ switch state {
+ // terminate at list element delimiter
+ case stateElement:
+ if parse[0] == ',' {
+ parse = parse[1:]
+ break Loop
+ }
+ state = stateParameter
+
+ // parse parameter (the key of key-value pair)
+ case stateParameter:
+ match := reToken.FindString(parse)
+ if len(match) == 0 {
+ return nil, parse, fmt.Errorf("failed to parse token at position %d", len(forwarded)-len(parse))
+ }
+ parameter = strings.ToLower(match)
+ parse = parse[len(match):]
+ state = stateKeyValueDelimiter
+
+ // parse '='
+ case stateKeyValueDelimiter:
+ if parse[0] != '=' {
+ return nil, parse, fmt.Errorf("expected '=', not '%c' at position %d", parse[0], len(forwarded)-len(parse))
+ }
+ parse = parse[1:]
+ state = stateValue
+
+ // parse value or quoted value
+ case stateValue:
+ if parse[0] == '"' {
+ parse = parse[1:]
+ state = stateQuotedValue
+ } else {
+ value = reToken.FindString(parse)
+ if len(value) == 0 {
+ return nil, parse, fmt.Errorf("failed to parse value at position %d", len(forwarded)-len(parse))
+ }
+ if _, exists := res[parameter]; exists {
+ return nil, parse, fmt.Errorf("duplicate parameter %q at position %d", parameter, len(forwarded)-len(parse))
+ }
+ res[parameter] = value
+ parse = parse[len(value):]
+ value = ""
+ state = statePairEnd
+ }
+
+ // parse a part of quoted value until the first backslash
+ case stateQuotedValue:
+ match := reQuotedValue.FindString(parse)
+ value += match
+ parse = parse[len(match):]
+ switch {
+ case len(parse) == 0:
+ return nil, parse, fmt.Errorf("unterminated quoted string")
+ case parse[0] == '"':
+ res[parameter] = value
+ value = ""
+ parse = parse[1:]
+ state = statePairEnd
+ case parse[0] == '\\':
+ parse = parse[1:]
+ state = stateEscapedCharacter
+ }
+
+ // parse escaped character in a quoted string, ignore the backslash
+ // transition back to QuotedValue state
+ case stateEscapedCharacter:
+ c := reEscapedCharacter.FindString(parse)
+ if len(c) == 0 {
+ return nil, parse, fmt.Errorf("invalid escape sequence at position %d", len(forwarded)-len(parse)-1)
+ }
+ value += c
+ parse = parse[1:]
+ state = stateQuotedValue
+
+ // expect either a new key-value pair, new list or end of input
+ case statePairEnd:
+ switch parse[0] {
+ case ';':
+ parse = parse[1:]
+ state = stateParameter
+ case ',':
+ state = stateElement
+ default:
+ return nil, parse, fmt.Errorf("expected ',' or ';', not %c at position %d", parse[0], len(forwarded)-len(parse))
+ }
+ }
+ }
+
+ return res, parse, nil
+}
diff --git a/vendor/github.com/docker/distribution/registry/api/v2/urls.go b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
index a959aaa..e2e242e 100644
--- a/vendor/github.com/docker/distribution/registry/api/v2/urls.go
+++ b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
@@ -1,8 +1,10 @@
package v2
import (
+ "net"
"net/http"
"net/url"
+ "strconv"
"strings"
"github.com/docker/distribution/reference"
@@ -49,10 +51,14 @@
var scheme string
forwardedProto := r.Header.Get("X-Forwarded-Proto")
+ // TODO: log the error
+ forwardedHeader, _, _ := parseForwardedHeader(r.Header.Get("Forwarded"))
switch {
case len(forwardedProto) > 0:
scheme = forwardedProto
+ case len(forwardedHeader["proto"]) > 0:
+ scheme = forwardedHeader["proto"]
case r.TLS != nil:
scheme = "https"
case len(r.URL.Scheme) > 0:
@@ -62,14 +68,46 @@
}
host := r.Host
- forwardedHost := r.Header.Get("X-Forwarded-Host")
- if len(forwardedHost) > 0 {
+
+ if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
// According to the Apache mod_proxy docs, X-Forwarded-Host can be a
// comma-separated list of hosts, to which each proxy appends the
// requested host. We want to grab the first from this comma-separated
// list.
hosts := strings.SplitN(forwardedHost, ",", 2)
host = strings.TrimSpace(hosts[0])
+ } else if addr, exists := forwardedHeader["for"]; exists {
+ host = addr
+ } else if h, exists := forwardedHeader["host"]; exists {
+ host = h
+ }
+
+ portLessHost, port := host, ""
+ if !isIPv6Address(portLessHost) {
+ // with go 1.6, this would treat the last part of IPv6 address as a port
+ portLessHost, port, _ = net.SplitHostPort(host)
+ }
+ if forwardedPort := r.Header.Get("X-Forwarded-Port"); len(port) == 0 && len(forwardedPort) > 0 {
+ ports := strings.SplitN(forwardedPort, ",", 2)
+ forwardedPort = strings.TrimSpace(ports[0])
+ if _, err := strconv.ParseInt(forwardedPort, 10, 32); err == nil {
+ port = forwardedPort
+ }
+ }
+
+ if len(portLessHost) > 0 {
+ host = portLessHost
+ }
+ if len(port) > 0 {
+ // remove enclosing brackets of ipv6 address otherwise they will be duplicated
+ if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
+ host = host[1 : len(host)-1]
+ }
+ // JoinHostPort properly encloses ipv6 addresses in square brackets
+ host = net.JoinHostPort(host, port)
+ } else if isIPv6Address(host) && host[0] != '[' {
+ // ipv6 needs to be enclosed in square brackets in urls
+ host = "[" + host + "]"
}
basePath := routeDescriptorsMap[RouteNameBase].Path
@@ -249,3 +287,28 @@
return appendValuesURL(up, values...).String()
}
+
+// isIPv6Address returns true if given string is a valid IPv6 address. No port is allowed. The address may be
+// enclosed in square brackets.
+func isIPv6Address(host string) bool {
+ if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
+ host = host[1 : len(host)-1]
+ }
+ // The IPv6 scoped addressing zone identifier starts after the last percent sign.
+ if i := strings.LastIndexByte(host, '%'); i > 0 {
+ host = host[:i]
+ }
+ ip := net.ParseIP(host)
+ if ip == nil {
+ return false
+ }
+ if ip.To16() == nil {
+ return false
+ }
+ if ip.To4() == nil {
+ return true
+ }
+ // dot can be present in ipv4-mapped address, it needs to come after a colon though
+ i := strings.IndexAny(host, ":.")
+ return i >= 0 && host[i] == ':'
+}
diff --git a/vendor/github.com/docker/distribution/registry/client/auth/addr.go b/vendor/github.com/docker/distribution/registry/client/auth/challenge/addr.go
similarity index 97%
rename from vendor/github.com/docker/distribution/registry/client/auth/addr.go
rename to vendor/github.com/docker/distribution/registry/client/auth/challenge/addr.go
index 6e77752..2c3ebe1 100644
--- a/vendor/github.com/docker/distribution/registry/client/auth/addr.go
+++ b/vendor/github.com/docker/distribution/registry/client/auth/challenge/addr.go
@@ -1,4 +1,4 @@
-package auth
+package challenge
import (
"net/url"
diff --git a/vendor/github.com/docker/distribution/registry/client/auth/authchallenge.go b/vendor/github.com/docker/distribution/registry/client/auth/challenge/authchallenge.go
similarity index 91%
rename from vendor/github.com/docker/distribution/registry/client/auth/authchallenge.go
rename to vendor/github.com/docker/distribution/registry/client/auth/challenge/authchallenge.go
index 69d9d6f..c9bdfc3 100644
--- a/vendor/github.com/docker/distribution/registry/client/auth/authchallenge.go
+++ b/vendor/github.com/docker/distribution/registry/client/auth/challenge/authchallenge.go
@@ -1,4 +1,4 @@
-package auth
+package challenge
import (
"fmt"
@@ -18,12 +18,12 @@
Parameters map[string]string
}
-// ChallengeManager manages the challenges for endpoints.
+// Manager manages the challenges for endpoints.
// The challenges are pulled out of HTTP responses. Only
// responses which expect challenges should be added to
// the manager, since a non-unauthorized request will be
// viewed as not requiring challenges.
-type ChallengeManager interface {
+type Manager interface {
// GetChallenges returns the challenges for the given
// endpoint URL.
GetChallenges(endpoint url.URL) ([]Challenge, error)
@@ -37,19 +37,19 @@
AddResponse(resp *http.Response) error
}
-// NewSimpleChallengeManager returns an instance of
-// ChallengeManger which only maps endpoints to challenges
+// NewSimpleManager returns an instance of
+// Manger which only maps endpoints to challenges
// based on the responses which have been added the
// manager. The simple manager will make no attempt to
// perform requests on the endpoints or cache the responses
// to a backend.
-func NewSimpleChallengeManager() ChallengeManager {
- return &simpleChallengeManager{
+func NewSimpleManager() Manager {
+ return &simpleManager{
Challanges: make(map[string][]Challenge),
}
}
-type simpleChallengeManager struct {
+type simpleManager struct {
sync.RWMutex
Challanges map[string][]Challenge
}
@@ -59,7 +59,7 @@
endpoint.Host = canonicalAddr(endpoint)
}
-func (m *simpleChallengeManager) GetChallenges(endpoint url.URL) ([]Challenge, error) {
+func (m *simpleManager) GetChallenges(endpoint url.URL) ([]Challenge, error) {
normalizeURL(&endpoint)
m.RLock()
@@ -68,7 +68,7 @@
return challenges, nil
}
-func (m *simpleChallengeManager) AddResponse(resp *http.Response) error {
+func (m *simpleManager) AddResponse(resp *http.Response) error {
challenges := ResponseChallenges(resp)
if resp.Request == nil {
return fmt.Errorf("missing request reference")
diff --git a/vendor/github.com/docker/distribution/registry/client/auth/session.go b/vendor/github.com/docker/distribution/registry/client/auth/session.go
index d03d8ff..ffc3384 100644
--- a/vendor/github.com/docker/distribution/registry/client/auth/session.go
+++ b/vendor/github.com/docker/distribution/registry/client/auth/session.go
@@ -12,6 +12,7 @@
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/registry/client"
+ "github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
)
@@ -58,7 +59,7 @@
// schemes. The handlers are tried in order, the higher priority authentication
// methods should be first. The challengeMap holds a list of challenges for
// a given root API endpoint (for example "https://registry-1.docker.io/v2/").
-func NewAuthorizer(manager ChallengeManager, handlers ...AuthenticationHandler) transport.RequestModifier {
+func NewAuthorizer(manager challenge.Manager, handlers ...AuthenticationHandler) transport.RequestModifier {
return &endpointAuthorizer{
challenges: manager,
handlers: handlers,
@@ -66,7 +67,7 @@
}
type endpointAuthorizer struct {
- challenges ChallengeManager
+ challenges challenge.Manager
handlers []AuthenticationHandler
transport http.RoundTripper
}
@@ -94,11 +95,11 @@
if len(challenges) > 0 {
for _, handler := range ea.handlers {
- for _, challenge := range challenges {
- if challenge.Scheme != handler.Scheme() {
+ for _, c := range challenges {
+ if c.Scheme != handler.Scheme() {
continue
}
- if err := handler.AuthorizeRequest(req, challenge.Parameters); err != nil {
+ if err := handler.AuthorizeRequest(req, c.Parameters); err != nil {
return err
}
}
diff --git a/vendor/github.com/docker/distribution/registry/client/errors.go b/vendor/github.com/docker/distribution/registry/client/errors.go
index f73e3c2..52d49d5 100644
--- a/vendor/github.com/docker/distribution/registry/client/errors.go
+++ b/vendor/github.com/docker/distribution/registry/client/errors.go
@@ -9,6 +9,7 @@
"net/http"
"github.com/docker/distribution/registry/api/errcode"
+ "github.com/docker/distribution/registry/client/auth/challenge"
)
// ErrNoErrorsInBody is returned when an HTTP response body parses to an empty
@@ -82,21 +83,52 @@
return errors
}
+func makeErrorList(err error) []error {
+ if errL, ok := err.(errcode.Errors); ok {
+ return []error(errL)
+ }
+ return []error{err}
+}
+
+func mergeErrors(err1, err2 error) error {
+ return errcode.Errors(append(makeErrorList(err1), makeErrorList(err2)...))
+}
+
// HandleErrorResponse returns error parsed from HTTP response for an
// unsuccessful HTTP response code (in the range 400 - 499 inclusive). An
// UnexpectedHTTPStatusError returned for response code outside of expected
// range.
func HandleErrorResponse(resp *http.Response) error {
- if resp.StatusCode == 401 {
+ if resp.StatusCode >= 400 && resp.StatusCode < 500 {
+ // Check for OAuth errors within the `WWW-Authenticate` header first
+ // See https://tools.ietf.org/html/rfc6750#section-3
+ for _, c := range challenge.ResponseChallenges(resp) {
+ if c.Scheme == "bearer" {
+ var err errcode.Error
+ // codes defined at https://tools.ietf.org/html/rfc6750#section-3.1
+ switch c.Parameters["error"] {
+ case "invalid_token":
+ err.Code = errcode.ErrorCodeUnauthorized
+ case "insufficient_scope":
+ err.Code = errcode.ErrorCodeDenied
+ default:
+ continue
+ }
+ if description := c.Parameters["error_description"]; description != "" {
+ err.Message = description
+ } else {
+ err.Message = err.Code.Message()
+ }
+
+ return mergeErrors(err, parseHTTPErrorResponse(resp.StatusCode, resp.Body))
+ }
+ }
err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
- if uErr, ok := err.(*UnexpectedHTTPResponseError); ok {
+ if uErr, ok := err.(*UnexpectedHTTPResponseError); ok && resp.StatusCode == 401 {
return errcode.ErrorCodeUnauthorized.WithDetail(uErr.Response)
}
return err
}
- if resp.StatusCode >= 400 && resp.StatusCode < 500 {
- return parseHTTPErrorResponse(resp.StatusCode, resp.Body)
- }
return &UnexpectedHTTPStatusError{Status: resp.Status}
}
diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
index 2518030..087398e 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
@@ -24,6 +24,15 @@
// NetworkDB instance drives the networkdb cluster and acts the broker
// for cluster-scoped and network-scoped gossip and watches.
type NetworkDB struct {
+ // The clocks MUST be the first things
+ // in this struct due to Golang issue #599.
+
+ // Global lamport clock for node network attach events.
+ networkClock serf.LamportClock
+
+ // Global lamport clock for table events.
+ tableClock serf.LamportClock
+
sync.RWMutex
// NetworkDB configuration.
@@ -59,12 +68,6 @@
// waiting for an ack.
bulkSyncAckTbl map[string]chan struct{}
- // Global lamport clock for node network attach events.
- networkClock serf.LamportClock
-
- // Global lamport clock for table events.
- tableClock serf.LamportClock
-
// Broadcast queue for network event gossip.
networkBroadcasts *memberlist.TransmitLimitedQueue
diff --git a/vendor/github.com/docker/swarmkit/api/specs.pb.go b/vendor/github.com/docker/swarmkit/api/specs.pb.go
index 30f573e..146fa8c 100644
--- a/vendor/github.com/docker/swarmkit/api/specs.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/specs.pb.go
@@ -477,8 +477,10 @@
Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
// TTY declares that a TTY should be attached to the standard streams,
// including stdin if it is still open.
- TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
- Mounts []Mount `protobuf:"bytes,8,rep,name=mounts" json:"mounts"`
+ TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
+ // OpenStdin declares that the standard input (stdin) should be open.
+ OpenStdin bool `protobuf:"varint,18,opt,name=open_stdin,json=openStdin,proto3" json:"open_stdin,omitempty"`
+ Mounts []Mount `protobuf:"bytes,8,rep,name=mounts" json:"mounts"`
// StopGracePeriod the grace period for stopping the container before
// forcefully killing the container.
StopGracePeriod *docker_swarmkit_v11.Duration `protobuf:"bytes,9,opt,name=stop_grace_period,json=stopGracePeriod" json:"stop_grace_period,omitempty"`
@@ -491,10 +493,12 @@
// that associates IP addresses with hostnames.
// Detailed documentation is available in:
// http://man7.org/linux/man-pages/man5/hosts.5.html
- // The format of the Hosts here could be:
- // <hostname>:<ip> (separated by `:`)
- // <hostname>=<ip> (separated by `=`)
- // <hostname> <ip> (separated by ` `)
+ // IP_address canonical_hostname [aliases...]
+ //
+ // The format of the Hosts in swarmkit follows the same as
+ // above.
+ // This is different from `docker run --add-host <hostname>:<ip>`
+ // where format is `<hostname>:<ip>`
Hosts []string `protobuf:"bytes,17,rep,name=hosts" json:"hosts,omitempty"`
// DNSConfig allows one to specify DNS related configuration in resolv.conf
DNSConfig *ContainerSpec_DNSConfig `protobuf:"bytes,15,opt,name=dns_config,json=dnsConfig" json:"dns_config,omitempty"`
@@ -769,6 +773,7 @@
Dir: m.Dir,
User: m.User,
TTY: m.TTY,
+ OpenStdin: m.OpenStdin,
StopGracePeriod: m.StopGracePeriod.Copy(),
PullOptions: m.PullOptions.Copy(),
DNSConfig: m.DNSConfig.Copy(),
@@ -1058,7 +1063,7 @@
if this == nil {
return "nil"
}
- s := make([]string, 0, 21)
+ s := make([]string, 0, 22)
s = append(s, "&api.ContainerSpec{")
s = append(s, "Image: "+fmt.Sprintf("%#v", this.Image)+",\n")
keysForLabels := make([]string, 0, len(this.Labels))
@@ -1082,6 +1087,7 @@
s = append(s, "User: "+fmt.Sprintf("%#v", this.User)+",\n")
s = append(s, "Groups: "+fmt.Sprintf("%#v", this.Groups)+",\n")
s = append(s, "TTY: "+fmt.Sprintf("%#v", this.TTY)+",\n")
+ s = append(s, "OpenStdin: "+fmt.Sprintf("%#v", this.OpenStdin)+",\n")
if this.Mounts != nil {
s = append(s, "Mounts: "+fmt.Sprintf("%#v", this.Mounts)+",\n")
}
@@ -1738,6 +1744,18 @@
i += copy(data[i:], s)
}
}
+ if m.OpenStdin {
+ data[i] = 0x90
+ i++
+ data[i] = 0x1
+ i++
+ if m.OpenStdin {
+ data[i] = 1
+ } else {
+ data[i] = 0
+ }
+ i++
+ }
return i, nil
}
@@ -2310,6 +2328,9 @@
n += 2 + l + sovSpecs(uint64(l))
}
}
+ if m.OpenStdin {
+ n += 3
+ }
return n
}
@@ -2579,6 +2600,7 @@
`DNSConfig:` + strings.Replace(fmt.Sprintf("%v", this.DNSConfig), "ContainerSpec_DNSConfig", "ContainerSpec_DNSConfig", 1) + `,`,
`Healthcheck:` + strings.Replace(fmt.Sprintf("%v", this.Healthcheck), "HealthConfig", "HealthConfig", 1) + `,`,
`Hosts:` + fmt.Sprintf("%v", this.Hosts) + `,`,
+ `OpenStdin:` + fmt.Sprintf("%v", this.OpenStdin) + `,`,
`}`,
}, "")
return s
@@ -4189,6 +4211,26 @@
}
m.Hosts = append(m.Hosts, string(data[iNdEx:postIndex]))
iNdEx = postIndex
+ case 18:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OpenStdin", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowSpecs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := data[iNdEx]
+ iNdEx++
+ v |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.OpenStdin = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipSpecs(data[iNdEx:])
@@ -5241,107 +5283,108 @@
func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
var fileDescriptorSpecs = []byte{
- // 1620 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0xcd, 0x72, 0xdb, 0xc8,
- 0x11, 0x26, 0x24, 0x8a, 0x3f, 0x0d, 0xca, 0xa6, 0xa6, 0xf6, 0x07, 0xe6, 0x6e, 0x48, 0x9a, 0xeb,
- 0x6c, 0xb4, 0xd9, 0x8a, 0x9c, 0x30, 0xa9, 0x8d, 0x37, 0xce, 0x56, 0xc2, 0xbf, 0xc8, 0x8c, 0x22,
- 0x2d, 0x6b, 0xa4, 0x75, 0xca, 0x27, 0xd6, 0x08, 0x18, 0x91, 0x28, 0x81, 0x18, 0x64, 0x30, 0xe0,
- 0x16, 0x6f, 0x39, 0x6e, 0xf9, 0x90, 0x37, 0xf0, 0x29, 0xcf, 0x90, 0x4b, 0x9e, 0xc0, 0xc7, 0x1c,
- 0x73, 0x52, 0xc5, 0x7c, 0x82, 0x54, 0xe5, 0x01, 0x92, 0x9a, 0xc1, 0x00, 0x04, 0x77, 0xa1, 0xb5,
- 0xab, 0xe2, 0xdb, 0x4c, 0xe3, 0xfb, 0x1a, 0x3d, 0x3d, 0x1f, 0xba, 0x1b, 0x60, 0x86, 0x01, 0xb5,
- 0xc3, 0xa3, 0x80, 0x33, 0xc1, 0x10, 0x72, 0x98, 0x7d, 0x4d, 0xf9, 0x51, 0xf8, 0x35, 0xe1, 0x8b,
- 0x6b, 0x57, 0x1c, 0x2d, 0x7f, 0xd6, 0x30, 0xc5, 0x2a, 0xa0, 0x1a, 0xd0, 0x78, 0x67, 0xc6, 0x66,
- 0x4c, 0x2d, 0x1f, 0xca, 0x95, 0xb6, 0xbe, 0xef, 0x44, 0x9c, 0x08, 0x97, 0xf9, 0x0f, 0x93, 0x45,
- 0xfc, 0xa0, 0xf3, 0x97, 0x22, 0x54, 0xce, 0x98, 0x43, 0xcf, 0x03, 0x6a, 0xa3, 0x63, 0x30, 0x89,
- 0xef, 0x33, 0xa1, 0x00, 0xa1, 0x65, 0xb4, 0x8d, 0x43, 0xb3, 0xdb, 0x3a, 0xfa, 0xee, 0x2b, 0x8f,
- 0x7a, 0x1b, 0x58, 0xbf, 0xf8, 0xf2, 0xa6, 0x55, 0xc0, 0x59, 0x26, 0xfa, 0x29, 0x14, 0x39, 0xf3,
- 0xa8, 0xb5, 0xd3, 0x36, 0x0e, 0xef, 0x74, 0x3f, 0xcc, 0xf3, 0x20, 0x5f, 0x8a, 0x99, 0x47, 0xb1,
- 0x42, 0xa2, 0x63, 0x80, 0x05, 0x5d, 0x5c, 0x52, 0x1e, 0xce, 0xdd, 0xc0, 0xda, 0x55, 0xbc, 0x1f,
- 0xdd, 0xc6, 0x93, 0xc1, 0x1e, 0x9d, 0xa6, 0x70, 0x9c, 0xa1, 0xa2, 0x53, 0xa8, 0x91, 0x25, 0x71,
- 0x3d, 0x72, 0xe9, 0x7a, 0xae, 0x58, 0x59, 0x45, 0xe5, 0xea, 0x93, 0xef, 0x75, 0xd5, 0xcb, 0x10,
- 0xf0, 0x16, 0xbd, 0xe3, 0x00, 0x6c, 0x5e, 0x84, 0x3e, 0x86, 0xf2, 0x64, 0x74, 0x36, 0x1c, 0x9f,
- 0x1d, 0xd7, 0x0b, 0x8d, 0x7b, 0xcf, 0x5f, 0xb4, 0xdf, 0x95, 0x3e, 0x36, 0x80, 0x09, 0xf5, 0x1d,
- 0xd7, 0x9f, 0xa1, 0x43, 0xa8, 0xf4, 0x06, 0x83, 0xd1, 0xe4, 0x62, 0x34, 0xac, 0x1b, 0x8d, 0xc6,
- 0xf3, 0x17, 0xed, 0xf7, 0xb6, 0x81, 0x3d, 0xdb, 0xa6, 0x81, 0xa0, 0x4e, 0xa3, 0xf8, 0xcd, 0x5f,
- 0x9b, 0x85, 0xce, 0x37, 0x06, 0xd4, 0xb2, 0x41, 0xa0, 0x8f, 0xa1, 0xd4, 0x1b, 0x5c, 0x8c, 0x9f,
- 0x8e, 0xea, 0x85, 0x0d, 0x3d, 0x8b, 0xe8, 0xd9, 0xc2, 0x5d, 0x52, 0xf4, 0x00, 0xf6, 0x26, 0xbd,
- 0xaf, 0xce, 0x47, 0x75, 0x63, 0x13, 0x4e, 0x16, 0x36, 0x21, 0x51, 0xa8, 0x50, 0x43, 0xdc, 0x1b,
- 0x9f, 0xd5, 0x77, 0xf2, 0x51, 0x43, 0x4e, 0x5c, 0x5f, 0x87, 0xf2, 0x6a, 0x17, 0xcc, 0x73, 0xca,
- 0x97, 0xae, 0xfd, 0x96, 0x35, 0xf1, 0x19, 0x14, 0x05, 0x09, 0xaf, 0x95, 0x26, 0xcc, 0x7c, 0x4d,
- 0x5c, 0x90, 0xf0, 0x5a, 0xbe, 0x54, 0xd3, 0x15, 0x5e, 0x2a, 0x83, 0xd3, 0xc0, 0x73, 0x6d, 0x22,
- 0xa8, 0xa3, 0x94, 0x61, 0x76, 0x7f, 0x98, 0xc7, 0xc6, 0x29, 0x4a, 0xc7, 0xff, 0xa4, 0x80, 0x33,
- 0x54, 0xf4, 0x18, 0x4a, 0x33, 0x8f, 0x5d, 0x12, 0x4f, 0x69, 0xc2, 0xec, 0xde, 0xcf, 0x73, 0x72,
- 0xac, 0x10, 0x1b, 0x07, 0x9a, 0x82, 0x1e, 0x41, 0x29, 0x0a, 0x1c, 0x22, 0xa8, 0x55, 0x52, 0xe4,
- 0x76, 0x1e, 0xf9, 0x2b, 0x85, 0x18, 0x30, 0xff, 0xca, 0x9d, 0x61, 0x8d, 0x47, 0x27, 0x50, 0xf1,
- 0xa9, 0xf8, 0x9a, 0xf1, 0xeb, 0xd0, 0x2a, 0xb7, 0x77, 0x0f, 0xcd, 0xee, 0xa7, 0xb9, 0x62, 0x8c,
- 0x31, 0x3d, 0x21, 0x88, 0x3d, 0x5f, 0x50, 0x5f, 0xc4, 0x6e, 0xfa, 0x3b, 0x96, 0x81, 0x53, 0x07,
- 0xe8, 0xd7, 0x50, 0xa1, 0xbe, 0x13, 0x30, 0xd7, 0x17, 0x56, 0xe5, 0xf6, 0x40, 0x46, 0x1a, 0x23,
- 0x93, 0x89, 0x53, 0x46, 0xbf, 0x04, 0xc5, 0x05, 0x73, 0x68, 0xe7, 0x21, 0x1c, 0x7c, 0x27, 0x59,
- 0xa8, 0x01, 0x15, 0x9d, 0xac, 0xf8, 0x96, 0x8b, 0x38, 0xdd, 0x77, 0xee, 0xc2, 0xfe, 0x56, 0x62,
- 0x54, 0xd9, 0x48, 0x6e, 0x0b, 0xf5, 0xa0, 0x6a, 0x33, 0x5f, 0x10, 0xd7, 0xa7, 0x5c, 0x0b, 0x24,
- 0x37, 0xb7, 0x83, 0x04, 0x24, 0x59, 0x4f, 0x0a, 0x78, 0xc3, 0x42, 0xbf, 0x83, 0x2a, 0xa7, 0x21,
- 0x8b, 0xb8, 0x4d, 0x43, 0xad, 0x90, 0xc3, 0xfc, 0x3b, 0x8e, 0x41, 0x98, 0xfe, 0x29, 0x72, 0x39,
- 0x95, 0x79, 0x0a, 0xf1, 0x86, 0x8a, 0x1e, 0x43, 0x99, 0xd3, 0x50, 0x10, 0x2e, 0xbe, 0xef, 0x92,
- 0x71, 0x0c, 0x99, 0x30, 0xcf, 0xb5, 0x57, 0x38, 0x61, 0xa0, 0xc7, 0x50, 0x0d, 0x3c, 0x62, 0x2b,
- 0xaf, 0xd6, 0x9e, 0xa2, 0xff, 0x20, 0x8f, 0x3e, 0x49, 0x40, 0x78, 0x83, 0x47, 0x9f, 0x03, 0x78,
- 0x6c, 0x36, 0x75, 0xb8, 0xbb, 0xa4, 0x5c, 0x8b, 0xa4, 0x91, 0xc7, 0x1e, 0x2a, 0x04, 0xae, 0x7a,
- 0x6c, 0x16, 0x2f, 0xd1, 0xf1, 0xff, 0xa5, 0x90, 0x8c, 0x3a, 0x4e, 0x00, 0x48, 0xfa, 0x54, 0xeb,
- 0xe3, 0x93, 0x37, 0x72, 0xa5, 0x6f, 0x24, 0x43, 0x47, 0xf7, 0xa1, 0x76, 0xc5, 0xb8, 0x4d, 0xa7,
- 0x5a, 0xf7, 0x55, 0xa5, 0x09, 0x53, 0xd9, 0x62, 0xa1, 0xf7, 0xab, 0x50, 0xe6, 0x91, 0x2f, 0xdc,
- 0x05, 0xed, 0x9c, 0xc0, 0xbb, 0xb9, 0x4e, 0x51, 0x17, 0x6a, 0xe9, 0x35, 0x4f, 0x5d, 0x47, 0xe9,
- 0xa3, 0xda, 0xbf, 0xbb, 0xbe, 0x69, 0x99, 0xa9, 0x1e, 0xc6, 0x43, 0x6c, 0xa6, 0xa0, 0xb1, 0xd3,
- 0xf9, 0x7b, 0x19, 0xf6, 0xb7, 0xc4, 0x82, 0xde, 0x81, 0x3d, 0x77, 0x41, 0x66, 0x34, 0xa6, 0xe3,
- 0x78, 0x83, 0x46, 0x50, 0xf2, 0xc8, 0x25, 0xf5, 0xa4, 0x64, 0x64, 0xda, 0x7e, 0xf2, 0x5a, 0xd5,
- 0x1d, 0xfd, 0x41, 0xe1, 0x47, 0xbe, 0xe0, 0x2b, 0xac, 0xc9, 0xc8, 0x82, 0xb2, 0xcd, 0x16, 0x0b,
- 0xe2, 0xcb, 0xf2, 0xb2, 0x7b, 0x58, 0xc5, 0xc9, 0x16, 0x21, 0x28, 0x12, 0x3e, 0x0b, 0xad, 0xa2,
- 0x32, 0xab, 0x35, 0xaa, 0xc3, 0x2e, 0xf5, 0x97, 0xd6, 0x9e, 0x32, 0xc9, 0xa5, 0xb4, 0x38, 0x6e,
- 0x7c, 0xe7, 0x55, 0x2c, 0x97, 0x92, 0x17, 0x85, 0x94, 0x5b, 0x65, 0x65, 0x52, 0x6b, 0xf4, 0x4b,
- 0x28, 0x2d, 0x58, 0xe4, 0x8b, 0xd0, 0xaa, 0xa8, 0x60, 0xef, 0xe5, 0x05, 0x7b, 0x2a, 0x11, 0xba,
- 0xfc, 0x69, 0x38, 0x7a, 0x02, 0x07, 0xa1, 0x60, 0xc1, 0x74, 0xc6, 0x89, 0x4d, 0xa7, 0x01, 0xe5,
- 0x2e, 0x73, 0xd4, 0x6d, 0xdc, 0x52, 0x45, 0x87, 0xba, 0xc3, 0xe3, 0xbb, 0x92, 0x76, 0x2c, 0x59,
- 0x13, 0x45, 0x42, 0x13, 0xa8, 0x05, 0x91, 0xe7, 0x4d, 0x59, 0x10, 0x17, 0x73, 0x50, 0x4e, 0xde,
- 0x20, 0x6b, 0x93, 0xc8, 0xf3, 0xbe, 0x8c, 0x49, 0xd8, 0x0c, 0x36, 0x1b, 0xf4, 0x1e, 0x94, 0x66,
- 0x9c, 0x45, 0x41, 0x68, 0x99, 0x2a, 0x1f, 0x7a, 0x87, 0xbe, 0x80, 0x72, 0x48, 0x6d, 0x4e, 0x45,
- 0x68, 0xd5, 0xd4, 0x69, 0x3f, 0xca, 0x7b, 0xc9, 0xb9, 0x82, 0x60, 0x7a, 0x45, 0x39, 0xf5, 0x6d,
- 0x8a, 0x13, 0x0e, 0xba, 0x07, 0xbb, 0x42, 0xac, 0xac, 0xfd, 0xb6, 0x71, 0x58, 0xe9, 0x97, 0xd7,
- 0x37, 0xad, 0xdd, 0x8b, 0x8b, 0x67, 0x58, 0xda, 0x64, 0x99, 0x9a, 0xb3, 0x50, 0xf8, 0x64, 0x41,
- 0xad, 0x3b, 0x2a, 0xbd, 0xe9, 0x1e, 0x3d, 0x03, 0x70, 0xfc, 0x70, 0x6a, 0xab, 0xef, 0xc2, 0xba,
- 0xab, 0x4e, 0xf7, 0xe9, 0xeb, 0x4f, 0x37, 0x3c, 0x3b, 0xd7, 0xc5, 0x76, 0x7f, 0x7d, 0xd3, 0xaa,
- 0xa6, 0x5b, 0x5c, 0x75, 0xfc, 0x30, 0x5e, 0xa2, 0x3e, 0x98, 0x73, 0x4a, 0x3c, 0x31, 0xb7, 0xe7,
- 0xd4, 0xbe, 0xb6, 0xea, 0xb7, 0xd7, 0xde, 0x27, 0x0a, 0xa6, 0x3d, 0x64, 0x49, 0x52, 0xc4, 0x32,
- 0xd4, 0xd0, 0x3a, 0x50, 0xb9, 0x8a, 0x37, 0x8d, 0xcf, 0xc1, 0xcc, 0x88, 0x52, 0x8a, 0xe9, 0x9a,
- 0xae, 0xb4, 0xce, 0xe5, 0x52, 0xd2, 0x96, 0xc4, 0x8b, 0xe2, 0x69, 0xaa, 0x8a, 0xe3, 0xcd, 0xaf,
- 0x76, 0x1e, 0x19, 0x8d, 0x2e, 0x98, 0x99, 0x9b, 0x41, 0x1f, 0xc1, 0x3e, 0xa7, 0x33, 0x37, 0x14,
- 0x7c, 0x35, 0x25, 0x91, 0x98, 0x5b, 0xbf, 0x55, 0x84, 0x5a, 0x62, 0xec, 0x45, 0x62, 0xde, 0x98,
- 0xc2, 0xe6, 0x80, 0xa8, 0x0d, 0xa6, 0x4c, 0x5c, 0x48, 0xf9, 0x92, 0x72, 0x59, 0xf6, 0x65, 0x5c,
- 0x59, 0x93, 0xbc, 0xe0, 0x90, 0x12, 0x6e, 0xcf, 0xd5, 0x27, 0x56, 0xc5, 0x7a, 0x27, 0xbf, 0x99,
- 0x44, 0x45, 0xfa, 0x9b, 0xd1, 0xdb, 0xce, 0x7f, 0x0c, 0xa8, 0x65, 0xfb, 0x0f, 0x1a, 0xc4, 0x5d,
- 0x47, 0x1d, 0xe9, 0x4e, 0xf7, 0xe1, 0xeb, 0xfa, 0x95, 0xaa, 0xf1, 0x5e, 0x24, 0x9d, 0x9d, 0xca,
- 0x19, 0x51, 0x91, 0xd1, 0x2f, 0x60, 0x2f, 0x60, 0x5c, 0x24, 0x5f, 0x7a, 0x33, 0xb7, 0x2e, 0x33,
- 0x9e, 0xd4, 0xc4, 0x18, 0xdc, 0x99, 0xc3, 0x9d, 0x6d, 0x6f, 0xe8, 0x01, 0xec, 0x3e, 0x1d, 0x4f,
- 0xea, 0x85, 0xc6, 0x07, 0xcf, 0x5f, 0xb4, 0xdf, 0xdf, 0x7e, 0xf8, 0xd4, 0xe5, 0x22, 0x22, 0xde,
- 0x78, 0x82, 0x7e, 0x0c, 0x7b, 0xc3, 0xb3, 0x73, 0x8c, 0xeb, 0x46, 0xa3, 0xf5, 0xfc, 0x45, 0xfb,
- 0x83, 0x6d, 0x9c, 0x7c, 0xc4, 0x22, 0xdf, 0xc1, 0xec, 0x32, 0x1d, 0x9b, 0xfe, 0xb6, 0x03, 0xa6,
- 0x2e, 0x80, 0x6f, 0x77, 0x6c, 0xfa, 0x0d, 0xec, 0xc7, 0x3d, 0x25, 0x91, 0xf5, 0xce, 0x6b, 0x5b,
- 0x4b, 0x2d, 0x26, 0xe8, 0x3b, 0xbe, 0x0f, 0x35, 0x37, 0x58, 0x7e, 0x36, 0xa5, 0x3e, 0xb9, 0xf4,
- 0xf4, 0x04, 0x55, 0xc1, 0xa6, 0xb4, 0x8d, 0x62, 0x93, 0xfc, 0xa6, 0x5c, 0x5f, 0x50, 0xee, 0xeb,
- 0xd9, 0xa8, 0x82, 0xd3, 0x3d, 0xfa, 0x02, 0x8a, 0x6e, 0x40, 0x16, 0xba, 0x1f, 0xe6, 0x9e, 0x60,
- 0x3c, 0xe9, 0x9d, 0x6a, 0x0d, 0xf6, 0x2b, 0xeb, 0x9b, 0x56, 0x51, 0x1a, 0xb0, 0xa2, 0xa1, 0x66,
- 0xd2, 0x92, 0xe4, 0x9b, 0x54, 0x89, 0xac, 0xe0, 0x8c, 0xa5, 0xf3, 0xdf, 0x22, 0x98, 0x03, 0x2f,
- 0x0a, 0x85, 0x2e, 0xf4, 0x6f, 0x2d, 0x6f, 0xcf, 0xe0, 0x80, 0xa8, 0x21, 0x9b, 0xf8, 0xb2, 0x6a,
- 0xaa, 0x56, 0xaf, 0x73, 0xf7, 0x20, 0xd7, 0x5d, 0x0a, 0x8e, 0xc7, 0x82, 0x7e, 0x49, 0xfa, 0xb4,
- 0x0c, 0x5c, 0x27, 0xdf, 0x7a, 0x82, 0xce, 0x61, 0x9f, 0x71, 0x7b, 0x4e, 0x43, 0x11, 0x17, 0x5a,
- 0x3d, 0x94, 0xe6, 0xfe, 0xae, 0x7c, 0x99, 0x05, 0xea, 0x2a, 0x13, 0x47, 0xbb, 0xed, 0x03, 0x3d,
- 0x82, 0x22, 0x27, 0x57, 0xc9, 0xd8, 0x92, 0xab, 0x6f, 0x4c, 0xae, 0xc4, 0x96, 0x0b, 0xc5, 0x40,
- 0xbf, 0x07, 0x70, 0xdc, 0x30, 0x20, 0xc2, 0x9e, 0x53, 0xae, 0xef, 0x29, 0xf7, 0x88, 0xc3, 0x14,
- 0xb5, 0xe5, 0x25, 0xc3, 0x46, 0x27, 0x50, 0xb5, 0x49, 0xa2, 0xb4, 0xd2, 0xed, 0x3d, 0x66, 0xd0,
- 0xd3, 0x2e, 0xea, 0xd2, 0xc5, 0xfa, 0xa6, 0x55, 0x49, 0x2c, 0xb8, 0x62, 0x13, 0xad, 0xbc, 0x13,
- 0xd8, 0x97, 0x13, 0xfc, 0xd4, 0xa1, 0x57, 0x24, 0xf2, 0x44, 0xa8, 0xda, 0xe1, 0x2d, 0x55, 0x53,
- 0x0e, 0x93, 0x43, 0x8d, 0xd3, 0x71, 0xd5, 0x44, 0xc6, 0x86, 0xfe, 0x08, 0x07, 0xd4, 0xb7, 0xf9,
- 0x4a, 0xe9, 0x2c, 0x89, 0xb0, 0x72, 0xfb, 0x61, 0x47, 0x29, 0x78, 0xeb, 0xb0, 0x75, 0xfa, 0x2d,
- 0x7b, 0xc7, 0x05, 0x88, 0xfb, 0xd0, 0xdb, 0xd5, 0x1f, 0x82, 0xa2, 0x43, 0x04, 0x51, 0x92, 0xab,
- 0x61, 0xb5, 0xee, 0x7f, 0xf8, 0xf2, 0x55, 0xb3, 0xf0, 0xcf, 0x57, 0xcd, 0xc2, 0xbf, 0x5f, 0x35,
- 0x8d, 0x3f, 0xaf, 0x9b, 0xc6, 0xcb, 0x75, 0xd3, 0xf8, 0xc7, 0xba, 0x69, 0xfc, 0x6b, 0xdd, 0x34,
- 0x2e, 0x4b, 0xea, 0x8f, 0xfc, 0xe7, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xce, 0x13, 0x97, 0xa2,
- 0xf0, 0x0f, 0x00, 0x00,
+ // 1640 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0xdd, 0x72, 0xdb, 0xc6,
+ 0x15, 0x26, 0x24, 0x8a, 0x3f, 0x07, 0x94, 0x4d, 0xed, 0xe4, 0x07, 0x66, 0x12, 0x8a, 0x66, 0xdc,
+ 0x54, 0x69, 0xa6, 0x72, 0xab, 0x76, 0x52, 0xa7, 0x6e, 0xa6, 0x25, 0x45, 0x56, 0x56, 0x55, 0x29,
+ 0x9c, 0x95, 0xe2, 0x8e, 0xaf, 0x38, 0x2b, 0x60, 0x45, 0x62, 0x04, 0x62, 0xd1, 0xdd, 0x05, 0x33,
+ 0xbc, 0xeb, 0x65, 0xc6, 0x17, 0x7d, 0x03, 0x5f, 0xf5, 0x19, 0xfa, 0x0e, 0xbe, 0xec, 0x65, 0x7b,
+ 0xa3, 0xa9, 0xf9, 0x04, 0x9d, 0xe9, 0x03, 0xb4, 0xb3, 0x8b, 0x05, 0x08, 0x26, 0x50, 0x9c, 0x99,
+ 0xf8, 0x6e, 0xf7, 0xe0, 0xfb, 0x0e, 0xce, 0x9e, 0xfd, 0x70, 0xce, 0x01, 0xd8, 0x22, 0xa2, 0xae,
+ 0xd8, 0x8f, 0x38, 0x93, 0x0c, 0x21, 0x8f, 0xb9, 0xd7, 0x94, 0xef, 0x8b, 0xaf, 0x08, 0x9f, 0x5d,
+ 0xfb, 0x72, 0x7f, 0xfe, 0xf3, 0x96, 0x2d, 0x17, 0x11, 0x35, 0x80, 0xd6, 0x5b, 0x13, 0x36, 0x61,
+ 0x7a, 0xf9, 0x50, 0xad, 0x8c, 0xf5, 0x5d, 0x2f, 0xe6, 0x44, 0xfa, 0x2c, 0x7c, 0x98, 0x2e, 0x92,
+ 0x07, 0xdd, 0xbf, 0x96, 0xa1, 0x76, 0xc6, 0x3c, 0x7a, 0x1e, 0x51, 0x17, 0x1d, 0x81, 0x4d, 0xc2,
+ 0x90, 0x49, 0x0d, 0x10, 0x8e, 0xd5, 0xb1, 0xf6, 0xec, 0x83, 0xdd, 0xfd, 0x6f, 0xbf, 0x72, 0xbf,
+ 0xb7, 0x82, 0xf5, 0xcb, 0x2f, 0x6f, 0x76, 0x4b, 0x38, 0xcf, 0x44, 0x3f, 0x83, 0x32, 0x67, 0x01,
+ 0x75, 0x36, 0x3a, 0xd6, 0xde, 0x9d, 0x83, 0xf7, 0x8b, 0x3c, 0xa8, 0x97, 0x62, 0x16, 0x50, 0xac,
+ 0x91, 0xe8, 0x08, 0x60, 0x46, 0x67, 0x97, 0x94, 0x8b, 0xa9, 0x1f, 0x39, 0x9b, 0x9a, 0xf7, 0xe3,
+ 0xdb, 0x78, 0x2a, 0xd8, 0xfd, 0xd3, 0x0c, 0x8e, 0x73, 0x54, 0x74, 0x0a, 0x0d, 0x32, 0x27, 0x7e,
+ 0x40, 0x2e, 0xfd, 0xc0, 0x97, 0x0b, 0xa7, 0xac, 0x5d, 0x7d, 0xfc, 0x9d, 0xae, 0x7a, 0x39, 0x02,
+ 0x5e, 0xa3, 0x77, 0x3d, 0x80, 0xd5, 0x8b, 0xd0, 0x47, 0x50, 0x1d, 0x0d, 0xcf, 0x06, 0xc7, 0x67,
+ 0x47, 0xcd, 0x52, 0xeb, 0xde, 0xf3, 0x17, 0x9d, 0xb7, 0x95, 0x8f, 0x15, 0x60, 0x44, 0x43, 0xcf,
+ 0x0f, 0x27, 0x68, 0x0f, 0x6a, 0xbd, 0xc3, 0xc3, 0xe1, 0xe8, 0x62, 0x38, 0x68, 0x5a, 0xad, 0xd6,
+ 0xf3, 0x17, 0x9d, 0x77, 0xd6, 0x81, 0x3d, 0xd7, 0xa5, 0x91, 0xa4, 0x5e, 0xab, 0xfc, 0xf5, 0xdf,
+ 0xda, 0xa5, 0xee, 0xd7, 0x16, 0x34, 0xf2, 0x41, 0xa0, 0x8f, 0xa0, 0xd2, 0x3b, 0xbc, 0x38, 0x7e,
+ 0x3a, 0x6c, 0x96, 0x56, 0xf4, 0x3c, 0xa2, 0xe7, 0x4a, 0x7f, 0x4e, 0xd1, 0x03, 0xd8, 0x1a, 0xf5,
+ 0xbe, 0x3c, 0x1f, 0x36, 0xad, 0x55, 0x38, 0x79, 0xd8, 0x88, 0xc4, 0x42, 0xa3, 0x06, 0xb8, 0x77,
+ 0x7c, 0xd6, 0xdc, 0x28, 0x46, 0x0d, 0x38, 0xf1, 0x43, 0x13, 0xca, 0xab, 0x4d, 0xb0, 0xcf, 0x29,
+ 0x9f, 0xfb, 0xee, 0x1b, 0xd6, 0xc4, 0xa7, 0x50, 0x96, 0x44, 0x5c, 0x6b, 0x4d, 0xd8, 0xc5, 0x9a,
+ 0xb8, 0x20, 0xe2, 0x5a, 0xbd, 0xd4, 0xd0, 0x35, 0x5e, 0x29, 0x83, 0xd3, 0x28, 0xf0, 0x5d, 0x22,
+ 0xa9, 0xa7, 0x95, 0x61, 0x1f, 0xfc, 0xa8, 0x88, 0x8d, 0x33, 0x94, 0x89, 0xff, 0x49, 0x09, 0xe7,
+ 0xa8, 0xe8, 0x31, 0x54, 0x26, 0x01, 0xbb, 0x24, 0x81, 0xd6, 0x84, 0x7d, 0x70, 0xbf, 0xc8, 0xc9,
+ 0x91, 0x46, 0xac, 0x1c, 0x18, 0x0a, 0x7a, 0x04, 0x95, 0x38, 0xf2, 0x88, 0xa4, 0x4e, 0x45, 0x93,
+ 0x3b, 0x45, 0xe4, 0x2f, 0x35, 0xe2, 0x90, 0x85, 0x57, 0xfe, 0x04, 0x1b, 0x3c, 0x3a, 0x81, 0x5a,
+ 0x48, 0xe5, 0x57, 0x8c, 0x5f, 0x0b, 0xa7, 0xda, 0xd9, 0xdc, 0xb3, 0x0f, 0x3e, 0x29, 0x14, 0x63,
+ 0x82, 0xe9, 0x49, 0x49, 0xdc, 0xe9, 0x8c, 0x86, 0x32, 0x71, 0xd3, 0xdf, 0x70, 0x2c, 0x9c, 0x39,
+ 0x40, 0xbf, 0x81, 0x1a, 0x0d, 0xbd, 0x88, 0xf9, 0xa1, 0x74, 0x6a, 0xb7, 0x07, 0x32, 0x34, 0x18,
+ 0x95, 0x4c, 0x9c, 0x31, 0xfa, 0x15, 0x28, 0xcf, 0x98, 0x47, 0xbb, 0x0f, 0x61, 0xe7, 0x5b, 0xc9,
+ 0x42, 0x2d, 0xa8, 0x99, 0x64, 0x25, 0xb7, 0x5c, 0xc6, 0xd9, 0xbe, 0x7b, 0x17, 0xb6, 0xd7, 0x12,
+ 0xa3, 0xcb, 0x46, 0x7a, 0x5b, 0xa8, 0x07, 0x75, 0x97, 0x85, 0x92, 0xf8, 0x21, 0xe5, 0x46, 0x20,
+ 0x85, 0xb9, 0x3d, 0x4c, 0x41, 0x8a, 0xf5, 0xa4, 0x84, 0x57, 0x2c, 0xf4, 0x7b, 0xa8, 0x73, 0x2a,
+ 0x58, 0xcc, 0x5d, 0x2a, 0x8c, 0x42, 0xf6, 0x8a, 0xef, 0x38, 0x01, 0x61, 0xfa, 0xe7, 0xd8, 0xe7,
+ 0x54, 0xe5, 0x49, 0xe0, 0x15, 0x15, 0x3d, 0x86, 0x2a, 0xa7, 0x42, 0x12, 0x2e, 0xbf, 0xeb, 0x92,
+ 0x71, 0x02, 0x19, 0xb1, 0xc0, 0x77, 0x17, 0x38, 0x65, 0xa0, 0xc7, 0x50, 0x8f, 0x02, 0xe2, 0x6a,
+ 0xaf, 0xce, 0x96, 0xa6, 0x7f, 0x50, 0x44, 0x1f, 0xa5, 0x20, 0xbc, 0xc2, 0xa3, 0xcf, 0x00, 0x02,
+ 0x36, 0x19, 0x7b, 0xdc, 0x9f, 0x53, 0x6e, 0x44, 0xd2, 0x2a, 0x62, 0x0f, 0x34, 0x02, 0xd7, 0x03,
+ 0x36, 0x49, 0x96, 0xe8, 0xe8, 0x07, 0x29, 0x24, 0xa7, 0x8e, 0x13, 0x00, 0x92, 0x3d, 0x35, 0xfa,
+ 0xf8, 0xf8, 0x7b, 0xb9, 0x32, 0x37, 0x92, 0xa3, 0xa3, 0xfb, 0xd0, 0xb8, 0x62, 0xdc, 0xa5, 0x63,
+ 0xa3, 0xfb, 0xba, 0xd6, 0x84, 0xad, 0x6d, 0x89, 0xd0, 0xfb, 0x75, 0xa8, 0xf2, 0x38, 0x94, 0xfe,
+ 0x8c, 0x76, 0x4f, 0xe0, 0xed, 0x42, 0xa7, 0xe8, 0x00, 0x1a, 0xd9, 0x35, 0x8f, 0x7d, 0x4f, 0xeb,
+ 0xa3, 0xde, 0xbf, 0xbb, 0xbc, 0xd9, 0xb5, 0x33, 0x3d, 0x1c, 0x0f, 0xb0, 0x9d, 0x81, 0x8e, 0xbd,
+ 0xee, 0xbf, 0xaa, 0xb0, 0xbd, 0x26, 0x16, 0xf4, 0x16, 0x6c, 0xf9, 0x33, 0x32, 0xa1, 0x09, 0x1d,
+ 0x27, 0x1b, 0x34, 0x84, 0x4a, 0x40, 0x2e, 0x69, 0xa0, 0x24, 0xa3, 0xd2, 0xf6, 0xd3, 0xd7, 0xaa,
+ 0x6e, 0xff, 0x8f, 0x1a, 0x3f, 0x0c, 0x25, 0x5f, 0x60, 0x43, 0x46, 0x0e, 0x54, 0x5d, 0x36, 0x9b,
+ 0x91, 0x50, 0x95, 0x97, 0xcd, 0xbd, 0x3a, 0x4e, 0xb7, 0x08, 0x41, 0x99, 0xf0, 0x89, 0x70, 0xca,
+ 0xda, 0xac, 0xd7, 0xa8, 0x09, 0x9b, 0x34, 0x9c, 0x3b, 0x5b, 0xda, 0xa4, 0x96, 0xca, 0xe2, 0xf9,
+ 0xc9, 0x9d, 0xd7, 0xb1, 0x5a, 0x2a, 0x5e, 0x2c, 0x28, 0x77, 0xaa, 0xda, 0xa4, 0xd7, 0xe8, 0x57,
+ 0x50, 0x99, 0xb1, 0x38, 0x94, 0xc2, 0xa9, 0xe9, 0x60, 0xef, 0x15, 0x05, 0x7b, 0xaa, 0x10, 0xa6,
+ 0xfc, 0x19, 0x38, 0x7a, 0x02, 0x3b, 0x42, 0xb2, 0x68, 0x3c, 0xe1, 0xc4, 0xa5, 0xe3, 0x88, 0x72,
+ 0x9f, 0x79, 0xfa, 0x36, 0x6e, 0xa9, 0xa2, 0x03, 0xd3, 0xe1, 0xf1, 0x5d, 0x45, 0x3b, 0x52, 0xac,
+ 0x91, 0x26, 0xa1, 0x11, 0x34, 0xa2, 0x38, 0x08, 0xc6, 0x2c, 0x4a, 0x8a, 0x39, 0x68, 0x27, 0xdf,
+ 0x23, 0x6b, 0xa3, 0x38, 0x08, 0xbe, 0x48, 0x48, 0xd8, 0x8e, 0x56, 0x1b, 0xf4, 0x0e, 0x54, 0x26,
+ 0x9c, 0xc5, 0x91, 0x70, 0x6c, 0x9d, 0x0f, 0xb3, 0x43, 0x9f, 0x43, 0x55, 0x50, 0x97, 0x53, 0x29,
+ 0x9c, 0x86, 0x3e, 0xed, 0x87, 0x45, 0x2f, 0x39, 0xd7, 0x10, 0x4c, 0xaf, 0x28, 0xa7, 0xa1, 0x4b,
+ 0x71, 0xca, 0x41, 0xf7, 0x60, 0x53, 0xca, 0x85, 0xb3, 0xdd, 0xb1, 0xf6, 0x6a, 0xfd, 0xea, 0xf2,
+ 0x66, 0x77, 0xf3, 0xe2, 0xe2, 0x19, 0x56, 0x36, 0x55, 0xa6, 0xa6, 0x4c, 0xc8, 0x90, 0xcc, 0xa8,
+ 0x73, 0x47, 0xa7, 0x37, 0xdb, 0xa3, 0x67, 0x00, 0x5e, 0x28, 0xc6, 0xae, 0xfe, 0x2e, 0x9c, 0xbb,
+ 0xfa, 0x74, 0x9f, 0xbc, 0xfe, 0x74, 0x83, 0xb3, 0x73, 0x53, 0x6c, 0xb7, 0x97, 0x37, 0xbb, 0xf5,
+ 0x6c, 0x8b, 0xeb, 0x5e, 0x28, 0x92, 0x25, 0xea, 0x83, 0x3d, 0xa5, 0x24, 0x90, 0x53, 0x77, 0x4a,
+ 0xdd, 0x6b, 0xa7, 0x79, 0x7b, 0xed, 0x7d, 0xa2, 0x61, 0xc6, 0x43, 0x9e, 0xa4, 0x44, 0xac, 0x42,
+ 0x15, 0xce, 0x8e, 0xce, 0x55, 0xb2, 0x41, 0x1f, 0x00, 0xb0, 0x88, 0x86, 0x63, 0x21, 0x3d, 0x3f,
+ 0x74, 0x90, 0x3a, 0x32, 0xae, 0x2b, 0xcb, 0xb9, 0x32, 0xb4, 0x3e, 0x03, 0x3b, 0xa7, 0x59, 0xa5,
+ 0xb5, 0x6b, 0xba, 0x30, 0x9f, 0x81, 0x5a, 0x2a, 0xaf, 0x73, 0x12, 0xc4, 0xc9, 0xb0, 0x55, 0xc7,
+ 0xc9, 0xe6, 0xd7, 0x1b, 0x8f, 0xac, 0xd6, 0x01, 0xd8, 0xb9, 0x8b, 0x43, 0x1f, 0xc2, 0x36, 0xa7,
+ 0x13, 0x5f, 0x48, 0xbe, 0x18, 0x93, 0x58, 0x4e, 0x9d, 0xdf, 0x69, 0x42, 0x23, 0x35, 0xf6, 0x62,
+ 0x39, 0x6d, 0x8d, 0x61, 0x75, 0x7e, 0xd4, 0x01, 0x5b, 0xe5, 0x55, 0x50, 0x3e, 0xa7, 0x5c, 0x75,
+ 0x05, 0x15, 0x76, 0xde, 0xa4, 0xee, 0x5f, 0x50, 0xc2, 0xdd, 0xa9, 0xfe, 0x02, 0xeb, 0xd8, 0xec,
+ 0xd4, 0x27, 0x95, 0x8a, 0xcc, 0x7c, 0x52, 0x66, 0xdb, 0xfd, 0xaf, 0x05, 0x8d, 0x7c, 0x7b, 0x42,
+ 0x87, 0x49, 0x53, 0xd2, 0x47, 0xba, 0x73, 0xf0, 0xf0, 0x75, 0xed, 0x4c, 0xb7, 0x80, 0x20, 0x56,
+ 0xce, 0x4e, 0xd5, 0x08, 0xa9, 0xc9, 0xe8, 0x97, 0xb0, 0x15, 0x31, 0x2e, 0xd3, 0x42, 0xd0, 0x2e,
+ 0x2c, 0xdb, 0x8c, 0xa7, 0x25, 0x33, 0x01, 0x77, 0xa7, 0x70, 0x67, 0xdd, 0x1b, 0x7a, 0x00, 0x9b,
+ 0x4f, 0x8f, 0x47, 0xcd, 0x52, 0xeb, 0xbd, 0xe7, 0x2f, 0x3a, 0xef, 0xae, 0x3f, 0x7c, 0xea, 0x73,
+ 0x19, 0x93, 0xe0, 0x78, 0x84, 0x7e, 0x02, 0x5b, 0x83, 0xb3, 0x73, 0x8c, 0x9b, 0x56, 0x6b, 0xf7,
+ 0xf9, 0x8b, 0xce, 0x7b, 0xeb, 0x38, 0xf5, 0x88, 0xc5, 0xa1, 0x87, 0xd9, 0x65, 0x36, 0x55, 0xfd,
+ 0x7d, 0x03, 0x6c, 0x53, 0x1f, 0xdf, 0xec, 0x54, 0xf5, 0x5b, 0xd8, 0x4e, 0x5a, 0x4e, 0xaa, 0xfa,
+ 0x8d, 0xd7, 0x76, 0x9e, 0x46, 0x42, 0x30, 0x77, 0x7c, 0x1f, 0x1a, 0x7e, 0x34, 0xff, 0x74, 0x4c,
+ 0x43, 0x72, 0x19, 0x98, 0x01, 0xab, 0x86, 0x6d, 0x65, 0x1b, 0x26, 0x26, 0xf5, 0xc9, 0xf9, 0xa1,
+ 0xa4, 0x3c, 0x34, 0xa3, 0x53, 0x0d, 0x67, 0x7b, 0xf4, 0x39, 0x94, 0xfd, 0x88, 0xcc, 0x4c, 0xbb,
+ 0x2c, 0x3c, 0xc1, 0xf1, 0xa8, 0x77, 0x6a, 0x34, 0xd8, 0xaf, 0x2d, 0x6f, 0x76, 0xcb, 0xca, 0x80,
+ 0x35, 0x0d, 0xb5, 0xd3, 0x8e, 0xa5, 0xde, 0xa4, 0x2b, 0x68, 0x0d, 0xe7, 0x2c, 0xdd, 0xff, 0x95,
+ 0xc1, 0x3e, 0x0c, 0x62, 0x21, 0x4d, 0x1f, 0x78, 0x63, 0x79, 0x7b, 0x06, 0x3b, 0x44, 0xcf, 0xe0,
+ 0x24, 0x54, 0x45, 0x55, 0x4f, 0x02, 0x26, 0x77, 0x0f, 0x0a, 0xdd, 0x65, 0xe0, 0x64, 0x6a, 0xe8,
+ 0x57, 0x94, 0x4f, 0xc7, 0xc2, 0x4d, 0xf2, 0x8d, 0x27, 0xe8, 0x1c, 0xb6, 0x19, 0x77, 0xa7, 0x54,
+ 0xc8, 0xa4, 0x0e, 0x9b, 0x99, 0xb5, 0xf0, 0x6f, 0xe6, 0x8b, 0x3c, 0xd0, 0x14, 0xa1, 0x24, 0xda,
+ 0x75, 0x1f, 0xe8, 0x11, 0x94, 0x39, 0xb9, 0x4a, 0xa7, 0x9a, 0x42, 0x7d, 0x63, 0x72, 0x25, 0xd7,
+ 0x5c, 0x68, 0x06, 0xfa, 0x03, 0x80, 0xe7, 0x8b, 0x88, 0x48, 0x77, 0x4a, 0xb9, 0xb9, 0xa7, 0xc2,
+ 0x23, 0x0e, 0x32, 0xd4, 0x9a, 0x97, 0x1c, 0x1b, 0x9d, 0x40, 0xdd, 0x25, 0xa9, 0xd2, 0x2a, 0xb7,
+ 0xb7, 0xa0, 0xc3, 0x9e, 0x71, 0xd1, 0x54, 0x2e, 0x96, 0x37, 0xbb, 0xb5, 0xd4, 0x82, 0x6b, 0x2e,
+ 0x31, 0xca, 0x3b, 0x81, 0x6d, 0x35, 0xe0, 0x8f, 0x3d, 0x7a, 0x45, 0xe2, 0x40, 0x0a, 0xdd, 0x2d,
+ 0x6f, 0x29, 0xaa, 0x6a, 0xd6, 0x1c, 0x18, 0x9c, 0x89, 0xab, 0x21, 0x73, 0x36, 0xf4, 0x27, 0xd8,
+ 0xa1, 0xa1, 0xcb, 0x17, 0x5a, 0x67, 0x69, 0x84, 0xb5, 0xdb, 0x0f, 0x3b, 0xcc, 0xc0, 0x6b, 0x87,
+ 0x6d, 0xd2, 0x6f, 0xd8, 0xbb, 0x3e, 0x40, 0xd2, 0xa6, 0xde, 0xac, 0xfe, 0x10, 0x94, 0x3d, 0x22,
+ 0x89, 0x96, 0x5c, 0x03, 0xeb, 0x75, 0xff, 0xfd, 0x97, 0xaf, 0xda, 0xa5, 0x7f, 0xbe, 0x6a, 0x97,
+ 0xfe, 0xf3, 0xaa, 0x6d, 0xfd, 0x65, 0xd9, 0xb6, 0x5e, 0x2e, 0xdb, 0xd6, 0x3f, 0x96, 0x6d, 0xeb,
+ 0xdf, 0xcb, 0xb6, 0x75, 0x59, 0xd1, 0x3f, 0xec, 0xbf, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xab, 0x02, 0x96, 0x72, 0x0f, 0x10, 0x00, 0x00,
}
diff --git a/vendor/github.com/docker/swarmkit/api/specs.proto b/vendor/github.com/docker/swarmkit/api/specs.proto
index ae2b787..5d72b6a 100644
--- a/vendor/github.com/docker/swarmkit/api/specs.proto
+++ b/vendor/github.com/docker/swarmkit/api/specs.proto
@@ -186,6 +186,9 @@
// including stdin if it is still open.
bool tty = 13 [(gogoproto.customname) = "TTY"];
+ // OpenStdin declares that the standard input (stdin) should be open.
+ bool open_stdin = 18;
+
repeated Mount mounts = 8 [(gogoproto.nullable) = false];
// StopGracePeriod the grace period for stopping the container before
@@ -212,10 +215,12 @@
// that associates IP addresses with hostnames.
// Detailed documentation is available in:
// http://man7.org/linux/man-pages/man5/hosts.5.html
- // The format of the Hosts here could be:
- // <hostname>:<ip> (separated by `:`)
- // <hostname>=<ip> (separated by `=`)
- // <hostname> <ip> (separated by ` `)
+ // IP_address canonical_hostname [aliases...]
+ //
+ // The format of the Hosts in swarmkit follows the same as
+ // above.
+ // This is different from `docker run --add-host <hostname>:<ip>`
+ // where format is `<hostname>:<ip>`
repeated string hosts = 17;
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)