Browse code

Merge pull request #30331 from vieux/1.13.1-rc1-cherrypicks

1.13.1 rc1 cherrypicks

Victor Vieux authored on 2017/01/27 12:21:38
Showing 68 changed files
... ...
@@ -126,7 +126,7 @@ RUN set -x \
126 126
 # IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
127 127
 #            will need updating, to avoid errors. Ping #docker-maintainers on IRC
128 128
 #            with a heads-up.
129
-ENV GO_VERSION 1.7.3
129
+ENV GO_VERSION 1.7.4
130 130
 RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
131 131
 	| tar -xzC /usr/local
132 132
 
... ...
@@ -97,7 +97,7 @@ RUN set -x \
97 97
 # so we use gccgo as bootstrap to build Go from source code.
98 98
 # We don't use the official ARMv6 released binaries as a GOROOT_BOOTSTRAP, because
99 99
 # not all ARM64 platforms support 32-bit mode. 32-bit mode is optional for ARMv8.
100
-ENV GO_VERSION 1.7.3
100
+ENV GO_VERSION 1.7.4
101 101
 RUN mkdir /usr/src/go && curl -fsSL https://golang.org/dl/go${GO_VERSION}.src.tar.gz | tar -v -C /usr/src/go -xz --strip-components=1 \
102 102
 	&& cd /usr/src/go/src \
103 103
 	&& GOOS=linux GOARCH=arm64 GOROOT_BOOTSTRAP="$(go env GOROOT)" ./make.bash
... ...
@@ -72,7 +72,7 @@ RUN cd /usr/local/lvm2 \
72 72
 # See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
73 73
 
74 74
 # Install Go
75
-ENV GO_VERSION 1.7.3
75
+ENV GO_VERSION 1.7.4
76 76
 RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" \
77 77
 	| tar -xzC /usr/local
78 78
 ENV PATH /go/bin:/usr/local/go/bin:$PATH
... ...
@@ -15,8 +15,7 @@
15 15
 # the case. Therefore, you don't have to disable it anymore.
16 16
 #
17 17
 
18
-# ppc64le/golang is a debian:jessie based image with golang installed
19
-FROM ppc64le/golang:1.6.3
18
+FROM ppc64le/debian:jessie
20 19
 
21 20
 # allow replacing httpredir or deb mirror
22 21
 ARG APT_MIRROR=deb.debian.org
... ...
@@ -95,25 +94,12 @@ RUN set -x \
95 95
 
96 96
 
97 97
 # Install Go
98
-# ppc64le doesn't have official go binaries, so use the version of go installed from the image
99
-# to build go from source.
100
-# NOTE: ppc64le has compatibility issues with older versions of go, so make sure the version >= 1.6
101
-ENV GO_VERSION 1.7.3
102
-ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz
98
+# NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4
99
+ENV GO_VERSION 1.7.4
100
+RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" \
101
+	| tar -xzC /usr/local
103 102
 
104
-RUN set -x \
105
-	&& TEMPDIR="$(mktemp -d)" \
106
-	&& mv /usr/local/go $TEMPDIR \
107
-	&& GOROOT_BOOTSTRAP=$TEMPDIR/go \
108
-	&& cd /usr/local \
109
-	&& curl -fsSL "$GO_DOWNLOAD_URL" -o golang.tar.gz \
110
-	&& tar -C /usr/local -xzf golang.tar.gz \
111
-	&& rm golang.tar.gz \
112
-	&& cd go/src && ./make.bash 2>&1 \
113
-	&& rm -rf $TEMPDIR
114
-
115
-ENV GOROOT_BOOTSTRAP /usr/local/go
116
-ENV PATH /usr/local/go/bin/:$PATH
103
+ENV PATH /go/bin:/usr/local/go/bin:$PATH
117 104
 ENV GOPATH /go
118 105
 
119 106
 # Dependency for golint
... ...
@@ -97,7 +97,7 @@ RUN cd /usr/local/lvm2 \
97 97
 	&& make install_device-mapper
98 98
 # See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
99 99
 
100
-ENV GO_VERSION 1.7.3
100
+ENV GO_VERSION 1.7.4
101 101
 RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \
102 102
 	| tar -xzC /usr/local
103 103
 
... ...
@@ -55,7 +55,7 @@ RUN set -x \
55 55
 # IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
56 56
 #            will need updating, to avoid errors. Ping #docker-maintainers on IRC
57 57
 #            with a heads-up.
58
-ENV GO_VERSION 1.7.3
58
+ENV GO_VERSION 1.7.4
59 59
 RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
60 60
 	| tar -xzC /usr/local
61 61
 ENV PATH /go/bin:/usr/local/go/bin:$PATH
... ...
@@ -165,8 +165,8 @@ SHELL ["powershell", "-command"]
165 165
 # Environment variable notes:
166 166
 #  - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
167 167
 #  - FROM_DOCKERFILE is used for detection of building within a container.
168
-ENV GO_VERSION=1.7.3 `
169
-    GIT_VERSION=2.10.2 `
168
+ENV GO_VERSION=1.7.4 `
169
+    GIT_VERSION=2.11.0 `
170 170
     GOPATH=C:\go `
171 171
     FROM_DOCKERFILE=1
172 172
 
... ...
@@ -163,7 +163,7 @@ func (n *networkRouter) buildNetworkResource(nw libnetwork.Network) *types.Netwo
163 163
 	r.Created = info.Created()
164 164
 	r.Scope = info.Scope()
165 165
 	if n.clusterProvider.IsManager() {
166
-		if _, err := n.clusterProvider.GetNetwork(nw.Name()); err == nil {
166
+		if _, err := n.clusterProvider.GetNetwork(nw.ID()); err == nil {
167 167
 			r.Scope = "swarm"
168 168
 		}
169 169
 	} else if info.Dynamic() {
... ...
@@ -74,6 +74,12 @@ func (o listOptionsProcessor) Size() bool {
74 74
 	return true
75 75
 }
76 76
 
77
+// Label is needed here as it allows the correct pre-processing
78
+// because Label() is a method with arguments
79
+func (o listOptionsProcessor) Label(name string) string {
80
+	return ""
81
+}
82
+
77 83
 func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
78 84
 	options := &types.ContainerListOptions{
79 85
 		All:     opts.all,
... ...
@@ -192,7 +192,10 @@ func (c *diskUsageImagesContext) Reclaimable() string {
192 192
 	c.AddHeader(reclaimableHeader)
193 193
 	for _, i := range c.images {
194 194
 		if i.Containers != 0 {
195
-			used += i.Size
195
+			if i.VirtualSize == -1 || i.SharedSize == -1 {
196
+				continue
197
+			}
198
+			used += i.VirtualSize - i.SharedSize
196 199
 		}
197 200
 	}
198 201
 
... ...
@@ -103,22 +103,58 @@ func inspectPlugin(ctx context.Context, dockerCli *command.DockerCli) inspect.Ge
103 103
 
104 104
 func inspectAll(ctx context.Context, dockerCli *command.DockerCli, getSize bool, typeConstraint string) inspect.GetRefFunc {
105 105
 	var inspectAutodetect = []struct {
106
-		ObjectType      string
107
-		IsSizeSupported bool
108
-		ObjectInspector func(string) (interface{}, []byte, error)
106
+		objectType      string
107
+		isSizeSupported bool
108
+		isSwarmObject   bool
109
+		objectInspector func(string) (interface{}, []byte, error)
109 110
 	}{
110
-		{"container", true, inspectContainers(ctx, dockerCli, getSize)},
111
-		{"image", false, inspectImages(ctx, dockerCli)},
112
-		{"network", false, inspectNetwork(ctx, dockerCli)},
113
-		{"volume", false, inspectVolume(ctx, dockerCli)},
114
-		{"service", false, inspectService(ctx, dockerCli)},
115
-		{"task", false, inspectTasks(ctx, dockerCli)},
116
-		{"node", false, inspectNode(ctx, dockerCli)},
117
-		{"plugin", false, inspectPlugin(ctx, dockerCli)},
111
+		{
112
+			objectType:      "container",
113
+			isSizeSupported: true,
114
+			objectInspector: inspectContainers(ctx, dockerCli, getSize),
115
+		},
116
+		{
117
+			objectType:      "image",
118
+			objectInspector: inspectImages(ctx, dockerCli),
119
+		},
120
+		{
121
+			objectType:      "network",
122
+			objectInspector: inspectNetwork(ctx, dockerCli),
123
+		},
124
+		{
125
+			objectType:      "volume",
126
+			objectInspector: inspectVolume(ctx, dockerCli),
127
+		},
128
+		{
129
+			objectType:      "service",
130
+			isSwarmObject:   true,
131
+			objectInspector: inspectService(ctx, dockerCli),
132
+		},
133
+		{
134
+			objectType:      "task",
135
+			isSwarmObject:   true,
136
+			objectInspector: inspectTasks(ctx, dockerCli),
137
+		},
138
+		{
139
+			objectType:      "node",
140
+			isSwarmObject:   true,
141
+			objectInspector: inspectNode(ctx, dockerCli),
142
+		},
143
+		{
144
+			objectType:      "plugin",
145
+			objectInspector: inspectPlugin(ctx, dockerCli),
146
+		},
118 147
 	}
119 148
 
120
-	isErrNotSwarmManager := func(err error) bool {
121
-		return strings.Contains(err.Error(), "This node is not a swarm manager")
149
+	// isSwarmManager does an Info API call to verify that the daemon is
150
+	// a swarm manager.
151
+	isSwarmManager := func() bool {
152
+		info, err := dockerCli.Client().Info(ctx)
153
+		if err != nil {
154
+			fmt.Fprintln(dockerCli.Err(), err)
155
+			return false
156
+		}
157
+		return info.Swarm.ControlAvailable
122 158
 	}
123 159
 
124 160
 	isErrNotSupported := func(err error) bool {
... ...
@@ -126,19 +162,39 @@ func inspectAll(ctx context.Context, dockerCli *command.DockerCli, getSize bool,
126 126
 	}
127 127
 
128 128
 	return func(ref string) (interface{}, []byte, error) {
129
+		const (
130
+			swarmSupportUnknown = iota
131
+			swarmSupported
132
+			swarmUnsupported
133
+		)
134
+
135
+		isSwarmSupported := swarmSupportUnknown
136
+
129 137
 		for _, inspectData := range inspectAutodetect {
130
-			if typeConstraint != "" && inspectData.ObjectType != typeConstraint {
138
+			if typeConstraint != "" && inspectData.objectType != typeConstraint {
131 139
 				continue
132 140
 			}
133
-			v, raw, err := inspectData.ObjectInspector(ref)
141
+			if typeConstraint == "" && inspectData.isSwarmObject {
142
+				if isSwarmSupported == swarmSupportUnknown {
143
+					if isSwarmManager() {
144
+						isSwarmSupported = swarmSupported
145
+					} else {
146
+						isSwarmSupported = swarmUnsupported
147
+					}
148
+				}
149
+				if isSwarmSupported == swarmUnsupported {
150
+					continue
151
+				}
152
+			}
153
+			v, raw, err := inspectData.objectInspector(ref)
134 154
 			if err != nil {
135
-				if typeConstraint == "" && (apiclient.IsErrNotFound(err) || isErrNotSwarmManager(err) || isErrNotSupported(err)) {
155
+				if typeConstraint == "" && (apiclient.IsErrNotFound(err) || isErrNotSupported(err)) {
136 156
 					continue
137 157
 				}
138 158
 				return v, raw, err
139 159
 			}
140
-			if getSize && !inspectData.IsSizeSupported {
141
-				fmt.Fprintf(dockerCli.Err(), "WARNING: --size ignored for %s\n", inspectData.ObjectType)
160
+			if getSize && !inspectData.isSizeSupported {
161
+				fmt.Fprintf(dockerCli.Err(), "WARNING: --size ignored for %s\n", inspectData.objectType)
142 162
 			}
143 163
 			return v, raw, err
144 164
 		}
... ...
@@ -13,6 +13,7 @@ import (
13 13
 	"unsafe"
14 14
 
15 15
 	"github.com/Sirupsen/logrus"
16
+	"github.com/docker/docker/pkg/system"
16 17
 	"github.com/spf13/pflag"
17 18
 	"golang.org/x/sys/windows"
18 19
 	"golang.org/x/sys/windows/svc"
... ...
@@ -165,10 +166,20 @@ func registerService() error {
165 165
 		return err
166 166
 	}
167 167
 	defer m.Disconnect()
168
+
169
+	depends := []string{}
170
+
171
+	// This dependency is required on build 14393 (RS1)
172
+	// it is added to the platform in newer builds
173
+	if system.GetOSVersion().Build == 14393 {
174
+		depends = append(depends, "ConDrv")
175
+	}
176
+
168 177
 	c := mgr.Config{
169 178
 		ServiceType:  windows.SERVICE_WIN32_OWN_PROCESS,
170 179
 		StartType:    mgr.StartAutomatic,
171 180
 		ErrorControl: mgr.ErrorNormal,
181
+		Dependencies: depends,
172 182
 		DisplayName:  "Docker Engine",
173 183
 	}
174 184
 
... ...
@@ -11,7 +11,7 @@ RUN update-alternatives --install /usr/bin/go go /usr/lib/go-1.6/bin/go 100
11 11
 # Install Go
12 12
 # aarch64 doesn't have official go binaries, so use the version of go installed from
13 13
 # the image to build go from source.
14
-ENV GO_VERSION 1.7.3
14
+ENV GO_VERSION 1.7.4
15 15
 RUN mkdir /usr/src/go && curl -fsSL https://golang.org/dl/go${GO_VERSION}.src.tar.gz | tar -v -C /usr/src/go -xz --strip-components=1 \
16 16
 	&& cd /usr/src/go/src \
17 17
 	&& GOOS=linux GOARCH=arm64 GOROOT_BOOTSTRAP="$(go env GOROOT)" ./make.bash
... ...
@@ -9,7 +9,7 @@ RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools bu
9 9
 # Install Go
10 10
 # aarch64 doesn't have official go binaries, so use the version of go installed from
11 11
 # the image to build go from source.
12
-ENV GO_VERSION 1.7.3
12
+ENV GO_VERSION 1.7.4
13 13
 RUN mkdir /usr/src/go && curl -fsSL https://golang.org/dl/go${GO_VERSION}.src.tar.gz | tar -v -C /usr/src/go -xz --strip-components=1 \
14 14
 	&& cd /usr/src/go/src \
15 15
 	&& GOOS=linux GOARCH=arm64 GOROOT_BOOTSTRAP="$(go env GOROOT)" ./make.bash
... ...
@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
10 10
 
11 11
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
12 12
 
13
-ENV GO_VERSION 1.7.3
13
+ENV GO_VERSION 1.7.4
14 14
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
15 15
 ENV PATH $PATH:/usr/local/go/bin
16 16
 
... ...
@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
10 10
 
11 11
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
12 12
 
13
-ENV GO_VERSION 1.7.3
13
+ENV GO_VERSION 1.7.4
14 14
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
15 15
 ENV PATH $PATH:/usr/local/go/bin
16 16
 
... ...
@@ -12,7 +12,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list.d
12 12
 RUN apt-get update && apt-get install -y -t wheezy-backports btrfs-tools --no-install-recommends && rm -rf /var/lib/apt/lists/*
13 13
 RUN apt-get update && apt-get install -y apparmor bash-completion  build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
14 14
 
15
-ENV GO_VERSION 1.7.3
15
+ENV GO_VERSION 1.7.4
16 16
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
17 17
 ENV PATH $PATH:/usr/local/go/bin
18 18
 
... ...
@@ -6,7 +6,7 @@ FROM ubuntu:precise
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion  build-essential cmake curl ca-certificates debhelper dh-apparmor  git libapparmor-dev  libltdl-dev  libsqlite3-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -6,7 +6,7 @@ FROM ubuntu:trusty
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -6,7 +6,7 @@ FROM ubuntu:xenial
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -6,7 +6,7 @@ FROM ubuntu:yakkety
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
10 10
 
11 11
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
12 12
 
13
-ENV GO_VERSION 1.7.3
13
+ENV GO_VERSION 1.7.4
14 14
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
15 15
 ENV PATH $PATH:/usr/local/go/bin
16 16
 
... ...
@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
10 10
 
11 11
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
12 12
 
13
-ENV GO_VERSION 1.7.3
13
+ENV GO_VERSION 1.7.4
14 14
 # GOARM is the ARM architecture version which is unrelated to the above Golang version
15 15
 ENV GOARM 6
16 16
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
... ...
@@ -6,7 +6,7 @@ FROM armhf/ubuntu:trusty
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev  libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -6,7 +6,7 @@ FROM armhf/ubuntu:xenial
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -6,7 +6,7 @@ FROM armhf/ubuntu:yakkety
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -59,22 +59,12 @@ for version in "${versions[@]}"; do
59 59
 		vim-common # tini dep
60 60
 	)
61 61
 
62
-	# trusty uses a different go package name then xenial and newer, so track that for later
63
-	goPackage=
64 62
 	case "$suite" in
65 63
 		trusty) 
66
-			# ppc64le doesn't have go binaries, so install go to bootstrap go
67
-			# trusty doesn't have a ppc64le golang-go package
68
-			packages+=( golang-1.6 )
69
-			goPackage='golang-1.6'
70
-
71 64
 			packages+=( libsystemd-journal-dev )
72 65
 			;;
73 66
 		*)
74 67
 			# libseccomp isn't available until ubuntu xenial and is required for "seccomp.h" & "libseccomp.so"
75
-			packages+=( golang-go )
76
-			goPackage='golang-go'
77
-
78 68
 			packages+=( libseccomp-dev )
79 69
 			packages+=( libsystemd-dev )
80 70
 			;;
... ...
@@ -98,25 +88,8 @@ for version in "${versions[@]}"; do
98 98
 	echo "RUN apt-get update && apt-get install -y ${packages[*]} --no-install-recommends && rm -rf /var/lib/apt/lists/*" >> "$version/Dockerfile"
99 99
 	echo >> "$version/Dockerfile"
100 100
 
101
-	# ppc64le doesn't have an official downloadable binary as of go 1.6.2. so use the
102
-	# older packaged go(v1.6.1) to bootstrap latest go, then remove the packaged go
103
-	echo "# Install Go" >> "$version/Dockerfile"
104
-	echo "# ppc64le doesn't have official go binaries, so use a distro packaged version of go" >> "$version/Dockerfile"
105
-	echo "# to build go from source." >> "$version/Dockerfile"
106
-	echo "# NOTE: ppc64le has compatibility issues with older versions of go, so make sure the version >= 1.6" >> "$version/Dockerfile"
107
-	
108 101
 	awk '$1 == "ENV" && $2 == "GO_VERSION" { print; exit }' ../../../../Dockerfile.ppc64le >> "$version/Dockerfile"
109
-	echo 'ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz' >> "$version/Dockerfile"
110
-	echo 'ENV GOROOT_BOOTSTRAP /usr/lib/go-1.6' >> "$version/Dockerfile"
111
-	echo >> "$version/Dockerfile"
112
-	
113
-	echo 'RUN curl -fsSL "$GO_DOWNLOAD_URL" -o golang.tar.gz \' >> "$version/Dockerfile"
114
-	echo '	&& tar -C /usr/local -xzf golang.tar.gz \' >> "$version/Dockerfile"
115
-	echo '	&& rm golang.tar.gz \' >> "$version/Dockerfile"
116
-	echo '	&& cd /usr/local/go/src && ./make.bash 2>&1 \' >> "$version/Dockerfile"
117
-	echo "	&& apt-get purge -y $goPackage && apt-get autoremove -y" >> "$version/Dockerfile"
118
-	echo >> "$version/Dockerfile"
119
-
102
+	echo 'RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local' >> "$version/Dockerfile"
120 103
 	echo 'ENV PATH $PATH:/usr/local/go/bin' >> "$version/Dockerfile"
121 104
 	echo >> "$version/Dockerfile"
122 105
 
... ...
@@ -4,22 +4,10 @@
4 4
 
5 5
 FROM ppc64le/ubuntu:trusty
6 6
 
7
-RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common golang-1.6 libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8
-
9
-# Install Go
10
-# ppc64le doesn't have official go binaries, so use a distro packaged version of go
11
-# to build go from source.
12
-# NOTE: ppc64le has compatibility issues with older versions of go, so make sure the version >= 1.6
13
-ENV GO_VERSION 1.7.3
14
-ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz
15
-ENV GOROOT_BOOTSTRAP /usr/lib/go-1.6
16
-
17
-RUN curl -fsSL "$GO_DOWNLOAD_URL" -o golang.tar.gz \
18
-	&& tar -C /usr/local -xzf golang.tar.gz \
19
-	&& rm golang.tar.gz \
20
-	&& cd /usr/local/go/src && ./make.bash 2>&1 \
21
-	&& apt-get purge -y golang-1.6 && apt-get autoremove -y
7
+RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
22 8
 
9
+ENV GO_VERSION 1.7.4
10
+RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
23 11
 ENV PATH $PATH:/usr/local/go/bin
24 12
 
25 13
 ENV AUTO_GOPATH 1
... ...
@@ -4,22 +4,10 @@
4 4
 
5 5
 FROM ppc64le/ubuntu:xenial
6 6
 
7
-RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common golang-go libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8
-
9
-# Install Go
10
-# ppc64le doesn't have official go binaries, so use a distro packaged version of go
11
-# to build go from source.
12
-# NOTE: ppc64le has compatibility issues with older versions of go, so make sure the version >= 1.6
13
-ENV GO_VERSION 1.7.3
14
-ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz
15
-ENV GOROOT_BOOTSTRAP /usr/lib/go-1.6
16
-
17
-RUN curl -fsSL "$GO_DOWNLOAD_URL" -o golang.tar.gz \
18
-	&& tar -C /usr/local -xzf golang.tar.gz \
19
-	&& rm golang.tar.gz \
20
-	&& cd /usr/local/go/src && ./make.bash 2>&1 \
21
-	&& apt-get purge -y golang-go && apt-get autoremove -y
7
+RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
22 8
 
9
+ENV GO_VERSION 1.7.4
10
+RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
23 11
 ENV PATH $PATH:/usr/local/go/bin
24 12
 
25 13
 ENV AUTO_GOPATH 1
... ...
@@ -4,22 +4,10 @@
4 4
 
5 5
 FROM ppc64le/ubuntu:yakkety
6 6
 
7
-RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common golang-go libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
8
-
9
-# Install Go
10
-# ppc64le doesn't have official go binaries, so use a distro packaged version of go
11
-# to build go from source.
12
-# NOTE: ppc64le has compatibility issues with older versions of go, so make sure the version >= 1.6
13
-ENV GO_VERSION 1.7.3
14
-ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz
15
-ENV GOROOT_BOOTSTRAP /usr/lib/go-1.6
16
-
17
-RUN curl -fsSL "$GO_DOWNLOAD_URL" -o golang.tar.gz \
18
-	&& tar -C /usr/local -xzf golang.tar.gz \
19
-	&& rm golang.tar.gz \
20
-	&& cd /usr/local/go/src && ./make.bash 2>&1 \
21
-	&& apt-get purge -y golang-go && apt-get autoremove -y
7
+RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libsqlite3-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
22 8
 
9
+ENV GO_VERSION 1.7.4
10
+RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
23 11
 ENV PATH $PATH:/usr/local/go/bin
24 12
 
25 13
 ENV AUTO_GOPATH 1
... ...
@@ -6,7 +6,7 @@ FROM s390x/ubuntu:xenial
6 6
 
7 7
 RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config libsystemd-dev vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
8 8
 
9
-ENV GO_VERSION 1.7.3
9
+ENV GO_VERSION 1.7.4
10 10
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
11 11
 ENV PATH $PATH:/usr/local/go/bin
12 12
 
... ...
@@ -8,7 +8,7 @@ RUN yum groupinstall -y "Development Tools"
8 8
 RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
9 9
 RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
10 10
 
11
-ENV GO_VERSION 1.7.3
11
+ENV GO_VERSION 1.7.4
12 12
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
13 13
 ENV PATH $PATH:/usr/local/go/bin
14 14
 
... ...
@@ -8,7 +8,7 @@ RUN dnf -y upgrade
8 8
 RUN dnf install -y @development-tools fedora-packager
9 9
 RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
10 10
 
11
-ENV GO_VERSION 1.7.3
11
+ENV GO_VERSION 1.7.4
12 12
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
13 13
 ENV PATH $PATH:/usr/local/go/bin
14 14
 
... ...
@@ -8,7 +8,7 @@ RUN dnf -y upgrade
8 8
 RUN dnf install -y @development-tools fedora-packager
9 9
 RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
10 10
 
11
-ENV GO_VERSION 1.7.3
11
+ENV GO_VERSION 1.7.4
12 12
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
13 13
 ENV PATH $PATH:/usr/local/go/bin
14 14
 
... ...
@@ -7,7 +7,7 @@ FROM opensuse:13.2
7 7
 RUN zypper --non-interactive install ca-certificates* curl gzip rpm-build
8 8
 RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static  libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim systemd-rpm-macros
9 9
 
10
-ENV GO_VERSION 1.7.3
10
+ENV GO_VERSION 1.7.4
11 11
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
12 12
 ENV PATH $PATH:/usr/local/go/bin
13 13
 
... ...
@@ -10,7 +10,7 @@ RUN yum install -y kernel-uek-devel-4.1.12-32.el6uek
10 10
 RUN yum groupinstall -y "Development Tools"
11 11
 RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static  libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel  tar git cmake vim-common
12 12
 
13
-ENV GO_VERSION 1.7.3
13
+ENV GO_VERSION 1.7.4
14 14
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
15 15
 ENV PATH $PATH:/usr/local/go/bin
16 16
 
... ...
@@ -7,7 +7,7 @@ FROM oraclelinux:7
7 7
 RUN yum groupinstall -y "Development Tools"
8 8
 RUN yum install -y --enablerepo=ol7_optional_latest btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
9 9
 
10
-ENV GO_VERSION 1.7.3
10
+ENV GO_VERSION 1.7.4
11 11
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
12 12
 ENV PATH $PATH:/usr/local/go/bin
13 13
 
... ...
@@ -7,7 +7,7 @@ FROM photon:1.0
7 7
 RUN tdnf install -y wget curl ca-certificates gzip make rpm-build sed gcc linux-api-headers glibc-devel binutils libseccomp libltdl-devel elfutils
8 8
 RUN tdnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
9 9
 
10
-ENV GO_VERSION 1.7.3
10
+ENV GO_VERSION 1.7.4
11 11
 RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
12 12
 ENV PATH $PATH:/usr/local/go/bin
13 13
 
... ...
@@ -361,18 +361,33 @@ __docker_complete_stacks() {
361 361
 # An optional first option `--id|--name` may be used to limit the
362 362
 # output to the IDs or names of matching items. This setting takes
363 363
 # precedence over the environment setting.
364
+# Completions may be added with `--add`, e.g. `--add self`.
364 365
 __docker_nodes() {
366
+	local add=()
365 367
 	local fields='$2'  # default: node name only
366 368
 	[ "${DOCKER_COMPLETION_SHOW_NODE_IDS}" = yes ] && fields='$1,$2' # ID and name
367 369
 
368
-	if [ "$1" = "--id" ] ; then
369
-		fields='$1' # IDs only
370
-		shift
371
-	elif [ "$1" = "--name" ] ; then
372
-		fields='$2' # names only
373
-		shift
374
-	fi
375
-	__docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}"
370
+	while true ; do
371
+		case "$1" in
372
+			--id)
373
+				fields='$1' # IDs only
374
+				shift
375
+				;;
376
+			--name)
377
+				fields='$2' # names only
378
+				shift
379
+				;;
380
+			--add)
381
+				add+=("$2")
382
+				shift 2
383
+				;;
384
+			*)
385
+				break
386
+				;;
387
+		esac
388
+	done
389
+
390
+	echo $(__docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}") "${add[@]}"
376 391
 }
377 392
 
378 393
 # __docker_complete_nodes applies completion of nodes based on the current
... ...
@@ -388,8 +403,7 @@ __docker_complete_nodes() {
388 388
 }
389 389
 
390 390
 __docker_complete_nodes_plus_self() {
391
-	__docker_complete_nodes "$@"
392
-	COMPREPLY+=( self )
391
+	__docker_complete_nodes --add self "$@"
393 392
 }
394 393
 
395 394
 # __docker_services returns a list of all services. Additional options to
... ...
@@ -1327,6 +1341,7 @@ _docker_container_run() {
1327 1327
 		--expose
1328 1328
 		--group-add
1329 1329
 		--hostname -h
1330
+		--init-path
1330 1331
 		--ip
1331 1332
 		--ip6
1332 1333
 		--ipc
... ...
@@ -1372,6 +1387,7 @@ _docker_container_run() {
1372 1372
 	local boolean_options="
1373 1373
 		--disable-content-trust=false
1374 1374
 		--help
1375
+		--init
1375 1376
 		--interactive -i
1376 1377
 		--oom-kill-disable
1377 1378
 		--privileged
... ...
@@ -1438,7 +1454,7 @@ _docker_container_run() {
1438 1438
 			__docker_complete_capabilities
1439 1439
 			return
1440 1440
 			;;
1441
-		--cidfile|--env-file|--label-file)
1441
+		--cidfile|--env-file|--init-path|--label-file)
1442 1442
 			_filedir
1443 1443
 			return
1444 1444
 			;;
... ...
@@ -1728,6 +1744,7 @@ _docker_daemon() {
1728 1728
 		--experimental
1729 1729
 		--help
1730 1730
 		--icc=false
1731
+		--init
1731 1732
 		--ip-forward=false
1732 1733
 		--ip-masq=false
1733 1734
 		--iptables=false
... ...
@@ -2004,6 +2021,7 @@ _docker_image_build() {
2004 2004
 		--quiet -q
2005 2005
 		--rm
2006 2006
 	"
2007
+	__docker_is_experimental && boolean_options+="--squash"
2007 2008
 
2008 2009
 	local all_options="$options_with_args $boolean_options"
2009 2010
 
... ...
@@ -2683,11 +2701,15 @@ _docker_service_ps() {
2683 2683
 			__docker_complete_services --cur "${cur##*=}" --name
2684 2684
 			return
2685 2685
 			;;
2686
+		node)
2687
+			__docker_complete_nodes_plus_self --cur "${cur##*=}"
2688
+			return
2689
+			;;
2686 2690
 	esac
2687 2691
 
2688 2692
 	case "$prev" in
2689 2693
 		--filter|-f)
2690
-			COMPREPLY=( $( compgen -W "desired-state id name" -S = -- "$cur" ) )
2694
+			COMPREPLY=( $( compgen -W "desired-state id name node" -S = -- "$cur" ) )
2691 2695
 			__docker_nospace
2692 2696
 			return
2693 2697
 			;;
... ...
@@ -2727,7 +2749,6 @@ _docker_service_update() {
2727 2727
 		--mount
2728 2728
 		--network
2729 2729
 		--no-healthcheck
2730
-		--publish -p
2731 2730
 		--replicas
2732 2731
 		--reserve-cpu
2733 2732
 		--reserve-memory
... ...
@@ -2765,7 +2786,7 @@ _docker_service_update() {
2765 2765
 			--host
2766 2766
 			--mode
2767 2767
 			--name
2768
-			--publish
2768
+			--publish -p
2769 2769
 			--secret
2770 2770
 		"
2771 2771
 
... ...
@@ -2907,6 +2928,8 @@ _docker_swarm() {
2907 2907
 		join
2908 2908
 		join-token
2909 2909
 		leave
2910
+		unlock
2911
+		unlock-key
2910 2912
 		update
2911 2913
 	"
2912 2914
 	__docker_subcommands "$subcommands" && return
... ...
@@ -2932,6 +2955,13 @@ _docker_swarm_init() {
2932 2932
 			fi
2933 2933
 			return
2934 2934
 			;;
2935
+		--availability)
2936
+			COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) )
2937
+			return
2938
+			;;
2939
+		--cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit)
2940
+			return
2941
+			;;
2935 2942
 		--listen-addr)
2936 2943
 			if [[ $cur == *: ]] ; then
2937 2944
 				COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
... ...
@@ -2945,7 +2975,7 @@ _docker_swarm_init() {
2945 2945
 
2946 2946
 	case "$cur" in
2947 2947
 		-*)
2948
-			COMPREPLY=( $( compgen -W "--advertise-addr --force-new-cluster --help --listen-addr" -- "$cur" ) )
2948
+			COMPREPLY=( $( compgen -W "--advertise-addr --autolock --availability --cert-expiry --dispatcher-heartbeat --external-ca --force-new-cluster --help --listen-addr --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
2949 2949
 			;;
2950 2950
 	esac
2951 2951
 }
... ...
@@ -3007,16 +3037,32 @@ _docker_swarm_leave() {
3007 3007
 	esac
3008 3008
 }
3009 3009
 
3010
+_docker_swarm_unlock() {
3011
+	case "$cur" in
3012
+		-*)
3013
+			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3014
+			;;
3015
+	esac
3016
+}
3017
+
3018
+_docker_swarm_unlock-key() {
3019
+	case "$cur" in
3020
+		-*)
3021
+			COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
3022
+			;;
3023
+	esac
3024
+}
3025
+
3010 3026
 _docker_swarm_update() {
3011 3027
 	case "$prev" in
3012
-		--cert-expiry|--dispatcher-heartbeat|--max-snapshots|--snapshot-interval|--task-history-limit)
3028
+		--cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit)
3013 3029
 			return
3014 3030
 			;;
3015 3031
 	esac
3016 3032
 
3017 3033
 	case "$cur" in
3018 3034
 		-*)
3019
-			COMPREPLY=( $( compgen -W "--cert-expiry --dispatcher-heartbeat --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
3035
+			COMPREPLY=( $( compgen -W "--autolock --cert-expiry --dispatcher-heartbeat --external-ca --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
3020 3036
 			;;
3021 3037
 	esac
3022 3038
 }
... ...
@@ -3289,7 +3335,7 @@ _docker_plugin_install() {
3289 3289
 
3290 3290
 	case "$cur" in
3291 3291
 		-*)
3292
-			COMPREPLY=( $( compgen -W "--alias --disable --grant-all-permissions --help" -- "$cur" ) )
3292
+			COMPREPLY=( $( compgen -W "--alias --disable --disable-content-trust=false --grant-all-permissions --help" -- "$cur" ) )
3293 3293
 			;;
3294 3294
 	esac
3295 3295
 }
... ...
@@ -3969,11 +4015,30 @@ _docker() {
3969 3969
 	local previous_extglob_setting=$(shopt -p extglob)
3970 3970
 	shopt -s extglob
3971 3971
 
3972
-	local commands=(
3973
-		attach
3972
+	local management_commands=(
3973
+		container
3974
+		image
3975
+		network
3976
+		node
3977
+		plugin
3978
+		secret
3979
+		service
3980
+		stack
3981
+		system
3982
+		volume
3983
+	)
3984
+
3985
+	local top_level_commands=(
3974 3986
 		build
3987
+		login
3988
+		logout
3989
+		run
3990
+		search
3991
+		version
3992
+	)
3993
+
3994
+	local legacy_commands=(
3975 3995
 		commit
3976
-		container
3977 3996
 		cp
3978 3997
 		create
3979 3998
 		diff
... ...
@@ -3981,20 +4046,14 @@ _docker() {
3981 3981
 		exec
3982 3982
 		export
3983 3983
 		history
3984
-		image
3985 3984
 		images
3986 3985
 		import
3987 3986
 		info
3988 3987
 		inspect
3989 3988
 		kill
3990 3989
 		load
3991
-		login
3992
-		logout
3993 3990
 		logs
3994
-		network
3995
-		node
3996 3991
 		pause
3997
-		plugin
3998 3992
 		port
3999 3993
 		ps
4000 3994
 		pull
... ...
@@ -4003,23 +4062,15 @@ _docker() {
4003 4003
 		restart
4004 4004
 		rm
4005 4005
 		rmi
4006
-		run
4007 4006
 		save
4008
-		search
4009
-		secret
4010
-		service
4011
-		stack
4012 4007
 		start
4013 4008
 		stats
4014 4009
 		stop
4015 4010
 		swarm
4016
-		system
4017 4011
 		tag
4018 4012
 		top
4019 4013
 		unpause
4020 4014
 		update
4021
-		version
4022
-		volume
4023 4015
 		wait
4024 4016
 	)
4025 4017
 
... ...
@@ -4027,6 +4078,9 @@ _docker() {
4027 4027
 		deploy
4028 4028
 	)
4029 4029
 
4030
+	local commands=(${management_commands[*]} ${top_level_commands[*]})
4031
+	[ -z "$DOCKER_HIDE_LEGACY_COMMANDS" ] && commands+=(${legacy_commands[*]})
4032
+
4030 4033
 	# These options are valid as global options for all client commands
4031 4034
 	# and valid as command options for `docker daemon`
4032 4035
 	local global_boolean_options="
... ...
@@ -474,6 +474,26 @@ __docker_complete_events_filter() {
474 474
     return ret
475 475
 }
476 476
 
477
+__docker_complete_prune_filters() {
478
+    [[ $PREFIX = -* ]] && return 1
479
+    integer ret=1
480
+    declare -a opts
481
+
482
+    opts=('until')
483
+
484
+    if compset -P '*='; then
485
+        case "${${words[-1]%=*}#*=}" in
486
+            *)
487
+                _message 'value' && ret=0
488
+                ;;
489
+        esac
490
+    else
491
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
492
+    fi
493
+
494
+    return ret
495
+}
496
+
477 497
 # BO container
478 498
 
479 499
 __docker_container_commands() {
... ...
@@ -541,6 +561,7 @@ __docker_container_subcommand() {
541 541
         "($help)*--group=[Set one or more supplementary user groups for the container]:group:_groups"
542 542
         "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts"
543 543
         "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]"
544
+        "($help)--init[Run an init inside the container that forwards signals and reaps processes]"
544 545
         "($help)--ip=[Container IPv4 address]:IPv4: "
545 546
         "($help)--ip6=[Container IPv6 address]:IPv6: "
546 547
         "($help)--ipc=[IPC namespace to use]:IPC namespace: "
... ...
@@ -731,6 +752,7 @@ __docker_container_subcommand() {
731 731
         (prune)
732 732
             _arguments $(__docker_arguments) \
733 733
                 $opts_help \
734
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
734 735
                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
735 736
             ;;
736 737
         (rename)
... ...
@@ -977,6 +999,7 @@ __docker_image_subcommand() {
977 977
             _arguments $(__docker_arguments) \
978 978
                 $opts_help \
979 979
                 "($help -a --all)"{-a,--all}"[Remove all unused images, not just dangling ones]" \
980
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
980 981
                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
981 982
             ;;
982 983
         (pull)
... ...
@@ -1204,6 +1227,7 @@ __docker_network_subcommand() {
1204 1204
         (prune)
1205 1205
             _arguments $(__docker_arguments) \
1206 1206
                 $opts_help \
1207
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
1207 1208
                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
1208 1209
             ;;
1209 1210
         (rm)
... ...
@@ -1497,9 +1521,15 @@ __docker_plugin_subcommand() {
1497 1497
     opts_help=("(: -)--help[Print usage]")
1498 1498
 
1499 1499
     case "$words[1]" in
1500
-        (disable|enable|inspect|install|ls|push|rm)
1500
+        (disable|enable|inspect|ls|push|rm)
1501
+            _arguments $(__docker_arguments) \
1502
+                $opts_help \
1503
+                "($help -)1:plugin:__docker_complete_plugins" && ret=0
1504
+            ;;
1505
+        (install)
1501 1506
             _arguments $(__docker_arguments) \
1502 1507
                 $opts_help \
1508
+                "($help)--alias=[Local name for plugin]:alias: " \
1503 1509
                 "($help -)1:plugin:__docker_complete_plugins" && ret=0
1504 1510
             ;;
1505 1511
         (set)
... ...
@@ -1588,7 +1618,7 @@ __docker_secret_subcommand() {
1588 1588
 
1589 1589
     case "$words[1]" in
1590 1590
         (create)
1591
-            _arguments $(__docker_arguments) \
1591
+            _arguments $(__docker_arguments) -A '-*' \
1592 1592
                 $opts_help \
1593 1593
                 "($help)*"{-l=,--label=}"[Secret labels]:label: " \
1594 1594
                 "($help -):secret: " && ret=0
... ...
@@ -2060,9 +2090,10 @@ __docker_swarm_subcommand() {
2060 2060
                 "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
2061 2061
             ;;
2062 2062
         (join)
2063
-            _arguments $(__docker_arguments) \
2063
+            _arguments $(__docker_arguments) -A '-*' \
2064 2064
                 $opts_help \
2065
-                "($help)--advertise-addr[Advertised address]:ip\:port: " \
2065
+                "($help)--advertise-addr=[Advertised address]:ip\:port: " \
2066
+                "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
2066 2067
                 "($help)--listen-addr=[Listen address]:ip\:port: " \
2067 2068
                 "($help)--token=[Token for entry into the swarm]:secret: " \
2068 2069
                 "($help -):host\:port: " && ret=0
... ...
@@ -2142,6 +2173,7 @@ __docker_system_subcommand() {
2142 2142
             _arguments $(__docker_arguments) \
2143 2143
                 $opts_help \
2144 2144
                 "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \
2145
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
2145 2146
                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
2146 2147
             ;;
2147 2148
         (help)
... ...
@@ -2370,6 +2402,7 @@ __docker_subcommand() {
2370 2370
                 "($help -g --graph)"{-g=,--graph=}"[Root of the Docker runtime]:path:_directories" \
2371 2371
                 "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
2372 2372
                 "($help)--icc[Enable inter-container communication]" \
2373
+                "($help)--init[Run an init inside containers to forward signals and reap processes]" \
2373 2374
                 "($help)--init-path=[Path to the docker-init binary]:docker-init binary:_files" \
2374 2375
                 "($help)*--insecure-registry=[Enable insecure registry communication]:registry: " \
2375 2376
                 "($help)--ip=[Default IP when binding container ports]" \
... ...
@@ -2492,14 +2525,14 @@ __docker_subcommand() {
2492 2492
             esac
2493 2493
             ;;
2494 2494
         (login)
2495
-            _arguments $(__docker_arguments) \
2495
+            _arguments $(__docker_arguments) -A '-*' \
2496 2496
                 $opts_help \
2497 2497
                 "($help -p --password)"{-p=,--password=}"[Password]:password: " \
2498 2498
                 "($help -u --user)"{-u=,--user=}"[Username]:username: " \
2499 2499
                 "($help -)1:server: " && ret=0
2500 2500
             ;;
2501 2501
         (logout)
2502
-            _arguments $(__docker_arguments) \
2502
+            _arguments $(__docker_arguments) -A '-*' \
2503 2503
                 $opts_help \
2504 2504
                 "($help -)1:server: " && ret=0
2505 2505
             ;;
... ...
@@ -2563,7 +2596,7 @@ __docker_subcommand() {
2563 2563
             __docker_image_subcommand && ret=0
2564 2564
             ;;
2565 2565
         (search)
2566
-            _arguments $(__docker_arguments) \
2566
+            _arguments $(__docker_arguments) -A '-*' \
2567 2567
                 $opts_help \
2568 2568
                 "($help)*"{-f=,--filter=}"[Filter values]:filter:->filter-options" \
2569 2569
                 "($help)--limit=[Maximum returned search results]:limit:(1 5 10 25 50)" \
... ...
@@ -352,7 +352,7 @@ func (c *Cluster) startNewNode(conf nodeStartConfig) (*node, error) {
352 352
 	c.actualLocalAddr = actualLocalAddr // not saved
353 353
 	c.saveState(conf)
354 354
 
355
-	c.config.Backend.SetClusterProvider(c)
355
+	c.config.Backend.DaemonJoinsCluster(c)
356 356
 	go func() {
357 357
 		err := detectLockedError(n.Err(ctx))
358 358
 		if err != nil {
... ...
@@ -725,6 +725,7 @@ func (c *Cluster) Leave(force bool) error {
725 725
 	if err := c.clearState(); err != nil {
726 726
 		return err
727 727
 	}
728
+
728 729
 	return nil
729 730
 }
730 731
 
... ...
@@ -752,7 +753,7 @@ func (c *Cluster) clearState() error {
752 752
 	if err := os.MkdirAll(c.root, 0700); err != nil {
753 753
 		return err
754 754
 	}
755
-	c.config.Backend.SetClusterProvider(nil)
755
+	c.config.Backend.DaemonLeavesCluster()
756 756
 	return nil
757 757
 }
758 758
 
... ...
@@ -47,7 +47,8 @@ type Backend interface {
47 47
 	VolumeCreate(name, driverName string, opts, labels map[string]string) (*types.Volume, error)
48 48
 	Containers(config *types.ContainerListOptions) ([]*types.Container, error)
49 49
 	SetNetworkBootstrapKeys([]*networktypes.EncryptionKey) error
50
-	SetClusterProvider(provider cluster.Provider)
50
+	DaemonJoinsCluster(provider cluster.Provider)
51
+	DaemonLeavesCluster()
51 52
 	IsSwarmCompatible() error
52 53
 	SubscribeToEvents(since, until time.Time, filter filters.Args) ([]events.Message, chan interface{})
53 54
 	UnsubscribeFromEvents(listener chan interface{})
... ...
@@ -446,8 +446,22 @@ func (daemon *Daemon) registerLink(parent, child *container.Container, alias str
446 446
 	return nil
447 447
 }
448 448
 
449
-// SetClusterProvider sets a component for querying the current cluster state.
450
-func (daemon *Daemon) SetClusterProvider(clusterProvider cluster.Provider) {
449
+// DaemonJoinsCluster informs the daemon has joined the cluster and provides
450
+// the handler to query the cluster component
451
+func (daemon *Daemon) DaemonJoinsCluster(clusterProvider cluster.Provider) {
452
+	daemon.setClusterProvider(clusterProvider)
453
+}
454
+
455
+// DaemonLeavesCluster informs the daemon has left the cluster
456
+func (daemon *Daemon) DaemonLeavesCluster() {
457
+	// Daemon is in charge of removing the attachable networks with
458
+	// connected containers when the node leaves the swarm
459
+	daemon.clearAttachableNetworks()
460
+	daemon.setClusterProvider(nil)
461
+}
462
+
463
+// setClusterProvider sets a component for querying the current cluster state.
464
+func (daemon *Daemon) setClusterProvider(clusterProvider cluster.Provider) {
451 465
 	daemon.clusterProvider = clusterProvider
452 466
 	// call this in a goroutine to allow netcontroller handle this event async
453 467
 	// and not block if it is in the middle of talking with cluster
... ...
@@ -1190,6 +1190,12 @@ func (daemon *Daemon) initCgroupsPath(path string) error {
1190 1190
 		return nil
1191 1191
 	}
1192 1192
 
1193
+	if daemon.configStore.CPURealtimePeriod == 0 && daemon.configStore.CPURealtimeRuntime == 0 {
1194
+		return nil
1195
+	}
1196
+
1197
+	// Recursively create cgroup to ensure that the system and all parent cgroups have values set
1198
+	// for the period and runtime as this limits what the children can be set to.
1193 1199
 	daemon.initCgroupsPath(filepath.Dir(path))
1194 1200
 
1195 1201
 	_, root, err := cgroups.FindCgroupMountpointAndRoot("cpu")
... ...
@@ -1198,16 +1204,19 @@ func (daemon *Daemon) initCgroupsPath(path string) error {
1198 1198
 	}
1199 1199
 
1200 1200
 	path = filepath.Join(root, path)
1201
-	sysinfo := sysinfo.New(false)
1202
-	if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
1203
-		return err
1204
-	}
1201
+	sysinfo := sysinfo.New(true)
1205 1202
 	if sysinfo.CPURealtimePeriod && daemon.configStore.CPURealtimePeriod != 0 {
1203
+		if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
1204
+			return err
1205
+		}
1206 1206
 		if err := ioutil.WriteFile(filepath.Join(path, "cpu.rt_period_us"), []byte(strconv.FormatInt(daemon.configStore.CPURealtimePeriod, 10)), 0700); err != nil {
1207 1207
 			return err
1208 1208
 		}
1209 1209
 	}
1210 1210
 	if sysinfo.CPURealtimeRuntime && daemon.configStore.CPURealtimeRuntime != 0 {
1211
+		if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
1212
+			return err
1213
+		}
1211 1214
 		if err := ioutil.WriteFile(filepath.Join(path, "cpu.rt_runtime_us"), []byte(strconv.FormatInt(daemon.configStore.CPURealtimeRuntime, 10)), 0700); err != nil {
1212 1215
 			return err
1213 1216
 		}
... ...
@@ -205,7 +205,7 @@ func (daemon *Daemon) Images(imageFilters filters.Args, all bool, withExtraAttrs
205 205
 	}
206 206
 
207 207
 	if withExtraAttrs {
208
-		// Get Shared and Unique sizes
208
+		// Get Shared sizes
209 209
 		for img, newImage := range imagesMap {
210 210
 			rootFS := *img.RootFS
211 211
 			rootFS.DiffIDs = nil
... ...
@@ -468,3 +468,31 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
468 468
 func (daemon *Daemon) GetNetworks() []libnetwork.Network {
469 469
 	return daemon.getAllNetworks()
470 470
 }
471
+
472
+// clearAttachableNetworks removes the attachable networks
473
+// after disconnecting any connected container
474
+func (daemon *Daemon) clearAttachableNetworks() {
475
+	for _, n := range daemon.GetNetworks() {
476
+		if !n.Info().Attachable() {
477
+			continue
478
+		}
479
+		for _, ep := range n.Endpoints() {
480
+			epInfo := ep.Info()
481
+			if epInfo == nil {
482
+				continue
483
+			}
484
+			sb := epInfo.Sandbox()
485
+			if sb == nil {
486
+				continue
487
+			}
488
+			containerID := sb.ContainerID()
489
+			if err := daemon.DisconnectContainerFromNetwork(containerID, n.ID(), true); err != nil {
490
+				logrus.Warnf("Failed to disconnect container %s from swarm network %s on cluster leave: %v",
491
+					containerID, n.Name(), err)
492
+			}
493
+		}
494
+		if err := daemon.DeleteManagedNetwork(n.ID()); err != nil {
495
+			logrus.Warnf("Failed to remove swarm network %s on cluster leave: %v", n.Name(), err)
496
+		}
497
+	}
498
+}
... ...
@@ -581,7 +581,7 @@ func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container)
581 581
 	if c.HostConfig.PidMode.IsPrivate() {
582 582
 		if (c.HostConfig.Init != nil && *c.HostConfig.Init) ||
583 583
 			(c.HostConfig.Init == nil && daemon.configStore.Init) {
584
-			s.Process.Args = append([]string{"/dev/init", c.Path}, c.Args...)
584
+			s.Process.Args = append([]string{"/dev/init", "--", c.Path}, c.Args...)
585 585
 			var path string
586 586
 			if daemon.configStore.InitPath == "" && c.HostConfig.InitPath == "" {
587 587
 				path, err = exec.LookPath(DefaultInitBinary)
... ...
@@ -23,7 +23,11 @@ import (
23 23
 var ImageTypes = []string{
24 24
 	schema2.MediaTypeImageConfig,
25 25
 	// Handle unexpected values from https://github.com/docker/distribution/issues/1621
26
+	// (see also https://github.com/docker/docker/issues/22378,
27
+	// https://github.com/docker/docker/issues/30083)
26 28
 	"application/octet-stream",
29
+	"application/json",
30
+	"text/html",
27 31
 	// Treat defaulted values as images, newer types cannot be implied
28 32
 	"",
29 33
 }
30 34
new file mode 100644
... ...
@@ -0,0 +1,164 @@
0
+---
1
+description: Volume plugin for Amazon EBS
2
+keywords: "API, Usage, plugins, documentation, developer, amazon, ebs, rexray, volume"
3
+title: Volume plugin for Amazon EBS
4
+---
5
+
6
+<!-- This file is maintained within the docker/docker Github
7
+     repository at https://github.com/docker/docker/. Make all
8
+     pull requests against that repo. If you see this file in
9
+     another repository, consider it read-only there, as it will
10
+     periodically be overwritten by the definitive file. Pull
11
+     requests which include edits to this file in other repositories
12
+     will be rejected.
13
+-->
14
+
15
+# A proof-of-concept Rexray plugin
16
+
17
+In this example, a simple Rexray plugin will be created for the purposes of using
18
+it on an Amazon EC2 instance with EBS. It is not meant to be a complete Rexray plugin.
19
+
20
+The example source is available at [https://github.com/tiborvass/rexray-plugin](https://github.com/tiborvass/rexray-plugin).
21
+
22
+To learn more about Rexray: [https://github.com/codedellemc/rexray](https://github.com/codedellemc/rexray)
23
+
24
+## 1. Make a Docker image
25
+
26
+The following is the Dockerfile used to containerize rexray.
27
+
28
+```Dockerfile
29
+FROM debian:jessie
30
+RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates
31
+RUN wget https://dl.bintray.com/emccode/rexray/stable/0.6.4/rexray-Linux-x86_64-0.6.4.tar.gz -O rexray.tar.gz && tar -xvzf rexray.tar.gz -C /usr/bin && rm rexray.tar.gz
32
+RUN mkdir -p /run/docker/plugins /var/lib/libstorage/volumes
33
+ENTRYPOINT ["rexray"]
34
+CMD ["--help"]
35
+```
36
+
37
+To build it you can run `image=$(cat Dockerfile | docker build -q -)` and `$image`
38
+will reference the containerized rexray image.
39
+
40
+## 2. Extract rootfs
41
+
42
+```sh
43
+$ TMPDIR=/tmp/rexray  # for the purpose of this example
44
+$  # create container without running it, to extract the rootfs from image
45
+$ docker create --name rexray "$image"
46
+$  # save the rootfs to a tar archive
47
+$ docker export -o $TMPDIR/rexray.tar rexray
48
+$  # extract rootfs from tar archive to a rootfs folder
49
+$ ( mkdir -p $TMPDIR/rootfs; cd $TMPDIR/rootfs; tar xf ../rexray.tar )
50
+```
51
+
52
+## 3. Add plugin configuration
53
+
54
+We have to put the following JSON to `$TMPDIR/config.json`:
55
+
56
+```json
57
+{
58
+      "Args": {
59
+        "Description": "",
60
+        "Name": "",
61
+        "Settable": null,
62
+        "Value": null
63
+      },
64
+      "Description": "A proof-of-concept EBS plugin (using rexray) for Docker",
65
+      "Documentation": "https://github.com/tiborvass/rexray-plugin",
66
+      "Entrypoint": [
67
+        "/usr/bin/rexray", "service", "start", "-f"
68
+      ],
69
+      "Env": [
70
+        {
71
+          "Description": "",
72
+          "Name": "REXRAY_SERVICE",
73
+          "Settable": [
74
+            "value"
75
+          ],
76
+          "Value": "ebs"
77
+        },
78
+        {
79
+          "Description": "",
80
+          "Name": "EBS_ACCESSKEY",
81
+          "Settable": [
82
+            "value"
83
+          ],
84
+          "Value": ""
85
+        },
86
+        {
87
+          "Description": "",
88
+          "Name": "EBS_SECRETKEY",
89
+          "Settable": [
90
+            "value"
91
+          ],
92
+          "Value": ""
93
+        }
94
+      ],
95
+      "Interface": {
96
+        "Socket": "rexray.sock",
97
+        "Types": [
98
+          "docker.volumedriver/1.0"
99
+        ]
100
+      },
101
+      "Linux": {
102
+        "AllowAllDevices": true,
103
+        "Capabilities": ["CAP_SYS_ADMIN"],
104
+        "Devices": null
105
+      },
106
+      "Mounts": [
107
+        {
108
+          "Source": "/dev",
109
+          "Destination": "/dev",
110
+          "Type": "bind",
111
+          "Options": ["rbind"]
112
+        }
113
+      ],
114
+      "Network": {
115
+        "Type": "host"
116
+      },
117
+      "PropagatedMount": "/var/lib/libstorage/volumes",
118
+      "User": {},
119
+      "WorkDir": ""
120
+}
121
+```
122
+
123
+Please note a couple of points:
124
+- `PropagatedMount` is needed so that the docker daemon can see mounts done by the
125
+rexray plugin from within the container, otherwise the docker daemon is not able
126
+to mount a docker volume.
127
+- The rexray plugin needs dynamic access to host devices. For that reason, we
128
+have to give it access to all devices under `/dev` and set `AllowAllDevices` to
129
+true for proper access.
130
+- The user of this simple plugin can change only 3 settings: `REXRAY_SERVICE`,
131
+`EBS_ACCESSKEY` and `EBS_SECRETKEY`. This is because of the reduced scope of this
132
+plugin. Ideally other rexray parameters could also be set.
133
+
134
+## 4. Create plugin
135
+
136
+`docker plugin create tiborvass/rexray-plugin "$TMPDIR"` will create the plugin.
137
+
138
+```sh
139
+$ docker plugin ls
140
+ID                  NAME                             DESCRIPTION                         ENABLED
141
+2475a4bd0ca5        tiborvass/rexray-plugin:latest   A rexray volume plugin for Docker   false
142
+```
143
+
144
+## 5. Test plugin
145
+
146
+```sh
147
+$ docker plugin set tiborvass/rexray-plugin EBS_ACCESSKEY=$AWS_ACCESSKEY EBS_SECRETKEY=$AWS_SECRETKEY`
148
+$ docker plugin enable tiborvass/rexray-plugin
149
+$ docker volume create -d tiborvass/rexray-plugin my-ebs-volume
150
+$ docker volume ls
151
+DRIVER                              VOLUME NAME
152
+tiborvass/rexray-plugin:latest      my-ebs-volume
153
+$ docker run --rm -v my-ebs-volume:/volume busybox sh -c 'echo bye > /volume/hi'
154
+$ docker run --rm -v my-ebs-volume:/volume busybox cat /volume/hi
155
+bye
156
+```
157
+
158
+## 6. Push plugin
159
+
160
+First, ensure you are logged in with `docker login`. Then you can run:
161
+`docker plugin push tiborvass/rexray-plugin` to push it like a regular docker
162
+image to a registry, to make it available for others to install via
163
+`docker plugin install tiborvass/rexray-plugin EBS_ACCESSKEY=$AWS_ACCESSKEY EBS_SECRETKEY=$AWS_SECRETKEY`.
... ...
@@ -154,7 +154,7 @@ This plugin is a volume driver. It requires a `host` network and the
154 154
 entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate
