diff --git a/cmd/docker.go b/cmd/docker.go index 691451541..8e57a6792 100644 --- a/cmd/docker.go +++ b/cmd/docker.go @@ -6,6 +6,9 @@ import ( "io/ioutil" "os" "os/exec" + "os/signal" + "strconv" + "strings" "github.com/Sirupsen/logrus" "github.com/rancher/go-rancher/client" @@ -19,7 +22,13 @@ func DockerCommand() cli.Command { Usage: "Run docker CLI on a host", Description: "\nUses the $RANCHER_DOCKER_HOST to run docker commands. Use `--host ` or `--host ` to select a different host.\n\nExample:\n\t$ rancher --host 1h1 docker ps\n", Action: hostDocker, - Flags: []cli.Flag{}, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "help-docker", + Usage: "Display the 'docker --help'", + }, + }, + SkipFlagParsing: true, } } @@ -28,8 +37,16 @@ func hostDocker(ctx *cli.Context) error { } func doDocker(ctx *cli.Context) error { - hostname := ctx.GlobalString("host") + args := ctx.Args() + if len(args) > 0 && (args[0] == "-h" || args[0] == "--help") { + return cli.ShowCommandHelp(ctx, "docker") + } + + if len(args) > 0 && args[0] == "--help-docker" { + return runDockerHelp("") + } + hostname := ctx.GlobalString("host") if hostname == "" { return fmt.Errorf("--host is required") } @@ -39,7 +56,7 @@ func doDocker(ctx *cli.Context) error { return err } - return runDocker(hostname, c, ctx.Args()) + return runDocker(hostname, c, args) } func runDockerCommand(hostname string, c *client.RancherClient, command string, args []string) error { @@ -50,6 +67,20 @@ func runDocker(hostname string, c *client.RancherClient, args []string) error { return runDockerWithOutput(hostname, c, args, os.Stdout, os.Stderr) } +func determineApiVersion(host *client.Host) string { + version := host.Labels["io.rancher.host.docker_version"] + parts := strings.Split(fmt.Sprint(version), ".") + if len(parts) != 2 { + return "" + } + num, err := strconv.Atoi(parts[1]) + if err != nil { + return "" + } + + return fmt.Sprintf("1.%d", num+12) +} + func runDockerWithOutput(hostname string, c *client.RancherClient, args []string, out, outErr io.Writer) error { resource, err := Lookup(c, hostname, "host") @@ -67,6 +98,8 @@ func runDockerWithOutput(hostname string, c *client.RancherClient, args []string return fmt.Errorf("Can not contact host %s in state %s", hostname, state) } + apiVersion := determineApiVersion(host) + tempfile, err := ioutil.TempFile("", "docker-sock") if err != nil { return err @@ -88,8 +121,12 @@ func runDockerWithOutput(hostname string, c *client.RancherClient, args []string }() var cmd *exec.Cmd - if len(args) == 1 && args[0] == "--" { - cmd = exec.Command(os.Getenv("SHELL"), args[1:]...) + if len(args) > 0 && args[0] == "--" { + if len(args) > 1 { + cmd = exec.Command(args[1], args[2:]...) + } else { + cmd = exec.Command(os.Getenv("SHELL")) + } cmd.Env = append(os.Environ(), "debian_chroot=docker:"+hostname) } else { cmd = exec.Command("docker", args...) @@ -97,9 +134,13 @@ func runDockerWithOutput(hostname string, c *client.RancherClient, args []string } cmd.Env = append(cmd.Env, "DOCKER_HOST="+dockerHost) + if apiVersion != "" { + cmd.Env = append(cmd.Env, "DOCKER_API_VERSION="+apiVersion) + } cmd.Stdin = os.Stdin cmd.Stdout = out cmd.Stderr = outErr + signal.Ignore(os.Interrupt) return cmd.Run() } diff --git a/cmd/exec.go b/cmd/exec.go index f5140f75f..f86472979 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -14,10 +14,11 @@ import ( func ExecCommand() cli.Command { return cli.Command{ - Name: "exec", - Usage: "Run a command on a container", - Description: "\nThe command will find the container on the host and use `docker exec` to access the container. Any options that `docker exec` uses can be passed as an option for `rancher exec`.\n\nExample:\n\t$ rancher exec -i -t 1i1\n", - Action: execCommand, + Name: "exec", + Usage: "Run a command on a container", + Description: "\nThe command will find the container on the host and use `docker exec` to access the container. Any options that `docker exec` uses can be passed as an option for `rancher exec`.\n\nExample:\n\t$ rancher exec -i -t 1i1\n", + Action: execCommand, + SkipFlagParsing: true, Flags: []cli.Flag{ cli.BoolFlag{ Name: "help-docker", @@ -32,7 +33,12 @@ func execCommand(ctx *cli.Context) error { } func execCommandInternal(ctx *cli.Context) error { - if ctx.Bool("help-docker") { + args := ctx.Args() + if len(args) > 0 && (args[0] == "-h" || args[0] == "--help") { + return cli.ShowCommandHelp(ctx, "exec") + } + + if len(args) > 0 && args[0] == "--help-docker" { return runDockerHelp("exec") } @@ -46,12 +52,14 @@ func execCommandInternal(ctx *cli.Context) error { return err } + // this is a massive hack. Need to fix the real issue + args = append([]string{"-i"}, args...) return runDockerCommand(hostID, c, "exec", args) } func isHelp(args []string) bool { for _, i := range args { - if i == "--help" { + if i == "--help" || i == "-h" { return true } } @@ -175,7 +183,11 @@ func getHostnameAndContainerID(c *client.RancherClient, containerID string) (str } func runDockerHelp(subcommand string) error { - cmd := exec.Command("docker", subcommand, "--help") + args := []string{"--help"} + if subcommand != "" { + args = []string{subcommand, "--help"} + } + cmd := exec.Command("docker", args...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr