(vsphere-iso) add ability to define multiple disks

Closes #8749
This commit is contained in:
Joshua Foster 2020-02-21 10:47:46 -05:00
parent 4ed896fc99
commit d7230827cd
8 changed files with 131 additions and 46 deletions

View File

@ -52,10 +52,7 @@ type NIC struct {
} }
type CreateConfig struct { type CreateConfig struct {
DiskThinProvisioned bool DiskControllerType string // example: "scsi", "pvscsi"
DiskEagerlyScrub bool
DiskControllerType string // example: "scsi", "pvscsi"
DiskSize int64
Annotation string Annotation string
Name string Name string
@ -69,6 +66,13 @@ type CreateConfig struct {
USBController bool USBController bool
Version uint // example: 10 Version uint // example: 10
Firmware string // efi or bios Firmware string // efi or bios
Storage []Disk
}
type Disk struct {
DiskSize int64
DiskEagerlyScrub bool
DiskThinProvisioned bool
} }
func (d *Driver) NewVM(ref *types.ManagedObjectReference) *VirtualMachine { func (d *Driver) NewVM(ref *types.ManagedObjectReference) *VirtualMachine {
@ -488,6 +492,10 @@ func (vm *VirtualMachine) GetDir() (string, error) {
} }
func addDisk(_ *Driver, devices object.VirtualDeviceList, config *CreateConfig) (object.VirtualDeviceList, error) { func addDisk(_ *Driver, devices object.VirtualDeviceList, config *CreateConfig) (object.VirtualDeviceList, error) {
if len(config.Storage) == 0 {
return nil, errors.New("no storage devices have been defined")
}
device, err := devices.CreateSCSIController(config.DiskControllerType) device, err := devices.CreateSCSIController(config.DiskControllerType)
if err != nil { if err != nil {
return nil, err return nil, err
@ -498,20 +506,22 @@ func addDisk(_ *Driver, devices object.VirtualDeviceList, config *CreateConfig)
return nil, err return nil, err
} }
disk := &types.VirtualDisk{ for _, dc := range config.Storage {
VirtualDevice: types.VirtualDevice{ disk := &types.VirtualDisk{
Key: devices.NewKey(), VirtualDevice: types.VirtualDevice{
Backing: &types.VirtualDiskFlatVer2BackingInfo{ Key: devices.NewKey(),
DiskMode: string(types.VirtualDiskModePersistent), Backing: &types.VirtualDiskFlatVer2BackingInfo{
ThinProvisioned: types.NewBool(config.DiskThinProvisioned), DiskMode: string(types.VirtualDiskModePersistent),
EagerlyScrub: types.NewBool(config.DiskEagerlyScrub), ThinProvisioned: types.NewBool(dc.DiskThinProvisioned),
EagerlyScrub: types.NewBool(dc.DiskEagerlyScrub),
},
}, },
}, CapacityInKB: dc.DiskSize * 1024,
CapacityInKB: config.DiskSize * 1024, }
}
devices.AssignController(disk, controller) devices.AssignController(disk, controller)
devices = append(devices, disk) devices = append(devices, disk)
}
return devices, nil return devices, nil
} }

View File

@ -31,6 +31,7 @@ type FlatConfig struct {
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"` DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"` DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"` DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"`
Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"`
Network *string `mapstructure:"network" cty:"network"` Network *string `mapstructure:"network" cty:"network"`
NetworkCard *string `mapstructure:"network_card" cty:"network_card"` NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"` NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
@ -153,6 +154,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, 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_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}, "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": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false},
"network_card": &hcldec.AttrSpec{Name: "network_card", 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())}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())},

View File

@ -1,5 +1,5 @@
//go:generate struct-markdown //go:generate struct-markdown
//go:generate mapstructure-to-hcl2 -type NIC,CreateConfig //go:generate mapstructure-to-hcl2 -type NIC,CreateConfig,DiskConfig
package iso package iso
@ -24,6 +24,15 @@ type NIC struct {
Passthrough *bool `mapstructure:"passthrough"` Passthrough *bool `mapstructure:"passthrough"`
} }
type DiskConfig struct {
// Set the size of the disk
DiskSize int64 `mapstructure:"disk_size" required:"true"`
// 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"`
}
type CreateConfig struct { type CreateConfig struct {
// Set VM hardware version. Defaults to the most current VM hardware // Set VM hardware version. Defaults to the most current VM hardware
// version supported by vCenter. See // version supported by vCenter. See
@ -44,6 +53,8 @@ type CreateConfig struct {
DiskThinProvisioned bool `mapstructure:"disk_thin_provisioned"` DiskThinProvisioned bool `mapstructure:"disk_thin_provisioned"`
// Enable VMDK eager scrubbing for VM. Defaults to `false`. // Enable VMDK eager scrubbing for VM. Defaults to `false`.
DiskEagerlyScrub bool `mapstructure:"disk_eagerly_scrub"` DiskEagerlyScrub bool `mapstructure:"disk_eagerly_scrub"`
// Storage
Storage []DiskConfig `mapstructure:"storage"`
// Set network VM will be connected to. // Set network VM will be connected to.
Network string `mapstructure:"network"` Network string `mapstructure:"network"`
// Set VM network card type. Example `vmxnet3`. // Set VM network card type. Example `vmxnet3`.
@ -115,23 +126,38 @@ 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,
DiskEagerlyScrub: disk.DiskEagerlyScrub,
DiskThinProvisioned: disk.DiskThinProvisioned,
})
}
vm, err = d.CreateVM(&driver.CreateConfig{ vm, err = d.CreateVM(&driver.CreateConfig{
DiskThinProvisioned: s.Config.DiskThinProvisioned, DiskControllerType: s.Config.DiskControllerType,
DiskEagerlyScrub: s.Config.DiskEagerlyScrub, Storage: disks,
DiskControllerType: s.Config.DiskControllerType, Annotation: s.Config.Notes,
DiskSize: s.Config.DiskSize, Name: s.Location.VMName,
Name: s.Location.VMName, Folder: s.Location.Folder,
Folder: s.Location.Folder, Cluster: s.Location.Cluster,
Cluster: s.Location.Cluster, Host: s.Location.Host,
Host: s.Location.Host, ResourcePool: s.Location.ResourcePool,
ResourcePool: s.Location.ResourcePool, Datastore: s.Location.Datastore,
Datastore: s.Location.Datastore, GuestOS: s.Config.GuestOSType,
GuestOS: s.Config.GuestOSType, NICs: networkCards,
NICs: networkCards, USBController: s.Config.USBController,
USBController: s.Config.USBController, Version: s.Config.Version,
Version: s.Config.Version, Firmware: s.Config.Firmware,
Firmware: s.Config.Firmware,
Annotation: s.Config.Notes,
}) })
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("error creating vm: %v", err)) state.Put("error", fmt.Errorf("error creating vm: %v", err))

