Skip to content

Commit

Permalink
fix: ensure user linger is enabled and disabled correctly
Browse files Browse the repository at this point in the history
Cause: The role was not always enabling user lingering before
creating resources, and not always canceling lingering after
removing resources.

Consequence: The role would give errors if attempting to create
a secret or other resource requiring lingering, or would leave
lingering enabled after removing resources.

Fix: Centralize linger handling and keep track of users which
may need linger canceling.  Ensure linger is canceled for all
users if all of that user's resources are removed and linger is
no longer needed.

Result: Resources for rootless users are always created properly.
Lingering is always canceled when no longer needed.

Fix issue with toml.j2 - ensure non-string values are written
as non-strings.

Fix idempotency issue where you could not clean up twice.

Allow testing rootless quadlet on EL8 by configuring settings
and kernel parameters and rebooting.

Signed-off-by: Rich Megginson <[email protected]>
  • Loading branch information
richm committed Feb 6, 2024
1 parent 852c0a4 commit 19a64bc
Show file tree
Hide file tree
Showing 14 changed files with 585 additions and 373 deletions.
62 changes: 62 additions & 0 deletions tasks/cancel_linger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
# Input:
# * __podman_linger_user - username
- name: Get user information
getent:
database: passwd
key: "{{ __podman_linger_user }}"
fail_key: true
when: "'getent_passwd' not in ansible_facts or
__podman_linger_user not in ansible_facts['getent_passwd']"

- name: Set cancel linger vars
set_fact:
__podman_xdg_runtime_dir: >-
/run/user/{{ ansible_facts["getent_passwd"][__podman_linger_user][1] }}
- name: Stat XDG_RUNTIME_DIR
stat:
path: "{{ __podman_xdg_runtime_dir }}"
register: __podman_xdg_stat

- name: Gather facts for containers
containers.podman.podman_container_info:
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: true
become_user: "{{ __podman_linger_user }}"
when: __podman_xdg_stat.stat.exists
register: __podman_container_info

- name: Gather facts for networks
command: podman network ls -q
register: __podman_networks
changed_when: false
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: true
become_user: "{{ __podman_linger_user }}"
when: __podman_xdg_stat.stat.exists

- name: Gather secrets
command: podman secret ls -n -q
register: __podman_linger_secrets
changed_when: false
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: true
become_user: "{{ __podman_linger_user }}"
when: __podman_xdg_stat.stat.exists

- name: Cancel linger if no more resources are in use
command: loginctl disable-linger {{ __podman_linger_user }}
when:
- __podman_xdg_stat.stat.exists
- __podman_container_info.containers | length == 0
- __podman_networks.stdout_lines | reject("match", "^podman$") |
reject("match", "^podman-default-kube-network$") |
list | length == 0
- __podman_linger_secrets.stdout == ""
changed_when: true
args:
removes: /var/lib/systemd/linger/{{ __podman_user }}
28 changes: 14 additions & 14 deletions tasks/cleanup_kube_spec.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
---
- name: Stat XDG_RUNTIME_DIR
stat:
path: "{{ __podman_xdg_runtime_dir }}"
register: __podman_xdg_stat
when:
- __podman_rootless | bool
- __podman_xdg_runtime_dir | d("") | length > 0

- name: Stop and disable service
systemd:
name: "{{ __podman_service_name.stdout }}"
Expand All @@ -10,6 +18,7 @@
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
register: __podman_service_status
when: not __podman_rootless or __podman_xdg_stat.stat.exists
failed_when:
- __podman_service_status is failed
- not __podman_service_status.stdout is search(__service_error)
Expand All @@ -24,6 +33,7 @@
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
register: __podman_removed
when: not __podman_rootless or __podman_xdg_stat.stat.exists

- name: Remove kubernetes yaml file
file:
Expand All @@ -39,17 +49,7 @@
when: __podman_removed is changed # noqa no-handler
changed_when: true

- name: Gather facts for all containers
containers.podman.podman_container_info:
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
register: __podman_container_info

- name: Cancel linger if no more containers are running
command: loginctl disable-linger {{ __podman_user }}
when:
- __podman_rootless | bool
- __podman_container_info.containers | length == 0
changed_when: true
- name: Manage linger
include_tasks: manage_linger.yml
vars:
__podman_item_state: absent
44 changes: 16 additions & 28 deletions tasks/cleanup_quadlet_spec.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
---
# NOTE: Stopping, disabling, and removing units should also stop
# and remove any pods and containers as well.
- name: Stat XDG_RUNTIME_DIR
stat:
path: "{{ __podman_xdg_runtime_dir }}"
register: __podman_xdg_stat
when:
- __podman_rootless | bool
- __podman_xdg_runtime_dir | d("") | length > 0

- name: Stop and disable service
systemd:
name: "{{ __podman_service_name }}"
Expand All @@ -12,7 +20,9 @@
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
register: __podman_service_status
when: __podman_service_name | length > 0
when:
- __podman_service_name | length > 0
- not __podman_rootless or __podman_xdg_stat.stat.exists
failed_when:
- __podman_service_status is failed
- not __podman_service_status.msg is search(__service_error)
Expand All @@ -25,6 +35,11 @@
state: absent
register: __podman_file_removed

- name: Manage linger
include_tasks: manage_linger.yml
vars:
__podman_item_state: absent

- name: Cleanup container resources
when: __podman_file_removed is changed # noqa no-handler
block:
Expand Down Expand Up @@ -53,30 +68,3 @@
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"

- name: Gather facts for all containers
containers.podman.podman_container_info:
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
register: __podman_container_info
no_log: true

