mirror of https://github.com/docker/docs.git
Merge pull request #658 from frapposelli/fusion-driver-fixes
Fusion driver fixes
This commit is contained in:
commit
d65f66a75d
|
@ -5,6 +5,7 @@
|
|||
package vmwarefusion
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -14,6 +15,7 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
@ -24,14 +26,13 @@ import (
|
|||
"github.com/docker/machine/ssh"
|
||||
"github.com/docker/machine/state"
|
||||
"github.com/docker/machine/utils"
|
||||
cssh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
const (
|
||||
B2D_USER = "docker"
|
||||
B2D_PASS = "tcuser"
|
||||
dockerConfigDir = "/var/lib/boot2docker"
|
||||
isoFilename = "boot2docker-vmw.iso"
|
||||
isoFilename = "boot2docker-1.5.0-GH747.iso"
|
||||
)
|
||||
|
||||
// Driver for VMware Fusion
|
||||
|
@ -40,6 +41,7 @@ type Driver struct {
|
|||
IPAddress string
|
||||
Memory int
|
||||
DiskSize int
|
||||
CPUs int
|
||||
ISO string
|
||||
Boot2DockerURL string
|
||||
CaCertPath string
|
||||
|
@ -105,6 +107,13 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
|
|||
d.SwarmHost = flags.String("swarm-host")
|
||||
d.SwarmDiscovery = flags.String("swarm-discovery")
|
||||
|
||||
// We support a maximum of 16 cpu to be consistent with Virtual Hardware 10
|
||||
// specs.
|
||||
d.CPUs = int(runtime.NumCPU())
|
||||
if d.CPUs > 16 {
|
||||
d.CPUs = 16
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -168,7 +177,7 @@ func (d *Driver) Create() error {
|
|||
|
||||
} else {
|
||||
// TODO: until vmw tools are merged into b2d master
|
||||
// we will use the iso from the vmware team
|
||||
// we will use the iso from the vmware team.
|
||||
//// todo: check latest release URL, download if it's new
|
||||
//// until then always use "latest"
|
||||
//isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL()
|
||||
|
@ -176,7 +185,8 @@ func (d *Driver) Create() error {
|
|||
// log.Warnf("Unable to check for the latest release: %s", err)
|
||||
//}
|
||||
|
||||
isoURL := "https://github.com/cloudnativeapps/boot2docker/releases/download/v1.5.0-vmw/boot2docker-1.5.0-vmw.iso"
|
||||
// see https://github.com/boot2docker/boot2docker/pull/747
|
||||
isoURL := "https://github.com/cloudnativeapps/boot2docker/releases/download/1.5.0-GH747/boot2docker-1.5.0-GH747.iso"
|
||||
|
||||
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
|
||||
log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath)
|
||||
|
@ -255,34 +265,22 @@ func (d *Driver) Create() error {
|
|||
return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting")
|
||||
}
|
||||
|
||||
// we got an IP, let's copy ssh keys over
|
||||
d.IPAddress = ip
|
||||
|
||||
key, err := ioutil.ReadFile(d.publicSSHKeyPath())
|
||||
if err != nil {
|
||||
// Generate a tar keys bundle
|
||||
if err := d.generateKeyBundle(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// so, vmrun above will not work without vmtools in b2d. since getting stuff into TCL
|
||||
// is much more painful, we simply use the b2d password to get the initial public key
|
||||
// onto the machine. from then on we use the pub key. meh.
|
||||
sshConfig := &cssh.ClientConfig{
|
||||
User: B2D_USER,
|
||||
Auth: []cssh.AuthMethod{
|
||||
cssh.Password(B2D_PASS),
|
||||
},
|
||||
}
|
||||
sshClient, err := cssh.Dial("tcp", fmt.Sprintf("%s:22", ip), sshConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session, err := sshClient.NewSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := session.Run(fmt.Sprintf("mkdir /home/docker/.ssh && echo \"%s\" > /home/docker/.ssh/authorized_keys", string(key))); err != nil {
|
||||
return err
|
||||
}
|
||||
session.Close()
|
||||
// Test if /var/lib/boot2docker exists
|
||||
vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "directoryExistsInGuest", d.vmxPath(), "/var/lib/boot2docker")
|
||||
|
||||
// Copy SSH keys bundle
|
||||
vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "CopyFileFromHostToGuest", d.vmxPath(), path.Join(d.storePath, "userdata.tar"), "/home/docker/userdata.tar")
|
||||
|
||||
// Expand tar file.
|
||||
vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo /bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar && sudo tar xf /var/lib/boot2docker/userdata.tar -C /home/docker/ > /var/log/userdata.log 2>&1 && sudo chown -R docker:staff /home/docker")
|
||||
|
||||
log.Debugf("Setting hostname: %s", d.MachineName)
|
||||
cmd, err := d.GetSSHCommand(fmt.Sprintf(
|
||||
|
@ -302,11 +300,13 @@ func (d *Driver) Create() error {
|
|||
}
|
||||
|
||||
func (d *Driver) Start() error {
|
||||
log.Infof("Starting %s...", d.MachineName)
|
||||
vmrun("start", d.vmxPath(), "nogui")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Driver) Stop() error {
|
||||
log.Infof("Gracefully shutting down %s...", d.MachineName)
|
||||
vmrun("stop", d.vmxPath(), "nogui")
|
||||
return nil
|
||||
}
|
||||
|
@ -319,18 +319,20 @@ func (d *Driver) Remove() error {
|
|||
return fmt.Errorf("Error stopping VM before deletion")
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Deleting %s...", d.MachineName)
|
||||
vmrun("deleteVM", d.vmxPath(), "nogui")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Driver) Restart() error {
|
||||
log.Infof("Gracefully restarting %s...", d.MachineName)
|
||||
vmrun("reset", d.vmxPath(), "nogui")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Driver) Kill() error {
|
||||
vmrun("stop", d.vmxPath(), "nogui")
|
||||
log.Infof("Forcibly halting %s...", d.MachineName)
|
||||
vmrun("stop", d.vmxPath(), "hard nogui")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -351,7 +353,8 @@ func (d *Driver) StartDocker() error {
|
|||
func (d *Driver) StopDocker() error {
|
||||
log.Debug("Stopping Docker...")
|
||||
|
||||
cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi")
|
||||
// Check if pidfile exists, then if process exists, depending on that stop docker or remove pidfile
|
||||
cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then if [ -f /proc/$(cat /var/run/docker.pid)/status ]; then sudo /etc/init.d/docker stop; else rm -f /var/run/docker.pid; fi fi")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -367,7 +370,7 @@ func (d *Driver) GetDockerConfigDir() string {
|
|||
}
|
||||
|
||||
func (d *Driver) Upgrade() error {
|
||||
return nil
|
||||
return fmt.Errorf("VMware Fusion does not currently support the upgrade operation.")
|
||||
}
|
||||
|
||||
func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) {
|
||||
|
@ -502,3 +505,58 @@ func (d *Driver) sshKeyPath() string {
|
|||
func (d *Driver) publicSSHKeyPath() string {
|
||||
return d.sshKeyPath() + ".pub"
|
||||
}
|
||||
|
||||
// Make a boot2docker userdata.tar key bundle
|
||||
func (d *Driver) generateKeyBundle() error {
|
||||
log.Debugf("Creating Tar key bundle...")
|
||||
|
||||
magicString := "boot2docker, this is vmware speaking"
|
||||
|
||||
tf, err := os.Create(path.Join(d.storePath, "userdata.tar"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tf.Close()
|
||||
var fileWriter io.WriteCloser = tf
|
||||
|
||||
tw := tar.NewWriter(fileWriter)
|
||||
defer tw.Close()
|
||||
|
||||
// magicString first so we can figure out who originally wrote the tar.
|
||||
file := &tar.Header{Name: magicString, Size: int64(len(magicString))}
|
||||
if err := tw.WriteHeader(file); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tw.Write([]byte(magicString)); err != nil {
|
||||
return err
|
||||
}
|
||||
// .ssh/key.pub => authorized_keys
|
||||
file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700}
|
||||
if err := tw.WriteHeader(file); err != nil {
|
||||
return err
|
||||
}
|
||||
pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644}
|
||||
if err := tw.WriteHeader(file); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tw.Write([]byte(pubKey)); err != nil {
|
||||
return err
|
||||
}
|
||||
file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644}
|
||||
if err := tw.WriteHeader(file); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tw.Write([]byte(pubKey)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
|
|
@ -8,30 +8,57 @@ const vmx = `
|
|||
.encoding = "UTF-8"
|
||||
config.version = "8"
|
||||
displayName = "{{.MachineName}}"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.connectionType = "nat"
|
||||
ethernet0.linkStatePropagation.enable = "TRUE"
|
||||
ethernet0.present = "TRUE"
|
||||
ethernet0.virtualDev = "e1000"
|
||||
ethernet0.connectionType = "nat"
|
||||
ethernet0.virtualDev = "vmxnet3"
|
||||
ethernet0.wakeOnPcktRcv = "FALSE"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.linkStatePropagation.enable = "TRUE"
|
||||
pciBridge0.present = "TRUE"
|
||||
pciBridge4.present = "TRUE"
|
||||
pciBridge4.virtualDev = "pcieRootPort"
|
||||
pciBridge4.functions = "8"
|
||||
pciBridge5.present = "TRUE"
|
||||
pciBridge5.virtualDev = "pcieRootPort"
|
||||
pciBridge5.functions = "8"
|
||||
pciBridge6.present = "TRUE"
|
||||
pciBridge6.virtualDev = "pcieRootPort"
|
||||
pciBridge6.functions = "8"
|
||||
pciBridge7.present = "TRUE"
|
||||
pciBridge7.virtualDev = "pcieRootPort"
|
||||
pciBridge7.functions = "8"
|
||||
pciBridge0.pciSlotNumber = "17"
|
||||
pciBridge4.pciSlotNumber = "21"
|
||||
pciBridge5.pciSlotNumber = "22"
|
||||
pciBridge6.pciSlotNumber = "23"
|
||||
pciBridge7.pciSlotNumber = "24"
|
||||
scsi0.pciSlotNumber = "160"
|
||||
usb.pciSlotNumber = "32"
|
||||
ethernet0.pciSlotNumber = "192"
|
||||
sound.pciSlotNumber = "33"
|
||||
vmci0.pciSlotNumber = "35"
|
||||
sata0.pciSlotNumber = "36"
|
||||
floppy0.present = "FALSE"
|
||||
guestOS = "other26xlinux-64"
|
||||
guestOS = "other3xlinux-64"
|
||||
hpet0.present = "TRUE"
|
||||
ide1:0.deviceType = "cdrom-image"
|
||||
ide1:0.fileName = "{{.ISO}}"
|
||||
ide1:0.present = "TRUE"
|
||||
sata0.present = "TRUE"
|
||||
sata0:1.present = "TRUE"
|
||||
sata0:1.fileName = "{{.ISO}}"
|
||||
sata0:1.deviceType = "cdrom-image"
|
||||
vmci0.present = "TRUE"
|
||||
mem.hotadd = "TRUE"
|
||||
memsize = "{{.Memory}}"
|
||||
powerType.powerOff = "hard"
|
||||
powerType.powerOn = "hard"
|
||||
powerType.reset = "hard"
|
||||
powerType.suspend = "hard"
|
||||
powerType.powerOff = "soft"
|
||||
powerType.powerOn = "soft"
|
||||
powerType.reset = "soft"
|
||||
powerType.suspend = "soft"
|
||||
scsi0.present = "TRUE"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
scsi0.virtualDev = "pvscsi"
|
||||
scsi0:0.fileName = "{{.MachineName}}.vmdk"
|
||||
scsi0:0.present = "TRUE"
|
||||
virtualHW.productCompatibility = "hosted"
|
||||
virtualHW.version = "10"
|
||||
msg.autoanswer = "TRUE"
|
||||
uuid.action = "create"
|
||||
numvcpus = "{{.CPUs}}"
|
||||
`
|
||||
|
|
Loading…
Reference in New Issue