From dfee3eb8ef9938946d9abf95f09f6379680db25b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 5 Jun 2013 20:40:39 -0700 Subject: [PATCH] builder/vmware: Properly detect host IP --- builder/vmware/host_ip.go | 43 ++++++++++++++++++++++++ builder/vmware/host_ip_test.go | 11 ++++++ builder/vmware/step_type_boot_command.go | 11 +++++- builder/vmware/step_wait_for_ip.go | 2 +- 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 builder/vmware/host_ip.go create mode 100644 builder/vmware/host_ip_test.go diff --git a/builder/vmware/host_ip.go b/builder/vmware/host_ip.go new file mode 100644 index 000000000..90fc9a6fc --- /dev/null +++ b/builder/vmware/host_ip.go @@ -0,0 +1,43 @@ +package vmware + +import ( + "bytes" + "errors" + "os/exec" + "regexp" +) + +// Interface to help find the host IP that is available from within +// the VMware virtual machines. +type HostIPFinder interface { + HostIP() (string, error) +} + +// IfconfigIPFinder finds the host IP based on the output of `ifconfig`. +type IfconfigIPFinder struct { + Device string +} + +func (f *IfconfigIPFinder) HostIP() (string, error) { + ifconfigPath, err := exec.LookPath("ifconfig") + if err != nil { + return "", err + } + + stdout := new(bytes.Buffer) + + cmd := exec.Command(ifconfigPath, f.Device) + cmd.Stdout = stdout + cmd.Stderr = new(bytes.Buffer) + if err := cmd.Run(); err != nil { + return "", err + } + + re := regexp.MustCompile(`inet\s*(.+?)\s`) + matches := re.FindStringSubmatch(stdout.String()) + if matches == nil { + return "", errors.New("IP not found in ifconfig output...") + } + + return matches[1], nil +} diff --git a/builder/vmware/host_ip_test.go b/builder/vmware/host_ip_test.go new file mode 100644 index 000000000..0f3d9266e --- /dev/null +++ b/builder/vmware/host_ip_test.go @@ -0,0 +1,11 @@ +package vmware + +import "testing" + +func TestIfconfigIPFinder_Impl(t *testing.T) { + var raw interface{} + raw = &IfconfigIPFinder{} + if _, ok := raw.(HostIPFinder); !ok { + t.Fatalf("IfconfigIPFinder is not a host IP finder") + } +} diff --git a/builder/vmware/step_type_boot_command.go b/builder/vmware/step_type_boot_command.go index b4bba8cc4..e340ae4d6 100644 --- a/builder/vmware/step_type_boot_command.go +++ b/builder/vmware/step_type_boot_command.go @@ -41,6 +41,7 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc ui := state["ui"].(packer.Ui) vncPort := state["vnc_port"].(uint) + // Connect to VNC ui.Say("Connecting to VM via VNC") nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort)) if err != nil { @@ -58,8 +59,16 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc log.Printf("Connected to VNC desktop: %s", c.DesktopName) + // Determine the host IP + ipFinder := &IfconfigIPFinder{"vmnet8"} + hostIp, err := ipFinder.HostIP() + if err != nil { + ui.Error(fmt.Sprintf("Error detecting host IP: %s", err)) + return multistep.ActionHalt + } + tplData := &bootCommandTemplateData{ - "127.0.0.1", + hostIp, httpPort, config.VMName, } diff --git a/builder/vmware/step_wait_for_ip.go b/builder/vmware/step_wait_for_ip.go index 24a4b10c5..e5fe5aa93 100644 --- a/builder/vmware/step_wait_for_ip.go +++ b/builder/vmware/step_wait_for_ip.go @@ -19,7 +19,7 @@ func (stepWaitForIP) Run(state map[string]interface{}) multistep.StepAction { ui := state["ui"].(packer.Ui) ui.Say("Waiting for SSH to become available...") - select{} + select {} return multistep.ActionContinue }