1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
# -*- coding: utf-8 -*-
# Copyright: (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>, and others
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import sys
DOCUMENTATION = r"""
---
module: async_status
short_description: Obtain status of asynchronous task
description:
- This module gets the status of an asynchronous task.
- This module is also supported for Windows targets.
version_added: "0.5"
options:
jid:
description:
- Job or task identifier
type: str
required: true
mode:
description:
- If V(status), obtain the status.
- If V(cleanup), clean up the async job cache (by default in C(~/.ansible_async/)) for the specified job O(jid), without waiting for it to finish.
type: str
choices: [ cleanup, status ]
default: status
notes:
- The RV(started) and RV(finished) return values were updated to return V(True) or V(False) instead of V(1) or V(0) in ansible-core 2.19.
extends_documentation_fragment:
- action_common_attributes
- action_common_attributes.flow
attributes:
action:
support: full
async:
support: none
check_mode:
support: full
version_added: '2.17'
diff_mode:
support: none
bypass_host_loop:
support: none
platform:
support: full
platforms: posix, windows
seealso:
- ref: playbooks_async
description: Detailed information on how to use asynchronous actions and polling.
author:
- Ansible Core Team
- Michael DeHaan
"""
EXAMPLES = r"""
---
- name: Asynchronous dnf task
ansible.builtin.dnf:
name: docker-io
state: present
async: 1000
poll: 0
register: dnf_sleeper
- name: Wait for asynchronous job to end
ansible.builtin.async_status:
jid: '{{ dnf_sleeper.ansible_job_id }}'
register: job_result
until: job_result is finished
retries: 100
delay: 10
- name: Clean up async file
ansible.builtin.async_status:
jid: '{{ dnf_sleeper.ansible_job_id }}'
mode: cleanup
"""
RETURN = r"""
ansible_job_id:
description: The asynchronous job id
returned: success
type: str
sample: '360874038559.4169'
finished:
description: Whether the asynchronous job has finished or not
returned: always
type: bool
sample: true
started:
description: Whether the asynchronous job has started or not
returned: always
type: bool
sample: true
stdout:
description: Any output returned by async_wrapper
returned: always
type: str
stderr:
description: Any errors returned by async_wrapper
returned: always
type: str
erased:
description: Path to erased job file
returned: when file is erased
type: str
"""
import json
import os
from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec=dict(
jid=dict(type="str", required=True),
mode=dict(type="str", default="status", choices=["cleanup", "status"]),
# passed in from the async_status action plugin
_async_dir=dict(type="path", required=True),
),
supports_check_mode=True,
)
mode = module.params['mode']
jid = module.params['jid']
async_dir = module.params['_async_dir']
# setup logging directory
log_path = os.path.join(async_dir, jid)
if not os.path.exists(log_path):
module.fail_json(msg="could not find job", ansible_job_id=jid, started=True, finished=True)
if mode == 'cleanup':
os.unlink(log_path)
module.exit_json(ansible_job_id=jid, erased=log_path)
# NOT in cleanup mode, assume regular status mode
# no remote kill mode currently exists, but probably should
# consider log_path + ".pid" file and also unlink that above
data = None
try:
with open(log_path) as f:
data = json.loads(f.read())
except Exception:
if not data:
# file not written yet? That means it is running
module.exit_json(results_file=log_path, ansible_job_id=jid, started=True, finished=False)
else:
module.fail_json(ansible_job_id=jid, results_file=log_path,
msg="Could not parse job output: %s" % data, started=True, finished=True)
if 'started' not in data:
data['finished'] = True
data['ansible_job_id'] = jid
elif 'finished' not in data:
data['finished'] = False
# just write the module output directly to stdout and exit; bypass other processing done by exit_json since it's already been done
print(f"\n{json.dumps(data)}") # pylint: disable=ansible-bad-function
sys.exit(0) # pylint: disable=ansible-bad-function
if __name__ == '__main__':
main()
|