Skip to content

fix(garm): set XDG_RUNTIME_DIR for runner jobs - #415

Closed
cbartz wants to merge 1 commit into
mainfrom
fix/garm-runner-xdg-runtime-dir
Closed

cbartz wants to merge 1 commit into
mainfrom
fix/garm-runner-xdg-runtime-dir

Conversation

@cbartz

@cbartz cbartz commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Always prepends a snippet to the shared github_linux_charmed runner template that enables lingering for the runner user and appends XDG_RUNTIME_DIR=/run/user/<uid> to the runner .env. Per-scaleset templates derive from this template, so every scaleset gets it.

Why we need it

In agent mode, GARM starts the runner from a system service without a login session, so jobs have no XDG_RUNTIME_DIR. Tools that keep per-user state there (skopeo login, podman, buildah) then fall back to /run/containers/<uid> and fail with mkdir /run/containers: permission denied. The previous runner manager started the runner via su -, which created a session.

Test plan

  • New unit test asserting the snippet is in the charmed template (no debug-ssh connections) and precedes the base body; full garm unit suite, lint, static and complexity pass.
  • Not yet verified on a live runner: check a fresh runner's job env contains XDG_RUNTIME_DIR and skopeo login succeeds.

Review focus

  • Relies on the runner reading actions-runner/.env in agent mode (same mechanism the job-start hook uses) and on passwordless sudo for the runner user at install time.
  • Only new runners pick this up.

Checklist

  • Changes comply with the project's coding standards and guidelines (see CONTRIBUTING.md and STYLE.md)
  • CONTRIBUTING.md has been updated upon changes to the contribution/development process (e.g. changes to the way tests are run) — N/A, no process change
  • Technical author has been assigned to review the PR in case of documentation changes (usually *.md files) — N/A, changelog entry only
  • I updated docs/changelog.md with user-relevant changes
  • I used AI to assist with preparing this PR
  • I added or updated tests as needed (unit and integration)
  • If integration test modules are used: I updated the workflow configuration — N/A
  • If this PR involves a Grafana dashboard: I added a screenshot of the dashboard — N/A
  • If this PR involves Terraform: terraform fmt passes and tflint reports no errors — N/A
  • If this PR involves Rockcraft: I updated the version — N/A
  • If this PR adds/removes a charm, or changes a charm's base class, conventions, tooling, or repo structure: I updated the relevant AGENTS.md — N/A
  • If this PR changes .copilot-collections.yaml or .github/instructions/: I re-checked the AGENTS.md "12-factor divergences" guidance — N/A

GARM's agent mode starts the runner from a system service without a login
session, so jobs have no XDG_RUNTIME_DIR and skopeo/podman/buildah fall back
to the root-owned /run/containers. Enable lingering for the runner user and
export XDG_RUNTIME_DIR via the runner .env from the shared charmed template.
@cbartz
cbartz requested a lite review from Copilot October 8, 2026 14:07

decoded = result.decode()
assert decoded.startswith("#!/bin/bash\n")
assert "sudo loginctl enable-linger runner" in decoded

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runner or ubuntu?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Provisioning should fail visibly or verify the runtime directory when setup commands fail.

1 open finding
What changed in this PR

Updates GARM runner templates to configure lingering and XDG_RUNTIME_DIR for agent-mode jobs.

Changes:

  • Adds runtime-directory setup to the shared runner template.
  • Adds unit coverage for the generated snippet.
  • Documents the fix in the changelog.
File Summary
docs/​changelog.md Documents the runner environment fix.
charms/​garm/​tests/​unit/​test_garm_template.py Tests the injected template commands.
charms/​garm/​src/​garm_template.py Configures lingering and XDG_RUNTIME_DIR; setup failures are currently swallowed.

🧠 Review effort: Lite


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

# podman, buildah) fall back to root-owned /run/containers. Lingering keeps
# /run/user/<uid> alive without a session; the .env entry exports it to every job.
_RUNNER_RUNTIME_DIR_SNIPPET: typing.Final[str] = f"""\
sudo loginctl enable-linger {RUNNER_USER} || true
@cbartz

cbartz commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favour of canonical/github-runner-image-builder-operator#245. The image already enables linger for the runner user (runner is an alias of ubuntu, same UID, which answers the inline question), so it owns /run/user/<uid>; setting XDG_RUNTIME_DIR there, via a garm-agent.service drop-in, keeps the directory and the variable pointing at it together.

AI-generated message.

@cbartz cbartz closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants