Files
grm/docs/user/faq.md
T
emil f712a4493e
Post-merge / detect-and-configure (push) Waiting to run
Post-merge / release-and-maintain (push) Waiting to run
GRM-152: fix: fetch rootless Docker scripts on Arch Linux
2026-07-16 15:56:59 +00:00

176 lines
8.0 KiB
Markdown

# FAQ
## How to obtain the Gitea registration token
There are three levels of registration tokens, depending on which repositories the runner should serve:
- **Instance-level** — Site Administration → Actions → Runners → Create Registration Token. The runner will handle jobs from all repositories.
- **Organization-level** — Organization → Settings → Actions → Runners → Create Registration Token. The runner will only handle jobs from repositories in that organization.
- **Repository-level** — Repository → Settings → Actions → Runners → Create Registration Token. The runner will only handle jobs from that specific repository.
Set the token as `GITEA_REGISTRATION_TOKEN` in your `.env` file or pass it via `--token` on the command line.
## What is the CI_GITEA_TOKEN and is it needed?
`CI_GITEA_TOKEN` is a Gitea admin API token used for optional post-install verification. When set, GRM queries the Gitea API after installation to confirm the runner appears in the runner list. This is purely informational — the integration test passes/fails based on the `.runner` file and systemd service, not the API check.
To generate one: Settings → Applications → Generate New Token, with the `admin` scope (or at minimum `read:user`, `read:repository`, `read:admin`).
If you skip it, GRM will still verify the runner correctly — it won't show the extra API confirmation.
## How to skip the sudo password prompt for automation
Configure passwordless sudo on the remote host and pass `--no-ask-become-pass` to the CLI command. This is recommended for CI/CD pipelines.
On the remote host, add a sudoers entry:
```bash
echo "ubuntu ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/grm
```
Then use:
```bash
grm install 192.168.1.10 --user ubuntu --key ~/.ssh/id_ed25519 --name prod-runner --no-ask-become-pass
```
## Can multiple runners run on the same host?
Yes. Each runner instance is fully isolated with its own system user (`grm-<name>`), rootless Docker daemon, data directory, and systemd user service. Install additional runners with different `--name` values and manage them independently by name.
```bash
grm install 192.168.1.10 --user ubuntu --name workflow-runner
grm install 192.168.1.10 --user ubuntu --name build-runner
grm list
```
Runners on the same host never interfere with each other or with the host's Docker installation.
## Why does a runner appear offline after installation?
Check that `GITEA_URL` and `GITEA_REGISTRATION_TOKEN` are correct, verify the runner service is running with `sudo -u grm-<name> systemctl --user status gitea-runner`, and check the logs for registration errors. You can also confirm the runner appears as **Online** in the Gitea UI under **Actions → Runners**.
Common causes:
- Registration token expired — generate a new one from Gitea
- Network connectivity issue between the runner host and Gitea
- Rootless Docker daemon not running — check `sudo -u grm-<name> systemctl --user status docker`
- Lingering not enabled — check `loginctl show-user grm-<name> | grep Linger`
## What does the "Event loop is closed" warning mean?
This is a harmless cleanup traceback from Molecule's Docker driver when the test process is interrupted. It does not indicate a test failure.
## Where are runner connection details stored?
GRM stores each runner's connection details (host, user, SSH key, Gitea URL, labels) in a local JSON registry at `~/.local/share/grm/runners.json`. After installation, lifecycle commands work by runner name only — you can override any stored value by passing the corresponding flag.
## How to update the gitea_runner binary
Use the `grm update` command:
```bash
grm update 192.168.1.10 --user ubuntu
```
To update to a specific version:
```bash
grm update 192.168.1.10 --user ubuntu --version 1.0.8
```
The update command downloads the new binary and replaces the existing one at `/usr/local/bin/gitea_runner`. The runner service is restarted automatically.
## How to remove a runner entirely
Use the `grm remove` command:
```bash
grm remove prod-runner --token <registration-token>
```
This deregisters the runner from Gitea, stops and disables the systemd service, removes the system user, deletes data and config directories, removes subuid/subgid entries, disables lingering, and removes the entry from the local registry.
If the remote host is already gone or unreachable, use `--force` to skip remote cleanup and only remove the local registry entry:
```bash
grm remove prod-runner --force
```
## What is the difference between disable and remove?
- **`grm disable <name>`** — Deregisters the runner from Gitea and stops the service, but leaves the user, directories, and service files in place. The runner can be re-enabled later with `grm enable` and re-registered with a new token.
- **`grm remove <name>`** — Removes the runner entirely: deregisters from Gitea, stops and disables the service, removes the system user, deletes all directories, and removes the local registry entry. This is irreversible.
## What operating systems are supported?
GRM supports Arch Linux (rolling), Ubuntu 22.04/24.04, and Debian 12. All supported OSes are tested in CI via Molecule scenarios on every PR that changes Ansible files.
On Arch Linux, the rootless Docker setup scripts (`dockerd-rootless-setuptool.sh`, `dockerd-rootless.sh`) and the `rootlesskit` runtime are provisioned automatically — Arch's `docker` package does not ship them. No extra setup is required.
## How to change the UI language
Set the `GRM_LANG` environment variable to one of the supported languages: `en` (English, default), `bg` (Bulgarian), `de` (German), `ru` (Russian), `zh` (Chinese), `pl` (Polish).
```bash
GRM_LANG=bg grm install 192.168.1.10 --user ubuntu --name prod-runner
```
Or set it in your `.env` file:
```bash
GRM_LANG=bg
```
## How to enable debug logging
Set the `GRM_LOG_LEVEL` environment variable to `DEBUG`:
```bash
GRM_LOG_LEVEL=DEBUG grm install 192.168.1.10 --user ubuntu --name prod-runner
```
The log file at `~/.local/state/grm/logs/grm.log` always captures DEBUG level regardless of this setting. Ansible execution logs are stored in timestamped files at `~/.local/state/grm/logs/ansible-<timestamp>.log`.
## What runner labels should be used?
By default, runners are registered with `docker,ubuntu-latest:docker://runner-images:ubuntu-22.04`. You can override this with `--labels` or the `GITEA_RUNNER_LABELS` environment variable.
Use an official Gitea runner image with Node.js, Python, and Docker CLI. Avoid bare OS images like `alpine:latest` because `actions/checkout@v4` needs Node.js.
Example:
```bash
grm install 192.168.1.10 --user ubuntu --name prod-runner \
--labels "docker:docker://gitea/runner-images:ubuntu-latest"
```
## Is GRM secure?
Yes. GRM is designed with security as a first-class concern:
- **Rootless Docker**: Each runner operates under a dedicated unprivileged system user. Containers never have root access to the host.
- **Secret handling**: Registration tokens are passed via temporary JSON files with `0600` permissions, never on the command line (CWE-214).
- **No shell injection**: The CLI never uses `shell=True` with subprocess.
- **Bandit security scan**: The CI pipeline runs Bandit on every PR.
## Can GRM be installed via pip?
Yes:
```bash
pip install grm
```
This installs the `grm` CLI and its Python dependencies. The Ansible playbooks and role are bundled with the package. For development or access to Make targets, clone the repository instead.
## How does GRM handle idempotence?
The Ansible role is idempotent — running `grm install` twice produces zero changes on the second run. Each task checks for existing state before making changes. For example:
- User creation uses `ansible.builtin.user` which only creates if the user doesn't exist
- Package installation uses `state: present` which only installs if not already installed
- Template creation uses `ansible.builtin.template` which only writes if the content changed
- Rootless Docker setup uses `creates:` to skip if already configured
This makes GRM safe for CI/CD pipelines and configuration management.