mirror of https://github.com/hashicorp/packer
Fix primary disk resize on clone and add tests (#10848)
* Fix primary disk resize on clone and add tests * remove commented testspull/10862/head
parent
794e83b171
commit
d81c02b456
@ -0,0 +1,251 @@
|
||||
package clone
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
)
|
||||
|
||||
func TestCreateConfig_Prepare(t *testing.T) {
|
||||
tc := []struct {
|
||||
name string
|
||||
config *CloneConfig
|
||||
fail bool
|
||||
expectedErrMsg string
|
||||
}{
|
||||
{
|
||||
name: "Valid config",
|
||||
config: &CloneConfig{
|
||||
Template: "template name",
|
||||
StorageConfig: common.StorageConfig{
|
||||
DiskControllerType: []string{"test"},
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "storage[0].'disk_size' is required",
|
||||
},
|
||||
{
|
||||
name: "Storage validate disk_size",
|
||||
config: &CloneConfig{
|
||||
StorageConfig: common.StorageConfig{
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 0,
|
||||
DiskThinProvisioned: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "storage[0].'disk_size' is required",
|
||||
},
|
||||
{
|
||||
name: "Storage validate disk_controller_index",
|
||||
config: &CloneConfig{
|
||||
StorageConfig: common.StorageConfig{
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 32768,
|
||||
DiskControllerIndex: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "storage[0].'disk_controller_index' references an unknown disk controller",
|
||||
},
|
||||
{
|
||||
name: "Validate template is set",
|
||||
config: &CloneConfig{
|
||||
StorageConfig: common.StorageConfig{
|
||||
DiskControllerType: []string{"test"},
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 32768,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "'template' is required",
|
||||
},
|
||||
{
|
||||
name: "Validate LinkedClone and DiskSize set at the same time",
|
||||
config: &CloneConfig{
|
||||
Template: "template name",
|
||||
LinkedClone: true,
|
||||
DiskSize: 32768,
|
||||
StorageConfig: common.StorageConfig{
|
||||
DiskControllerType: []string{"test"},
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 32768,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "'linked_clone' and 'disk_size' cannot be used together",
|
||||
},
|
||||
{
|
||||
name: "Validate MacAddress and Network not set at the same time",
|
||||
config: &CloneConfig{
|
||||
Template: "template name",
|
||||
MacAddress: "some mac address",
|
||||
StorageConfig: common.StorageConfig{
|
||||
DiskControllerType: []string{"test"},
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 32768,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
expectedErrMsg: "'network' is required when 'mac_address' is specified",
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range tc {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
errs := c.config.Prepare()
|
||||
if c.fail {
|
||||
if len(errs) == 0 {
|
||||
t.Fatalf("Config preprare should fail")
|
||||
}
|
||||
if errs[0].Error() != c.expectedErrMsg {
|
||||
t.Fatalf("Expected error message: %s but was '%s'", c.expectedErrMsg, errs[0].Error())
|
||||
}
|
||||
} else {
|
||||
if len(errs) != 0 {
|
||||
t.Fatalf("Config preprare should not fail: %s", errs[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateVM_Run(t *testing.T) {
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("ui", &packersdk.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
})
|
||||
driverMock := driver.NewDriverMock()
|
||||
state.Put("driver", driverMock)
|
||||
step := basicStepCloneVM()
|
||||
step.Force = true
|
||||
vmPath := path.Join(step.Location.Folder, step.Location.VMName)
|
||||
vmMock := new(driver.VirtualMachineMock)
|
||||
driverMock.VM = vmMock
|
||||
|
||||
if action := step.Run(context.TODO(), state); action == multistep.ActionHalt {
|
||||
t.Fatalf("Should not halt.")
|
||||
}
|
||||
|
||||
// Pre clean VM
|
||||
if !driverMock.PreCleanVMCalled {
|
||||
t.Fatalf("driver.PreCleanVM should be called.")
|
||||
}
|
||||
if driverMock.PreCleanForce != step.Force {
|
||||
t.Fatalf("Force PreCleanVM should be %t but was %t.", step.Force, driverMock.PreCleanForce)
|
||||
}
|
||||
if driverMock.PreCleanVMPath != vmPath {
|
||||
t.Fatalf("VM path expected to be %s but was %s", vmPath, driverMock.PreCleanVMPath)
|
||||
}
|
||||
|
||||
if !driverMock.FindVMCalled {
|
||||
t.Fatalf("driver.FindVM should be called.")
|
||||
}
|
||||
if !vmMock.CloneCalled {
|
||||
t.Fatalf("vm.Clone should be called.")
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(vmMock.CloneConfig, driverCreateConfig(step.Config, step.Location)); diff != "" {
|
||||
t.Fatalf("wrong driver.CreateConfig: %s", diff)
|
||||
}
|
||||
vm, ok := state.GetOk("vm")
|
||||
if !ok {
|
||||
t.Fatal("state must contain the VM")
|
||||
}
|
||||
if vm != driverMock.VM {
|
||||
t.Fatalf("state doesn't contain the created VM.")
|
||||
}
|
||||
}
|
||||
|
||||
func basicStepCloneVM() *StepCloneVM {
|
||||
step := &StepCloneVM{
|
||||
Config: createConfig(),
|
||||
Location: basicLocationConfig(),
|
||||
}
|
||||
return step
|
||||
}
|
||||
|
||||
func basicLocationConfig() *common.LocationConfig {
|
||||
return &common.LocationConfig{
|
||||
VMName: "test-vm",
|
||||
Folder: "test-folder",
|
||||
Cluster: "test-cluster",
|
||||
Host: "test-host",
|
||||
ResourcePool: "test-resource-pool",
|
||||
Datastore: "test-datastore",
|
||||
}
|
||||
}
|
||||
|
||||
func createConfig() *CloneConfig {
|
||||
return &CloneConfig{
|
||||
Template: "template name",
|
||||
StorageConfig: common.StorageConfig{
|
||||
DiskControllerType: []string{"pvscsi"},
|
||||
Storage: []common.DiskConfig{
|
||||
{
|
||||
DiskSize: 32768,
|
||||
DiskThinProvisioned: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func driverCreateConfig(config *CloneConfig, location *common.LocationConfig) *driver.CloneConfig {
|
||||
var disks []driver.Disk
|
||||
for _, disk := range config.StorageConfig.Storage {
|
||||
disks = append(disks, driver.Disk{
|
||||
DiskSize: disk.DiskSize,
|
||||
DiskEagerlyScrub: disk.DiskEagerlyScrub,
|
||||
DiskThinProvisioned: disk.DiskThinProvisioned,
|
||||
ControllerIndex: disk.DiskControllerIndex,
|
||||
})
|
||||
}
|
||||
|
||||
return &driver.CloneConfig{
|
||||
StorageConfig: driver.StorageConfig{
|
||||
DiskControllerType: config.StorageConfig.DiskControllerType,
|
||||
Storage: disks,
|
||||
},
|
||||
Annotation: config.Notes,
|
||||
Name: location.VMName,
|
||||
Folder: location.Folder,
|
||||
Cluster: location.Cluster,
|
||||
Host: location.Host,
|
||||
ResourcePool: location.ResourcePool,
|
||||
Datastore: location.Datastore,
|
||||
LinkedClone: config.LinkedClone,
|
||||
Network: config.Network,
|
||||
MacAddress: config.MacAddress,
|
||||
VAppProperties: config.VAppConfig.Properties,
|
||||
PrimaryDiskSize: config.DiskSize,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue