--help option and help command should print to stdout not stderr

--help and help are successful commands so output should not go to error.

    QE teams have requested this change, also users doing docker help | less
    or docker run --help | less would expect this to work.

    Usage statement should only be printed when the user asks for it.
    Errors should print error message and then suggest the docker COMMAND --help
    command to see usage information.

    The current behaviour causes the user to have to search for the error message
    and sometimes scrolls right off the screen.  For example a error on a
    "docker run" command is very difficult to diagnose.

    Finally erros should always exit with a non 0 exit code, if the user
    makes a CLI error.

Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: rhatdan)
This commit is contained in:
Dan Walsh 2014-10-15 17:14:12 -04:00 committed by Michal Minar
parent 1510a324db
commit a2b529ead2
41 changed files with 390 additions and 89 deletions

View File

@ -75,8 +75,8 @@ func (cli *DockerCli) Cmd(args ...string) error {
if len(args) > 0 { if len(args) > 0 {
method, exists := cli.getMethod(args[0]) method, exists := cli.getMethod(args[0])
if !exists { if !exists {
fmt.Println("Error: Command not found:", args[0]) fmt.Fprintf(cli.err, "docker: '%s' is not a docker command. See 'docker --help'.\n", args[0])
return cli.CmdHelp() os.Exit(1)
} }
return method(args[1:]...) return method(args[1:]...)
} }
@ -90,9 +90,10 @@ func (cli *DockerCli) Subcmd(name, signature, description string) *flag.FlagSet
if flags.FlagCountUndeprecated() > 0 { if flags.FlagCountUndeprecated() > 0 {
options = "[OPTIONS] " options = "[OPTIONS] "
} }
fmt.Fprintf(cli.err, "\nUsage: docker %s %s%s\n\n%s\n\n", name, options, signature, description) fmt.Fprintf(cli.out, "\nUsage: docker %s %s%s\n\n%s\n\n", name, options, signature, description)
flags.SetOutput(cli.out)
flags.PrintDefaults() flags.PrintDefaults()
os.Exit(2) os.Exit(0)
} }
return flags return flags
} }

View File

