Skip to content

Commit

Permalink
vmware_guest: use the disk argument to modify disk size and type (ans…
Browse files Browse the repository at this point in the history
  • Loading branch information
jctanner authored and mattclay committed Dec 8, 2016
1 parent bbf60e3 commit d9b5d9e
Showing 1 changed file with 68 additions and 13 deletions.
81 changes: 68 additions & 13 deletions lib/ansible/modules/extras/cloud/vmware/vmware_guest.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
import atexit
import os
import ssl
import string
import time

from ansible.module_utils.urls import fetch_url
Expand Down Expand Up @@ -503,15 +504,20 @@ def remove_vm(self, vm):
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'])
Expand All @@ -534,30 +540,79 @@ def deploy_template(self, poweron=False, wait_for_ip=False):
# 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

# fixme ... use the pool from the cluster if given
relospec.pool = resource_pools[0]
relospec.host = hostsystem

clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
clonespec_kwargs = {}
clonespec_kwargs['location'] = relospec

# 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

template = get_obj(self.content, [vim.VirtualMachine], self.params['template'])
clonespec = vim.vm.CloneSpec(**clonespec_kwargs)
task = template.Clone(folder=destfolder, name=self.params['name'], spec=clonespec)
self.wait_for_task(task)

Expand Down

0 comments on commit d9b5d9e

Please sign in to comment.