Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/integration_test_app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- uses: canonical/setup-lxd@v0.1.3
- uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version: "3.14"
- name: Install tox
run: |
sudo apt-get update
Expand Down
2 changes: 1 addition & 1 deletion app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[project]
name = "github-runner-image-builder"
version = "0.14.0"
version = "0.14.1"
authors = [
{ name = "Canonical IS DevOps", email = "is-devops-team@canonical.com" },
]
Expand Down
5 changes: 5 additions & 0 deletions app/src/github_runner_image_builder/openstack_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ def run(
script_secrets=image_config.script_config.script_secrets,
ssh_conn=ssh_conn,
)
logger.info("Cleaning cloud-init state before snapshot.")
ssh_conn.run(
"sudo cloud-init clean --logs --machine-id --seed --configs all",
timeout=EXTERNAL_SCRIPT_GENERAL_TIMEOUT,
)
_shutoff_server(conn=conn, server=builder)
image = store.create_snapshot(
cloud_name=cloud_config.cloud_name,
Expand Down
19 changes: 19 additions & 0 deletions app/src/github_runner_image_builder/templates/cloud-init.sh.j2
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ function configure_system_users() {
/usr/sbin/groupadd -f microk8s
/usr/sbin/groupadd -f docker
/usr/sbin/usermod --append --groups docker,microk8s,lxd,sudo ubuntu

# Create runner user as alias to ubuntu for GARM compatibility.
# GARM expects a runner user with /home/runner/actions-runner path.
echo "Configuring runner user alias for GARM compatibility"
UBUNTU_UID=$(/usr/bin/id -u ubuntu)
UBUNTU_GID=$(/usr/bin/id -g ubuntu)
Comment thread
florentianayuwono marked this conversation as resolved.
# --non-unique: allow reusing ubuntu's UID (duplicate UIDs are rejected by default).
# --uid/--gid: share ubuntu's UID/GID so both users have identical file permissions.
# --no-create-home: skip creating /home/runner; runner's home is set to /home/ubuntu instead.
# 2>/dev/null || true: ignore errors (e.g. runner user already exists) without failing the script.
/usr/sbin/useradd --non-unique --uid "$UBUNTU_UID" --gid "$UBUNTU_GID" --no-create-home --home-dir /home/ubuntu runner 2>/dev/null || true
/usr/sbin/usermod --append --groups docker,microk8s,lxd,sudo runner 2>/dev/null || true
Comment thread
florentianayuwono marked this conversation as resolved.
Comment on lines +178 to +180
# Symlink /home/runner -> /home/ubuntu so GARM's hardcoded /home/runner/actions-runner path resolves correctly.
# If /home/runner exists as a plain directory (not a symlink), remove it first; otherwise ln -sfnT would
# create the symlink inside the directory instead of replacing it.
# -T: treat destination as a file path, never as a directory target (prevents ln from creating the
# symlink inside /home/runner if it exists as a directory after rmdir fails).
[ -d /home/runner ] && ! [ -L /home/runner ] && rmdir /home/runner 2>/dev/null || true
Comment on lines +182 to +186
/usr/bin/ln -sfnT /home/ubuntu /home/runner
}


Expand Down
8 changes: 4 additions & 4 deletions app/tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ def openstack_connection_fixture(
with openstack.connect(cloud_name) as conn:
yield conn

images = conn.list_images()
for image in images:
if str(image.name).startswith(test_id):
conn.delete_image(image)
# images = conn.list_images()
# for image in images:
# if str(image.name).startswith(test_id):
# conn.delete_image(image)


@pytest.fixture(scope="module", name="dockerhub_mirror")
Expand Down
19 changes: 19 additions & 0 deletions app/tests/unit/test_openstack_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,25 @@ def test__generate_cloud_init_script(
/usr/sbin/groupadd -f microk8s
/usr/sbin/groupadd -f docker
/usr/sbin/usermod --append --groups docker,microk8s,lxd,sudo ubuntu

# Create runner user as alias to ubuntu for GARM compatibility.
# GARM expects a runner user with /home/runner/actions-runner path.
echo "Configuring runner user alias for GARM compatibility"
UBUNTU_UID=$(/usr/bin/id -u ubuntu)
UBUNTU_GID=$(/usr/bin/id -g ubuntu)
# --non-unique: allow reusing ubuntu's UID (duplicate UIDs are rejected by default).
# --uid/--gid: share ubuntu's UID/GID so both users have identical file permissions.
# --no-create-home: skip creating /home/runner; runner's home is set to /home/ubuntu instead.
# 2>/dev/null || true: ignore errors (e.g. runner user already exists) without failing the script.
/usr/sbin/useradd --non-unique --uid "$UBUNTU_UID" --gid "$UBUNTU_GID" --no-create-home --home-dir /home/ubuntu runner 2>/dev/null || true
/usr/sbin/usermod --append --groups docker,microk8s,lxd,sudo runner 2>/dev/null || true
Comment thread
florentianayuwono marked this conversation as resolved.
# Symlink /home/runner -> /home/ubuntu so GARM's hardcoded /home/runner/actions-runner path resolves correctly.
# If /home/runner exists as a plain directory (not a symlink), remove it first; otherwise ln -sfnT would
# create the symlink inside the directory instead of replacing it.
# -T: treat destination as a file path, never as a directory target (prevents ln from creating the
# symlink inside /home/runner if it exists as a directory after rmdir fails).
[ -d /home/runner ] && ! [ -L /home/runner ] && rmdir /home/runner 2>/dev/null || true
/usr/bin/ln -sfnT /home/ubuntu /home/runner
}}


Expand Down
5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!-- vale Canonical.007-Headings-sentence-case = NO -->

## [#223 Fix GARM image incompatibility](https://github.com/canonical/github-runner-image-builder-operator/pull/223) (2026-05-27)

- Add `runner` user as an alias to the `ubuntu` user (same UID/GID, same home directory) so GARM can boot runners from images produced by this charm.

## [#213 Fix proxy setup]

- Fix proxy setup for image-relation joined hook.
Expand All @@ -11,6 +15,7 @@
## [#221 Add resource recommendation for charm deployment](https://github.com/canonical/github-runner-image-builder-operator/pull/221)

<!-- vale Canonical.013-Spell-out-numbers-below-10 = NO -->

- Add 2 vCPUs, 8 GiB RAM, and 20 GiB disk OpenStack flavor recommendation.
<!-- vale Canonical.013-Spell-out-numbers-below-10 = YES -->

Expand Down
Loading