@ -64,6 +64,8 @@ func (cli *DockerCli) CmdHelp(args ...string) error {
method, exists := cli.getMethod(args[0]) method, exists := cli.getMethod(args[0])
if !exists { if !exists {
fmt.Fprintf(cli.err, "Error: Command not found: %s\n", args[0]) fmt.Fprintf(cli.err, "Error: Command not found: %s\n", args[0])
fmt.Fprintf(cli.err, "docker: '%s' is not a docker command. See 'docker --help'.\n", args[0])
os.Exit(1)
} else { } else {
method("--help") method("--help")
return nil return nil
@ -83,13 +85,18 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
rm := cmd.Bool([]string{"#rm", "-rm"}, true, "Remove intermediate containers after a successful build") rm := cmd.Bool([]string{"#rm", "-rm"}, true, "Remove intermediate containers after a successful build")
forceRm := cmd.Bool([]string{"-force-rm"}, false, "Always remove intermediate containers, even after unsuccessful builds") forceRm := cmd.Bool([]string{"-force-rm"}, false, "Always remove intermediate containers, even after unsuccessful builds")
pull := cmd.Bool([]string{"-pull"}, false, "Always attempt to pull a newer version of the image") pull := cmd.Bool([]string{"-pull"}, false, "Always attempt to pull a newer version of the image")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
var ( var (
context archive.Archive context archive.Archive
@ -254,10 +261,16 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
cmd.StringVar(&username, []string{"u", "-username"}, "", "Username") cmd.StringVar(&username, []string{"u", "-username"}, "", "Username")
cmd.StringVar(&password, []string{"p", "-password"}, "", "Password") cmd.StringVar(&password, []string{"p", "-password"}, "", "Password")
cmd.StringVar(&email, []string{"e", "-email"}, "", "Email") cmd.StringVar(&email, []string{"e", "-email"}, "", "Email")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
err := cmd.Parse(args) err := cmd.Parse(args)
if err != nil { if err != nil {
return nil return nil
} }
if *help {
cmd.Usage()
return nil
}
serverAddress := registry.IndexServerAddress() serverAddress := registry.IndexServerAddress()
if len(cmd.Args()) > 0 { if len(cmd.Args()) > 0 {
serverAddress = cmd.Arg(0) serverAddress = cmd.Arg(0)
@ -390,13 +403,18 @@ func (cli *DockerCli) CmdLogout(args ...string) error {
// 'docker wait': block until a container stops // 'docker wait': block until a container stops
func (cli *DockerCli) CmdWait(args ...string) error { func (cli *DockerCli) CmdWait(args ...string) error {
cmd := cli.Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.") cmd := cli.Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var encounteredError error var encounteredError error
for _, name := range cmd.Args() { for _, name := range cmd.Args() {
status, err := waitForExit(cli, name) status, err := waitForExit(cli, name)
@ -416,10 +434,8 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 0) {
if cmd.NArg() > 0 { os.Exit(1)
cmd.Usage()
return nil
} }
if dockerversion.VERSION != "" { if dockerversion.VERSION != "" {
fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION) fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION)
@ -462,9 +478,8 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() > 0 { if cmd.BadArgs(flag.Exact, 0) {
cmd.Usage() os.Exit(1)
return nil
} }
body, _, err := readBody(cli.call("GET", "/info", nil, false)) body, _, err := readBody(cli.call("GET", "/info", nil, false))
@ -579,13 +594,18 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
func (cli *DockerCli) CmdStop(args ...string) error { func (cli *DockerCli) CmdStop(args ...string) error {
cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period") cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period")
nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.") nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
v := url.Values{} v := url.Values{}
v.Set("t", strconv.Itoa(*nSeconds)) v.Set("t", strconv.Itoa(*nSeconds))
@ -606,13 +626,18 @@ func (cli *DockerCli) CmdStop(args ...string) error {
func (cli *DockerCli) CmdRestart(args ...string) error { func (cli *DockerCli) CmdRestart(args ...string) error {
cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container") cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container")
nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.") nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
v := url.Values{} v := url.Values{}
v.Set("t", strconv.Itoa(*nSeconds)) v.Set("t", strconv.Itoa(*nSeconds))
@ -664,15 +689,19 @@ func (cli *DockerCli) CmdStart(args ...string) error {
cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container") cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container")
attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process") attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process")
openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN") openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
) )
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
hijacked := make(chan io.Closer) hijacked := make(chan io.Closer)
@ -778,10 +807,8 @@ func (cli *DockerCli) CmdUnpause(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
if cmd.NArg() != 1 { os.Exit(1)
cmd.Usage()
return nil
} }
var encounteredError error var encounteredError error
@ -801,10 +828,8 @@ func (cli *DockerCli) CmdPause(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
if cmd.NArg() != 1 { os.Exit(1)
cmd.Usage()
return nil
} }
var encounteredError error var encounteredError error
@ -822,13 +847,18 @@ func (cli *DockerCli) CmdPause(args ...string) error {
func (cli *DockerCli) CmdInspect(args ...string) error { func (cli *DockerCli) CmdInspect(args ...string) error {
cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image") cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image")
tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.") tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var tmpl *template.Template var tmpl *template.Template
if *tmplStr != "" { if *tmplStr != "" {
@ -901,13 +931,18 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
func (cli *DockerCli) CmdTop(args ...string) error { func (cli *DockerCli) CmdTop(args ...string) error {
cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container") cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() == 0 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
val := url.Values{} val := url.Values{}
if cmd.NArg() > 1 { if cmd.NArg() > 1 {
val.Set("ps_args", strings.Join(cmd.Args()[1:], " ")) val.Set("ps_args", strings.Join(cmd.Args()[1:], " "))
@ -936,13 +971,17 @@ func (cli *DockerCli) CmdTop(args ...string) error {
func (cli *DockerCli) CmdPort(args ...string) error { func (cli *DockerCli) CmdPort(args ...string) error {
cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT") cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false) stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false)
if err != nil { if err != nil {
@ -995,13 +1034,18 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image")
noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents")
) )
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
v := url.Values{} v := url.Values{}
if *force { if *force {
@ -1040,14 +1084,18 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image") cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image")
quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs") quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
body, _, err := readBody(cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false)) body, _, err := readBody(cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false))
if err != nil { if err != nil {
@ -1098,14 +1146,18 @@ func (cli *DockerCli) CmdRm(args ...string) error {
v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container") 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 and not the underlying container") link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container")
force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)") force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
val := url.Values{} val := url.Values{}
if *v { if *v {
@ -1136,14 +1188,18 @@ func (cli *DockerCli) CmdRm(args ...string) error {
func (cli *DockerCli) CmdKill(args ...string) error { func (cli *DockerCli) CmdKill(args ...string) error {
cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal") cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal")
signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container") signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var encounteredError error var encounteredError error
for _, name := range cmd.Args() { for _, name := range cmd.Args() {
@ -1159,15 +1215,18 @@ func (cli *DockerCli) CmdKill(args ...string) error {
func (cli *DockerCli) CmdImport(args ...string) error { func (cli *DockerCli) CmdImport(args ...string) error {
cmd := cli.Subcmd("import", "URL|- [REPOSITORY[:TAG]]", "Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it.") cmd := cli.Subcmd("import", "URL|- [REPOSITORY[:TAG]]", "Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it.")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var ( var (
v = url.Values{} v = url.Values{}
src = cmd.Arg(0) src = cmd.Arg(0)
@ -1201,15 +1260,19 @@ func (cli *DockerCli) CmdImport(args ...string) error {
func (cli *DockerCli) CmdPush(args ...string) error { func (cli *DockerCli) CmdPush(args ...string) error {
cmd := cli.Subcmd("push", "NAME[:TAG]", "Push an image or a repository to the registry") cmd := cli.Subcmd("push", "NAME[:TAG]", "Push an image or a repository to the registry")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
name := cmd.Arg(0) if *help {
if name == "" {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
name := cmd.Arg(0)
cli.LoadConfigFile() cli.LoadConfigFile()
@ -1267,14 +1330,19 @@ func (cli *DockerCli) CmdPush(args ...string) error {
func (cli *DockerCli) CmdPull(args ...string) error { func (cli *DockerCli) CmdPull(args ...string) error {
cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry") cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry")
allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
if cmd.NArg() != 1 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
var ( var (
v = url.Values{} v = url.Values{}
remote = cmd.Arg(0) remote = cmd.Arg(0)
@ -1338,6 +1406,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
// FIXME: --viz and --tree are deprecated. Remove them in a future version. // FIXME: --viz and --tree are deprecated. Remove them in a future version.
flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format") flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format")
flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format") flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
flFilter := opts.NewListOpts(nil) flFilter := opts.NewListOpts(nil)
cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')") cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")
@ -1345,10 +1414,13 @@ func (cli *DockerCli) CmdImages(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() > 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Max, 1) {
os.Exit(1)
}
// Consolidate all filter flags, and sanity check them early. // Consolidate all filter flags, and sanity check them early.
// They'll get process in the daemon/server. // They'll get process in the daemon/server.
@ -1578,6 +1650,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs") quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes") size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.") all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
noTrunc = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") noTrunc = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show only the latest created container, include non-running ones.") nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show only the latest created container, include non-running ones.")
since = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show only containers created since Id or Name, include non-running ones.") since = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show only containers created since Id or Name, include non-running ones.")
@ -1591,7 +1664,10 @@ func (cli *DockerCli) CmdPs(args ...string) error {
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
cmd.Usage()
return nil
}
if *last == -1 && *nLatest { if *last == -1 && *nLatest {
*last = 1 *last = 1
} }
@ -1732,20 +1808,28 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")") flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
cmd.Usage()
return nil
}
if cmd.BadArgs(flag.Max, 2) {
os.Exit(1)
}
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var ( var (
name = cmd.Arg(0) name = cmd.Arg(0)
repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1)) repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
) )
if name == "" || len(cmd.Args()) > 2 {
cmd.Usage()
return nil
}
//Check if the given image name can be resolved //Check if the given image name can be resolved
if repository != "" { if repository != "" {
if _, _, err := registry.ResolveRepositoryName(repository); err != nil { if _, _, err := registry.ResolveRepositoryName(repository); err != nil {
@ -1790,18 +1874,21 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
cmd := cli.Subcmd("events", "", "Get real time events from the server") cmd := cli.Subcmd("events", "", "Get real time events from the server")
since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp") since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp")
until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp") until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
flFilter := opts.NewListOpts(nil) flFilter := opts.NewListOpts(nil)
cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'event=stop')") cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'event=stop')")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
if cmd.NArg() != 0 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 0) {
os.Exit(1)
}
var ( var (
v = url.Values{} v = url.Values{}
loc = time.FixedZone(time.Now().Zone()) loc = time.FixedZone(time.Now().Zone())
@ -1849,14 +1936,18 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
func (cli *DockerCli) CmdExport(args ...string) error { func (cli *DockerCli) CmdExport(args ...string) error {
cmd := cli.Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive to STDOUT") cmd := cli.Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive to STDOUT")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
if cmd.NArg() != 1 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
if err := cli.stream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, cli.out, nil); err != nil { if err := cli.stream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, cli.out, nil); err != nil {
return err return err
@ -1866,13 +1957,18 @@ func (cli *DockerCli) CmdExport(args ...string) error {
func (cli *DockerCli) CmdDiff(args ...string) error { func (cli *DockerCli) CmdDiff(args ...string) error {
cmd := cli.Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem") cmd := cli.Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false)) body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false))
@ -1905,16 +2001,20 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)") tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
) )
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
name := cmd.Arg(0) name := cmd.Arg(0)
stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false) stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false)
@ -1948,16 +2048,19 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
cmd = cli.Subcmd("attach", "CONTAINER", "Attach to a running container") cmd = cli.Subcmd("attach", "CONTAINER", "Attach to a running container")
noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN") 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 (non-TTY mode only). SIGCHLD, SIGKILL, and SIGSTOP are not proxied.") proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process (non-TTY mode only). SIGCHLD, SIGKILL, and SIGSTOP are not proxied.")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
) )
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
if cmd.NArg() != 1 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
name := cmd.Arg(0) name := cmd.Arg(0)
stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false) stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false)
@ -2027,13 +2130,18 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds") trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds")
automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds") automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds")
stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars") stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 1) {
os.Exit(1)
}
v := url.Values{} v := url.Values{}
v.Set("term", cmd.Arg(0)) v.Set("term", cmd.Arg(0))
@ -2079,13 +2187,18 @@ type ports []int
func (cli *DockerCli) CmdTag(args ...string) error { func (cli *DockerCli) CmdTag(args ...string) error {
cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository") cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository")
force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force") force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if cmd.NArg() != 2 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 2) {
os.Exit(1)
}
var ( var (
repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1)) repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
@ -2158,6 +2271,7 @@ func newCIDFile(path string) (*cidFile, error) {
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
return nil, fmt.Errorf("Container ID file found, make sure the other container isn't running or delete %s", path) return nil, fmt.Errorf("Container ID file found, make sure the other container isn't running or delete %s", path)
} }
f, err := os.Create(path) f, err := os.Create(path)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to create the container ID file: %s", err) return nil, fmt.Errorf("Failed to create the container ID file: %s", err)
@ -2474,14 +2588,18 @@ func (cli *DockerCli) CmdRun(args ...string) error {
func (cli *DockerCli) CmdCp(args ...string) error { func (cli *DockerCli) CmdCp(args ...string) error {
cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH") cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil return nil
} }
if *help {
if cmd.NArg() != 2 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 2) {
os.Exit(1)
}
var copyData engine.Env var copyData engine.Env
info := strings.Split(cmd.Arg(0), ":") info := strings.Split(cmd.Arg(0), ":")
@ -2514,16 +2632,20 @@ func (cli *DockerCli) CmdCp(args ...string) error {
func (cli *DockerCli) CmdSave(args ...string) error { func (cli *DockerCli) CmdSave(args ...string) error {
cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)") cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)")
outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT") help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return err return err
} }
if cmd.NArg() < 1 { if *help {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
var ( var (
output io.Writer = cli.out output io.Writer = cli.out
@ -2558,15 +2680,18 @@ func (cli *DockerCli) CmdSave(args ...string) error {
func (cli *DockerCli) CmdLoad(args ...string) error { func (cli *DockerCli) CmdLoad(args ...string) error {
cmd := cli.Subcmd("load", "", "Load an image from a tar archive on STDIN") cmd := cli.Subcmd("load", "", "Load an image from a tar archive on STDIN")
infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN") infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN")
help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return err return err
} }
if *help {
if cmd.NArg() != 0 {
cmd.Usage() cmd.Usage()
return nil return nil
} }
if cmd.BadArgs(flag.Exact, 0) {
os.Exit(1)
}
var ( var (
input io.Reader = cli.in input io.Reader = cli.in
@ -2588,14 +2713,9 @@ func (cli *DockerCli) CmdExec(args ...string) error {
cmd := cli.Subcmd("exec", "CONTAINER COMMAND [ARG...]", "Run a command in a running container") cmd := cli.Subcmd("exec", "CONTAINER COMMAND [ARG...]", "Run a command in a running container")
execConfig, err := runconfig.ParseExec(cmd, args) execConfig, err := runconfig.ParseExec(cmd, args)
if err != nil { if execConfig.Container == "" || err != nil {
cmd.Usage()
return err return err
} }
if execConfig.Container == "" {
cmd.Usage()
return nil
}
stream, _, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, false) stream, _, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, false)
if err != nil { if err != nil {

View File

@ -36,6 +36,7 @@ var (
flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level") flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level")
flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by --tlsverify flag") flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by --tlsverify flag")
flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage")
flTlsVerify = flag.Bool([]string{"-tlsverify"}, dockerTlsVerify, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") flTlsVerify = flag.Bool([]string{"-tlsverify"}, dockerTlsVerify, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)")
// these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs // these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs
@ -57,8 +58,9 @@ func init() {
opts.HostListVar(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode or connect to in client mode, specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") opts.HostListVar(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode or connect to in client mode, specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.")
flag.Usage = func() { flag.Usage = func() {
fmt.Fprint(os.Stderr, "Usage: docker [OPTIONS] COMMAND [arg...]\n\nA self-sufficient runtime for linux containers.\n\nOptions:\n") fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n\nA self-sufficient runtime for linux containers.\n\nOptions:\n")
flag.CommandLine.SetOutput(os.Stdout)
flag.PrintDefaults() flag.PrintDefaults()
help := "\nCommands:\n" help := "\nCommands:\n"
@ -105,6 +107,6 @@ func init() {
help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1]) help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1])
} }
help += "\nRun 'docker COMMAND --help' for more information on a command." help += "\nRun 'docker COMMAND --help' for more information on a command."
fmt.Fprintf(os.Stderr, "%s\n", help) fmt.Fprintf(os.Stdout, "%s\n", help)
} }
} }

View File

@ -6,6 +6,7 @@ docker-attach - Attach to a running container
# SYNOPSIS # SYNOPSIS
**docker attach** **docker attach**
[**--help**]/
[**--no-stdin**[=*false*]] [**--no-stdin**[=*false*]]
[**--sig-proxy**[=*true*]] [**--sig-proxy**[=*true*]]
CONTAINER CONTAINER
@ -24,6 +25,9 @@ It is forbidden to redirect the standard input of a docker attach command while
attaching to a tty-enabled container (i.e.: launched with -t`). attaching to a tty-enabled container (i.e.: launched with -t`).
# OPTIONS # OPTIONS
**--help**
Print usage statement
**--no-stdin**=*true*|*false* **--no-stdin**=*true*|*false*
Do not attach STDIN. The default is *false*. Do not attach STDIN. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-build - Build a new image from the source code at PATH
# SYNOPSIS # SYNOPSIS
**docker build** **docker build**
[**--help**]
[**--force-rm**[=*false*]] [**--force-rm**[=*false*]]
[**--no-cache**[=*false*]] [**--no-cache**[=*false*]]
[**-q**|**--quiet**[=*false*]] [**-q**|**--quiet**[=*false*]]
@ -36,6 +37,9 @@ as context.
**--no-cache**=*true*|*false* **--no-cache**=*true*|*false*
Do not use cache when building the image. The default is *false*. Do not use cache when building the image. The default is *false*.
**--help**
Print usage statement
**-q**, **--quiet**=*true*|*false* **-q**, **--quiet**=*true*|*false*
Suppress the verbose output generated by the containers. The default is *false*. Suppress the verbose output generated by the containers. The default is *false*.

View File

@ -7,6 +7,7 @@ docker-commit - Create a new image from a container's changes
# SYNOPSIS # SYNOPSIS
**docker commit** **docker commit**
[**-a**|**--author**[=*AUTHOR*]] [**-a**|**--author**[=*AUTHOR*]]
[**--help**]
[**-m**|**--message**[=*MESSAGE*]] [**-m**|**--message**[=*MESSAGE*]]
[**-p**|**--pause**[=*true*]] [**-p**|**--pause**[=*true*]]
CONTAINER [REPOSITORY[:TAG]] CONTAINER [REPOSITORY[:TAG]]
@ -18,6 +19,9 @@ Using an existing container's name or ID you can create a new image.
**-a**, **--author**="" **-a**, **--author**=""
Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
**--help**
Print usage statement
**-m**, **--message**="" **-m**, **--message**=""
Commit message Commit message

View File

@ -6,6 +6,7 @@ docker-cp - Copy files/folders from the PATH to the HOSTPATH
# SYNOPSIS # SYNOPSIS
**docker cp** **docker cp**
[**--help**]
CONTAINER:PATH HOSTPATH CONTAINER:PATH HOSTPATH
# DESCRIPTION # DESCRIPTION
@ -14,7 +15,8 @@ path. Paths are relative to the root of the filesystem. Files
can be copied from a running or stopped container. can be copied from a running or stopped container.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES
An important shell script file, created in a bash shell, is copied from An important shell script file, created in a bash shell, is copied from

View File

@ -21,6 +21,7 @@ docker-create - Create a new container
[**--env-file**[=*[]*]] [**--env-file**[=*[]*]]
[**--expose**[=*[]*]] [**--expose**[=*[]*]]
[**-h**|**--hostname**[=*HOSTNAME*]] [**-h**|**--hostname**[=*HOSTNAME*]]
[**--help**]
[**-i**|**--interactive**[=*false*]] [**-i**|**--interactive**[=*false*]]
[**--ipc**[=*IPC*]] [**--ipc**[=*IPC*]]
[**--link**[=*[]*]] [**--link**[=*[]*]]
@ -87,6 +88,9 @@ IMAGE [COMMAND] [ARG...]
**-h**, **--hostname**="" **-h**, **--hostname**=""
Container host name Container host name
**--help**
Print usage statement
**-i**, **--interactive**=*true*|*false* **-i**, **--interactive**=*true*|*false*
Keep STDIN open even if not attached. The default is *false*. Keep STDIN open even if not attached. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-diff - Inspect changes on a container's filesystem
# SYNOPSIS # SYNOPSIS
**docker diff** **docker diff**
[**--help**]
CONTAINER CONTAINER
# DESCRIPTION # DESCRIPTION
@ -14,7 +15,8 @@ shortened container ID or the container name set using
**docker run --name** option. **docker run --name** option.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES
Inspect the changes to on a nginx container: Inspect the changes to on a nginx container:

View File

@ -6,6 +6,7 @@ docker-events - Get real time events from the server
# SYNOPSIS # SYNOPSIS
**docker events** **docker events**
[**--help**]
[**--since**[=*SINCE*]] [**--since**[=*SINCE*]]
[**--until**[=*UNTIL*]] [**--until**[=*UNTIL*]]
@ -23,6 +24,9 @@ and Docker images will report:
untag, delete untag, delete
# OPTIONS # OPTIONS
**--help**
Print usage statement
**--since**="" **--since**=""
Show all events created since timestamp Show all events created since timestamp

View File

@ -7,6 +7,7 @@ docker-exec - Run a command in a running container
# SYNOPSIS # SYNOPSIS
**docker exec** **docker exec**
[**-d**|**--detach**[=*false*]] [**-d**|**--detach**[=*false*]]
[**--help**]
[**-i**|**--interactive**[=*false*]] [**-i**|**--interactive**[=*false*]]
[**-t**|**--tty**[=*false*]] [**-t**|**--tty**[=*false*]]
CONTAINER COMMAND [ARG...] CONTAINER COMMAND [ARG...]
@ -25,6 +26,9 @@ container is unpaused, and then run
**-d**, **--detach**=*true*|*false* **-d**, **--detach**=*true*|*false*
Detached mode: run command in the background. The default is *false*. Detached mode: run command in the background. The default is *false*.
**--help**
Print usage statement
**-i**, **--interactive**=*true*|*false* **-i**, **--interactive**=*true*|*false*
Keep STDIN open even if not attached. The default is *false*. Keep STDIN open even if not attached. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-export - Export the contents of a filesystem as a tar archive to STDOUT
# SYNOPSIS # SYNOPSIS
**docker export** **docker export**
[**--help**]
CONTAINER CONTAINER
# DESCRIPTION # DESCRIPTION
@ -14,7 +15,8 @@ container ID or container name. The output is exported to STDOUT and can be
redirected to a tar file. redirected to a tar file.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES
Export the contents of the container called angry_bell to a tar file Export the contents of the container called angry_bell to a tar file

View File

@ -6,6 +6,7 @@ docker-history - Show the history of an image
# SYNOPSIS # SYNOPSIS
**docker history** **docker history**
[**--help**]
[**--no-trunc**[=*false*]] [**--no-trunc**[=*false*]]
[**-q**|**--quiet**[=*false*]] [**-q**|**--quiet**[=*false*]]
IMAGE IMAGE
@ -15,6 +16,9 @@ IMAGE
Show the history of when and how an image was created. Show the history of when and how an image was created.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**--no-trunc**=*true*|*false* **--no-trunc**=*true*|*false*
Don't truncate output. The default is *false*. Don't truncate output. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-images - List images
# SYNOPSIS # SYNOPSIS
**docker images** **docker images**
[**--help**]
[**-a**|**--all**[=*false*]] [**-a**|**--all**[=*false*]]
[**-f**|**--filter**[=*[]*]] [**-f**|**--filter**[=*[]*]]
[**--no-trunc**[=*false*]] [**--no-trunc**[=*false*]]
@ -35,6 +36,9 @@ versions.
**-f**, **--filter**=[] **-f**, **--filter**=[]
Provide filter values (i.e. 'dangling=true') Provide filter values (i.e. 'dangling=true')
**--help**
Print usage statement
**--no-trunc**=*true*|*false* **--no-trunc**=*true*|*false*
Don't truncate output. The default is *false*. Don't truncate output. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-import - Create an empty filesystem image and import the contents of the
# SYNOPSIS # SYNOPSIS
**docker import** **docker import**
[**--help**]
URL|- [REPOSITORY[:TAG]] URL|- [REPOSITORY[:TAG]]
# DESCRIPTION # DESCRIPTION
@ -13,7 +14,8 @@ Create a new filesystem image from the contents of a tarball (`.tar`,
`.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. `.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES

View File

@ -6,6 +6,7 @@ docker-info - Display system-wide information
# SYNOPSIS # SYNOPSIS
**docker info** **docker info**
[**--help**]
# DESCRIPTION # DESCRIPTION
@ -20,7 +21,8 @@ allocates a certain amount of data space and meta data space from the space
available on the volume where `/var/lib/docker` is mounted. available on the volume where `/var/lib/docker` is mounted.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES

View File

@ -6,6 +6,7 @@ docker-inspect - Return low-level information on a container or image
# SYNOPSIS # SYNOPSIS
**docker inspect** **docker inspect**
[**--help**]
[**-f**|**--format**[=*FORMAT*]] [**-f**|**--format**[=*FORMAT*]]
CONTAINER|IMAGE [CONTAINER|IMAGE...] CONTAINER|IMAGE [CONTAINER|IMAGE...]
@ -17,6 +18,9 @@ array. If a format is specified, the given template will be executed for
each result. each result.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-f**, **--format**="" **-f**, **--format**=""
Format the output using the given go template. Format the output using the given go template.

View File

@ -6,6 +6,7 @@ docker-kill - Kill a running container using SIGKILL or a specified signal
# SYNOPSIS # SYNOPSIS
**docker kill** **docker kill**
[**--help**]
[**-s**|**--signal**[=*"KILL"*]] [**-s**|**--signal**[=*"KILL"*]]
CONTAINER [CONTAINER...] CONTAINER [CONTAINER...]
@ -15,6 +16,9 @@ The main process inside each container specified will be sent SIGKILL,
or any signal specified with option --signal. or any signal specified with option --signal.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-s**, **--signal**="KILL" **-s**, **--signal**="KILL"
Signal to send to the container Signal to send to the container

View File

@ -6,6 +6,7 @@ docker-load - Load an image from a tar archive on STDIN
# SYNOPSIS # SYNOPSIS
**docker load** **docker load**
[**--help**]
[**-i**|**--input**[=*INPUT*]] [**-i**|**--input**[=*INPUT*]]
@ -15,6 +16,9 @@ Loads a tarred repository from a file or the standard input stream.
Restores both images and tags. Restores both images and tags.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-i**, **--input**="" **-i**, **--input**=""
Read from a tar archive file, instead of STDIN Read from a tar archive file, instead of STDIN

View File

@ -7,6 +7,7 @@ docker-login - Register or log in to a Docker registry server, if no server is s
# SYNOPSIS # SYNOPSIS
**docker login** **docker login**
[**-e**|**--email**[=*EMAIL*]] [**-e**|**--email**[=*EMAIL*]]
[**--help**]
[**-p**|**--password**[=*PASSWORD*]] [**-p**|**--password**[=*PASSWORD*]]
[**-u**|**--username**[=*USERNAME*]] [**-u**|**--username**[=*USERNAME*]]
[SERVER] [SERVER]
@ -20,6 +21,9 @@ login to a private registry you can specify this by adding the server name.
**-e**, **--email**="" **-e**, **--email**=""
Email Email
**--help**
Print usage statement
**-p**, **--password**="" **-p**, **--password**=""
Password Password

View File

@ -7,6 +7,7 @@ docker-logs - Fetch the logs of a container
# SYNOPSIS # SYNOPSIS
**docker logs** **docker logs**
[**-f**|**--follow**[=*false*]] [**-f**|**--follow**[=*false*]]
[**--help**]
[**-t**|**--timestamps**[=*false*]] [**-t**|**--timestamps**[=*false*]]
[**--tail**[=*"all"*]] [**--tail**[=*"all"*]]
CONTAINER CONTAINER
@ -22,6 +23,9 @@ The **docker logs --follow** command combines commands **docker logs** and
then continue streaming new output from the containers stdout and stderr. then continue streaming new output from the containers stdout and stderr.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-f**, **--follow**=*true*|*false* **-f**, **--follow**=*true*|*false*
Follow log output. The default is *false*. Follow log output. The default is *false*.

View File

@ -6,13 +6,15 @@ docker-port - List port mappings for the CONTAINER, or lookup the public-facing
# SYNOPSIS # SYNOPSIS
**docker port** **docker port**
[**--help**]
CONTAINER [PRIVATE_PORT[/PROTO]] CONTAINER [PRIVATE_PORT[/PROTO]]
# DESCRIPTION # DESCRIPTION
List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES
You can find out all the ports mapped by not specifying a `PRIVATE_PORT`, or You can find out all the ports mapped by not specifying a `PRIVATE_PORT`, or

View File

@ -8,6 +8,7 @@ docker-ps - List containers
**docker ps** **docker ps**
[**-a**|**--all**[=*false*]] [**-a**|**--all**[=*false*]]
[**--before**[=*BEFORE*]] [**--before**[=*BEFORE*]]
[**--help**]
[**-f**|**--filter**[=*[]*]] [**-f**|**--filter**[=*[]*]]
[**-l**|**--latest**[=*false*]] [**-l**|**--latest**[=*false*]]
[**-n**[=*-1*]] [**-n**[=*-1*]]
@ -29,6 +30,9 @@ the running containers.
**--before**="" **--before**=""
Show only container created before Id or Name, include non-running ones. Show only container created before Id or Name, include non-running ones.
**--help**
Print usage statement
**-f**, **--filter**=[] **-f**, **--filter**=[]
Provide filter values. Valid filters: Provide filter values. Valid filters:
exited=<int> - containers with exit code of <int> exited=<int> - containers with exit code of <int>

View File

@ -7,6 +7,7 @@ docker-pull - Pull an image or a repository from the registry
# SYNOPSIS # SYNOPSIS
**docker pull** **docker pull**
[**-a**|**--all-tags**[=*false*]] [**-a**|**--all-tags**[=*false*]]
[**--help**]
NAME[:TAG] NAME[:TAG]
# DESCRIPTION # DESCRIPTION
@ -19,8 +20,10 @@ It is also possible to specify a non-default registry to pull from.
# OPTIONS # OPTIONS
**-a**, **--all-tags**=*true*|*false* **-a**, **--all-tags**=*true*|*false*
Download all tagged images in the repository. The default is *false*. Download all tagged images in the repository. The default is *false*.
**--help**
Print usage statement
# EXAMPLES # EXAMPLE
# Pull a repository with multiple images # Pull a repository with multiple images
# Note that if the image is previously downloaded then the status would be # Note that if the image is previously downloaded then the status would be

View File

@ -6,6 +6,7 @@ docker-push - Push an image or a repository to the registry
# SYNOPSIS # SYNOPSIS
**docker push** **docker push**
[**--help**]
NAME[:TAG] NAME[:TAG]
# DESCRIPTION # DESCRIPTION
@ -15,7 +16,8 @@ image can be pushed to another, perhaps private, registry as demonstrated in
the example below. the example below.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES

View File

@ -6,6 +6,7 @@ docker-restart - Restart a running container
# SYNOPSIS # SYNOPSIS
**docker restart** **docker restart**
[**--help**]
[**-t**|**--time**[=*10*]] [**-t**|**--time**[=*10*]]
CONTAINER [CONTAINER...] CONTAINER [CONTAINER...]
@ -13,6 +14,9 @@ CONTAINER [CONTAINER...]
Restart each container listed. Restart each container listed.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-t**, **--time**=10 **-t**, **--time**=10
Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds. Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.

View File

@ -19,6 +19,9 @@ remove a running container unless you use the \fB-f\fR option. To see all
containers on a host use the **docker ps -a** command. containers on a host use the **docker ps -a** command.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-f**, **--force**=*true*|*false* **-f**, **--force**=*true*|*false*
Force the removal of a running container (uses SIGKILL). The default is *false*. Force the removal of a running container (uses SIGKILL). The default is *false*.

View File

@ -7,6 +7,7 @@ docker-rmi - Remove one or more images
# SYNOPSIS # SYNOPSIS
**docker rmi** **docker rmi**
[**-f**|**--force**[=*false*]] [**-f**|**--force**[=*false*]]
[**--help**]
[**--no-prune**[=*false*]] [**--no-prune**[=*false*]]
IMAGE [IMAGE...] IMAGE [IMAGE...]
@ -21,6 +22,9 @@ use the **docker images** command.
**-f**, **--force**=*true*|*false* **-f**, **--force**=*true*|*false*
Force removal of the image. The default is *false*. Force removal of the image. The default is *false*.
**--help**
Print usage statement
**--no-prune**=*true*|*false* **--no-prune**=*true*|*false*
Do not delete untagged parents. The default is *false*. Do not delete untagged parents. The default is *false*.

View File

@ -22,6 +22,7 @@ docker-run - Run a command in a new container
[**--env-file**[=*[]*]] [**--env-file**[=*[]*]]
[**--expose**[=*[]*]] [**--expose**[=*[]*]]
[**-h**|**--hostname**[=*HOSTNAME*]] [**-h**|**--hostname**[=*HOSTNAME*]]
[**--help**]
[**-i**|**--interactive**[=*false*]] [**-i**|**--interactive**[=*false*]]
[**--ipc**[=*IPC*]] [**--ipc**[=*IPC*]]
[**--link**[=*[]*]] [**--link**[=*[]*]]
@ -153,6 +154,9 @@ ENTRYPOINT.
Sets the container host name that is available inside the container. Sets the container host name that is available inside the container.
**--help**
Print usage statement
**-i**, **--interactive**=*true*|*false* **-i**, **--interactive**=*true*|*false*
Keep STDIN open even if not attached. The default is *false*. Keep STDIN open even if not attached. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-save - Save an image(s) to a tar archive (streamed to STDOUT by default)
# SYNOPSIS # SYNOPSIS
**docker save** **docker save**
[**--help**]
[**-o**|**--output**[=*OUTPUT*]] [**-o**|**--output**[=*OUTPUT*]]
IMAGE [IMAGE...] IMAGE [IMAGE...]
@ -16,6 +17,9 @@ parent layers, and all tags + versions, or specified repo:tag.
Stream to a file instead of STDOUT by using **-o**. Stream to a file instead of STDOUT by using **-o**.
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-o**, **--output**="" **-o**, **--output**=""
Write to a file, instead of STDOUT Write to a file, instead of STDOUT

View File

@ -7,6 +7,7 @@ docker-search - Search the Docker Hub for images
# SYNOPSIS # SYNOPSIS
**docker search** **docker search**
[**--automated**[=*false*]] [**--automated**[=*false*]]
[**--help**]
[**--no-trunc**[=*false*]] [**--no-trunc**[=*false*]]
[**-s**|**--stars**[=*0*]] [**-s**|**--stars**[=*0*]]
TERM TERM
@ -22,6 +23,9 @@ is automated.
**--automated**=*true*|*false* **--automated**=*true*|*false*
Only show automated builds. The default is *false*. Only show automated builds. The default is *false*.
**--help**
Print usage statement
**--no-trunc**=*true*|*false* **--no-trunc**=*true*|*false*
Don't truncate output. The default is *false*. Don't truncate output. The default is *false*.

View File

@ -7,6 +7,7 @@ docker-start - Restart a stopped container
# SYNOPSIS # SYNOPSIS
**docker start** **docker start**
[**-a**|**--attach**[=*false*]] [**-a**|**--attach**[=*false*]]
[**--help**]
[**-i**|**--interactive**[=*false*]] [**-i**|**--interactive**[=*false*]]
CONTAINER [CONTAINER...] CONTAINER [CONTAINER...]
@ -18,6 +19,9 @@ Start a stopped container.
**-a**, **--attach**=*true*|*false* **-a**, **--attach**=*true*|*false*
Attach container's STDOUT and STDERR and forward all signals to the process. The default is *false*. Attach container's STDOUT and STDERR and forward all signals to the process. The default is *false*.
**--help**
Print usage statement
**-i**, **--interactive**=*true*|*false* **-i**, **--interactive**=*true*|*false*
Attach container's STDIN. The default is *false*. Attach container's STDIN. The default is *false*.

View File

@ -6,6 +6,7 @@ docker-stop - Stop a running container by sending SIGTERM and then SIGKILL after
# SYNOPSIS # SYNOPSIS
**docker stop** **docker stop**
[**--help**]
[**-t**|**--time**[=*10*]] [**-t**|**--time**[=*10*]]
CONTAINER [CONTAINER...] CONTAINER [CONTAINER...]
@ -14,6 +15,9 @@ Stop a running container (Send SIGTERM, and then SIGKILL after
grace period) grace period)
# OPTIONS # OPTIONS
**--help**
Print usage statement
**-t**, **--time**=10 **-t**, **--time**=10
Number of seconds to wait for the container to stop before killing it. Default is 10 seconds. Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.

View File

@ -7,6 +7,7 @@ docker-tag - Tag an image into a repository
# SYNOPSIS # SYNOPSIS
**docker tag** **docker tag**
[**-f**|**--force**[=*false*]] [**-f**|**--force**[=*false*]]
[**--help**]
IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
# DESCRIPTION # DESCRIPTION

View File

@ -6,6 +6,7 @@ docker-top - Display the running processes of a container
# SYNOPSIS # SYNOPSIS
**docker top** **docker top**
[**--help**]
CONTAINER [ps OPTIONS] CONTAINER [ps OPTIONS]
# DESCRIPTION # DESCRIPTION
@ -14,7 +15,8 @@ Look up the running process of the container. ps-OPTION can be any of the
options you would pass to a Linux ps command. options you would pass to a Linux ps command.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES

View File

@ -6,6 +6,7 @@ docker-wait - Block until a container stops, then print its exit code.
# SYNOPSIS # SYNOPSIS
**docker wait** **docker wait**
[**--help**]
CONTAINER [CONTAINER...] CONTAINER [CONTAINER...]
# DESCRIPTION # DESCRIPTION
@ -13,7 +14,8 @@ CONTAINER [CONTAINER...]
Block until a container stops, then print its exit code. Block until a container stops, then print its exit code.
# OPTIONS # OPTIONS
There are no available options. **--help**
Print usage statement
# EXAMPLES # EXAMPLES

View File

@ -26,6 +26,9 @@ To see the man page for a command run **man docker <command>**.
**-D**=*true*|*false* **-D**=*true*|*false*
Enable debug mode. Default is false. Enable debug mode. Default is false.
**--help**
Print usage statement
**-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host:port] to bind or **-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host:port] to bind or
unix://[/path/to/socket] to use. unix://[/path/to/socket] to use.
The socket(s) to bind to in daemon mode specified using one or more The socket(s) to bind to in daemon mode specified using one or more

View File

@ -15,6 +15,19 @@ or execute `docker help`:
... ...
## Help
To list the help on any command just execute the command, followed by the `--help` option.
$ sudo docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
-a, --attach=[] Attach to STDIN, STDOUT or STDERR.
-c, --cpu-shares=0 CPU shares (relative weight)
...
## Option types ## Option types
Single character commandline options can be combined, so rather than Single character commandline options can be combined, so rather than

View File

@ -410,6 +410,47 @@ func IsSet(name string) bool {
return CommandLine.IsSet(name) return CommandLine.IsSet(name)
} }
// Indicator used to pass to BadArgs function
const (
Exact = 1
Max = 2
Min = 3
)
// Bad Args takes two arguments.
// The first one indicates whether the number of arguments should, be
// A Minimal number of arguments, a maximum number of arguments or
// The exact number of arguments required
// If the actuall number of arguments is not valid and error message
// prints and true is returned, otherwise false is returned
func (f *FlagSet) BadArgs(arg_type, nargs int) bool {
if arg_type == Max && f.NArg() > nargs {
if nargs == 1 {
fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
} else {
fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
}
return true
}
if arg_type == Exact && f.NArg() != nargs {
if nargs == 1 {
fmt.Fprintf(f.out(), "docker: '%s' requires 1 argument. See 'docker %s --help'.\n", f.name, f.name)
} else {
fmt.Fprintf(f.out(), "docker: '%s' requires %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
}
return true
}
if arg_type == Min && f.NArg() < nargs {
if nargs == 1 {
fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
} else {
fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
}
return true
}
return false
}
// Set sets the value of the named flag. // Set sets the value of the named flag.
func (f *FlagSet) Set(name, value string) error { func (f *FlagSet) Set(name, value string) error {
flag, ok := f.formal[name] flag, ok := f.formal[name]
@ -483,7 +524,7 @@ func defaultUsage(f *FlagSet) {
// Usage prints to standard error a usage message documenting all defined command-line flags. // Usage prints to standard error a usage message documenting all defined command-line flags.
// The function is a variable that may be changed to point to a custom function. // The function is a variable that may be changed to point to a custom function.
var Usage = func() { var Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0])
PrintDefaults() PrintDefaults()
} }
@ -789,7 +830,7 @@ func Var(value Value, names []string, usage string) {
func (f *FlagSet) failf(format string, a ...interface{}) error { func (f *FlagSet) failf(format string, a ...interface{}) error {
err := fmt.Errorf(format, a...) err := fmt.Errorf(format, a...)
fmt.Fprintln(f.out(), err) fmt.Fprintln(f.out(), err)
f.usage() fmt.Fprintf(f.out(), "See 'docker %s --help'.\n", f.name)
return err return err
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"os"
) )
type ExecConfig struct { type ExecConfig struct {
@ -45,17 +46,22 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached") flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY") flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: run command in the background") flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: run command in the background")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
execCmd []string execCmd []string
container string container string
) )
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil, err return nil, err
} }
parsedArgs := cmd.Args() if *help {
if len(parsedArgs) < 2 { cmd.Usage()
return nil, fmt.Errorf("not enough arguments to create exec command") return nil, nil
}
if cmd.BadArgs(flag.Min, 2) {
os.Exit(1)
} }
container = cmd.Arg(0) container = cmd.Arg(0)
parsedArgs := cmd.Args()
execCmd = parsedArgs[1:] execCmd = parsedArgs[1:]
execConfig := &ExecConfig{ execConfig := &ExecConfig{

View File

@ -2,6 +2,7 @@ package runconfig
import ( import (
"fmt" "fmt"
"os"
"path" "path"
"strconv" "strconv"
"strings" "strings"
@ -61,6 +62,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)") flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flIpcMode = cmd.String([]string{"-ipc"}, "", "Default is to create a private IPC namespace (POSIX SysV IPC) for the container\n'container:<name|id>': reuses another container shared memory, semaphores and message queues\n'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.") flIpcMode = cmd.String([]string{"-ipc"}, "", "Default is to create a private IPC namespace (POSIX SysV IPC) for the container\n'container:<name|id>': reuses another container shared memory, semaphores and message queues\n'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.")
flRestartPolicy = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)") flRestartPolicy = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)")
help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
) )
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR.") cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR.")
@ -86,6 +88,13 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
if err := cmd.Parse(args); err != nil { if err := cmd.Parse(args); err != nil {
return nil, nil, cmd, err return nil, nil, cmd, err
} }
if *help {
cmd.Usage()
return nil, nil, cmd, nil
}
if cmd.BadArgs(flag.Min, 1) {
os.Exit(1)
}
// Validate input params // Validate input params
if *flWorkingDir != "" && !path.IsAbs(*flWorkingDir) { if *flWorkingDir != "" && !path.IsAbs(*flWorkingDir) {
@ -156,11 +165,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
parsedArgs = cmd.Args() parsedArgs = cmd.Args()
runCmd []string runCmd []string
entrypoint []string entrypoint []string
image string
)
if len(parsedArgs) >= 1 {
image = cmd.Arg(0) image = cmd.Arg(0)
} )
if len(parsedArgs) > 1 { if len(parsedArgs) > 1 {
runCmd = parsedArgs[1:] runCmd = parsedArgs[1:]
} }