Skip to content

Commit 31d2a25

Browse files
committed
test(podman): cover user namespace configurations
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 06ea61e commit 31d2a25

16 files changed

Lines changed: 1052 additions & 1 deletion
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- name: Capture the default rootless Podman user-namespace mapping
6+
hosts: all
7+
gather_facts: false
8+
vars:
9+
podman_reference_image: "{{ openshell_podman_reference_image }}"
10+
podman_reference_uid_map: /var/lib/openshell-test-inputs/podman/reference-uid-map
11+
tasks:
12+
- name: Wait for SSH
13+
ansible.builtin.wait_for_connection:
14+
15+
- name: Read OpenShell gateway service user
16+
become: true
17+
ansible.builtin.command:
18+
argv:
19+
- systemctl
20+
- show
21+
- openshell-gateway.service
22+
- --property
23+
- User
24+
- --value
25+
changed_when: false
26+
register: openshell_gateway_service_user
27+
28+
- name: Require the rootless Podman gateway user
29+
ansible.builtin.assert:
30+
that:
31+
- openshell_gateway_service_user.stdout == "tmachine"
32+
fail_msg: >-
33+
The Podman default-userns suite requires a rootless Podman gateway
34+
running as tmachine, not {{ openshell_gateway_service_user.stdout | default("unknown") }}
35+
36+
- name: Read OpenShell gateway configuration
37+
become: true
38+
ansible.builtin.slurp:
39+
src: /etc/openshell/gateway.toml
40+
register: openshell_gateway_config
41+
42+
- name: Require unconfigured Podman user namespaces
43+
ansible.builtin.assert:
44+
that:
45+
- >-
46+
(openshell_gateway_config.content | b64decode)
47+
is not regex('(?m)^\\s*(userns|uidmap|gidmap)\\s*=')
48+
fail_msg: >-
49+
The Podman default-userns suite requires gateway.toml to omit userns,
50+
uidmap, and gidmap.
51+
52+
- name: Resolve tmachine UID
53+
ansible.builtin.command:
54+
argv:
55+
- id
56+
- -u
57+
- tmachine
58+
changed_when: false
59+
register: tmachine_uid
60+
61+
- name: Create Podman test-input directory
62+
become: true
63+
ansible.builtin.file:
64+
path: "{{ podman_reference_uid_map | dirname }}"
65+
state: directory
66+
owner: tmachine
67+
group: tmachine
68+
mode: "0700"
69+
70+
- name: Pull the Podman reference image
71+
become: true
72+
become_user: tmachine
73+
ansible.builtin.command:
74+
argv: [podman, pull, "{{ podman_reference_image }}"]
75+
environment:
76+
HOME: /home/tmachine
77+
XDG_RUNTIME_DIR: "/run/user/{{ tmachine_uid.stdout }}"
78+
changed_when: false
79+
80+
- name: Capture direct Podman default UID mapping
81+
become: true
82+
become_user: tmachine
83+
ansible.builtin.command:
84+
argv:
85+
- podman
86+
- run
87+
- --rm
88+
- --pull
89+
- never
90+
- --entrypoint
91+
- /bin/cat
92+
- "{{ podman_reference_image }}"
93+
- /proc/self/uid_map
94+
environment:
95+
HOME: /home/tmachine
96+
XDG_RUNTIME_DIR: "/run/user/{{ tmachine_uid.stdout }}"
97+
changed_when: false
98+
register: podman_default_uid_map
99+
100+
- name: Require a direct Podman UID mapping
101+
ansible.builtin.assert:
102+
that:
103+
- podman_default_uid_map.stdout | trim | length > 0
104+
fail_msg: Direct rootless Podman reference container returned no UID mapping
105+
106+
- name: Store direct Podman default UID mapping
107+
become: true
108+
ansible.builtin.copy:
109+
content: "{{ podman_default_uid_map.stdout | trim }}\n"
110+
dest: "{{ podman_reference_uid_map }}"
111+
owner: tmachine
112+
group: tmachine
113+
mode: "0600"
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- name: Run Podman archive tests
6+
hosts: all
7+
gather_facts: false
8+
vars:
9+
podman_test_root: /var/lib/openshell-driver-tests/podman
10+
podman_test_input_dir: /var/lib/openshell-test-inputs/podman
11+
tasks:
12+
- name: Wait for SSH
13+
ansible.builtin.wait_for_connection:
14+
15+
- name: Create Podman test directory
16+
become: true
17+
ansible.builtin.file:
18+
path: "{{ podman_test_root }}"
19+
state: directory
20+
owner: tmachine
21+
group: tmachine
22+
mode: "0700"
23+
24+
- name: Install Podman test bundle
25+
become: true
26+
ansible.builtin.unarchive:
27+
src: "{{ openshell_podman_test_bundle }}"
28+
dest: "{{ podman_test_root }}"
29+
owner: tmachine
30+
group: tmachine
31+
32+
- name: Remove any previous OpenShell gateway registration
33+
ansible.builtin.command:
34+
argv: [/usr/local/bin/openshell, gateway, remove, tmachine]
35+
changed_when: false
36+
failed_when: false
37+
38+
- name: Register the configured OpenShell gateway
39+
ansible.builtin.command:
40+
argv: [/usr/local/bin/openshell, gateway, add, http://127.0.0.1:17670, --local, --name, tmachine]
41+
42+
- name: Run Podman archive tests
43+
ansible.builtin.command:
44+
argv: [cargo-nextest, nextest, run, --archive-file, "{{ podman_test_root }}/tests.tar.zst", --workspace-remap, "{{ podman_test_root }}", --no-capture]
45+
environment:
46+
OPENSHELL_BIN: /usr/local/bin/openshell
47+
OPENSHELL_TEST_INPUT_DIR: "{{ podman_test_input_dir }}"
48+
OPENSHELL_PODMAN_TEST_IMAGE: "{{ openshell_podman_test_image | default('') }}"
49+
register: podman_test_result
50+
changed_when: false
51+
failed_when: false
52+
53+
- name: Show Podman test diagnostics
54+
ansible.builtin.debug:
55+
var: podman_test_result.stderr_lines
56+
57+
- name: Show Podman test result
58+
ansible.builtin.debug:
59+
var: podman_test_result.stdout_lines
60+
61+
- name: Capture OpenShell gateway journal after Podman test failure
62+
become: true
63+
ansible.builtin.command:
64+
argv:
65+
- journalctl
66+
- --unit
67+
- openshell-gateway.service
68+
- --no-pager
69+
- --lines
70+
- "200"
71+
changed_when: false
72+
failed_when: false
73+
when: podman_test_result.rc != 0
74+
register: podman_gateway_journal
75+
76+
- name: Show OpenShell gateway journal after Podman test failure
77+
ansible.builtin.debug:
78+
var: podman_gateway_journal.stdout_lines
79+
when: podman_test_result.rc != 0
80+
81+
- name: Resolve tmachine UID after Podman test failure
82+
ansible.builtin.command:
83+
argv: [id, --user, tmachine]
84+
changed_when: false
85+
when: podman_test_result.rc != 0
86+
register: podman_tmachine_uid
87+
88+
- name: Discover Podman containers after test failure
89+
become: true
90+
become_user: tmachine
91+
ansible.builtin.command:
92+
argv: [timeout, "15", podman, ps, --all, --quiet, --no-trunc]
93+
environment:
94+
HOME: /home/tmachine
95+
XDG_RUNTIME_DIR: "/run/user/{{ podman_tmachine_uid.stdout }}"
96+
changed_when: false
97+
failed_when: false
98+
when: podman_test_result.rc != 0
99+
register: podman_failed_containers
100+
101+
- name: Capture rootless Podman journal after test failure
102+
become: true
103+
become_user: tmachine
104+
ansible.builtin.command:
105+
argv: [journalctl, --user, --unit, podman.service, --no-pager, --lines, "200"]
106+
environment:
107+
HOME: /home/tmachine
108+
XDG_RUNTIME_DIR: "/run/user/{{ podman_tmachine_uid.stdout }}"
109+
changed_when: false
110+
failed_when: false
111+
when: podman_test_result.rc != 0
112+
register: podman_service_journal
113+
114+
- name: Show rootless Podman journal after test failure
115+
ansible.builtin.debug:
116+
var: podman_service_journal.stdout_lines
117+
when: podman_test_result.rc != 0
118+
119+
- name: Capture Podman container inspection after test failure
120+
become: true
121+
become_user: tmachine
122+
ansible.builtin.command:
123+
argv: [timeout, "15", podman, inspect, "{{ item }}"]
124+
environment:
125+
HOME: /home/tmachine
126+
XDG_RUNTIME_DIR: "/run/user/{{ podman_tmachine_uid.stdout }}"
127+
changed_when: false
128+
failed_when: false
129+
when: podman_test_result.rc != 0
130+
loop: "{{ podman_failed_containers.stdout_lines | default([]) }}"
131+
register: podman_failed_container_inspection
132+
133+
- name: Show Podman container inspection after test failure
134+
ansible.builtin.debug:
135+
var: podman_failed_container_inspection.results
136+
when: podman_test_result.rc != 0
137+
138+
- name: Capture Podman container logs after test failure
139+
become: true
140+
become_user: tmachine
141+
ansible.builtin.command:
142+
argv: [timeout, "15", podman, logs, "{{ item }}"]
143+
environment:
144+
HOME: /home/tmachine
145+
XDG_RUNTIME_DIR: "/run/user/{{ podman_tmachine_uid.stdout }}"
146+
changed_when: false
147+
failed_when: false
148+
when: podman_test_result.rc != 0
149+
loop: "{{ podman_failed_containers.stdout_lines | default([]) }}"
150+
register: podman_failed_container_logs
151+
152+
- name: Show Podman container logs after test failure
153+
ansible.builtin.debug:
154+
var: podman_failed_container_logs.results
155+
when: podman_test_result.rc != 0
156+
157+
- name: Require Podman archive success
158+
ansible.builtin.assert:
159+
that: [podman_test_result.rc == 0]
160+
fail_msg: Podman archive tests failed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- import_playbook: userns-profile.yaml
6+
vars:
7+
podman_userns_profile: auto
8+
podman_userns_config: "{{ openshell_podman_userns_auto_config }}"
9+
podman_userns_reference_args: [--userns, auto]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- import_playbook: userns-profile.yaml
6+
vars:
7+
podman_userns_profile: keep-id
8+
podman_userns_config: "{{ openshell_podman_userns_keep_id_config }}"
9+
podman_userns_reference_args: [--userns, keep-id]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- import_playbook: userns-profile.yaml
6+
vars:
7+
podman_userns_profile: private
8+
podman_userns_config: "{{ openshell_podman_userns_private_config }}"
9+
podman_userns_reference_args:
10+
# Podman infers a private namespace from explicit maps; its CLI rejects
11+
# combining --userns private with --uidmap/--gidmap.
12+
- --uidmap
13+
- 0:0:1
14+
- --uidmap
15+
- 1:1:65535
16+
- --gidmap
17+
- 0:0:1
18+
- --gidmap
19+
- 1:1:65535

0 commit comments

Comments
 (0)