- name: Gather facts for networks
command: podman network ls -q
register: __podman_networks
changed_when: false
environment:
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"

- name: Cancel linger if no more resources are in use
command: loginctl disable-linger {{ __podman_user }}
when:
- __podman_rootless | bool
- __podman_container_info.containers | length == 0
- __podman_networks.stdout_lines | reject('match', '^podman$') |
list | length == 0
changed_when: true
9 changes: 4 additions & 5 deletions tasks/create_update_kube_spec.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
---
- name: Enable lingering if needed
command: loginctl enable-linger {{ __podman_user }}
when: __podman_rootless | bool
args:
creates: /var/lib/systemd/linger/{{ __podman_user }}
- name: Manage linger
include_tasks: manage_linger.yml
vars:
__podman_item_state: present

- name: Get the host mount volumes
set_fact:
Expand Down
9 changes: 4 additions & 5 deletions tasks/create_update_quadlet_spec.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
---
- name: Enable lingering if needed
command: loginctl enable-linger {{ __podman_user }}
when: __podman_rootless | bool
args:
creates: /var/lib/systemd/linger/{{ __podman_user }}
- name: Manage linger
include_tasks: manage_linger.yml
vars:
__podman_item_state: present

- name: Create host directories
file: "{{ __defaults | combine(podman_host_directories[__hostitem])
Expand Down
17 changes: 17 additions & 0 deletions tasks/handle_secret.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@
__podman_xdg_runtime_dir: >-
/run/user/{{ ansible_facts["getent_passwd"][__podman_user][1] }}
- name: Manage linger
include_tasks: manage_linger.yml
vars:
__podman_item_state: "{{ __podman_secret.state | d('present') }}"

- name: Stat XDG_RUNTIME_DIR
stat:
path: "{{ __podman_xdg_runtime_dir }}"
register: __podman_xdg_stat
when:
- __podman_rootless | bool
- __podman_xdg_runtime_dir | d("") | length > 0

# if XDG_RUNTIME_DIR does not exist, this means linger
# was already canceled, which means the user is attempting
# to remove more than once
- name: Manage each secret
containers.podman.podman_secret:
data: "{{ __podman_secret.data | string
Expand All @@ -35,4 +51,5 @@
XDG_RUNTIME_DIR: "{{ __podman_xdg_runtime_dir }}"
become: "{{ __podman_rootless | ternary(true, omit) }}"
become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
when: not __podman_rootless or __podman_xdg_stat.stat.exists
no_log: true
10 changes: 10 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
selinux_ports: "{{ podman_selinux_ports }}"
when: podman_selinux_ports | length > 0

- name: Keep track of users that need to cancel linger
set_fact:
__podman_cancel_user_linger: []

- name: Handle secrets
include_tasks: handle_secret.yml
loop: "{{ podman_secrets }}"
Expand All @@ -124,3 +128,9 @@
loop: "{{ podman_quadlet_specs }}"
loop_control:
loop_var: __podman_quadlet_spec_item

- name: Cancel linger
include_tasks: cancel_linger.yml
loop: "{{ __podman_cancel_user_linger }}"
loop_control:
loop_var: __podman_linger_user
27 changes: 27 additions & 0 deletions tasks/manage_linger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
# Input:
# * __podman_rootless - true or false
# * __podman_user - name of user
# * __podman_item_state - present or absent
# Globals: __podman_cancel_user_linger
- name: Enable linger if needed
when:
- __podman_rootless | bool
- __podman_item_state | d('present') != 'absent'
block:
- name: Enable linger if needed
command: loginctl enable-linger {{ __podman_user }}
when: __podman_rootless | bool
args:
creates: /var/lib/systemd/linger/{{ __podman_user }}

- name: Mark user as not yet needing to cancel linger
set_fact:
__podman_cancel_user_linger: "{{ __podman_cancel_user_linger | difference([__podman_user]) }}"

- name: Mark user for possible linger cancel
set_fact:
__podman_cancel_user_linger: "{{ __podman_cancel_user_linger | union([__podman_user]) }}"
when:
- __podman_rootless | bool
- __podman_item_state | d('present') == 'absent'
2 changes: 2 additions & 0 deletions templates/toml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
{{ key }}={{ value }}
{% elif value is mapping and value is not string %}
{{ key }} = [{%- for k in value %} "{{k}}={{value[k]}}", {%- endfor %}]
{% elif value is not string %}
{{ key }} = {{ value }}
{% else %}
{{ key }}="{{ value }}"
{% endif %}
Expand Down
10 changes: 9 additions & 1 deletion tests/tests_basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@
spec:
containers:
- name: bogus
image: this_is_a_bogus_image
image: >-
quay.io/linux-system-roles/this_is_a_bogus_image:latest
rescue:
- name: Verify image not pulled
Expand Down Expand Up @@ -407,6 +408,12 @@
^[ ]*podman-kube@.+-{{ item[0] }}[.]yml[.]service[ ]+loaded[
]+active
rescue:
- name: Dump journal
command: journalctl -ex
changed_when: false
failed_when: true

always:
# have to clean up storage.conf - otherwise, get this message:
# A storage.conf file exists at /etc/containers/storage.conf
Expand All @@ -430,3 +437,4 @@
file:
path: "{{ __kube_file_src.path }}"
state: absent
delegate_to: localhost
7 changes: 7 additions & 0 deletions tests/tests_config_files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@
loop_var: __file
vars:
__fingerprint: "system_role:podman"

rescue:
- name: Dump journal
command: journalctl -ex
changed_when: false
failed_when: true

always:
- name: Remove test config files
file:
Expand Down
Loading

0 comments on commit 19a64bc

Please sign in to comment.