From 933ee3b234bbf6a91de8f18afaa7194ca4805a50 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Fri, 17 Nov 2017 17:04:33 -0800 Subject: [PATCH] Add VirtualDiskManager.CreateChildDisk (#925) --- govc/datastore/disk/create.go | 12 ++++- object/virtual_disk_manager_internal.go | 59 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/govc/datastore/disk/create.go b/govc/datastore/disk/create.go index c629c2a2c..b0a1eaffa 100644 --- a/govc/datastore/disk/create.go +++ b/govc/datastore/disk/create.go @@ -61,7 +61,8 @@ func (cmd *create) Description() string { Examples: govc datastore.mkdir disks - govc datastore.disk.create -size 24G disks/disk1.vmdk` + govc datastore.disk.create -size 24G disks/disk1.vmdk + govc datastore.disk.create disks/parent.vmdk disk/child.vmdk` } func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { @@ -81,6 +82,8 @@ func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { m := object.NewVirtualDiskManager(ds.Client()) + var task *object.Task + spec := &types.FileBackedVirtualDiskSpec{ VirtualDiskSpec: types.VirtualDiskSpec{ AdapterType: string(types.VirtualDiskAdapterTypeLsiLogic), @@ -89,7 +92,12 @@ func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { CapacityKb: int64(cmd.Bytes) / 1024, } - task, err := m.CreateVirtualDisk(ctx, ds.Path(f.Arg(0)), dc, spec) + if f.NArg() == 1 { + task, err = m.CreateVirtualDisk(ctx, ds.Path(f.Arg(0)), dc, spec) + } else { + task, err = m.CreateChildDisk(ctx, ds.Path(f.Arg(0)), dc, ds.Path(f.Arg(1)), dc, true) + } + if err != nil { return err } diff --git a/object/virtual_disk_manager_internal.go b/object/virtual_disk_manager_internal.go index 642cd62f6..d99a22eea 100644 --- a/object/virtual_disk_manager_internal.go +++ b/object/virtual_disk_manager_internal.go @@ -95,3 +95,62 @@ func (m VirtualDiskManager) QueryVirtualDiskInfo(ctx context.Context, name strin return info.Result.(arrayOfVirtualDiskInfo).VirtualDiskInfo, nil } + +type createChildDiskTaskRequest struct { + This types.ManagedObjectReference `xml:"_this"` + ChildName string `xml:"childName"` + ChildDatacenter *types.ManagedObjectReference `xml:"childDatacenter,omitempty"` + ParentName string `xml:"parentName"` + ParentDatacenter *types.ManagedObjectReference `xml:"parentDatacenter,omitempty"` + IsLinkedClone bool `xml:"isLinkedClone"` +} + +type createChildDiskTaskResponse struct { + Returnval types.ManagedObjectReference `xml:"returnval"` +} + +type createChildDiskTaskBody struct { + Req *createChildDiskTaskRequest `xml:"urn:internalvim25 CreateChildDisk_Task,omitempty"` + Res *createChildDiskTaskResponse `xml:"urn:vim25 CreateChildDisk_TaskResponse,omitempty"` + Err *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *createChildDiskTaskBody) Fault() *soap.Fault { return b.Err } + +func createChildDiskTask(ctx context.Context, r soap.RoundTripper, req *createChildDiskTaskRequest) (*createChildDiskTaskResponse, error) { + var reqBody, resBody createChildDiskTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +func (m VirtualDiskManager) CreateChildDisk(ctx context.Context, parent string, pdc *Datacenter, name string, dc *Datacenter, linked bool) (*Task, error) { + req := createChildDiskTaskRequest{ + This: m.Reference(), + ChildName: name, + ParentName: parent, + IsLinkedClone: linked, + } + + if dc != nil { + ref := dc.Reference() + req.ChildDatacenter = &ref + } + + if pdc != nil { + ref := pdc.Reference() + req.ParentDatacenter = &ref + } + + res, err := createChildDiskTask(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(m.Client(), res.Returnval), nil +}