Skip to content

Commit

Permalink
fix: subgid maps user to gids, not group to gids
Browse files Browse the repository at this point in the history
Cause: The podman role was looking up groups in the subgid values, not
users.

Consequence: If the user name was different from the group name, the role
would fail to lookup the subgid values.

Fix: Ensure that the user is used to lookup the subgid values.

Result: The subgid values are looked up correctly.

Signed-off-by: Rich Megginson <[email protected]>
  • Loading branch information
richm committed Sep 4, 2024
1 parent 392b482 commit ad01b00
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 51 deletions.
56 changes: 28 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,11 @@ restrictions:
* They must be already present on the system - the role will not create the
users or groups - the role will exit with an error if a non-existent user or
group is specified
* They must already exist in `/etc/subuid` and `/etc/subgid`, or are otherwise
provided by your identity management system - the role will exit with an error
if a specified user is not present in `/etc/subuid`, or if a specified group
is not in `/etc/subgid`. The role uses `getsubids` to check the user and
group if available, or checks the files directly if `getsubids` is not
available.
* The user must already exist in `/etc/subuid` and `/etc/subgid`, or otherwise
be provided by your identity management system - the role will exit with an
error if a specified user is not present in `/etc/subuid` and `/etc/subgid`.
The role uses `getsubids` to check the user and group if available, or checks
the files directly if `getsubids` is not available.

## Role Variables

Expand All @@ -56,14 +55,15 @@ except for the following:
* `started` - Create the pods and systemd services, and start them running
* `created` - Create the pods and systemd services, but do not start them
* `absent` - Remove the pods and systemd services
* `run_as_user` - Use this to specify a per-pod user. If you do not
specify this, then the global default `podman_run_as_user` value will be used.
* `run_as_user` - Use this to specify a per-pod user. If you do not specify
this, then the global default `podman_run_as_user` value will be used.
Otherwise, `root` will be used. NOTE: The user must already exist - the role
will not create one. The user must be present in `/etc/subuid`.
* `run_as_group` - Use this to specify a per-pod group. If you do not
specify this, then the global default `podman_run_as_group` value will be
used. Otherwise, `root` will be used. NOTE: The group must already exist -
the role will not create one. The group must be present in `/etc/subgid`.
will not create one. The user must be present in `/etc/subuid` and
`/etc/subgid`.
* `run_as_group` - Use this to specify a per-pod group. If you do not specify
this, then the global default `podman_run_as_group` value will be used.
Otherwise, `root` will be used. NOTE: The group must already exist - the role
will not create one.
* `systemd_unit_scope` - The scope to use for the systemd unit. If you do not
specify this, then the global default `podman_systemd_unit_scope` will be
used. Otherwise, the scope will be `system` for root containers, and `user`
Expand Down Expand Up @@ -278,14 +278,13 @@ podman_selinux_ports:
This is the name of the user to use for all rootless containers. You can also
specify per-container username with `run_as_user` in `podman_kube_specs`. NOTE:
The user must already exist - the role will not create one. The user must be
present in `/etc/subuid`.
present in `/etc/subuid` and `/etc/subgid`.

### podman_run_as_group

This is the name of the group to use for all rootless containers. You can also
specify per-container group name with `run_as_group` in `podman_kube_specs`.
NOTE: The group must already exist - the role will not create one. The group must
be present in `/etc/subgid`.
NOTE: The group must already exist - the role will not create one.

### podman_systemd_unit_scope

Expand Down Expand Up @@ -433,14 +432,15 @@ The keys of each `dict` are as follows:
* `run_as_user` - Use this to specify a per-credential file owner. If you do
not specify this, then the global default `podman_run_as_user` value will be
used. Otherwise, `root` will be used. NOTE: The user must already exist - the
role will not create one. The user must be present in `/etc/subuid`. NOTE:
This is used as the user for the `$HOME` directory if `file` is not specified,
and as the owner of the file. If you want the owner of the file to be
different than the user used for `$HOME`, specify `file` as an absolute path.
role will not create one. The user must be present in `/etc/subuid` and
`/etc/subgid`. NOTE: This is used as the user for the `$HOME` directory if
`file` is not specified, and as the owner of the file. If you want the owner
of the file to be different than the user used for `$HOME`, specify `file` as
an absolute path.
* `run_as_group` - Use this to specify a per-credential file group. If you do
not specify this, then the global default `podman_run_as_group` value will be
used. Otherwise, `root` will be used. NOTE: The group must already exist -
the role will not create one. The group must be present in `/etc/subgid`.
the role will not create one.
* `mode` - The mode of the file - default is `"0600"`.

For example, if you have
Expand Down Expand Up @@ -577,24 +577,24 @@ PodmanArgs=--secret=my-app-pwd,type=env,target=MYAPP_PASSWORD

### podman_subuid_info, podman_subgid_info

The role needs to ensure any users and groups are present in the subuid and
The role needs to ensure any users 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:
user 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`
* `start` - the start of the id range for that user, as an `int`
* `range` - the id range for that user, 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 }}"
group: "{{ 2001 + podman_subgid_info['dbuser']['start'] - 1 }}"
```

Where `1001` is the uid for user `dbuser`, and `1001` is the gid for group
`dbgroup`.
Where `1001` is the uid for user `dbuser`, and `2001` is the gid for the
group you want to use.

**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
Expand Down
32 changes: 9 additions & 23 deletions tasks/handle_user_group.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@
{{ ansible_facts["getent_passwd"][__podman_user][2] }}
{%- endif -%}
- name: Get group information
getent:
database: group
key: "{{ __podman_group }}"
fail_key: false
when: "'getent_group' not in ansible_facts or
__podman_group not in ansible_facts['getent_group']"

- name: Set group name
set_fact:
__podman_group_name: "{{ ansible_facts['getent_group'].keys() |
list | first }}"

- name: See if getsubids exists
stat:
path: /usr/bin/getsubids
Expand All @@ -50,13 +37,13 @@
- __podman_user not in ["root", "0"]
- __podman_stat_getsubids.stat.exists
block:
- name: Check user with getsubids
- name: Check with getsubids for user subuids
command: getsubids {{ __podman_user | quote }}
changed_when: false
register: __podman_register_subuids

- name: Check group with getsubids
command: getsubids -g {{ __podman_group_name | quote }}
- name: Check with getsubids for user subgids
command: getsubids -g {{ __podman_user | quote }}
changed_when: false
register: __podman_register_subgids

Expand All @@ -67,7 +54,7 @@
{'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:
combine({__podman_user:
{'start': __subgid_data[2] | int, 'range': __subgid_data[3] | int}})
if __subgid_data | length > 0 else podman_subgid_info | d({}) }}"
vars:
Expand All @@ -78,7 +65,6 @@
when:
- not __podman_stat_getsubids.stat.exists
- __podman_user not in ["root", "0"]
- __podman_group not in ["root", "0"]
block:
- name: Get subuid file
slurp:
Expand All @@ -97,7 +83,7 @@
{'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:
combine({__podman_user:
{'start': __subgid_data[1] | int, 'range': __subgid_data[2] | int}})
if __subgid_data else podman_subgid_info | d({}) }}"
vars:
Expand All @@ -108,7 +94,7 @@
if __subuid_match_line else none }}"
__subgid_match_line: "{{
(__podman_register_subgids.content | b64decode).split('\n') | list |
select('match', '^' ~ __podman_group_name ~ ':') | list }}"
select('match', '^' ~ __podman_user ~ ':') | list }}"
__subgid_data: "{{ __subgid_match_line[0].split(':') | list
if __subgid_match_line else none }}"

Expand All @@ -119,9 +105,9 @@
/etc/subuid file - cannot continue
when: not __podman_user in podman_subuid_info

- name: Fail if group not in subgid file
- name: Fail if user not in subgid file
fail:
msg: >
The given podman group [{{ __podman_group_name }}] is not in the
The given podman user [{{ __podman_user }}] is not in the
/etc/subgid file - cannot continue
when: not __podman_group_name in podman_subuid_info
when: not __podman_user in podman_subgid_info

0 comments on commit ad01b00

Please sign in to comment.