|
|
@ -202,6 +202,13 @@ options:
|
|
|
|
- "vmware-tools needs to be installed on the given virtual machine in order to work with this parameter."
|
|
|
|
- "vmware-tools needs to be installed on the given virtual machine in order to work with this parameter."
|
|
|
|
default: 'no'
|
|
|
|
default: 'no'
|
|
|
|
type: bool
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
wait_for_customization:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Wait until vCenter detects all guest customizations as successfully completed.
|
|
|
|
|
|
|
|
- When enabled, the VM will automatically be powered on.
|
|
|
|
|
|
|
|
default: 'no'
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
version_added: '2.8'
|
|
|
|
state_change_timeout:
|
|
|
|
state_change_timeout:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- If the C(state) is set to C(shutdownguest), by default the module will return immediately after sending the shutdown signal.
|
|
|
|
- If the C(state) is set to C(shutdownguest), by default the module will return immediately after sending the shutdown signal.
|
|
|
@ -2193,12 +2200,18 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
task = vm.ReconfigVM_Task(vm_custom_spec)
|
|
|
|
task = vm.ReconfigVM_Task(vm_custom_spec)
|
|
|
|
self.wait_for_task(task)
|
|
|
|
self.wait_for_task(task)
|
|
|
|
|
|
|
|
|
|
|
|
if self.params['wait_for_ip_address'] or self.params['state'] in ['poweredon', 'restarted']:
|
|
|
|
if self.params['wait_for_ip_address'] or self.params['wait_for_customization'] or self.params['state'] in ['poweredon', 'restarted']:
|
|
|
|
set_vm_power_state(self.content, vm, 'poweredon', force=False)
|
|
|
|
set_vm_power_state(self.content, vm, 'poweredon', force=False)
|
|
|
|
|
|
|
|
|
|
|
|
if self.params['wait_for_ip_address']:
|
|
|
|
if self.params['wait_for_ip_address']:
|
|
|
|
self.wait_for_vm_ip(vm)
|
|
|
|
self.wait_for_vm_ip(vm)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.params['wait_for_customization']:
|
|
|
|
|
|
|
|
is_customization_ok = self.wait_for_customization(vm)
|
|
|
|
|
|
|
|
if not is_customization_ok:
|
|
|
|
|
|
|
|
vm_facts = self.gather_facts(vm)
|
|
|
|
|
|
|
|
return {'changed': self.change_detected, 'failed': True, 'instance': vm_facts}
|
|
|
|
|
|
|
|
|
|
|
|
vm_facts = self.gather_facts(vm)
|
|
|
|
vm_facts = self.gather_facts(vm)
|
|
|
|
return {'changed': self.change_detected, 'failed': False, 'instance': vm_facts}
|
|
|
|
return {'changed': self.change_detected, 'failed': False, 'instance': vm_facts}
|
|
|
|
|
|
|
|
|
|
|
@ -2341,6 +2354,38 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
|
|
|
|
|
|
|
|
return facts
|
|
|
|
return facts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_vm_events(self, eventTypeIdList):
|
|
|
|
|
|
|
|
newvm = self.get_vm()
|
|
|
|
|
|
|
|
byEntity = vim.event.EventFilterSpec.ByEntity(entity=newvm, recursion="self")
|
|
|
|
|
|
|
|
filterSpec = vim.event.EventFilterSpec(entity=byEntity, eventTypeId=eventTypeIdList)
|
|
|
|
|
|
|
|
eventManager = self.content.eventManager
|
|
|
|
|
|
|
|
return eventManager.QueryEvent(filterSpec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def wait_for_customization(self, vm, poll=10000, sleep=10):
|
|
|
|
|
|
|
|
facts = {}
|
|
|
|
|
|
|
|
thispoll = 0
|
|
|
|
|
|
|
|
while thispoll <= poll:
|
|
|
|
|
|
|
|
eventStarted = self.get_vm_events(['CustomizationStartedEvent'])
|
|
|
|
|
|
|
|
if len(eventStarted):
|
|
|
|
|
|
|
|
thispoll = 0
|
|
|
|
|
|
|
|
while thispoll <= poll:
|
|
|
|
|
|
|
|
eventsFinishedResult = self.get_vm_events(['CustomizationSucceeded', 'CustomizationFailed'])
|
|
|
|
|
|
|
|
if len(eventsFinishedResult):
|
|
|
|
|
|
|
|
if not isinstance(eventsFinishedResult[0], vim.event.CustomizationSucceeded):
|
|
|
|
|
|
|
|
self.module.fail_json(msg='Customization failed with error {0}:\n{1}'.format(
|
|
|
|
|
|
|
|
eventsFinishedResult[0]._wsdlName, eventsFinishedResult[0].fullFormattedMessage))
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
time.sleep(sleep)
|
|
|
|
|
|
|
|
thispoll += 1
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
time.sleep(sleep)
|
|
|
|
|
|
|
|
thispoll += 1
|
|
|
|
|
|
|
|
self.module.fail_json('waiting for customizations timed out.')
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
def main():
|
|
|
|
argument_spec = vmware_argument_spec()
|
|
|
|
argument_spec = vmware_argument_spec()
|
|
|
@ -2371,6 +2416,7 @@ def main():
|
|
|
|
resource_pool=dict(type='str'),
|
|
|
|
resource_pool=dict(type='str'),
|
|
|
|
customization=dict(type='dict', default={}, no_log=True),
|
|
|
|
customization=dict(type='dict', default={}, no_log=True),
|
|
|
|
customization_spec=dict(type='str', default=None),
|
|
|
|
customization_spec=dict(type='str', default=None),
|
|
|
|
|
|
|
|
wait_for_customization=dict(type='bool', default=False),
|
|
|
|
vapp_properties=dict(type='list', default=[]),
|
|
|
|
vapp_properties=dict(type='list', default=[]),
|
|
|
|
datastore=dict(type='str'),
|
|
|
|
datastore=dict(type='str'),
|
|
|
|
convert=dict(type='str', choices=['thin', 'thick', 'eagerzeroedthick']),
|
|
|
|
convert=dict(type='str', choices=['thin', 'thick', 'eagerzeroedthick']),
|
|
|
|