Skip to content

test(tmachine): give guest tests a way to stop and start the gateway #4465

Open

Description

@politerealism

User Story

As a contributor migrating Podman e2e coverage into tmachine, I want a test running in the guest to stop, start and restart the gateway without wrapper-owned metadata, so restart and recovery behavior is exercised on every driver instead of being excluded or silently skipped.

Problem Statement

Tests that need to restart the gateway can't run in the tmachine guest today.

  • podman_gateway_start, podman_corporate_proxy and local_driver_token_restart are in podmanE2eFollowUpBinaries in tests/artifacts.nix. The comment there says the corporate-proxy and gateway-start binaries "self-skip without wrapper-owned gateway metadata", so they are excluded to avoid false passes.
  • These tests get gateway control from ManagedGateway::from_env(), which only exists when the e2e wrapper started the gateway. In the guest it returns nothing and the test prints "Skipping" and passes.
  • tmachine can already restart the gateway, but only at provisioning time, from Ansible (for example userns-profile.yaml). A running test has no handle for it.
  • The archived tests run as the unprivileged tmachine user. That user has passwordless sudo in the guest, so privilege isn't the blocker. Knowing how to reach the gateway is.

How the gateway runs in the guest today, as far as I can tell:

Profile Unit Runs as Control
Playbook-provisioned, rootful Podman system unit openshell-gateway.service root systemctl as root
Playbook-provisioned, rootless Podman system unit openshell-gateway.service tmachine systemctl as root
Packaged (RPM/DEB) user unit, scope: user the gateway user, with XDG_RUNTIME_DIR set systemctl --user as that user

The Podman e2e archive playbook uses the first two. The packaged shape differs in unit scope, which a test shouldn't have to know.

RFC 0016 (#3460) puts restart and upgrade continuity in a later "disruption" phase and defers the harness design. It also says to separate portable recovery assertions from environment-specific disruption actuators. This issue is a small step in that direction, not the full harness.

Impact / Why This Matters

  • Restart behavior is a public contract (RFC 0016 lists continuity across gateway restarts in conformance), but the tests that cover it for Podman don't run in CI's tmachine lane.
  • Those tests are part of what keeps the Podman exclusion list from shrinking. Three of the entries are there because of this, alongside others excluded for different reasons.
  • Upgrade tests (ci(qualification): add reusable N-to-N+1 upgrade testsuite #2975) will need the same capability, so the first piece built for restarts could be reused there.
  • Workaround today: the wrapper lane (e2e:podman:ci) runs a hand-picked allowlist with a wrapper-managed gateway. That isn't the tmachine lane and doesn't cover rootful or the package install paths.

Proposed Design

Add a small actuator interface to the shared conformance library:

  • A test asks to stop, start or restart the gateway and waits for it to be healthy. It doesn't see env vars, unit names or systemctl.
  • One implementation for the tmachine guest hides the system-unit versus user-unit difference and the rootful versus rootless difference. The playbook that provisions the gateway already knows the unit name, scope, run-as user and UID, so it could write them to a small descriptor file at a fixed guest path, and the implementation reads it and builds the right systemctl call (using the guest's existing passwordless sudo). That keeps one source of truth and no extra script to maintain.
  • The wrapper keeps its own implementation of the same interface, so the same test runs in both places.
  • Scope stays at restart control. Fault injection, upgrade orchestration and anything about the full disruption harness stays in the later phase.

Once that exists, the restart tests can move behind it, one at a time.

A test that depends on environment variables to find its gateway is hard to reuse across targets. The interface is meant to keep that detail in the actuator instead of in each test.

Alternatives Considered

  • Wait for the full disruption harness. Cleaner in theory, but it has no design or timeline yet, and restart tests stay excluded in the meantime.
  • Provide wrapper-style metadata in the guest through env vars. Smallest change, but it keeps the pattern tests shouldn't depend on and would need a second copy of that logic per profile.
  • Have each test shell out to systemctl itself. Works, but duplicates the system/user and rootful/rootless branching in every test.
  • Run restart tests only on the wrapper lane. Keeps coverage, but leaves rootful and package-install paths without it.

Open Questions

  • Should this live as a small library piece now, or be folded into the disruption harness design?
  • Should the guest implementation read a playbook-written descriptor (my preference, since the playbooks already own those values), detect the unit on its own, or use a helper script?
  • I'm happy to write up the broader disruption design (upgrades, fault injection, other drivers) as a follow-up, as an addition to RFC 0016 or a short design doc, if that would help. This issue is meant to stay small and give that design a first, concrete piece to build on.
  • Which of the three excluded tests should move first? local_driver_token_restart is VM-specific and may not fit.
  • After a gateway restart, should running Podman sandboxes keep running, or stop as they do today? The restart tests assert current behavior, so any change there changes what they check.

Acceptance Criteria

  • A test in the tmachine guest can stop, start and restart the gateway and wait for health, on rootless and rootful Podman.
  • At least one of the restart tests runs in the tmachine lane, and its entry is removed from podmanE2eFollowUpBinaries.
  • A test that can't reach the actuator fails or is listed as excluded. It doesn't silently pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions