mirror of
https://github.com/hashicorp/packer.git
synced 2026-06-13 18:50:11 -04:00
Move driver_esx5 to commons and allow it to be instantiated wtih NewDriver()
This commit is contained in:
parent
a66b6e0d48
commit
46cfb5a30c
5 changed files with 234 additions and 101 deletions
|
|
@ -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")
|
||||
}
|
||||
|
||||
97
builder/vmware/common/driver_esx5_test.go
Normal file
97
builder/vmware/common/driver_esx5_test.go
Normal file
|
|
@ -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…
Reference in a new issue