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

[Enhancement] VMware Fusion driver #1479

Merged
merged 5 commits into from
Sep 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -166,6 +194,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 @@ -216,6 +252,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 @@ -227,6 +270,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 @@ -268,6 +349,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 @@ -472,3 +559,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