mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	cli: new daemon command and new cli package
This patch creates a new cli package that allows to combine both client and daemon commands (there is only one daemon command: docker daemon). The `-d` and `--daemon` top-level flags are deprecated and a special message is added to prompt the user to use `docker daemon`. Providing top-level daemon-specific flags for client commands result in an error message prompting the user to use `docker daemon`. This patch does not break any old but correct usages. This also makes `-d` and `--daemon` flags, as well as the `daemon` command illegal in client-only binaries. Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
		
							parent
							
								
									490e78a642
								
							
						
					
					
						commit
						96ce3a194a
					
				
					 67 changed files with 913 additions and 614 deletions
				
			
		| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/signal"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -16,9 +17,10 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker attach [OPTIONS] CONTAINER
 | 
			
		||||
func (cli *DockerCli) CmdAttach(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("attach", []string{"CONTAINER"}, "Attach to a running container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("attach", []string{"CONTAINER"}, "Attach to a running container", true)
 | 
			
		||||
	noStdin := cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN")
 | 
			
		||||
	proxy := cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process")
 | 
			
		||||
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +77,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if status != 0 {
 | 
			
		||||
		return StatusError{StatusCode: status}
 | 
			
		||||
		return Cli.StatusError{StatusCode: status}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/graph/tags"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,7 @@ const (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker build [OPTIONS] PATH | URL | -
 | 
			
		||||
func (cli *DockerCli) CmdBuild(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("build", []string{"PATH | URL | -"}, "Build a new image from the source code at PATH", true)
 | 
			
		||||
	cmd := Cli.Subcmd("build", []string{"PATH | URL | -"}, "Build a new image from the source code at PATH", true)
 | 
			
		||||
	tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) for the image")
 | 
			
		||||
	suppressOutput := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the verbose output generated by the containers")
 | 
			
		||||
	noCache := cmd.Bool([]string{"#no-cache", "-no-cache"}, false, "Do not use cache when building the image")
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +65,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 | 
			
		|||
	flCgroupParent := cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
 | 
			
		||||
 | 
			
		||||
	ulimits := make(map[string]*ulimit.Ulimit)
 | 
			
		||||
	flUlimits := opts.NewUlimitOpt(ulimits)
 | 
			
		||||
	flUlimits := opts.NewUlimitOpt(&ulimits)
 | 
			
		||||
	cmd.Var(flUlimits, []string{"-ulimit"}, "Ulimit options")
 | 
			
		||||
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -325,7 +326,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 | 
			
		|||
		if jerr.Code == 0 {
 | 
			
		||||
			jerr.Code = 1
 | 
			
		||||
		}
 | 
			
		||||
		return StatusError{Status: jerr.Message, StatusCode: jerr.Code}
 | 
			
		||||
		return Cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,25 +2,28 @@ package client
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	"github.com/docker/docker/pkg/sockets"
 | 
			
		||||
	"github.com/docker/docker/pkg/term"
 | 
			
		||||
	"github.com/docker/docker/pkg/tlsconfig"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DockerCli represents the docker command line client.
 | 
			
		||||
// Instances of the client can be returned from NewDockerCli.
 | 
			
		||||
type DockerCli struct {
 | 
			
		||||
	// initializing closure
 | 
			
		||||
	init func() error
 | 
			
		||||
 | 
			
		||||
	// proto holds the client protocol i.e. unix.
 | 
			
		||||
	proto string
 | 
			
		||||
	// addr holds the client address.
 | 
			
		||||
| 
						 | 
				
			
			@ -55,116 +58,11 @@ type DockerCli struct {
 | 
			
		|||
	transport *http.Transport
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var funcMap = template.FuncMap{
 | 
			
		||||
	"json": func(v interface{}) string {
 | 
			
		||||
		a, _ := json.Marshal(v)
 | 
			
		||||
		return string(a)
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cli *DockerCli) Out() io.Writer {
 | 
			
		||||
	return cli.out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cli *DockerCli) Err() io.Writer {
 | 
			
		||||
	return cli.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
 | 
			
		||||
	camelArgs := make([]string, len(args))
 | 
			
		||||
	for i, s := range args {
 | 
			
		||||
		if len(s) == 0 {
 | 
			
		||||
			return nil, false
 | 
			
		||||
		}
 | 
			
		||||
		camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
 | 
			
		||||
func (cli *DockerCli) Initialize() error {
 | 
			
		||||
	if cli.init == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	methodName := "Cmd" + strings.Join(camelArgs, "")
 | 
			
		||||
	method := reflect.ValueOf(cli).MethodByName(methodName)
 | 
			
		||||
	if !method.IsValid() {
 | 
			
		||||
		return nil, false
 | 
			
		||||
	}
 | 
			
		||||
	return method.Interface().(func(...string) error), true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cmd executes the specified command.
 | 
			
		||||
func (cli *DockerCli) Cmd(args ...string) error {
 | 
			
		||||
	if len(args) > 1 {
 | 
			
		||||
		method, exists := cli.getMethod(args[:2]...)
 | 
			
		||||
		if exists {
 | 
			
		||||
			return method(args[2:]...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		method, exists := cli.getMethod(args[0])
 | 
			
		||||
		if !exists {
 | 
			
		||||
			return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'.", args[0])
 | 
			
		||||
		}
 | 
			
		||||
		return method(args[1:]...)
 | 
			
		||||
	}
 | 
			
		||||
	return cli.CmdHelp()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subcmd is a subcommand of the main "docker" command.
 | 
			
		||||
// A subcommand represents an action that can be performed
 | 
			
		||||
// from the Docker command line client.
 | 
			
		||||
//
 | 
			
		||||
// Multiple subcommand synopses may be provided with one 'Usage' line being
 | 
			
		||||
// printed for each in the following way:
 | 
			
		||||
//
 | 
			
		||||
//	Usage:	docker <subcmd-name> [OPTIONS] <synopsis 0>
 | 
			
		||||
// 		docker <subcmd-name> [OPTIONS] <synopsis 1>
 | 
			
		||||
// 		...
 | 
			
		||||
//
 | 
			
		||||
// If no undeprecated flags are added to the returned FlagSet, "[OPTIONS]" will
 | 
			
		||||
// not be included on the usage synopsis lines. If no synopses are given, only
 | 
			
		||||
// one usage synopsis line will be printed with nothing following the
 | 
			
		||||
// "[OPTIONS]" section
 | 
			
		||||
//
 | 
			
		||||
// To see all available subcommands, run "docker --help".
 | 
			
		||||
func (cli *DockerCli) Subcmd(name string, synopses []string, description string, exitOnError bool) *flag.FlagSet {
 | 
			
		||||
	var errorHandling flag.ErrorHandling
 | 
			
		||||
	if exitOnError {
 | 
			
		||||
		errorHandling = flag.ExitOnError
 | 
			
		||||
	} else {
 | 
			
		||||
		errorHandling = flag.ContinueOnError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags := flag.NewFlagSet(name, errorHandling)
 | 
			
		||||
 | 
			
		||||
	flags.Usage = func() {
 | 
			
		||||
		flags.ShortUsage()
 | 
			
		||||
		flags.PrintDefaults()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags.ShortUsage = func() {
 | 
			
		||||
		options := ""
 | 
			
		||||
		if flags.FlagCountUndeprecated() > 0 {
 | 
			
		||||
			options = " [OPTIONS]"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(synopses) == 0 {
 | 
			
		||||
			synopses = []string{""}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Allow for multiple command usage synopses.
 | 
			
		||||
		for i, synopsis := range synopses {
 | 
			
		||||
			lead := "\t"
 | 
			
		||||
			if i == 0 {
 | 
			
		||||
				// First line needs the word 'Usage'.
 | 
			
		||||
				lead = "Usage:\t"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if synopsis != "" {
 | 
			
		||||
				synopsis = " " + synopsis
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintf(flags.Out(), "\n%sdocker %s%s%s", lead, name, options, synopsis)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(flags.Out(), "\n\n%s\n", description)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return flags
 | 
			
		||||
	return cli.init()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckTtyInput checks if we are trying to attach to a container tty
 | 
			
		||||
| 
						 | 
				
			
			@ -187,64 +85,78 @@ func (cli *DockerCli) PsFormat() string {
 | 
			
		|||
// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
 | 
			
		||||
// is set the client scheme will be set to https.
 | 
			
		||||
// The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035).
 | 
			
		||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, addr string, tlsConfig *tls.Config) *DockerCli {
 | 
			
		||||
	var (
 | 
			
		||||
		inFd          uintptr
 | 
			
		||||
		outFd         uintptr
 | 
			
		||||
		isTerminalIn  = false
 | 
			
		||||
		isTerminalOut = false
 | 
			
		||||
		scheme        = "http"
 | 
			
		||||
		basePath      = ""
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if tlsConfig != nil {
 | 
			
		||||
		scheme = "https"
 | 
			
		||||
	}
 | 
			
		||||
	if in != nil {
 | 
			
		||||
		inFd, isTerminalIn = term.GetFdInfo(in)
 | 
			
		||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientFlags) *DockerCli {
 | 
			
		||||
	cli := &DockerCli{
 | 
			
		||||
		in:      in,
 | 
			
		||||
		out:     out,
 | 
			
		||||
		err:     err,
 | 
			
		||||
		keyFile: clientFlags.Common.TrustKey,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if out != nil {
 | 
			
		||||
		outFd, isTerminalOut = term.GetFdInfo(out)
 | 
			
		||||
	cli.init = func() error {
 | 
			
		||||
		clientFlags.PostParse()
 | 
			
		||||
 | 
			
		||||
		hosts := clientFlags.Common.Hosts
 | 
			
		||||
 | 
			
		||||
		switch len(hosts) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			defaultHost := os.Getenv("DOCKER_HOST")
 | 
			
		||||
			if defaultHost == "" {
 | 
			
		||||
				defaultHost = opts.DefaultHost
 | 
			
		||||
			}
 | 
			
		||||
			defaultHost, err := opts.ValidateHost(defaultHost)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			hosts = []string{defaultHost}
 | 
			
		||||
		case 1:
 | 
			
		||||
			// only accept one host to talk to
 | 
			
		||||
		default:
 | 
			
		||||
			return errors.New("Please specify only one -H")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protoAddrParts := strings.SplitN(hosts[0], "://", 2)
 | 
			
		||||
		cli.proto, cli.addr = protoAddrParts[0], protoAddrParts[1]
 | 
			
		||||
 | 
			
		||||
		if cli.proto == "tcp" {
 | 
			
		||||
			// error is checked in pkg/parsers already
 | 
			
		||||
			parsed, _ := url.Parse("tcp://" + cli.addr)
 | 
			
		||||
			cli.addr = parsed.Host
 | 
			
		||||
			cli.basePath = parsed.Path
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if clientFlags.Common.TLSOptions != nil {
 | 
			
		||||
			cli.scheme = "https"
 | 
			
		||||
			var e error
 | 
			
		||||
			cli.tlsConfig, e = tlsconfig.Client(*clientFlags.Common.TLSOptions)
 | 
			
		||||
			if e != nil {
 | 
			
		||||
				return e
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			cli.scheme = "http"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if cli.in != nil {
 | 
			
		||||
			cli.inFd, cli.isTerminalIn = term.GetFdInfo(cli.in)
 | 
			
		||||
		}
 | 
			
		||||
		if cli.out != nil {
 | 
			
		||||
			cli.outFd, cli.isTerminalOut = term.GetFdInfo(cli.out)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// The transport is created here for reuse during the client session.
 | 
			
		||||
		cli.transport = &http.Transport{
 | 
			
		||||
			TLSClientConfig: cli.tlsConfig,
 | 
			
		||||
		}
 | 
			
		||||
		sockets.ConfigureTCPTransport(cli.transport, cli.proto, cli.addr)
 | 
			
		||||
 | 
			
		||||
		configFile, e := cliconfig.Load(cliconfig.ConfigDir())
 | 
			
		||||
		if e != nil {
 | 
			
		||||
			fmt.Fprintf(cli.err, "WARNING: Error loading config file:%v\n", e)
 | 
			
		||||
		}
 | 
			
		||||
		cli.configFile = configFile
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		err = out
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// The transport is created here for reuse during the client session.
 | 
			
		||||
	tr := &http.Transport{
 | 
			
		||||
		TLSClientConfig: tlsConfig,
 | 
			
		||||
	}
 | 
			
		||||
	sockets.ConfigureTCPTransport(tr, proto, addr)
 | 
			
		||||
 | 
			
		||||
	configFile, e := cliconfig.Load(cliconfig.ConfigDir())
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if proto == "tcp" {
 | 
			
		||||
		// error is checked in pkg/parsers already
 | 
			
		||||
		parsed, _ := url.Parse("tcp://" + addr)
 | 
			
		||||
		addr = parsed.Host
 | 
			
		||||
		basePath = parsed.Path
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &DockerCli{
 | 
			
		||||
		proto:         proto,
 | 
			
		||||
		addr:          addr,
 | 
			
		||||
		basePath:      basePath,
 | 
			
		||||
		configFile:    configFile,
 | 
			
		||||
		in:            in,
 | 
			
		||||
		out:           out,
 | 
			
		||||
		err:           err,
 | 
			
		||||
		keyFile:       keyFile,
 | 
			
		||||
		inFd:          inFd,
 | 
			
		||||
		outFd:         outFd,
 | 
			
		||||
		isTerminalIn:  isTerminalIn,
 | 
			
		||||
		isTerminalOut: isTerminalOut,
 | 
			
		||||
		tlsConfig:     tlsConfig,
 | 
			
		||||
		scheme:        scheme,
 | 
			
		||||
		transport:     tr,
 | 
			
		||||
	}
 | 
			
		||||
	return cli
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,3 @@
 | 
			
		|||
// Run "docker help SUBCOMMAND" or "docker SUBCOMMAND --help" to see more information on any Docker subcommand, including the full list of options supported for the subcommand.
 | 
			
		||||
// See https://docs.docker.com/installation/ for instructions on installing Docker.
 | 
			
		||||
package client
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
// An StatusError reports an unsuccessful exit by a command.
 | 
			
		||||
type StatusError struct {
 | 
			
		||||
	Status     string
 | 
			
		||||
	StatusCode int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e StatusError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +18,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
 | 
			
		||||
func (cli *DockerCli) CmdCommit(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("commit", []string{"CONTAINER [REPOSITORY[:TAG]]"}, "Create a new image from a container's changes", true)
 | 
			
		||||
	cmd := Cli.Subcmd("commit", []string{"CONTAINER [REPOSITORY[:TAG]]"}, "Create a new image from a container's changes", true)
 | 
			
		||||
	flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
 | 
			
		||||
	flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
 | 
			
		||||
	flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +38,7 @@ const (
 | 
			
		|||
// 	docker cp CONTAINER:PATH LOCALPATH|-
 | 
			
		||||
// 	docker cp LOCALPATH|- CONTAINER:PATH
 | 
			
		||||
func (cli *DockerCli) CmdCp(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd(
 | 
			
		||||
	cmd := Cli.Subcmd(
 | 
			
		||||
		"cp",
 | 
			
		||||
		[]string{"CONTAINER:PATH LOCALPATH|-", "LOCALPATH|- CONTAINER:PATH"},
 | 
			
		||||
		strings.Join([]string{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/graph/tags"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/registry"
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +138,7 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
 | 
			
		||||
func (cli *DockerCli) CmdCreate(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("create", []string{"IMAGE [COMMAND] [ARG...]"}, "Create a new container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("create", []string{"IMAGE [COMMAND] [ARG...]"}, "Create a new container", true)
 | 
			
		||||
 | 
			
		||||
	// These are flags not stored in Config/HostConfig
 | 
			
		||||
	var (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +18,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker diff CONTAINER
 | 
			
		||||
func (cli *DockerCli) CmdDiff(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("diff", []string{"CONTAINER"}, "Inspect changes on a container's filesystem", true)
 | 
			
		||||
	cmd := Cli.Subcmd("diff", []string{"CONTAINER"}, "Inspect changes on a container's filesystem", true)
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers/filters"
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker events [OPTIONS]
 | 
			
		||||
func (cli *DockerCli) CmdEvents(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("events", nil, "Get real time events from the server", true)
 | 
			
		||||
	cmd := Cli.Subcmd("events", nil, "Get real time events from the server", true)
 | 
			
		||||
	since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp")
 | 
			
		||||
	until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
 | 
			
		||||
	flFilter := opts.NewListOpts(nil)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/pkg/promise"
 | 
			
		||||
	"github.com/docker/docker/runconfig"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -15,12 +16,12 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
 | 
			
		||||
func (cli *DockerCli) CmdExec(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("exec", []string{"CONTAINER COMMAND [ARG...]"}, "Run a command in a running container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("exec", []string{"CONTAINER COMMAND [ARG...]"}, "Run a command in a running container", true)
 | 
			
		||||
 | 
			
		||||
	execConfig, err := runconfig.ParseExec(cmd, args)
 | 
			
		||||
	// just in case the ParseExec does not exit
 | 
			
		||||
	if execConfig.Container == "" || err != nil {
 | 
			
		||||
		return StatusError{StatusCode: 1}
 | 
			
		||||
		return Cli.StatusError{StatusCode: 1}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	serverResp, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, nil)
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +127,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if status != 0 {
 | 
			
		||||
		return StatusError{StatusCode: status}
 | 
			
		||||
		return Cli.StatusError{StatusCode: status}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker export [OPTIONS] CONTAINER
 | 
			
		||||
func (cli *DockerCli) CmdExport(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("export", []string{"CONTAINER"}, "Export the contents of a container's filesystem as a tar archive", true)
 | 
			
		||||
	cmd := Cli.Subcmd("export", []string{"CONTAINER"}, "Export the contents of a container's filesystem as a tar archive", true)
 | 
			
		||||
	outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT")
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
package client
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CmdHelp displays information on a Docker command.
 | 
			
		||||
//
 | 
			
		||||
// If more than one command is specified, information is only shown for the first command.
 | 
			
		||||
//
 | 
			
		||||
// Usage: docker help COMMAND or docker COMMAND --help
 | 
			
		||||
func (cli *DockerCli) CmdHelp(args ...string) error {
 | 
			
		||||
	if len(args) > 1 {
 | 
			
		||||
		method, exists := cli.getMethod(args[:2]...)
 | 
			
		||||
		if exists {
 | 
			
		||||
			method("--help")
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		method, exists := cli.getMethod(args[0])
 | 
			
		||||
		if !exists {
 | 
			
		||||
			return fmt.Errorf("docker: '%s' is not a docker command. See 'docker --help'.", args[0])
 | 
			
		||||
		}
 | 
			
		||||
		method("--help")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flag.Usage()
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/stringid"
 | 
			
		||||
	"github.com/docker/docker/pkg/stringutils"
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +18,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker history [OPTIONS] IMAGE
 | 
			
		||||
func (cli *DockerCli) CmdHistory(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("history", []string{"IMAGE"}, "Show the history of an image", true)
 | 
			
		||||
	cmd := Cli.Subcmd("history", []string{"IMAGE"}, "Show the history of an image", true)
 | 
			
		||||
	human := cmd.Bool([]string{"H", "-human"}, true, "Print sizes and dates in human readable format")
 | 
			
		||||
	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
 | 
			
		||||
	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +22,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker images [OPTIONS] [REPOSITORY]
 | 
			
		||||
func (cli *DockerCli) CmdImages(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("images", []string{"[REPOSITORY]"}, "List images", true)
 | 
			
		||||
	cmd := Cli.Subcmd("images", []string{"[REPOSITORY]"}, "List images", true)
 | 
			
		||||
	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
 | 
			
		||||
	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
 | 
			
		||||
	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +20,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
 | 
			
		||||
func (cli *DockerCli) CmdImport(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
 | 
			
		||||
	cmd := Cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
 | 
			
		||||
	flChanges := opts.NewListOpts(nil)
 | 
			
		||||
	cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/pkg/httputils"
 | 
			
		||||
	"github.com/docker/docker/pkg/ioutils"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker info
 | 
			
		||||
func (cli *DockerCli) CmdInfo(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("info", nil, "Display system-wide information", true)
 | 
			
		||||
	cmd := Cli.Subcmd("info", nil, "Display system-wide information", true)
 | 
			
		||||
	cmd.Require(flag.Exact, 0)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,14 +9,22 @@ import (
 | 
			
		|||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var funcMap = template.FuncMap{
 | 
			
		||||
	"json": func(v interface{}) string {
 | 
			
		||||
		a, _ := json.Marshal(v)
 | 
			
		||||
		return string(a)
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CmdInspect displays low-level information on one or more containers or images.
 | 
			
		||||
//
 | 
			
		||||
// Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
 | 
			
		||||
func (cli *DockerCli) CmdInspect(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, "Return low-level information on a container or image", true)
 | 
			
		||||
	cmd := Cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, "Return low-level information on a container or image", true)
 | 
			
		||||
	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
 | 
			
		||||
	inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +37,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
 | 
			
		|||
 | 
			
		||||
	if *tmplStr != "" {
 | 
			
		||||
		if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil {
 | 
			
		||||
			return StatusError{StatusCode: 64,
 | 
			
		||||
			return Cli.StatusError{StatusCode: 64,
 | 
			
		||||
				Status: "Template parsing error: " + err.Error()}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +151,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if status != 0 {
 | 
			
		||||
		return StatusError{StatusCode: status}
 | 
			
		||||
		return Cli.StatusError{StatusCode: status}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +11,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdKill(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("kill", []string{"CONTAINER [CONTAINER...]"}, "Kill a running container using SIGKILL or a specified signal", true)
 | 
			
		||||
	cmd := Cli.Subcmd("kill", []string{"CONTAINER [CONTAINER...]"}, "Kill a running container using SIGKILL or a specified signal", true)
 | 
			
		||||
	signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import (
 | 
			
		|||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker load [OPTIONS]
 | 
			
		||||
func (cli *DockerCli) CmdLoad(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("load", nil, "Load an image from a tar archive or STDIN", true)
 | 
			
		||||
	cmd := Cli.Subcmd("load", nil, "Load an image from a tar archive or STDIN", true)
 | 
			
		||||
	infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN")
 | 
			
		||||
	cmd.Require(flag.Exact, 0)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/term"
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +22,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker login SERVER
 | 
			
		||||
func (cli *DockerCli) CmdLogin(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("login", []string{"[SERVER]"}, "Register or log in to a Docker registry server, if no server is\nspecified \""+registry.INDEXSERVER+"\" is the default.", true)
 | 
			
		||||
	cmd := Cli.Subcmd("login", []string{"[SERVER]"}, "Register or log in to a Docker registry server, if no server is\nspecified \""+registry.INDEXSERVER+"\" is the default.", true)
 | 
			
		||||
	cmd.Require(flag.Max, 1)
 | 
			
		||||
 | 
			
		||||
	var username, password, email string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/registry"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker logout [SERVER]
 | 
			
		||||
func (cli *DockerCli) CmdLogout(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("logout", []string{"[SERVER]"}, "Log out from a Docker registry, if no server is\nspecified \""+registry.INDEXSERVER+"\" is the default.", true)
 | 
			
		||||
	cmd := Cli.Subcmd("logout", []string{"[SERVER]"}, "Log out from a Docker registry, if no server is\nspecified \""+registry.INDEXSERVER+"\" is the default.", true)
 | 
			
		||||
	cmd.Require(flag.Max, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/timeutils"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// docker logs [OPTIONS] CONTAINER
 | 
			
		||||
func (cli *DockerCli) CmdLogs(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("logs", []string{"CONTAINER"}, "Fetch the logs of a container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("logs", []string{"CONTAINER"}, "Fetch the logs of a container", true)
 | 
			
		||||
	follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
 | 
			
		||||
	since := cmd.String([]string{"-since"}, "", "Show logs since timestamp")
 | 
			
		||||
	times := cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +11,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker pause CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdPause(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("pause", []string{"CONTAINER [CONTAINER...]"}, "Pause all processes within a container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("pause", []string{"CONTAINER [CONTAINER...]"}, "Pause all processes within a container", true)
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/nat"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker port CONTAINER [PRIVATE_PORT[/PROTO]]
 | 
			
		||||
func (cli *DockerCli) CmdPort(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("port", []string{"CONTAINER [PRIVATE_PORT[/PROTO]]"}, "List port mappings for the CONTAINER, or lookup the public-facing port that\nis NAT-ed to the PRIVATE_PORT", true)
 | 
			
		||||
	cmd := Cli.Subcmd("port", []string{"CONTAINER [PRIVATE_PORT[/PROTO]]"}, "List port mappings for the CONTAINER, or lookup the public-facing port that\nis NAT-ed to the PRIVATE_PORT", true)
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/docker/docker/api/client/ps"
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers/filters"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +23,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
 | 
			
		|||
		psFilterArgs = filters.Args{}
 | 
			
		||||
		v            = url.Values{}
 | 
			
		||||
 | 
			
		||||
		cmd      = cli.Subcmd("ps", nil, "List containers", true)
 | 
			
		||||
		cmd      = Cli.Subcmd("ps", nil, "List containers", true)
 | 
			
		||||
		quiet    = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
 | 
			
		||||
		size     = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
 | 
			
		||||
		all      = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/graph/tags"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST]
 | 
			
		||||
func (cli *DockerCli) CmdPull(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, "Pull an image or a repository from a registry", true)
 | 
			
		||||
	cmd := Cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, "Pull an image or a repository from a registry", true)
 | 
			
		||||
	allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository")
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/registry"
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker push NAME[:TAG]
 | 
			
		||||
func (cli *DockerCli) CmdPush(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("push", []string{"NAME[:TAG]"}, "Push an image or a repository to a registry", true)
 | 
			
		||||
	cmd := Cli.Subcmd("push", []string{"NAME[:TAG]"}, "Push an image or a repository to a registry", true)
 | 
			
		||||
	cmd.Require(flag.Exact, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +11,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker rename OLD_NAME NEW_NAME
 | 
			
		||||
func (cli *DockerCli) CmdRename(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("rename", []string{"OLD_NAME NEW_NAME"}, "Rename a container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("rename", []string{"OLD_NAME NEW_NAME"}, "Rename a container", true)
 | 
			
		||||
	cmd.Require(flag.Exact, 2)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdRestart(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("restart", []string{"CONTAINER [CONTAINER...]"}, "Restart a running container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("restart", []string{"CONTAINER [CONTAINER...]"}, "Restart a running container", true)
 | 
			
		||||
	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Seconds to wait for stop before killing the container")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdRm(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("rm", []string{"CONTAINER [CONTAINER...]"}, "Remove one or more containers", true)
 | 
			
		||||
	cmd := Cli.Subcmd("rm", []string{"CONTAINER [CONTAINER...]"}, "Remove one or more containers", true)
 | 
			
		||||
	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container")
 | 
			
		||||
	link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link")
 | 
			
		||||
	force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
 | 
			
		||||
func (cli *DockerCli) CmdRmi(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("rmi", []string{"IMAGE [IMAGE...]"}, "Remove one or more images", true)
 | 
			
		||||
	cmd := Cli.Subcmd("rmi", []string{"IMAGE [IMAGE...]"}, "Remove one or more images", true)
 | 
			
		||||
	force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image")
 | 
			
		||||
	noprune := cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	"github.com/docker/docker/pkg/promise"
 | 
			
		||||
	"github.com/docker/docker/pkg/signal"
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +40,7 @@ func (cid *cidFile) Write(id string) error {
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
 | 
			
		||||
func (cli *DockerCli) CmdRun(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("run", []string{"IMAGE [COMMAND] [ARG...]"}, "Run a command in a new container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("run", []string{"IMAGE [COMMAND] [ARG...]"}, "Run a command in a new container", true)
 | 
			
		||||
 | 
			
		||||
	// These are flags not stored in Config/HostConfig
 | 
			
		||||
	var (
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +250,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if status != 0 {
 | 
			
		||||
		return StatusError{StatusCode: status}
 | 
			
		||||
		return Cli.StatusError{StatusCode: status}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker save [OPTIONS] IMAGE [IMAGE...]
 | 
			
		||||
func (cli *DockerCli) CmdSave(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("save", []string{"IMAGE [IMAGE...]"}, "Save an image(s) to a tar archive (streamed to STDOUT by default)", true)
 | 
			
		||||
	cmd := Cli.Subcmd("save", []string{"IMAGE [IMAGE...]"}, "Save an image(s) to a tar archive (streamed to STDOUT by default)", true)
 | 
			
		||||
	outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
	"text/tabwriter"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/pkg/stringutils"
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +26,7 @@ func (r ByStars) Less(i, j int) bool { return r[i].StarCount < r[j].StarCount }
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker search [OPTIONS] TERM
 | 
			
		||||
func (cli *DockerCli) CmdSearch(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("search", []string{"TERM"}, "Search the Docker Hub for images", true)
 | 
			
		||||
	cmd := Cli.Subcmd("search", []string{"TERM"}, "Search the Docker Hub for images", true)
 | 
			
		||||
	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
 | 
			
		||||
	trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds")
 | 
			
		||||
	automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/promise"
 | 
			
		||||
	"github.com/docker/docker/pkg/signal"
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +45,7 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdStart(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("start", []string{"CONTAINER [CONTAINER...]"}, "Start one or more stopped containers", true)
 | 
			
		||||
	cmd := Cli.Subcmd("start", []string{"CONTAINER [CONTAINER...]"}, "Start one or more stopped containers", true)
 | 
			
		||||
	attach := cmd.Bool([]string{"a", "-attach"}, false, "Attach STDOUT/STDERR and forward signals")
 | 
			
		||||
	openStdin := cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +163,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
 | 
			
		|||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if status != 0 {
 | 
			
		||||
			return StatusError{StatusCode: status}
 | 
			
		||||
			return Cli.StatusError{StatusCode: status}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/units"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +125,7 @@ func (s *containerStats) Display(w io.Writer) error {
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker stats CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdStats(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("stats", []string{"CONTAINER [CONTAINER...]"}, "Display a live stream of one or more containers' resource usage statistics", true)
 | 
			
		||||
	cmd := Cli.Subcmd("stats", []string{"CONTAINER [CONTAINER...]"}, "Display a live stream of one or more containers' resource usage statistics", true)
 | 
			
		||||
	noStream := cmd.Bool([]string{"-no-stream"}, false, "Disable streaming stats and only pull the first result")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"net/url"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdStop(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("stop", []string{"CONTAINER [CONTAINER...]"}, "Stop a running container by sending SIGTERM and then SIGKILL after a\ngrace period", true)
 | 
			
		||||
	cmd := Cli.Subcmd("stop", []string{"CONTAINER [CONTAINER...]"}, "Stop a running container by sending SIGTERM and then SIGKILL after a\ngrace period", true)
 | 
			
		||||
	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Seconds to wait for stop before killing it")
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/registry"
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
 | 
			
		||||
func (cli *DockerCli) CmdTag(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("tag", []string{"IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]"}, "Tag an image into a repository", true)
 | 
			
		||||
	cmd := Cli.Subcmd("tag", []string{"IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]"}, "Tag an image into a repository", true)
 | 
			
		||||
	force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
 | 
			
		||||
	cmd.Require(flag.Exact, 2)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"text/tabwriter"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker top CONTAINER
 | 
			
		||||
func (cli *DockerCli) CmdTop(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("top", []string{"CONTAINER [ps OPTIONS]"}, "Display the running processes of a container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("top", []string{"CONTAINER [ps OPTIONS]"}, "Display the running processes of a container", true)
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +11,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker unpause CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdUnpause(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("unpause", []string{"CONTAINER [CONTAINER...]"}, "Unpause all processes within a container", true)
 | 
			
		||||
	cmd := Cli.Subcmd("unpause", []string{"CONTAINER [CONTAINER...]"}, "Unpause all processes within a container", true)
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/api"
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	"github.com/docker/docker/autogen/dockerversion"
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/utils"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +43,7 @@ type VersionData struct {
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker version
 | 
			
		||||
func (cli *DockerCli) CmdVersion(args ...string) (err error) {
 | 
			
		||||
	cmd := cli.Subcmd("version", nil, "Show the Docker version information.", true)
 | 
			
		||||
	cmd := Cli.Subcmd("version", nil, "Show the Docker version information.", true)
 | 
			
		||||
	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
 | 
			
		||||
	cmd.Require(flag.Exact, 0)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +54,7 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
 | 
			
		|||
 | 
			
		||||
	var tmpl *template.Template
 | 
			
		||||
	if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil {
 | 
			
		||||
		return StatusError{StatusCode: 64,
 | 
			
		||||
		return Cli.StatusError{StatusCode: 64,
 | 
			
		||||
			Status: "Template parsing error: " + err.Error()}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +86,7 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
 | 
			
		|||
	defer serverResp.body.Close()
 | 
			
		||||
 | 
			
		||||
	if err = json.NewDecoder(serverResp.body).Decode(&vd.Server); err != nil {
 | 
			
		||||
		return StatusError{StatusCode: 1,
 | 
			
		||||
		return Cli.StatusError{StatusCode: 1,
 | 
			
		||||
			Status: "Error reading remote version: " + err.Error()}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	Cli "github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,7 @@ import (
 | 
			
		|||
//
 | 
			
		||||
// Usage: docker wait CONTAINER [CONTAINER...]
 | 
			
		||||
func (cli *DockerCli) CmdWait(args ...string) error {
 | 
			
		||||
	cmd := cli.Subcmd("wait", []string{"CONTAINER [CONTAINER...]"}, "Block until a container stops, then print its exit code.", true)
 | 
			
		||||
	cmd := Cli.Subcmd("wait", []string{"CONTAINER [CONTAINER...]"}, "Block until a container stops, then print its exit code.", true)
 | 
			
		||||
	cmd.Require(flag.Min, 1)
 | 
			
		||||
 | 
			
		||||
	cmd.ParseFlags(args, true)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										200
									
								
								cli/cli.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								cli/cli.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,200 @@
 | 
			
		|||
package cli
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Cli represents a command line interface.
 | 
			
		||||
type Cli struct {
 | 
			
		||||
	Stderr   io.Writer
 | 
			
		||||
	handlers []Handler
 | 
			
		||||
	Usage    func()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handler holds the different commands Cli will call
 | 
			
		||||
// It should have methods with names starting with `Cmd` like:
 | 
			
		||||
// 	func (h myHandler) CmdFoo(args ...string) error
 | 
			
		||||
type Handler interface{}
 | 
			
		||||
 | 
			
		||||
// Initializer can be optionally implemented by a Handler to
 | 
			
		||||
// initialize before each call to one of its commands.
 | 
			
		||||
type Initializer interface {
 | 
			
		||||
	Initialize() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New instantiates a ready-to-use Cli.
 | 
			
		||||
func New(handlers ...Handler) *Cli {
 | 
			
		||||
	// make the generic Cli object the first cli handler
 | 
			
		||||
	// in order to handle `docker help` appropriately
 | 
			
		||||
	cli := new(Cli)
 | 
			
		||||
	cli.handlers = append([]Handler{cli}, handlers...)
 | 
			
		||||
	return cli
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// initErr is an error returned upon initialization of a handler implementing Initializer.
 | 
			
		||||
type initErr struct{ error }
 | 
			
		||||
 | 
			
		||||
func (err initErr) Error() string {
 | 
			
		||||
	return err.Error()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cli *Cli) command(args ...string) (func(...string) error, error) {
 | 
			
		||||
	for _, c := range cli.handlers {
 | 
			
		||||
		if c == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		camelArgs := make([]string, len(args))
 | 
			
		||||
		for i, s := range args {
 | 
			
		||||
			if len(s) == 0 {
 | 
			
		||||
				return nil, errors.New("empty command")
 | 
			
		||||
			}
 | 
			
		||||
			camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
 | 
			
		||||
		}
 | 
			
		||||
		methodName := "Cmd" + strings.Join(camelArgs, "")
 | 
			
		||||
		method := reflect.ValueOf(c).MethodByName(methodName)
 | 
			
		||||
		if method.IsValid() {
 | 
			
		||||
			if c, ok := c.(Initializer); ok {
 | 
			
		||||
				if err := c.Initialize(); err != nil {
 | 
			
		||||
					return nil, initErr{err}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return method.Interface().(func(...string) error), nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, errors.New("command not found")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run executes the specified command.
 | 
			
		||||
func (cli *Cli) Run(args ...string) error {
 | 
			
		||||
	if len(args) > 1 {
 | 
			
		||||
		command, err := cli.command(args[:2]...)
 | 
			
		||||
		switch err := err.(type) {
 | 
			
		||||
		case nil:
 | 
			
		||||
			return command(args[2:]...)
 | 
			
		||||
		case initErr:
 | 
			
		||||
			return err.error
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		command, err := cli.command(args[0])
 | 
			
		||||
		switch err := err.(type) {
 | 
			
		||||
		case nil:
 | 
			
		||||
			return command(args[1:]...)
 | 
			
		||||
		case initErr:
 | 
			
		||||
			return err.error
 | 
			
		||||
		}
 | 
			
		||||
		cli.noSuchCommand(args[0])
 | 
			
		||||
	}
 | 
			
		||||
	return cli.CmdHelp()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cli *Cli) noSuchCommand(command string) {
 | 
			
		||||
	if cli.Stderr == nil {
 | 
			
		||||
		cli.Stderr = os.Stderr
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintf(cli.Stderr, "docker: '%s' is not a docker command.\nSee 'docker --help'.\n", command)
 | 
			
		||||
	os.Exit(1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CmdHelp displays information on a Docker command.
 | 
			
		||||
//
 | 
			
		||||
// If more than one command is specified, information is only shown for the first command.
 | 
			
		||||
//
 | 
			
		||||
// Usage: docker help COMMAND or docker COMMAND --help
 | 
			
		||||
func (cli *Cli) CmdHelp(args ...string) error {
 | 
			
		||||
	if len(args) > 1 {
 | 
			
		||||
		command, err := cli.command(args[:2]...)
 | 
			
		||||
		switch err := err.(type) {
 | 
			
		||||
		case nil:
 | 
			
		||||
			command("--help")
 | 
			
		||||
			return nil
 | 
			
		||||
		case initErr:
 | 
			
		||||
			return err.error
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		command, err := cli.command(args[0])
 | 
			
		||||
		switch err := err.(type) {
 | 
			
		||||
		case nil:
 | 
			
		||||
			command("--help")
 | 
			
		||||
			return nil
 | 
			
		||||
		case initErr:
 | 
			
		||||
			return err.error
 | 
			
		||||
		}
 | 
			
		||||
		cli.noSuchCommand(args[0])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cli.Usage == nil {
 | 
			
		||||
		flag.Usage()
 | 
			
		||||
	} else {
 | 
			
		||||
		cli.Usage()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subcmd is a subcommand of the main "docker" command.
 | 
			
		||||
// A subcommand represents an action that can be performed
 | 
			
		||||
// from the Docker command line client.
 | 
			
		||||
//
 | 
			
		||||
// To see all available subcommands, run "docker --help".
 | 
			
		||||
func Subcmd(name string, synopses []string, description string, exitOnError bool) *flag.FlagSet {
 | 
			
		||||
	var errorHandling flag.ErrorHandling
 | 
			
		||||
	if exitOnError {
 | 
			
		||||
		errorHandling = flag.ExitOnError
 | 
			
		||||
	} else {
 | 
			
		||||
		errorHandling = flag.ContinueOnError
 | 
			
		||||
	}
 | 
			
		||||
	flags := flag.NewFlagSet(name, errorHandling)
 | 
			
		||||
	flags.Usage = func() {
 | 
			
		||||
		flags.ShortUsage()
 | 
			
		||||
		flags.PrintDefaults()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags.ShortUsage = func() {
 | 
			
		||||
		options := ""
 | 
			
		||||
		if flags.FlagCountUndeprecated() > 0 {
 | 
			
		||||
			options = " [OPTIONS]"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(synopses) == 0 {
 | 
			
		||||
			synopses = []string{""}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Allow for multiple command usage synopses.
 | 
			
		||||
		for i, synopsis := range synopses {
 | 
			
		||||
			lead := "\t"
 | 
			
		||||
			if i == 0 {
 | 
			
		||||
				// First line needs the word 'Usage'.
 | 
			
		||||
				lead = "Usage:\t"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if synopsis != "" {
 | 
			
		||||
				synopsis = " " + synopsis
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintf(flags.Out(), "\n%sdocker %s%s%s", lead, name, options, synopsis)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(flags.Out(), "\n\n%s\n", description)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return flags
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An StatusError reports an unsuccessful exit by a command.
 | 
			
		||||
type StatusError struct {
 | 
			
		||||
	Status     string
 | 
			
		||||
	StatusCode int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e StatusError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								cli/client.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								cli/client.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
package cli
 | 
			
		||||
 | 
			
		||||
import flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
 | 
			
		||||
// ClientFlags represents flags for the docker client.
 | 
			
		||||
type ClientFlags struct {
 | 
			
		||||
	FlagSet   *flag.FlagSet
 | 
			
		||||
	Common    *CommonFlags
 | 
			
		||||
	PostParse func()
 | 
			
		||||
 | 
			
		||||
	ConfigDir string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								cli/common.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								cli/common.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
package cli
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/tlsconfig"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CommonFlags represents flags that are common to both the client and the daemon.
 | 
			
		||||
type CommonFlags struct {
 | 
			
		||||
	FlagSet   *flag.FlagSet
 | 
			
		||||
	PostParse func()
 | 
			
		||||
 | 
			
		||||
	Debug      bool
 | 
			
		||||
	Hosts      []string
 | 
			
		||||
	LogLevel   string
 | 
			
		||||
	TLS        bool
 | 
			
		||||
	TLSVerify  bool
 | 
			
		||||
	TLSOptions *tlsconfig.Options
 | 
			
		||||
	TrustKey   string
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -41,22 +41,22 @@ type CommonConfig struct {
 | 
			
		|||
// the current process.
 | 
			
		||||
// Subsequent calls to `flag.Parse` will populate config with values parsed
 | 
			
		||||
// from the command-line.
 | 
			
		||||
func (config *Config) InstallCommonFlags() {
 | 
			
		||||
	opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
 | 
			
		||||
	opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options")
 | 
			
		||||
	flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, "Path to use for daemon PID file")
 | 
			
		||||
	flag.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, "Root of the Docker runtime")
 | 
			
		||||
	flag.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", "Root of the Docker execdriver")
 | 
			
		||||
	flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
 | 
			
		||||
	flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
 | 
			
		||||
	flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, defaultExec, "Exec driver to use")
 | 
			
		||||
	flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU")
 | 
			
		||||
	flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
 | 
			
		||||
	flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
 | 
			
		||||
func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&config.GraphOptions, nil), []string{"-storage-opt"}, usageFn("Set storage driver options"))
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&config.ExecOptions, nil), []string{"-exec-opt"}, usageFn("Set exec driver options"))
 | 
			
		||||
	cmd.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, usageFn("Path to use for daemon PID file"))
 | 
			
		||||
	cmd.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, usageFn("Root of the Docker runtime"))
 | 
			
		||||
	cmd.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", usageFn("Root of the Docker execdriver"))
 | 
			
		||||
	cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run"))
 | 
			
		||||
	cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use"))
 | 
			
		||||
	cmd.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, defaultExec, usageFn("Exec driver to use"))
 | 
			
		||||
	cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
 | 
			
		||||
	cmd.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, usageFn("Enable CORS headers in the remote API, this is deprecated by --api-cors-header"))
 | 
			
		||||
	cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API"))
 | 
			
		||||
	// FIXME: why the inconsistency between "hosts" and "sockets"?
 | 
			
		||||
	opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
 | 
			
		||||
	opts.DNSSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use")
 | 
			
		||||
	opts.LabelListVar(&config.Labels, []string{"-label"}, "Set key=value labels to the daemon")
 | 
			
		||||
	flag.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", "Default driver for container logs")
 | 
			
		||||
	opts.LogOptsVar(config.LogConfig.Config, []string{"-log-opt"}, "Set log driver options")
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&config.Dns, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&config.DnsSearch, opts.ValidateDNSSearch), []string{"-dns-search"}, usageFn("DNS search domains to use"))
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&config.Labels, opts.ValidateLabel), []string{"-label"}, usageFn("Set key=value labels to the daemon"))
 | 
			
		||||
	cmd.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", usageFn("Default driver for container logs"))
 | 
			
		||||
	cmd.Var(opts.NewMapOpts(config.LogConfig.Config, nil), []string{"-log-opt"}, usageFn("Set log driver options"))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ package daemon
 | 
			
		|||
 | 
			
		||||
import flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
 | 
			
		||||
func (config *Config) attachExperimentalFlags() {
 | 
			
		||||
	flag.StringVar(&config.DefaultNetwork, []string{"-default-network"}, "", "Set default network")
 | 
			
		||||
	flag.StringVar(&config.NetworkKVStore, []string{"-kv-store"}, "", "Set KV Store configuration")
 | 
			
		||||
func (config *Config) attachExperimentalFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
	cmd.StringVar(&config.DefaultNetwork, []string{"-default-network"}, "", usageFn("Set default network"))
 | 
			
		||||
	cmd.StringVar(&config.NetworkKVStore, []string{"-kv-store"}, "", usageFn("Set KV Store configuration"))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,27 +49,28 @@ type bridgeConfig struct {
 | 
			
		|||
// the current process.
 | 
			
		||||
// Subsequent calls to `flag.Parse` will populate config with values parsed
 | 
			
		||||
// from the command-line.
 | 
			
		||||
func (config *Config) InstallFlags() {
 | 
			
		||||
func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
	// First handle install flags which are consistent cross-platform
 | 
			
		||||
	config.InstallCommonFlags()
 | 
			
		||||
	config.InstallCommonFlags(cmd, usageFn)
 | 
			
		||||
 | 
			
		||||
	// Then platform-specific install flags
 | 
			
		||||
	flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
 | 
			
		||||
	flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
 | 
			
		||||
	cmd.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, usageFn("Enable selinux support"))
 | 
			
		||||
	cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", usageFn("Group for the unix socket"))
 | 
			
		||||
	config.Ulimits = make(map[string]*ulimit.Ulimit)
 | 
			
		||||
	opts.UlimitMapVar(config.Ulimits, []string{"-default-ulimit"}, "Set default ulimits for containers")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
 | 
			
		||||
	flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
 | 
			
		||||
	flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
 | 
			
		||||
	flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
 | 
			
		||||
	flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
 | 
			
		||||
	opts.IPVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
 | 
			
		||||
	opts.IPVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
 | 
			
		||||
	opts.IPVar(&config.Bridge.DefaultIP, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
 | 
			
		||||
	flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
 | 
			
		||||
	config.attachExperimentalFlags()
 | 
			
		||||
	cmd.Var(opts.NewUlimitOpt(&config.Ulimits), []string{"-default-ulimit"}, usageFn("Set default ulimits for containers"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, usageFn("Enable addition of iptables rules"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, usageFn("Enable net.ipv4.ip_forward"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, usageFn("Enable IP masquerading"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, usageFn("Enable IPv6 networking"))
 | 
			
		||||
	cmd.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", usageFn("Specify network bridge IP"))
 | 
			
		||||
	cmd.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", usageFn("Attach containers to a network bridge"))
 | 
			
		||||
	cmd.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", usageFn("IPv4 subnet for fixed IPs"))
 | 
			
		||||
	cmd.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", usageFn("IPv6 subnet for fixed IPs"))
 | 
			
		||||
	cmd.Var(opts.NewIpOpt(&config.Bridge.DefaultGatewayIPv4, ""), []string{"-default-gateway"}, usageFn("Container default gateway IPv4 address"))
 | 
			
		||||
	cmd.Var(opts.NewIpOpt(&config.Bridge.DefaultGatewayIPv6, ""), []string{"-default-gateway-v6"}, usageFn("Container default gateway IPv6 address"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, usageFn("Enable inter-container communication"))
 | 
			
		||||
	cmd.Var(opts.NewIpOpt(&config.Bridge.DefaultIP, "0.0.0.0"), []string{"#ip", "-ip"}, usageFn("Default IP when binding container ports"))
 | 
			
		||||
	cmd.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, usageFn("Use userland proxy for loopback traffic"))
 | 
			
		||||
 | 
			
		||||
	config.attachExperimentalFlags(cmd, usageFn)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,5 +2,7 @@
 | 
			
		|||
 | 
			
		||||
package daemon
 | 
			
		||||
 | 
			
		||||
func (config *Config) attachExperimentalFlags() {
 | 
			
		||||
import flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
 | 
			
		||||
func (config *Config) attachExperimentalFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,9 +32,9 @@ type Config struct {
 | 
			
		|||
// the current process.
 | 
			
		||||
// Subsequent calls to `flag.Parse` will populate config with values parsed
 | 
			
		||||
// from the command-line.
 | 
			
		||||
func (config *Config) InstallFlags() {
 | 
			
		||||
func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
	// First handle install flags which are consistent cross-platform
 | 
			
		||||
	config.InstallCommonFlags()
 | 
			
		||||
	config.InstallCommonFlags(cmd, usageFn)
 | 
			
		||||
 | 
			
		||||
	// Then platform-specific install flags.
 | 
			
		||||
	flag.StringVar(&config.Bridge.VirtualSwitchName, []string{"b", "-bridge"}, "", "Attach containers to a virtual switch")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,28 @@
 | 
			
		|||
// +build !daemon
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log" // see gh#8745, client needs to use go log pkg
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func mainDaemon() {
 | 
			
		||||
	log.Fatal("This is a client-only binary - running the Docker daemon is not supported.")
 | 
			
		||||
var clientFlags = &cli.ClientFlags{FlagSet: new(flag.FlagSet), Common: commonFlags}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	client := clientFlags.FlagSet
 | 
			
		||||
	client.StringVar(&clientFlags.ConfigDir, []string{"-config"}, cliconfig.ConfigDir(), "Location of client config files")
 | 
			
		||||
 | 
			
		||||
	clientFlags.PostParse = func() {
 | 
			
		||||
		clientFlags.Common.PostParse()
 | 
			
		||||
 | 
			
		||||
		if clientFlags.ConfigDir != "" {
 | 
			
		||||
			cliconfig.SetConfigDir(clientFlags.ConfigDir)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if clientFlags.Common.TrustKey == "" {
 | 
			
		||||
			clientFlags.Common.TrustKey = filepath.Join(cliconfig.ConfigDir(), defaultTrustKeyFile)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										101
									
								
								docker/common.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								docker/common.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/tlsconfig"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	defaultTrustKeyFile = "key.json"
 | 
			
		||||
	defaultCaFile       = "ca.pem"
 | 
			
		||||
	defaultKeyFile      = "key.pem"
 | 
			
		||||
	defaultCertFile     = "cert.pem"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	daemonFlags *flag.FlagSet
 | 
			
		||||
	commonFlags = &cli.CommonFlags{FlagSet: new(flag.FlagSet)}
 | 
			
		||||
 | 
			
		||||
	dockerCertPath  = os.Getenv("DOCKER_CERT_PATH")
 | 
			
		||||
	dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if dockerCertPath == "" {
 | 
			
		||||
		dockerCertPath = cliconfig.ConfigDir()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	commonFlags.PostParse = postParseCommon
 | 
			
		||||
 | 
			
		||||
	cmd := commonFlags.FlagSet
 | 
			
		||||
 | 
			
		||||
	cmd.BoolVar(&commonFlags.Debug, []string{"D", "-debug"}, false, "Enable debug mode")
 | 
			
		||||
	cmd.StringVar(&commonFlags.LogLevel, []string{"l", "-log-level"}, "info", "Set the logging level")
 | 
			
		||||
	cmd.BoolVar(&commonFlags.TLS, []string{"-tls"}, false, "Use TLS; implied by --tlsverify")
 | 
			
		||||
	cmd.BoolVar(&commonFlags.TLSVerify, []string{"-tlsverify"}, dockerTLSVerify, "Use TLS and verify the remote")
 | 
			
		||||
 | 
			
		||||
	// TODO use flag flag.String([]string{"i", "-identity"}, "", "Path to libtrust key file")
 | 
			
		||||
 | 
			
		||||
	var tlsOptions tlsconfig.Options
 | 
			
		||||
	commonFlags.TLSOptions = &tlsOptions
 | 
			
		||||
	cmd.StringVar(&tlsOptions.CAFile, []string{"-tlscacert"}, filepath.Join(dockerCertPath, defaultCaFile), "Trust certs signed only by this CA")
 | 
			
		||||
	cmd.StringVar(&tlsOptions.CertFile, []string{"-tlscert"}, filepath.Join(dockerCertPath, defaultCertFile), "Path to TLS certificate file")
 | 
			
		||||
	cmd.StringVar(&tlsOptions.KeyFile, []string{"-tlskey"}, filepath.Join(dockerCertPath, defaultKeyFile), "Path to TLS key file")
 | 
			
		||||
 | 
			
		||||
	cmd.Var(opts.NewListOptsRef(&commonFlags.Hosts, opts.ValidateHost), []string{"H", "-host"}, "Daemon socket(s) to connect to")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func postParseCommon() {
 | 
			
		||||
	cmd := commonFlags.FlagSet
 | 
			
		||||
 | 
			
		||||
	if commonFlags.LogLevel != "" {
 | 
			
		||||
		lvl, err := logrus.ParseLevel(commonFlags.LogLevel)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", commonFlags.LogLevel)
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
		logrus.SetLevel(lvl)
 | 
			
		||||
	} else {
 | 
			
		||||
		logrus.SetLevel(logrus.InfoLevel)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if commonFlags.Debug {
 | 
			
		||||
		os.Setenv("DEBUG", "1")
 | 
			
		||||
		logrus.SetLevel(logrus.DebugLevel)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Regardless of whether the user sets it to true or false, if they
 | 
			
		||||
	// specify --tlsverify at all then we need to turn on tls
 | 
			
		||||
	// TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need to check that here as well
 | 
			
		||||
	if cmd.IsSet("-tlsverify") || commonFlags.TLSVerify {
 | 
			
		||||
		commonFlags.TLS = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !commonFlags.TLS {
 | 
			
		||||
		commonFlags.TLSOptions = nil
 | 
			
		||||
	} else {
 | 
			
		||||
		tlsOptions := commonFlags.TLSOptions
 | 
			
		||||
		tlsOptions.InsecureSkipVerify = !commonFlags.TLSVerify
 | 
			
		||||
 | 
			
		||||
		// Reset CertFile and KeyFile to empty string if the user did not specify
 | 
			
		||||
		// the respective flags and the respective default files were not found.
 | 
			
		||||
		if !cmd.IsSet("-tlscert") {
 | 
			
		||||
			if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) {
 | 
			
		||||
				tlsOptions.CertFile = ""
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !cmd.IsSet("-tlskey") {
 | 
			
		||||
			if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) {
 | 
			
		||||
				tlsOptions.KeyFile = ""
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										164
									
								
								docker/daemon.go
									
										
									
									
									
								
							
							
						
						
									
										164
									
								
								docker/daemon.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,14 +8,18 @@ import (
 | 
			
		|||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	apiserver "github.com/docker/docker/api/server"
 | 
			
		||||
	"github.com/docker/docker/autogen/dockerversion"
 | 
			
		||||
	"github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	"github.com/docker/docker/daemon"
 | 
			
		||||
	"github.com/docker/docker/daemon/logger"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/pidfile"
 | 
			
		||||
	"github.com/docker/docker/pkg/signal"
 | 
			
		||||
| 
						 | 
				
			
			@ -26,17 +30,63 @@ import (
 | 
			
		|||
	"github.com/docker/docker/utils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const daemonUsage = "       docker daemon [ --help | ... ]\n"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	daemonCfg   = &daemon.Config{}
 | 
			
		||||
	registryCfg = ®istry.Options{}
 | 
			
		||||
	flDaemon              = flag.Bool([]string{"#d", "#-daemon"}, false, "Enable daemon mode (deprecated; use docker daemon)")
 | 
			
		||||
	daemonCli cli.Handler = NewDaemonCli()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if daemonCfg.LogConfig.Config == nil {
 | 
			
		||||
		daemonCfg.LogConfig.Config = make(map[string]string)
 | 
			
		||||
// TODO: remove once `-d` is retired
 | 
			
		||||
func handleGlobalDaemonFlag() {
 | 
			
		||||
	// This block makes sure that if the deprecated daemon flag `--daemon` is absent,
 | 
			
		||||
	// then all daemon-specific flags are absent as well.
 | 
			
		||||
	if !*flDaemon && daemonFlags != nil {
 | 
			
		||||
		flag.CommandLine.Visit(func(fl *flag.Flag) {
 | 
			
		||||
			for _, name := range fl.Names {
 | 
			
		||||
				name := strings.TrimPrefix(name, "#")
 | 
			
		||||
				if daemonFlags.Lookup(name) != nil {
 | 
			
		||||
					// daemon flag was NOT specified, but daemon-specific flags were
 | 
			
		||||
					// so let's error out
 | 
			
		||||
					fmt.Fprintf(os.Stderr, "docker: the daemon flag '-%s' must follow the 'docker daemon' command.\n", name)
 | 
			
		||||
					os.Exit(1)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *flDaemon {
 | 
			
		||||
		if *flHelp {
 | 
			
		||||
			// We do not show the help output here, instead, we tell the user about the new daemon command,
 | 
			
		||||
			// because the help output is so long they would not see the warning anyway.
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "Please use 'docker daemon --help' instead.")
 | 
			
		||||
			os.Exit(0)
 | 
			
		||||
		}
 | 
			
		||||
		daemonCli.(*DaemonCli).CmdDaemon(flag.Args()...)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func presentInHelp(usage string) string { return usage }
 | 
			
		||||
func absentFromHelp(string) string      { return "" }
 | 
			
		||||
 | 
			
		||||
// NewDaemonCli returns a pre-configured daemon CLI
 | 
			
		||||
func NewDaemonCli() *DaemonCli {
 | 
			
		||||
	daemonFlags = cli.Subcmd("daemon", nil, "Enable daemon mode", true)
 | 
			
		||||
 | 
			
		||||
	// TODO(tiborvass): remove InstallFlags?
 | 
			
		||||
	daemonConfig := new(daemon.Config)
 | 
			
		||||
	daemonConfig.InstallFlags(daemonFlags, presentInHelp)
 | 
			
		||||
	daemonConfig.InstallFlags(flag.CommandLine, absentFromHelp)
 | 
			
		||||
	registryOptions := new(registry.Options)
 | 
			
		||||
	registryOptions.InstallFlags(daemonFlags, presentInHelp)
 | 
			
		||||
	registryOptions.InstallFlags(flag.CommandLine, absentFromHelp)
 | 
			
		||||
	daemonFlags.Require(flag.Exact, 0)
 | 
			
		||||
 | 
			
		||||
	return &DaemonCli{
 | 
			
		||||
		Config:          daemonConfig,
 | 
			
		||||
		registryOptions: registryOptions,
 | 
			
		||||
	}
 | 
			
		||||
	daemonCfg.InstallFlags()
 | 
			
		||||
	registryCfg.InstallFlags()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func migrateKey() (err error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,14 +129,56 @@ func migrateKey() (err error) {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func mainDaemon() {
 | 
			
		||||
	if utils.ExperimentalBuild() {
 | 
			
		||||
		logrus.Warn("Running experimental build")
 | 
			
		||||
// DaemonCli represents the daemon CLI.
 | 
			
		||||
type DaemonCli struct {
 | 
			
		||||
	*daemon.Config
 | 
			
		||||
	registryOptions *registry.Options
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getGlobalFlag() (globalFlag *flag.Flag) {
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if x := recover(); x != nil {
 | 
			
		||||
			switch f := x.(type) {
 | 
			
		||||
			case *flag.Flag:
 | 
			
		||||
				globalFlag = f
 | 
			
		||||
			default:
 | 
			
		||||
				panic(x)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	visitor := func(f *flag.Flag) { panic(f) }
 | 
			
		||||
	commonFlags.FlagSet.Visit(visitor)
 | 
			
		||||
	clientFlags.FlagSet.Visit(visitor)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CmdDaemon is the daemon command, called the raw arguments after `docker daemon`.
 | 
			
		||||
func (cli *DaemonCli) CmdDaemon(args ...string) error {
 | 
			
		||||
	if *flDaemon {
 | 
			
		||||
		// allow legacy forms `docker -D -d` and `docker -d -D`
 | 
			
		||||
		logrus.Warn("please use 'docker daemon' instead.")
 | 
			
		||||
	} else if !commonFlags.FlagSet.IsEmpty() || !clientFlags.FlagSet.IsEmpty() {
 | 
			
		||||
		// deny `docker -D daemon`
 | 
			
		||||
		illegalFlag := getGlobalFlag()
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "invalid flag '-%s'.\nSee 'docker daemon --help'.\n", illegalFlag.Names[0])
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	} else {
 | 
			
		||||
		// allow new form `docker daemon -D`
 | 
			
		||||
		flag.Merge(daemonFlags, commonFlags.FlagSet)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if flag.NArg() != 0 {
 | 
			
		||||
		flag.Usage()
 | 
			
		||||
		return
 | 
			
		||||
	daemonFlags.ParseFlags(args, true)
 | 
			
		||||
	commonFlags.PostParse()
 | 
			
		||||
 | 
			
		||||
	if len(commonFlags.Hosts) == 0 {
 | 
			
		||||
		commonFlags.Hosts = []string{opts.DefaultHost}
 | 
			
		||||
	}
 | 
			
		||||
	if commonFlags.TrustKey == "" {
 | 
			
		||||
		commonFlags.TrustKey = filepath.Join(getDaemonConfDir(), defaultTrustKeyFile)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if utils.ExperimentalBuild() {
 | 
			
		||||
		logrus.Warn("Running experimental build")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logrus.SetFormatter(&logrus.TextFormatter{TimestampFormat: timeutils.RFC3339NanoFixed})
 | 
			
		||||
| 
						 | 
				
			
			@ -95,15 +187,15 @@ func mainDaemon() {
 | 
			
		|||
		logrus.Fatalf("Failed to set umask: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(daemonCfg.LogConfig.Config) > 0 {
 | 
			
		||||
		if err := logger.ValidateLogOpts(daemonCfg.LogConfig.Type, daemonCfg.LogConfig.Config); err != nil {
 | 
			
		||||
	if len(cli.LogConfig.Config) > 0 {
 | 
			
		||||
		if err := logger.ValidateLogOpts(cli.LogConfig.Type, cli.LogConfig.Config); err != nil {
 | 
			
		||||
			logrus.Fatalf("Failed to set log opts: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var pfile *pidfile.PidFile
 | 
			
		||||
	if daemonCfg.Pidfile != "" {
 | 
			
		||||
		pf, err := pidfile.New(daemonCfg.Pidfile)
 | 
			
		||||
	if cli.Pidfile != "" {
 | 
			
		||||
		pf, err := pidfile.New(cli.Pidfile)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Fatalf("Error starting daemon: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -115,21 +207,26 @@ func mainDaemon() {
 | 
			
		|||
		}()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cli.LogConfig.Config == nil {
 | 
			
		||||
		cli.LogConfig.Config = make(map[string]string)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	serverConfig := &apiserver.ServerConfig{
 | 
			
		||||
		Logging:     true,
 | 
			
		||||
		EnableCors:  daemonCfg.EnableCors,
 | 
			
		||||
		CorsHeaders: daemonCfg.CorsHeaders,
 | 
			
		||||
		EnableCors:  cli.EnableCors,
 | 
			
		||||
		CorsHeaders: cli.CorsHeaders,
 | 
			
		||||
		Version:     dockerversion.VERSION,
 | 
			
		||||
	}
 | 
			
		||||
	serverConfig = setPlatformServerConfig(serverConfig, daemonCfg)
 | 
			
		||||
	serverConfig = setPlatformServerConfig(serverConfig, cli.Config)
 | 
			
		||||
 | 
			
		||||
	if *flTLS {
 | 
			
		||||
		if *flTLSVerify {
 | 
			
		||||
			tlsOptions.ClientAuth = tls.RequireAndVerifyClientCert
 | 
			
		||||
	if commonFlags.TLSOptions != nil {
 | 
			
		||||
		if !commonFlags.TLSOptions.InsecureSkipVerify {
 | 
			
		||||
			// server requires and verifies client's certificate
 | 
			
		||||
			commonFlags.TLSOptions.ClientAuth = tls.RequireAndVerifyClientCert
 | 
			
		||||
		}
 | 
			
		||||
		tlsConfig, err := tlsconfig.Server(tlsOptions)
 | 
			
		||||
		tlsConfig, err := tlsconfig.Server(*commonFlags.TLSOptions)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Fatal(err)
 | 
			
		||||
			logrus.Fatalf("foobar: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		serverConfig.TLSConfig = tlsConfig
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +238,7 @@ func mainDaemon() {
 | 
			
		|||
	// daemon doesn't exit
 | 
			
		||||
	serveAPIWait := make(chan error)
 | 
			
		||||
	go func() {
 | 
			
		||||
		if err := api.ServeApi(flHosts); err != nil {
 | 
			
		||||
		if err := api.ServeApi(commonFlags.Hosts); err != nil {
 | 
			
		||||
			logrus.Errorf("ServeAPI error: %v", err)
 | 
			
		||||
			serveAPIWait <- err
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -152,10 +249,10 @@ func mainDaemon() {
 | 
			
		|||
	if err := migrateKey(); err != nil {
 | 
			
		||||
		logrus.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	daemonCfg.TrustKeyPath = *flTrustKey
 | 
			
		||||
	cli.TrustKeyPath = commonFlags.TrustKey
 | 
			
		||||
 | 
			
		||||
	registryService := registry.NewService(registryCfg)
 | 
			
		||||
	d, err := daemon.NewDaemon(daemonCfg, registryService)
 | 
			
		||||
	registryService := registry.NewService(cli.registryOptions)
 | 
			
		||||
	d, err := daemon.NewDaemon(cli.Config, registryService)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if pfile != nil {
 | 
			
		||||
			if err := pfile.Remove(); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +298,7 @@ func mainDaemon() {
 | 
			
		|||
		}
 | 
			
		||||
		logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// shutdownDaemon just wraps daemon.Shutdown() to handle a timeout in case
 | 
			
		||||
| 
						 | 
				
			
			@ -219,3 +317,11 @@ func shutdownDaemon(d *daemon.Daemon, timeout time.Duration) {
 | 
			
		|||
		logrus.Error("Force shutdown daemon")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getDaemonConfDir() string {
 | 
			
		||||
	// TODO: update for Windows daemon
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		return cliconfig.ConfigDir()
 | 
			
		||||
	}
 | 
			
		||||
	return "/etc/docker"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								docker/daemon_none.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docker/daemon_none.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
// +build !daemon
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "github.com/docker/docker/cli"
 | 
			
		||||
 | 
			
		||||
const daemonUsage = ""
 | 
			
		||||
 | 
			
		||||
var daemonCli cli.Handler
 | 
			
		||||
 | 
			
		||||
// TODO: remove once `-d` is retired
 | 
			
		||||
func handleGlobalDaemonFlag() {}
 | 
			
		||||
							
								
								
									
										143
									
								
								docker/docker.go
									
										
									
									
									
								
							
							
						
						
									
										143
									
								
								docker/docker.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,31 +1,20 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sort"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/api/client"
 | 
			
		||||
	"github.com/docker/docker/autogen/dockerversion"
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	"github.com/docker/docker/cli"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/reexec"
 | 
			
		||||
	"github.com/docker/docker/pkg/term"
 | 
			
		||||
	"github.com/docker/docker/pkg/tlsconfig"
 | 
			
		||||
	"github.com/docker/docker/utils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	defaultTrustKeyFile = "key.json"
 | 
			
		||||
	defaultCaFile       = "ca.pem"
 | 
			
		||||
	defaultKeyFile      = "key.pem"
 | 
			
		||||
	defaultCertFile     = "cert.pem"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	if reexec.Init() {
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -34,116 +23,58 @@ func main() {
 | 
			
		|||
	// Set terminal emulation based on platform as required.
 | 
			
		||||
	stdin, stdout, stderr := term.StdStreams()
 | 
			
		||||
 | 
			
		||||
	initLogging(stderr)
 | 
			
		||||
	logrus.SetOutput(stderr)
 | 
			
		||||
 | 
			
		||||
	flag.Merge(flag.CommandLine, clientFlags.FlagSet, commonFlags.FlagSet)
 | 
			
		||||
 | 
			
		||||
	flag.Usage = func() {
 | 
			
		||||
		fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n"+daemonUsage+"       docker [ -h | --help | -v | --version ]\n\n")
 | 
			
		||||
		fmt.Fprint(os.Stdout, "A self-sufficient runtime for containers.\n\nOptions:\n")
 | 
			
		||||
 | 
			
		||||
		flag.CommandLine.SetOutput(os.Stdout)
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
 | 
			
		||||
		help := "\nCommands:\n"
 | 
			
		||||
 | 
			
		||||
		// TODO(tiborvass): no need to sort if we ensure dockerCommands is sorted
 | 
			
		||||
		sort.Sort(byName(dockerCommands))
 | 
			
		||||
 | 
			
		||||
		for _, cmd := range dockerCommands {
 | 
			
		||||
			help += fmt.Sprintf("    %-10.10s%s\n", cmd.name, cmd.description)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		help += "\nRun 'docker COMMAND --help' for more information on a command."
 | 
			
		||||
		fmt.Fprintf(os.Stdout, "%s\n", help)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	// FIXME: validate daemon flags here
 | 
			
		||||
 | 
			
		||||
	if *flVersion {
 | 
			
		||||
		showVersion()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *flConfigDir != "" {
 | 
			
		||||
		cliconfig.SetConfigDir(*flConfigDir)
 | 
			
		||||
	}
 | 
			
		||||
	clientCli := client.NewDockerCli(stdin, stdout, stderr, clientFlags)
 | 
			
		||||
	// TODO: remove once `-d` is retired
 | 
			
		||||
	handleGlobalDaemonFlag()
 | 
			
		||||
 | 
			
		||||
	if *flLogLevel != "" {
 | 
			
		||||
		lvl, err := logrus.ParseLevel(*flLogLevel)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel)
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
		setLogLevel(lvl)
 | 
			
		||||
	} else {
 | 
			
		||||
		setLogLevel(logrus.InfoLevel)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *flDebug {
 | 
			
		||||
		os.Setenv("DEBUG", "1")
 | 
			
		||||
		setLogLevel(logrus.DebugLevel)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(flHosts) == 0 {
 | 
			
		||||
		defaultHost := os.Getenv("DOCKER_HOST")
 | 
			
		||||
		if defaultHost == "" || *flDaemon {
 | 
			
		||||
			if runtime.GOOS != "windows" {
 | 
			
		||||
				// If we do not have a host, default to unix socket
 | 
			
		||||
				defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket)
 | 
			
		||||
			} else {
 | 
			
		||||
				// If we do not have a host, default to TCP socket on Windows
 | 
			
		||||
				defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		defaultHost, err := opts.ValidateHost(defaultHost)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if *flDaemon {
 | 
			
		||||
				logrus.Fatal(err)
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprint(os.Stderr, err)
 | 
			
		||||
			}
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
		flHosts = append(flHosts, defaultHost)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setDefaultConfFlag(flTrustKey, defaultTrustKeyFile)
 | 
			
		||||
 | 
			
		||||
	// Regardless of whether the user sets it to true or false, if they
 | 
			
		||||
	// specify --tlsverify at all then we need to turn on tls
 | 
			
		||||
	// *flTlsVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need to check that here as well
 | 
			
		||||
	if flag.IsSet("-tlsverify") || *flTLSVerify {
 | 
			
		||||
		*flTLS = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if *flDaemon {
 | 
			
		||||
		if *flHelp {
 | 
			
		||||
			flag.Usage()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		mainDaemon()
 | 
			
		||||
	if *flHelp {
 | 
			
		||||
		// if global flag --help is present, regardless of what other options and commands there are,
 | 
			
		||||
		// just print the usage.
 | 
			
		||||
		flag.Usage()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// From here on, we assume we're a client, not a server.
 | 
			
		||||
 | 
			
		||||
	if len(flHosts) > 1 {
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "Please specify only one -H")
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
 | 
			
		||||
 | 
			
		||||
	var tlsConfig *tls.Config
 | 
			
		||||
	if *flTLS {
 | 
			
		||||
		tlsOptions.InsecureSkipVerify = !*flTLSVerify
 | 
			
		||||
		if !flag.IsSet("-tlscert") {
 | 
			
		||||
			if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) {
 | 
			
		||||
				tlsOptions.CertFile = ""
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !flag.IsSet("-tlskey") {
 | 
			
		||||
			if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) {
 | 
			
		||||
				tlsOptions.KeyFile = ""
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		var err error
 | 
			
		||||
		tlsConfig, err = tlsconfig.Client(tlsOptions)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintln(stderr, err)
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	cli := client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], tlsConfig)
 | 
			
		||||
 | 
			
		||||
	if err := cli.Cmd(flag.Args()...); err != nil {
 | 
			
		||||
		if sterr, ok := err.(client.StatusError); ok {
 | 
			
		||||
	c := cli.New(clientCli, daemonCli)
 | 
			
		||||
	if err := c.Run(flag.Args()...); err != nil {
 | 
			
		||||
		if sterr, ok := err.(cli.StatusError); ok {
 | 
			
		||||
			if sterr.Status != "" {
 | 
			
		||||
				fmt.Fprintln(cli.Err(), sterr.Status)
 | 
			
		||||
				fmt.Fprintln(os.Stderr, sterr.Status)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
			}
 | 
			
		||||
			os.Exit(sterr.StatusCode)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintln(cli.Err(), err)
 | 
			
		||||
		fmt.Fprintln(os.Stderr, err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										170
									
								
								docker/flags.go
									
										
									
									
									
								
							
							
						
						
									
										170
									
								
								docker/flags.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,16 +1,10 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sort"
 | 
			
		||||
import flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/cliconfig"
 | 
			
		||||
	"github.com/docker/docker/opts"
 | 
			
		||||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/tlsconfig"
 | 
			
		||||
var (
 | 
			
		||||
	flHelp    = flag.Bool([]string{"h", "-help"}, false, "Print usage")
 | 
			
		||||
	flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type command struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -24,118 +18,46 @@ func (a byName) Len() int           { return len(a) }
 | 
			
		|||
func (a byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 | 
			
		||||
func (a byName) Less(i, j int) bool { return a[i].name < a[j].name }
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	dockerCertPath  = os.Getenv("DOCKER_CERT_PATH")
 | 
			
		||||
	dockerTlSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
 | 
			
		||||
 | 
			
		||||
	dockerCommands = []command{
 | 
			
		||||
		{"attach", "Attach to a running container"},
 | 
			
		||||
		{"build", "Build an image from a Dockerfile"},
 | 
			
		||||
		{"commit", "Create a new image from a container's changes"},
 | 
			
		||||
		{"cp", "Copy files/folders from a container to a HOSTDIR or to STDOUT"},
 | 
			
		||||
		{"create", "Create a new container"},
 | 
			
		||||
		{"diff", "Inspect changes on a container's filesystem"},
 | 
			
		||||
		{"events", "Get real time events from the server"},
 | 
			
		||||
		{"exec", "Run a command in a running container"},
 | 
			
		||||
		{"export", "Export a container's filesystem as a tar archive"},
 | 
			
		||||
		{"history", "Show the history of an image"},
 | 
			
		||||
		{"images", "List images"},
 | 
			
		||||
		{"import", "Import the contents from a tarball to create a filesystem image"},
 | 
			
		||||
		{"info", "Display system-wide information"},
 | 
			
		||||
		{"inspect", "Return low-level information on a container or image"},
 | 
			
		||||
		{"kill", "Kill a running container"},
 | 
			
		||||
		{"load", "Load an image from a tar archive or STDIN"},
 | 
			
		||||
		{"login", "Register or log in to a Docker registry"},
 | 
			
		||||
		{"logout", "Log out from a Docker registry"},
 | 
			
		||||
		{"logs", "Fetch the logs of a container"},
 | 
			
		||||
		{"port", "List port mappings or a specific mapping for the CONTAINER"},
 | 
			
		||||
		{"pause", "Pause all processes within a container"},
 | 
			
		||||
		{"ps", "List containers"},
 | 
			
		||||
		{"pull", "Pull an image or a repository from a registry"},
 | 
			
		||||
		{"push", "Push an image or a repository to a registry"},
 | 
			
		||||
		{"rename", "Rename a container"},
 | 
			
		||||
		{"restart", "Restart a running container"},
 | 
			
		||||
		{"rm", "Remove one or more containers"},
 | 
			
		||||
		{"rmi", "Remove one or more images"},
 | 
			
		||||
		{"run", "Run a command in a new container"},
 | 
			
		||||
		{"save", "Save an image(s) to a tar archive"},
 | 
			
		||||
		{"search", "Search the Docker Hub for images"},
 | 
			
		||||
		{"start", "Start one or more stopped containers"},
 | 
			
		||||
		{"stats", "Display a live stream of container(s) resource usage statistics"},
 | 
			
		||||
		{"stop", "Stop a running container"},
 | 
			
		||||
		{"tag", "Tag an image into a repository"},
 | 
			
		||||
		{"top", "Display the running processes of a container"},
 | 
			
		||||
		{"unpause", "Unpause all processes within a container"},
 | 
			
		||||
		{"version", "Show the Docker version information"},
 | 
			
		||||
		{"wait", "Block until a container stops, then print its exit code"},
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if dockerCertPath == "" {
 | 
			
		||||
		dockerCertPath = cliconfig.ConfigDir()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getDaemonConfDir() string {
 | 
			
		||||
	// TODO: update for Windows daemon
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		return cliconfig.ConfigDir()
 | 
			
		||||
	}
 | 
			
		||||
	return "/etc/docker"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	flConfigDir = flag.String([]string{"-config"}, cliconfig.ConfigDir(), "Location of client config files")
 | 
			
		||||
	flVersion   = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
 | 
			
		||||
	flDaemon    = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
 | 
			
		||||
	flDebug     = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
 | 
			
		||||
	flLogLevel  = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level")
 | 
			
		||||
	flTLS       = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by --tlsverify")
 | 
			
		||||
	flHelp      = flag.Bool([]string{"h", "-help"}, false, "Print usage")
 | 
			
		||||
	flTLSVerify = flag.Bool([]string{"-tlsverify"}, dockerTlSVerify, "Use TLS and verify the remote")
 | 
			
		||||
 | 
			
		||||
	// these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs
 | 
			
		||||
	tlsOptions tlsconfig.Options
 | 
			
		||||
	flTrustKey *string
 | 
			
		||||
	flHosts    []string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func setDefaultConfFlag(flag *string, def string) {
 | 
			
		||||
	if *flag == "" {
 | 
			
		||||
		if *flDaemon {
 | 
			
		||||
			*flag = filepath.Join(getDaemonConfDir(), def)
 | 
			
		||||
		} else {
 | 
			
		||||
			*flag = filepath.Join(cliconfig.ConfigDir(), def)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	var placeholderTrustKey string
 | 
			
		||||
	// TODO use flag flag.String([]string{"i", "-identity"}, "", "Path to libtrust key file")
 | 
			
		||||
	flTrustKey = &placeholderTrustKey
 | 
			
		||||
 | 
			
		||||
	flag.StringVar(&tlsOptions.CAFile, []string{"-tlscacert"}, filepath.Join(dockerCertPath, defaultCaFile), "Trust certs signed only by this CA")
 | 
			
		||||
	flag.StringVar(&tlsOptions.CertFile, []string{"-tlscert"}, filepath.Join(dockerCertPath, defaultCertFile), "Path to TLS certificate file")
 | 
			
		||||
	flag.StringVar(&tlsOptions.KeyFile, []string{"-tlskey"}, filepath.Join(dockerCertPath, defaultKeyFile), "Path to TLS key file")
 | 
			
		||||
	opts.HostListVar(&flHosts, []string{"H", "-host"}, "Daemon socket(s) to connect to")
 | 
			
		||||
 | 
			
		||||
	flag.Usage = func() {
 | 
			
		||||
		fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n\nA self-sufficient runtime for containers.\n\nOptions:\n")
 | 
			
		||||
 | 
			
		||||
		flag.CommandLine.SetOutput(os.Stdout)
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
 | 
			
		||||
		help := "\nCommands:\n"
 | 
			
		||||
 | 
			
		||||
		sort.Sort(byName(dockerCommands))
 | 
			
		||||
 | 
			
		||||
		for _, cmd := range dockerCommands {
 | 
			
		||||
			help += fmt.Sprintf("    %-10.10s%s\n", cmd.name, cmd.description)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		help += "\nRun 'docker COMMAND --help' for more information on a command."
 | 
			
		||||
		fmt.Fprintf(os.Stdout, "%s\n", help)
 | 
			
		||||
	}
 | 
			
		||||
// TODO(tiborvass): do not show 'daemon' on client-only binaries
 | 
			
		||||
// and deduplicate description in dockerCommands and cli subcommands
 | 
			
		||||
var dockerCommands = []command{
 | 
			
		||||
	{"attach", "Attach to a running container"},
 | 
			
		||||
	{"build", "Build an image from a Dockerfile"},
 | 
			
		||||
	{"commit", "Create a new image from a container's changes"},
 | 
			
		||||
	{"cp", "Copy files/folders from a container to a HOSTDIR or to STDOUT"},
 | 
			
		||||
	{"create", "Create a new container"},
 | 
			
		||||
	{"diff", "Inspect changes on a container's filesystem"},
 | 
			
		||||
	{"events", "Get real time events from the server"},
 | 
			
		||||
	{"exec", "Run a command in a running container"},
 | 
			
		||||
	{"export", "Export a container's filesystem as a tar archive"},
 | 
			
		||||
	{"history", "Show the history of an image"},
 | 
			
		||||
	{"images", "List images"},
 | 
			
		||||
	{"import", "Import the contents from a tarball to create a filesystem image"},
 | 
			
		||||
	{"info", "Display system-wide information"},
 | 
			
		||||
	{"inspect", "Return low-level information on a container or image"},
 | 
			
		||||
	{"kill", "Kill a running container"},
 | 
			
		||||
	{"load", "Load an image from a tar archive or STDIN"},
 | 
			
		||||
	{"login", "Register or log in to a Docker registry"},
 | 
			
		||||
	{"logout", "Log out from a Docker registry"},
 | 
			
		||||
	{"logs", "Fetch the logs of a container"},
 | 
			
		||||
	{"port", "List port mappings or a specific mapping for the CONTAINER"},
 | 
			
		||||
	{"pause", "Pause all processes within a container"},
 | 
			
		||||
	{"ps", "List containers"},
 | 
			
		||||
	{"pull", "Pull an image or a repository from a registry"},
 | 
			
		||||
	{"push", "Push an image or a repository to a registry"},
 | 
			
		||||
	{"rename", "Rename a container"},
 | 
			
		||||
	{"restart", "Restart a running container"},
 | 
			
		||||
	{"rm", "Remove one or more containers"},
 | 
			
		||||
	{"rmi", "Remove one or more images"},
 | 
			
		||||
	{"run", "Run a command in a new container"},
 | 
			
		||||
	{"save", "Save an image(s) to a tar archive"},
 | 
			
		||||
	{"search", "Search the Docker Hub for images"},
 | 
			
		||||
	{"start", "Start one or more stopped containers"},
 | 
			
		||||
	{"stats", "Display a live stream of container(s) resource usage statistics"},
 | 
			
		||||
	{"stop", "Stop a running container"},
 | 
			
		||||
	{"tag", "Tag an image into a repository"},
 | 
			
		||||
	{"top", "Display the running processes of a container"},
 | 
			
		||||
	{"unpause", "Unpause all processes within a container"},
 | 
			
		||||
	{"version", "Show the Docker version information"},
 | 
			
		||||
	{"wait", "Block until a container stops, then print its exit code"},
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func setLogLevel(lvl logrus.Level) {
 | 
			
		||||
	logrus.SetLevel(lvl)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initLogging(stderr io.Writer) {
 | 
			
		||||
	logrus.SetOutput(stderr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,8 @@ func (s *DockerDaemonSuite) TestCliProxyProxyTCPSock(c *check.C) {
 | 
			
		|||
		c.Fatal("could not find ip to connect to")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := s.d.Start("-H", "tcp://"+ip+":2375"); err != nil {
 | 
			
		||||
	s.d.GlobalFlags = []string{"-H", "tcp://" + ip + ":2375"}
 | 
			
		||||
	if err := s.d.Start(); err != nil {
 | 
			
		||||
		c.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								opts/hosts_unix.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								opts/hosts_unix.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package opts
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
var DefaultHost = fmt.Sprintf("unix://%s", DefaultUnixSocket)
 | 
			
		||||
							
								
								
									
										7
									
								
								opts/hosts_windows.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								opts/hosts_windows.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
// +build windows
 | 
			
		||||
 | 
			
		||||
package opts
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
var DefaultHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
 | 
			
		||||
							
								
								
									
										25
									
								
								opts/opts.go
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								opts/opts.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -32,37 +32,37 @@ var (
 | 
			
		|||
// ListVar Defines a flag with the specified names and usage, and put the value
 | 
			
		||||
// list into ListOpts that will hold the values.
 | 
			
		||||
func ListVar(values *[]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newListOptsRef(values, nil), names, usage)
 | 
			
		||||
	flag.Var(NewListOptsRef(values, nil), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MapVar Defines a flag with the specified names and usage, and put the value
 | 
			
		||||
// map into MapOpt that will hold the values (key,value).
 | 
			
		||||
func MapVar(values map[string]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newMapOpt(values, nil), names, usage)
 | 
			
		||||
	flag.Var(NewMapOpts(values, nil), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogOptsVar Defines a flag with the specified names and usage for --log-opts,
 | 
			
		||||
// and put the value map into MapOpt that will hold the values (key,value).
 | 
			
		||||
func LogOptsVar(values map[string]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newMapOpt(values, nil), names, usage)
 | 
			
		||||
	flag.Var(NewMapOpts(values, nil), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HostListVar Defines a flag with the specified names and usage and put the
 | 
			
		||||
// value into a ListOpts that will hold the values, validating the Host format.
 | 
			
		||||
func HostListVar(values *[]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newListOptsRef(values, ValidateHost), names, usage)
 | 
			
		||||
	flag.Var(NewListOptsRef(values, ValidateHost), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IPListVar Defines a flag with the specified names and usage and put the
 | 
			
		||||
// value into a ListOpts that will hold the values, validating the IP format.
 | 
			
		||||
func IPListVar(values *[]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newListOptsRef(values, ValidateIPAddress), names, usage)
 | 
			
		||||
	flag.Var(NewListOptsRef(values, ValidateIPAddress), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DNSSearchListVar Defines a flag with the specified names and usage and put the
 | 
			
		||||
// value into a ListOpts that will hold the values, validating the DNS search format.
 | 
			
		||||
func DNSSearchListVar(values *[]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newListOptsRef(values, ValidateDNSSearch), names, usage)
 | 
			
		||||
	flag.Var(NewListOptsRef(values, ValidateDNSSearch), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IPVar Defines a flag with the specified names and usage for IP and will use
 | 
			
		||||
| 
						 | 
				
			
			@ -74,12 +74,12 @@ func IPVar(value *net.IP, names []string, defaultValue, usage string) {
 | 
			
		|||
// LabelListVar Defines a flag with the specified names and usage and put the
 | 
			
		||||
// value into a ListOpts that will hold the values, validating the label format.
 | 
			
		||||
func LabelListVar(values *[]string, names []string, usage string) {
 | 
			
		||||
	flag.Var(newListOptsRef(values, ValidateLabel), names, usage)
 | 
			
		||||
	flag.Var(NewListOptsRef(values, ValidateLabel), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UlimitMapVar Defines a flag with the specified names and usage for --ulimit,
 | 
			
		||||
// and put the value map into a UlimitOpt that will hold the values.
 | 
			
		||||
func UlimitMapVar(values map[string]*ulimit.Ulimit, names []string, usage string) {
 | 
			
		||||
func UlimitMapVar(values *map[string]*ulimit.Ulimit, names []string, usage string) {
 | 
			
		||||
	flag.Var(NewUlimitOpt(values), names, usage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -92,10 +92,10 @@ type ListOpts struct {
 | 
			
		|||
// NewListOpts Create a new ListOpts with the specified validator.
 | 
			
		||||
func NewListOpts(validator ValidatorFctType) ListOpts {
 | 
			
		||||
	var values []string
 | 
			
		||||
	return *newListOptsRef(&values, validator)
 | 
			
		||||
	return *NewListOptsRef(&values, validator)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
 | 
			
		||||
func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
 | 
			
		||||
	return &ListOpts{
 | 
			
		||||
		values:    values,
 | 
			
		||||
		validator: validator,
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +191,10 @@ func (opts *MapOpts) String() string {
 | 
			
		|||
	return fmt.Sprintf("%v", map[string]string((opts.values)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMapOpt(values map[string]string, validator ValidatorFctType) *MapOpts {
 | 
			
		||||
func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
 | 
			
		||||
	if values == nil {
 | 
			
		||||
		values = make(map[string]string)
 | 
			
		||||
	}
 | 
			
		||||
	return &MapOpts{
 | 
			
		||||
		values:    values,
 | 
			
		||||
		validator: validator,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ func TestValidateIPAddress(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
func TestMapOpts(t *testing.T) {
 | 
			
		||||
	tmpMap := make(map[string]string)
 | 
			
		||||
	o := newMapOpt(tmpMap, logOptsValidator)
 | 
			
		||||
	o := NewMapOpts(tmpMap, logOptsValidator)
 | 
			
		||||
	o.Set("max-size=1")
 | 
			
		||||
	if o.String() != "map[max-size:1]" {
 | 
			
		||||
		t.Errorf("%s != [map[max-size:1]", o.String())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,10 +7,13 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
type UlimitOpt struct {
 | 
			
		||||
	values map[string]*ulimit.Ulimit
 | 
			
		||||
	values *map[string]*ulimit.Ulimit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewUlimitOpt(ref map[string]*ulimit.Ulimit) *UlimitOpt {
 | 
			
		||||
func NewUlimitOpt(ref *map[string]*ulimit.Ulimit) *UlimitOpt {
 | 
			
		||||
	if ref == nil {
 | 
			
		||||
		ref = &map[string]*ulimit.Ulimit{}
 | 
			
		||||
	}
 | 
			
		||||
	return &UlimitOpt{ref}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,14 +23,14 @@ func (o *UlimitOpt) Set(val string) error {
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	o.values[l.Name] = l
 | 
			
		||||
	(*o.values)[l.Name] = l
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *UlimitOpt) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	for _, v := range o.values {
 | 
			
		||||
	for _, v := range *o.values {
 | 
			
		||||
		out = append(out, v.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +39,7 @@ func (o *UlimitOpt) String() string {
 | 
			
		|||
 | 
			
		||||
func (o *UlimitOpt) GetList() []*ulimit.Ulimit {
 | 
			
		||||
	var ulimits []*ulimit.Ulimit
 | 
			
		||||
	for _, v := range o.values {
 | 
			
		||||
	for _, v := range *o.values {
 | 
			
		||||
		ulimits = append(ulimits, v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -526,7 +526,7 @@ func (f *FlagSet) PrintDefaults() {
 | 
			
		|||
				names = append(names, name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(names) > 0 {
 | 
			
		||||
		if len(names) > 0 && len(flag.Usage) > 0 {
 | 
			
		||||
			val := flag.DefValue
 | 
			
		||||
 | 
			
		||||
			if home != "" && strings.HasPrefix(val, home) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1143,3 +1143,53 @@ func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
 | 
			
		|||
	f.name = name
 | 
			
		||||
	f.errorHandling = errorHandling
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mergeVal struct {
 | 
			
		||||
	Value
 | 
			
		||||
	key  string
 | 
			
		||||
	fset *FlagSet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v mergeVal) Set(s string) error {
 | 
			
		||||
	return v.fset.Set(v.key, s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v mergeVal) IsBoolFlag() bool {
 | 
			
		||||
	if b, ok := v.Value.(boolFlag); ok {
 | 
			
		||||
		return b.IsBoolFlag()
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Merge(dest *FlagSet, flagsets ...*FlagSet) error {
 | 
			
		||||
	for _, fset := range flagsets {
 | 
			
		||||
		for k, f := range fset.formal {
 | 
			
		||||
			if _, ok := dest.formal[k]; ok {
 | 
			
		||||
				var err error
 | 
			
		||||
				if fset.name == "" {
 | 
			
		||||
					err = fmt.Errorf("flag redefined: %s", k)
 | 
			
		||||
				} else {
 | 
			
		||||
					err = fmt.Errorf("%s flag redefined: %s", fset.name, k)
 | 
			
		||||
				}
 | 
			
		||||
				fmt.Fprintln(fset.Out(), err.Error())
 | 
			
		||||
				// Happens only if flags are declared with identical names
 | 
			
		||||
				switch dest.errorHandling {
 | 
			
		||||
				case ContinueOnError:
 | 
			
		||||
					return err
 | 
			
		||||
				case ExitOnError:
 | 
			
		||||
					os.Exit(2)
 | 
			
		||||
				case PanicOnError:
 | 
			
		||||
					panic(err)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			newF := *f
 | 
			
		||||
			newF.Value = mergeVal{f.Value, k, fset}
 | 
			
		||||
			dest.formal[k] = &newF
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *FlagSet) IsEmpty() bool {
 | 
			
		||||
	return len(f.actual) == 0
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,11 +17,18 @@ import (
 | 
			
		|||
 | 
			
		||||
// Options represents the information needed to create client and server TLS configurations.
 | 
			
		||||
type Options struct {
 | 
			
		||||
	CAFile string
 | 
			
		||||
 | 
			
		||||
	// If either CertFile or KeyFile is empty, Client() will not load them
 | 
			
		||||
	// preventing the client from authenticating to the server.
 | 
			
		||||
	// However, Server() requires them and will error out if they are empty.
 | 
			
		||||
	CertFile string
 | 
			
		||||
	KeyFile  string
 | 
			
		||||
 | 
			
		||||
	// client-only option
 | 
			
		||||
	InsecureSkipVerify bool
 | 
			
		||||
	ClientAuth         tls.ClientAuthType
 | 
			
		||||
	CAFile             string
 | 
			
		||||
	CertFile           string
 | 
			
		||||
	KeyFile            string
 | 
			
		||||
	// server-only option
 | 
			
		||||
	ClientAuth tls.ClientAuthType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extra (server-side) accepted CBC cipher suites - will phase out in the future
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,11 +43,11 @@ var (
 | 
			
		|||
 | 
			
		||||
// InstallFlags adds command-line options to the top-level flag parser for
 | 
			
		||||
// the current process.
 | 
			
		||||
func (options *Options) InstallFlags() {
 | 
			
		||||
func (options *Options) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
 | 
			
		||||
	options.Mirrors = opts.NewListOpts(ValidateMirror)
 | 
			
		||||
	flag.Var(&options.Mirrors, []string{"-registry-mirror"}, "Preferred Docker registry mirror")
 | 
			
		||||
	cmd.Var(&options.Mirrors, []string{"-registry-mirror"}, usageFn("Preferred Docker registry mirror"))
 | 
			
		||||
	options.InsecureRegistries = opts.NewListOpts(ValidateIndexName)
 | 
			
		||||
	flag.Var(&options.InsecureRegistries, []string{"-insecure-registry"}, "Enable insecure registry communication")
 | 
			
		||||
	cmd.Var(&options.InsecureRegistries, []string{"-insecure-registry"}, usageFn("Enable insecure registry communication"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type netIPNet net.IPNet
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,6 @@ import (
 | 
			
		|||
	flag "github.com/docker/docker/pkg/mflag"
 | 
			
		||||
	"github.com/docker/docker/pkg/nat"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/pkg/ulimit"
 | 
			
		||||
	"github.com/docker/docker/pkg/units"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +47,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 | 
			
		|||
		flLabels  = opts.NewListOpts(opts.ValidateEnv)
 | 
			
		||||
		flDevices = opts.NewListOpts(opts.ValidateDevice)
 | 
			
		||||
 | 
			
		||||
		ulimits   = make(map[string]*ulimit.Ulimit)
 | 
			
		||||
		flUlimits = opts.NewUlimitOpt(ulimits)
 | 
			
		||||
		flUlimits = opts.NewUlimitOpt(nil)
 | 
			
		||||
 | 
			
		||||
		flPublish     = opts.NewListOpts(nil)
 | 
			
		||||
		flExpose      = opts.NewListOpts(nil)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue