Skip to content

Commit

Permalink
New Feature: docker#1342 Get an internal IP of cloud hosted machine (…
Browse files Browse the repository at this point in the history
…implementation for GCE and VirtualBox, placeholders for the rest currently)

Signed-off-by: Andrew Grande <[email protected]>
  • Loading branch information
aperepel committed Jun 15, 2015
1 parent 6d26992 commit 471189d
Show file tree
Hide file tree
Showing 21 changed files with 170 additions and 31 deletions.
7 changes: 7 additions & 0 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ var Commands = []cli.Command{
Usage: "Get the IP address of a machine",
Description: "Argument(s) are one or more machine names.",
Action: cmdIp,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "private, p",
Usage: "Return an instance's private IP address.",
},
},
},
{
Name: "kill",
Expand Down Expand Up @@ -410,6 +416,7 @@ func machineCommand(actionName string, host *libmachine.Host, errorChan chan<- e
"kill": host.Kill,
"upgrade": host.Upgrade,
"ip": host.PrintIP,
"privateIp": host.PrintPrivateIP,
}

log.Debugf("command=%s machine=%s", actionName, host.Name)
Expand Down
13 changes: 12 additions & 1 deletion commands/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@ import (
)

func cmdIp(c *cli.Context) {
if err := runActionWithContext("ip", c); err != nil {
if len(c.Args()) == 0 {
cli.ShowCommandHelp(c, "ip")
log.Fatal("You must specify a machine name")
}

ctx := "ip"

if c.Bool("private") {
ctx = "privateIp"
}

if err := runActionWithContext(ctx, c); err != nil {
log.Fatal(err)
}
}
4 changes: 4 additions & 0 deletions commands/scp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func (d ScpFakeDriver) GetIP() (string, error) {
return "12.34.56.78", nil
}

func (d ScpFakeDriver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d ScpFakeDriver) GetState() (state.State, error) {
return d.MockState, nil
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/amazonec2/amazonec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package amazonec2
import (
"crypto/md5"
"crypto/rand"
"errors"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -442,6 +443,10 @@ func (d *Driver) GetIP() (string, error) {
return inst.IpAddress, nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
inst, err := d.getInstance()
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions drivers/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ func (d *Driver) GetIP() (string, error) {
return d.getHostname(), nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
if err := d.setUserSubscription(); err != nil {
return state.Error, err
Expand Down
5 changes: 5 additions & 0 deletions drivers/digitalocean/digitalocean.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package digitalocean

import (
"errors"
"fmt"
"io/ioutil"
"path/filepath"
Expand Down Expand Up @@ -266,6 +267,10 @@ func (d *Driver) GetIP() (string, error) {
return d.IPAddress, nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
droplet, _, err := d.getClient().Droplets.Get(d.DropletID)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions drivers/drivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type Driver interface {
// e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net
GetIP() (string, error)

// GetPrivateIP returns an internal host IP
GetPrivateIP() (string, error)

// GetMachineName returns the name of the machine
GetMachineName() string

Expand Down
5 changes: 5 additions & 0 deletions drivers/exoscale/exoscale.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package exoscale

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"path/filepath"
Expand Down Expand Up @@ -173,6 +174,10 @@ func (d *Driver) GetIP() (string, error) {
return d.IPAddress, nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
client := egoscale.NewClient(d.URL, d.ApiKey, d.ApiSecretKey)
vm, err := client.GetVirtualMachine(d.Id)
Expand Down
5 changes: 5 additions & 0 deletions drivers/fakedriver/fakedriver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fakedriver

import (
"errors"
"github.com/docker/machine/drivers"
"github.com/docker/machine/state"
)
Expand Down Expand Up @@ -37,6 +38,10 @@ func (d *FakeDriver) GetIP() (string, error) {
return "1.2.3.4", nil
}

func (d *FakeDriver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *FakeDriver) GetSSHHostname() (string, error) {
return "", nil
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/generic/generic.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package generic

import (
"errors"
"fmt"
"net"
"os"
Expand Down Expand Up @@ -164,6 +165,10 @@ func (d *Driver) GetIP() (string, error) {
return d.IPAddress, nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
addr := fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort)
_, err := net.DialTimeout("tcp", addr, defaultTimeout)
Expand Down
37 changes: 25 additions & 12 deletions drivers/google/compute_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ import (

// ComputeUtil is used to wrap the raw GCE API code and store common parameters.
type ComputeUtil struct {
zone string
instanceName string
userName string
project string
diskTypeURL string
service *raw.Service
zoneURL string
authTokenPath string
globalURL string
ipAddress string
SwarmMaster bool
SwarmHost string
zone string
instanceName string
userName string
project string
diskTypeURL string
service *raw.Service
zoneURL string
authTokenPath string
globalURL string
ipAddress string
privateIpAddress string
SwarmMaster bool
SwarmHost string
}

const (
Expand Down Expand Up @@ -305,3 +306,15 @@ func (c *ComputeUtil) ip() (string, error) {
}
return c.ipAddress, nil
}

// returns an internal IP address of the instance.
func (c *ComputeUtil) privateIp() (string, error) {
if c.privateIpAddress == "" {
instance, err := c.service.Instances.Get(c.project, c.zone, c.instanceName).Do()
if err != nil {
return "", err
}
c.privateIpAddress = instance.NetworkInterfaces[0].NetworkIP
}
return c.privateIpAddress, nil
}
45 changes: 28 additions & 17 deletions drivers/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,24 @@ import (

// Driver is a struct compatible with the docker.hosts.drivers.Driver interface.
type Driver struct {
IPAddress string
MachineName string
SSHUser string
SSHPort int
Zone string
MachineType string
DiskType string
Scopes string
DiskSize int
AuthTokenPath string
storePath string
Project string
CaCertPath string
PrivateKeyPath string
SwarmMaster bool
SwarmHost string
SwarmDiscovery string
IPAddress string
PrivateIPAddress string
MachineName string
SSHUser string
SSHPort int
Zone string
MachineType string
DiskType string
Scopes string
DiskSize int
AuthTokenPath string
storePath string
Project string
CaCertPath string
PrivateKeyPath string
SwarmMaster bool
SwarmHost string
SwarmDiscovery string
}

func init() {
Expand Down Expand Up @@ -211,6 +212,15 @@ func (d *Driver) GetIP() (string, error) {
return c.ip()
}

// returns the internal IP address of the GCE instance.
func (d *Driver) GetPrivateIP() (string, error) {
c, err := newComputeUtil(d)
if err != nil {
return "", err
}
return c.privateIp()
}

// GetState returns a docker.hosts.state.State value representing the current state of the host.
func (d *Driver) GetState() (state.State, error) {
c, err := newComputeUtil(d)
Expand Down Expand Up @@ -250,6 +260,7 @@ func (d *Driver) Start() error {
return err
}
d.IPAddress, err = d.GetIP()
d.PrivateIPAddress, err = d.GetPrivateIP()
return err
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/hyperv/hyperv_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package hyperv
import (
"archive/tar"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -436,6 +437,10 @@ func (d *Driver) GetIP() (string, error) {
return resp[0], nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) publicSSHKeyPath() string {
return d.GetSSHKeyPath() + ".pub"
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/none/none.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package none

import (
"errors"
"fmt"
neturl "net/url"

Expand Down Expand Up @@ -58,6 +59,10 @@ func (d *Driver) GetIP() (string, error) {
return d.IPAddress, nil
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetMachineName() string {
return ""
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/openstack/openstack.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package openstack

import (
"errors"
"fmt"
"io/ioutil"
"path/filepath"
Expand Down Expand Up @@ -312,6 +313,10 @@ func (d *Driver) GetIP() (string, error) {
return "", fmt.Errorf("No IP found for the machine")
}

func (d *Driver) GetPrivateIP() (string, error) {
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
log.WithField("MachineId", d.MachineId).Debug("Get status for OpenStack instance...")
if err := d.initCompute(); err != nil {
Expand Down
6 changes: 6 additions & 0 deletions drivers/softlayer/driver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package softlayer

import (
"errors"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -305,6 +306,11 @@ func (d *Driver) GetIP() (string, error) {
}
}

func (d *Driver) GetPrivateIP() (string, error) {
// TODO there's some private ip code in GetIP(), review for applicability
return "", errors.New("not implemented")
}

func (d *Driver) GetState() (state.State, error) {
s, err := d.getClient().VirtualGuest().PowerState(d.Id)
if err != nil {
Expand Down
18 changes: 17 additions & 1 deletion drivers/virtualbox/virtualbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,15 @@ func (d *Driver) setMachineNameIfNotSet() {
}

func (d *Driver) GetIP() (string, error) {
return d._getIp(false)
}

func (d *Driver) GetPrivateIP() (string, error) {
return d._getIp(true)
}

// helper function to get an external/internal IP based on the flag (true for private)
func (d *Driver) _getIp(private bool) (string, error) {
// DHCP is used to get the IP, so virtualbox hosts don't have IPs unless
// they are running
s, err := d.GetState()
Expand All @@ -506,7 +515,14 @@ func (d *Driver) GetIP() (string, error) {
return "", drivers.ErrHostIsNotRunning
}

output, err := drivers.RunSSHCommandFromDriver(d, "ip addr show dev eth1")
// eth1 for public
network := "eth1"
if private {
network = "eth0"
}

sshCmd := fmt.Sprintf("ip addr show dev %s", network)
output, err := drivers.RunSSHCommandFromDriver(d, sshCmd)
if err != nil {
return "", err
}
Expand Down
Loading

0 comments on commit 471189d

Please sign in to comment.