Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1479 from mschygulla/enhanced-vmwarefusion-driver
Browse files Browse the repository at this point in the history
[Enhancement] VMware Fusion driver
  • Loading branch information
nathanleclaire committed Sep 11, 2015
2 parents 7c4d0a5 + 82a7bf4 commit b52fa33
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 4 deletions.
131 changes: 127 additions & 4 deletions drivers/vmwarefusion/fusion_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ package vmwarefusion

import (
"archive/tar"
"bytes"
"fmt"
"io/ioutil"
"net"
"os"
"regexp"
"runtime"
Expand All @@ -21,12 +23,14 @@ import (
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
cryptossh "golang.org/x/crypto/ssh"
)

const (
B2DUser = "docker"
B2DPass = "tcuser"
isoFilename = "boot2docker.iso"
B2DUser = "docker"
B2DPass = "tcuser"
isoFilename = "boot2docker.iso"
isoConfigDrive = "configdrive.iso"
)

// Driver for VMware Fusion
Expand All @@ -38,6 +42,10 @@ type Driver struct {
ISO string
Boot2DockerURL string
CPUS int

SSHPassword string
ConfigDriveISO string
ConfigDriveURL string
}

func init() {
Expand All @@ -56,6 +64,11 @@ func GetCreateFlags() []cli.Flag {
Name: "vmwarefusion-boot2docker-url",
Usage: "Fusion URL for boot2docker image",
},
cli.StringFlag{
EnvVar: "FUSION_CONFIGDRIVE_URL",
Name: "vmwarefusion-configdrive-url",
Usage: "Fusion URL for cloud-init configdrive",
},
cli.IntFlag{
EnvVar: "FUSION_CPU_COUNT",
Name: "vmwarefusion-cpu-count",
Expand All @@ -74,6 +87,18 @@ func GetCreateFlags() []cli.Flag {
Usage: "Fusion size of disk for host VM (in MB)",
Value: 20000,
},
cli.StringFlag{
EnvVar: "FUSION_SSH_USER",
Name: "vmwarefusion-ssh-user",
Usage: "SSH user",
Value: B2DUser,
},
cli.StringFlag{
EnvVar: "FUSION_SSH_PASSWORD",
Name: "vmwarefusion-ssh-password",
Usage: "SSH password",
Value: B2DPass,
},
}
}

Expand Down Expand Up @@ -103,11 +128,14 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.CPU = flags.Int("vmwarefusion-cpu-count")
d.DiskSize = flags.Int("vmwarefusion-disk-size")
d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url")
d.ConfigDriveURL = flags.String("vmwarefusion-configdrive-url")
d.ConfigDriveISO = d.ResolveStorePath(isoConfigDrive)
d.ISO = d.ResolveStorePath(isoFilename)
d.SwarmMaster = flags.Bool("swarm-master")
d.SwarmHost = flags.String("swarm-host")
d.SwarmDiscovery = flags.String("swarm-discovery")
d.SSHUser = "docker"
d.SSHUser = flags.String("vmwarefusion-ssh-user")
d.SSHPassword = flags.String("vmwarefusion-ssh-password")
d.SSHPort = 22

// We support a maximum of 16 cpu to be consistent with Virtual Hardware 10
Expand Down Expand Up @@ -169,6 +197,14 @@ func (d *Driver) Create() error {
return err
}

// download cloud-init config drive
if d.ConfigDriveURL != "" {
log.Infof("Downloading %s from %s", isoConfigDrive, d.ConfigDriveURL)
if err := b2dutils.DownloadISO(d.ResolveStorePath("."), isoConfigDrive, d.ConfigDriveURL); err != nil {
return err
}
}

log.Infof("Creating SSH key...")
if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
return err
Expand Down Expand Up @@ -219,6 +255,13 @@ func (d *Driver) Create() error {

if ip != "" {
log.Debugf("Got an ip: %s", ip)
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, 22), time.Duration(2*time.Second))
if err != nil {
log.Debugf("SSH Daemon not responding yet: %s", err)
time.Sleep(2 * time.Second)
continue
}
conn.Close()
break
}
}
Expand All @@ -230,6 +273,44 @@ func (d *Driver) Create() error {
// we got an IP, let's copy ssh keys over
d.IPAddress = ip

// Do not execute the rest of boot2docker specific configuration
// The uplaod of the public ssh key uses a ssh connection,
// this works without installed vmware client tools
if d.ConfigDriveURL != "" {
var keyfh *os.File
var keycontent []byte

log.Infof("Copy public SSH key to %s [%s]", d.MachineName, d.IPAddress)

// create .ssh folder in users home
if err := executeSSHCommand(fmt.Sprintf("mkdir -p /home/%s/.ssh", d.SSHUser), d); err != nil {
return err
}

// read generated public ssh key
if keyfh, err = os.Open(d.publicSSHKeyPath()); err != nil {
return err
}
defer keyfh.Close()

if keycontent, err = ioutil.ReadAll(keyfh); err != nil {
return err
}

// add public ssh key to authorized_keys
if err := executeSSHCommand(fmt.Sprintf("echo '%s' > /home/%s/.ssh/authorized_keys", string(keycontent), d.SSHUser), d); err != nil {
return err
}

// make it secure
if err := executeSSHCommand(fmt.Sprintf("chmod 600 /home/%s/.ssh/authorized_keys", d.SSHUser), d); err != nil {
return err
}

log.Debugf("Leaving create sequence early, configdrive found")
return nil
}

// Generate a tar keys bundle
if err := d.generateKeyBundle(); err != nil {
return err
Expand Down Expand Up @@ -271,6 +352,12 @@ func (d *Driver) Start() error {
log.Infof("Starting %s...", d.MachineName)
vmrun("start", d.vmxPath(), "nogui")

// Do not execute the rest of boot2docker specific configuration, exit here
if d.ConfigDriveURL != "" {
log.Debugf("Leaving start sequence early, configdrive found")
return nil
}

log.Debugf("Mounting Shared Folders...")
var shareName, shareDir string // TODO configurable at some point
switch runtime.GOOS {
Expand Down Expand Up @@ -475,3 +562,39 @@ func (d *Driver) generateKeyBundle() error {
return nil

}

// execute command over SSH with user / password authentication
func executeSSHCommand(command string, d *Driver) error {
log.Debugf("Execute executeSSHCommand: %s", command)

config := &cryptossh.ClientConfig{
User: d.SSHUser,
Auth: []cryptossh.AuthMethod{
cryptossh.Password(d.SSHPassword),
},
}

client, err := cryptossh.Dial("tcp", fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), config)
if err != nil {
log.Debugf("Failed to dial:", err)
return err
}

session, err := client.NewSession()
if err != nil {
log.Debugf("Failed to create session: " + err.Error())
return err
}
defer session.Close()

var b bytes.Buffer
session.Stdout = &b

if err := session.Run(command); err != nil {
log.Debugf("Failed to run: " + err.Error())
return err
}
log.Debugf("Stdout from executeSSHCommand: %s", b.String())

return nil
}
5 changes: 5 additions & 0 deletions drivers/vmwarefusion/vmx_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ sata0.present = "TRUE"
sata0:1.present = "TRUE"
sata0:1.fileName = "{{.ISO}}"
sata0:1.deviceType = "cdrom-image"
{{ if .ConfigDriveURL }}
sata0:2.present = "TRUE"
sata0:2.fileName = "{{.ConfigDriveISO}}"
sata0:2.deviceType = "cdrom-image"
{{ end }}
vmci0.present = "TRUE"
mem.hotadd = "TRUE"
memsize = "{{.Memory}}"
Expand Down

0 comments on commit b52fa33

Please sign in to comment.