summaryrefslogtreecommitdiff
path: root/api/client/commands.go
diff options
context:
space:
mode:
Diffstat (limited to 'api/client/commands.go')
-rw-r--r--api/client/commands.go142
1 files changed, 87 insertions, 55 deletions
diff --git a/api/client/commands.go b/api/client/commands.go
index 0cdf3f1acb..df2125f5f3 100644
--- a/api/client/commands.go
+++ b/api/client/commands.go
@@ -13,6 +13,7 @@ import (
"os"
"os/exec"
"path"
+ "path/filepath"
"runtime"
"strconv"
"strings"
@@ -36,6 +37,10 @@ import (
"github.com/dotcloud/docker/utils/filters"
)
+const (
+ tarHeaderSize = 512
+)
+
func (cli *DockerCli) CmdHelp(args ...string) error {
if len(args) > 0 {
method, exists := cli.getMethod(args[0])
@@ -51,7 +56,7 @@ func (cli *DockerCli) CmdHelp(args ...string) error {
{"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 the containers filesystem to the host path"},
+ {"cp", "Copy files/folders from a container's filesystem to the host path"},
{"diff", "Inspect changes on a container's filesystem"},
{"events", "Get real time events from the server"},
{"export", "Stream the contents of a container as a tar archive"},
@@ -62,25 +67,25 @@ func (cli *DockerCli) CmdHelp(args ...string) error {
{"inspect", "Return low-level information on a container"},
{"kill", "Kill a running container"},
{"load", "Load an image from a tar archive"},
- {"login", "Register or Login to the docker registry server"},
+ {"login", "Register or log in to the Docker registry server"},
{"logs", "Fetch the logs of a container"},
- {"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"},
+ {"port", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT"},
{"pause", "Pause all processes within a container"},
{"ps", "List containers"},
- {"pull", "Pull an image or a repository from the docker registry server"},
- {"push", "Push an image or a repository to the docker registry server"},
+ {"pull", "Pull an image or a repository from a Docker registry server"},
+ {"push", "Push an image or a repository to a Docker registry server"},
{"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 to a tar archive"},
- {"search", "Search for an image in the docker index"},
+ {"search", "Search for an image on the Docker Hub"},
{"start", "Start a stopped container"},
{"stop", "Stop a running container"},
{"tag", "Tag an image into a repository"},
{"top", "Lookup the running processes of a container"},
{"unpause", "Unpause a paused container"},
- {"version", "Show the docker version information"},
+ {"version", "Show the Docker version information"},
{"wait", "Block until a container stops, then print its exit code"},
} {
help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1])
@@ -113,13 +118,22 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
_, err = exec.LookPath("git")
hasGit := err == nil
if cmd.Arg(0) == "-" {
- // As a special case, 'docker build -' will build from an empty context with the
- // contents of stdin as a Dockerfile
- dockerfile, err := ioutil.ReadAll(cli.in)
- if err != nil {
- return err
+ // As a special case, 'docker build -' will build from either an empty context with the
+ // contents of stdin as a Dockerfile, or a tar-ed context from stdin.
+ buf := bufio.NewReader(cli.in)
+ magic, err := buf.Peek(tarHeaderSize)
+ if err != nil && err != io.EOF {
+ return fmt.Errorf("failed to peek context header from STDIN: %v", err)
+ }
+ if !archive.IsArchive(magic) {
+ dockerfile, err := ioutil.ReadAll(buf)
+ if err != nil {
+ return fmt.Errorf("failed to read Dockerfile from STDIN: %v", err)
+ }
+ context, err = archive.Generate("Dockerfile", string(dockerfile))
+ } else {
+ context = ioutil.NopCloser(buf)
}
- context, err = archive.Generate("Dockerfile", string(dockerfile))
} else if utils.IsURL(cmd.Arg(0)) && (!utils.IsGIT(cmd.Arg(0)) || !hasGit) {
isRemote = true
} else {
@@ -150,7 +164,25 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
if err = utils.ValidateContextDirectory(root); err != nil {
return fmt.Errorf("Error checking context is accessible: '%s'. Please check permissions and try again.", err)
}
- context, err = archive.Tar(root, archive.Uncompressed)
+ options := &archive.TarOptions{
+ Compression: archive.Uncompressed,
+ }
+ if ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore")); err != nil && !os.IsNotExist(err) {
+ return fmt.Errorf("Error reading .dockerignore: '%s'", err)
+ } else if err == nil {
+ for _, pattern := range strings.Split(string(ignore), "\n") {
+ ok, err := filepath.Match(pattern, "Dockerfile")
+ if err != nil {
+ utils.Errorf("Bad .dockerignore pattern: '%s', error: %s", pattern, err)
+ continue
+ }
+ if ok {
+ return fmt.Errorf("Dockerfile was excluded by .dockerignore pattern '%s'", pattern)
+ }
+ options.Excludes = append(options.Excludes, pattern)
+ }
+ }
+ context, err = archive.TarWithOptions(root, options)
}
var body io.Reader
// Setup an upload progress bar
@@ -216,7 +248,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
// 'docker login': login / register a user to registry service.
func (cli *DockerCli) CmdLogin(args ...string) error {
- cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or Login to a docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
+ cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
var username, password, email string
@@ -342,7 +374,7 @@ func (cli *DockerCli) CmdWait(args ...string) error {
// 'docker version': show version information
func (cli *DockerCli) CmdVersion(args ...string) error {
- cmd := cli.Subcmd("version", "", "Show the docker version information.")
+ cmd := cli.Subcmd("version", "", "Show the Docker version information.")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -439,6 +471,9 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
if initPath := remoteInfo.Get("InitPath"); initPath != "" {
fmt.Fprintf(cli.out, "Init Path: %s\n", initPath)
}
+ if len(remoteInfo.GetList("Sockets")) != 0 {
+ fmt.Fprintf(cli.out, "Sockets: %v\n", remoteInfo.GetList("Sockets"))
+ }
}
if len(remoteInfo.GetList("IndexServerAddress")) != 0 {
@@ -462,8 +497,8 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
}
func (cli *DockerCli) CmdStop(args ...string) error {
- cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container (Send SIGTERM, and then SIGKILL after grace period)")
- nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it.")
+ cmd := cli.Subcmd("stop", "[OPTIONS] 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.")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -490,7 +525,7 @@ func (cli *DockerCli) CmdStop(args ...string) error {
func (cli *DockerCli) CmdRestart(args ...string) error {
cmd := cli.Subcmd("restart", "[OPTIONS] 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=10")
+ 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.")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -547,8 +582,8 @@ func (cli *DockerCli) CmdStart(args ...string) error {
tty bool
cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container")
- attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's stdout/stderr and forward all signals to the process")
- openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's stdin")
+ 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")
)
if err := cmd.Parse(args); err != nil {
@@ -679,7 +714,7 @@ func (cli *DockerCli) CmdPause(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/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.")
if err := cmd.Parse(args); err != nil {
return nil
@@ -759,7 +794,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
}
func (cli *DockerCli) CmdTop(args ...string) error {
- cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Lookup the running processes of a container")
+ cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -794,7 +829,7 @@ func (cli *DockerCli) CmdTop(args ...string) error {
}
func (cli *DockerCli) CmdPort(args ...string) error {
- cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT")
+ cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -842,7 +877,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
func (cli *DockerCli) CmdRmi(args ...string) error {
var (
cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images")
- force = cmd.Bool([]string{"f", "-force"}, false, "Force")
+ force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image")
noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents")
)
if err := cmd.Parse(args); err != nil {
@@ -945,7 +980,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
func (cli *DockerCli) CmdRm(args ...string) error {
cmd := cli.Subcmd("rm", "[OPTIONS] CONTAINER [CONTAINER...]", "Remove one or more containers")
- v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated to 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")
force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of running container")
@@ -982,7 +1017,7 @@ func (cli *DockerCli) CmdRm(args ...string) error {
// 'docker kill NAME' kills a running container
func (cli *DockerCli) CmdKill(args ...string) error {
- cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container (send SIGKILL, or specified signal)")
+ cmd := cli.Subcmd("kill", "[OPTIONS] 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")
if err := cmd.Parse(args); err != nil {
@@ -1114,7 +1149,7 @@ func (cli *DockerCli) CmdPush(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")
- tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in repository")
+ tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in a repository")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -1503,25 +1538,21 @@ func (cli *DockerCli) CmdPs(args ...string) error {
func (cli *DockerCli) CmdCommit(args ...string) error {
cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes")
+ 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 (eg. \"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.
- 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")
if err := cmd.Parse(args); err != nil {
return nil
}
- var name, repository, tag string
-
- if cmd.NArg() == 3 {
- fmt.Fprintf(cli.err, "[DEPRECATED] The format 'CONTAINER [REPOSITORY [TAG]]' as been deprecated. Please use CONTAINER [REPOSITORY[:TAG]]\n")
- name, repository, tag = cmd.Arg(0), cmd.Arg(1), cmd.Arg(2)
- } else {
- name = cmd.Arg(0)
+ var (
+ name = cmd.Arg(0)
repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
- }
+ )
- if name == "" {
+ if name == "" || len(cmd.Args()) > 2 {
cmd.Usage()
return nil
}
@@ -1539,6 +1570,11 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
v.Set("tag", tag)
v.Set("comment", *flComment)
v.Set("author", *flAuthor)
+
+ if *flPause != true {
+ v.Set("pause", "0")
+ }
+
var (
config *runconfig.Config
env engine.Env
@@ -1657,6 +1693,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container")
follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
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)")
)
if err := cmd.Parse(args); err != nil {
@@ -1690,6 +1727,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
if *follow {
v.Set("follow", "1")
}
+ v.Set("tail", *tail)
return cli.streamHelper("GET", "/containers/"+name+"/logs?"+v.Encode(), env.GetSubEnv("Config").GetBool("Tty"), nil, cli.out, cli.err, nil)
}
@@ -1697,8 +1735,8 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
func (cli *DockerCli) CmdAttach(args ...string) error {
var (
cmd = cli.Subcmd("attach", "[OPTIONS] CONTAINER", "Attach to a running container")
- noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach stdin")
- proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
+ noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN")
+ proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied.")
)
if err := cmd.Parse(args); err != nil {
@@ -1769,11 +1807,11 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
}
func (cli *DockerCli) CmdSearch(args ...string) error {
- cmd := cli.Subcmd("search", "TERM", "Search the docker index for images")
+ cmd := cli.Subcmd("search", "TERM", "Search the Docker Hub for images")
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")
- stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least xxx stars")
+ stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars")
if err := cmd.Parse(args); err != nil {
return nil
}
@@ -1829,21 +1867,15 @@ func (cli *DockerCli) CmdTag(args ...string) error {
if err := cmd.Parse(args); err != nil {
return nil
}
- if cmd.NArg() != 2 && cmd.NArg() != 3 {
+ if cmd.NArg() != 2 {
cmd.Usage()
return nil
}
- var repository, tag string
-
- if cmd.NArg() == 3 {
- fmt.Fprintf(cli.err, "[DEPRECATED] The format 'IMAGE [REPOSITORY [TAG]]' as been deprecated. Please use IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG]]\n")
- repository, tag = cmd.Arg(1), cmd.Arg(2)
- } else {
+ var (
repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
- }
-
- v := url.Values{}
+ v = url.Values{}
+ )
//Check if the given image name can be resolved
if _, _, err := registry.ResolveRepositoryName(repository); err != nil {
@@ -1906,7 +1938,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
}
if cidFileInfo.Size() == 0 {
if err := os.Remove(hostConfig.ContainerIDFile); err != nil {
- fmt.Printf("failed to remove CID file '%s': %s \n", hostConfig.ContainerIDFile, err)
+ fmt.Printf("failed to remove Container ID file '%s': %s \n", hostConfig.ContainerIDFile, err)
}
}
}()
@@ -2156,7 +2188,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
}
func (cli *DockerCli) CmdSave(args ...string) error {
- cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to stdout by default)")
+ cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to STDOUT by default)")
outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
if err := cmd.Parse(args); err != nil {