Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions .github/workflows/integration_test_app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ jobs:
strategy:
fail-fast: false
matrix:
image: [focal, jammy, noble, resolute]
arch: [amd64, arm64, s390x, ppc64le]
image: [noble]
arch: [arm64]
# image: [focal, jammy, noble, resolute]
# arch: [amd64, arm64, s390x, ppc64le]
exclude:
- image: focal
arch: ppc64le
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",
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