mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add handling for full and linked clone
and commit disk mode additions
This commit is contained in:
parent
a2eae208c5
commit
d8b1c9c777
2 changed files with 119 additions and 48 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue