feat(agent): attach to active X11 session for the desktop tab (VA-86) #93

Merged
David merged 1 commit from feat/VA-86-x11-session-attach into main 2026-06-30 23:00:01 +02:00
Owner

What

Extends the root system service's active-session discovery (VA-84) to also drive an X11 session, completing the desktop tab's X11 support. Builds on VA-84, which is merged to main (PR #89).

Why this is small

The X11-vs-Wayland selection in the KVM crate is already environment-driven: vervain_agent_kvm::wayland::is_wayland_session() keys off WAYLAND_DISPLAY/XDG_SESSION_TYPE, and the X11 capture (x11rb::connect(None)) and XTEST input both read DISPLAY/XAUTHORITY from the environment. VA-84 already discovers the active seat0 session and exports the Wayland addressing. So the only missing piece for X11 is resolving and exporting DISPLAY/XAUTHORITY. The change is therefore confined to crates/vervain-agent/src/active_session.rs.

Changes

  • parse_session_props now reads logind's Display= and Leader= properties; discover requests them from loginctl show-session.
  • For an X11 active session, discover resolves DISPLAY and XAUTHORITY and export_env exports them. An X11 attach sets XDG_SESSION_TYPE=x11 and leaves WAYLAND_DISPLAY unset, so is_wayland_session() returns false and the existing X11 capture + XTEST path is selected automatically (AC2). Wayland sessions are unchanged.
  • Resolution precedence (new pure, unit-tested resolve_x11): DISPLAY from logind's Display property, falling back to the session leader's /proc/<pid>/environ; XAUTHORITY from the leader's environ, falling back to the owning user's ~/.Xauthority (home resolved from /etc/passwd, file existence checked). As root all of these are readable on disk.
  • Clean degradation (AC for no-crash): when no XAUTHORITY resolves, DISPLAY is still exported and the desktop tab returns the existing NotAvailable status rather than crashing.
  • New pure helpers environ_lookup, parse_passwd_home, resolve_x11 plus thin I/O wrappers read_proc_environ, home_for_uid. Module docs, attach_and_log, and the README desktop-tab line updated.

Acceptance criteria

  • On an X11 active session, a root system install drives the desktop tab via the X11 capture + XTEST path (mechanism wired; live mouse/keyboard injection on a real X11 host is manual host validation, matching the VA-82/VA-83/VA-84 desktop-tab pattern - no X11 host in CI).
  • Session-type detection picks the X11 path for X11 sessions and the VA-84 Wayland path for Wayland sessions (environment-driven selection; covered by resolve_x11 and session-type unit tests).
  • just check and the Docker build pass.

Tests / checks

  • 7 new unit tests (17 total in the active_session module), all green.
  • just check (fmt, clippy --deny warnings, test) passes.
  • The authoritative oci-build/check.Dockerfile build passes locally, including the Windows cross-check and the swtpm TPM test (also runs the pre-commit hook on commit).
## What Extends the root system service's active-session discovery (VA-84) to also drive an **X11** session, completing the desktop tab's X11 support. Builds on VA-84, which is merged to main (PR #89). ## Why this is small The X11-vs-Wayland selection in the KVM crate is already environment-driven: `vervain_agent_kvm::wayland::is_wayland_session()` keys off `WAYLAND_DISPLAY`/`XDG_SESSION_TYPE`, and the X11 capture (`x11rb::connect(None)`) and XTEST input both read `DISPLAY`/`XAUTHORITY` from the environment. VA-84 already discovers the active seat0 session and exports the Wayland addressing. So the only missing piece for X11 is resolving and exporting `DISPLAY`/`XAUTHORITY`. The change is therefore confined to `crates/vervain-agent/src/active_session.rs`. ## Changes - `parse_session_props` now reads logind's `Display=` and `Leader=` properties; `discover` requests them from `loginctl show-session`. - For an X11 active session, `discover` resolves `DISPLAY` and `XAUTHORITY` and `export_env` exports them. An X11 attach sets `XDG_SESSION_TYPE=x11` and leaves `WAYLAND_DISPLAY` unset, so `is_wayland_session()` returns false and the existing X11 capture + XTEST path is selected automatically (AC2). Wayland sessions are unchanged. - Resolution precedence (new pure, unit-tested `resolve_x11`): `DISPLAY` from logind's `Display` property, falling back to the session leader's `/proc/<pid>/environ`; `XAUTHORITY` from the leader's environ, falling back to the owning user's `~/.Xauthority` (home resolved from `/etc/passwd`, file existence checked). As root all of these are readable on disk. - Clean degradation (AC for no-crash): when no `XAUTHORITY` resolves, `DISPLAY` is still exported and the desktop tab returns the existing `NotAvailable` status rather than crashing. - New pure helpers `environ_lookup`, `parse_passwd_home`, `resolve_x11` plus thin I/O wrappers `read_proc_environ`, `home_for_uid`. Module docs, `attach_and_log`, and the README desktop-tab line updated. ## Acceptance criteria - [x] On an X11 active session, a root system install drives the desktop tab via the X11 capture + XTEST path (mechanism wired; live mouse/keyboard injection on a real X11 host is manual host validation, matching the VA-82/VA-83/VA-84 desktop-tab pattern - no X11 host in CI). - [x] Session-type detection picks the X11 path for X11 sessions and the VA-84 Wayland path for Wayland sessions (environment-driven selection; covered by `resolve_x11` and session-type unit tests). - [x] `just check` and the Docker build pass. ## Tests / checks - 7 new unit tests (17 total in the `active_session` module), all green. - `just check` (fmt, clippy `--deny warnings`, test) passes. - The authoritative `oci-build/check.Dockerfile` build passes locally, including the Windows cross-check and the swtpm TPM test (also runs the pre-commit hook on commit).
feat(agent): attach to active X11 session for the desktop tab
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 15m35s
Create release / Create release from merged PR (pull_request) Has been skipped
7f0978e200
Extend the root system service's active-session discovery (VA-84) to also drive an X11 session. For an X11 active session, discovery now resolves DISPLAY and the session's X authority file and exports DISPLAY/XAUTHORITY, so the desktop tab's existing X11 capture (x11rb::connect, which reads both vars) and XTEST input path reach the logged-in user's session. As root these are readable on disk.

Selection between the X11 and Wayland paths stays environment-driven: an X11 attach sets XDG_SESSION_TYPE=x11 and leaves WAYLAND_DISPLAY unset, so is_wayland_session() returns false and the X11 path is chosen; a Wayland session is unchanged.

DISPLAY comes from logind's session Display property (falling back to the session leader's /proc/<pid>/environ); XAUTHORITY comes from the leader's environ (falling back to the owning user's ~/.Xauthority, resolved from /etc/passwd). When neither resolves, DISPLAY is still exported and the desktop tab degrades to a clear NotAvailable status rather than crashing.

Adds pure, unit-tested helpers (environ_lookup, parse_passwd_home, resolve_x11) and parses the logind Display/Leader properties; 7 new tests. just check (fmt, clippy --deny warnings, test) and the oci-build/check.Dockerfile build (incl. the Windows cross-check and TPM test) pass.

#VA-86

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
David scheduled this pull request to auto merge when all checks succeed 2026-06-30 22:50:13 +02:00
David merged commit 77cdbd9e76 into main 2026-06-30 23:00:01 +02:00
David deleted branch feat/VA-86-x11-session-attach 2026-06-30 23:00:01 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-agent!93
No description provided.