Move driver_esx5 to commons and allow it to be instantiated wtih NewDriver()

pull/6927/head
Alexander Laamanen 9 years ago committed by Megan Marsh
parent a66b6e0d48
commit 46cfb5a30c

@ -83,44 +83,61 @@ type Driver interface {
// system, or an error if the driver couldn't be initialized.
func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) {
drivers := []Driver{}
switch runtime.GOOS {
case "darwin":
log.Printf("**** NewDriver()")
if dconfig.RemoteType != "" {
log.Printf("**** Creating the remote driver.")
drivers = []Driver{
&Fusion6Driver{
Fusion5Driver: Fusion5Driver{
&ESX5Driver{
Host: dconfig.RemoteHost,
Port: dconfig.RemotePort,
Username: dconfig.RemoteUser,
Password: dconfig.RemotePassword,
PrivateKey: dconfig.RemotePrivateKey,
Datastore: dconfig.RemoteDatastore,
CacheDatastore: dconfig.RemoteCacheDatastore,
CacheDirectory: dconfig.RemoteCacheDirectory,
},
}
} else {
switch runtime.GOOS {
case "darwin":
drivers = []Driver{
&Fusion6Driver{
Fusion5Driver: Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
},
&Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
},
&Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
}
case "linux":
fallthrough
case "windows":
drivers = []Driver{
&Workstation10Driver{
Workstation9Driver: Workstation9Driver{
}
case "linux":
fallthrough
case "windows":
drivers = []Driver{
&Workstation10Driver{
Workstation9Driver: Workstation9Driver{
SSHConfig: config,
},
},
&Workstation9Driver{
SSHConfig: config,
},
},
&Workstation9Driver{
SSHConfig: config,
},
&Player6Driver{
Player5Driver: Player5Driver{
&Player6Driver{
Player5Driver: Player5Driver{
SSHConfig: config,
},
},
&Player5Driver{
SSHConfig: config,
},
},
&Player5Driver{
SSHConfig: config,
},
}
default:
return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS)
}
default:
return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS)
}
errs := ""

@ -7,7 +7,16 @@ import (
)
type DriverConfig struct {
FusionAppPath string `mapstructure:"fusion_app_path"`
FusionAppPath string `mapstructure:"fusion_app_path"`
RemoteType string `mapstructure:"remote_type"`
RemoteDatastore string `mapstructure:"remote_datastore"`
RemoteCacheDatastore string `mapstructure:"remote_cache_datastore"`
RemoteCacheDirectory string `mapstructure:"remote_cache_directory"`
RemoteHost string `mapstructure:"remote_host"`
RemotePort uint `mapstructure:"remote_port"`
RemoteUser string `mapstructure:"remote_username"`
RemotePassword string `mapstructure:"remote_password"`
RemotePrivateKey string `mapstructure:"remote_private_key_file"`
}
func (c *DriverConfig) Prepare(ctx *interpolate.Context) []error {

@ -1,4 +1,4 @@
package iso
package common
import (
"bufio"
@ -43,7 +43,20 @@ type ESX5Driver struct {
}
func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
return errors.New("Cloning is not supported with the ESX driver.")
ret, err := d.sh("test -r %s", src)
if err != nil {
return errors.New("Source VMX not found")
}
ret, err = d.run(nil, "ls")
files := strings.Split(ret, "\n")
if err != nil {
return errors.New("Error running cmd")
}
for _, f := range files {
log.Printf("One file is: %s", f)
}
log.Printf("Return was: %s", ret)
}
func (d *ESX5Driver) CompactDisk(diskPathLocal string) error {
@ -375,74 +388,71 @@ func (ESX5Driver) UpdateVMX(_, password string, port uint, data map[string]strin
}
func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) {
config := state.Get("config").(*Config)
sshc := config.SSHConfig.Comm
port := sshc.SSHPort
if sshc.Type == "winrm" {
port = sshc.WinRMPort
}
if address := config.CommConfig.Host(); address != "" {
return address, nil
}
r, err := d.esxcli("network", "vm", "list")
if err != nil {
return "", err
}
// The value in the Name field returned by 'esxcli network vm list'
// corresponds directly to the value of displayName set in the VMX file
var displayName string
if v, ok := state.GetOk("display_name"); ok {
displayName = v.(string)
}
record, err := r.find("Name", displayName)
if err != nil {
return "", err
}
wid := record["WorldID"]
if wid == "" {
return "", errors.New("VM WorldID not found")
}
r, err = d.esxcli("network", "vm", "port", "list", "-w", wid)
if err != nil {
return "", err
}
// Loop through interfaces
for {
record, err = r.read()
if err == io.EOF {
break
}
if err != nil {
return "", err
}
if record["IPAddress"] == "0.0.0.0" {
continue
}
// When multiple NICs are connected to the same network, choose
// one that has a route back. This Dial should ensure that.
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", record["IPAddress"], port), 2*time.Second)
if err != nil {
if e, ok := err.(*net.OpError); ok {
if e.Timeout() {
log.Printf("Timeout connecting to %s", record["IPAddress"])
continue
} else if strings.Contains(e.Error(), "connection refused") {
log.Printf("Connection refused when connecting to: %s", record["IPAddress"])
continue
}
}
} else {
defer conn.Close()
address := record["IPAddress"]
return address, nil
}
}
// config := state.Get("config").(*Config)
// sshc := config.SSHConfig.Comm
// port := sshc.SSHPort
// if sshc.Type == "winrm" {
// port = sshc.WinRMPort
// }
//
// if address, ok := state.GetOk("vm_address"); ok {
// return address.(string), nil
// }
//
// if address := config.CommConfig.Host(); address != "" {
// state.Put("vm_address", address)
// return address, nil
// }
//
// r, err := d.esxcli("network", "vm", "list")
// if err != nil {
// return "", err
// }
//
// record, err := r.find("Name", config.VMName)
// if err != nil {
// return "", err
// }
// wid := record["WorldID"]
// if wid == "" {
// return "", errors.New("VM WorldID not found")
// }
//
// r, err = d.esxcli("network", "vm", "port", "list", "-w", wid)
// if err != nil {
// return "", err
// }
//
// // Loop through interfaces
// for {
// record, err = r.read()
// if err == io.EOF {
// break
// }
// if err != nil {
// return "", err
// }
//
// if record["IPAddress"] == "0.0.0.0" {
// continue
// }
// // When multiple NICs are connected to the same network, choose
// // one that has a route back. This Dial should ensure that.
// conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", record["IPAddress"], port), 2*time.Second)
// if err != nil {
// if e, ok := err.(*net.OpError); ok {
// if e.Timeout() {
// log.Printf("Timeout connecting to %s", record["IPAddress"])
// continue
// }
// }
// } else {
// defer conn.Close()
// address := record["IPAddress"]
// state.Put("vm_address", address)
// return address, nil
// }
// }
return "", errors.New("No interface on the VM has an IP address ready")
}

@ -0,0 +1,97 @@
package common
import (
"fmt"
"net"
"testing"
"github.com/mitchellh/multistep"
)
func TestESX5Driver_implDriver(t *testing.T) {
var _ Driver = new(ESX5Driver)
}
func TestESX5Driver_UpdateVMX(t *testing.T) {
var driver ESX5Driver
data := make(map[string]string)
driver.UpdateVMX("0.0.0.0", "", 5900, data)
if _, ok := data["remotedisplay.vnc.ip"]; ok {
// Do not add the remotedisplay.vnc.ip on ESXi
t.Fatal("invalid VMX data key: remotedisplay.vnc.ip")
}
if enabled := data["remotedisplay.vnc.enabled"]; enabled != "TRUE" {
t.Errorf("bad VMX data for key remotedisplay.vnc.enabled: %v", enabled)
}
if port := data["remotedisplay.vnc.port"]; port != fmt.Sprint(port) {
t.Errorf("bad VMX data for key remotedisplay.vnc.port: %v", port)
}
}
func TestESX5Driver_implOutputDir(t *testing.T) {
var _ OutputDir = new(ESX5Driver)
}
func TestESX5Driver_implVNCAddressFinder(t *testing.T) {
var _ VNCAddressFinder = new(ESX5Driver)
}
func TestESX5Driver_implRemoteDriver(t *testing.T) {
var _ RemoteDriver = new(ESX5Driver)
}
func TestESX5Driver_HostIP(t *testing.T) {
expected_host := "127.0.0.1"
//create mock SSH server
listen, _ := net.Listen("tcp", fmt.Sprintf("%s:0", expected_host))
port := listen.Addr().(*net.TCPAddr).Port
defer listen.Close()
driver := ESX5Driver{Host: "localhost", Port: uint(port)}
if host, _ := driver.HostIP(); host != expected_host {
t.Error(fmt.Sprintf("Expected string, %s but got %s", expected_host, host))
}
}
func TestESX5Driver_CommHost(t *testing.T) {
const expected_host = "127.0.0.1"
config := testConfig()
config["communicator"] = "winrm"
config["winrm_username"] = "username"
config["winrm_password"] = "password"
config["winrm_host"] = expected_host
var b Builder
warns, err := b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if host := b.config.CommConfig.Host(); host != expected_host {
t.Fatalf("setup failed, bad host name: %s", host)
}
state := new(multistep.BasicStateBag)
state.Put("config", &b.config)
var driver ESX5Driver
host, err := driver.CommHost(state)
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if host != expected_host {
t.Errorf("bad host name: %s", host)
}
address, ok := state.GetOk("vm_address")
if !ok {
t.Error("state not updated with vm_address")
}
if address.(string) != expected_host {
t.Errorf("bad vm_address: %s", address.(string))
}
}

@ -16,7 +16,7 @@ func NewDriver(config *Config) (vmwcommon.Driver, error) {
}
drivers = []vmwcommon.Driver{
&ESX5Driver{
&vmwcommon.ESX5Driver{
Host: config.RemoteHost,
Port: config.RemotePort,
Username: config.RemoteUser,

Loading…
Cancel
Save