From ef9adc2f79c2f6161cf4b1625a4c60e8c8958f46 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Fri, 2 Oct 2026 09:06:40 +0200 Subject: [PATCH] test(tmachine): support package-installed Podman driver suites Signed-off-by: Evan Lezar --- .github/workflows/branch-e2e.yml | 6 +- CI.md | 7 +- TESTING.md | 22 +++- tasks/test.toml | 7 ++ tests/ansible/gateway_context_test.py | 115 ++++++++++++++++++ .../podman/default-userns-baseline.yaml | 6 +- .../ansible/playbooks/drivers/podman/e2e.yaml | 55 ++++----- .../playbooks/drivers/podman/tests.yaml | 39 ++---- .../drivers/podman/userns-profile.yaml | 22 ++-- .../roles/openshell_client/tasks/main.yaml | 14 +++ .../tasks/main.yaml | 3 + .../openshell_test_gateway/tasks/journal.yaml | 22 ++++ .../openshell_test_gateway/tasks/main.yaml | 42 +++++++ .../openshell_test_gateway/tasks/publish.yaml | 23 ++++ .../openshell_test_gateway/tasks/restart.yaml | 35 ++++++ 15 files changed, 339 insertions(+), 79 deletions(-) create mode 100644 tests/ansible/gateway_context_test.py create mode 100644 tests/ansible/roles/openshell_test_gateway/tasks/journal.yaml create mode 100644 tests/ansible/roles/openshell_test_gateway/tasks/main.yaml create mode 100644 tests/ansible/roles/openshell_test_gateway/tasks/publish.yaml create mode 100644 tests/ansible/roles/openshell_test_gateway/tasks/restart.yaml diff --git a/.github/workflows/branch-e2e.yml b/.github/workflows/branch-e2e.yml index eb903a55fc..a33cbc8c3b 100644 --- a/.github/workflows/branch-e2e.yml +++ b/.github/workflows/branch-e2e.yml @@ -303,9 +303,9 @@ jobs: integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }} test-matrix: >- [ - {"environment":"fedora-podman-rootful","installer":"binaries","testsuite":"driver-podman"}, - {"environment":"fedora-podman-rootless","installer":"binaries","testsuite":"e2e-podman"}, - {"environment":"fedora-podman-rootless","installer":"binaries","testsuite":"driver-podman"} + {"environment":"fedora-podman-rootful","installer":"rpm","testsuite":"driver-podman"}, + {"environment":"fedora-podman-rootless","installer":"rpm","testsuite":"e2e-podman"}, + {"environment":"fedora-podman-rootless","installer":"rpm","testsuite":"driver-podman"} ] docker-e2e: diff --git a/CI.md b/CI.md index c5a19e1f08..5bf9425ed8 100644 --- a/CI.md +++ b/CI.md @@ -77,9 +77,10 @@ runs without optional E2E labels. Core integration qualification builds and inst the DEB on Ubuntu with Docker and installs the CLI and gateway RPMs on Fedora with rootful and rootless Podman. These lanes run conformance using the matching runtime images. Release Dev and Release Tag use the same package installers. -Fedora provider-refresh tests also use RPMs. The Podman driver-specific suites -retain the binary installer because their fixtures configure its system service, -local HTTP gateway, and CLI path. The manual Integration Tests workflow defaults +Fedora provider-refresh tests also use RPMs. The Podman driver-specific branch +lanes use RPMs for rootful and rootless user-namespace comparisons and rootless +Podman E2E. Their fixtures use the installed gateway's registration, active +configuration, and service context. The manual Integration Tests workflow defaults to the package installers and downloads the packages selected by its matrix. Three opt-in labels enable the long-running E2E suites: diff --git a/TESTING.md b/TESTING.md index a1c2f9476e..e541b924d1 100644 --- a/TESTING.md +++ b/TESTING.md @@ -290,10 +290,28 @@ Run the portable subset in a disposable rootless Podman guest: ```shell nix run .#build-artifacts -nix run .#tmachine -- test fedora-podman-rootless binaries e2e-podman -nix run .#tmachine -- test fedora-podman-rootless binaries driver-podman +nix run .#tmachine -- test fedora-podman-rootless rpm e2e-podman +nix run .#tmachine -- test fedora-podman-rootless rpm driver-podman ``` +The driver suites also support the `binaries` installer. The shared installer +roles save the active gateway configuration, registration name, service scope, +service owner, and network name in `/var/lib/openshell-test/gateway.yaml`. +Suites resolve `openshell` from PATH and use that registration, including the +packaged gateway's HTTPS client credentials. Namespace fixtures modify the +active qualification configuration and restart its system or user service. +Failure diagnostics select the matching journal unit and user ID. Missing +metadata or credentials fail the run; suites do not replace package setup with +an HTTP gateway. Ansible sources participate in tmachine's installation cache +hash, so older cached installations are rebuilt with this metadata. + +The `driver-podman` suite supports rootful and rootless Podman. The +`e2e-podman` archive requires rootless Podman for its host workload fixtures. +DEB and RPM installers share the gateway role; available environments pair +DEB with Ubuntu/Docker and RPM with Fedora/Podman. A DEB/Podman run requires an +Ubuntu Podman environment. Run `mise run test:tmachine-gateway` to check the +binary and package service contexts without launching a guest. + Print the exact tmachine archive selection as a shell `PODMAN_CI_TESTS` array: ```shell diff --git a/tasks/test.toml b/tasks/test.toml index 8a90f3c084..6cda74c656 100644 --- a/tasks/test.toml +++ b/tasks/test.toml @@ -16,6 +16,7 @@ depends = [ "test:e2e-image-overrides", "test:gateway-config", "test:packaging-assets", + "test:tmachine-gateway", "test:qualification-summary", "test:codex-security-release-range", "test:docs-website", @@ -307,3 +308,9 @@ description = "Test generated local gateway TOML without starting a runtime" run = "bash tasks/scripts/test-gateway-config.sh" run_windows = "echo Skipping test:gateway-config: Unix gateway scripts do not apply on Windows." hide = true + +["test:tmachine-gateway"] +description = "Check tmachine binary and package gateway service contexts" +run = "ANSIBLE_LOCAL_TEMP=/tmp/openshell-ansible-local uv run --no-project --with pytest --with ansible-core --with pyyaml pytest tests/ansible/gateway_context_test.py" +run_windows = "echo Skipping test:tmachine-gateway: Ansible gateway qualification runs on Unix hosts." +hide = true diff --git a/tests/ansible/gateway_context_test.py b/tests/ansible/gateway_context_test.py new file mode 100644 index 0000000000..af9d3fe5ba --- /dev/null +++ b/tests/ansible/gateway_context_test.py @@ -0,0 +1,115 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Check installer/service combinations without requiring a Linux guest.""" + +from pathlib import Path + +import pytest +import yaml +from ansible.template import Templar, trust_as_template + +ROOT = Path(__file__).resolve().parents[2] +ROLES = ROOT / "tests/ansible/roles" + + +def tasks(role, name="main.yaml"): + return yaml.safe_load((ROLES / role / "tasks" / name).read_text()) + + +def render(value, variables): + if isinstance(value, dict): + return {key: render(item, variables) for key, item in value.items()} + if isinstance(value, list): + return [render(item, variables) for item in value] + if isinstance(value, str): + return Templar(variables=variables).template(trust_as_template(value)) + return value + + +@pytest.mark.parametrize("installer", ["binaries", "deb", "rpm"]) +@pytest.mark.parametrize("rootless", [False, True]) +def test_installed_gateway_service_context(installer, rootless): + variables = { + "openshell_gateway_user": "tmachine" if rootless else "root", + "openshell_gateway_home": "/home/tmachine" if rootless else "/root", + "openshell_gateway_uid": "1000" if rootless else "0", + } + packaged = installer != "binaries" + if packaged: + # Use the actual package registration inputs, including HTTPS. + registration = tasks("openshell_packaged_gateway")[-1] + variables.update(registration["vars"]) + assert variables["openshell_client_gateway_endpoint"].startswith("https://") + context = render( + tasks("openshell_client")[-1]["vars"]["openshell_test_gateway_context"], + variables, + ) + assert context["name"] == ("openshell" if packaged else "tmachine") + assert context["config_path"] == ( + "/var/lib/openshell-qualification/gateway.toml" + if packaged + else "/etc/openshell/gateway.toml" + ) + assert context["service_scope"] == ("user" if packaged else "system") + assert context["service_user"] == ("tmachine" if packaged and rootless else "root") + assert str(context["service_uid"]) == ("1000" if packaged and rootless else "0") + assert context["network_name"] == ("openshell" if packaged else "tmachine") + variables["openshell_test_gateway"] = context + + environment = render( + tasks("openshell_test_gateway")[-1]["ansible.builtin.set_fact"][ + "openshell_test_gateway_service_environment" + ], + variables, + ) + assert environment["HOME"] == ( + "/home/tmachine" if packaged and rootless else "/root" + ) + assert environment["XDG_RUNTIME_DIR"] == f"/run/user/{context['service_uid']}" + assert environment["DBUS_SESSION_BUS_ADDRESS"] == ( + f"unix:path=/run/user/{context['service_uid']}/bus" + ) + + restart = tasks("openshell_test_gateway", "restart.yaml")[0]["block"][0] + assert render(restart["become_user"], variables) == context["service_user"] + assert ( + render(restart["ansible.builtin.systemd_service"]["scope"], variables) + == (context["service_scope"]) + ) + journal = render( + tasks("openshell_test_gateway", "journal.yaml")[0]["ansible.builtin.command"][ + "argv" + ], + variables, + ) + if packaged: + assert "_SYSTEMD_USER_UNIT=openshell-gateway.service" in journal + assert f"_UID={context['service_uid']}" in journal + assert "--unit" not in journal + else: + assert journal[1:3] == ["--unit", "openshell-gateway.service"] + + +def test_missing_gateway_metadata_has_no_binary_fallback(): + metadata_task = tasks("openshell_test_gateway")[0] + assert metadata_task["ansible.builtin.slurp"]["src"] == ( + "/var/lib/openshell-test/gateway.yaml" + ) + assert "ignore_errors" not in metadata_task + assert "failed_when" not in metadata_task + + +def test_fixture_targets_podman_table_in_active_config(): + play = yaml.safe_load( + ( + ROOT / "tests/ansible/playbooks/drivers/podman/userns-profile.yaml" + ).read_text() + )[0] + fixture = next( + task["ansible.builtin.blockinfile"] + for task in play["tasks"] + if "ansible.builtin.blockinfile" in task + ) + assert fixture["path"] == "{{ openshell_test_gateway.config_path }}" + assert fixture["insertafter"] == r"^\[openshell\.drivers\.podman\]$" diff --git a/tests/ansible/playbooks/drivers/podman/default-userns-baseline.yaml b/tests/ansible/playbooks/drivers/podman/default-userns-baseline.yaml index 7356ae3c5e..2542741dd8 100644 --- a/tests/ansible/playbooks/drivers/podman/default-userns-baseline.yaml +++ b/tests/ansible/playbooks/drivers/podman/default-userns-baseline.yaml @@ -12,6 +12,10 @@ - name: Wait for SSH ansible.builtin.wait_for_connection: + - name: Resolve installed gateway context + ansible.builtin.include_role: + name: openshell_test_gateway + - name: Detect tmachine container runtime ansible.builtin.include_role: name: tmachine_container_runtime @@ -38,7 +42,7 @@ - name: Read OpenShell gateway configuration become: true ansible.builtin.slurp: - src: /etc/openshell/gateway.toml + src: "{{ openshell_test_gateway.config_path }}" register: openshell_gateway_config - name: Require unconfigured Podman user namespaces diff --git a/tests/ansible/playbooks/drivers/podman/e2e.yaml b/tests/ansible/playbooks/drivers/podman/e2e.yaml index e839a2cfff..e20d120d68 100644 --- a/tests/ansible/playbooks/drivers/podman/e2e.yaml +++ b/tests/ansible/playbooks/drivers/podman/e2e.yaml @@ -11,6 +11,21 @@ - name: Wait for SSH ansible.builtin.wait_for_connection: + - name: Resolve installed gateway context + ansible.builtin.include_role: + name: openshell_test_gateway + + - name: Detect tmachine container runtime + ansible.builtin.include_role: + name: tmachine_container_runtime + + - name: Require rootless Podman for the E2E workload fixtures + ansible.builtin.assert: + that: + - tmachine_container_runtime_name == 'podman' + - tmachine_container_runtime_is_rootless + fail_msg: The Podman E2E archive requires the rootless Podman environment + - name: Create Podman E2E test directory become: true ansible.builtin.file: @@ -46,17 +61,7 @@ - "{{ podman_e2e_test_root }}/openshell-e2e-python-dev.tar" environment: HOME: /home/tmachine - XDG_RUNTIME_DIR: /run/user/1000 - - - name: Remove any previous OpenShell gateway registration - ansible.builtin.command: - argv: [/usr/local/bin/openshell, gateway, remove, tmachine] - changed_when: false - failed_when: false - - - name: Register the configured OpenShell gateway - ansible.builtin.command: - argv: [/usr/local/bin/openshell, gateway, add, http://127.0.0.1:17670, --local, --name, tmachine] + XDG_RUNTIME_DIR: "/run/user/{{ tmachine_container_runtime_tmachine_uid.stdout }}" - name: Run Podman E2E archive tests ansible.builtin.command: @@ -73,16 +78,16 @@ - --no-fail-fast environment: CONTAINER_ENGINE: podman - CONTAINER_HOST: unix:///run/user/1000/podman/podman.sock + CONTAINER_HOST: "unix://{{ tmachine_container_runtime_socket }}" HOME: /home/tmachine - OPENSHELL_BIN: /usr/local/bin/openshell + OPENSHELL_BIN: "{{ openshell_test_cli.stdout }}" OPENSHELL_E2E_CONTAINER_ENGINE_UNSET_XDG_CONFIG_HOME: "1" OPENSHELL_E2E_DRIVER: podman - OPENSHELL_E2E_NETWORK_NAME: tmachine + OPENSHELL_E2E_NETWORK_NAME: "{{ openshell_test_gateway.network_name }}" OPENSHELL_E2E_SANDBOX_NAMESPACE: tmachine - OPENSHELL_GATEWAY: tmachine - OPENSHELL_PODMAN_SOCKET: /run/user/1000/podman/podman.sock - XDG_RUNTIME_DIR: /run/user/1000 + OPENSHELL_GATEWAY: "{{ openshell_test_gateway.name }}" + OPENSHELL_PODMAN_SOCKET: "{{ tmachine_container_runtime_socket }}" + XDG_RUNTIME_DIR: "/run/user/{{ tmachine_container_runtime_tmachine_uid.stdout }}" register: podman_e2e_test_result changed_when: false failed_when: false @@ -95,18 +100,10 @@ ansible.builtin.debug: var: podman_e2e_test_result.stdout_lines - - name: Capture OpenShell gateway journal after Podman E2E test failure - become: true - ansible.builtin.command: - argv: [journalctl, --unit, openshell-gateway.service, --no-pager, --lines, "200"] - changed_when: false - failed_when: false - when: podman_e2e_test_result.rc != 0 - register: podman_e2e_gateway_journal - - - name: Show OpenShell gateway journal after Podman E2E test failure - ansible.builtin.debug: - var: podman_e2e_gateway_journal.stdout_lines + - name: Collect installed gateway diagnostics after test failure + ansible.builtin.include_role: + name: openshell_test_gateway + tasks_from: journal.yaml when: podman_e2e_test_result.rc != 0 - name: Require Podman E2E archive success diff --git a/tests/ansible/playbooks/drivers/podman/tests.yaml b/tests/ansible/playbooks/drivers/podman/tests.yaml index abe2f6e553..11390fb57f 100644 --- a/tests/ansible/playbooks/drivers/podman/tests.yaml +++ b/tests/ansible/playbooks/drivers/podman/tests.yaml @@ -12,6 +12,10 @@ - name: Wait for SSH ansible.builtin.wait_for_connection: + - name: Resolve installed gateway context + ansible.builtin.include_role: + name: openshell_test_gateway + - name: Detect tmachine container runtime ansible.builtin.include_role: name: tmachine_container_runtime @@ -39,21 +43,12 @@ owner: tmachine group: tmachine - - name: Remove any previous OpenShell gateway registration - ansible.builtin.command: - argv: [/usr/local/bin/openshell, gateway, remove, tmachine] - changed_when: false - failed_when: false - - - name: Register the configured OpenShell gateway - ansible.builtin.command: - argv: [/usr/local/bin/openshell, gateway, add, http://127.0.0.1:17670, --local, --name, tmachine] - - name: Run Podman archive tests ansible.builtin.command: argv: [cargo-nextest, nextest, run, --archive-file, "{{ podman_test_root }}/tests.tar.zst", --workspace-remap, "{{ podman_test_root }}", --no-capture] environment: - OPENSHELL_BIN: /usr/local/bin/openshell + OPENSHELL_GATEWAY: "{{ openshell_test_gateway.name }}" + OPENSHELL_BIN: "{{ openshell_test_cli.stdout }}" OPENSHELL_TEST_INPUT_DIR: "{{ podman_test_input_dir }}" OPENSHELL_PODMAN_TEST_IMAGE: "{{ openshell_podman_test_image | default('') }}" register: podman_test_result @@ -68,24 +63,10 @@ ansible.builtin.debug: var: podman_test_result.stdout_lines - - name: Capture OpenShell gateway journal after Podman test failure - become: true - ansible.builtin.command: - argv: - - journalctl - - --unit - - openshell-gateway.service - - --no-pager - - --lines - - "200" - changed_when: false - failed_when: false - when: podman_test_result.rc != 0 - register: podman_gateway_journal - - - name: Show OpenShell gateway journal after Podman test failure - ansible.builtin.debug: - var: podman_gateway_journal.stdout_lines + - name: Collect installed gateway diagnostics after test failure + ansible.builtin.include_role: + name: openshell_test_gateway + tasks_from: journal.yaml when: podman_test_result.rc != 0 - name: Discover Podman containers after test failure diff --git a/tests/ansible/playbooks/drivers/podman/userns-profile.yaml b/tests/ansible/playbooks/drivers/podman/userns-profile.yaml index a3071c2833..64880a0aa4 100644 --- a/tests/ansible/playbooks/drivers/podman/userns-profile.yaml +++ b/tests/ansible/playbooks/drivers/podman/userns-profile.yaml @@ -12,6 +12,10 @@ - name: Wait for SSH ansible.builtin.wait_for_connection: + - name: Resolve installed gateway context + ansible.builtin.include_role: + name: openshell_test_gateway + - name: Detect tmachine container runtime ansible.builtin.include_role: name: tmachine_container_runtime @@ -38,21 +42,15 @@ - name: Apply the Podman user-namespace fixture become: true ansible.builtin.blockinfile: - path: /etc/openshell/gateway.toml + path: "{{ openshell_test_gateway.config_path }}" + insertafter: '^\[openshell\.drivers\.podman\]$' marker: "# {mark} OpenShell Podman userns test fixture" block: "{{ lookup('ansible.builtin.file', podman_userns_config) | trim }}" - - name: Restart OpenShell gateway with the Podman user-namespace fixture - become: true - ansible.builtin.systemd_service: - name: openshell-gateway.service - state: restarted - - - name: Wait for the configured OpenShell gateway - ansible.builtin.wait_for: - host: 127.0.0.1 - port: 17670 - timeout: 60 + - name: Restart installed gateway with the Podman user-namespace fixture + ansible.builtin.include_role: + name: openshell_test_gateway + tasks_from: restart.yaml - name: Capture direct Podman user-namespace mapping become: true diff --git a/tests/ansible/roles/openshell_client/tasks/main.yaml b/tests/ansible/roles/openshell_client/tasks/main.yaml index 6586f23ac2..8a60195fa1 100644 --- a/tests/ansible/roles/openshell_client/tasks/main.yaml +++ b/tests/ansible/roles/openshell_client/tasks/main.yaml @@ -12,3 +12,17 @@ - --local - --name - "{{ openshell_client_gateway_name | default('tmachine') }}" + +- name: Publish test gateway context + ansible.builtin.include_role: + name: openshell_test_gateway + tasks_from: publish.yaml + vars: + openshell_test_gateway_context: + name: "{{ openshell_client_gateway_name | default('tmachine') }}" + config_path: "{{ openshell_client_gateway_config_path | default('/etc/openshell/gateway.toml') }}" + service_scope: "{{ openshell_client_gateway_service_scope | default('system') }}" + service_user: "{{ openshell_gateway_user if openshell_client_gateway_service_scope | default('system') == 'user' else 'root' }}" + service_home: "{{ openshell_gateway_home if openshell_client_gateway_service_scope | default('system') == 'user' else '/root' }}" + service_uid: "{{ openshell_gateway_uid if openshell_client_gateway_service_scope | default('system') == 'user' else '0' }}" + network_name: "{{ openshell_client_gateway_network_name | default('tmachine') }}" diff --git a/tests/ansible/roles/openshell_packaged_gateway/tasks/main.yaml b/tests/ansible/roles/openshell_packaged_gateway/tasks/main.yaml index a3e04f52bf..a50e238150 100644 --- a/tests/ansible/roles/openshell_packaged_gateway/tasks/main.yaml +++ b/tests/ansible/roles/openshell_packaged_gateway/tasks/main.yaml @@ -121,3 +121,6 @@ vars: openshell_client_gateway_endpoint: https://127.0.0.1:17670 openshell_client_gateway_name: openshell + openshell_client_gateway_config_path: /var/lib/openshell-qualification/gateway.toml + openshell_client_gateway_service_scope: user + openshell_client_gateway_network_name: openshell diff --git a/tests/ansible/roles/openshell_test_gateway/tasks/journal.yaml b/tests/ansible/roles/openshell_test_gateway/tasks/journal.yaml new file mode 100644 index 0000000000..2e5d7874f9 --- /dev/null +++ b/tests/ansible/roles/openshell_test_gateway/tasks/journal.yaml @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +--- +# Root's packaged user unit can log to the system journal. Match journal +# fields instead of --user so both root and tmachine user units are captured. +- name: Capture installed gateway journal + become: true + ansible.builtin.command: + argv: >- + {{ ['journalctl'] + + (['_SYSTEMD_USER_UNIT=openshell-gateway.service', '_UID=' ~ openshell_test_gateway.service_uid] + if openshell_test_gateway.service_scope == 'user' + else ['--unit', 'openshell-gateway.service']) + + ['--no-pager', '--lines', '200'] }} + register: openshell_test_gateway_journal + changed_when: false + failed_when: false + +- name: Show installed gateway journal + ansible.builtin.debug: + var: openshell_test_gateway_journal.stdout_lines diff --git a/tests/ansible/roles/openshell_test_gateway/tasks/main.yaml b/tests/ansible/roles/openshell_test_gateway/tasks/main.yaml new file mode 100644 index 0000000000..55d18b310e --- /dev/null +++ b/tests/ansible/roles/openshell_test_gateway/tasks/main.yaml @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +--- +- name: Read installed gateway context + ansible.builtin.slurp: + src: /var/lib/openshell-test/gateway.yaml + register: openshell_test_gateway_metadata + +- name: Load installed gateway context + ansible.builtin.set_fact: + openshell_test_gateway: "{{ (openshell_test_gateway_metadata.content | b64decode | from_yaml).openshell_test_gateway }}" + +- name: Validate installed gateway context + ansible.builtin.assert: + that: + - openshell_test_gateway.service_scope in ['system', 'user'] + - openshell_test_gateway.config_path is match('^/') + - openshell_test_gateway.name | length > 0 + +- name: Resolve installed OpenShell CLI from PATH + ansible.builtin.command: + argv: [/bin/sh, -c, command -v openshell] + register: openshell_test_cli + changed_when: false + +- name: Check active gateway configuration + become: true + ansible.builtin.stat: + path: "{{ openshell_test_gateway.config_path }}" + register: openshell_test_gateway_config + +- name: Require active gateway configuration + ansible.builtin.assert: + that: [openshell_test_gateway_config.stat.isreg | default(false)] + +- name: Resolve gateway service environment + ansible.builtin.set_fact: + openshell_test_gateway_service_environment: + HOME: "{{ openshell_test_gateway.service_home }}" + XDG_RUNTIME_DIR: "/run/user/{{ openshell_test_gateway.service_uid }}" + DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ openshell_test_gateway.service_uid }}/bus" diff --git a/tests/ansible/roles/openshell_test_gateway/tasks/publish.yaml b/tests/ansible/roles/openshell_test_gateway/tasks/publish.yaml new file mode 100644 index 0000000000..1e04d266c2 --- /dev/null +++ b/tests/ansible/roles/openshell_test_gateway/tasks/publish.yaml @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +--- +# Installation and suite execution are separate Ansible processes. Persist only +# non-secret metadata; the CLI keeps registration and mTLS credentials itself. +- name: Create test gateway metadata directory + become: true + ansible.builtin.file: + path: /var/lib/openshell-test + state: directory + owner: root + group: root + mode: "0755" + +- name: Publish installed gateway context + become: true + ansible.builtin.copy: + dest: /var/lib/openshell-test/gateway.yaml + owner: root + group: root + mode: "0644" + content: "{{ {'openshell_test_gateway': openshell_test_gateway_context} | to_nice_yaml }}" diff --git a/tests/ansible/roles/openshell_test_gateway/tasks/restart.yaml b/tests/ansible/roles/openshell_test_gateway/tasks/restart.yaml new file mode 100644 index 0000000000..56b56123f9 --- /dev/null +++ b/tests/ansible/roles/openshell_test_gateway/tasks/restart.yaml @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +--- +- name: Restart installed gateway + block: + - name: Restart gateway service with the active configuration + become: true + become_user: "{{ openshell_test_gateway.service_user }}" + ansible.builtin.systemd_service: + name: openshell-gateway.service + scope: "{{ openshell_test_gateway.service_scope }}" + state: restarted + environment: "{{ openshell_test_gateway_service_environment }}" + + - name: Wait for authenticated gateway readiness + ansible.builtin.command: + argv: ["{{ openshell_test_cli.stdout }}", gateway, info, --output, json] + environment: + OPENSHELL_GATEWAY: "{{ openshell_test_gateway.name }}" + changed_when: false + register: openshell_test_gateway_ready + retries: 30 + delay: 2 + until: >- + openshell_test_gateway_ready.rc == 0 and + (openshell_test_gateway_ready.stdout | from_json).status == 'healthy' + + rescue: + - name: Collect gateway restart diagnostics + ansible.builtin.include_tasks: journal.yaml + + - name: Report gateway restart failure + ansible.builtin.fail: + msg: Installed gateway failed to restart with the driver fixture