From 4aa27cadbf86cb09f8c25721e3a5d41c7ade69af Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 27 Aug 2025 13:27:51 -0700 Subject: [PATCH 1/2] cron: Handle exception raised while writing cron file Fixes: #85726 Signed-off-by: Abhijeet Kasurde --- changelogs/fragments/cron_non_existent_file.yml | 3 +++ lib/ansible/modules/cron.py | 15 ++++++++++++--- test/integration/targets/cron/tasks/main.yml | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/cron_non_existent_file.yml diff --git a/changelogs/fragments/cron_non_existent_file.yml b/changelogs/fragments/cron_non_existent_file.yml new file mode 100644 index 00000000000..eeec6e6a767 --- /dev/null +++ b/changelogs/fragments/cron_non_existent_file.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - cron - handle FileNotFoundError and OSError exception while writing cron file (https://github.com/ansible/ansible/issues/85726). diff --git a/lib/ansible/modules/cron.py b/lib/ansible/modules/cron.py index 325aa524beb..54ee28b502f 100644 --- a/lib/ansible/modules/cron.py +++ b/lib/ansible/modules/cron.py @@ -311,9 +311,15 @@ class CronTab: if backup_file: fileh = open(backup_file, 'wb') elif self.cron_file: - fileh = open(self.b_cron_file, 'wb') + try: + fileh = open(self.b_cron_file, 'wb') + except FileNotFoundError as ex: + self.module.fail_json(msg=f'Unable to open {self.cron_file} for writing as file does not exists') else: - filed, path = tempfile.mkstemp(prefix='crontab') + try: + filed, path = tempfile.mkstemp(prefix='crontab') + except OSError as ex: + self.module.fail_json(msg=f'Unable to create temporary file for writing crontab as {ex}') os.chmod(path, S_IRWU_RWG_RWO) fileh = os.fdopen(filed, 'wb') @@ -662,7 +668,10 @@ def main(): # if requested make a backup before making a change if backup and not module.check_mode: - (dummy, backup_file) = tempfile.mkstemp(prefix='crontab') + try: + (dummy, backup_file) = tempfile.mkstemp(prefix='crontab') + except OSError as ex: + module.fail_json(msg=f"Unable to create temporary file for backup: {ex}") crontab.write(backup_file) if env: diff --git a/test/integration/targets/cron/tasks/main.yml b/test/integration/targets/cron/tasks/main.yml index 45640e1e82b..4053935044d 100644 --- a/test/integration/targets/cron/tasks/main.yml +++ b/test/integration/targets/cron/tasks/main.yml @@ -319,3 +319,19 @@ - assert: that: not cron_file_stats.stat.exists + +- name: Add cron job with invalid cron_file path + ansible.builtin.cron: + name: "Bad cron entry" + job: "/usr/bin/true" + minute: "0" + cron_file: "bad/file" + user: root + ignore_errors: yes + register: non_existent_cron_file_job + +- name: Check if we fail due to invalid cron_file path + assert: + that: + - non_existent_cron_file_job.failed + - "'Unable to open' in non_existent_cron_file_job.msg" From fc65ca200fcfcaa2e7288703cf13a59affc7e18d Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 2 Dec 2025 09:35:45 -0800 Subject: [PATCH 2/2] review request Signed-off-by: Abhijeet Kasurde --- lib/ansible/modules/cron.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/cron.py b/lib/ansible/modules/cron.py index 54ee28b502f..aa49a9f0243 100644 --- a/lib/ansible/modules/cron.py +++ b/lib/ansible/modules/cron.py @@ -313,8 +313,8 @@ class CronTab: elif self.cron_file: try: fileh = open(self.b_cron_file, 'wb') - except FileNotFoundError as ex: - self.module.fail_json(msg=f'Unable to open {self.cron_file} for writing as file does not exists') + except (OSError, FileNotFoundError) as ex: + self.module.fail_json(msg=f'Unable to open {self.cron_file} for writing: {to_native(ex)}') else: try: filed, path = tempfile.mkstemp(prefix='crontab') @@ -671,7 +671,7 @@ def main(): try: (dummy, backup_file) = tempfile.mkstemp(prefix='crontab') except OSError as ex: - module.fail_json(msg=f"Unable to create temporary file for backup: {ex}") + module.fail_json(msg=f"Unable to create temporary file for backup: {to_native(ex)}") crontab.write(backup_file) if env: