diff --git a/iso/builder.go b/iso/builder.go index c42acd0d4..cb21ef77d 100644 --- a/iso/builder.go +++ b/iso/builder.go @@ -74,6 +74,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &StepBootCommand{ Config: &b.config.BootConfig, + Ctx: b.config.ctx, + VMName: b.config.VMName, }, &common.StepWaitForIp{}, &communicator.StepConnect{ diff --git a/iso/config.go b/iso/config.go index 21daf494e..4f88fafce 100644 --- a/iso/config.go +++ b/iso/config.go @@ -37,6 +37,11 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { err := config.Decode(c, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &c.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "boot_command", + }, + }, }, raws...) if err != nil { return nil, nil, err diff --git a/iso/step_boot_command.go b/iso/step_boot_command.go index 895df03a1..0edec8c53 100644 --- a/iso/step_boot_command.go +++ b/iso/step_boot_command.go @@ -3,12 +3,14 @@ package iso import ( "context" "fmt" - "github.com/hashicorp/packer/common" + packerCommon "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" "github.com/jetbrains-infra/packer-builder-vsphere/driver" "golang.org/x/mobile/event/key" "log" + "net" "os" "strings" "time" @@ -18,10 +20,17 @@ import ( type BootConfig struct { BootCommand []string `mapstructure:"boot_command"` RawBootWait string `mapstructure:"boot_wait"` // example: "1m30s"; default: "10s" + HTTPIP string `mapstructure:"http_ip"` bootWait time.Duration } +type bootCommandTemplateData struct { + HTTPIP string + HTTPPort uint + Name string +} + func (c *BootConfig) Prepare() []error { var errs []error @@ -40,6 +49,8 @@ func (c *BootConfig) Prepare() []error { type StepBootCommand struct { Config *BootConfig + VMName string + Ctx interpolate.Context } var special = map[string]key.Code{ @@ -71,10 +82,10 @@ var special = map[string]key.Code{ "": key.CodeDownArrow, } -var keyInterval = common.PackerKeyDefault +var keyInterval = packerCommon.PackerKeyDefault func init() { - if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { + if delay, err := time.ParseDuration(os.Getenv(packerCommon.PackerKeyEnv)); err == nil { keyInterval = delay } } @@ -101,13 +112,29 @@ WAITLOOP: } } - ui.Say("Typing boot command...") + ip := getHostIP(s.Config.HTTPIP) + err := packerCommon.SetHTTPIP(ip) + if err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + s.Ctx.Data = &bootCommandTemplateData{ + ip, + state.Get("http_port").(uint), + s.VMName, + } + ui.Say("Typing boot command...") var keyAlt bool var keyCtrl bool var keyShift bool + for _, command := range s.Config.BootCommand { + message, err := interpolate.Render(command, &s.Ctx) + if err != nil { + state.Put("error", err) + return multistep.ActionHalt + } - for _, message := range s.Config.BootCommand { for len(message) > 0 { if _, ok := state.GetOk(multistep.StateCancelled); ok { return multistep.ActionHalt @@ -205,3 +232,24 @@ WAITLOOP: } func (s *StepBootCommand) Cleanup(state multistep.StateBag) {} + +func getHostIP(s string) string { + if net.ParseIP(s) != nil { + return s + } + + var ipaddr string + addrs, err := net.InterfaceAddrs() + if err != nil { + fmt.Println(err) + os.Exit(2) + } + + for _, a := range addrs { + if ip, ok := a.(*net.IPNet); ok && !ip.IP.IsLoopback() { + ipaddr = ip.IP.String() + break + } + } + return ipaddr +} diff --git a/iso/step_create.go b/iso/step_create.go index 30237ee96..122e542e8 100644 --- a/iso/step_create.go +++ b/iso/step_create.go @@ -3,13 +3,10 @@ package iso import ( "context" "fmt" - packerCommon "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/jetbrains-infra/packer-builder-vsphere/common" "github.com/jetbrains-infra/packer-builder-vsphere/driver" - "net" - "os" ) type CreateConfig struct { @@ -26,29 +23,6 @@ type CreateConfig struct { USBController bool `mapstructure:"usb_controller"` Notes string `mapstructure:"notes"` - - HTTPIP string `mapstructure:"http_ip"` -} - -func getHostIP(s string) string { - if net.ParseIP(s) != nil { - return s - } - - var ipaddr string - addrs, err := net.InterfaceAddrs() - if err != nil { - fmt.Println(err) - os.Exit(2) - } - - for _, a := range addrs { - if ip, ok := a.(*net.IPNet); ok && !ip.IP.IsLoopback() { - ipaddr = ip.IP.String() - break - } - } - return ipaddr } func (c *CreateConfig) Prepare() []error { @@ -92,8 +66,6 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste } } - packerCommon.SetHTTPIP(getHostIP(s.Config.HTTPIP)) - ui.Say("Creating VM...") vm, err := d.CreateVM(&driver.CreateConfig{ DiskThinProvisioned: s.Config.DiskThinProvisioned,