Skip to content

Commit 65eb916

Browse files
SDAChesselezar
andauthored
test(tmachine): add Debian installer profile (#3461)
* test(tmachine): add Debian installer profile Signed-off-by: Simon Scatton <sscatton@nvidia.com> * refactor(ci): centralize conformance matrix Signed-off-by: Simon Scatton <sscatton@nvidia.com> * test(ci): prefer packaged conformance artifacts Signed-off-by: Simon Scatton <sscatton@nvidia.com> * test(tmachine): use packaged Debian gateway service Signed-off-by: Simon Scatton <sscatton@nvidia.com> * test(tmachine): isolate Debian qualification config Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Simon Scatton <sscatton@nvidia.com> Signed-off-by: Evan Lezar <elezar@nvidia.com> Co-authored-by: Evan Lezar <elezar@nvidia.com>
1 parent 1905069 commit 65eb916

14 files changed

Lines changed: 214 additions & 37 deletions

File tree

.github/workflows/integration-runner.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ on:
2424
type: string
2525
default: >-
2626
[
27-
{"environment":"ubuntu-docker-rootful","installer":"binaries","testsuite":"conformance"},
27+
{"environment":"ubuntu-docker-rootful","installer":"deb","testsuite":"conformance"},
2828
{"environment":"fedora-podman-rootful","installer":"binaries","testsuite":"conformance"},
2929
{"environment":"fedora-podman-rootless","installer":"binaries","testsuite":"conformance"}
3030
]

.github/workflows/prepare-integration-inputs.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ on:
1111
required: false
1212
type: string
1313
default: ""
14+
deb-artifact-name:
15+
description: Debian package artifact to include in the tmachine inputs
16+
required: false
17+
type: string
18+
default: ""
1419
outputs:
1520
source_sha:
1621
description: Source revision of the candidate artifacts
@@ -65,6 +70,22 @@ jobs:
6570
github-token: ${{ github.token }}
6671
run-id: ${{ inputs['artifact-run-id'] || github.run_id }}
6772

73+
- name: Download Debian package artifact
74+
if: inputs['deb-artifact-name'] != ''
75+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
76+
with:
77+
name: ${{ inputs['deb-artifact-name'] }}
78+
path: artifacts/packages/download
79+
github-token: ${{ github.token }}
80+
run-id: ${{ inputs['artifact-run-id'] || github.run_id }}
81+
82+
- name: Stage Debian package input
83+
if: inputs['deb-artifact-name'] != ''
84+
run: |
85+
set -euo pipefail
86+
mv artifacts/packages/download/*.deb artifacts/packages/openshell.deb
87+
rmdir artifacts/packages/download
88+
6889
- name: Log in to GHCR
6990
run: echo "${{ github.token }}" | docker login ghcr.io -u "${GITHUB_ACTOR}" --password-stdin
7091

.github/workflows/release-dev.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,14 @@ jobs:
102102
checkout-ref: ${{ github.sha }}
103103

104104
prepare-integration:
105-
needs: [build-binaries, build-images]
105+
needs: [build-binaries, build-deb, build-images]
106106
permissions:
107107
actions: read
108108
contents: read
109109
packages: read
110110
uses: ./.github/workflows/prepare-integration-inputs.yml
111+
with:
112+
deb-artifact-name: deb-linux-amd64
111113

112114
conformance-integration:
113115
needs: prepare-integration

.github/workflows/release-tag.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,14 @@ jobs:
130130
checkout-ref: ${{ needs.compute-versions.outputs.source_sha }}
131131

132132
prepare-integration:
133-
needs: [compute-versions, build-binaries, build-images]
133+
needs: [compute-versions, build-binaries, build-deb, build-images]
134134
permissions:
135135
actions: read
136136
contents: read
137137
packages: read
138138
uses: ./.github/workflows/prepare-integration-inputs.yml
139+
with:
140+
deb-artifact-name: deb-linux-amd64
139141

140142
conformance-integration:
141143
needs: prepare-integration

architecture/build.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ includes, templates, inventory, and requirements. The digest uses sorted
275275
relative paths, file contents, and executable permissions; source symlinks
276276
are unsupported. Both keys also retain the ordered playbook paths and contents,
277277
their base disk contents, and whether Galaxy is enabled; install keys
278-
include named binary inputs. The top-level `.roles` directory is excluded:
278+
include named artifact inputs. The top-level `.roles` directory is excluded:
279279
Galaxy release pins in `requirements.yaml` are treated as immutable, including
280280
any transitive dependency pins. Cache misses with Galaxy enabled reinstall
281281
the required roles and their dependencies before running playbooks.
@@ -286,7 +286,17 @@ the gateway, sandbox, and supervisor as separate binaries for their respective
286286
Dockerfiles. The helpers stage binaries under `artifacts/binaries` so local and
287287
CI builds expose the same inputs to tmachine and image assembly. The Ubuntu
288288
Docker and Fedora Podman environments import both local runtime images and
289-
configure the gateway to use them.
289+
configure the gateway to use them. The Ubuntu `deb` installer consumes
290+
`artifacts/packages/openshell.deb`; the `binaries` installer remains available
291+
for direct executable installation on every environment. Release Dev and
292+
Release Tag run Ubuntu conformance through the Debian package, while Fedora
293+
continues using direct executable installation until RPM coverage is available.
294+
The Debian qualification profile keeps candidate-image overrides outside the
295+
operator-owned gateway configuration: it writes a harness-owned file under
296+
`/var/lib/openshell-qualification` and selects it through the packaged systemd
297+
unit's `gateway.env` hook. Ordinary package installations continue to use the
298+
gateway's built-in runtime-image defaults unless the operator configures an
299+
override.
290300

291301
## Python Wheel Packaging
292302

tests/ansible/playbooks/conformance/cli.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@
3939
- conformance_archive.stat.isreg | default(false)
4040
fail_msg: OpenShell conformance test bundle did not contain tests.tar.zst
4141

42+
- name: Resolve installed OpenShell CLI
43+
ansible.builtin.command:
44+
argv:
45+
- /bin/sh
46+
- -c
47+
- command -v openshell
48+
register: openshell_cli
49+
changed_when: false
50+
4251
- name: Run OpenShell conformance archive
4352
ansible.builtin.command:
4453
argv:
@@ -51,7 +60,7 @@
5160
- /var/lib/openshell-conformance/tests
5261
- --no-capture
5362
environment:
54-
OPENSHELL_BIN: /usr/local/bin/openshell
63+
OPENSHELL_BIN: "{{ openshell_cli.stdout }}"
5564
register: conformance_result
5665
changed_when: false
5766
failed_when: false

tests/ansible/playbooks/features/provider-refresh/keycloak.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@
4949
- provider_refresh_keycloak_test_archive.stat.isreg | default(false)
5050
fail_msg: Keycloak provider refresh test bundle did not contain tests.tar.zst
5151

52+
- name: Resolve installed OpenShell CLI
53+
ansible.builtin.command:
54+
argv:
55+
- /bin/sh
56+
- -c
57+
- command -v openshell
58+
register: openshell_cli
59+
changed_when: false
60+
5261
- name: Run Keycloak provider refresh archive
5362
ansible.builtin.command:
5463
argv:
@@ -61,7 +70,7 @@
6170
- /var/lib/openshell-provider-refresh/tests
6271
- --no-capture
6372
environment:
64-
OPENSHELL_BIN: /usr/local/bin/openshell
73+
OPENSHELL_BIN: "{{ openshell_cli.stdout }}"
6574
OPENSHELL_E2E_OIDC_ISSUER: http://127.0.0.1:8180/realms/openshell
6675
OPENSHELL_E2E_OIDC_USERNAME: admin@test
6776
OPENSHELL_E2E_OIDC_PASSWORD: admin
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
- name: Install OpenShell Debian package
6+
hosts: all
7+
gather_facts: false
8+
tasks:
9+
- name: Wait for SSH
10+
ansible.builtin.wait_for_connection:
11+
12+
- name: Copy OpenShell Debian package
13+
become: true
14+
ansible.builtin.copy:
15+
src: "{{ openshell_deb }}"
16+
dest: /var/tmp/openshell.deb
17+
mode: "0644"
18+
19+
- name: Install OpenShell Debian package
20+
become: true
21+
ansible.builtin.apt:
22+
deb: /var/tmp/openshell.deb
23+
24+
- name: Copy OpenShell runtime images
25+
become: true
26+
ansible.builtin.copy:
27+
src: "{{ item.src }}"
28+
dest: "/var/tmp/{{ item.name }}.tar"
29+
mode: "0644"
30+
loop:
31+
- name: openshell-sandbox
32+
src: "{{ openshell_sandbox_image }}"
33+
- name: openshell-supervisor
34+
src: "{{ openshell_supervisor_image }}"
35+
36+
- name: Load OpenShell runtime images
37+
become: true
38+
ansible.builtin.command:
39+
argv:
40+
- docker
41+
- load
42+
- --input
43+
- "/var/tmp/{{ item }}.tar"
44+
loop:
45+
- openshell-sandbox
46+
- openshell-supervisor
47+
48+
# The package normally starts from its built-in runtime-image defaults.
49+
# Qualification instead pins the candidate images staged by tmachine, so
50+
# keep that override separate from the operator-owned gateway.toml.
51+
- name: Create OpenShell qualification configuration directory
52+
become: true
53+
ansible.builtin.file:
54+
path: /var/lib/openshell-qualification
55+
state: directory
56+
owner: root
57+
group: root
58+
mode: "0755"
59+
60+
- name: Configure candidate OpenShell runtime images for qualification
61+
become: true
62+
ansible.builtin.copy:
63+
dest: /var/lib/openshell-qualification/gateway.toml
64+
owner: root
65+
group: root
66+
mode: "0644"
67+
content: |
68+
[openshell]
69+
version = 2
70+
71+
[openshell.drivers.docker]
72+
sandbox_runtime_image = "docker.io/openshell/sandbox:tmachine"
73+
supervisor_image = "docker.io/openshell/supervisor:tmachine"
74+
75+
- name: Create OpenShell environment directory
76+
ansible.builtin.file:
77+
path: /home/tmachine/.config/openshell
78+
state: directory
79+
mode: "0700"
80+
81+
- name: Select qualification gateway configuration
82+
ansible.builtin.copy:
83+
dest: /home/tmachine/.config/openshell/gateway.env
84+
mode: "0600"
85+
content: |
86+
OPENSHELL_GATEWAY_CONFIG=/var/lib/openshell-qualification/gateway.toml
87+
88+
- name: Start tmachine user manager
89+
ansible.builtin.include_role:
90+
name: tmachine_user_manager
91+
92+
- name: Start packaged OpenShell gateway service
93+
ansible.builtin.systemd_service:
94+
name: openshell-gateway.service
95+
scope: user
96+
daemon_reload: true
97+
enabled: true
98+
state: started
99+
environment:
100+
XDG_RUNTIME_DIR: /run/user/1000
101+
DBUS_SESSION_BUS_ADDRESS: unix:path=/run/user/1000/bus
102+
103+
- name: Wait for OpenShell gateway
104+
ansible.builtin.wait_for:
105+
host: 127.0.0.1
106+
port: 17670
107+
timeout: 60
108+
109+
- name: Register packaged OpenShell gateway
110+
ansible.builtin.include_role:
111+
name: openshell_client
112+
vars:
113+
openshell_client_gateway_endpoint: https://127.0.0.1:17670
114+
openshell_client_gateway_name: openshell

tests/ansible/playbooks/podman-rootless.yaml

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,9 @@
99
- name: Wait for SSH
1010
ansible.builtin.wait_for_connection:
1111

12-
- name: Enable lingering for tmachine
13-
become: true
14-
ansible.builtin.command:
15-
argv:
16-
- loginctl
17-
- enable-linger
18-
- tmachine
19-
changed_when: false
20-
21-
- name: Resolve tmachine UID
22-
ansible.builtin.command:
23-
argv:
24-
- id
25-
- -u
26-
- tmachine
27-
changed_when: false
28-
register: tmachine_uid
29-
3012
- name: Start tmachine user manager
31-
become: true
32-
ansible.builtin.systemd_service:
33-
name: "user@{{ tmachine_uid.stdout }}.service"
34-
state: started
13+
ansible.builtin.include_role:
14+
name: tmachine_user_manager
3515

3616
- name: Enable rootless Podman socket
3717
become: true
@@ -43,5 +23,5 @@
4323
state: started
4424
environment:
4525
HOME: /home/tmachine
46-
XDG_RUNTIME_DIR: "/run/user/{{ tmachine_uid.stdout }}"
47-
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ tmachine_uid.stdout }}/bus"
26+
XDG_RUNTIME_DIR: /run/user/1000
27+
DBUS_SESSION_BUS_ADDRESS: unix:path=/run/user/1000/bus

tests/ansible/roles/openshell_client/tasks/main.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
---
5-
- name: Register OpenShell gateway for tmachine test client
5+
- name: Register OpenShell gateway for test client
66
ansible.builtin.command:
77
argv:
8-
- /usr/local/bin/openshell
8+
- openshell
99
- gateway
1010
- add
11-
- http://127.0.0.1:17670
11+
- "{{ openshell_client_gateway_endpoint | default('http://127.0.0.1:17670') }}"
1212
- --local
1313
- --name
14-
- tmachine
14+
- "{{ openshell_client_gateway_name | default('tmachine') }}"

0 commit comments

Comments
 (0)