diff --git a/docs/index.md b/docs/index.md index 00354cf9d0..f8e10b973a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1464,6 +1464,7 @@ Options: - `--virtualbox-disk-size`: Size of disk for the host in MB. - `--virtualbox-boot2docker-url`: The URL of the boot2docker image. Defaults to the latest available version. - `--virtualbox-import-boot2docker-vm`: The name of a Boot2Docker VM to import. + - `--virtualbox-hostonly-cidr`: The CIDR of the host only adapter. The `--virtualbox-boot2docker-url` flag takes a few different forms. By default, if no value is specified for this flag, Machine will check locally for @@ -1482,6 +1483,15 @@ file://$HOME/Downloads/rc.iso` to test out a release candidate ISO that you have downloaded already. You could also just get an ISO straight from the Internet using the `http://` form. +To customize the host only adapter, you can use the `--virtualbox-hostonly-cidr` +flag. This will specify the host IP and Machine will calculate the VirtualBox +DHCP server address (a random IP on the subnet between `.1` and `.25`) so +it does not clash with the specified host IP. +Machine will also specify the DHCP lower bound to `.100` and the upper bound +to `.254`. For example, a specified CIDR of `192.168.24.1/24` would have a +DHCP server between `192.168.24.2-25`, a lower bound of `192.168.24.100` and +upper bound of `192.168.24.254`. + Environment variables and default values: | CLI option | Environment variable | Default | @@ -1491,6 +1501,7 @@ Environment variables and default values: | `--virtualbox-disk-size` | `VIRTUALBOX_DISK_SIZE` | `20000` | | `--virtualbox-boot2docker-url` | `VIRTUALBOX_BOOT2DOCKER_URL` | *Latest boot2docker url* | | `--virtualbox-import-boot2docker-vm` | - | `boot2docker-vm` | +| `--virtualbox-hostonly-cidr` | `VIRTUALBOX_HOSTONLY_CIDR` | `192.168.99.1/24` | #### VMware Fusion Creates machines locally on [VMware Fusion](http://www.vmware.com/products/fusion). Requires VMware Fusion to be installed. diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index efb9495e1b..08f8492f7f 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "net" "os" "os/exec" @@ -44,6 +45,7 @@ type Driver struct { SwarmDiscovery string storePath string Boot2DockerImportVM string + HostOnlyCIDR string } func init() { @@ -86,6 +88,12 @@ func GetCreateFlags() []cli.Flag { Usage: "The name of a Boot2Docker VM to import", Value: "", }, + cli.StringFlag{ + Name: "virtualbox-hostonly-cidr", + Usage: "Specify the Host Only CIDR", + Value: "192.168.99.1/24", + EnvVar: "VIRTUALBOX_HOSTONLY_CIDR", + }, } } @@ -150,6 +158,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmDiscovery = flags.String("swarm-discovery") d.SSHUser = "docker" d.Boot2DockerImportVM = flags.String("virtualbox-import-boot2docker-vm") + d.HostOnlyCIDR = flags.String("virtualbox-hostonly-cidr") return nil } @@ -273,7 +282,7 @@ func (d *Driver) Create() error { return err } - if err := setupHostOnlyNetwork(d.MachineName); err != nil { + if err := d.setupHostOnlyNetwork(d.MachineName); err != nil { return err } @@ -360,7 +369,7 @@ func (d *Driver) Start() error { } // check network to re-create if needed - if err := setupHostOnlyNetwork(d.MachineName); err != nil { + if err := d.setupHostOnlyNetwork(d.MachineName); err != nil { return err } @@ -564,6 +573,44 @@ func (d *Driver) generateDiskImage(size int) error { return createDiskImage(d.diskPath(), size, raw) } +func (d *Driver) setupHostOnlyNetwork(machineName string) error { + ip, network, err := net.ParseCIDR(d.HostOnlyCIDR) + nAddr := network.IP.To4() + + var dhcpAddr net.IP + // select pseudo-random DHCP addr; make sure not to clash with the host + for { + n := rand.Intn(25) + if byte(n) != nAddr[3] { + dhcpAddr = net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(1)) + log.Debugf("using %s for dhcp address", dhcpAddr) + break + } + } + + hostOnlyNetwork, err := getOrCreateHostOnlyNetwork( + ip, + network.Mask, + dhcpAddr, + net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(100)), + net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(254)), + ) + + if err != nil { + return err + } + + if err := vbm("modifyvm", machineName, + "--nic2", "hostonly", + "--nictype2", "82540EM", + "--hostonlyadapter2", hostOnlyNetwork.Name, + "--cableconnected2", "on"); err != nil { + return err + } + + return nil +} + // createDiskImage makes a disk image at dest with the given size in MB. If r is // not nil, it will be read as a raw disk image to convert from. func createDiskImage(dest string, size int, r io.Reader) error { @@ -670,27 +717,3 @@ func setPortForwarding(machine string, interfaceNum int, mapName, protocol strin } return actualHostPort, nil } - -func setupHostOnlyNetwork(machineName string) error { - hostOnlyNetwork, err := getOrCreateHostOnlyNetwork( - net.ParseIP("192.168.99.1"), - net.IPv4Mask(255, 255, 255, 0), - net.ParseIP("192.168.99.2"), - net.ParseIP("192.168.99.100"), - net.ParseIP("192.168.99.254"), - ) - - if err != nil { - return err - } - - if err := vbm("modifyvm", machineName, - "--nic2", "hostonly", - "--nictype2", "82540EM", - "--hostonlyadapter2", hostOnlyNetwork.Name, - "--cableconnected2", "on"); err != nil { - return err - } - - return nil -}