mirror of https://github.com/docker/docs.git
Merge pull request #1479 from mschygulla/enhanced-vmwarefusion-driver
[Enhancement] VMware Fusion driver
This commit is contained in:
commit
b52fa33056
|
@ -6,8 +6,10 @@ package vmwarefusion
|
|||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
@ -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
|
||||
|
@ -38,6 +42,10 @@ type Driver struct {
|
|||
ISO string
|
||||
Boot2DockerURL string
|
||||
CPUS int
|
||||
|
||||
SSHPassword string
|
||||
ConfigDriveISO string
|
||||
ConfigDriveURL string
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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}}"
|
||||
|
|
Loading…
Reference in New Issue