From a0f079a627d6ff908d2076b065090251c2ec67dd Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Tue, 21 Apr 2015 22:58:07 -0400 Subject: [PATCH] Enhancing `docker-machine ip` to support multiple host arguments Fixes #999 Signed-off-by: Dave Henderson --- commands/commands.go | 3 ++- commands/ip.go | 7 +---- docs/index.md | 9 ++++--- libmachine/host.go | 9 +++++++ libmachine/host_test.go | 60 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/commands/commands.go b/commands/commands.go index cedd5d6adf..fc9d39bd17 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -234,7 +234,7 @@ var Commands = []cli.Command{ { Name: "ip", Usage: "Get the IP address of a machine", - Description: "Argument is a machine name. Will use the active machine if none is provided.", + Description: "Argument(s) are one or more machine names. Will use the active machine if none is provided.", Action: cmdIp, }, { @@ -342,6 +342,7 @@ func machineCommand(actionName string, host *libmachine.Host, errorChan chan<- e "restart": host.Restart, "kill": host.Kill, "upgrade": host.Upgrade, + "ip": host.PrintIP, } log.Debugf("command=%s machine=%s", actionName, host.Name) diff --git a/commands/ip.go b/commands/ip.go index c280a61051..b6b9fb5c71 100644 --- a/commands/ip.go +++ b/commands/ip.go @@ -1,18 +1,13 @@ package commands import ( - "fmt" - log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" ) func cmdIp(c *cli.Context) { - ip, err := getHost(c).Driver.GetIP() - if err != nil { + if err := runActionWithContext("ip", c); err != nil { log.Fatal(err) } - - fmt.Println(ip) } diff --git a/docs/index.md b/docs/index.md index 9f3328148e..dafa687297 100644 --- a/docs/index.md +++ b/docs/index.md @@ -535,11 +535,16 @@ Show help text. #### ip -Get the IP address of a machine. +Get the IP address of one or more machines. ``` $ docker-machine ip 192.168.99.104 +$ docker-machine ip dev +192.168.99.104 +$ docker-machine ip dev dev2 +192.168.99.104 +192.168.99.105 ``` #### kill @@ -1051,5 +1056,3 @@ details, see [PR #553](https://github.com/docker/machine/issues/553). * Improvements and isolation of provisioning functionality, so Machine can provision and configure the Docker Engine based on OS detection. For details, see [PR #553](https://github.com/docker/machine/issues/553). - - diff --git a/libmachine/host.go b/libmachine/host.go index 0cd1579931..794676c1cf 100644 --- a/libmachine/host.go +++ b/libmachine/host.go @@ -334,6 +334,15 @@ func (h *Host) SaveConfig() error { return nil } +func (h *Host) PrintIP() error { + if ip, err := h.Driver.GetIP(); err != nil { + return err + } else { + fmt.Println(ip) + } + return nil +} + func sshAvailableFunc(h *Host) func() bool { return func() bool { log.Debug("Getting to WaitForSSH function...") diff --git a/libmachine/host_test.go b/libmachine/host_test.go index 4f2b7603e7..38d4b42e8f 100644 --- a/libmachine/host_test.go +++ b/libmachine/host_test.go @@ -1,16 +1,21 @@ package libmachine import ( + "bytes" "fmt" + "io" "io/ioutil" "os" - + "strings" "testing" + "github.com/docker/machine/drivers/fakedriver" _ "github.com/docker/machine/drivers/none" "github.com/docker/machine/libmachine/auth" "github.com/docker/machine/libmachine/engine" "github.com/docker/machine/libmachine/swarm" + + "github.com/stretchr/testify/assert" ) const ( @@ -22,8 +27,13 @@ const ( var ( hostTestStorePath string + stdout *os.File ) +func init() { + stdout = os.Stdout +} + func getTestStore() (Store, error) { tmpDir, err := ioutil.TempDir("", "machine-test-") if err != nil { @@ -39,6 +49,7 @@ func getTestStore() (Store, error) { } func cleanup() { + os.Stdout = stdout os.RemoveAll(hostTestStorePath) } @@ -124,7 +135,7 @@ func TestValidateHostnameValid(t *testing.T) { for _, v := range hosts { isValid := ValidateHostName(v) if !isValid { - t.Fatal("Thought a valid hostname was invalid: %s", v) + t.Fatalf("Thought a valid hostname was invalid: %s", v) } } } @@ -139,7 +150,7 @@ func TestValidateHostnameInvalid(t *testing.T) { for _, v := range hosts { isValid := ValidateHostName(v) if isValid { - t.Fatal("Thought an invalid hostname was valid: %s", v) + t.Fatalf("Thought an invalid hostname was valid: %s", v) } } } @@ -172,3 +183,46 @@ func TestHostOptions(t *testing.T) { t.Fatal(err) } } + +func TestPrintIPEmptyGivenLocalEngine(t *testing.T) { + defer cleanup() + host, _ := getDefaultTestHost() + + out, w := captureStdout() + + assert.Nil(t, host.PrintIP()) + w.Close() + + assert.Equal(t, "", strings.TrimSpace(<-out)) +} + +func TestPrintIPPrintsGivenRemoteEngine(t *testing.T) { + defer cleanup() + host, _ := getDefaultTestHost() + host.Driver = &fakedriver.FakeDriver{} + + out, w := captureStdout() + + assert.Nil(t, host.PrintIP()) + + w.Close() + + assert.Equal(t, "1.2.3.4", strings.TrimSpace(<-out)) +} + +func captureStdout() (chan string, *os.File) { + r, w, _ := os.Pipe() + + // This is reversed in cleanup() + os.Stdout = w + + out := make(chan string) + + go func() { + var testOutput bytes.Buffer + io.Copy(&testOutput, r) + out <- testOutput.String() + }() + + return out, w +}