diff --git a/builder/vsphere/iso/config.hcl2spec.go b/builder/vsphere/iso/config.hcl2spec.go index e48a385d5..5723d9946 100644 --- a/builder/vsphere/iso/config.hcl2spec.go +++ b/builder/vsphere/iso/config.hcl2spec.go @@ -29,12 +29,7 @@ type FlatConfig struct { GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"` Firmware *string `mapstructure:"firmware" cty:"firmware"` DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"` - DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"` - DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"` - DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"` Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"` - Network *string `mapstructure:"network" cty:"network"` - NetworkCard *string `mapstructure:"network_card" cty:"network_card"` NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"` USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"` Notes *string `mapstructure:"notes" cty:"notes"` @@ -158,12 +153,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false}, "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, "disk_controller_type": &hcldec.AttrSpec{Name: "disk_controller_type", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, - "disk_thin_provisioned": &hcldec.AttrSpec{Name: "disk_thin_provisioned", Type: cty.Bool, Required: false}, - "disk_eagerly_scrub": &hcldec.AttrSpec{Name: "disk_eagerly_scrub", Type: cty.Bool, Required: false}, "storage": &hcldec.BlockListSpec{TypeName: "storage", Nested: hcldec.ObjectSpec((*FlatDiskConfig)(nil).HCL2Spec())}, - "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, - "network_card": &hcldec.AttrSpec{Name: "network_card", Type: cty.String, Required: false}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())}, "usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.Bool, Required: false}, "notes": &hcldec.AttrSpec{Name: "notes", Type: cty.String, Required: false}, diff --git a/builder/vsphere/iso/step_create.go b/builder/vsphere/iso/step_create.go index 6ebd9d7e8..ea3e71bdd 100644 --- a/builder/vsphere/iso/step_create.go +++ b/builder/vsphere/iso/step_create.go @@ -79,18 +79,8 @@ type CreateConfig struct { Firmware string `mapstructure:"firmware"` // Set VM disk controller type. Example `pvscsi`. DiskControllerType string `mapstructure:"disk_controller_type"` - // The size of the disk in MB. - DiskSize int64 `mapstructure:"disk_size"` - // Enable VMDK thin provisioning for VM. Defaults to `false`. - DiskThinProvisioned bool `mapstructure:"disk_thin_provisioned"` - // Enable VMDK eager scrubbing for VM. Defaults to `false`. - DiskEagerlyScrub bool `mapstructure:"disk_eagerly_scrub"` // A collection of one or more disks to be provisioned along with the VM. Storage []DiskConfig `mapstructure:"storage"` - // Set network VM will be connected to. - Network string `mapstructure:"network"` - // Set VM network card type. Example `vmxnet3`. - NetworkCard string `mapstructure:"network_card"` // Network adapters NICs []NIC `mapstructure:"network_adapters"` // Create USB controller for virtual machine. Defaults to `false`. @@ -108,8 +98,6 @@ func (c *CreateConfig) Prepare() []error { errs = append(errs, fmt.Errorf("storage[%d].'disk_size' is required", i)) } } - } else if c.DiskSize == 0 { - errs = append(errs, fmt.Errorf("'disk_size' or 'storage' is required")) } if c.GuestOSType == "" { @@ -144,11 +132,6 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste // add network/network card an the first nic for backwards compatibility in the type is defined var networkCards []driver.NIC - if s.Config.NetworkCard != "" { - networkCards = append(networkCards, driver.NIC{ - NetworkCard: s.Config.NetworkCard, - Network: s.Config.Network}) - } for _, nic := range s.Config.NICs { networkCards = append(networkCards, driver.NIC{ Network: nic.Network, @@ -160,13 +143,6 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste // add disk as the first drive for backwards compatibility if the type is defined var disks []driver.Disk - if s.Config.DiskSize != 0 { - disks = append(disks, driver.Disk{ - DiskSize: s.Config.DiskSize, - DiskEagerlyScrub: s.Config.DiskEagerlyScrub, - DiskThinProvisioned: s.Config.DiskThinProvisioned, - }) - } for _, disk := range s.Config.Storage { disks = append(disks, driver.Disk{ DiskSize: disk.DiskSize, diff --git a/builder/vsphere/iso/step_create.hcl2spec.go b/builder/vsphere/iso/step_create.hcl2spec.go index 9f1e31fdf..7cf143141 100644 --- a/builder/vsphere/iso/step_create.hcl2spec.go +++ b/builder/vsphere/iso/step_create.hcl2spec.go @@ -9,19 +9,14 @@ import ( // FlatCreateConfig is an auto-generated flat version of CreateConfig. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatCreateConfig struct { - Version *uint `mapstructure:"vm_version" cty:"vm_version"` - GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"` - Firmware *string `mapstructure:"firmware" cty:"firmware"` - DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"` - DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"` - DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"` - DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"` - Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"` - Network *string `mapstructure:"network" cty:"network"` - NetworkCard *string `mapstructure:"network_card" cty:"network_card"` - NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"` - USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"` - Notes *string `mapstructure:"notes" cty:"notes"` + Version *uint `mapstructure:"vm_version" cty:"vm_version"` + GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"` + Firmware *string `mapstructure:"firmware" cty:"firmware"` + DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"` + Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"` + NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"` + USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"` + Notes *string `mapstructure:"notes" cty:"notes"` } // FlatMapstructure returns a new FlatCreateConfig. @@ -36,19 +31,14 @@ func (*CreateConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec. // The decoded values from this spec will then be applied to a FlatCreateConfig. func (*FlatCreateConfig) HCL2Spec() map[string]hcldec.Spec { s := map[string]hcldec.Spec{ - "vm_version": &hcldec.AttrSpec{Name: "vm_version", Type: cty.Number, Required: false}, - "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false}, - "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, - "disk_controller_type": &hcldec.AttrSpec{Name: "disk_controller_type", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, - "disk_thin_provisioned": &hcldec.AttrSpec{Name: "disk_thin_provisioned", Type: cty.Bool, Required: false}, - "disk_eagerly_scrub": &hcldec.AttrSpec{Name: "disk_eagerly_scrub", Type: cty.Bool, Required: false}, - "storage": &hcldec.BlockListSpec{TypeName: "storage", Nested: hcldec.ObjectSpec((*FlatDiskConfig)(nil).HCL2Spec())}, - "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, - "network_card": &hcldec.AttrSpec{Name: "network_card", Type: cty.String, Required: false}, - "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())}, - "usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.Bool, Required: false}, - "notes": &hcldec.AttrSpec{Name: "notes", Type: cty.String, Required: false}, + "vm_version": &hcldec.AttrSpec{Name: "vm_version", Type: cty.Number, Required: false}, + "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false}, + "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, + "disk_controller_type": &hcldec.AttrSpec{Name: "disk_controller_type", Type: cty.String, Required: false}, + "storage": &hcldec.BlockListSpec{TypeName: "storage", Nested: hcldec.ObjectSpec((*FlatDiskConfig)(nil).HCL2Spec())}, + "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())}, + "usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.Bool, Required: false}, + "notes": &hcldec.AttrSpec{Name: "notes", Type: cty.String, Required: false}, } return s } diff --git a/fix/fixer.go b/fix/fixer.go index 11bd4160c..859e6e3aa 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -49,6 +49,7 @@ func init() { "comm-config": new(FixerCommConfig), "ssh-wait-timeout": new(FixerSSHTimout), "docker-tag-tags": new(FixerDockerTagtoTags), + "vsphere-iso-net-disk": new(FixerVSphereNetworkDisk), } FixerOrder = []string{ @@ -81,5 +82,6 @@ func init() { "galaxy-command", "comm-config", "ssh-wait-timeout", + "vsphere-iso-net-disk", } } diff --git a/fix/fixer_vsphere_network_storage.go b/fix/fixer_vsphere_network_storage.go new file mode 100644 index 000000000..0bb60c670 --- /dev/null +++ b/fix/fixer_vsphere_network_storage.go @@ -0,0 +1,110 @@ +package fix + +import ( + "github.com/mitchellh/mapstructure" +) + +// FixerVSphereNetworkDisk changes vsphere-iso network and networkCard fields into a network adapter and +// changes the disk_size, disk_thin_provisioned, and disk_eagerly_scrub into a storage adapter +type FixerVSphereNetworkDisk struct{} + +func (FixerVSphereNetworkDisk) Fix(input map[string]interface{}) (map[string]interface{}, error) { + // The type we'll decode into; we only care about builders + type template struct { + Builders []map[string]interface{} + } + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.Decode(input, &tpl); err != nil { + return nil, err + } + + for _, builder := range tpl.Builders { + builderTypeRaw, ok := builder["type"] + if !ok { + continue + } + + builderType, ok := builderTypeRaw.(string) + if !ok { + continue + } + + if builderType != "vsphere-iso" { + continue + } + + var networkAdapters []interface{} + nic := make(map[string]interface{}) + hasNetwork := false + + networkRaw, ok := builder["network"] + if ok { + nic["network"] = networkRaw + delete(builder, "network") + hasNetwork = true + } + + networkCardRaw, ok := builder["networkCard"] + if ok { + nic["networkCard"] = networkCardRaw + delete(builder, "networkCard") + hasNetwork = true + } + + if hasNetwork { + networkAdapters = append(networkAdapters, nic) + adaptersRaw, ok := builder["network_adapters"] + if ok { + existingAdapters := adaptersRaw.([]interface{}) + networkAdapters = append(networkAdapters, existingAdapters...) + } + + builder["network_adapters"] = networkAdapters + } + + var storage []interface{} + disk := make(map[string]interface{}) + hasStorage := false + + diskSizeRaw, ok := builder["disk_size"] + if ok { + disk["disk_size"] = diskSizeRaw + delete(builder, "disk_size") + hasStorage = true + } + + discThinProvisionedRaw, ok := builder["disk_thin_provisioned"] + if ok { + disk["disk_thin_provisioned"] = discThinProvisionedRaw + hasStorage = true + delete(builder, "disk_thin_provisioned") + } + + diskEagerlyScrubRaw, ok := builder["disk_eagerly_scrub"] + if ok { + disk["disk_eagerly_scrub"] = diskEagerlyScrubRaw + hasStorage = true + delete(builder, "disk_eagerly_scrub") + } + + if hasStorage { + storage = append(storage, disk) + storageRaw, ok := builder["storage"] + if ok { + existingStorage := storageRaw.([]interface{}) + storage = append(storage, existingStorage...) + } + + builder["storage"] = storage + } + } + + input["builders"] = tpl.Builders + return input, nil +} + +func (FixerVSphereNetworkDisk) Synopsis() string { + return `Removes deprecated network and disk fields from "vsphere-iso" builder` +} diff --git a/fix/fixer_vsphere_network_storage_test.go b/fix/fixer_vsphere_network_storage_test.go new file mode 100644 index 000000000..b9d23b26f --- /dev/null +++ b/fix/fixer_vsphere_network_storage_test.go @@ -0,0 +1,138 @@ +package fix + +import ( + "reflect" + "testing" +) + +func TestFixerVSphereNetwork_impl(t *testing.T) { + var _ Fixer = new(FixerVSphereNetworkDisk) +} + +func TestFixerVSphereNetwork_Fix(t *testing.T) { + cases := []struct { + Input map[string]interface{} + Expected map[string]interface{} + }{ + { + Input: map[string]interface{}{ + "type": "vsphere-iso", + "network": "", + "networkCard": "vmxnet3", + "disk_size": 5000, + }, + + Expected: map[string]interface{}{ + "type": "vsphere-iso", + "network_adapters": []interface{}{ + map[string]interface{}{ + "network": "", + "networkCard": "vmxnet3", + }, + }, + "storage": []interface{}{ + map[string]interface{}{ + "disk_size": 5000, + }, + }, + }, + }, + { + Input: map[string]interface{}{ + "type": "vsphere-iso", + "network": "myNetwork", + "networkCard": "vmxnet3", + "disk_size": 5000, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + }, + + Expected: map[string]interface{}{ + "type": "vsphere-iso", + "network_adapters": []interface{}{ + map[string]interface{}{ + "network": "myNetwork", + "networkCard": "vmxnet3", + }, + }, + "storage": []interface{}{ + map[string]interface{}{ + "disk_size": 5000, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + }, + }, + }, + }, + { + Input: map[string]interface{}{ + "type": "vsphere-iso", + "network": "myNetwork", + "networkCard": "vmxnet3", + "disk_size": 5000, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + "network_adapters": []interface{}{ + map[string]interface{}{ + "network": "net1", + "networkCard": "vmxnet3", + }, + }, + "storage": []interface{}{ + map[string]interface{}{ + "disk_size": 5001, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + }, + }, + }, + + Expected: map[string]interface{}{ + "type": "vsphere-iso", + "network_adapters": []interface{}{ + map[string]interface{}{ + "network": "myNetwork", + "networkCard": "vmxnet3", + }, + map[string]interface{}{ + "network": "net1", + "networkCard": "vmxnet3", + }, + }, + "storage": []interface{}{ + map[string]interface{}{ + "disk_size": 5000, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + }, + map[string]interface{}{ + "disk_size": 5001, + "disk_thin_provisioned": true, + "disk_eagerly_scrub": true, + }, + }, + }, + }, + } + + for _, tc := range cases { + var f FixerVSphereNetworkDisk + + input := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Input}, + } + + expected := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Expected}, + } + + output, err := f.Fix(input) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(output, expected) { + t.Fatalf("unexpected: %#v\nexpected: %#v\n", output, expected) + } + } +} diff --git a/website/pages/partials/builder/vsphere/iso/CreateConfig-not-required.mdx b/website/pages/partials/builder/vsphere/iso/CreateConfig-not-required.mdx index 705ee483e..221550f34 100644 --- a/website/pages/partials/builder/vsphere/iso/CreateConfig-not-required.mdx +++ b/website/pages/partials/builder/vsphere/iso/CreateConfig-not-required.mdx @@ -13,18 +13,8 @@ - `disk_controller_type` (string) - Set VM disk controller type. Example `pvscsi`. -- `disk_size` (int64) - The size of the disk in MB. - -- `disk_thin_provisioned` (bool) - Enable VMDK thin provisioning for VM. Defaults to `false`. - -- `disk_eagerly_scrub` (bool) - Enable VMDK eager scrubbing for VM. Defaults to `false`. - - `storage` ([]DiskConfig) - A collection of one or more disks to be provisioned along with the VM. -- `network` (string) - Set network VM will be connected to. - -- `network_card` (string) - Set VM network card type. Example `vmxnet3`. - - `network_adapters` ([]NIC) - Network adapters - `usb_controller` (bool) - Create USB controller for virtual machine. Defaults to `false`.