Skip to content

Commit 0eed21f

Browse files
Enhancement/1887/zos unarchive (#2020)
* async changes for unarchive * test case to test the async functionality for zos_unarchive * changelog addition * Update test_zos_unarchive_func.py --------- Co-authored-by: André Marcel Gutiérrez Benítez <[email protected]>
1 parent 5bef980 commit 0eed21f

File tree

4 files changed

+138
-2
lines changed

4 files changed

+138
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
minor_changes:
2+
- zos_unarchive - Adds support for unarchiving files in asynchronous mode inside playbooks.
3+
(https://github.com/ansible-collections/ibm_zos_core/pull/2020).

plugins/action/zos_unarchive.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) IBM Corporation 2023, 2024
1+
# Copyright (c) IBM Corporation 2023, 2025
22
# Licensed under the Apache License, Version 2.0 (the "License");
33
# you may not use this file except in compliance with the License.
44
# You may obtain a copy of the License at
@@ -34,11 +34,14 @@ def _process_boolean(arg, default=False):
3434

3535
class ActionModule(ActionBase):
3636
def run(self, tmp=None, task_vars=None):
37+
self._supports_async = True
3738
if task_vars is None:
3839
task_vars = dict()
3940

4041
result = super(ActionModule, self).run(tmp, task_vars)
4142

43+
self._task_vars = task_vars
44+
4245
if result.get("skipped"):
4346
return result
4447

@@ -53,6 +56,7 @@ def run(self, tmp=None, task_vars=None):
5356
module_name="ibm.ibm_zos_core.zos_unarchive",
5457
module_args=module_args,
5558
task_vars=task_vars,
59+
wrap_async=self._task.async_val
5660
)
5761
)
5862
else:
@@ -102,6 +106,8 @@ def run(self, tmp=None, task_vars=None):
102106
)
103107
copy_task = self._task.copy()
104108
copy_task.args = copy_module_args
109+
# Making the zos_copy task run synchronously every time.
110+
copy_task.async_val = 0
105111
copy_action = self._shared_loader_obj.action_loader.get(
106112
'ibm.ibm_zos_core.zos_copy',
107113
task=copy_task,
@@ -120,6 +126,7 @@ def run(self, tmp=None, task_vars=None):
120126
module_name="ibm.ibm_zos_core.zos_unarchive",
121127
module_args=module_args,
122128
task_vars=task_vars,
129+
wrap_async=self._task.async_val
123130
)
124131
)
125132
else:

plugins/modules/zos_unarchive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
support: full
319319
description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller.
320320
async:
321-
support: none
321+
support: full
322322
description: Supports being used with the ``async`` keyword.
323323
check_mode:
324324
support: full

tests/functional/modules/test_zos_unarchive_func.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515

1616
from __future__ import absolute_import, division, print_function
1717

18+
import os
1819
import pytest
1920
import tempfile
2021
from tempfile import mkstemp
2122
from ibm_zos_core.tests.helpers.dataset import get_tmp_ds_name
23+
import yaml
24+
from shellescape import quote
25+
import subprocess
2226

2327
__metaclass__ = type
2428

@@ -33,6 +37,51 @@
3337

3438
USS_FORMATS = ['tar', 'gz', 'bz2', 'zip', 'pax']
3539

