Add handling for full and linked clone

and commit disk mode additions
This commit is contained in:
Aditya Kulkarni 2016-10-31 12:30:49 -04:00
parent a2eae208c5
commit d8b1c9c777
2 changed files with 119 additions and 48 deletions

View file

@ -533,27 +533,29 @@ Example of a minimal profile:
Cloning from a Snapshot
=======================
.. versionadded:: 2016.3.4
Cloning a template works similar to cloning a VM except for the fact that
a snapshot number must be provided.
.. versionadded:: 2016.3.5
Cloning from a snapshot requires that one of the
supported options be set in the cloud profile.
Supported options are ``createNewChildDiskBacking``,
``moveChildMostDiskBacking``, ``moveAllDiskBackingsAndAllowSharing``
and ``moveAllDiskBackingsAndDisallowSharing``.
Example of a minimal profile:
.. code-block:: yaml
my-template-clone:
provider: vcenter01
clonefrom: 'salt_vm'
snapshot: 3
.. image:: /_static/snapshot_manager.png
:align: center
:scale: 70%
.. note::
The previous diagram shows how to identify the snapshot number. Selected
(third snapshot) is number 3.
provider: vcenter01
clonefrom: 'salt_vm'
snapshot:
disk_move_type: createNewChildDiskBacking
# these types are also supported
# disk_move_type: moveChildMostDiskBacking
# disk_move_type: moveAllDiskBackingsAndAllowSharing
# disk_move_type: moveAllDiskBackingsAndDisallowSharing
Creating a VM
@ -634,7 +636,7 @@ Example of a complete profile:
Specifying disk backing mode
============================
.. versionadded:: Nitrogen
.. versionadded:: 2016.3.5
Disk backing mode can now be specified when cloning a VM. This option
can be set in the cloud profile as shown in example below:
@ -652,6 +654,7 @@ can be set in the cloud profile as shown in example below:
disk:
Hard disk 1:
mode: 'independent_nonpersistent'
size: 42
Hard disk 2:
size: 15

View file

@ -132,9 +132,12 @@ from salt.exceptions import SaltCloudSystemExit
# Import salt cloud libs
import salt.config as config
from salt.ext.six.moves import range
# Attempt to import pyVim and pyVmomi libs
FLATTEN_DISK_FULL_CLONE = 'moveAllDiskBackingsAndDisallowSharing'
COPY_ALL_DISKS_FULL_CLONE = 'moveAllDiskBackingsAndAllowSharing'
CURRENT_STATE_LINKED_CLONE = 'moveChildMostDiskBacking'
QUICK_LINKED_CLONE = 'createNewChildDiskBacking'
try:
from pyVmomi import vim
HAS_PYVMOMI = True
@ -613,28 +616,38 @@ def _manage_devices(devices, vm=None, container_ref=None):
# there is at least one disk specified to be created/configured
unit_number += 1
existing_disks_label.append(device.deviceInfo.label)
# log.info('all = %s', str(devices['disk'].keys()))
if device.deviceInfo.label in list(devices['disk'].keys()):
disk_spec = None
if 'size' in devices['disk'][device.deviceInfo.label]:
disk_spec = _get_size_spec(device, devices)
size_gb = float(devices['disk'][device.deviceInfo.label]['size'])
else:
raise SaltCloudSystemExit(
'Please specify a size'
' for the disk "{0}" in'
' your cloud profile'
''.format(device.deviceInfo.label))
size_kb = int(size_gb * 1024 * 1024)
if device.capacityInKB < size_kb:
# expand the disk
disk_spec = _edit_existing_hard_disk_helper(device, size_kb)
if 'mode' in devices['disk'][device.deviceInfo.label]:
if devices['disk'][device.deviceInfo.label]['mode'] \
in [
'independent_persistent',
'persistent',
'independent_nonpersistent',
'nonpersistent',
'undoable',
'append'
'dependent',
]:
disk_spec = _get_mode_spec(device, devices, disk_spec)
else:
raise SaltCloudSystemExit('Invalid disk'
' backing mode'
' specified!')
if disk_spec:
device_specs.append(disk_spec)
device_specs.append(disk_spec)
elif isinstance(device.backing, vim.vm.device.VirtualEthernetCard.NetworkBackingInfo) or isinstance(device.backing, vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo):
# this is a network adapter
@ -2237,18 +2250,6 @@ def create(vm_):
raise SaltCloudSystemExit(
'The VM/template that you have specified under clonefrom does not exist.'
)
snapshot = None
if clone_type == 'vm' and 'snapshot' in vm_:
num = int(vm_['snapshot']) - 1
snapshot = object_ref.rootSnapshot[0]
# Drill down to the correct snapshot number
for _ in range(num):
try:
snapshot = snapshot.childSnapshot[0]
except IndexError:
raise SaltCloudSystemExit('Specified snapshot'
' does not exist.')
else:
clone_type = None
object_ref = None
@ -2387,20 +2388,18 @@ def create(vm_):
config_spec.extraConfig.append(option)
if 'clonefrom' in vm_:
if not snapshot:
# Create the clone specs
clone_spec = vim.vm.CloneSpec(
template=template,
location=reloc_spec,
config=config_spec
)
else:
clone_spec = vim.vm.CloneSpec(
template=template,
location=reloc_spec,
config=config_spec,
snapshot=snapshot
)
clone_spec = handle_snapshot(
config_spec,
object_ref,
reloc_spec,
template,
vm_
)
if not clone_spec:
clone_spec = build_clonespec(config_spec,
object_ref,
reloc_spec,
template)
if customization and (devices and 'network' in list(devices.keys())) and 'Windows' not in object_ref.config.guestFullName:
global_ip = vim.vm.customization.GlobalIPSettings()
@ -2525,6 +2524,75 @@ def create(vm_):
return data
def handle_snapshot(config_spec, object_ref, reloc_spec, template, vm_):
'''
Returns a clone spec for cloning from shapshots
:rtype vim.vm.CloneSpec
'''
if 'snapshot' not in vm_:
return None
allowed_types = [
FLATTEN_DISK_FULL_CLONE,
COPY_ALL_DISKS_FULL_CLONE,
CURRENT_STATE_LINKED_CLONE,
QUICK_LINKED_CLONE,
]
clone_spec = get_clonespec_for_valid_snapshot(
config_spec,
object_ref,
reloc_spec,
template,
vm_)
if not clone_spec:
raise SaltCloudSystemExit('Invalid disk move type specified'
' supported types are'
' {0}'.format(' '.join(allowed_types)))
return clone_spec
def get_clonespec_for_valid_snapshot(config_spec, object_ref, reloc_spec, template, vm_):
'''
return clonespec only if values are valid
'''
moving = True
if QUICK_LINKED_CLONE == vm_['snapshot']['disk_move_type']:
reloc_spec.diskMoveType = QUICK_LINKED_CLONE
elif CURRENT_STATE_LINKED_CLONE == vm_['snapshot']['disk_move_type']:
reloc_spec.diskMoveType = CURRENT_STATE_LINKED_CLONE
elif COPY_ALL_DISKS_FULL_CLONE == vm_['snapshot']['disk_move_type']:
reloc_spec.diskMoveType = COPY_ALL_DISKS_FULL_CLONE
elif FLATTEN_DISK_FULL_CLONE == vm_['snapshot']['disk_move_type']:
reloc_spec.diskMoveType = FLATTEN_DISK_FULL_CLONE
else:
moving = False
if moving:
return build_clonespec(config_spec, object_ref, reloc_spec, template)
else:
return None
def build_clonespec(config_spec, object_ref, reloc_spec, template):
'''
Returns the clone spec
'''
if reloc_spec.diskMoveType == QUICK_LINKED_CLONE:
return vim.vm.CloneSpec(
template=template,
location=reloc_spec,
config=config_spec,
snapshot=object_ref.snapshot.currentSnapshot
)
else:
return vim.vm.CloneSpec(
template=template,
location=reloc_spec,
config=config_spec
)
def create_datacenter(kwargs=None, call=None):
'''
Create a new data center in this VMware environment