From a117ed02a2f940cbb828950c10850d66f23903b6 Mon Sep 17 00:00:00 2001 From: 4DBug <4DBug@github.com> Date: Tue, 3 Mar 2026 02:05:08 -0600 Subject: [PATCH] gitea mirrors --- .stfolder/syncthing-folder-a0745f.txt | 2 +- modules/hosts/laptop/laptop.nix | 1 - modules/services/gitea-mirrors.nix | 201 ++++++++++++++++++++++++++ modules/services/gitea.nix | 21 ++- modules/software/docker.nix | 3 - 5 files changed, 222 insertions(+), 6 deletions(-) create mode 100644 modules/services/gitea-mirrors.nix delete mode 100644 modules/software/docker.nix diff --git a/.stfolder/syncthing-folder-a0745f.txt b/.stfolder/syncthing-folder-a0745f.txt index 2f6a7df..b3ae570 100644 --- a/.stfolder/syncthing-folder-a0745f.txt +++ b/.stfolder/syncthing-folder-a0745f.txt @@ -2,4 +2,4 @@ # Do not delete. folderID: nix -created: 2026-01-29T23:06:32-06:00 +created: 2026-01-29T23:05:44-06:00 diff --git a/modules/hosts/laptop/laptop.nix b/modules/hosts/laptop/laptop.nix index 6e6aba2..fc3420f 100644 --- a/modules/hosts/laptop/laptop.nix +++ b/modules/hosts/laptop/laptop.nix @@ -26,7 +26,6 @@ catppuccin #librewolf nixcord - organize ]; nixos = { diff --git a/modules/services/gitea-mirrors.nix b/modules/services/gitea-mirrors.nix new file mode 100644 index 0000000..2617fbe --- /dev/null +++ b/modules/services/gitea-mirrors.nix @@ -0,0 +1,201 @@ +{ den, ... }: { + den.aspects.gitea-mirrors = { + nixos = { pkgs, lib, config, ... }: + let + cfg = config.services.gitea; + mcfg = cfg.mirrors; + + uniqueOwners = lib.unique ( + (map (m: m.owner) mcfg.repos) ++ + (map (m: m.owner) mcfg.users) + ); + + giteaUrl = "http://localhost:${toString cfg.settings.server.HTTP_PORT}"; + tokenFile = "${cfg.stateDir}/mirror-setup-token"; + + setupScript = pkgs.writeShellScript "gitea-mirror-setup" '' + set -euo pipefail + + GITEA_URL="${giteaUrl}" + TOKEN_FILE="${tokenFile}" + GITEA_CMD="${lib.getExe cfg.package}" + + # wait for gitea to be ready + for i in $(seq 1 60); do + if ${pkgs.curl}/bin/curl -sf "$GITEA_URL/api/v1/version" >/dev/null 2>&1; then + break + fi + sleep 2 + done + + $GITEA_CMD admin user create \ + --username "${mcfg.adminUser}" \ + --email "${mcfg.adminEmail}" \ + --random-password \ + --admin \ + --must-change-password=false 2>/dev/null || true + + if [ ! -f "$TOKEN_FILE" ]; then + TOKEN=$($GITEA_CMD admin user generate-access-token \ + --username "${mcfg.adminUser}" \ + --token-name "mirror-setup" \ + --scopes "all" \ + --raw) + echo "$TOKEN" > "$TOKEN_FILE" + chmod 600 "$TOKEN_FILE" + fi + + TOKEN=$(cat "$TOKEN_FILE") + AUTH="Authorization: token $TOKEN" + + ${lib.concatMapStringsSep "\n" (owner: '' + RAND_PASS=$(${pkgs.openssl}/bin/openssl rand -base64 32) + ${pkgs.curl}/bin/curl -sf -X POST "$GITEA_URL/api/v1/admin/users" \ + -H "$AUTH" \ + -H "Content-Type: application/json" \ + -d "{ + \"username\": \"${owner}\", + \"email\": \"${owner}@mirror.localhost\", + \"password\": \"$RAND_PASS\", + \"must_change_password\": false, + \"visibility\": \"public\" + }" >/dev/null 2>&1 || true + '') uniqueOwners} + + ${lib.concatMapStringsSep "\n" (m: '' + ${pkgs.curl}/bin/curl -sf -X POST "$GITEA_URL/api/v1/repos/migrate" \ + -H "$AUTH" \ + -H "Content-Type: application/json" \ + -d '{ + "clone_addr": "${m.source}", + "repo_name": "${m.repo}", + "repo_owner": "${m.owner}", + "mirror": true, + "private": false, + "service": "${m.service or "git"}" + }' >/dev/null 2>&1 || true + '') mcfg.repos} + + ${lib.concatMapStringsSep "\n" (u: + let + platform = u.platform; + owner = u.owner; + baseUrl = u.baseUrl or (if platform == "github" then "https://api.github.com" + else if platform == "gitlab" then "https://gitlab.com" + else if platform == "gitea" then u.baseUrl + else throw "mirrors.users: unsupported platform '${platform}', provide baseUrl"); + cloneBase = if platform == "github" then "https://github.com/${owner}" + else if platform == "gitlab" then "${u.baseUrl or "https://gitlab.com"}/${owner}" + else if platform == "gitea" then "${u.baseUrl}/${owner}" + else throw "mirrors.users: unsupported platform '${platform}'"; + service = if platform == "github" then "github" + else if platform == "gitlab" then "gitlab" + else if platform == "gitea" then "gitea" + else "git"; + jqExpr = if platform == "gitlab" then ".[].path" else ".[].name"; + pageSize = if platform == "gitea" then 50 else 100; + pageSizeStr = toString pageSize; + listUrl = if platform == "github" then "${baseUrl}/users/${owner}/repos?per_page=${pageSizeStr}&type=owner" + else if platform == "gitlab" then "${baseUrl}/api/v4/users/${owner}/projects?per_page=${pageSizeStr}" + else "${baseUrl}/api/v1/users/${owner}/repos?limit=${pageSizeStr}"; + in '' + echo "Fetching repos for ${owner} from ${platform}..." + PAGE=1 + while true; do + REPOS=$(${pkgs.curl}/bin/curl -sf "${listUrl}&page=$PAGE" || echo "[]") + + NAMES=$(echo "$REPOS" | ${pkgs.jq}/bin/jq -r '${jqExpr}') + if [ -z "$NAMES" ] || [ "$NAMES" = "null" ]; then + break + fi + + for REPO_NAME in $NAMES; do + ${pkgs.curl}/bin/curl -sf -X POST "$GITEA_URL/api/v1/repos/migrate" \ + -H "$AUTH" \ + -H "Content-Type: application/json" \ + -d "{ + \"clone_addr\": \"${cloneBase}/$REPO_NAME.git\", + \"repo_name\": \"$REPO_NAME\", + \"repo_owner\": \"${owner}\", + \"mirror\": true, + \"private\": false, + \"service\": \"${service}\" + }" >/dev/null 2>&1 || true + done + + COUNT=$(echo "$REPOS" | ${pkgs.jq}/bin/jq 'length') + if [ "$COUNT" -lt ${pageSizeStr} ]; then break; fi + PAGE=$((PAGE + 1)) + done + '') mcfg.users} + + echo "Mirror setup complete." + ''; + in + { + options.services.gitea.mirrors = { + adminUser = lib.mkOption { + type = lib.types.str; + default = "admin"; + description = "Gitea admin username for mirror management."; + }; + + adminEmail = lib.mkOption { + type = lib.types.str; + default = "admin@localhost"; + description = "Gitea admin email."; + }; + + repos = lib.mkOption { + type = lib.types.listOf (lib.types.attrsOf lib.types.str); + default = []; + description = "Individual repositories to mirror. Each entry: { owner, repo, source, service? }."; + example = [ + { owner = "nixos"; repo = "nixpkgs"; source = "https://github.com/NixOS/nixpkgs.git"; service = "github"; } + ]; + }; + + users = lib.mkOption { + type = lib.types.listOf (lib.types.attrsOf lib.types.str); + default = []; + description = "Mirror all public repos of a user/org. Each entry: { owner, platform, baseUrl? }."; + example = [ + { owner = "catppuccin"; platform = "github"; } + ]; + }; + }; + + config = lib.mkIf (mcfg.repos != [] || mcfg.users != []) { + services.gitea.settings.mirror = { + DEFAULT_INTERVAL = "6h"; + MIN_INTERVAL = "10m"; + }; + + services.gitea.settings."cron.update_mirrors" = { + SCHEDULE = "@every 10m"; + RUN_AT_START = true; + }; + + systemd.services.gitea-mirror-setup = { + description = "Setup Gitea mirror repositories"; + after = [ "gitea.service" ]; + requires = [ "gitea.service" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = cfg.user; + Group = cfg.group; + ExecStart = setupScript; + WorkingDirectory = cfg.stateDir; + Environment = [ + "GITEA_WORK_DIR=${cfg.stateDir}" + "GITEA_CUSTOM=${cfg.customDir}" + ]; + }; + }; + }; + }; + }; +} diff --git a/modules/services/gitea.nix b/modules/services/gitea.nix index 4f652ce..6281886 100644 --- a/modules/services/gitea.nix +++ b/modules/services/gitea.nix @@ -1,5 +1,7 @@ -{ +{ den, ... }: { den.aspects.gitea = { + includes = [ den.aspects.gitea-mirrors ]; + nixos = { services.gitea = { enable = true; @@ -11,6 +13,23 @@ }; settings.server.HTTP_PORT = 3002; + + mirrors = { + adminUser = "admin"; + adminEmail = "admin@bug.tools"; + + repos = [ + { owner = "gmodena"; repo = "nix-flatpak"; source = "https://github.com/gmodena/nix-flatpak.git"; service = "github"; } + { owner = "FlameFlag"; repo = "nixcord"; source = "https://github.com/FlameFlag/nixcord.git"; service = "github"; } + { owner = "jacob.eva"; repo = "opencom-lte"; source = "https://git.liberatedsystems.co.uk/jacob.eva/opencom-lte.git"; } + ]; + + users = [ + { owner = "catppuccin"; platform = "github"; } + { owner = "picosh"; platform = "github"; } + { owner = "vic"; platform = "github"; } + ]; + }; }; }; }; diff --git a/modules/software/docker.nix b/modules/software/docker.nix deleted file mode 100644 index 0db3279..0000000 --- a/modules/software/docker.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - -}