vmware_guest: use the disk argument to modify disk size and type (#2918)
Fixes #2706
This commit is contained in:
parent
bbf60e36eb
commit
d9b5d9e551
1 changed files with 68 additions and 13 deletions
|
@ -164,6 +164,7 @@ except ImportError:
|
|||
import atexit
|
||||
import os
|
||||
import ssl
|
||||
import string
|
||||
import time
|
||||
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
|
@ -503,15 +504,20 @@ class PyVmomiHelper(object):
|
|||
def deploy_template(self, poweron=False, wait_for_ip=False):
|
||||
|
||||
# https://github.com/vmware/pyvmomi-community-samples/blob/master/samples/clone_vm.py
|
||||
# https://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/vim.vm.CloneSpec.html
|
||||
# https://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/vim.vm.ConfigSpec.html
|
||||
|
||||
# FIXME:
|
||||
# - clusters
|
||||
# - multiple datacenters
|
||||
# - resource pools
|
||||
# - multiple templates by the same name
|
||||
# - use disk config from template by default
|
||||
# - multiple disks
|
||||
# - static IPs
|
||||
|
||||
# FIXME: need to search for this in the same way as guests to ensure accuracy
|
||||
template = get_obj(self.content, [vim.VirtualMachine], self.params['template'])
|
||||
|
||||
datacenters = get_all_objs(self.content, [vim.Datacenter])
|
||||
datacenter = get_obj(self.content, [vim.Datacenter],
|
||||
self.params['datacenter'])
|
||||
|
@ -534,19 +540,20 @@ class PyVmomiHelper(object):
|
|||
# grab the folder vim object
|
||||
destfolder = folders[0][1]
|
||||
|
||||
if not 'disk' in self.params:
|
||||
return ({'changed': False, 'failed': True, 'msg': "'disk' is required for VM deployment"})
|
||||
|
||||
datastore_name = self.params['disk'][0]['datastore']
|
||||
datastore = get_obj(self.content, [vim.Datastore], datastore_name)
|
||||
|
||||
|
||||
# cluster or hostsystem ... ?
|
||||
# FIXME: cluster or hostsystem ... ?
|
||||
#cluster = get_obj(self.content, [vim.ClusterComputeResource], self.params['esxi']['hostname'])
|
||||
hostsystem = get_obj(self.content, [vim.HostSystem], self.params['esxi_hostname'])
|
||||
|
||||
resource_pools = get_all_objs(self.content, [vim.ResourcePool])
|
||||
|
||||
if self.params['disk']:
|
||||
datastore_name = self.params['disk'][0]['datastore']
|
||||
datastore = get_obj(self.content, [vim.Datastore], datastore_name)
|
||||
else:
|
||||
# use the template's existing DS
|
||||
disks = [x for x in template.config.hardware.device if isinstance(x, vim.vm.device.VirtualDisk)]
|
||||
datastore = disks[0].backing.datastore
|
||||
datastore_name = datastore.name
|
||||
|
||||
relospec = vim.vm.RelocateSpec()
|
||||
relospec.datastore = datastore
|
||||
|
||||
|
@ -554,10 +561,58 @@ class PyVmomiHelper(object):
|
|||
relospec.pool = resource_pools[0]
|
||||
relospec.host = hostsystem
|
||||
|
||||
clonespec = vim.vm.CloneSpec()
|
||||
clonespec.location = relospec
|
||||
clonespec_kwargs = {}
|
||||
clonespec_kwargs['location'] = relospec
|
||||
|
||||
template = get_obj(self.content, [vim.VirtualMachine], self.params['template'])
|
||||
# create disk spec if not default
|
||||
if self.params['disk']:
|
||||
# grab the template's first disk and modify it for this customization
|
||||
disks = [x for x in template.config.hardware.device if isinstance(x, vim.vm.device.VirtualDisk)]
|
||||
diskspec = vim.vm.device.VirtualDeviceSpec()
|
||||
# set the operation to edit so that it knows to keep other settings
|
||||
diskspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
|
||||
diskspec.device = disks[0]
|
||||
|
||||
# get the first disk attributes
|
||||
pspec = self.params.get('disk')[0]
|
||||
|
||||
# is it thin?
|
||||
if pspec.get('type', '').lower() == 'thin':
|
||||
diskspec.device.backing.thinProvisioned = True
|
||||
|
||||
# what size is it?
|
||||
if [x for x in pspec.keys() if x.startswith('size_') or x == 'size']:
|
||||
# size_tb, size_gb, size_mb, size_kb, size_b ...?
|
||||
if 'size' in pspec:
|
||||
# http://stackoverflow.com/a/1451407
|
||||
trans = string.maketrans('', '')
|
||||
chars = trans.translate(trans, string.digits)
|
||||
expected = pspec['size'].translate(trans, chars)
|
||||
expected = expected
|
||||
unit = pspec['size'].replace(expected, '').lower()
|
||||
expected = int(expected)
|
||||
else:
|
||||
expected = [x for x in pspec.keys() if x.startswith('size_')][0]
|
||||
unit = expected.split('_')[-1].lower()
|
||||
|
||||
kb = None
|
||||
if unit == 'tb':
|
||||
kb = expected * 1024 * 1024 * 1024
|
||||
elif unit == 'gb':
|
||||
kb = expected * 1024 * 1024
|
||||
elif unit ==' mb':
|
||||
kb = expected * 1024
|
||||
elif unit == 'kb':
|
||||
kb = expected
|
||||
else:
|
||||
self.module.fail_json(msg='%s is not a supported unit for disk size' % unit)
|
||||
diskspec.device.capacityInKB = kb
|
||||
|
||||
# tell the configspec that the disk device needs to change
|
||||
configspec = vim.vm.ConfigSpec(deviceChange=[diskspec])
|
||||
clonespec_kwargs['config'] = configspec
|
||||
|
||||
clonespec = vim.vm.CloneSpec(**clonespec_kwargs)
|
||||
task = template.Clone(folder=destfolder, name=self.params['name'], spec=clonespec)
|
||||
self.wait_for_task(task)
|
||||
|
||||
|
|
Loading…
Reference in a new issue