Support for Linked Cloning in vsphere, based off of 6814028be7

This commit is contained in:
Adam Heeren 2016-02-24 10:39:24 -05:00
parent ae371b5492
commit c40f73960e
1 changed files with 34 additions and 4 deletions

View File

@ -50,6 +50,7 @@ type virtualMachine struct {
cluster string cluster string
resourcePool string resourcePool string
datastore string datastore string
linkedClone bool
vcpu int vcpu int
memoryMb int64 memoryMb int64
template string template string
@ -124,6 +125,12 @@ func resourceVSphereVirtualMachine() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"linkedClone": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},
"gateway": &schema.Schema{ "gateway": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -318,6 +325,10 @@ func resourceVSphereVirtualMachineCreate(d *schema.ResourceData, meta interface{
vm.timeZone = v.(string) vm.timeZone = v.(string)
} }
if v, ok := d.GetOk("linkedClone"); ok {
vm.linkedClone = v.(bool)
}
if raw, ok := d.GetOk("dns_suffixes"); ok { if raw, ok := d.GetOk("dns_suffixes"); ok {
for _, v := range raw.([]interface{}) { for _, v := range raw.([]interface{}) {
vm.dnsSuffixes = append(vm.dnsSuffixes, v.(string)) vm.dnsSuffixes = append(vm.dnsSuffixes, v.(string))
@ -707,8 +718,15 @@ func buildNetworkDevice(f *find.Finder, label, adapterType string) (*types.Virtu
} }
// buildVMRelocateSpec builds VirtualMachineRelocateSpec to set a place for a new VirtualMachine. // buildVMRelocateSpec builds VirtualMachineRelocateSpec to set a place for a new VirtualMachine.
func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *object.VirtualMachine, initType string) (types.VirtualMachineRelocateSpec, error) { func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *object.VirtualMachine, linkedClone bool, initType string) (types.VirtualMachineRelocateSpec, error) {
var key int var key int
var moveType string
if linkedClone {
moveType = "createNewChildDiskBacking"
} else {
moveType = "moveAllDiskBackingsAndDisallowSharing"
}
log.Printf("[DEBUG] relocate type: [%s]", moveType)
devices, err := vm.Device(context.TODO()) devices, err := vm.Device(context.TODO())
if err != nil { if err != nil {
@ -724,8 +742,9 @@ func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *obje
rpr := rp.Reference() rpr := rp.Reference()
dsr := ds.Reference() dsr := ds.Reference()
return types.VirtualMachineRelocateSpec{ return types.VirtualMachineRelocateSpec{
Datastore: &dsr, Datastore: &dsr,
Pool: &rpr, Pool: &rpr,
DiskMoveType: moveType,
Disk: []types.VirtualMachineRelocateSpecDiskLocator{ Disk: []types.VirtualMachineRelocateSpecDiskLocator{
types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{
Datastore: dsr, Datastore: dsr,
@ -1099,7 +1118,7 @@ func (vm *virtualMachine) deployVirtualMachine(c *govmomi.Client) error {
} }
log.Printf("[DEBUG] datastore: %#v", datastore) log.Printf("[DEBUG] datastore: %#v", datastore)
relocateSpec, err := buildVMRelocateSpec(resourcePool, datastore, template, vm.hardDisks[0].initType) relocateSpec, err := buildVMRelocateSpec(resourcePool, datastore, template, vm.linkedClone, vm.hardDisks[0].initType)
if err != nil { if err != nil {
return err return err
} }
@ -1204,6 +1223,17 @@ func (vm *virtualMachine) deployVirtualMachine(c *govmomi.Client) error {
Config: &configSpec, Config: &configSpec,
PowerOn: false, PowerOn: false,
} }
if vm.linkedClone {
var template_mo mo.VirtualMachine
err = template.Properties(context.TODO(), template.Reference(), []string{"parent", "config.template", "resourcePool", "snapshot", "guest.toolsVersionStatus2", "config.guestFullName"}, &template_mo)
if err != nil {
return fmt.Errorf("Error reading base VM properties: %s", err)
}
if template_mo.Snapshot == nil {
return fmt.Errorf("`linkedClone=true`, but image VM has no snapshots")
}
cloneSpec.Snapshot = template_mo.Snapshot.CurrentSnapshot
}
log.Printf("[DEBUG] clone spec: %v", cloneSpec) log.Printf("[DEBUG] clone spec: %v", cloneSpec)
task, err := template.Clone(context.TODO(), folder, vm.name, cloneSpec) task, err := template.Clone(context.TODO(), folder, vm.name, cloneSpec)