randomparity / randomparity/kdive
live_vm_host requires github_runner_user but never declares it, coupling the role to the CI runner
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 26m
- Merged PRs (30d)
- 311
Description
## Problem
The `live_vm_host` role reads `github_runner_user` in roughly twenty places but never declares
it. The variable is defined only in `github_runner/defaults/main.yml:2`, and Ansible loads a
role's defaults only for roles in the play — so `live_vm_host` silently requires the
`github_runner` role to be in the same play as itself.
The practical effect: a host cannot be provisioned as a live-VM worker host without also being
turned into a GitHub Actions runner.
## Observed
Running `libvirt_stack` + `libvirt_pool_net` + `live_vm_host` against a host — the same three
roles `deploy/ansible/playbooks/runner.yml` runs, minus `github_runner`:
```
TASK [live_vm_host : Ensure the runner service account exists in kvm and libvirt] ***
fatal: FAILED! => {"changed": false, "msg": "Task failed: Finalization of task args for
'ansible.builtin.user' failed: Error while resolving value for 'name':
'github_runner_user' is undefined"}
```
It fails at the first use and every later one would fail the same way.
## Evidence
Defined in exactly one place, and not in the role that consumes it:
```
deploy/ansible/roles/github_runner/defaults/main.yml:2:github_runner_user: github-runner
```
Consumed throughout `live_vm_host`, including as the owner of files and the account for
`become_user`:
```
deploy/ansible/roles/live_vm_host/tasks/main.yml:40: name: "{{ github_runner_user }}"
deploy/ansible/roles/live_vm_host/tasks/main.yml:63: name: "{{ github_runner_user }}"
deploy/ansible/roles/live_vm_host/tasks/main.yml:88: ansible.builtin.command: "loginctl enable-linger {{ github_runner_user }}"
deploy/ansible/roles/live_vm_host/tasks/main.yml:107: owner: "{{ github_runner_user }}"
deploy/ansible/roles/live_vm_host/tasks/main.yml:117: become_user: "{{ github_runner_user }}"
deploy/ansible/roles/live_vm_host/tasks/main.yml:373: local_worker_host_operator_user: "{{ github_runner_user }}"
(…~20 references in total)
```
`live_vm_host/meta/` declares no dependency on `github_runner`, and
`live_vm_host/defaults/main.yml` does not define the variable or a fallback.
There is a second instance of the same pattern in the other direction:
`local_worker_host/tasks/packages_debian.yml:4` installs `{{ live_vm_host_packages }}`, a
`live_vm_host`-prefixed name that is actually defined in
`local_worker_host/defaults/main.yml:9` and carries an explicit
`# noqa: var-naming[no-role-prefix]` to silence the lint that would flag it. So the prefix
convention is already known to be violated here and is suppressed rather than resolved.
## Why it matters
The role names a real boundary — "the account that owns the live-VM worker files" — but spells it
as the CI runner's account. That conflates two things that are only incidentally equal on the one
host that exists today, and it makes the role untestable and unusable anywhere else: a second
worker host, a developer box reproducing a live failure, or a proof run that must not also
register a CI runner.
It also weakens `runner.yml` itself. Because the coupling is implicit, reordering the roles or
splitting the playbook would break it with an `undefined` error at apply time rather than at lint
or check time.
## Expected
Either:
1. **Give the role its own variable**, e.g. `live_vm_host_operator_user`, defaulting to
`github_runner_user` where that is defined so `runner.yml` keeps working unchanged, and have
`runner.yml` pass it explicitly; or
2. **Declare the dependency** in `live_vm_host/meta/main.yml` if the coupling is genuinely
intended, so it is at least stated and the role fails with a dependency error rather than an
undefined-variable error.
(1) matches what the role actually means and is the smaller behavioural change. `local_worker_host`
already takes a `local_worker_host_operator_user` for exactly this purpose, and
`live_vm_host/tasks/main.yml:373` sets it *from* `github_runner_user` — so the shape to copy is
already in the tree.
## Out of scope
- Renaming `live_vm_host_packages` to match its owning role. Same class of problem, opposite
direction, and it is pinned by `deploy/ansible/tests/run-local-worker-host.py`; worth its own
decision.
- The missing `python3-dev` entry in that package list, filed separately.
## Provenance
Found while provisioning a host as a live-VM worker host without making it a CI runner, in order
to run a live proof for an unrelated pull request. Confirmed by reading where the variable is
defined and where it is consumed, not inferred from the failure message alone.
Contributor guide
Research direction
Start with deploy/ansible/roles/live_vm_host/tasks/main.yml and compare its variable uses with github_runner/defaults/main.yml and live_vm_host/defaults/main.yml. Read deploy/ansible/playbooks/runner.yml and live_vm_host/meta/main.yml to understand the current role boundary, using local_worker_host as the existing variable pattern. Done means the live_vm_host role can run without github_runner while runner.yml continues to work unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ansible
- Domain
- devops
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100