View File

@ -1,4 +1,4 @@
// Code generated by "mapstructure-to-hcl2 -type NIC,CreateConfig"; DO NOT EDIT. // Code generated by "mapstructure-to-hcl2 -type NIC,CreateConfig,DiskConfig"; DO NOT EDIT.
package iso package iso
import ( import (
@ -9,18 +9,19 @@ import (
// FlatCreateConfig is an auto-generated flat version of CreateConfig. // FlatCreateConfig is an auto-generated flat version of CreateConfig.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatCreateConfig struct { type FlatCreateConfig struct {
Version *uint `mapstructure:"vm_version" cty:"vm_version"` Version *uint `mapstructure:"vm_version" cty:"vm_version"`
GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"` GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"`
Firmware *string `mapstructure:"firmware" cty:"firmware"` Firmware *string `mapstructure:"firmware" cty:"firmware"`
DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"` DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"`
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"` DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"` DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"` DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"`
Network *string `mapstructure:"network" cty:"network"` Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"`
NetworkCard *string `mapstructure:"network_card" cty:"network_card"` Network *string `mapstructure:"network" cty:"network"`
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"` NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"` NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
Notes *string `mapstructure:"notes" cty:"notes"` USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
Notes *string `mapstructure:"notes" cty:"notes"`
} }
// FlatMapstructure returns a new FlatCreateConfig. // FlatMapstructure returns a new FlatCreateConfig.
@ -42,6 +43,7 @@ func (*FlatCreateConfig) HCL2Spec() map[string]hcldec.Spec {
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, 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_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}, "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": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false},
"network_card": &hcldec.AttrSpec{Name: "network_card", 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())}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())},
@ -51,6 +53,33 @@ func (*FlatCreateConfig) HCL2Spec() map[string]hcldec.Spec {
return s return s
} }
// FlatDiskConfig is an auto-generated flat version of DiskConfig.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatDiskConfig struct {
DiskSize *int64 `mapstructure:"disk_size" required:"true" cty:"disk_size"`
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"`
}
// FlatMapstructure returns a new FlatDiskConfig.
// FlatDiskConfig is an auto-generated flat version of DiskConfig.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*DiskConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatDiskConfig)
}
// HCL2Spec returns the hcl spec of a DiskConfig.
// This spec is used by HCL to read the fields of DiskConfig.
// The decoded values from this spec will then be applied to a FlatDiskConfig.
func (*FlatDiskConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"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},
}
return s
}
// FlatNIC is an auto-generated flat version of NIC. // FlatNIC is an auto-generated flat version of NIC.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNIC struct { type FlatNIC struct {

View File

@ -70,6 +70,12 @@ necessary for this build to succeed and can be found further down the page.
### Network Adapter Configuration ### Network Adapter Configuration
<%= partial "partials/builder/vsphere/iso/NIC-required" %> <%= partial "partials/builder/vsphere/iso/NIC-required" %>
### Storage Configuration
<%= partial "partials/builder/vsphere/iso/DiskConfig-required" %>
### Optional Storage Configuration
<%= partial "partials/builder/vsphere/iso/DiskConfig-not-required" %>
### Floppy Configuration ### Floppy Configuration
<%= partial "partials/builder/vsphere/iso/FloppyConfig-not-required" %> <%= partial "partials/builder/vsphere/iso/FloppyConfig-not-required" %>

View File

@ -19,6 +19,8 @@
- `disk_eagerly_scrub` (bool) - Enable VMDK eager scrubbing for VM. Defaults to `false`. - `disk_eagerly_scrub` (bool) - Enable VMDK eager scrubbing for VM. Defaults to `false`.
- `storage` ([]DiskConfig) - Storage
- `network` (string) - Set network VM will be connected to. - `network` (string) - Set network VM will be connected to.
- `network_card` (string) - Set VM network card type. Example `vmxnet3`. - `network_card` (string) - Set VM network card type. Example `vmxnet3`.

View File

@ -0,0 +1,6 @@
<!-- Code generated from the comments of the DiskConfig struct in builder/vsphere/iso/step_create.go; DO NOT EDIT MANUALLY -->
- `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`.

View File

@ -0,0 +1,4 @@
<!-- Code generated from the comments of the DiskConfig struct in builder/vsphere/iso/step_create.go; DO NOT EDIT MANUALLY -->
- `disk_size` (int64) - Set the size of the disk