155 155
 with Docker Engine. This plugin has no runtime parameters.
156 156
 
157
-### Creating the plugin
157
+#### Creating the plugin
158 158
 
159 159
 A new plugin can be created by running
160 160
 `docker plugin create <plugin-name> ./path/to/plugin/data` where the plugin
... ...
@@ -163,4 +163,4 @@ in subdirectory `rootfs`.
163 163
 
164 164
 After that the plugin `<plugin-name>` will show up in `docker plugin ls`.
165 165
 Plugins can be pushed to remote registries with
166
-`docker plugin push <plugin-name>`.
167 166
\ No newline at end of file
167
+`docker plugin push <plugin-name>`.
... ...
@@ -63,6 +63,8 @@ Options:
63 63
       --health-timeout duration     Maximum time to allow one check to run (ns|us|ms|s|m|h) (default 0s)
64 64
       --help                        Print usage
65 65
   -h, --hostname string             Container host name
66
+      --init                        Run an init inside the container that forwards signals and reaps processes
67
+      --init-path string            Path to the docker-init binary
66 68
   -i, --interactive                 Keep STDIN open even if not attached
67 69
       --io-maxbandwidth string      Maximum IO bandwidth limit for the system drive (Windows only)
68 70
       --io-maxiops uint             Maximum IOps limit for the system drive (Windows only)
