From 2e48aa9ef3440a1e477095c10813418b2030fc76 Mon Sep 17 00:00:00 2001 From: Jordan Holt Date: Mon, 10 Mar 2025 16:16:26 +0000 Subject: [PATCH] gitea-runner: move out of module --- hosts/odyssey/default.nix | 2 +- hosts/odyssey/gitea-runner.nix | 228 ++++++++++++++++++++++ modules/nixos/services/gitea-runner.nix | 242 ------------------------ 3 files changed, 229 insertions(+), 243 deletions(-) create mode 100644 hosts/odyssey/gitea-runner.nix delete mode 100644 modules/nixos/services/gitea-runner.nix diff --git a/hosts/odyssey/default.nix b/hosts/odyssey/default.nix index d604c66..d4ac9e2 100644 --- a/hosts/odyssey/default.nix +++ b/hosts/odyssey/default.nix @@ -8,6 +8,7 @@ { imports = [ ./hardware-configuration.nix + ./gitea-runner.nix ../desktop.nix ]; @@ -112,7 +113,6 @@ ]; repoPath = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo"; }; - gitea-runner.enable = true; }; shell = { zsh.enable = true; diff --git a/hosts/odyssey/gitea-runner.nix b/hosts/odyssey/gitea-runner.nix new file mode 100644 index 0000000..3538eea --- /dev/null +++ b/hosts/odyssey/gitea-runner.nix @@ -0,0 +1,228 @@ +{ + pkgs, + config, + self, + ... +}: + +# Based on: https://git.clan.lol/clan/clan-infra/src/branch/main/modules/web01/gitea/actions-runner.nix + +let + hostname = config.networking.hostName; + giteaUrl = "https://git.vimium.com"; + + storeDepsBins = with pkgs; [ + coreutils + findutils + gnugrep + gawk + git + nix + nix-update + bash + jq + nodejs + ]; + + storeDeps = pkgs.runCommand "store-deps" { } '' + mkdir -p $out/bin + for dir in ${toString storeDepsBins}; do + for bin in "$dir"/bin/*; do + ln -s "$bin" "$out/bin/$(basename "$bin")" + done + done + + # Add SSL CA certs + mkdir -p $out/etc/ssl/certs + cp -a "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" $out/etc/ssl/certs/ca-bundle.crt + ''; +in +{ + modules.podman.enable = true; + + systemd.services = { + gitea-runner-nix-image = { + wantedBy = [ "multi-user.target" ]; + after = [ "podman.service" ]; + requires = [ "podman.service" ]; + path = [ + config.virtualisation.podman.package + pkgs.gnutar + pkgs.shadow + pkgs.getent + ]; + script = '' + set -eux -o pipefail + mkdir -p etc/nix + + # Create an unpriveleged user that we can use also without the run-as-user.sh script + touch etc/passwd etc/group + groupid=$(cut -d: -f3 < <(getent group nix-ci-user)) + userid=$(cut -d: -f3 < <(getent passwd nix-ci-user)) + groupadd --prefix $(pwd) --gid "$groupid" nix-ci-user + emptypassword='$6$1ero.LwbisiU.h3D$GGmnmECbPotJoPQ5eoSTD6tTjKnSWZcjHoVTkxFLZP17W9hRi/XkmCiAMOfWruUwy8gMjINrBMNODc7cYEo4K.' + useradd --prefix $(pwd) -p "$emptypassword" -m -d /tmp -u "$userid" -g "$groupid" -G nix-ci-user nix-ci-user + + cat < etc/nix/nix.conf + accept-flake-config = true + experimental-features = nix-command flakes + NIX_CONFIG + + cat < etc/nsswitch.conf + passwd: files mymachines systemd + group: files mymachines systemd + shadow: files + + hosts: files mymachines dns myhostname + networks: files + + ethers: files + services: files + protocols: files + rpc: files + NSSWITCH + + # list the content as it will be imported into the container + tar -cv . | tar -tvf - + tar -cv . | podman import - gitea-runner-nix + ''; + serviceConfig = { + RuntimeDirectory = "gitea-runner-nix-image"; + WorkingDirectory = "/run/gitea-runner-nix-image"; + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + + gitea-runner-nix = { + after = [ "gitea-runner-nix-image.service" ]; + requires = [ "gitea-runner-nix-image.service" ]; + + serviceConfig = { + # Hardening (may overlap with DynamicUser=) + # The following options are only for optimizing output of systemd-analyze + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + # ProtectClock= adds DeviceAllow=char-rtc r + DeviceAllow = ""; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + UMask = "0066"; + ProtectProc = "invisible"; + SystemCallFilter = [ + "~@clock" + "~@cpu-emulation" + "~@module" + "~@mount" + "~@obsolete" + "~@raw-io" + "~@reboot" + "~@swap" + # needed by go? + #"~@resources" + "~@privileged" + "~capset" + "~setdomainname" + "~sethostname" + ]; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + "AF_NETLINK" + ]; + + # Needs network access + PrivateNetwork = false; + # Cannot be true due to Node + MemoryDenyWriteExecute = false; + + # The more restrictive "pid" option makes `nix` commands in CI emit + # "GC Warning: Couldn't read /proc/stat" + # You may want to set this to "pid" if not using `nix` commands + ProcSubset = "all"; + # Coverage programs for compiled code such as `cargo-tarpaulin` disable + # ASLR (address space layout randomization) which requires the + # `personality` syscall + # You may want to set this to `true` if not using coverage tooling on + # compiled code + LockPersonality = false; + + # Note that this has some interactions with the User setting; so you may + # want to consult the systemd docs if using both. + DynamicUser = true; + }; + }; + }; + + users.users.nix-ci-user = { + group = "nix-ci-user"; + description = "Used for running nix-based CI jobs"; + home = "/var/empty"; + isSystemUser = true; + }; + users.groups.nix-ci-user = { }; + + age.secrets."files/services/gitea-runner/${hostname}-token" = { + file = "${self.inputs.secrets}/files/services/gitea-runner/${hostname}-token.age"; + group = "podman"; + }; + + services.gitea-actions-runner.instances = { + act = { + enable = true; + url = giteaUrl; + name = "act-runner-${hostname}"; + + tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path; + settings = { + cache.enabled = true; + runner.capacity = 4; + }; + + labels = [ + "debian-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest" + "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest" + ]; + }; + nix = { + enable = true; + url = giteaUrl; + name = "nix-runner-${hostname}"; + + tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path; + settings = { + cache.enabled = true; + container = { + options = "-e NIX_BUILD_SHELL=/bin/bash -e PAGER=cat -e PATH=/bin -e SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt --device /dev/kvm -v /nix:/nix -v ${storeDeps}/bin:/bin -v ${storeDeps}/etc/ssl:/etc/ssl --user nix-ci-user"; + network = "host"; + valid_volumes = [ + "/nix" + "${storeDeps}/bin" + "${storeDeps}/etc/ssl" + ]; + }; + runner.capacity = 4; + }; + + labels = [ + "nix:docker://gitea-runner-nix" + ]; + }; + }; +} diff --git a/modules/nixos/services/gitea-runner.nix b/modules/nixos/services/gitea-runner.nix deleted file mode 100644 index bad6b82..0000000 --- a/modules/nixos/services/gitea-runner.nix +++ /dev/null @@ -1,242 +0,0 @@ -{ - pkgs, - config, - lib, - self, - ... -}: - -# Based on: https://git.clan.lol/clan/clan-infra/src/branch/main/modules/web01/gitea/actions-runner.nix - -with lib; - -let - cfg = config.modules.services.gitea-runner; - hostname = config.networking.hostName; - giteaUrl = "https://git.vimium.com"; - - storeDepsBins = with pkgs; [ - coreutils - findutils - gnugrep - gawk - git - nix - nix-update - bash - jq - nodejs - ]; - - storeDeps = pkgs.runCommand "store-deps" { } '' - mkdir -p $out/bin - for dir in ${toString storeDepsBins}; do - for bin in "$dir"/bin/*; do - ln -s "$bin" "$out/bin/$(basename "$bin")" - done - done - - # Add SSL CA certs - mkdir -p $out/etc/ssl/certs - cp -a "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" $out/etc/ssl/certs/ca-bundle.crt - ''; -in -{ - options.modules.services.gitea-runner = { - enable = mkOption { - default = false; - example = true; - description = mdDoc "Enable a runner for Gitea Actions on this host"; - }; - }; - - config = mkIf cfg.enable { - modules.podman.enable = true; - - systemd.services = { - gitea-runner-nix-image = { - wantedBy = [ "multi-user.target" ]; - after = [ "podman.service" ]; - requires = [ "podman.service" ]; - path = [ - config.virtualisation.podman.package - pkgs.gnutar - pkgs.shadow - pkgs.getent - ]; - script = '' - set -eux -o pipefail - mkdir -p etc/nix - - # Create an unpriveleged user that we can use also without the run-as-user.sh script - touch etc/passwd etc/group - groupid=$(cut -d: -f3 < <(getent group nix-ci-user)) - userid=$(cut -d: -f3 < <(getent passwd nix-ci-user)) - groupadd --prefix $(pwd) --gid "$groupid" nix-ci-user - emptypassword='$6$1ero.LwbisiU.h3D$GGmnmECbPotJoPQ5eoSTD6tTjKnSWZcjHoVTkxFLZP17W9hRi/XkmCiAMOfWruUwy8gMjINrBMNODc7cYEo4K.' - useradd --prefix $(pwd) -p "$emptypassword" -m -d /tmp -u "$userid" -g "$groupid" -G nix-ci-user nix-ci-user - - cat < etc/nix/nix.conf - accept-flake-config = true - experimental-features = nix-command flakes - NIX_CONFIG - - cat < etc/nsswitch.conf - passwd: files mymachines systemd - group: files mymachines systemd - shadow: files - - hosts: files mymachines dns myhostname - networks: files - - ethers: files - services: files - protocols: files - rpc: files - NSSWITCH - - # list the content as it will be imported into the container - tar -cv . | tar -tvf - - tar -cv . | podman import - gitea-runner-nix - ''; - serviceConfig = { - RuntimeDirectory = "gitea-runner-nix-image"; - WorkingDirectory = "/run/gitea-runner-nix-image"; - Type = "oneshot"; - RemainAfterExit = true; - }; - }; - - gitea-runner-nix = { - after = [ "gitea-runner-nix-image.service" ]; - requires = [ "gitea-runner-nix-image.service" ]; - - serviceConfig = { - # Hardening (may overlap with DynamicUser=) - # The following options are only for optimizing output of systemd-analyze - AmbientCapabilities = ""; - CapabilityBoundingSet = ""; - # ProtectClock= adds DeviceAllow=char-rtc r - DeviceAllow = ""; - NoNewPrivileges = true; - PrivateDevices = true; - PrivateMounts = true; - PrivateTmp = true; - PrivateUsers = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectSystem = "strict"; - RemoveIPC = true; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - UMask = "0066"; - ProtectProc = "invisible"; - SystemCallFilter = [ - "~@clock" - "~@cpu-emulation" - "~@module" - "~@mount" - "~@obsolete" - "~@raw-io" - "~@reboot" - "~@swap" - # needed by go? - #"~@resources" - "~@privileged" - "~capset" - "~setdomainname" - "~sethostname" - ]; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_UNIX" - "AF_NETLINK" - ]; - - # Needs network access - PrivateNetwork = false; - # Cannot be true due to Node - MemoryDenyWriteExecute = false; - - # The more restrictive "pid" option makes `nix` commands in CI emit - # "GC Warning: Couldn't read /proc/stat" - # You may want to set this to "pid" if not using `nix` commands - ProcSubset = "all"; - # Coverage programs for compiled code such as `cargo-tarpaulin` disable - # ASLR (address space layout randomization) which requires the - # `personality` syscall - # You may want to set this to `true` if not using coverage tooling on - # compiled code - LockPersonality = false; - - # Note that this has some interactions with the User setting; so you may - # want to consult the systemd docs if using both. - DynamicUser = true; - }; - }; - }; - - users.users.nix-ci-user = { - group = "nix-ci-user"; - description = "Used for running nix-based CI jobs"; - home = "/var/empty"; - isSystemUser = true; - }; - users.groups.nix-ci-user = { }; - - age.secrets."files/services/gitea-runner/${hostname}-token" = { - file = "${self.inputs.secrets}/files/services/gitea-runner/${hostname}-token.age"; - group = "podman"; - }; - - services.gitea-actions-runner.instances = { - act = { - enable = true; - url = giteaUrl; - name = "act-runner-${hostname}"; - - tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path; - settings = { - cache.enabled = true; - runner.capacity = 4; - }; - - labels = [ - "debian-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest" - "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest" - ]; - }; - nix = { - enable = true; - url = giteaUrl; - name = "nix-runner-${hostname}"; - - tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path; - settings = { - cache.enabled = true; - container = { - options = "-e NIX_BUILD_SHELL=/bin/bash -e PAGER=cat -e PATH=/bin -e SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt --device /dev/kvm -v /nix:/nix -v ${storeDeps}/bin:/bin -v ${storeDeps}/etc/ssl:/etc/ssl --user nix-ci-user"; - network = "host"; - valid_volumes = [ - "/nix" - "${storeDeps}/bin" - "${storeDeps}/etc/ssl" - ]; - }; - runner.capacity = 4; - }; - - labels = [ - "nix:docker://gitea-runner-nix" - ]; - }; - }; - }; -}