From 7b1644e0b3f69cd91c4c973d2e4ce12a8c29c764 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 2 Sep 2025 08:11:30 -0700 Subject: [PATCH] dnf: Check if installroot is directory or not (#85748) * dnf: Check if installroot is directory or not * dnf library creates installroot if it is missing. check if installroot is directory or not. Fixes: #85680 Signed-off-by: Abhijeet Kasurde --- changelogs/fragments/dnf_installroot_dir.yml | 3 ++ lib/ansible/modules/dnf.py | 3 ++ lib/ansible/modules/dnf5.py | 4 +++ .../targets/dnf/tasks/dnfinstallroot.yml | 30 +++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 changelogs/fragments/dnf_installroot_dir.yml diff --git a/changelogs/fragments/dnf_installroot_dir.yml b/changelogs/fragments/dnf_installroot_dir.yml new file mode 100644 index 00000000000..dcb9bb2acdf --- /dev/null +++ b/changelogs/fragments/dnf_installroot_dir.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - dnf - Check if installroot is directory or not (https://github.com/ansible/ansible/issues/85680). diff --git a/lib/ansible/modules/dnf.py b/lib/ansible/modules/dnf.py index 9d14a90dc15..3c07ffd52af 100644 --- a/lib/ansible/modules/dnf.py +++ b/lib/ansible/modules/dnf.py @@ -537,6 +537,9 @@ class DnfModule(YumDnf): conf.sslverify = sslverify # Set installroot + if not os.path.isdir(installroot): + self.module.fail_json(msg=f"Installroot {installroot} must be a directory") + conf.installroot = installroot # Load substitutions from the filesystem diff --git a/lib/ansible/modules/dnf5.py b/lib/ansible/modules/dnf5.py index dc2d0eb5e13..b469c975882 100644 --- a/lib/ansible/modules/dnf5.py +++ b/lib/ansible/modules/dnf5.py @@ -595,6 +595,10 @@ class Dnf5Module(YumDnf): conf.localpkg_gpgcheck = not self.disable_gpg_check conf.sslverify = self.sslverify conf.clean_requirements_on_remove = self.autoremove + + if not os.path.isdir(self.installroot): + self.module.fail_json(msg=f"Installroot {self.installroot} must be a directory") + conf.installroot = self.installroot conf.use_host_config = True # needed for installroot conf.cacheonly = "all" if self.cacheonly else "none" diff --git a/test/integration/targets/dnf/tasks/dnfinstallroot.yml b/test/integration/targets/dnf/tasks/dnfinstallroot.yml index 19f67069096..7ec646b0fea 100644 --- a/test/integration/targets/dnf/tasks/dnfinstallroot.yml +++ b/test/integration/targets/dnf/tasks/dnfinstallroot.yml @@ -33,3 +33,33 @@ file: path: "/{{ dnfroot.stdout }}/" state: absent + +- block: + - name: Clean setup + file: + path: "{{ remote_tmp_dir }}/file_root" + state: absent + + - name: Setup - create invalid installroot file (not a dir) + copy: + content: '' + dest: "{{ remote_tmp_dir }}/file_root" + + - name: Try with invalid installroot + dnf: + name: bash + state: present + installroot: "{{ remote_tmp_dir }}/file_root" + ignore_errors: yes + register: invalid_install_root + + - name: Check if invalid installroot failed + assert: + that: + - invalid_install_root.failed + - "'Installroot ' ~ remote_tmp_dir ~ '/file_root must be a directory' in invalid_install_root.msg" + always: + - name: Cleanup invalid installroot + file: + path: "{{ remote_tmp_dir }}/file_root" + state: absent