1
0
Fork 0
mirror of https://github.com/containers/ansible-podman-collections.git synced 2026-02-04 07:11:49 +00:00

Add podman Quadlet modules

This commit introduces two new modules for managing Podman Quadlets:

- podman_quadlet: Install and remove Podman Quadlet files
  * Supports installing single files, directories, and additional config files
  * Implements idempotent state management (present/absent)
  * Validates parameters and provides meaningful error messages
  * Default force=true for removal operations
  * Removed deprecated 'ignore' parameter in favor of built-in idempotency

- podman_quadlet_info: Gather information about installed Quadlets
  * Lists all installed quadlets or prints specific quadlet content
  * Supports filtering by quadlet kinds (container, pod, network, etc.)
  * Provides detailed quadlet metadata including status and paths

Key features:
- Shared utilities in module_utils/podman/quadlet.py for code reuse
- Comprehensive integration tests for both modules
- Full idempotency support for all operations
- Proper handling of edge cases (missing files, malformed quadlets, etc.)
- Check mode support for safe dry-run operations
- Extensive documentation and examples

The modules use relative imports for module_utils to support local
development and testing with the containers.podman collection.

Signed-off-by: Sagi Shnaidman <sshnaidm@redhat.com>
This commit is contained in:
Sagi Shnaidman 2025-11-23 15:07:06 +02:00 committed by Sergey
parent a808c18fbc
commit 09bb5454a9
9 changed files with 2091 additions and 0 deletions

View file

