diff --git a/builder/nutanix/config.go b/builder/nutanix/config.go index 58aa25c..e88d6f7 100644 --- a/builder/nutanix/config.go +++ b/builder/nutanix/config.go @@ -34,8 +34,9 @@ type Config struct { shutdowncommand.ShutdownConfig `mapstructure:",squash"` ClusterConfig `mapstructure:",squash"` VmConfig `mapstructure:",squash"` - ForceDeregister bool `mapstructure:"force_deregister" json:"force_deregister" required:"false"` - ImageDescription string `mapstructure:"image_description" json:"image_description" required:"false"` + ForceDeregister bool `mapstructure:"force_deregister" json:"force_deregister" required:"false"` + ImageDescription string `mapstructure:"image_description" json:"image_description" required:"false"` + WaitTimeout time.Duration `mapstructure:"ip_wait_timeout" json:"ip_wait_timeout" required:"false"` ctx interpolate.Context } @@ -159,6 +160,11 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { c.CommConfig.SSHTimeout = 20 * time.Minute } + // Define default ip_wait_timeout to 15 min + if c.WaitTimeout == 0 { + c.WaitTimeout = 15 * time.Minute + } + errs = packersdk.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) errs = packersdk.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...) errs = packersdk.MultiErrorAppend(errs, c.CommConfig.Prepare(&c.ctx)...) diff --git a/builder/nutanix/config.hcl2spec.go b/builder/nutanix/config.hcl2spec.go index 5c788bd..ee94afb 100644 --- a/builder/nutanix/config.hcl2spec.go +++ b/builder/nutanix/config.hcl2spec.go @@ -121,6 +121,7 @@ type FlatConfig struct { UserData *string `mapstructure:"user_data" json:"user_data" required:"false" cty:"user_data" hcl:"user_data"` ForceDeregister *bool `mapstructure:"force_deregister" json:"force_deregister" required:"false" cty:"force_deregister" hcl:"force_deregister"` ImageDescription *string `mapstructure:"image_description" json:"image_description" required:"false" cty:"image_description" hcl:"image_description"` + WaitTimeout *string `mapstructure:"ip_wait_timeout" json:"ip_wait_timeout" required:"false" cty:"ip_wait_timeout" hcl:"ip_wait_timeout"` } // FlatMapstructure returns a new FlatConfig. @@ -215,6 +216,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false}, "force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false}, "image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false}, + "ip_wait_timeout": &hcldec.AttrSpec{Name: "ip_wait_timeout", Type: cty.String, Required: false}, } return s } diff --git a/builder/nutanix/driver.go b/builder/nutanix/driver.go index 8ea655a..221df10 100644 --- a/builder/nutanix/driver.go +++ b/builder/nutanix/driver.go @@ -458,7 +458,12 @@ func (d *NutanixDriver) Create(req *v3.VMIntentInput) (*nutanixInstance, error) } // Wait for the VM obtain an IP address - for i := 0; i < 60; i++ { + + log.Printf("[INFO] Waiting for IP, up to timeout: %s", d.Config.WaitTimeout) + + iteration := int(d.Config.WaitTimeout.Seconds()) / 5 + + for i := 0; i < iteration; i++ { vm, err = conn.V3.GetVM(uuid) if err != nil || len(vm.Status.Resources.NicList[0].IPEndpointList) == (0) { log.Printf("Waiting VM (%s) ip configuration", uuid) diff --git a/builder/nutanix/step_build_vm.go b/builder/nutanix/step_build_vm.go index 08dbd41..c94a456 100644 --- a/builder/nutanix/step_build_vm.go +++ b/builder/nutanix/step_build_vm.go @@ -16,7 +16,6 @@ type stepBuildVM struct { func (s *stepBuildVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { //Update UI ui := state.Get("ui").(packer.Ui) - //config := state.Get("config").(*Config) ui.Say("Creating Packer Builder VM on Nutanix Cluster.") d := state.Get("driver").(Driver) config := state.Get("config").(*Config) diff --git a/docs/builders/nutanix.mdx b/docs/builders/nutanix.mdx index 5e212ec..7552f9b 100644 --- a/docs/builders/nutanix.mdx +++ b/docs/builders/nutanix.mdx @@ -21,7 +21,7 @@ These parameters allow to define information about platform and temporary VM use - `nutanix_endpoint` (string) - Prism Central FQDN or IP. - `cluster_name` or `cluster_uuid` (string) - Nutanix cluster name or uuid used to create and store image. - `os_type` (string) - OS Type ("Linux" or "Windows"). - + ### Optional - `nutanix_port` (number) - Port used for connection to Prism Central. - `nutanix_insecure` (bool) - Authorize connection to Prism Central without valid certificate. @@ -30,6 +30,7 @@ These parameters allow to define information about platform and temporary VM use - `cd_files` (array of strings) - A list of files to place onto a CD that is attached when the VM is booted. This can include either files or directories; any directories will be copied onto the CD recursively, preserving directory structure hierarchy. - `cd_label` (string) - Label of this CD Drive. - `boot_type` (string) - Type of boot used on the temporary VM ("legacy" or "UEFI"). + - `ip_wait_timeout` (duration string | ex: "0h42m0s") - Amount of time to wait for VM's IP, similar to 'ssh_timeout'. Defaults to 15m (15 minutes). See the Golang [ParseDuration](https://golang.org/pkg/time/#ParseDuration) documentation for full details. ## Output configuration These parameters allow to configure everything around image creation, from the temporary VM connection to the final image definition. diff --git a/go.mod b/go.mod index 25bdb19..41924b2 100644 --- a/go.mod +++ b/go.mod @@ -90,11 +90,11 @@ require ( github.com/ulikunitz/xz v0.5.10 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect - golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect + golang.org/x/net v0.5.0 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect - golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/term v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/api v0.56.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index cef9d86..080dc7a 100644 --- a/go.sum +++ b/go.sum @@ -719,8 +719,8 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5o golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -817,11 +817,11 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -830,8 +830,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=