From 2380e504087144fad610eb06f9e4cb235a3d4d80 Mon Sep 17 00:00:00 2001 From: Jimmy Conner Date: Tue, 16 May 2017 08:26:51 -0500 Subject: [PATCH] vmware_guest: Add support for Linked Clones (#23284) * vmware_guest: Add support for Linked Clones * Resolve PEP8 Issues * Change snapshot_name to snapshot_src * Add additional option 'snapshot_linked' to specify whether to use a linked clone or not * Changed snapshot_linked parameter to "linked_clone" * Remove unnecessary conditional --- .../modules/cloud/vmware/vmware_guest.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest.py b/lib/ansible/modules/cloud/vmware/vmware_guest.py index ae2d02bd5b..3dc9ed59d8 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_guest.py +++ b/lib/ansible/modules/cloud/vmware/vmware_guest.py @@ -104,6 +104,16 @@ options: - Wait until vCenter detects an IP address for the VM - This requires vmware-tools (vmtoolsd) to properly work after creation default: False + snapshot_src: + description: + - Name of an existing snapshot to use to create a clone of a VM. + default: None + version_added: "2.4" + linked_clone: + description: + - Whether to create a Linked Clone from the snapshot specified + default: False + version_added: "2.4" force: description: - Ignore warnings and complete the actions @@ -1096,10 +1106,22 @@ class PyVmomiHelper(object): relospec.datastore = datastore relospec.pool = resource_pool + if self.params['snapshot_src'] is not None and self.params['linked_clone']: + relospec.diskMoveType = vim.vm.RelocateSpec.DiskMoveOptions.createNewChildDiskBacking + clonespec = vim.vm.CloneSpec(template=self.params['is_template'], location=relospec) if self.customspec: clonespec.customization = self.customspec + if self.params['snapshot_src'] is not None: + snapshot = self.get_snapshots_by_name_recursively(snapshots=vm_obj.snapshot.rootSnapshotList, + snapname=self.params['snapshot_src']) + if len(snapshot) != 1: + self.module.fail_json(msg='virtual machine "{0}" does not contain snapshot named "{1}"'.format( + self.params['template'], self.params['snapshot_src'])) + + clonespec.snapshot = snapshot[0].snapshot + clonespec.config = self.configspec task = vm_obj.Clone(folder=destfolder, name=self.params['name'], spec=clonespec) self.change_detected = True @@ -1142,6 +1164,15 @@ class PyVmomiHelper(object): vm_facts = self.gather_facts(vm) return {'changed': self.change_detected, 'failed': False, 'instance': vm_facts} + def get_snapshots_by_name_recursively(self, snapshots, snapname): + snap_obj = [] + for snapshot in snapshots: + if snapshot.name == snapname: + snap_obj.append(snapshot) + else: + snap_obj = snap_obj + self.get_snapshots_by_name_recursively(snapshot.childSnapshotList, snapname) + return snap_obj + def reconfigure_vm(self): self.configspec = vim.vm.ConfigSpec() self.configspec.deviceChange = [] @@ -1284,6 +1315,8 @@ def main(): esxi_hostname=dict(type='str'), cluster=dict(type='str'), wait_for_ip_address=dict(type='bool', default=False), + snapshot_src=dict(type='str', default=None), + linked_clone=dict(type='bool', default=False), networks=dict(type='list', default=[]), resource_pool=dict(type='str'), customization=dict(type='dict', no_log=True, default={}),