@ -0,0 +1,794 @@
- name: Test podman_quadlet
block:
- name: Discover podman version
shell: podman version | grep "^Version:" | awk {'print $2'}
register: podman_v
- name: Set podman version fact
set_fact:
podman_version: "{{ podman_v.stdout | string }}"
- name: Print podman version
debug: var=podman_v.stdout
- name: Define quadlet user dir
set_fact:
quadlet_user_dir: "{{ ansible_env.HOME }}/.config/containers/systemd"
- name: Create temporary directory for single-file quadlet
ansible.builtin.tempfile:
state: directory
prefix: quadlet_single_
register: quadlet_single_dir
- name: Write a simple container quadlet file
copy:
dest: "{{ quadlet_single_dir.path }}/test-single.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
- name: Install quadlet from a single file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/test-single.container"
reload_systemd: true
register: install_single
- name: Assert install_single changed
assert:
that:
- install_single.changed
- name: Verify quadlet file exists in user dir
stat:
path: "{{ quadlet_user_dir }}/test-single.container"
register: single_stat
- name: Assert quadlet file present
assert:
that:
- single_stat.stat.exists
- name: Reinstall quadlet single file should be idempotent
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/test-single.container"
reload_systemd: false
register: reinstall_single
- name: Assert reinstall_single not changed
assert:
that:
- not reinstall_single.changed
- name: Remove quadlet without suffix (module should resolve)
containers.podman.podman_quadlet:
state: absent
name:
- test-single
register: rm_no_suffix
- name: Assert rm_no_suffix changed
assert:
that:
- rm_no_suffix.changed
- name: Create temporary directory for quadlet application
ansible.builtin.tempfile:
state: directory
prefix: quadlet_app_
register: quadlet_app_dir
- name: Write two quadlet files into application dir
copy:
dest: "{{ item.dest }}"
mode: "0644"
content: "{{ item.content }}"
loop:
- {
dest: "{{ quadlet_app_dir.path }}/app-a.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- {
dest: "{{ quadlet_app_dir.path }}/app-b.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- name: Install quadlet application (directory)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_app_dir.path }}"
register: install_app
- name: Verify both app quadlets installed
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/app-a.container"
- "{{ quadlet_user_dir }}/app-b.container"
register: app_stats
- name: Assert app files present
assert:
that:
- app_stats.results | map(attribute='stat.exists') | list | min
- name: Remove one quadlet from the application (should remove whole app)
containers.podman.podman_quadlet:
state: absent
name:
- app-a.container
register: rm_app_one
- name: Recreate two standalone quadlets and remove by names list
block:
- name: Write two standalone quadlets
copy:
dest: "{{ item.dest }}"
mode: "0644"
content: "{{ item.content }}"
loop:
- {
dest: "{{ quadlet_single_dir.path }}/standalone-a.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- {
dest: "{{ quadlet_single_dir.path }}/standalone-b.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- name: Install two standalone quadlets
containers.podman.podman_quadlet:
state: present
src: "{{ item }}"
loop:
- "{{ quadlet_single_dir.path }}/standalone-a.container"
- "{{ quadlet_single_dir.path }}/standalone-b.container"
- name: Remove both via names list
containers.podman.podman_quadlet:
state: absent
name:
- standalone-a.container
- standalone-b.container
register: rm_both
- name: Assert removal succeeded and return value structure is correct
assert:
that:
- rm_both.changed
- rm_both.quadlets is defined
- rm_both.quadlets | length == 2
- rm_both.quadlets[0].name in ['standalone-a.container', 'standalone-b.container']
- rm_both.quadlets[1].name in ['standalone-a.container', 'standalone-b.container']
- name: Verify both app quadlets are removed
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/app-a.container"
- "{{ quadlet_user_dir }}/app-b.container"
register: app_rm_stats
- name: Assert app files absent
assert:
that:
- (app_rm_stats.results | map(attribute='stat.exists') | list) | select('equalto', true) | list | length == 0
- name: Remove non-existent quadlet (should be idempotent)
containers.podman.podman_quadlet:
state: absent
name:
- does-not-exist.container
register: rm_non_existent
- name: Assert rm_non_existent succeeded but not changed
assert:
that:
- not rm_non_existent.changed
# Edge case and negative tests
- name: Test invalid src parameter (missing file)
containers.podman.podman_quadlet:
state: present
src: /nonexistent/path/file.container
register: invalid_src
ignore_errors: true
- name: Assert invalid src fails appropriately
assert:
that:
- invalid_src is failed
- name: Test absent state without name or all (should fail)
containers.podman.podman_quadlet:
state: absent
register: absent_missing_args
ignore_errors: true
- name: Assert absent missing args fails
assert:
that:
- absent_missing_args is failed
- absent_missing_args.msg is search("must be specified")
- name: Test force parameter
block:
- name: Create a quadlet file for force test
copy:
dest: "{{ quadlet_single_dir.path }}/force-test.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
- name: Install quadlet for force test
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/force-test.container"
register: force_install
- name: Assert install succeeded
assert:
that:
- force_install.changed
- name: Remove quadlet with force=false (testing non-default)
containers.podman.podman_quadlet:
state: absent
name:
- force-test.container
force: false
register: rm_no_force
- name: Assert removal succeeded even without force
assert:
that:
- rm_no_force.changed
- name: Test files parameter (additional files)
block:
- name: Create main quadlet and additional config file
copy:
dest: "{{ item.dest }}"
mode: "0644"
content: "{{ item.content }}"
loop:
- {
dest: "{{ quadlet_single_dir.path }}/app-with-config.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- {
dest: "{{ quadlet_single_dir.path }}/app.conf",
content: "# Configuration file\nkey=value\n",
}
- name: Install quadlet with additional files
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/app-with-config.container"
files:
- "{{ quadlet_single_dir.path }}/app.conf"
register: install_with_files
- name: Assert install with files succeeded
assert:
that:
- install_with_files.changed
- name: Verify both files are installed
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/app-with-config.container"
- "{{ quadlet_user_dir }}/app.conf"
register: files_stats
- name: Assert both files present
assert:
that:
- files_stats.results | map(attribute='stat.exists') | list | min
- name: Remove quadlet with files
containers.podman.podman_quadlet:
state: absent
name:
- app-with-config.container
- name: Test malformed quadlet file handling
block:
- name: Create malformed quadlet file
copy:
dest: "{{ quadlet_single_dir.path }}/malformed.container"
mode: "0644"
content: |
[Container
Image=docker.io/library/alpine:latest
# Missing closing bracket
- name: Try to install malformed quadlet
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/malformed.container"
register: malformed_install
ignore_errors: true
# Note: Podman may accept malformed files, so we don't assert failure
- name: Cleanup malformed quadlet if installed
containers.podman.podman_quadlet:
state: absent
name:
- malformed.container
ignore_errors: true
- name: Test update scenario (content change triggers remove+install)
block:
- name: Create quadlet for update test
copy:
dest: "{{ quadlet_single_dir.path }}/update-test.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 100'
- name: Install quadlet for update test
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/update-test.container"
register: update_install_first
- name: Assert first install changed
assert:
that:
- update_install_first.changed
- name: Modify the quadlet file content
copy:
dest: "{{ quadlet_single_dir.path }}/update-test.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 200'
- name: Reinstall modified quadlet (should trigger update)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/update-test.container"
register: update_install_second
- name: Assert update changed
assert:
that:
- update_install_second.changed
- name: Read installed file content
slurp:
src: "{{ quadlet_user_dir }}/update-test.container"
register: installed_content
- name: Assert installed file has updated content
assert:
that:
- "'sleep 200' in (installed_content.content | b64decode)"
- name: Reinstall same content again (should be idempotent)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/update-test.container"
register: update_install_third
- name: Assert idempotent after update
assert:
that:
- not update_install_third.changed
- name: Cleanup update test quadlet
containers.podman.podman_quadlet:
state: absent
name:
- update-test.container
- name: Test update with files parameter
block:
- name: Create quadlet and config for files update test
copy:
dest: "{{ item.dest }}"
mode: "0644"
content: "{{ item.content }}"
loop:
- {
dest: "{{ quadlet_single_dir.path }}/files-update.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- {
dest: "{{ quadlet_single_dir.path }}/files-update.conf",
content: "# Config v1\nkey=value1\n",
}
- name: Install quadlet with config file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/files-update.container"
files:
- "{{ quadlet_single_dir.path }}/files-update.conf"
register: files_update_first
- name: Assert first install changed
assert:
that:
- files_update_first.changed
- name: Modify the config file only
copy:
dest: "{{ quadlet_single_dir.path }}/files-update.conf"
mode: "0644"
content: |
# Config v2
key=value2
- name: Reinstall with modified config file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/files-update.container"
files:
- "{{ quadlet_single_dir.path }}/files-update.conf"
register: files_update_second
- name: Assert config change triggered update
assert:
that:
- files_update_second.changed
- name: Read installed config file content
slurp:
src: "{{ quadlet_user_dir }}/files-update.conf"
register: installed_conf_content
- name: Assert installed config has updated content
assert:
that:
- "'value2' in (installed_conf_content.content | b64decode)"
- name: Cleanup files update test
containers.podman.podman_quadlet:
state: absent
name:
- files-update.container
- name: Test check mode
block:
- name: Create quadlet for check mode test
copy:
dest: "{{ quadlet_single_dir.path }}/check-mode.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
- name: Install quadlet in check mode
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/check-mode.container"
check_mode: true
register: check_mode_install
- name: Assert check mode shows change but doesn't install
assert:
that:
- check_mode_install.changed
- name: Verify file not actually installed in check mode
stat:
path: "{{ quadlet_user_dir }}/check-mode.container"
register: check_mode_stat
- name: Assert file not present after check mode
assert:
that:
- not check_mode_stat.stat.exists
- name: Remove in check mode (should show change)
containers.podman.podman_quadlet:
state: absent
name:
- check-mode.container
check_mode: true
register: check_mode_remove
- name: Assert check mode remove shows no change (idempotent)
assert:
that:
- not check_mode_remove.changed
- name: Install quadlet for real to test check mode removal
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/check-mode.container"
- name: Remove in check mode (should show change now)
containers.podman.podman_quadlet:
state: absent
name:
- check-mode.container
check_mode: true
register: check_mode_remove_existing
- name: Assert check mode remove existing shows change
assert:
that:
- check_mode_remove_existing.changed
- name: Verify file still exists after check mode remove
stat:
path: "{{ quadlet_user_dir }}/check-mode.container"
register: check_mode_stat_existing
- name: Assert file present
assert:
that:
- check_mode_stat_existing.stat.exists
- name: Test asset removal detection (files removed from install)
block:
- name: Create quadlet and config for asset removal test
copy:
dest: "{{ item.dest }}"
mode: "0644"
content: "{{ item.content }}"
loop:
- {
dest: "{{ quadlet_single_dir.path }}/asset-removal.container",
content: "[Container]\nImage=docker.io/library/alpine:latest\nExec=/bin/sh -c 'sleep 600'\n",
}
- {
dest: "{{ quadlet_single_dir.path }}/asset-removal.conf",
content: "# Asset config\nkey=value\n",
}
- name: Install quadlet with config file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/asset-removal.container"
files:
- "{{ quadlet_single_dir.path }}/asset-removal.conf"
register: asset_removal_first
- name: Assert first install changed
assert:
that:
- asset_removal_first.changed
- name: Verify both files are installed
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/asset-removal.container"
- "{{ quadlet_user_dir }}/asset-removal.conf"
register: asset_files_stats
- name: Assert both files present
assert:
that:
- asset_files_stats.results | map(attribute='stat.exists') | list | min
- name: Reinstall without the config file (should detect asset removal)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/asset-removal.container"
register: asset_removal_second
- name: Assert reinstall detected change due to asset removal
assert:
that:
- asset_removal_second.changed
- name: Verify config file is removed
stat:
path: "{{ quadlet_user_dir }}/asset-removal.conf"
register: asset_conf_stat
- name: Assert config file removed
assert:
that:
- not asset_conf_stat.stat.exists
- name: Cleanup asset removal test
containers.podman.podman_quadlet:
state: absent
name:
- asset-removal.container
ignore_errors: true
- name: Test .quadlets file install (Podman 6.0+)
when: podman_version is version('6.0', '>=')
block:
- name: Create a .quadlets file with multiple sections
copy:
dest: "{{ quadlet_single_dir.path }}/webapp.quadlets"
mode: "0644"
content: |
# FileName=web-server
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
---
# FileName=app-storage
[Volume]
Label=app=webapp
- name: Install .quadlets file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/webapp.quadlets"
register: quadlets_install
- name: Assert .quadlets install changed
assert:
that:
- quadlets_install.changed
- name: Verify generated quadlet files exist
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/web-server.container"
- "{{ quadlet_user_dir }}/app-storage.volume"
register: quadlets_stats
- name: Assert generated files present
assert:
that:
- quadlets_stats.results | map(attribute='stat.exists') | list | min
- name: Reinstall same .quadlets file (should be idempotent)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/webapp.quadlets"
register: quadlets_reinstall
- name: Assert .quadlets reinstall idempotent
assert:
that:
- not quadlets_reinstall.changed
- name: Modify .quadlets file content
copy:
dest: "{{ quadlet_single_dir.path }}/webapp.quadlets"
mode: "0644"
content: |
# FileName=web-server
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 999'
---
# FileName=app-storage
[Volume]
Label=app=webapp
- name: Reinstall modified .quadlets file
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_single_dir.path }}/webapp.quadlets"
register: quadlets_update
- name: Assert .quadlets update detected change
assert:
that:
- quadlets_update.changed
- name: Read installed container file content
slurp:
src: "{{ quadlet_user_dir }}/web-server.container"
register: quadlets_container_content
- name: Assert container file has updated content
assert:
that:
- "'sleep 999' in (quadlets_container_content.content | b64decode)"
- name: Cleanup .quadlets test (remove via app marker)
containers.podman.podman_quadlet:
state: absent
name:
- web-server.container
ignore_errors: true
- name: Skip .quadlets test notice
debug:
msg: "Skipping .quadlets test - requires Podman 6.0+ (current: {{ podman_version }})"
when: podman_version is version('6.0', '<')
- name: Test nested subdirectory validation
block:
- name: Create temporary directory for subdir test
ansible.builtin.tempfile:
state: directory
prefix: quadlet_subdir_
register: quadlet_subdir_test_dir
- name: Create a subdirectory inside the app directory
file:
path: "{{ quadlet_subdir_test_dir.path }}/nested_subdir"
state: directory
- name: Create a quadlet file in the parent directory
copy:
dest: "{{ quadlet_subdir_test_dir.path }}/test.container"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
- name: Create a file in the nested subdirectory
copy:
dest: "{{ quadlet_subdir_test_dir.path }}/nested_subdir/nested.conf"
mode: "0644"
content: "# Nested config\n"
- name: Try to install directory with subdirectory (should fail)
containers.podman.podman_quadlet:
state: present
src: "{{ quadlet_subdir_test_dir.path }}"
register: subdir_install
ignore_errors: true
- name: Assert subdir install fails with expected message
assert:
that:
- subdir_install is failed
- subdir_install.msg is search("nested") or subdir_install.msg is search("subdirector")
always:
# clean the test quadlets
- name: Cleanup installed quadlets
containers.podman.podman_quadlet:
state: absent
name:
- test-single.container
- app-a.container
- app-b.container
- force-test.container
- app-with-config.container
- malformed.container
- check-mode.container
- update-test.container
- files-update.container
- asset-removal.container
- web-server.container
- app-storage.volume
ignore_errors: true
- name: Verify cleanup - files should be removed from filesystem
stat:
path: "{{ item }}"
loop:
- "{{ quadlet_user_dir }}/test-single.container"
- "{{ quadlet_user_dir }}/app-a.container"
- "{{ quadlet_user_dir }}/app-b.container"
- "{{ quadlet_user_dir }}/force-test.container"
- "{{ quadlet_user_dir }}/app-with-config.container"
- "{{ quadlet_user_dir }}/app.conf"
- "{{ quadlet_user_dir }}/update-test.container"
- "{{ quadlet_user_dir }}/files-update.container"
- "{{ quadlet_user_dir }}/files-update.conf"
- "{{ quadlet_user_dir }}/asset-removal.container"
- "{{ quadlet_user_dir }}/asset-removal.conf"
- "{{ quadlet_user_dir }}/web-server.container"
- "{{ quadlet_user_dir }}/app-storage.volume"
register: cleanup_stats
ignore_errors: true
- name: Assert all test files removed from filesystem
assert:
that:
- (cleanup_stats.results | map(attribute='stat.exists') | list) | select('equalto', true) | list | length == 0
quiet: true
ignore_errors: true

View file

@ -0,0 +1,119 @@
- name: Test podman_quadlet_info
block:
- name: Discover podman version
shell: podman version | grep "^Version:" | awk {'print $2'}
register: podman_v
- name: Set podman version fact
set_fact:
podman_version: "{{ podman_v.stdout | string }}"
- name: Print podman version
debug: var=podman_v.stdout
- name: Define quadlet user dir
set_fact:
quadlet_user_dir: "{{ ansible_env.HOME }}/.config/containers/systemd"
- name: Create a temporary file quadlet to inspect
ansible.builtin.tempfile:
state: file
suffix: .container
register: info_quadlet_tmp
- name: Write a quadlet content to temp file
copy:
dest: "{{ info_quadlet_tmp.path }}"
mode: "0644"
content: |
[Container]
Image=docker.io/library/alpine:latest
Exec=/bin/sh -c 'sleep 600'
- name: Install temp quadlet
containers.podman.podman_quadlet:
state: present
src: "{{ info_quadlet_tmp.path }}"
- name: List quadlets
containers.podman.podman_quadlet_info: {}
register: list_info
- name: Assert quadlets list includes our file
assert:
that:
- list_info.quadlets is defined
- name: Print specific quadlet
containers.podman.podman_quadlet_info:
name: "{{ info_quadlet_tmp.path | basename }}"
register: print_info
- name: Assert print contains our section
assert:
that:
- print_info.content is search('\\[Container\\]')
# Test filtering and edge cases
- name: Test kinds filtering (container only)
containers.podman.podman_quadlet_info:
kinds: [container]
register: filtered_info
- name: Assert filtered results are only containers
assert:
that:
- filtered_info.quadlets is defined
# If there are results, all should end with .container
- filtered_info.quadlets | length == 0 or (filtered_info.quadlets | map(attribute='Name') | select('search', '\\.container$') | list | length == filtered_info.quadlets | length)
- name: Test quadlet_dir filtering
containers.podman.podman_quadlet_info:
quadlet_dir: "{{ quadlet_user_dir }}"
register: dir_filtered_info
- name: Assert quadlet_dir filtered results have correct paths
assert:
that:
- dir_filtered_info.quadlets is defined
# If there are results, all paths should be under the specified directory
- dir_filtered_info.quadlets | length == 0 or (dir_filtered_info.quadlets | map(attribute='Path') | select('search', quadlet_user_dir) | list | length == dir_filtered_info.quadlets | length)
- name: Test non-existent quadlet print
containers.podman.podman_quadlet_info:
name: non-existent-quadlet.container
register: nonexistent_print
ignore_errors: true
- name: Assert non-existent print fails appropriately
assert:
that:
- nonexistent_print is failed
- name: Test check mode for info module
containers.podman.podman_quadlet_info: {}
check_mode: true
register: check_mode_info
- name: Assert check mode works for info
assert:
that:
- not check_mode_info.changed
- check_mode_info.quadlets is defined
- name: Test debug mode
containers.podman.podman_quadlet_info:
debug: true
register: debug_info
- name: Assert debug output present
assert:
that:
- debug_info.stdout is defined or debug_info.stderr is defined
always:
# clean the test quadlets
- name: Cleanup installed quadlet
containers.podman.podman_quadlet:
state: absent
name: "{{ info_quadlet_tmp.path | basename }}"