40+
PLAYBOOK_ASYNC_TEST = """- hosts: zvm
41+
collections:
42+
- ibm.ibm_zos_core
43+
gather_facts: False
44+
environment:
45+
_BPXK_AUTOCVT: "ON"
46+
ZOAU_HOME: "{0}"
47+
PYTHONPATH: "{0}/lib/{2}"
48+
LIBPATH: "{0}/lib:{1}/lib:/lib:/usr/lib:."
49+
PATH: "{0}/bin:/bin:/usr/lpp/rsusr/ported/bin:/var/bin:/usr/lpp/rsusr/ported/bin:/usr/lpp/java/java180/J8.0_64/bin:{1}/bin:"
50+
_CEE_RUNOPTS: "FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)"
51+
_TAG_REDIR_ERR: "txt"
52+
_TAG_REDIR_IN: "txt"
53+
_TAG_REDIR_OUT: "txt"
54+
LANG: "C"
55+
PYTHONSTDINENCODING: "cp1047"
56+
57+
tasks:
58+
- name: Execute script in async mode.
59+
ibm.ibm_zos_core.zos_unarchive:
60+
src: {3}
61+
format:
62+
name: {4}
63+
remote_src: True
64+
async: 45
65+
poll: 0
66+
register: job_task
67+
68+
- name: Query async task.
69+
async_status:
70+
jid: "{{{{ job_task.ansible_job_id }}}}"
71+
register: job_result
72+
until: job_result.finished
73+
retries: 20
74+
delay: 5
75+
"""
76+
77+
INVENTORY_ASYNC_TEST = """all:
78+
hosts:
79+
zvm:
80+
ansible_host: {0}
81+
ansible_ssh_private_key_file: {1}
82+
ansible_user: {2}
83+
ansible_python_interpreter: {3}"""
84+
3685
def set_uss_test_env(ansible_zos_module, test_files):
3786
for key, value in test_files.items():
3887
ansible_zos_module.all.shell(
@@ -1185,3 +1234,80 @@ def test_gdg_unarchive(ansible_zos_module, dstype, format):
11851234
finally:
11861235
hosts.all.shell(cmd=f'drm "{HLQ}.*"')
11871236

1237+
@pytest.mark.uss
1238+
def test_zos_unarchive_async(ansible_zos_module, get_config):
1239+
try:
1240+
# Load environment details from the config file
1241+
with open(get_config, 'r') as file:
1242+
environment = yaml.safe_load(file)
1243+
1244+
ssh_key = environment["ssh_key"]
1245+
hosts = environment["host"].upper()
1246+
user = environment["user"].upper()
1247+
python_path = environment["python_path"]
1248+
cut_python_path = python_path[:python_path.find('/bin')].strip()
1249+
zoau = environment["environment"]["ZOAU_ROOT"]
1250+
python_version = cut_python_path.split('/')[2]
1251+
archive_format = USS_FORMATS[0]
1252+
1253+
# Create a temporary archive file for testing
1254+
hosts_zos = ansible_zos_module
1255+
hosts_zos.all.file(path=f"{USS_TEMP_DIR}", state="absent")
1256+
hosts_zos.all.file(path=USS_TEMP_DIR, state="directory")
1257+
set_uss_test_env(hosts_zos, USS_TEST_FILES)
1258+
dest = f"{USS_TEMP_DIR}/archive.{archive_format}"
1259+
archive_result = hosts_zos.all.zos_archive(src=list(USS_TEST_FILES.keys()),
1260+
dest=dest,
1261+
format=dict(
1262+
name=archive_format
1263+
))
1264+
# remove files
1265+
for file in USS_TEST_FILES.keys():
1266+
hosts_zos.all.file(path=file, state="absent")
1267+
1268+
# Create temporary playbook and inventory files
1269+
playbook = tempfile.NamedTemporaryFile(delete=True)
1270+
inventory = tempfile.NamedTemporaryFile(delete=True)
1271+
1272+
os.system("echo {0} > {1}".format(
1273+
quote(PLAYBOOK_ASYNC_TEST.format(
1274+
zoau,
1275+
cut_python_path,
1276+
python_version,
1277+
dest,
1278+
archive_format,
1279+
)),
1280+
playbook.name
1281+
))
1282+
1283+
os.system("echo {0} > {1}".format(
1284+
quote(INVENTORY_ASYNC_TEST.format(
1285+
hosts,
1286+
ssh_key,
1287+
user,
1288+
python_path
1289+
)),
1290+
inventory.name
1291+
))
1292+
1293+
# Run the Ansible playbook
1294+
command = "ansible-playbook -i {0} {1}".format(
1295+
inventory.name,
1296+
playbook.name
1297+
)
1298+
1299+
result = subprocess.run(
1300+
command,
1301+
capture_output=True,
1302+
shell=True,
1303+
timeout=120,
1304+
encoding='utf-8'
1305+
)
1306+
1307+
# Assertions to validate the result
1308+
assert result.returncode == 0
1309+
assert "ok=2" in result.stdout
1310+
assert "changed=2" in result.stdout
1311+
assert result.stderr == ""
1312+
finally:
1313+
hosts_zos.all.file(path=f"{USS_TEMP_DIR}", state="absent")

0 commit comments

Comments
 (0)