From 16ec7553b71351eabdbd62fdc118f5d374c65bf3 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Wed, 17 Apr 2024 10:12:14 -0600 Subject: [PATCH 1/3] feat: manage TLS cert/key files for registry connections and validate certs Feature: Add two new parameters: podman_registry_certificates is a list of dict. Each dict specifies the certs and keys to use to connect to the specified registry using TLS and optionally use certificate authentication. More information can be found in the manpage for containers-certs.d. podman_validate_certs is a boolean which allows you to require or disable TLS certificate checking (i.e. if you do not have a CA cert for podman_registry_certificates and you still want to pull images from a TLS enabled registry). This corresponds to the parameter "validate_certs" of the module containers.podman.podman_image. You can also control certificate validation by using podman_registries_conf to configure the "insecure" parameter for a registry. Reason: Users need to be able to configure the TLS settings for connecting to registries. Result: Users can connect to registries using TLS and control how that works. QE: tests_auth_and_security.yml has been extended for this. Signed-off-by: Rich Megginson --- README.md | 71 +++++++++++++++++ defaults/main.yml | 11 +++ tasks/create_update_kube_spec.yml | 2 + tasks/create_update_quadlet_spec.yml | 2 + tasks/handle_certs_d.yml | 115 +++++++++++++++++++++++++++ tasks/handle_credential_files.yml | 10 ++- tasks/handle_kube_spec.yml | 3 + tasks/handle_quadlet_spec.yml | 3 + tasks/main.yml | 39 +++++++-- tests/tasks/setup_registry.yml | 19 ++--- tests/tests_auth_and_security.yml | 72 ++++++++++++++++- vars/main.yml | 6 ++ 12 files changed, 329 insertions(+), 24 deletions(-) create mode 100644 tasks/handle_certs_d.yml diff --git a/README.md b/README.md index 383577d4..c2a96236 100644 --- a/README.md +++ b/README.md @@ -458,6 +458,77 @@ owner will be `my_user` and the mode will be `"0600"`. The directories `/home/my_user/.config` and `/home/my_user/.config/containers` will be created if they do not exist. +### podman_registry_certificates + +This variable is a `list` of `dict` elements that allows you to manage TLS +certificates and keys used to connect to registries. The directories, formats, +and files are as described in `man containers-certs.d`. The names of the keys +used for TLS certificates and keys follow the +[system roles TLS naming conventions](https://linux-system-roles.github.io/documentation/tls_crypto_parameter_and_key_names.html). NOTE: the `client_` prefix has been dropped +here for `cert` and `private_key` because there are only clients in this context. + +NOTE: You are strongly encouraged to use Ansible Vault to encrypt private keys and +any other sensitive values. + +The keys of each `dict` are as follows: + +* `state` - default is `present`. Use `absent` to remove files. +* `run_as_user` - This is the user that will be the owner of the files, and is + used to find the `$HOME` directory for the files. If you do not specify this, + then the global default `podman_run_as_user` value will be used. Otherwise, + `root` will be used. +* `run_as_group` - This is the group that will be the owner of the files. If + you do not specify this, then the global default `podman_run_as_group` value + will be used. Otherwise, `root` will be used. +* `registry_host` - Required - the hostname or `hostname:port` of the registry. + This will be used as the name of the directory under + `$HOME/.config/containers/certs.d` (for rootless containers) or + `/etc/containers/certs.d` (for system containers) which will hold the + certificates and keys. If using `state: absent` and all of the files are + removed, the directory will be removed. +* `cert` - name of the file in the `certs.d` directory holding the TLS client + certificate. If not specified, use the basename of `cert_src`. If that isn't + specified, use `client.cert`. +* `private_key` - name of the file in the `certs.d` directory holding the TLS + client private key. If not specified, use the basename of `private_key_src`. + If that isn't specified, use `client.key` +* `ca_cert` - name of the file in the `certs.d` directory holding the TLS CA + certificate. If not specified, use the basename of `ca_cert_src`. If that + isn't specified, use `ca.crt` +* `cert_src` - name of the file on the control node to be copied to `cert`. +* `private_key_src` - name of the file on the control node to be copied to + `private_key`. +* `ca_cert_src` - name of the file on the control node to be copied to + `ca_cert`. +* `cert_content` - contents of the certificate to be copied to `cert`. +* `private_key_content` - contents of the private key to be copied to + `private_key`. + +```yaml +podman_run_as_user: root +podman_registry_certificates: + - registry_host: quay.io:5000 + cert_src: client.cert + private_key_content: !vault | + $ANSIBLE_VAULT..... + ca_cert_src: ca.crt +``` + +This will create the directory `/etc/containers/certs.d/quay.io:5000/`, will copy +the local file `client.cert` looked up from the usual Ansible file lookup path +to `/etc/containers/certs.d/quay.io:5000/client.cert`, will copy the contents of +the Ansible Vault encrypted `private_key_content` to +`/etc/containers/certs.d/quay.io:5000/client.key`, and will copy the local file +`ca.crt` looked up from the usual Ansible file lookup path to +`/etc/containers/certs.d/quay.io:5000/ca.crt`. + +### podman_validate_certs + +Boolean - default is null - use this to control if pulling images from +registries will validate TLS certs or not. The default `null` means to use +whatever is the default used by the `containers.podman.podman_image` module. You +can override this on a per-spec basis using `validate_certs`. + ## Variables Exported by the Role ### podman_version diff --git a/defaults/main.yml b/defaults/main.yml index ded93c21..64d7e7c2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -124,3 +124,14 @@ podman_registry_password: "{{ container_image_password | d('') }}" # For more information, see "man containers-auth.json" and # "man containers-registries.conf" podman_credential_files: [] + +# This variable is a `list` of `dict` elements that allows you to manage TLS +# certificates and keys used to connect to registries +podman_registry_certificates: [] + +# Can set to true or false to control if pulling images from +# registries will validate the TLS certs. +# The default null means to use whatever is the default used +# by the containers.podman.podman_image module +# You can override this on a per-spec basis using validate_certs +podman_validate_certs: null diff --git a/tasks/create_update_kube_spec.yml b/tasks/create_update_kube_spec.yml index ac6d4c14..173192d4 100644 --- a/tasks/create_update_kube_spec.yml +++ b/tasks/create_update_kube_spec.yml @@ -44,6 +44,8 @@ if __podman_registry_username | length > 0 else omit }}" password: "{{ __podman_registry_password if __podman_registry_password | length > 0 else omit }}" + validate_certs: "{{ (__podman_validate_certs in ['', none]) | + ternary(omit, __podman_validate_certs) }}" register: __podman_image_updated when: __podman_pull_image | bool until: __podman_image_updated is success diff --git a/tasks/create_update_quadlet_spec.yml b/tasks/create_update_quadlet_spec.yml index 517824e3..468c18a6 100644 --- a/tasks/create_update_quadlet_spec.yml +++ b/tasks/create_update_quadlet_spec.yml @@ -28,6 +28,8 @@ if __podman_registry_username | length > 0 else omit }}" password: "{{ __podman_registry_password if __podman_registry_password | length > 0 else omit }}" + validate_certs: "{{ (__podman_validate_certs in ['', none]) | + ternary(omit, __podman_validate_certs) }}" register: __podman_image_updated when: __podman_pull_image | bool until: __podman_image_updated is success diff --git a/tasks/handle_certs_d.yml b/tasks/handle_certs_d.yml new file mode 100644 index 00000000..ce5f87b5 --- /dev/null +++ b/tasks/handle_certs_d.yml @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: MIT +--- +- name: Check given registry_host + fail: + msg: >- + The given registry host {{ __podman_cert_spec_item['registry_host'] }} + is invalid - cannot be used as the directory name + when: __podman_cert_spec_item["registry_host"] is search("/") + +- name: Set per-cert spec variables part 0 + set_fact: + __podman_user: "{{ __podman_cert_spec_item['run_as_user'] | + d(podman_run_as_user) }}" + +- name: Set per-cert spec variables part 1 + set_fact: + __podman_rootless: "{{ __podman_user != 'root' }}" + +- name: Check user and group information + include_tasks: handle_user_group.yml + vars: + __podman_spec_item: "{{ __podman_cert_spec_item }}" + +- name: Set per-cert spec variables part 2 + set_fact: + __podman_user_home_dir: "{{ + ansible_facts['getent_passwd'][__podman_user][4] }}" + +- name: Set per-cert spec variables part 3 + set_fact: + __podman_certs_d_path: "{{ (__podman_user_home_dir ~ + __podman_user_certs_d_path + if __podman_rootless else __podman_system_certs_d_path) ~ + '/' ~ __podman_cert_spec_item['registry_host'] }}" + +- name: Set per-cert spec variables part 4 + set_fact: + __podman_cert_file_list: + - dest: "{{ __podman_certs_d_path ~ '/' ~ + (__podman_cert_spec_item['cert'] | basename + if 'cert' in __podman_cert_spec_item + else __podman_cert_spec_item['cert_src'] | basename + if 'cert_src' in __podman_cert_spec_item + else 'client.cert') }}" + content: "{{ __podman_cert_spec_item['cert_content'] | d('') }}" + src: "{{ __podman_cert_spec_item['cert_src'] | d('') }}" + - dest: "{{ __podman_certs_d_path ~ '/' ~ + (__podman_cert_spec_item['key'] | basename + if 'key' in __podman_cert_spec_item + else __podman_cert_spec_item['key_src'] | basename + if 'key_src' in __podman_cert_spec_item + else 'client.key') }}" + content: "{{ __podman_cert_spec_item['key_content'] | d('') }}" + src: "{{ __podman_cert_spec_item['key_src'] | d('') }}" + - dest: "{{ __podman_certs_d_path ~ '/' ~ + (__podman_cert_spec_item['ca_cert'] | basename + if 'ca_cert' in __podman_cert_spec_item + else __podman_cert_spec_item['ca_cert_src'] | basename + if 'ca_cert_src' in __podman_cert_spec_item + else 'ca.crt') }}" + content: "{{ __podman_cert_spec_item['ca_cert_content'] | d('') }}" + src: "{{ __podman_cert_spec_item['ca_cert_src'] | d('') }}" + no_log: true + +- name: Create TLS files + when: + - __podman_cert_spec_item["state"] | d("present") == "present" + - __podman_handle_state == "present" + block: + - name: Ensure certs.d directory + file: + path: "{{ __podman_certs_d_path }}" + state: directory + owner: "{{ __podman_user }}" + group: "{{ __podman_group }}" + mode: "0700" + + - name: Ensure certs.d files + copy: + content: "{{ item.content if item.content | length > 0 else omit }}" + src: "{{ item.src if item.src | length > 0 else omit }}" + dest: "{{ item.dest }}" + owner: "{{ __podman_user }}" + group: "{{ __podman_group }}" + mode: "0600" + when: (item.content | length > 0) or (item.src | length > 0) + loop: "{{ __podman_cert_file_list }}" + no_log: true + +- name: Remove TLS files + when: + - __podman_cert_spec_item["state"] | d("present") == "absent" + - __podman_handle_state == "absent" + block: + - name: Remove certs.d files + file: + path: "{{ item.dest }}" + state: absent + loop: "{{ __podman_cert_file_list }}" + no_log: true + + - name: Find files in certs.d directory + find: + path: "{{ __podman_certs_d_path }}" + file_type: any + hidden: true + register: __certs_d_dir_files + no_log: true + + - name: Ensure the certs.d directory is absent if empty + file: + path: "{{ __podman_certs_d_path }}" + state: absent + when: __certs_d_dir_files.matched == 0 + no_log: true diff --git a/tasks/handle_credential_files.yml b/tasks/handle_credential_files.yml index 6b4e1a0c..44cbae87 100644 --- a/tasks/handle_credential_files.yml +++ b/tasks/handle_credential_files.yml @@ -31,8 +31,6 @@ else __podman_credential_item['file'] }}" __podman_credential_mode: "{{ __podman_credential_item['mode'] if 'mode' in __podman_credential_item else '0600' }}" - __podman_credential_state: "{{ __podman_credential_item['state'] - if 'state' in __podman_credential_item else 'present' }}" vars: __authdir: "{{ ansible_facts['getent_passwd'][__podman_credential_user][4] ~ @@ -40,7 +38,9 @@ no_log: true - name: Handle state present - when: __podman_credential_state == "present" + when: + - __podman_credential_item["state"] | d("present") == "present" + - __podman_handle_state == "present" block: - name: Ensure the credentials directory is present file: @@ -73,7 +73,9 @@ no_log: true - name: Handle state absent - when: __podman_credential_state == "absent" + when: + - __podman_credential_item["state"] | d("present") == "absent" + - __podman_handle_state == "absent" block: - name: Ensure credential file is absent file: diff --git a/tasks/handle_kube_spec.yml b/tasks/handle_kube_spec.yml index e5f208c1..0490a630 100644 --- a/tasks/handle_kube_spec.yml +++ b/tasks/handle_kube_spec.yml @@ -115,6 +115,9 @@ __podman_kube_spec_item['registry_password'] if 'registry_password' in __podman_kube_spec_item else podman_registry_password }}" + __podman_validate_certs: "{{ __podman_kube_spec_item['validate_certs'] + if 'validate_certs' in __podman_kube_spec_item + else podman_validate_certs }}" no_log: true - name: Get service name using systemd-escape diff --git a/tasks/handle_quadlet_spec.yml b/tasks/handle_quadlet_spec.yml index 6c75362b..23f44223 100644 --- a/tasks/handle_quadlet_spec.yml +++ b/tasks/handle_quadlet_spec.yml @@ -212,6 +212,9 @@ __podman_quadlet_spec_item['registry_password'] if 'registry_password' in __podman_quadlet_spec_item else podman_registry_password }}" + __podman_validate_certs: "{{ __podman_quadlet_spec_item['validate_certs'] + if 'validate_certs' in __podman_quadlet_spec_item + else podman_validate_certs }}" no_log: true - name: Cleanup quadlets diff --git a/tasks/main.yml b/tasks/main.yml index 4ab96b69..98691559 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -111,20 +111,31 @@ set_fact: __podman_cancel_user_linger: [] -- name: Handle secrets - include_tasks: handle_secret.yml - loop: "{{ podman_secrets }}" +- name: Handle certs.d files - present + include_tasks: handle_certs_d.yml + vars: + __podman_handle_state: present + loop: "{{ podman_registry_certificates }}" loop_control: - loop_var: __podman_secret_item + loop_var: __podman_cert_spec_item no_log: true -- name: Handle credential files +- name: Handle credential files - present include_tasks: handle_credential_files.yml + vars: + __podman_handle_state: present loop: "{{ podman_credential_files }}" loop_control: loop_var: __podman_credential_item no_log: true +- name: Handle secrets + include_tasks: handle_secret.yml + loop: "{{ podman_secrets }}" + loop_control: + loop_var: __podman_secret_item + no_log: true + - name: Handle Kubernetes specifications include_tasks: handle_kube_spec.yml loop: "{{ podman_kube_specs }}" @@ -144,3 +155,21 @@ loop: "{{ __podman_cancel_user_linger }}" loop_control: loop_var: __podman_linger_user + +- name: Handle credential files - absent + include_tasks: handle_credential_files.yml + vars: + __podman_handle_state: absent + loop: "{{ podman_credential_files }}" + loop_control: + loop_var: __podman_credential_item + no_log: true + +- name: Handle certs.d files - absent + include_tasks: handle_certs_d.yml + vars: + __podman_handle_state: absent + loop: "{{ podman_registry_certificates }}" + loop_control: + loop_var: __podman_cert_spec_item + no_log: true diff --git a/tests/tasks/setup_registry.yml b/tests/tasks/setup_registry.yml index 9b0a3b08..b5c2127a 100644 --- a/tests/tasks/setup_registry.yml +++ b/tests/tasks/setup_registry.yml @@ -12,7 +12,8 @@ - name: Set authdir set_fact: __podman_registry_authdir: "{{ __podman_registry_tempfile.path ~ '/auth' }}" - __podman_test_authfile: "{{ __podman_registry_tempfile.path ~ '/auth/auth.json' }}" + __podman_test_authfile: "{{ + __podman_registry_tempfile.path ~ '/auth/auth.json' }}" - name: Create authdir file: @@ -43,17 +44,12 @@ dest: "{{ __podman_registry_authdir ~ '/registry_key.pem' }}" mode: "0600" -- name: Create cert dir for registry - file: - path: /etc/containers/certs.d/localhost:5000 - state: directory - mode: "0755" - - name: Write CA cert for registry copy: - content: "{{ certificate_test_certs['podman_registry']['ca_content'] }}" - dest: /etc/containers/certs.d/localhost:5000/ca.crt - mode: "0644" + content: "{{ + certificate_test_certs['podman_registry']['ca_content'] }}" + dest: "{{ __podman_registry_authdir ~ '/ca.crt' }}" + mode: "0600" - name: Ensure test packages package: @@ -88,7 +84,6 @@ - name: Set paths for cleanup set_fact: __podman_cleanup_paths: - - /etc/containers/certs.d/localhost:5000 - "{{ __podman_registry_tempfile.path }}" # # In case $PODMAN_TEST_KEEP_LOGIN_REGISTRY is set, for testing later @@ -124,6 +119,7 @@ shell: >- podman pull {{ item.key }}; podman push --authfile="{{ __podman_test_authfile }}" + --cert-dir="{{ __podman_registry_authdir }}" {{ item.key }} docker://{{ item.value }} loop: "{{ dict(__podman_test_images | zip(podman_local_test_images)) | @@ -133,6 +129,7 @@ - name: Verify test images in local registry command: >- skopeo inspect --authfile="{{ __podman_test_authfile }}" + --cert-dir="{{ __podman_registry_authdir }}" docker://{{ item }} changed_when: false loop: "{{ podman_local_test_images }}" diff --git a/tests/tests_auth_and_security.yml b/tests/tests_auth_and_security.yml index 42c563ac..6805d4e6 100644 --- a/tests/tests_auth_and_security.yml +++ b/tests/tests_auth_and_security.yml @@ -8,6 +8,7 @@ __podman_test_username: podman_username local_test_image: "{{ podman_local_test_images[0] }}" podman_quadlet_spec_base: + name: auth_test_1_quadlet type: container state: created activate_systemd_unit: false @@ -48,12 +49,13 @@ __podman_test_images: - "{{ test_image }}" - - name: Run the role with no credentials, should fail + - name: Run the role with no credentials and no cert checking block: - - name: Run the role with no credentials + - name: Run the role with no credentials and no cert checking include_role: name: linux-system-roles.podman vars: + podman_validate_certs: false podman_quadlet_specs: - "{{ podman_quadlet_spec_base }}" podman_kube_specs: @@ -73,6 +75,32 @@ vars: expected_msg: Failed to pull image + - name: Run the role with credentials and cert checking + block: + - name: Run the role with credentials and cert checking + include_role: + name: linux-system-roles.podman + vars: + podman_validate_certs: true + podman_quadlet_specs: + - "{{ podman_quadlet_spec_creds }}" + podman_kube_specs: + - "{{ podman_kube_spec_creds }}" + + - name: Should not get here + fail: + msg: UNREACHABLE + + rescue: + - name: Check error + fail: + msg: >- + Role did not fail with the expected message {{ expected_msg }} but + instead failed with {{ ansible_failed_result | to_nice_json }} + when: not expected_msg in ansible_failed_result.results[0].msg | d("") + vars: + expected_msg: Failed to pull image + - name: Run remaining tasks in block with cleanup block: - name: Create a local tmpdir @@ -83,7 +111,7 @@ register: __local_tmpdir delegate_to: localhost - - name: Run the role with credentials in spec + - name: Run the role with credentials in spec and CA cert include_role: name: linux-system-roles.podman vars: @@ -93,6 +121,10 @@ - "{{ podman_quadlet_spec_creds }}" podman_kube_specs: - "{{ podman_kube_spec_creds }}" + podman_registry_certificates: + - registry_host: localhost:5000 + ca_cert_content: "{{ + certificate_test_certs['podman_registry']['ca_content'] }}" - name: Run the role with credentials in global vars include_role: @@ -123,6 +155,20 @@ podman_kube_specs: - "{{ podman_kube_spec_base }}" + - name: Remove all container resources - root + include_role: + name: linux-system-roles.podman + vars: + podman_kube_specs: + - "{{ podman_kube_spec_base | combine({'state': 'absent'}) }}" + podman_quadlet_specs: + - "{{ podman_quadlet_spec_base | combine({'state': 'absent'}) }}" + podman_credential_files: + - state: absent + podman_registry_certificates: + - registry_host: localhost:5000 + state: absent + - name: Create a user for rootless user: name: auth_test_user1 @@ -141,8 +187,20 @@ - "{{ podman_quadlet_spec_base | combine(__run_as_user) }}" podman_kube_specs: - "{{ podman_kube_spec_base | combine(__run_as_user) }}" + podman_registry_certificates: + - registry_host: localhost:5000 + run_as_user: auth_test_user1 + ca_cert_content: "{{ + certificate_test_certs['podman_registry']['ca_content'] }}" + + rescue: + - name: Dump journal + command: journalctl -ex + changed_when: false + failed_when: true always: + # in case the test errored before this happened - name: Remove all container resources - root include_role: name: linux-system-roles.podman @@ -153,8 +211,11 @@ - "{{ podman_quadlet_spec_base | combine({'state': 'absent'}) }}" podman_credential_files: - state: absent + podman_registry_certificates: + - registry_host: localhost:5000 + state: absent - - name: Remove pods and units - rootless + - name: Remove all container resources - rootless include_role: name: linux-system-roles.podman vars: @@ -165,6 +226,9 @@ - "{{ podman_quadlet_spec_base | combine({'state': 'absent'}) }}" podman_credential_files: - state: absent + podman_registry_certificates: + - registry_host: localhost:5000 + state: absent - name: Remove user user: diff --git a/vars/main.yml b/vars/main.yml index 38402ff3..bdc1135b 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -76,3 +76,9 @@ __podman_system_quadlet_path: "/etc/containers/systemd" # location for user quadlet files __podman_user_quadlet_path: "/.config/containers/systemd" + +# location for user certs_d +__podman_user_certs_d_path: "/.config/containers/certs.d" + +# location for system certs_d +__podman_system_certs_d_path: "/etc/containers/certs.d" From ccb62dc1fbb42762fb1ea43b61965a375567c167 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Fri, 19 Apr 2024 07:33:41 -0600 Subject: [PATCH 2/3] uid 1001 conflicts on some test systems --- tests/tests_basic.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/tests_basic.yml b/tests/tests_basic.yml index b8ddc500..c91cc5f7 100644 --- a/tests/tests_basic.yml +++ b/tests/tests_basic.yml @@ -8,14 +8,14 @@ podman_host_directories: "{{ __test_tmpdir.path ~ '/httpd1-create' }}": mode: "0777" - owner: "{{ 1001 + + owner: "{{ 3001 + podman_subuid_info[__podman_test_username]['start'] - 1 }}" - group: "{{ 1001 + + group: "{{ 3001 + podman_subgid_info[__podman_test_username]['start'] - 1 }}" podman_run_as_user: root __podman_test_username: podman_basic_user test_names_users: - - [httpd1, "{{ __podman_test_username }}", 1001] + - [httpd1, "{{ __podman_test_username }}", 3001] - [httpd2, root, 0] - [httpd3, root, 0] podman_create_host_directories: true @@ -172,7 +172,7 @@ - name: Create user user: name: "{{ __podman_test_username }}" - uid: 1001 + uid: 3001 - name: Create tempfile for kube_src tempfile: From 8dc17cba8081960e75e42de115265c9840b7d118 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Fri, 19 Apr 2024 09:11:03 -0600 Subject: [PATCH 3/3] catch errors during cleanup --- tests/tests_auth_and_security.yml | 105 +++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 32 deletions(-) diff --git a/tests/tests_auth_and_security.yml b/tests/tests_auth_and_security.yml index 6805d4e6..ca1fccf8 100644 --- a/tests/tests_auth_and_security.yml +++ b/tests/tests_auth_and_security.yml @@ -200,40 +200,74 @@ failed_when: true always: - # in case the test errored before this happened - - name: Remove all container resources - root - include_role: - name: linux-system-roles.podman - vars: - podman_kube_specs: - - "{{ podman_kube_spec_base | combine({'state': 'absent'}) }}" - podman_quadlet_specs: - - "{{ podman_quadlet_spec_base | combine({'state': 'absent'}) }}" - podman_credential_files: - - state: absent - podman_registry_certificates: - - registry_host: localhost:5000 + - name: Cleanup root resources + block: + # in case the test errored before this happened + - name: Remove all container resources - root + include_role: + name: linux-system-roles.podman + vars: + podman_kube_specs: + - "{{ podman_kube_spec_base | combine({'state': 'absent'}) }}" + podman_quadlet_specs: + - "{{ podman_quadlet_spec_base | + combine({'state': 'absent'}) }}" + podman_credential_files: + - state: absent + podman_registry_certificates: + - registry_host: localhost:5000 + state: absent + rescue: + - name: Check journal for root cleanup errors + command: journalctl -ex + changed_when: false + + - name: Cleanup rootless resources + block: + - name: Remove all container resources - rootless + include_role: + name: linux-system-roles.podman + vars: + podman_run_as_user: auth_test_user1 + podman_kube_specs: + - "{{ podman_kube_spec_base | combine({'state': 'absent'}) }}" + podman_quadlet_specs: + - "{{ podman_quadlet_spec_base | + combine({'state': 'absent'}) }}" + podman_credential_files: + - state: absent + podman_registry_certificates: + - registry_host: localhost:5000 + state: absent + rescue: + - name: Check journal for rootless cleanup errors + command: journalctl -ex + changed_when: false + + - name: Remove test user resources + block: + - name: Remove user + user: + name: auth_test_user1 state: absent - - name: Remove all container resources - rootless - include_role: - name: linux-system-roles.podman - vars: - podman_run_as_user: auth_test_user1 - podman_kube_specs: - - "{{ podman_kube_spec_base | combine({'state': 'absent'}) }}" - podman_quadlet_specs: - - "{{ podman_quadlet_spec_base | combine({'state': 'absent'}) }}" - podman_credential_files: - - state: absent - podman_registry_certificates: - - registry_host: localhost:5000 + - name: Remove homedir + file: + path: /home/auth_test_user1 state: absent + rescue: + # this usually fails when the user is still running some process + - name: See if any process is held by the user + shell: | + set -euxo pipefail + exec 1>&2 + ps -ef | grep auth_test_user1 || : + ps -ef | grep 2001 || : + changed_when: false - - name: Remove user - user: - name: auth_test_user1 - state: absent + - name: Check journal for user removal errors + command: journalctl -ex + changed_when: false - name: Remove local tmpdir file: @@ -241,5 +275,12 @@ state: absent delegate_to: localhost - - name: Clean up registry - include_tasks: tasks/cleanup_registry.yml + - name: Clean up registry and other test resources + block: + - name: Clean up registry + include_tasks: tasks/cleanup_registry.yml + rescue: + - name: Check journal for registry cleanup errors + command: journalctl -ex + changed_when: false + failed_when: true