Re-enable the CommHost() call. Use common's driver factory.

This commit is contained in:
Alexander Laamanen 2017-02-01 13:32:02 +02:00 committed by Megan Marsh
parent ba22090bc9
commit 7b5943160b
7 changed files with 79 additions and 119 deletions

View File

@ -15,6 +15,7 @@ import (
"strings"
"time"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
)
@ -81,11 +82,9 @@ type Driver interface {
// NewDriver returns a new driver implementation for this operating
// system, or an error if the driver couldn't be initialized.
func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) {
func NewDriver(dconfig *DriverConfig, config *SSHConfig, commConfig *communicator.Config, vmName string) (Driver, error) {
drivers := []Driver{}
log.Printf("**** NewDriver()")
if dconfig.RemoteType != "" {
log.Printf("**** Creating the remote driver.")
drivers = []Driver{
&ESX5Driver{
Host: dconfig.RemoteHost,
@ -96,6 +95,8 @@ func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) {
Datastore: dconfig.RemoteDatastore,
CacheDatastore: dconfig.RemoteCacheDatastore,
CacheDirectory: dconfig.RemoteCacheDirectory,
VMName: vmName,
CommConfig: *commConfig,
},
}

View File

@ -16,8 +16,8 @@ import (
"strings"
"time"
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
"github.com/hashicorp/packer/communicator/ssh"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
helperssh "github.com/hashicorp/packer/helper/ssh"
"github.com/hashicorp/packer/packer"
@ -37,6 +37,8 @@ type ESX5Driver struct {
Datastore string
CacheDatastore string
CacheDirectory string
VMName string
CommConfig communicator.Config
comm packer.Communicator
outputDir string
@ -56,9 +58,9 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
log.Printf("Source: %s\n", srcVmx)
log.Printf("Dest: %s\n", dstVmx)
err := d.sh("mkdir", dstDir)
err := d.MkdirAll()
if err != nil {
return fmt.Errorf("Failed to create the destination directory %s: %s", dstDir, err)
return fmt.Errorf("Failed to create the destination directory %s: %s", d.outputDir, err)
}
err = d.sh("cp", srcVmx, dstVmx)
@ -458,71 +460,66 @@ 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, 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
// }
// }
port := d.CommConfig.Port()
if address, ok := state.GetOk("vm_address"); ok {
return address.(string), nil
}
if address := d.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", d.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")
}

View File

@ -70,6 +70,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
// Connect to VNC
ui.Say(fmt.Sprintf("Connecting to VM via VNC (%s:%d)", vncIp, vncPort))
nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", vncIp, vncPort))
if err != nil {
err := fmt.Errorf("Error connecting to VNC: %s", err)

View File

@ -76,17 +76,6 @@ type Config struct {
VMXDiskTemplatePath string `mapstructure:"vmx_disk_template_path"`
VMXTemplatePath string `mapstructure:"vmx_template_path"`
// remote vsphere
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"`
CommConfig communicator.Config `mapstructure:",squash"`
ctx interpolate.Context

View File

@ -9,36 +9,5 @@ import (
// NewDriver returns a new driver implementation for this operating
// system, or an error if the driver couldn't be initialized.
func NewDriver(config *Config) (vmwcommon.Driver, error) {
drivers := []vmwcommon.Driver{}
if config.RemoteType == "" {
return vmwcommon.NewDriver(&config.DriverConfig, &config.SSHConfig)
}
drivers = []vmwcommon.Driver{
&vmwcommon.ESX5Driver{
Host: config.RemoteHost,
Port: config.RemotePort,
Username: config.RemoteUser,
Password: config.RemotePassword,
PrivateKeyFile: config.RemotePrivateKey,
Datastore: config.RemoteDatastore,
CacheDatastore: config.RemoteCacheDatastore,
CacheDirectory: config.RemoteCacheDirectory,
},
}
errs := ""
for _, driver := range drivers {
err := driver.Verify()
if err == nil {
return driver, nil
}
errs += "* " + err.Error() + "\n"
}
return nil, fmt.Errorf(
"Unable to initialize any driver for this platform. The errors\n"+
"from each driver are shown below. Please fix at least one driver\n"+
"to continue:\n%s", errs)
return vmwcommon.NewDriver(&config.DriverConfig, &config.SSHConfig, &config.CommConfig, config.VMName)
}

View File

@ -34,7 +34,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
// Run executes a Packer build and returns a packer.Artifact representing
// a VMware image.
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
driver, err := vmwcommon.NewDriver(&b.config.DriverConfig, &b.config.SSHConfig)
driver, err := vmwcommon.NewDriver(&b.config.DriverConfig, &b.config.SSHConfig, &b.config.CommConfig, b.config.VMName)
if err != nil {
return nil, fmt.Errorf("Failed creating VMware driver: %s", err)
}
@ -83,10 +83,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&vmwcommon.StepUploadVMX{
RemoteType: b.config.RemoteType,
},
&vmwcommon.StepRegister{
Format: "foo",
KeepRegistered: false,
},
&vmwcommon.StepConfigureVNC{
Enabled: !b.config.DisableVNC,
VNCBindAddress: b.config.VNCBindAddress,
@ -94,6 +90,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
VNCPortMax: b.config.VNCPortMax,
VNCDisablePassword: b.config.VNCDisablePassword,
},
&vmwcommon.StepRegister{
Format: "foo",
KeepRegistered: false,
},
&vmwcommon.StepRun{
DurationBeforeStop: 5 * time.Second,
Headless: b.config.Headless,

View File

@ -8,6 +8,7 @@ import (
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
@ -33,6 +34,8 @@ type Config struct {
SourcePath string `mapstructure:"source_path"`
VMName string `mapstructure:"vm_name"`
CommConfig communicator.Config `mapstructure:",squash"`
ctx interpolate.Context
}