Skip to content

Commit 40a596c

Browse files
committed
vcsim: Add VirtualMachine.PromoteDisks_Task method
- Add backing.parent.fileName validation and capacity propagation in vm.configureDevice Signed-off-by: Doug MacEachern <[email protected]>
1 parent 59cb29b commit 40a596c

File tree

2 files changed

+136
-2
lines changed

2 files changed

+136
-2
lines changed

govc/test/vm.bats

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,50 @@ load test_helper
755755
[ $result -eq 2 ]
756756
}
757757

758+
@test "vm.disk.promote" {
759+
vcsim_env
760+
761+
export GOVC_VM=DC0_H0_VM0
762+
763+
run govc vm.disk.promote
764+
assert_failure
765+
766+
run govc vm.disk.promote invalid-disk-name
767+
assert_failure
768+
769+
run govc device.info disk-*-0
770+
assert_success
771+
grep -v "Parent:" <<<"$output" # No parent disk
772+
773+
run govc vm.disk.promote disk-*-0
774+
assert_success
775+
776+
run govc disk.create -size 10M my-disk
777+
assert_success
778+
id="$output"
779+
780+
run govc disk.ls -json "$id"
781+
assert_success
782+
783+
run jq -r .objects[].config.backing.filePath <<<"$output"
784+
assert_success
785+
path="$output"
786+
787+
run govc vm.disk.attach -link -disk "$path"
788+
assert_success
789+
790+
run govc device.info disk-*-1
791+
assert_success
792+
assert_line "Parent: $path" # Has parent disk
793+
794+
run govc vm.disk.promote disk-*-1
795+
assert_success
796+
797+
run govc device.info disk-*-1
798+
assert_success
799+
grep -v "Parent:" <<<"$output" # No more parent disk
800+
}
801+
758802
@test "vm.create new disk with datastore argument" {
759803
vcsim_env
760804

simulator/virtual_machine.go

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ import (
2525
"github.com/vmware/govmomi/internal"
2626
"github.com/vmware/govmomi/object"
2727
"github.com/vmware/govmomi/simulator/esx"
28+
"github.com/vmware/govmomi/units"
2829
"github.com/vmware/govmomi/vim25/methods"
2930
"github.com/vmware/govmomi/vim25/mo"
3031
"github.com/vmware/govmomi/vim25/soap"
3132
"github.com/vmware/govmomi/vim25/types"
32-
"github.com/vmware/govmomi/vmdk"
3333
)
3434

3535
type VirtualMachine struct {
@@ -1351,7 +1351,6 @@ func (vm *VirtualMachine) configureDevice(
13511351
}
13521352
}
13531353

1354-
summary = fmt.Sprintf("%s KB", numberToString(x.CapacityInKB, ','))
13551354
switch b := d.Backing.(type) {
13561355
case *types.VirtualDiskSparseVer2BackingInfo:
13571356
// Sparse disk creation not supported in ESX
@@ -1361,6 +1360,40 @@ func (vm *VirtualMachine) configureDevice(
13611360
},
13621361
}
13631362
case types.BaseVirtualDeviceFileBackingInfo:
1363+
parent := ""
1364+
1365+
switch backing := d.Backing.(type) {
1366+
case *types.VirtualDiskFlatVer2BackingInfo:
1367+
if backing.Parent != nil {
1368+
parent = backing.Parent.FileName
1369+
}
1370+
case *types.VirtualDiskSeSparseBackingInfo:
1371+
if backing.Parent != nil {
1372+
parent = backing.Parent.FileName
1373+
}
1374+
case *types.VirtualDiskSparseVer2BackingInfo:
1375+
if backing.Parent != nil {
1376+
parent = backing.Parent.FileName
1377+
}
1378+
}
1379+
1380+
if parent != "" {
1381+
desc, _, err := ctx.Map.FileManager().DiskDescriptor(ctx, &dc.Self, parent)
1382+
if err != nil {
1383+
return &types.InvalidDeviceSpec{
1384+
InvalidVmConfig: types.InvalidVmConfig{
1385+
Property: "virtualDeviceSpec.device.backing.parent.fileName",
1386+
},
1387+
}
1388+
}
1389+
1390+
// Disk Capacity is always same as the parent's
1391+
x.CapacityInBytes = int64(desc.Capacity())
1392+
x.CapacityInKB = x.CapacityInBytes / 1024
1393+
}
1394+
1395+
summary = fmt.Sprintf("%s KB", numberToString(x.CapacityInKB, ','))
1396+
13641397
info := b.GetVirtualDeviceFileBackingInfo()
13651398
var path object.DatastorePath
13661399
path.FromString(info.FileName)
@@ -2821,6 +2854,63 @@ func (vm *VirtualMachine) DetachDiskTask(ctx *Context, req *types.DetachDisk_Tas
28212854
}
28222855
}
28232856

2857+
func (vm *VirtualMachine) PromoteDisksTask(ctx *Context, req *types.PromoteDisks_Task) soap.HasFault {
2858+
task := CreateTask(vm, "promoteDisks", func(t *Task) (types.AnyType, types.BaseMethodFault) {
2859+
devices := object.VirtualDeviceList(vm.Config.Hardware.Device)
2860+
devices = devices.SelectByType((*types.VirtualDisk)(nil))
2861+
var cap int64
2862+
2863+
for i := range req.Disks {
2864+
d := devices.FindByKey(req.Disks[i].Key)
2865+
if d == nil {
2866+
return nil, &types.InvalidArgument{InvalidProperty: "disks"}
2867+
}
2868+
2869+
disk := d.(*types.VirtualDisk)
2870+
2871+
switch backing := disk.Backing.(type) {
2872+
case *types.VirtualDiskFlatVer2BackingInfo:
2873+
if backing.Parent != nil {
2874+
cap += disk.CapacityInBytes
2875+
if req.Unlink {
2876+
backing.Parent = nil
2877+
}
2878+
}
2879+
case *types.VirtualDiskSeSparseBackingInfo:
2880+
if backing.Parent != nil {
2881+
cap += disk.CapacityInBytes
2882+
if req.Unlink {
2883+
backing.Parent = nil
2884+
}
2885+
}
2886+
case *types.VirtualDiskSparseVer2BackingInfo:
2887+
if backing.Parent != nil {
2888+
cap += disk.CapacityInBytes
2889+
if req.Unlink {
2890+
backing.Parent = nil
2891+
}
2892+
}
2893+
}
2894+
}
2895+
2896+
// Built-in default delay. `simulator.TaskDelay` can be used to add additional time
2897+
// Translates to roughly 1s per 1GB
2898+
sleep := time.Duration(cap/units.MB) * time.Millisecond
2899+
if sleep > 0 {
2900+
log.Printf("%s: sleep %s for %s", t.Info.DescriptionId, sleep, units.ByteSize(cap))
2901+
time.Sleep(sleep)
2902+
}
2903+
2904+
return nil, nil
2905+
})
2906+
2907+
return &methods.PromoteDisks_TaskBody{
2908+
Res: &types.PromoteDisks_TaskResponse{
2909+
Returnval: task.Run(ctx),
2910+
},
2911+
}
2912+
}
2913+
28242914
func (vm *VirtualMachine) ShutdownGuest(ctx *Context, c *types.ShutdownGuest) soap.HasFault {
28252915
r := &methods.ShutdownGuestBody{}
28262916

0 commit comments

Comments
 (0)