From 0566f1f999b217c4de257ecf34574db9d5f0ced6 Mon Sep 17 00:00:00 2001 From: Moss Date: Mon, 27 Jan 2020 16:49:31 +0100 Subject: [PATCH] Extract http ip discover to a new step --- builder/qemu/builder.go | 1 + builder/qemu/step_http_ip_discover.go | 21 +++++++++++ builder/qemu/step_type_boot_command.go | 3 +- .../vmware/common/step_http_ip_discover.go | 36 +++++++++++++++++++ .../vmware/common/step_type_boot_command.go | 13 +------ builder/vmware/iso/builder.go | 1 + builder/vmware/vmx/builder.go | 1 + common/step_provision.go | 1 + common/step_provision_test.go | 8 +++++ packer/provisioner.go | 1 + website/source/docs/templates/engine.html.md | 2 +- 11 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 builder/qemu/step_http_ip_discover.go create mode 100644 builder/vmware/common/step_http_ip_discover.go diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 140ad90c1..4a238e562 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -614,6 +614,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack new(stepCreateDisk), new(stepCopyDisk), new(stepResizeDisk), + new(stepHTTPIPDiscover), &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, diff --git a/builder/qemu/step_http_ip_discover.go b/builder/qemu/step_http_ip_discover.go new file mode 100644 index 000000000..d8cbb2250 --- /dev/null +++ b/builder/qemu/step_http_ip_discover.go @@ -0,0 +1,21 @@ +package qemu + +import ( + "context" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" +) + +// Step to discover the http ip +// which guests use to reach the vm host +// To make sure the IP is set before boot command and http server steps +type stepHTTPIPDiscover struct{} + +func (s *stepHTTPIPDiscover) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + hostIP := "10.0.2.2" + common.SetHTTPIP(hostIP) + + return multistep.ActionContinue +} + +func (s *stepHTTPIPDiscover) Cleanup(state multistep.StateBag) {} diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index c6aa09ea2..d61aef3d4 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -96,8 +96,7 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) log.Printf("Connected to VNC desktop: %s", c.DesktopName) - hostIP := "10.0.2.2" - common.SetHTTPIP(hostIP) + hostIP := common.GetHTTPIP() configCtx := config.ctx configCtx.Data = &bootCommandTemplateData{ hostIP, diff --git a/builder/vmware/common/step_http_ip_discover.go b/builder/vmware/common/step_http_ip_discover.go new file mode 100644 index 000000000..8d813480f --- /dev/null +++ b/builder/vmware/common/step_http_ip_discover.go @@ -0,0 +1,36 @@ +package common + +import ( + "context" + "fmt" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "log" +) + +// Step to discover the http ip +// which guests use to reach the vm host +// To make sure the IP is set before boot command and http server steps +type StepHTTPIPDiscover struct{} + +func (s *StepHTTPIPDiscover) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + + // Determine the host IP + hostIP, err := driver.HostIP(state) + if err != nil { + err := fmt.Errorf("Error detecting host IP: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Host IP for the VMware machine: %s", hostIP) + common.SetHTTPIP(hostIP) + + return multistep.ActionContinue +} + +func (*StepHTTPIPDiscover) Cleanup(multistep.StateBag) {} diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index ad615f6a4..470dd9575 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -99,18 +99,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) log.Printf("Connected to VNC desktop: %s", c.DesktopName) - // Determine the host IP - hostIP, err := driver.HostIP(state) - if err != nil { - err := fmt.Errorf("Error detecting host IP: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - log.Printf("Host IP for the VMware machine: %s", hostIP) - common.SetHTTPIP(hostIP) - + hostIP := common.GetHTTPIP() s.Ctx.Data = &bootCommandTemplateData{ hostIP, httpPort, diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 4af036035..2eab40520 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -109,6 +109,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack DisplayName: b.config.VMXDisplayName, }, &vmwcommon.StepSuppressMessages{}, + &vmwcommon.StepHTTPIPDiscover{}, &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index d00e59ab1..b0d1a1e33 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -103,6 +103,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack DisplayName: b.config.VMXDisplayName, }, &vmwcommon.StepSuppressMessages{}, + &vmwcommon.StepHTTPIPDiscover{}, &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, diff --git a/common/step_provision.go b/common/step_provision.go index 5a45fb720..730829af1 100644 --- a/common/step_provision.go +++ b/common/step_provision.go @@ -48,6 +48,7 @@ func PopulateProvisionHookData(state multistep.StateBag) map[string]interface{} } hookData["PackerRunUUID"] = os.Getenv("PACKER_RUN_UUID") + hookData["PackerHTTPAddr"] = GetHTTPAddr() // Read communicator data into hook data comm, ok := state.GetOk("communicator_config") diff --git a/common/step_provision_test.go b/common/step_provision_test.go index 2771fc616..809aaed64 100644 --- a/common/step_provision_test.go +++ b/common/step_provision_test.go @@ -39,12 +39,17 @@ func TestPopulateProvisionHookData(t *testing.T) { generatedData := map[string]interface{}{"Data": "generated"} instanceId := 11111 packerRunUUID := "1fa225b8-27d1-42d1-9117-221772213962" + httpIP := "10.0.2.2" + httpPort := "2222" + httpAddr := fmt.Sprintf("%s:%s", httpIP, httpPort) state.Put("generated_data", generatedData) state.Put("instance_id", instanceId) state.Put("communicator_config", commConfig) os.Setenv("PACKER_RUN_UUID", packerRunUUID) + SetHTTPIP(httpIP) + SetHTTPPort(httpPort) hookData := PopulateProvisionHookData(state) @@ -60,6 +65,9 @@ func TestPopulateProvisionHookData(t *testing.T) { if hookData["PackerRunUUID"] != packerRunUUID { t.Fatalf("Bad: Expecting hookData[\"PackerRunUUID\"] was %s but actual value was %s", packerRunUUID, hookData["PackerRunUUID"]) } + if hookData["PackerHTTPAddr"] != httpAddr { + t.Fatalf("Bad: Expecting hookData[\"PackerHTTPAddr\"] was %s but actual value was %s", httpAddr, hookData["PackerHTTPAddr"]) + } if hookData["Host"] != commConfig.Host() { t.Fatalf("Bad: Expecting hookData[\"Host\"] was %s but actual value was %s", commConfig.Host(), hookData["Host"]) } diff --git a/packer/provisioner.go b/packer/provisioner.go index 68f5a2946..fce6355f3 100644 --- a/packer/provisioner.go +++ b/packer/provisioner.go @@ -68,6 +68,7 @@ func BasicPlaceholderData() map[string]string { placeholderData["Password"] = fmt.Sprintf(msg, "Password") placeholderData["ConnType"] = fmt.Sprintf(msg, "Type") placeholderData["PackerRunUUID"] = fmt.Sprintf(msg, "PackerRunUUID") + placeholderData["PackerHTTPAddr"] = fmt.Sprintf(msg, "PackerHTTPAddr") placeholderData["SSHPublicKey"] = fmt.Sprintf(msg, "SSHPublicKey") placeholderData["SSHPrivateKey"] = fmt.Sprintf(msg, "SSHPrivateKey") diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index cb3ee535e..c16f8b8d9 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -76,7 +76,7 @@ Here is a full list of the available functions for reference. Valid variables to request are: "ID", "Host", "Port", "User", "Password", "ConnType", - "PackerRunUUID", "SSHPublicKey", and "SSHPrivateKey". + "PackerRunUUID", "PackerHTTPAddr", "SSHPublicKey", and "SSHPrivateKey". Depending on which communicator you are using, some of these values may be empty -- for example, the public and private keys are unique to the SSH communicator. InstanceID represents the vm being provisioned. For example,