1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Wait for VM state to reach poweredoff when state: shutdownguest (#31669)

This change adds the optional wait_for_state_change argument to the
vmware_guest, vmware_guest_powerstate module, which allows for module
completion to be blocked when using the shutdownguest state until the
VM has reached the poweredoff state.

Fixes: #28498

Signed-off-by: Jim Gu <heming.gu@mercurygate.com>
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
Jim Gu 2018-02-21 06:44:12 -05:00 committed by Abhijeet Kasurde
parent df8a5d7a4f
commit b6d4fa1c96
3 changed files with 47 additions and 3 deletions

View file

@ -716,7 +716,7 @@ def find_host_by_cluster_datacenter(module, content, datacenter_name, cluster_na
return None, cluster return None, cluster
def set_vm_power_state(content, vm, state, force): def set_vm_power_state(content, vm, state, force, timeout=0):
""" """
Set the power status for a VM determined by the current and Set the power status for a VM determined by the current and
requested states. force is forceful requested states. force is forceful
@ -764,6 +764,8 @@ def set_vm_power_state(content, vm, state, force):
if vm.guest.toolsRunningStatus == 'guestToolsRunning': if vm.guest.toolsRunningStatus == 'guestToolsRunning':
if expected_state == 'shutdownguest': if expected_state == 'shutdownguest':
task = vm.ShutdownGuest() task = vm.ShutdownGuest()
if timeout > 0:
result.update(wait_for_poweroff(vm, timeout))
else: else:
task = vm.RebootGuest() task = vm.RebootGuest()
# Set result['changed'] immediately because # Set result['changed'] immediately because
@ -799,6 +801,20 @@ def set_vm_power_state(content, vm, state, force):
return result return result
def wait_for_poweroff(vm, timeout=300):
result = dict()
interval = 15
while timeout > 0:
if vm.runtime.powerState.lower() == 'poweredoff':
break
time.sleep(interval)
timeout -= interval
else:
result['failed'] = True
result['msg'] = 'Timeout while waiting for VM power off.'
return result
class PyVmomi(object): class PyVmomi(object):
def __init__(self, module): def __init__(self, module):
""" """

View file

@ -156,6 +156,13 @@ options:
- "vmware-tools needs to be installed on given virtual machine in order to work with this parameter." - "vmware-tools needs to be installed on given virtual machine in order to work with this parameter."
default: 'no' default: 'no'
type: bool type: bool
state_change_timeout:
description:
- If the C(state) is set to C(shutdownguest), by default the module will return immediately after sending the shutdown signal.
- If this argument is set to a positive integer, the module will instead wait for the VM to reach the poweredoff state.
- The value sets a timeout in seconds for the module to wait for the state change.
default: 0
version_added: '2.6'
snapshot_src: snapshot_src:
description: description:
- Name of the existing snapshot to use to create a clone of a VM. - Name of the existing snapshot to use to create a clone of a VM.
@ -1994,6 +2001,7 @@ def main():
esxi_hostname=dict(type='str'), esxi_hostname=dict(type='str'),
cluster=dict(type='str'), cluster=dict(type='str'),
wait_for_ip_address=dict(type='bool', default=False), wait_for_ip_address=dict(type='bool', default=False),
state_change_timeout=dict(type='int', default=0),
snapshot_src=dict(type='str'), snapshot_src=dict(type='str'),
linked_clone=dict(type='bool', default=False), linked_clone=dict(type='bool', default=False),
networks=dict(type='list', default=[]), networks=dict(type='list', default=[]),
@ -2054,7 +2062,7 @@ def main():
) )
module.exit_json(**result) module.exit_json(**result)
# set powerstate # set powerstate
tmp_result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force']) tmp_result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force'], module.params['state_change_timeout'])
if tmp_result['changed']: if tmp_result['changed']:
result["changed"] = True result["changed"] = True
if not tmp_result["failed"]: if not tmp_result["failed"]:

View file

@ -64,6 +64,13 @@ options:
- Date and time in string format at which specificed task needs to be performed. - Date and time in string format at which specificed task needs to be performed.
- "The required format for date and time - 'dd/mm/yyyy hh:mm'." - "The required format for date and time - 'dd/mm/yyyy hh:mm'."
- Scheduling task requires vCenter server. A standalone ESXi server does not support this option. - Scheduling task requires vCenter server. A standalone ESXi server does not support this option.
state_change_timeout:
description:
- If the C(state) is set to C(shutdown-guest), by default the module will return immediately after sending the shutdown signal.
- If this argument is set to a positive integer, the module will instead wait for the VM to reach the poweredoff state.
- The value sets a timeout in seconds for the module to wait for the state change.
default: 0
version_added: '2.6'
extends_documentation_fragment: vmware.documentation extends_documentation_fragment: vmware.documentation
''' '''
@ -92,6 +99,18 @@ EXAMPLES = r'''
scheduled_at: "09/01/2018 10:18" scheduled_at: "09/01/2018 10:18"
delegate_to: localhost delegate_to: localhost
register: deploy_at_schedule_datetime register: deploy_at_schedule_datetime
- name: Wait for the virtual machine to shutdown
vmware_guest_powerstate:
hostname: 192.0.2.44
username: administrator@vsphere.local
password: vmware
validate_certs: no
name: testvm_2
state: shutdown-guest
state_change_timeout: 200
delegate_to: localhost
register: deploy
''' '''
RETURN = r''' # ''' RETURN = r''' # '''
@ -118,6 +137,7 @@ def main():
folder=dict(type='str', default='/vm'), folder=dict(type='str', default='/vm'),
force=dict(type='bool', default=False), force=dict(type='bool', default=False),
scheduled_at=dict(type='str'), scheduled_at=dict(type='str'),
state_change_timeout=dict(type='int', default=0),
) )
module = AnsibleModule(argument_spec=argument_spec, module = AnsibleModule(argument_spec=argument_spec,
@ -182,7 +202,7 @@ def main():
"given are invalid: %s" % (module.params.get('state'), "given are invalid: %s" % (module.params.get('state'),
to_native(e.msg))) to_native(e.msg)))
else: else:
result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force']) result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force'], module.params['state_change_timeout'])
else: else:
module.fail_json(msg="Unable to set power state for non-existing virtual machine : '%s'" % (module.params.get('uuid') or module.params.get('name'))) module.fail_json(msg="Unable to set power state for non-existing virtual machine : '%s'" % (module.params.get('uuid') or module.params.get('name')))