From c741ce2aaf7dca66514b36a75b2d44808dc6357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoran=20Peri=C4=8Di=C4=87?= Date: Mon, 6 Apr 2026 00:33:13 +0200 Subject: [PATCH] v0.3.0-4: rootless Podman improvements - Add btrfs storage.conf for gitea-runner user - Add gitea-runner-podman.service dependency to runner service - Auto-allocate subuid/subgid ranges via usermod (min 524288) - Add systemd-container dep for loginctl enable-linger - Use sysusers_create_package in %pre for proper user creation - Track /var/lib/gitea/runners dir in %files - Use runuser instead of sudo in setup script - Add After=systemd-logind.service to podman service - Fix SELinux volume label (:Z -> :z) in config.yaml --- config.yaml | 2 +- gitea-act-runner-setup | 2 +- gitea-act_runner.spec | 39 ++++++++++++++++++++-------- gitea-act_runner@.service | 3 ++- gitea-runner-podman.service | 2 +- storage.conf | 51 +++++++++++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 storage.conf diff --git a/config.yaml b/config.yaml index 1fc9fab..ec9ca93 100644 --- a/config.yaml +++ b/config.yaml @@ -60,7 +60,7 @@ container: # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). privileged: false # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway). - options: -v /var/cache/act-runner/pnpm-store:/cache/pnpm-store:Z + options: -v /var/cache/act-runner/pnpm-store:/cache/pnpm-store:z # The parent directory of a job's working directory. # If it's empty, /workspace will be used. workdir_parent: diff --git a/gitea-act-runner-setup b/gitea-act-runner-setup index 9e531b9..9897416 100755 --- a/gitea-act-runner-setup +++ b/gitea-act-runner-setup @@ -18,4 +18,4 @@ chown gitea-runner:gitea-runner "$RUNNER_DIR" systemctl enable --now gitea-runner-podman.service cd "$RUNNER_DIR" -sudo -u gitea-runner gitea-act-runner register -c "$CONFIG" +runuser -u gitea-runner -- gitea-act-runner register -c "$CONFIG" diff --git a/gitea-act_runner.spec b/gitea-act_runner.spec index 7cf4202..96a4219 100644 --- a/gitea-act_runner.spec +++ b/gitea-act_runner.spec @@ -1,6 +1,6 @@ Name: gitea-act_runner Version: 0.3.0 -Release: 2%{?dist} +Release: 4%{?dist} Summary: Gitea act runner service. License: MIT Group: System Environment/Base @@ -13,10 +13,11 @@ Source11: config.yaml Source12: gitea-act-runner-setup Source13: gitea-act-runner.sysusers Source14: gitea-runner-podman.service +Source15: storage.conf BuildRequires: systemd-rpm-macros -Requires: shadow-utils Requires: podman +Requires: systemd-container %{?systemd_requires} ExclusiveArch: x86_64 aarch64 @@ -48,21 +49,26 @@ install -m 755 %{SOURCE12} %{buildroot}%{_bindir}/gitea-act-runner-setup install -d -m 750 %{buildroot}%{_sharedstatedir}/gitea/runners +# Podman storage config for gitea-runner user — uses native btrfs driver +# instead of overlayfs for better performance on btrfs filesystems +install -d -m 750 %{buildroot}%{_sharedstatedir}/gitea/runners/.config/containers +install -m 644 %{SOURCE15} %{buildroot}%{_sharedstatedir}/gitea/runners/.config/containers/storage.conf + install -d -m 755 %{buildroot}/var/cache/act-runner/pnpm-store -%post +%pre %sysusers_create_package gitea-act-runner %{SOURCE13} +%post if [ $1 -eq 1 ]; then loginctl enable-linger gitea-runner || : fi -if ! grep -q "gitea-runner" /etc/subuid; then - LAST_ID=$(tail -n 1 /etc/subuid | cut -d: -f2) - [ -z "$LAST_ID" ] && START_ID=100000 || START_ID=$((LAST_ID + 65536)) - - echo "gitea-runner:$START_ID:65536" >> /etc/subuid - echo "gitea-runner:$START_ID:65536" >> /etc/subgid +if ! grep -q "^gitea-runner:" /etc/subuid 2>/dev/null; then + NEXT=$(awk -F: '{n=$2+$3} END{print n+0}' /etc/subuid 2>/dev/null) + [ "$NEXT" -lt 524288 ] && NEXT=524288 + END=$((NEXT + 65535)) + usermod --add-subuids "$NEXT-$END" --add-subgids "$NEXT-$END" gitea-runner 2>/dev/null || : fi %systemd_post gitea-act_runner@.service @@ -89,13 +95,24 @@ fi %{_sysusersdir}/gitea-act-runner.conf %defattr(-,gitea-runner,gitea-runner,750) +%dir %{_sharedstatedir}/gitea/runners %dir %{_sysconfdir}/gitea %dir %{_sysconfdir}/gitea/runners %config(noreplace) %{_sysconfdir}/gitea/runners/runner1.yaml -%dir %attr(0750,gitea-runner,gitea-runner) /var/cache/act-runner -%dir %attr(0750,gitea-runner,gitea-runner) /var/cache/act-runner/pnpm-store +%dir %{_sharedstatedir}/gitea/runners/.config +%dir %{_sharedstatedir}/gitea/runners/.config/containers +%config(noreplace) %{_sharedstatedir}/gitea/runners/.config/containers/storage.conf + +%dir /var/cache/act-runner +%dir /var/cache/act-runner/pnpm-store %changelog +* Mon Apr 06 2026 Zoran Pericic - 0.3.0-4 +- Add Podman btrfs storage.conf for gitea-runner user +- Add dependency on gitea-runner-podman.service +- Use usermod --add-subuids for subuid/subgid allocation +- Add systemd-container dependency for loginctl enable-linger + * Mon Mar 17 2025 Zoran Pericic - 0.3.0-2 - Add gitea-runner-podman.service for rootless Podman API socket diff --git a/gitea-act_runner@.service b/gitea-act_runner@.service index d8f973a..0d30551 100644 --- a/gitea-act_runner@.service +++ b/gitea-act_runner@.service @@ -1,6 +1,7 @@ [Unit] Description=Act runner is a runner for Gitea -After=network.target +After=network.target gitea-runner-podman.service +Requires=gitea-runner-podman.service ConditionPathExists=/var/lib/gitea/runners/%i/.runner StartLimitIntervalSec=60 StartLimitBurst=3 diff --git a/gitea-runner-podman.service b/gitea-runner-podman.service index a9b786d..80ca98c 100644 --- a/gitea-runner-podman.service +++ b/gitea-runner-podman.service @@ -1,6 +1,6 @@ [Unit] Description=Podman API socket for Gitea Act Runner -After=network.target +After=network.target systemd-logind.service [Service] Type=exec diff --git a/storage.conf b/storage.conf new file mode 100644 index 0000000..069d365 --- /dev/null +++ b/storage.conf @@ -0,0 +1,51 @@ +# Podman storage configuration for gitea-runner user +# ================================================== +# +# PREREQUISITE: /var/lib/gitea must be a separate Btrfs mount point. +# This ensures all runner workloads (container images, layers, build cache) +# stay on the Btrfs partition, isolated from the system root filesystem. +# +# Example /etc/fstab entry (recommended mount options for CI workloads): +# /dev/sdXN /var/lib/gitea btrfs noatime,compress=zstd:1,space_cache=v2,autodefrag,discard=async,commit=120 0 0 +# +# Mount option breakdown: +# noatime - Skip access time updates on reads, reduces write I/O +# compress=zstd:1 - Transparent compression; level 1 is fast with good ratio, +# can reduce container image storage by up to 50% +# space_cache=v2 - Faster free-space tracking for frequent allocate/delete +# cycles typical of container image churn +# autodefrag - Background defrag for small random writes (build artifacts) +# discard=async - Async TRIM for SSDs (omit this for spinning disks) +# commit=120 - Flush data every 120s instead of 30s — reduces write +# overhead; acceptable for CI data that can be rebuilt +# +# WHY BTRFS DRIVER? +# - Fast snapshots: Gitea runners frequently pull and remove images. The btrfs +# driver uses subvolumes, which is faster than OverlayFS on XFS. +# - Layer deduplication: When multiple runners use similar base images (e.g. +# node, go), Btrfs deduplicates them automatically, saving disk space. +# - Resource isolation: Since /var/lib/gitea is a separate mount, heavy runner +# I/O won't slow down the system root on XFS. +# +# INSTALLATION: +# This file is installed to: +# /var/lib/gitea/runners/.config/containers/storage.conf +# Podman reads it automatically when running as the gitea-runner user. +# +# INITIALIZATION (run as gitea-runner after install): +# podman system reset +# podman info | grep -E "store|graphRoot" +# Verify: storage.driver must be "btrfs" and graphRoot must point +# inside /var/lib/gitea/runners/ +# +# All values below are commented out as examples. Uncomment and adjust +# to match your environment. + +# [storage] +# driver = "btrfs" +# +# # Podman will automatically create subdirectories here +# graphroot = "/var/lib/gitea/runners/.local/share/containers/storage" + +# [storage.options] +# # Optional: add quotas here if you want to limit disk space for runners