rhel-system-roles/SOURCES/0104-fix-do-not-use-become-for-changing-hostdir-ownership.patch

211 lines
8.2 KiB
Diff
Raw Permalink Normal View History

From b2e79348094ea8d89b71727d82a80a9f3cfbb1ce Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Tue, 9 Apr 2024 18:28:19 -0600
Subject: [PATCH 104/115] fix: do not use become for changing hostdir
ownership, and expose subuid/subgid info
When creating host directories, do not use `become`, because if
it needs to change ownership, that must be done by `root`, not
as the rootless podman user.
In order to test this, I have changed the role to export the subuid and subgid
information for the rootless users as two dictionaries:
`podman_subuid_info` and `podman_subgid_info`. See `README.md` for
usage.
NOTE that depending on the namespace used by your containers, you might not
be able to use the subuid and subgid information, which comes from `getsubids`
if available, or directly from the files `/etc/subuid` and `/etc/subgid` on
the host.
QE: The test tests_basic.yml has been extended for this.
Signed-off-by: Rich Megginson <rmeggins@redhat.com>
(cherry picked from commit 3d02eb725355088df6c707717547f5ad6b7c400c)
---
README.md | 28 ++++++++++++
tasks/create_update_kube_spec.yml | 2 -
tasks/create_update_quadlet_spec.yml | 2 -
tasks/handle_user_group.yml | 66 +++++++++++++++++++++-------
tests/tests_basic.yml | 2 +
5 files changed, 79 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
index ea1edfb..e5a7c12 100644
--- a/README.md
+++ b/README.md
@@ -418,6 +418,34 @@ PodmanArgs=--secret=my-app-pwd,type=env,target=MYAPP_PASSWORD
{% endif %}
```
+### podman_subuid_info, podman_subgid_info
+
+The role needs to ensure any users and groups are present in the subuid and
+subgid information. Once it extracts this data, it will be available in
+`podman_subuid_info` and `podman_subgid_info`. These are dicts. The key is the
+user or group name, and the value is a `dict` with two fields:
+
+* `start` - the start of the id range for that user or group, as an `int`
+* `range` - the id range for that user or group, as an `int`
+
+```yaml
+podman_host_directories:
+ "/var/lib/db":
+ mode: "0777"
+ owner: "{{ 1001 + podman_subuid_info['dbuser']['start'] - 1 }}"
+ group: "{{ 1001 + podman_subgid_info['dbgroup']['start'] - 1 }}"
+```
+
+Where `1001` is the uid for user `dbuser`, and `1001` is the gid for group
+`dbgroup`.
+
+**NOTE**: depending on the namespace used by your containers, you might not be
+able to use the subuid and subgid information, which comes from `getsubids` if
+available, or directly from the files `/etc/subuid` and `/etc/subgid` on the
+host. See
+[podman user namespace modes](https://www.redhat.com/sysadmin/rootless-podman-user-namespace-modes)
+for more information.
+
## Example Playbooks
Create rootless container with volume mount:
diff --git a/tasks/create_update_kube_spec.yml b/tasks/create_update_kube_spec.yml
index 95d7d35..7a8ba9c 100644
--- a/tasks/create_update_kube_spec.yml
+++ b/tasks/create_update_kube_spec.yml
@@ -32,8 +32,6 @@
__defaults: "{{ {'path': item} | combine(__podman_hostdirs_defaults) |
combine(__owner_group) }}"
loop: "{{ __podman_volumes }}"
- become: "{{ __podman_rootless | ternary(true, omit) }}"
- become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
when:
- podman_create_host_directories | bool
- __podman_volumes | d([]) | length > 0
diff --git a/tasks/create_update_quadlet_spec.yml b/tasks/create_update_quadlet_spec.yml
index c3e0095..062c105 100644
--- a/tasks/create_update_quadlet_spec.yml
+++ b/tasks/create_update_quadlet_spec.yml
@@ -16,8 +16,6 @@
__defaults: "{{ {'path': item} | combine(__podman_hostdirs_defaults) |
combine(__owner_group) }}"
loop: "{{ __podman_volumes }}"
- become: "{{ __podman_rootless | ternary(true, omit) }}"
- become_user: "{{ __podman_rootless | ternary(__podman_user, omit) }}"
when:
- podman_create_host_directories | bool
- __podman_volumes | d([]) | length > 0
diff --git a/tasks/handle_user_group.yml b/tasks/handle_user_group.yml
index 17300b6..ea9984d 100644
--- a/tasks/handle_user_group.yml
+++ b/tasks/handle_user_group.yml
@@ -52,10 +52,26 @@
- name: Check user with getsubids
command: getsubids {{ __podman_user | quote }}
changed_when: false
+ register: __podman_register_subuids
- name: Check group with getsubids
command: getsubids -g {{ __podman_group_name | quote }}
changed_when: false
+ register: __podman_register_subgids
+
+ - name: Set user subuid and subgid info
+ set_fact:
+ podman_subuid_info: "{{ podman_subuid_info | d({}) |
+ combine({__podman_user:
+ {'start': __subuid_data[2] | int, 'range': __subuid_data[3] | int}})
+ if __subuid_data | length > 0 else podman_subuid_info | d({}) }}"
+ podman_subgid_info: "{{ podman_subgid_info | d({}) |
+ combine({__podman_group_name:
+ {'start': __subgid_data[2] | int, 'range': __subgid_data[3] | int}})
+ if __subgid_data | length > 0 else podman_subgid_info | d({}) }}"
+ vars:
+ __subuid_data: "{{ __podman_register_subuids.stdout.split() | list }}"
+ __subgid_data: "{{ __podman_register_subgids.stdout.split() | list }}"
- name: Check subuid, subgid files if no getsubids
when:
@@ -63,32 +79,48 @@
- __podman_user not in ["root", "0"]
- __podman_group not in ["root", "0"]
block:
- - name: Check if user is in subuid file
- find:
- path: /etc
- pattern: subuid
- use_regex: true
- contains: "^{{ __podman_user }}:.*$"
- register: __podman_uid_line_found
+ - name: Get subuid file
+ slurp:
+ path: /etc/subuid
+ register: __podman_register_subuids
+
+ - name: Get subgid file
+ slurp:
+ path: /etc/subgid
+ register: __podman_register_subgids
+
+ - name: Set user subuid and subgid info
+ set_fact:
+ podman_subuid_info: "{{ podman_subuid_info | d({}) |
+ combine({__podman_user:
+ {'start': __subuid_data[1] | int, 'range': __subuid_data[2] | int}})
+ if __subuid_data else podman_subuid_info | d({}) }}"
+ podman_subgid_info: "{{ podman_subgid_info | d({}) |
+ combine({__podman_group_name:
+ {'start': __subgid_data[1] | int, 'range': __subgid_data[2] | int}})
+ if __subgid_data else podman_subgid_info | d({}) }}"
+ vars:
+ __subuid_match_line: "{{
+ (__podman_register_subuids.content | b64decode).split('\n') | list |
+ select('match', '^' ~ __podman_user ~ ':') | list }}"
+ __subuid_data: "{{ __subuid_match_line[0].split(':') | list
+ if __subuid_match_line else null }}"
+ __subgid_match_line: "{{
+ (__podman_register_subgids.content | b64decode).split('\n') | list |
+ select('match', '^' ~ __podman_group_name ~ ':') | list }}"
+ __subgid_data: "{{ __subgid_match_line[0].split(':') | list
+ if __subgid_match_line else null }}"
- name: Fail if user not in subuid file
fail:
msg: >
The given podman user [{{ __podman_user }}] is not in the
/etc/subuid file - cannot continue
- when: not __podman_uid_line_found.matched
-
- - name: Check if group is in subgid file
- find:
- path: /etc
- pattern: subgid
- use_regex: true
- contains: "^{{ __podman_group_name }}:.*$"
- register: __podman_gid_line_found
+ when: not __podman_user in podman_subuid_info
- name: Fail if group not in subgid file
fail:
msg: >
The given podman group [{{ __podman_group_name }}] is not in the
/etc/subgid file - cannot continue
- when: not __podman_gid_line_found.matched
+ when: not __podman_group_name in podman_subuid_info
diff --git a/tests/tests_basic.yml b/tests/tests_basic.yml
index d578b15..121c3a7 100644
--- a/tests/tests_basic.yml
+++ b/tests/tests_basic.yml
@@ -8,6 +8,8 @@
podman_host_directories:
"/tmp/httpd1-create":
mode: "0777"
+ owner: "{{ 1001 + podman_subuid_info['user1']['start'] - 1 }}"
+ group: "{{ 1001 + podman_subgid_info['user1']['start'] - 1 }}"
podman_run_as_user: root
test_names_users:
- [httpd1, user1, 1001]
--
2.46.0