diff --git a/changelogs/fragments/102_module_at_add_chdir_option.yml b/changelogs/fragments/102_module_at_add_chdir_option.yml new file mode 100644 index 0000000..e4724ed --- /dev/null +++ b/changelogs/fragments/102_module_at_add_chdir_option.yml @@ -0,0 +1,2 @@ +minor_changes: + - at - add option ``chdir`` to permit to launch the ``at`` command from a specific directory (https://github.com/ansible-collections/ansible.posix/issues/13). diff --git a/plugins/modules/at.py b/plugins/modules/at.py index a35ec4e..97213c6 100644 --- a/plugins/modules/at.py +++ b/plugins/modules/at.py @@ -17,6 +17,12 @@ description: - All jobs are executed in the 'a' queue. version_added: "1.0.0" options: + chdir: + description: + - An optional location from where to run the command C(at). + - Useful for intance when running a playbook using ansible-pull with C(purge) option. + type: path + version_added: 1.3.0 command: description: - A command to be executed in the future. @@ -38,7 +44,7 @@ options: description: - The state dictates if the command or script file should be evaluated as present(added) or absent(deleted). type: str - choices: [ absent, present ] + choices: [absent, present] default: present unique: description: @@ -78,32 +84,32 @@ import tempfile from ansible.module_utils.basic import AnsibleModule -def add_job(module, result, at_cmd, count, units, command, script_file): +def add_job(module, result, at_cmd, count, units, command, script_file, chdir=None): at_command = "%s -f %s now + %s %s" % (at_cmd, script_file, count, units) - rc, out, err = module.run_command(at_command, check_rc=True) + rc, out, err = module.run_command(at_command, cwd=chdir, check_rc=True) if command: os.unlink(script_file) result['changed'] = True -def delete_job(module, result, at_cmd, command, script_file): +def delete_job(module, result, at_cmd, command, script_file, chdir=None): for matching_job in get_matching_jobs(module, at_cmd, script_file): at_command = "%s -r %s" % (at_cmd, matching_job) - rc, out, err = module.run_command(at_command, check_rc=True) + rc, out, err = module.run_command(at_command, cwd=chdir, check_rc=True) result['changed'] = True if command: os.unlink(script_file) module.exit_json(**result) -def get_matching_jobs(module, at_cmd, script_file): +def get_matching_jobs(module, at_cmd, script_file, chdir=None): matching_jobs = [] atq_cmd = module.get_bin_path('atq', True) # Get list of job numbers for the user. atq_command = "%s" % atq_cmd - rc, out, err = module.run_command(atq_command, check_rc=True) + rc, out, err = module.run_command(atq_command, cwd=chdir, check_rc=True) current_jobs = out.splitlines() if len(current_jobs) == 0: return matching_jobs @@ -118,7 +124,7 @@ def get_matching_jobs(module, at_cmd, script_file): split_current_job = current_job.split() at_opt = '-c' if platform.system() != 'AIX' else '-lv' at_command = "%s %s %s" % (at_cmd, at_opt, split_current_job[0]) - rc, out, err = module.run_command(at_command, check_rc=True) + rc, out, err = module.run_command(at_command, cwd=chdir, check_rc=True) if script_file_string in out: matching_jobs.append(split_current_job[0]) @@ -139,6 +145,7 @@ def main(): module = AnsibleModule( argument_spec=dict( command=dict(type='str'), + chdir=dict(type='path'), script_file=dict(type='str'), count=dict(type='int'), units=dict(type='str', choices=['minutes', 'hours', 'days', 'weeks']), @@ -152,6 +159,7 @@ def main(): at_cmd = module.get_bin_path('at', True) + chdir = module.params['chdir'] command = module.params['command'] script_file = module.params['script_file'] count = module.params['count'] @@ -173,7 +181,7 @@ def main(): # if absent remove existing and return if state == 'absent': - delete_job(module, result, at_cmd, command, script_file) + delete_job(module, result, at_cmd, command, script_file, chdir=chdir) # if unique if existing return unchanged if unique: @@ -186,7 +194,7 @@ def main(): result['count'] = count result['units'] = units - add_job(module, result, at_cmd, count, units, command, script_file) + add_job(module, result, at_cmd, count, units, command, script_file, chdir=chdir) module.exit_json(**result) diff --git a/tests/integration/targets/at/aliases b/tests/integration/targets/at/aliases index 85f744a..6eae8bd 100644 --- a/tests/integration/targets/at/aliases +++ b/tests/integration/targets/at/aliases @@ -1,3 +1,2 @@ shippable/posix/group1 destructive -disabled # fixme package diff --git a/tests/integration/targets/at/tasks/main.yml b/tests/integration/targets/at/tasks/main.yml index cd09e11..3351532 100644 --- a/tests/integration/targets/at/tasks/main.yml +++ b/tests/integration/targets/at/tasks/main.yml @@ -28,16 +28,16 @@ ## at ## -- name: define distros to attempt installing at on +- name: define distros to attempt installing at on set_fact: package_distros: - - RedHat - - CentOS - - ScientificLinux - - Fedora - - Ubuntu - - Debian - - openSUSE Leap + - RedHat + - CentOS + - ScientificLinux + - Fedora + - Ubuntu + - Debian + - openSUSE Leap - name: ensure at is installed package: @@ -54,9 +54,66 @@ - debug: var=at_test0 - name: validate results assert: - that: - - 'at_test0.changed is defined' - - 'at_test0.count is defined' - - 'at_test0.script_file is defined' - - 'at_test0.state is defined' - - 'at_test0.units is defined' + that: + - 'at_test0.changed is defined' + - 'at_test0.count is defined' + - 'at_test0.script_file is defined' + - 'at_test0.state is defined' + - 'at_test0.units is defined' + +- name: Add a useless command using at + at: + command: /bin/logger 'AT task ran from Ansible' + count: 1 + units: minutes + unique: yes + register: at_add + +- debug: var=at_add + +- name: Wait for at to run the previous command + pause: + minutes: 1 + +- name: Add a useless command + at: + command: /bin/logger 'AT task ran from Ansible' + count: 1 + units: minutes + unique: true + state: absent + register: at_removal + +- debug: var=at_removal + +- name: Validate results + assert: + that: + - at_add is changed + - at_removal is changed + +- name: Create an at command with chdir with valid value + at: + command: /bin/logger 'AT task ran from Ansible with chdir' + count: 1 + units: minutes + chdir: /tmp + register: at_chdir_valid +- debug: var=at_chdir_valid + +- name: Create an at command with chdir with invalid value + at: + command: /bin/logger 'AT task ran from Ansible with chdir' + count: 1 + units: minutes + chdir: /invalid + register: at_chdir_invalid + ignore_errors: true + +- debug: var=at_chdir_invalid + +- name: Validate results + assert: + that: + - at_chdir_valid is changed + - not at_chdir_valid is changed