Browse code

Merge pull request #32190 from vieux/cherry-picks-17.04-rc2

cherry picks 17.04.0-rc2

Victor Vieux authored on 2017/03/29 15:50:27
Showing 31 changed files
... ...
@@ -141,6 +141,9 @@ run: build ## run the docker daemon in a container
141 141
 shell: build ## start a shell inside the build env
142 142
 	$(DOCKER_RUN_DOCKER) bash
143 143
 
144
+yaml-docs-gen: build ## generate documentation YAML files consumed by docs repo
145
+	$(DOCKER_RUN_DOCKER) sh -c 'hack/make.sh yaml-docs-generator && ( cd bundles/latest/yaml-docs-generator; mkdir docs; ./yaml-docs-generator --target $$(pwd)/docs )'
146
+
144 147
 test: build ## run the unit, integration and docker-py tests
145 148
 	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration-cli test-docker-py
146 149
 
... ...
@@ -253,9 +253,9 @@ func (s *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter,
253 253
 		return err
254 254
 	}
255 255
 
256
-	version := httputils.VersionFromContext(ctx)
257 256
 	filterParam := r.Form.Get("filter")
258
-	if versions.LessThanOrEqualTo(version, "1.28") && filterParam != "" {
257
+	// FIXME(vdemeester) This has been deprecated in 1.13, and is target for removal for v17.12
258
+	if filterParam != "" {
259 259
 		imageFilters.Add("reference", filterParam)
260 260
 	}
261 261
 
... ...
@@ -486,10 +486,10 @@ definitions:
486 486
         description: |
487 487
           The test to perform. Possible values are:
488 488
 
489
-          - `{}` inherit healthcheck from image or parent image
490
-          - `{"NONE"}` disable healthcheck
491
-          - `{"CMD", args...}` exec arguments directly
492
-          - `{"CMD-SHELL", command}` run command with system's default shell
489
+          - `[]` inherit healthcheck from image or parent image
490
+          - `["NONE"]` disable healthcheck
491
+          - `["CMD", args...]` exec arguments directly
492
+          - `["CMD-SHELL", command]` run command with system's default shell
493 493
         type: "array"
494 494
         items:
495 495
           type: "string"
... ...
@@ -305,6 +305,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
305 305
 			}
306 306
 			return cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
307 307
 		}
308
+		return err
308 309
 	}
309 310
 
310 311
 	// Windows: show error message about modified file permissions if the
... ...
@@ -35,9 +35,14 @@ func NewLoginCommand(dockerCli *command.DockerCli) *cobra.Command {
35 35
 	}
36 36
 
37 37
 	flags := cmd.Flags()
38
+
38 39
 	flags.StringVarP(&opts.user, "username", "u", "", "Username")
39 40
 	flags.StringVarP(&opts.password, "password", "p", "", "Password")
40 41
 
42
+	// Deprecated in 1.11: Should be removed in docker 17.06
43
+	flags.StringVarP(&opts.email, "email", "e", "", "Email")
44
+	flags.MarkDeprecated("email", "will be removed in 17.06.")
45
+
41 46
 	return cmd
42 47
 }
43 48
 
... ...
@@ -46,7 +46,7 @@ func deployBundle(ctx context.Context, dockerCli *command.DockerCli, opts deploy
46 46
 		for _, networkName := range service.Networks {
47 47
 			nets = append(nets, swarm.NetworkAttachmentConfig{
48 48
 				Target:  namespace.Scope(networkName),
49
-				Aliases: []string{networkName},
49
+				Aliases: []string{internalName},
50 50
 			})
51 51
 		}
52 52
 
... ...
@@ -24,7 +24,7 @@ func newDaemonCommand() *cobra.Command {
24 24
 		RunE: func(cmd *cobra.Command, args []string) error {
25 25
 			return runDaemon()
26 26
 		},
27
-		Deprecated: "and will be removed in Docker 1.16. Please run `dockerd` directly.",
27
+		Deprecated: "and will be removed in Docker 17.12. Please run `dockerd` directly.",
28 28
 	}
29 29
 	cmd.SetHelpFunc(helpFunc)
30 30
 	return cmd
... ...
@@ -978,6 +978,7 @@ __docker_image_subcommand() {
978 978
         (build)
979 979
             _arguments $(__docker_arguments) \
980 980
                 $opts_help \
981
+                "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: " \
981 982
                 "($help)*--build-arg=[Build-time variables]:<varname>=<value>: " \
982 983
                 "($help)*--cache-from=[Images to consider as cache sources]: :__docker_complete_repositories_with_tags" \
983 984
                 "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" \
... ...
@@ -36,7 +36,7 @@ func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerA
36 36
 	}
37 37
 
38 38
 	cfg := stream.AttachConfig{
39
-		UseStdin:   c.UseStdin && container.Config.OpenStdin,
39
+		UseStdin:   c.UseStdin,
40 40
 		UseStdout:  c.UseStdout,
41 41
 		UseStderr:  c.UseStderr,
42 42
 		TTY:        container.Config.Tty,
... ...
@@ -79,7 +79,7 @@ func (daemon *Daemon) ContainerAttachRaw(prefixOrName string, stdin io.ReadClose
79 79
 		return err
80 80
 	}
81 81
 	cfg := stream.AttachConfig{
82
-		UseStdin:   stdin != nil && container.Config.OpenStdin,
82
+		UseStdin:   stdin != nil,
83 83
 		UseStdout:  stdout != nil,
84 84
 		UseStderr:  stderr != nil,
85 85
 		TTY:        container.Config.Tty,
... ...
@@ -147,6 +147,10 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *stream.Attach
147 147
 		cfg.Stdin = r
148 148
 	}
149 149
 
150
+	if !c.Config.OpenStdin {
151
+		cfg.Stdin = nil
152
+	}
153
+
150 154
 	waitChan := make(chan struct{})
151 155
 	if c.Config.StdinOnce && !c.Config.Tty {
152 156
 		defer func() {
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"path/filepath"
7 7
 	"strings"
8 8
 	"syscall"
9
-	"unsafe"
10 9
 
11 10
 	"github.com/Microsoft/hcsshim"
12 11
 	"github.com/Sirupsen/logrus"
... ...
@@ -245,7 +244,7 @@ func checkSystem() error {
245 245
 		return fmt.Errorf("Failed to load vmcompute.dll. Ensure that the Containers role is installed.")
246 246
 	}
247 247
 
248
-	return waitOOBEComplete()
248
+	return nil
249 249
 }
250 250
 
251 251
 // configureKernelSecuritySupport configures and validate security support for the kernel
... ...
@@ -617,35 +616,3 @@ func (daemon *Daemon) verifyVolumesInfo(container *container.Container) error {
617 617
 func (daemon *Daemon) setupSeccompProfile() error {
618 618
 	return nil
619 619
 }
620
-
621
-func waitOOBEComplete() error {
622
-	kernel32 := windows.NewLazySystemDLL("kernel32.dll")
623
-	registerWaitUntilOOBECompleted := kernel32.NewProc("RegisterWaitUntilOOBECompleted")
624
-	unregisterWaitUntilOOBECompleted := kernel32.NewProc("UnregisterWaitUntilOOBECompleted")
625
-
626
-	callbackChan := make(chan struct{})
627
-	callbackFunc := func(uintptr) uintptr {
628
-		close(callbackChan)
629
-		return 0
630
-	}
631
-	callbackFuncPtr := syscall.NewCallback(callbackFunc)
632
-
633
-	var callbackHandle syscall.Handle
634
-	ret, _, err := registerWaitUntilOOBECompleted.Call(callbackFuncPtr, 0, uintptr(unsafe.Pointer(&callbackHandle)))
635
-	if ret == 0 {
636
-		if err == errInvalidState {
637
-			return nil
638
-		}
639
-		return fmt.Errorf("failed to register OOBEComplete callback. Error: %v", err)
640
-	}
641
-
642
-	// Wait for the callback when OOBE is finished
643
-	<-callbackChan
644
-
645
-	ret, _, err = unregisterWaitUntilOOBECompleted.Call(uintptr(callbackHandle))
646
-	if ret == 0 {
647
-		return fmt.Errorf("failed to unregister OOBEComplete callback. Error: %v", err)
648
-	}
649
-
650
-	return nil
651
-}
652 620
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+
1
+---
2
+title: "container"
3
+description: "The container command description and usage"
4
+keywords: "container"
5
+---
6
+
7
+<!-- This file is maintained within the docker/docker Github
8
+     repository at https://github.com/docker/docker/. Make all
9
+     pull requests against that repo. If you see this file in
10
+     another repository, consider it read-only there, as it will
11
+     periodically be overwritten by the definitive file. Pull
12
+     requests which include edits to this file in other repositories
13
+     will be rejected.
14
+-->
15
+
16
+# container
17
+
18
+```markdown
19
+Usage:  docker container COMMAND
20
+
21
+Manage containers
22
+
23
+Options:
24
+      --help   Print usage
25
+
26
+Commands:
27
+  attach      Attach to a running container
28
+  commit      Create a new image from a container's changes
29
+  cp          Copy files/folders between a container and the local filesystem
30
+  create      Create a new container
31
+  diff        Inspect changes to files or directories on a container's filesystem
32
+  exec        Run a command in a running container
33
+  export      Export a container's filesystem as a tar archive
34
+  inspect     Display detailed information on one or more containers
35
+  kill        Kill one or more running containers
36
+  logs        Fetch the logs of a container
37
+  ls          List containers
38
+  pause       Pause all processes within one or more containers
39
+  port        List port mappings or a specific mapping for the container
40
+  prune       Remove all stopped containers
41
+  rename      Rename a container
42
+  restart     Restart one or more containers
43
+  rm          Remove one or more containers
44
+  run         Run a command in a new container
45
+  start       Start one or more stopped containers
46
+  stats       Display a live stream of container(s) resource usage statistics
47
+  stop        Stop one or more running containers
48
+  top         Display the running processes of a container
49
+  unpause     Unpause all processes within one or more containers
50
+  update      Update configuration of one or more containers
51
+  wait        Block until one or more containers stop, then print their exit codes
52
+
53
+Run 'docker container COMMAND --help' for more information on a command.
54
+
55
+```
56
+
57
+## Description
58
+
59
+Manage containers.
60
+
0 61
new file mode 100644
... ...
@@ -0,0 +1,47 @@
0
+
1
+---
2
+title: "image"
3
+description: "The image command description and usage"
4
+keywords: "image"
5
+---
6
+
7
+<!-- This file is maintained within the docker/docker Github
8
+     repository at https://github.com/docker/docker/. Make all
9
+     pull requests against that repo. If you see this file in
10
+     another repository, consider it read-only there, as it will
11
+     periodically be overwritten by the definitive file. Pull
12
+     requests which include edits to this file in other repositories
13
+     will be rejected.
14
+-->
15
+
16
+# image
17
+
18
+```markdown
19
+Usage:  docker image COMMAND
20
+
21
+Manage images
22
+
23
+Options:
24
+      --help   Print usage
25
+
26
+Commands:
27
+  build       Build an image from a Dockerfile
28
+  history     Show the history of an image
29
+  import      Import the contents from a tarball to create a filesystem image
30
+  inspect     Display detailed information on one or more images
31
+  load        Load an image from a tar archive or STDIN
32
+  ls          List images
33
+  prune       Remove unused images
34
+  pull        Pull an image or a repository from a registry
35
+  push        Push an image or a repository to a registry
36
+  rm          Remove one or more images
37
+  save        Save one or more images to a tar archive (streamed to STDOUT by default)
38
+  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
39
+
40
+Run 'docker image COMMAND --help' for more information on a command.
41
+
42
+```
43
+
44
+## Description
45
+
46
+Manage images.
... ...
@@ -26,7 +26,7 @@ Options:
26 26
                        The tarball may be compressed with gzip, bzip, or xz
27 27
   -q, --quiet          Suppress the load output but still outputs the imported images
28 28
 ```
29
-## Descriptino
29
+## Description
30 30
 
31 31
 `docker load` loads a tarred repository from a file or the standard input stream.
32 32
 It restores both images and tags.
33 33
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+---
1
+title: "network"
2
+description: "The network command description and usage"
3
+keywords: "network"
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
+# network
16
+
17
+```markdown
18
+Usage:  docker network COMMAND
19
+
20
+Manage networks
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  connect     Connect a container to a network
27
+  create      Create a network
28
+  disconnect  Disconnect a container from a network
29
+  inspect     Display detailed information on one or more networks
30
+  ls          List networks
31
+  prune       Remove all unused networks
32
+  rm          Remove one or more networks
33
+
34
+Run 'docker network COMMAND --help' for more information on a command.
35
+```
36
+
37
+## Description
38
+
39
+Manage networks. You can use subcommand to create, list, inspect, remove,
40
+connect and disconnect networks.
41
+
42
+## Related commands
43
+
44
+* [network create](network_create.md)
45
+* [network inspect](network_inspect.md)
46
+* [network list](network_list.md)
47
+* [network rm](network_rm.md)
48
+* [network prune](network_prune.md)
0 49
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+
1
+---
2
+title: "node"
3
+description: "The node command description and usage"
4
+keywords: "node"
5
+---
6
+
7
+<!-- This file is maintained within the docker/docker Github
8
+     repository at https://github.com/docker/docker/. Make all
9
+     pull requests against that repo. If you see this file in
10
+     another repository, consider it read-only there, as it will
11
+     periodically be overwritten by the definitive file. Pull
12
+     requests which include edits to this file in other repositories
13
+     will be rejected.
14
+-->
15
+
16
+# node
17
+
18
+```markdown
19
+Usage:  docker node COMMAND
20
+
21
+Manage Swarm nodes
22
+
23
+Options:
24
+      --help   Print usage
25
+
26
+Commands:
27
+  demote      Demote one or more nodes from manager in the swarm
28
+  inspect     Display detailed information on one or more nodes
29
+  ls          List nodes in the swarm
30
+  promote     Promote one or more nodes to manager in the swarm
31
+  ps          List tasks running on one or more nodes, defaults to current node
32
+  rm          Remove one or more nodes from the swarm
33
+  update      Update a node
34
+
35
+Run 'docker node COMMAND --help' for more information on a command.
36
+```
37
+
38
+## Description
39
+
40
+Manage nodes.
41
+
0 42
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+---
1
+title: "plugin"
2
+description: "The plugin command description and usage"
3
+keywords: "plugin"
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
+# plugin
16
+
17
+```markdown
18
+Usage:  docker plugin COMMAND
19
+
20
+Manage plugins
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  create      Create a plugin from a rootfs and configuration. Plugin data directory must contain config.json and rootfs directory.
27
+  disable     Disable a plugin
28
+  enable      Enable a plugin
29
+  inspect     Display detailed information on one or more plugins
30
+  install     Install a plugin
31
+  ls          List plugins
32
+  push        Push a plugin to a registry
33
+  rm          Remove one or more plugins
34
+  set         Change settings for a plugin
35
+  upgrade     Upgrade an existing plugin
36
+
37
+Run 'docker plugin COMMAND --help' for more information on a command.
38
+
39
+```
40
+
41
+## Description
42
+
43
+Manage plugins.
0 44
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+---
1
+title: "secret"
2
+description: "The secret command description and usage"
3
+keywords: "secret"
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
+# secret
16
+
17
+```markdown
18
+Usage:  docker secret COMMAND
19
+
20
+Manage Docker secrets
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  create      Create a secret from a file or STDIN as content
27
+  inspect     Display detailed information on one or more secrets
28
+  ls          List secrets
29
+  rm          Remove one or more secrets
30
+
31
+Run 'docker secret COMMAND --help' for more information on a command.
32
+
33
+```
34
+
35
+## Description
36
+
37
+Manage secrets.
38
+
39
+## Related commands
40
+
41
+* [secret create](secret_create.md)
42
+* [secret inspect](secret_inspect.md)
43
+* [secret list](secret_list.md)
44
+* [secret rm](secret_rm.md)
0 45
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+---
1
+title: "service"
2
+description: "The service command description and usage"
3
+keywords: "service"
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
+# service
16
+
17
+```markdown
18
+Usage:  docker service COMMAND
19
+
20
+Manage services
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  create      Create a new service
27
+  inspect     Display detailed information on one or more services
28
+  logs        Fetch the logs of a service
29
+  ls          List services
30
+  ps          List the tasks of a service
31
+  rm          Remove one or more services
32
+  scale       Scale one or multiple replicated services
33
+  update      Update a service
34
+
35
+Run 'docker service COMMAND --help' for more information on a command.
36
+```
37
+
38
+## Description
39
+
40
+Manage services.
41
+
0 42
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+---
1
+title: "stack"
2
+description: "The stack command description and usage"
3
+keywords: "stack"
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
+# stack
16
+
17
+```markdown
18
+Usage:  docker stack COMMAND
19
+
20
+Manage Docker stacks
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  deploy      Deploy a new stack or update an existing stack
27
+  ls          List stacks
28
+  ps          List the tasks in the stack
29
+  rm          Remove the stack
30
+  services    List the services in the stack
31
+
32
+Run 'docker stack COMMAND --help' for more information on a command.
33
+```
34
+
35
+## Description
36
+
37
+Manage stacks.
38
+
... ...
@@ -27,7 +27,7 @@ Options:
27 27
       --help   Print usage
28 28
 ```
29 29
 
30
-## Descriptino
30
+## Description
31 31
 
32 32
 Lists the stacks.
33 33
 
34 34
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+---
1
+title: "swarm"
2
+description: "The swarm command description and usage"
3
+keywords: "swarm"
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
+# swarm
16
+
17
+```markdown
18
+Usage:  docker swarm COMMAND
19
+
20
+Manage Swarm
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  init        Initialize a swarm
27
+  join        Join a swarm as a node and/or manager
28
+  join-token  Manage join tokens
29
+  leave       Leave the swarm
30
+  unlock      Unlock swarm
31
+  unlock-key  Manage the unlock key
32
+  update      Update the swarm
33
+
34
+Run 'docker swarm COMMAND --help' for more information on a command.
35
+```
36
+
37
+## Description
38
+
39
+Manage the swarm.
0 40
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+---
1
+title: "system"
2
+description: "The system command description and usage"
3
+keywords: "system"
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
+# system
16
+
17
+```markdown
18
+Usage:  docker system COMMAND
19
+
20
+Manage Docker
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  df          Show docker disk usage
27
+  events      Get real time events from the server
28
+  info        Display system-wide information
29
+  prune       Remove unused data
30
+
31
+Run 'docker system COMMAND --help' for more information on a command.
32
+```
33
+
34
+## Description
35
+
36
+Manage docker.
0 37
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+---
1
+title: "volume"
2
+description: "The volume command description and usage"
3
+keywords: "volume"
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
+# volume
16
+
17
+```markdown
18
+Usage:  docker volume COMMAND
19
+
20
+Manage volumes
21
+
22
+Options:
23
+      --help   Print usage
24
+
25
+Commands:
26
+  create      Create a volume
27
+  inspect     Display detailed information on one or more volumes
28
+  ls          List volumes
29
+  prune       Remove all unused volumes
30
+  rm          Remove one or more volumes
31
+
32
+Run 'docker volume COMMAND --help' for more information on a command.
33
+```
34
+
35
+## Description
36
+
37
+Manage volumes. You can use subcommand to create, list, inspect, remove
38
+volumes.
39
+
40
+## Related commands
41
+
42
+* [volume create](volume_create.md)
43
+* [volume inspect](volume_inspect.md)
44
+* [volume list](volume_list.md)
45
+* [volume rm](volume_rm.md)
46
+* [volume prune](volume_prune.md)
47
+* [Understand Data Volumes](https://docs.docker.com/engine/tutorials/dockervolumes/)
0 48
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+FROM scratch
1
+COPY docs /docs
2
+# CMD cannot be nil so we set it to empty string
3
+CMD  [""]
0 4
new file mode 100644
... ...
@@ -0,0 +1,86 @@
0
+package main
1
+
2
+import (
3
+	"fmt"
4
+	"io/ioutil"
5
+	"log"
6
+	"os"
7
+	"path/filepath"
8
+	"strings"
9
+
10
+	"github.com/docker/docker/cli/command"
11
+	"github.com/docker/docker/cli/command/commands"
12
+	"github.com/docker/docker/pkg/term"
13
+	"github.com/spf13/cobra"
14
+	"github.com/spf13/pflag"
15
+)
16
+
17
+const descriptionSourcePath = "docs/reference/commandline/"
18
+
19
+func generateCliYaml(opts *options) error {
20
+	stdin, stdout, stderr := term.StdStreams()
21
+	dockerCli := command.NewDockerCli(stdin, stdout, stderr)
22
+	cmd := &cobra.Command{Use: "docker"}
23
+	commands.AddCommands(cmd, dockerCli)
24
+	source := filepath.Join(opts.source, descriptionSourcePath)
25
+	if err := loadLongDescription(cmd, source); err != nil {
26
+		return err
27
+	}
28
+
29
+	cmd.DisableAutoGenTag = true
30
+	return GenYamlTree(cmd, opts.target)
31
+}
32
+
33
+func loadLongDescription(cmd *cobra.Command, path ...string) error {
34
+	for _, cmd := range cmd.Commands() {
35
+		if cmd.Name() == "" {
36
+			continue
37
+		}
38
+		fullpath := filepath.Join(path[0], strings.Join(append(path[1:], cmd.Name()), "_")+".md")
39
+
40
+		if cmd.HasSubCommands() {
41
+			loadLongDescription(cmd, path[0], cmd.Name())
42
+		}
43
+
44
+		if _, err := os.Stat(fullpath); err != nil {
45
+			log.Printf("WARN: %s does not exist, skipping\n", fullpath)
46
+			continue
47
+		}
48
+
49
+		content, err := ioutil.ReadFile(fullpath)
50
+		if err != nil {
51
+			return err
52
+		}
53
+		description, examples := parseMDContent(string(content))
54
+		cmd.Long = description
55
+		cmd.Example = examples
56
+	}
57
+	return nil
58
+}
59
+
60
+type options struct {
61
+	source string
62
+	target string
63
+}
64
+
65
+func parseArgs() (*options, error) {
66
+	opts := &options{}
67
+	cwd, _ := os.Getwd()
68
+	flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
69
+	flags.StringVar(&opts.source, "root", cwd, "Path to project root")
70
+	flags.StringVar(&opts.target, "target", "/tmp", "Target path for generated yaml files")
71
+	err := flags.Parse(os.Args[1:])
72
+	return opts, err
73
+}
74
+
75
+func main() {
76
+	opts, err := parseArgs()
77
+	if err != nil {
78
+		fmt.Fprintln(os.Stderr, err.Error())
79
+	}
80
+	fmt.Printf("Project root: %s\n", opts.source)
81
+	fmt.Printf("Generating yaml files into %s\n", opts.target)
82
+	if err := generateCliYaml(opts); err != nil {
83
+		fmt.Fprintf(os.Stderr, "Failed to generate yaml files: %s\n", err.Error())
84
+	}
85
+}
0 86
new file mode 100644
... ...
@@ -0,0 +1,212 @@
0
+package main
1
+
2
+import (
3
+	"fmt"
4
+	"io"
5
+	"os"
6
+	"path/filepath"
7
+	"sort"
8
+	"strings"
9
+
10
+	"github.com/spf13/cobra"
11
+	"github.com/spf13/pflag"
12
+	"gopkg.in/yaml.v2"
13
+)
14
+
15
+type cmdOption struct {
16
+	Option       string
17
+	Shorthand    string `yaml:",omitempty"`
18
+	DefaultValue string `yaml:"default_value,omitempty"`
19
+	Description  string `yaml:",omitempty"`
20
+}
21
+
22
+type cmdDoc struct {
23
+	Name             string      `yaml:"command"`
24
+	SeeAlso          []string    `yaml:"parent,omitempty"`
25
+	Version          string      `yaml:"engine_version,omitempty"`
26
+	Aliases          string      `yaml:",omitempty"`
27
+	Short            string      `yaml:",omitempty"`
28
+	Long             string      `yaml:",omitempty"`
29
+	Usage            string      `yaml:",omitempty"`
30
+	Pname            string      `yaml:",omitempty"`
31
+	Plink            string      `yaml:",omitempty"`
32
+	Cname            []string    `yaml:",omitempty"`
33
+	Clink            []string    `yaml:",omitempty"`
34
+	Options          []cmdOption `yaml:",omitempty"`
35
+	InheritedOptions []cmdOption `yaml:"inherited_options,omitempty"`
36
+	Example          string      `yaml:"examples,omitempty"`
37
+}
38
+
39
+// GenYamlTree creates yaml structured ref files
40
+func GenYamlTree(cmd *cobra.Command, dir string) error {
41
+	identity := func(s string) string { return s }
42
+	emptyStr := func(s string) string { return "" }
43
+	return GenYamlTreeCustom(cmd, dir, emptyStr, identity)
44
+}
45
+
46
+// GenYamlTreeCustom creates yaml structured ref files
47
+func GenYamlTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
48
+	for _, c := range cmd.Commands() {
49
+		if !c.IsAvailableCommand() || c.IsHelpCommand() {
50
+			continue
51
+		}
52
+		if err := GenYamlTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
53
+			return err
54
+		}
55
+	}
56
+
57
+	basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".yaml"
58
+	filename := filepath.Join(dir, basename)
59
+	f, err := os.Create(filename)
60
+	if err != nil {
61
+		return err
62
+	}
63
+	defer f.Close()
64
+
65
+	if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
66
+		return err
67
+	}
68
+	if err := GenYamlCustom(cmd, f, linkHandler); err != nil {
69
+		return err
70
+	}
71
+	return nil
72
+}
73
+
74
+// GenYamlCustom creates custom yaml output
75
+func GenYamlCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
76
+	cliDoc := cmdDoc{}
77
+	cliDoc.Name = cmd.CommandPath()
78
+
79
+	// Check experimental: ok := cmd.Tags["experimental"]
80
+
81
+	cliDoc.Aliases = strings.Join(cmd.Aliases, ", ")
82
+	cliDoc.Short = cmd.Short
83
+	cliDoc.Long = cmd.Long
84
+	if len(cliDoc.Long) == 0 {
85
+		cliDoc.Long = cliDoc.Short
86
+	}
87
+
88
+	if cmd.Runnable() {
89
+		cliDoc.Usage = cmd.UseLine()
90
+	}
91
+
92
+	if len(cmd.Example) > 0 {
93
+		cliDoc.Example = cmd.Example
94
+	}
95
+
96
+	flags := cmd.NonInheritedFlags()
97
+	if flags.HasFlags() {
98
+		cliDoc.Options = genFlagResult(flags)
99
+	}
100
+	flags = cmd.InheritedFlags()
101
+	if flags.HasFlags() {
102
+		cliDoc.InheritedOptions = genFlagResult(flags)
103
+	}
104
+
105
+	if hasSeeAlso(cmd) {
106
+		if cmd.HasParent() {
107
+			parent := cmd.Parent()
108
+			cliDoc.Pname = parent.CommandPath()
109
+			link := cliDoc.Pname + ".yaml"
110
+			cliDoc.Plink = strings.Replace(link, " ", "_", -1)
111
+			cmd.VisitParents(func(c *cobra.Command) {
112
+				if c.DisableAutoGenTag {
113
+					cmd.DisableAutoGenTag = c.DisableAutoGenTag
114
+				}
115
+			})
116
+		}
117
+
118
+		children := cmd.Commands()
119
+		sort.Sort(byName(children))
120
+
121
+		for _, child := range children {
122
+			if !child.IsAvailableCommand() || child.IsHelpCommand() {
123
+				continue
124
+			}
125
+			currentChild := cliDoc.Name + " " + child.Name()
126
+			cliDoc.Cname = append(cliDoc.Cname, cliDoc.Name+" "+child.Name())
127
+			link := currentChild + ".yaml"
128
+			cliDoc.Clink = append(cliDoc.Clink, strings.Replace(link, " ", "_", -1))
129
+		}
130
+	}
131
+
132
+	final, err := yaml.Marshal(&cliDoc)
133
+	if err != nil {
134
+		fmt.Println(err)
135
+		os.Exit(1)
136
+	}
137
+	if _, err := fmt.Fprintln(w, string(final)); err != nil {
138
+		return err
139
+	}
140
+	return nil
141
+}
142
+
143
+func genFlagResult(flags *pflag.FlagSet) []cmdOption {
144
+	var result []cmdOption
145
+
146
+	flags.VisitAll(func(flag *pflag.Flag) {
147
+		// Todo, when we mark a shorthand is deprecated, but specify an empty message.
148
+		// The flag.ShorthandDeprecated is empty as the shorthand is deprecated.
149
+		// Using len(flag.ShorthandDeprecated) > 0 can't handle this, others are ok.
150
+		if !(len(flag.ShorthandDeprecated) > 0) && len(flag.Shorthand) > 0 {
151
+			opt := cmdOption{
152
+				Option:       flag.Name,
153
+				Shorthand:    flag.Shorthand,
154
+				DefaultValue: flag.DefValue,
155
+				Description:  forceMultiLine(flag.Usage),
156
+			}
157
+			result = append(result, opt)
158
+		} else {
159
+			opt := cmdOption{
160
+				Option:       flag.Name,
161
+				DefaultValue: forceMultiLine(flag.DefValue),
162
+				Description:  forceMultiLine(flag.Usage),
163
+			}
164
+			result = append(result, opt)
165
+		}
166
+	})
167
+
168
+	return result
169
+}
170
+
171
+// Temporary workaround for yaml lib generating incorrect yaml with long strings
172
+// that do not contain \n.
173
+func forceMultiLine(s string) string {
174
+	if len(s) > 60 && !strings.Contains(s, "\n") {
175
+		s = s + "\n"
176
+	}
177
+	return s
178
+}
179
+
180
+// Small duplication for cobra utils
181
+func hasSeeAlso(cmd *cobra.Command) bool {
182
+	if cmd.HasParent() {
183
+		return true
184
+	}
185
+	for _, c := range cmd.Commands() {
186
+		if !c.IsAvailableCommand() || c.IsHelpCommand() {
187
+			continue
188
+		}
189
+		return true
190
+	}
191
+	return false
192
+}
193
+
194
+func parseMDContent(mdString string) (description string, examples string) {
195
+	parsedContent := strings.Split(mdString, "\n## ")
196
+	for _, s := range parsedContent {
197
+		if strings.Index(s, "Description") == 0 {
198
+			description = strings.Trim(s, "Description\n")
199
+		}
200
+		if strings.Index(s, "Examples") == 0 {
201
+			examples = strings.Trim(s, "Examples\n")
202
+		}
203
+	}
204
+	return
205
+}
206
+
207
+type byName []*cobra.Command
208
+
209
+func (s byName) Len() int           { return len(s) }
210
+func (s byName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
211
+func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
0 212
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+#!/usr/bin/env bash
1
+set -e
2
+
3
+[ -z "$KEEPDEST" ] && \
4
+	rm -rf "$DEST"
5
+
6
+(
7
+	source "${MAKEDIR}/.binary-setup"
8
+	export BINARY_SHORT_NAME="yaml-docs-generator"
9
+	export GO_PACKAGE='github.com/docker/docker/docs/yaml'
10
+	source "${MAKEDIR}/.binary"
11
+)
0 12
new file mode 100755
... ...
@@ -0,0 +1,19 @@
0
+#!/bin/bash
1
+
2
+if [ -n "${BUILD_DOCS}" ]; then
3
+	set -e
4
+	DOCS_IMAGE=${DOCS_IMAGE:-${IMAGE_NAME}-docs}
5
+	docker run \
6
+		--entrypoint '' \
7
+		--privileged \
8
+		-e DOCKER_GITCOMMIT=$(git rev-parse --short HEAD) \
9
+		-v $(pwd)/docs/yaml/docs:/docs \
10
+		"${IMAGE_NAME}" \
11
+		sh -c 'hack/make.sh yaml-docs-generator && bundles/latest/yaml-docs-generator/yaml-docs-generator --target /docs'
12
+
13
+	(
14
+		cd docs/yaml
15
+		docker build -t ${DOCS_IMAGE} .
16
+		docker push ${DOCS_IMAGE}
17
+	)
18
+fi
... ...
@@ -28,3 +28,17 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLoginToPrivateRegistry(c *check.C)
28 28
 	// now it's fine
29 29
 	dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
30 30
 }
31
+
32
+func (s *DockerRegistryAuthHtpasswdSuite) TestLoginToPrivateRegistryDeprecatedEmailFlag(c *check.C) {
33
+	// Test to make sure login still works with the deprecated -e and --email flags
34
+	// wrong credentials
35
+	out, _, err := dockerCmdWithError("login", "-u", s.reg.Username(), "-p", "WRONGPASSWORD", "-e", s.reg.Email(), privateRegistryURL)
36
+	c.Assert(err, checker.NotNil, check.Commentf(out))
37
+	c.Assert(out, checker.Contains, "401 Unauthorized")
38
+
39
+	// now it's fine
40
+	// -e flag
41
+	dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), "-e", s.reg.Email(), privateRegistryURL)
42
+	// --email flag
43
+	dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), "--email", s.reg.Email(), privateRegistryURL)
44
+}
... ...
@@ -107,7 +107,7 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *check.C) {
107 107
 	s.d.Cmd("build", "--file", dockerfileName, ".")
108 108
 	regexpCheckUA(c, buildUA)
109 109
 
110
-	s.d.Cmd("login", "-u", "richard", "-p", "testtest", loginReg.URL())
110
+	s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", loginReg.URL())
111 111
 	regexpCheckUA(c, loginUA)
112 112
 
113 113
 	s.d.Cmd("pull", pullRepoName)
... ...
@@ -203,6 +203,11 @@ func (r *V2) Password() string {
203 203
 	return r.password
204 204
 }
205 205
 
206
+// Email returns the configured email of the server
207
+func (r *V2) Email() string {
208
+	return r.email
209
+}
210
+
206 211
 // Path returns the path where the registry write data
207 212
 func (r *V2) Path() string {
208 213
 	return filepath.Join(r.dir, "docker", "registry", "v2")