... ...
@@ -67,6 +67,8 @@ Options:
67 67
       --health-timeout duration     Maximum time to allow one check to run (ns|us|ms|s|m|h) (default 0s)
68 68
       --help                        Print usage
69 69
   -h, --hostname string             Container host name
70
+      --init                        Run an init inside the container that forwards signals and reaps processes
71
+      --init-path string            Path to the docker-init binary
70 72
   -i, --interactive                 Keep STDIN open even if not attached
71 73
       --io-maxbandwidth string      Maximum IO bandwidth limit for the system drive (Windows only)
72 74
                                     (Windows only). The format is `<number><unit>`.
... ...
@@ -137,7 +137,7 @@ Create a service specifying the secret, target, user/group ID and mode:
137 137
 ```bash
138 138
 $ docker service create --name redis \
139 139
     --secret source=ssh-key,target=ssh \
140
-    --secret src=app-key,target=app,uid=1000,gid=1001,mode=0400 \
140
+    --secret source=app-key,target=app,uid=1000,gid=1001,mode=0400 \
141 141
     redis:3.0.6
142 142
 4cdgfyky7ozwh3htjfw0d12qv
143 143
 ```
... ...
@@ -85,7 +85,7 @@ do
85 85
 			git clone https://github.com/krallin/tini.git "$GOPATH/tini"
86 86
 			cd "$GOPATH/tini"
87 87
 			git checkout -q "$TINI_COMMIT"
88
-			cmake -DMINIMAL=ON .
88
+			cmake .
89 89
 			make tini-static
90 90
 			cp tini-static /usr/local/bin/docker-init
91 91
 			;;
... ...
@@ -3,6 +3,7 @@
3 3
 package main
4 4
 
5 5
 import (
6
+	"encoding/json"
6 7
 	"fmt"
7 8
 	"net/http"
8 9
 	"os"
... ...
@@ -13,6 +14,7 @@ import (
13 13
 	"syscall"
14 14
 	"time"
15 15
 
16
+	"github.com/docker/docker/api/types"
16 17
 	"github.com/docker/docker/api/types/swarm"
17 18
 	"github.com/docker/docker/pkg/integration/checker"
18 19
 	"github.com/go-check/check"
... ...
@@ -1310,3 +1312,56 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsDelete(c *check.C) {
1310 1310
 	c.Assert(err, checker.IsNil)
1311 1311
 	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
1312 1312
 }
1313
+
1314
+// Test case for 30242, where duplicate networks, with different drivers `bridge` and `overlay`,
1315
+// caused both scopes to be `swarm` for `docker network inspect` and `docker network ls`.
1316
+// This test makes sure the fixes correctly output scopes instead.
1317
+func (s *DockerSwarmSuite) TestAPIDuplicateNetworks(c *check.C) {
1318
+	d := s.AddDaemon(c, true, true)
1319
+
1320
+	name := "foo"
1321
+	networkCreateRequest := types.NetworkCreateRequest{
1322
+		Name: name,
1323
+		NetworkCreate: types.NetworkCreate{
1324
+			CheckDuplicate: false,
1325
+		},
1326
+	}
1327
+
1328
+	var n1 types.NetworkCreateResponse
1329
+	networkCreateRequest.NetworkCreate.Driver = "bridge"
1330
+
1331
+	status, out, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
1332
+	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
1333
+	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
1334
+
1335
+	c.Assert(json.Unmarshal(out, &n1), checker.IsNil)
1336
+
1337
+	var n2 types.NetworkCreateResponse
1338
+	networkCreateRequest.NetworkCreate.Driver = "overlay"
1339
+
1340
+	status, out, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
1341
+	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
1342
+	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
1343
+
1344
+	c.Assert(json.Unmarshal(out, &n2), checker.IsNil)
1345
+
1346
+	var r1 types.NetworkResource
1347
+
1348
+	status, out, err = d.SockRequest("GET", "/networks/"+n1.ID, nil)
1349
+	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
1350
+	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
1351
+
1352
+	c.Assert(json.Unmarshal(out, &r1), checker.IsNil)
1353
+
1354
+	c.Assert(r1.Scope, checker.Equals, "local")
1355
+
1356
+	var r2 types.NetworkResource
1357
+
1358
+	status, out, err = d.SockRequest("GET", "/networks/"+n2.ID, nil)
1359
+	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
1360
+	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
1361
+
1362
+	c.Assert(json.Unmarshal(out, &r2), checker.IsNil)
1363
+
1364
+	c.Assert(r2.Scope, checker.Equals, "swarm")
1365
+}
... ...
@@ -943,3 +943,10 @@ func (s *DockerSuite) TestPsFilterMissingArgErrorCode(c *check.C) {
943 943
 	_, errCode, _ := dockerCmdWithError("ps", "--filter")
944 944
 	c.Assert(errCode, checker.Equals, 125)
945 945
 }
946
+
947
+// Test case for 30291
948
+func (s *DockerSuite) TestPsFormatTemplateWithArg(c *check.C) {
949
+	runSleepingContainer(c, "-d", "--name", "top", "--label", "some.label=label.foo-bar")
950
+	out, _ := dockerCmd(c, "ps", "--format", `{{.Names}} {{.Label "some.label"}}`)
951
+	c.Assert(strings.TrimSpace(out), checker.Equals, "top label.foo-bar")
952
+}
... ...
@@ -393,6 +393,33 @@ func (s *DockerSwarmSuite) TestOverlayAttachable(c *check.C) {
393 393
 	c.Assert(strings.TrimSpace(out), checker.Equals, "true")
394 394
 }
395 395
 
396
+func (s *DockerSwarmSuite) TestOverlayAttachableOnSwarmLeave(c *check.C) {
397
+	d := s.AddDaemon(c, true, true)
398
+
399
+	// Create an attachable swarm network
400
+	nwName := "attovl"
401
+	out, err := d.Cmd("network", "create", "-d", "overlay", "--attachable", nwName)
402
+	c.Assert(err, checker.IsNil, check.Commentf(out))
403
+
404
+	// Connect a container to the network
405
+	out, err = d.Cmd("run", "-d", "--network", nwName, "--name", "c1", "busybox", "top")
406
+	c.Assert(err, checker.IsNil, check.Commentf(out))
407
+
408
+	// Leave the swarm
409
+	err = d.Leave(true)
410
+	c.Assert(err, checker.IsNil)
411
+
412
+	// Check the container is disconnected
413
+	out, err = d.Cmd("inspect", "c1", "--format", "{{.NetworkSettings.Networks."+nwName+"}}")
414
+	c.Assert(err, checker.IsNil)
415
+	c.Assert(strings.TrimSpace(out), checker.Equals, "<no value>")
416
+
417
+	// Check the network is gone
418
+	out, err = d.Cmd("network", "ls", "--format", "{{.Name}}")
419
+	c.Assert(err, checker.IsNil)
420
+	c.Assert(out, checker.Not(checker.Contains), nwName)
421
+}
422
+
396 423
 func (s *DockerSwarmSuite) TestSwarmRemoveInternalNetwork(c *check.C) {
397 424
 	d := s.AddDaemon(c, true, true)
398 425
 
... ...
@@ -45,7 +45,7 @@ func (clnt *client) GetServerVersion(ctx context.Context) (*ServerVersion, error
45 45
 // AddProcess is the handler for adding a process to an already running
46 46
 // container. It's called through docker exec. It returns the system pid of the
47 47
 // exec'd process.
48
-func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, specp Process, attachStdio StdioCallback) (int, error) {
48
+func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, specp Process, attachStdio StdioCallback) (pid int, err error) {
49 49
 	clnt.lock(containerID)
50 50
 	defer clnt.unlock(containerID)
51 51
 	container, err := clnt.getContainer(containerID)
... ...
@@ -101,7 +101,14 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
101 101
 		Rlimits:         convertRlimits(sp.Rlimits),
102 102
 	}
103 103
 
104
-	iopipe, err := p.openFifos(sp.Terminal)
104
+	fifoCtx, cancel := context.WithCancel(context.Background())
105
+	defer func() {
106
+		if err != nil {
107
+			cancel()
108
+		}
109
+	}()
110
+
111
+	iopipe, err := p.openFifos(fifoCtx, sp.Terminal)
105 112
 	if err != nil {
106 113
 		return -1, err
107 114
 	}
... ...
@@ -335,7 +342,14 @@ func (clnt *client) restore(cont *containerd.Container, lastEvent *containerd.Ev
335 335
 		}
336 336
 	}
337 337
 
338
-	iopipe, err := container.openFifos(terminal)
338
+	fifoCtx, cancel := context.WithCancel(context.Background())
339
+	defer func() {
340
+		if err != nil {
341
+			cancel()
342
+		}
343
+	}()
344
+
345
+	iopipe, err := container.openFifos(fifoCtx, terminal)
339 346
 	if err != nil {
340 347
 		return err
341 348
 	}
... ...
@@ -90,7 +90,7 @@ func (ctr *container) spec() (*specs.Spec, error) {
90 90
 	return &spec, nil
91 91
 }
92 92
 
93
-func (ctr *container) start(checkpoint string, checkpointDir string, attachStdio StdioCallback) error {
93
+func (ctr *container) start(checkpoint string, checkpointDir string, attachStdio StdioCallback) (err error) {
94 94
 	spec, err := ctr.spec()
95 95
 	if err != nil {
96 96
 		return nil
... ...
@@ -100,7 +100,14 @@ func (ctr *container) start(checkpoint string, checkpointDir string, attachStdio
100 100
 	defer cancel()
101 101
 	ready := make(chan struct{})
102 102
 
103
-	iopipe, err := ctr.openFifos(spec.Process.Terminal)
103
+	fifoCtx, cancel := context.WithCancel(context.Background())
104
+	defer func() {
105
+		if err != nil {
106
+			cancel()
107
+		}
108
+	}()
109
+
110
+	iopipe, err := ctr.openFifos(fifoCtx, spec.Process.Terminal)
104 111
 	if err != nil {
105 112
 		return err
106 113
 	}
... ...
@@ -9,7 +9,6 @@ import (
9 9
 	"path/filepath"
10 10
 	goruntime "runtime"
11 11
 	"strings"
12
-	"time"
13 12
 
14 13
 	containerd "github.com/docker/containerd/api/grpc/types"
15 14
 	"github.com/tonistiigi/fifo"
... ...
@@ -31,13 +30,11 @@ type process struct {
31 31
 	dir string
32 32
 }
33 33
 
34
-func (p *process) openFifos(terminal bool) (pipe *IOPipe, err error) {
34
+func (p *process) openFifos(ctx context.Context, terminal bool) (pipe *IOPipe, err error) {
35 35
 	if err := os.MkdirAll(p.dir, 0700); err != nil {
36 36
 		return nil, err
37 37
 	}
38 38
 
39
-	ctx, _ := context.WithTimeout(context.Background(), 15*time.Second)
40
-
41 39
 	io := &IOPipe{}
42 40
 
43 41
 	io.Stdin, err = fifo.OpenFifo(ctx, p.fifo(unix.Stdin), unix.O_WRONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
... ...
@@ -41,6 +41,8 @@ docker-run - Run a command in a new container
41 41
 [**--group-add**[=*[]*]]
42 42
 [**-h**|**--hostname**[=*HOSTNAME*]]
43 43
 [**--help**]
44
+[**--init**]
45
+[**--init-path**[=*[]*]]
44 46
 [**-i**|**--interactive**]
45 47
 [**--ip**[=*IPv4-ADDRESS*]]
46 48
 [**--ip6**[=*IPv6-ADDRESS*]]
... ...
@@ -309,7 +311,13 @@ redirection on the host system.
309 309
    Sets the container host name that is available inside the container.
310 310
 
311 311
 **--help**
312
-  Print usage statement
312
+   Print usage statement
313
+
314
+**--init**
315
+   Run an init inside the container that forwards signals and reaps processes
316
+
317
+**--init-path**=""
318
+   Path to the docker-init binary
313 319
 
314 320
 **-i**, **--interactive**=*true*|*false*
315 321
    Keep STDIN open even if not attached. The default is *false*.
... ...
@@ -50,7 +50,7 @@ func (o *SecretOpt) Set(value string) error {
50 50
 
51 51
 		value := parts[1]
52 52
 		switch key {
53
-		case "source":
53
+		case "source", "src":
54 54
 			options.Source = value
55 55
 		case "target":
56 56
 			tDir, _ := filepath.Split(value)
... ...
@@ -35,6 +35,18 @@ func TestSecretOptionsSourceTarget(t *testing.T) {
35 35
 	assert.Equal(t, req.Target, "testing")
36 36
 }
37 37
 
38
+func TestSecretOptionsShorthand(t *testing.T) {
39
+	var opt SecretOpt
40
+
41
+	testCase := "src=foo,target=testing"
42
+	assert.NilError(t, opt.Set(testCase))
43
+
44
+	reqs := opt.Value()
45
+	assert.Equal(t, len(reqs), 1)
46
+	req := reqs[0]
47
+	assert.Equal(t, req.Source, "foo")
48
+}
49
+
38 50
 func TestSecretOptionsCustomUidGid(t *testing.T) {
39 51
 	var opt SecretOpt
40 52
 
... ...
@@ -1,6 +1,7 @@
1 1
 package plugins
2 2
 
3 3
 import (
4
+	"errors"
4 5
 	"path/filepath"
5 6
 	"runtime"
6 7
 	"sync"
... ...
@@ -20,6 +21,12 @@ func TestPluginAddHandler(t *testing.T) {
20 20
 	testActive(t, p)
21 21
 }
22 22
 
23
+func TestPluginWaitBadPlugin(t *testing.T) {
24
+	p := &Plugin{activateWait: sync.NewCond(&sync.Mutex{})}
25
+	p.activateErr = errors.New("some junk happened")
26
+	testActive(t, p)
27
+}
28
+
23 29
 func testActive(t *testing.T, p *Plugin) {
24 30
 	done := make(chan struct{})
25 31
 	go func() {
... ...
@@ -78,12 +78,6 @@ type Plugin struct {
78 78
 	handlersRun bool
79 79
 }
80 80
 
81
-// BasePath returns the path to which all paths returned by the plugin are relative to.
82
-// For v1 plugins, this always returns the host's root directory.
83
-func (p *Plugin) BasePath() string {
84
-	return "/"
85
-}
86
-
87 81
 // Name returns the name of the plugin.
88 82
 func (p *Plugin) Name() string {
89 83
 	return p.name
... ...
@@ -175,7 +169,7 @@ func (p *Plugin) activateWithLock() error {
175 175
 
176 176
 func (p *Plugin) waitActive() error {
177 177
 	p.activateWait.L.Lock()
178
-	for !p.activated() {
178
+	for !p.activated() && p.activateErr == nil {
179 179
 		p.activateWait.Wait()
180 180
 	}
181 181
 	p.activateWait.L.Unlock()
182 182
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+package plugins
1
+
2
+// BasePath returns the path to which all paths returned by the plugin are relative to.
3
+// For v1 plugins, this always returns the host's root directory.
4
+func (p *Plugin) BasePath() string {
5
+	return "/"
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+package plugins
1
+
2
+// BasePath returns the path to which all paths returned by the plugin are relative to.
3
+// For Windows v1 plugins, this returns an empty string, since the plugin is already aware
4
+// of the absolute path of the mount.
5
+func (p *Plugin) BasePath() string {
6
+	return ""
7
+}
... ...
@@ -82,23 +82,23 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
82 82
 
83 83
 	swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
84 84
 	if !quiet && !swapLimit {
85
-		logrus.Warn("Your kernel does not support swap memory limit.")
85
+		logrus.Warn("Your kernel does not support swap memory limit")
86 86
 	}
87 87
 	memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes")
88 88
 	if !quiet && !memoryReservation {
89
-		logrus.Warn("Your kernel does not support memory reservation.")
89
+		logrus.Warn("Your kernel does not support memory reservation")
90 90
 	}
91 91
 	oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control")
92 92
 	if !quiet && !oomKillDisable {
93
-		logrus.Warn("Your kernel does not support oom control.")
93
+		logrus.Warn("Your kernel does not support oom control")
94 94
 	}
95 95
 	memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness")
96 96
 	if !quiet && !memorySwappiness {
97
-		logrus.Warn("Your kernel does not support memory swappiness.")
97
+		logrus.Warn("Your kernel does not support memory swappiness")
98 98
 	}
99 99
 	kernelMemory := cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes")
100 100
 	if !quiet && !kernelMemory {
101
-		logrus.Warn("Your kernel does not support kernel memory limit.")
101
+		logrus.Warn("Your kernel does not support kernel memory limit")
102 102
 	}
103 103
 
104 104
 	return cgroupMemInfo{