From 3d0302f0ae29ac87aa6c11b2883983ef3c57ed78 Mon Sep 17 00:00:00 2001 From: syuparn Date: Sat, 5 Nov 2022 13:58:05 +0900 Subject: [PATCH] vcsim: Fix duplicated name check in CloneVM_Task Closes: #2983 Signed-off-by: syuparn --- govc/test/vm.bats | 5 ++- simulator/virtual_machine.go | 11 ++++- simulator/virtual_machine_test.go | 71 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/govc/test/vm.bats b/govc/test/vm.bats index a1c26bc93..d1ac1addd 100755 --- a/govc/test/vm.bats +++ b/govc/test/vm.bats @@ -800,8 +800,11 @@ load test_helper run govc vm.clone -cluster DC0_C0 -vm "$vm" "$clone" assert_failure # already exists + run govc datastore.cp "$clone"/"$clone".vmx "$clone"/"$clone".vmx.copy + run govc vm.destroy "$clone" + run govc datastore.mv "$clone"/"$clone".vmx.copy "$clone"/"$clone".vmx # leave vmx file run govc vm.clone -force -vm "$vm" "$clone" - assert_success # clone vm with the same name + assert_success # clone vm with the same name vmx file vm=$(new_empty_vm) run govc vm.disk.create -vm "$vm" -thick -eager -size 10M -name "$vm/data.vmdk" diff --git a/simulator/virtual_machine.go b/simulator/virtual_machine.go index 8c256580d..bc51998c8 100644 --- a/simulator/virtual_machine.go +++ b/simulator/virtual_machine.go @@ -1022,8 +1022,9 @@ var vmwOUI = net.HardwareAddr([]byte{0x0, 0xc, 0x29}) // From http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.vsphere.networking.doc%2FGUID-DC7478FF-DC44-4625-9AD7-38208C56A552.html // "The host generates generateMAC addresses that consists of the VMware OUI 00:0C:29 and the last three octets in hexadecimal -// format of the virtual machine UUID. The virtual machine UUID is based on a hash calculated by using the UUID of the -// ESXi physical machine and the path to the configuration file (.vmx) of the virtual machine." +// +// format of the virtual machine UUID. The virtual machine UUID is based on a hash calculated by using the UUID of the +// ESXi physical machine and the path to the configuration file (.vmx) of the virtual machine." func (vm *VirtualMachine) generateMAC(unit int32) string { id := []byte(vm.Config.Uuid) @@ -1901,6 +1902,12 @@ func (vm *VirtualMachine) CloneVMTask(ctx *Context, req *types.CloneVM_Task) soa if pool == nil { return nil, &types.InvalidArgument{InvalidProperty: "spec.location.pool"} } + if obj := ctx.Map.FindByName(req.Name, folder.ChildEntity); obj != nil { + return nil, &types.DuplicateName{ + Name: req.Name, + Object: obj.Reference(), + } + } config := types.VirtualMachineConfigSpec{ Name: req.Name, GuestId: vm.Config.GuestId, diff --git a/simulator/virtual_machine_test.go b/simulator/virtual_machine_test.go index e659bc42b..a983eddb1 100644 --- a/simulator/virtual_machine_test.go +++ b/simulator/virtual_machine_test.go @@ -333,6 +333,77 @@ func TestCreateVmWithSpecialCharaters(t *testing.T) { } } +func TestCloneVm(t *testing.T) { + tests := []struct { + name string + vmName string + config types.VirtualMachineCloneSpec + fail bool + }{ + { + "clone a vm", + "cloned-vm", + types.VirtualMachineCloneSpec{ + Template: false, + PowerOn: false, + }, + false, + }, + { + "vm name is duplicated", + "DC0_H0_VM0", + types.VirtualMachineCloneSpec{ + Template: false, + PowerOn: false, + }, + true, + }, + } + + for _, test := range tests { + test := test // assign to local var since loop var is reused + + t.Run(test.name, func(t *testing.T) { + m := VPX() + defer m.Remove() + + Test(func(ctx context.Context, c *vim25.Client) { + finder := find.NewFinder(c, false) + dc, err := finder.DefaultDatacenter(ctx) + if err != nil { + t.Fatal(err) + } + + folders, err := dc.Folders(ctx) + if err != nil { + t.Fatal(err) + } + + vmFolder := folders.VmFolder + + vmm := Map.Any("VirtualMachine").(*VirtualMachine) + vm := object.NewVirtualMachine(c, vmm.Reference()) + + task, err := vm.Clone(ctx, vmFolder, test.vmName, test.config) + if err != nil { + t.Fatal(err) + } + + err = task.Wait(ctx) + if test.fail { + if err == nil { + t.Errorf("%s: expected error", test.name) + } + } else { + if err != nil { + t.Errorf("%s: %s", test.name, err) + } + } + }, m) + }) + } +} + func TestReconfigVmDevice(t *testing.T) { ctx := context.Background()