gerrit01: add a one-way-sync service

It's basic and does not handle conflicts which needs to be manually
managed.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
This commit is contained in:
Raito Bezarius 2024-07-04 15:18:21 +02:00
parent e148d54b18
commit 6d948be57e
6 changed files with 139 additions and 0 deletions

View file

@ -2,6 +2,7 @@
machines = {
bagel-box = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAsO4bNqY04uG13Pg3ubHfRDssTphDLzZ4YUniE5/p+M";
meta01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5t9gYorOWgpCFDJgb24pyCKIabGpeI2H/UfdvXODcT";
gerrit01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+eSZu+u9sCynrMlsmFzQHLIELQAuVg0Cs1pBvwb4+A";
};
users = {

View file

@ -38,6 +38,30 @@
data = "/gerrit-data";
};
age.secrets.owsDeployKey.file = ../../secrets/ows-deploy-key.age;
bagel.nixpkgs.one-way-sync = {
enable = true;
pushUrl = "ssh://ows_bot@cl.forkos.org:29418/nixpkgs";
deployKeyPath = config.age.secrets.owsDeployKey.path;
branches."refs/heads/sandbox/raito/raito-unstable-small" = {
name = "raito-unstable-sync";
fromUri = "https://github.com/NixOS/nixpkgs";
fromRefspec = "nixos-unstable-small";
localRefspec = "refs/remotes/origin/sandbox/raito/raito-unstable-small";
timer = "6 h";
};
branches."refs/heads/sandbox/raito/raito-nixos-24.05" = {
name = "raito-release-sync";
fromUri = "https://github.com/NixOS/nixpkgs";
fromRefspec = "nixos-24.05";
localRefspec = "refs/remotes/origin/sandbox/raito/raito-nixos-24.05";
timer = "24 h";
};
};
i18n.defaultLocale = "fr_FR.UTF-8";
system.stateVersion = "24.05";

View file

@ -7,6 +7,7 @@ let
hydra-s3-credentials = [ machines.bagel-box ];
hydra-ssh-key-priv = [ machines.bagel-box ];
netbox-environment = [ machines.meta01 ];
ows-deploy-key = [ machines.gerrit01 ];
};
in
builtins.listToAttrs (

BIN
secrets/ows-deploy-key.age Normal file

Binary file not shown.

View file

@ -23,6 +23,7 @@ in
imports = [
./www.nix
./one-way-sync.nix
];
config = mkIf cfg.enable {

View file

@ -0,0 +1,112 @@
{ lib, config, pkgs, ... }:
let
cfg = config.bagel.nixpkgs.one-way-sync;
inherit (lib) mkIf mkOption mkEnableOption types mapAttrs';
mkSyncTimer = { name, timer, ... }: {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = timer;
Persistent = true;
Unit = "ows-${name}.service";
};
};
mkSyncService = targetRef: { name, fromUri, fromRefspec, localRefspec, ... }: {
path = [ pkgs.gitFull ];
script = ''
set -eo pipefail
echo "Syncing ${fromUri}:${fromRefspec} to ${cfg.workingDir}/nixpkgs-${name}:${targetRef}"
cd ${cfg.workingDir}
git clone https://cl.forkos.org/nixpkgs --reference ${cfg.referenceDir} nixpkgs-${name} || true
cd nixpkgs-${name}
EXPECTED_REF=$(git rev-list ${localRefspec} | head -1)
git fetch ${fromUri} ${fromRefspec}
git rebase FETCH_HEAD ${localRefspec}
GIT_SSH_COMMAND='ssh -i ${cfg.deployKeyPath}' git push ${cfg.pushUrl} HEAD:${targetRef} --force-with-lease=${targetRef}:$EXPECTED_REF --force-if-includes
'';
serviceConfig = {
User = "git";
Group = "git";
Type = "oneshot";
RuntimeDirectory = "onewaysync";
WorkingDirectory = cfg.workingDir;
};
};
in
{
options.bagel.nixpkgs.one-way-sync = {
enable = mkEnableOption "the one-way sync from GitHub repositories";
referenceDir = mkOption {
type = types.str;
default = "/var/lib/gerrit/git/nixpkgs.git";
description = "Local repository reference";
};
workingDir = mkOption {
type = types.str;
default = "/run/onewaysync/";
description = "Working directory for the service";
};
pushUrl = mkOption {
type = types.str;
example = "ssh://...";
description = "Push URL for the target repository";
};
deployKeyPath = mkOption {
type = types.path;
example = "/run/agenix.d/ows-priv-key";
description = "Deployment private SSH key to push to the repository";
};
branches = mkOption {
type = types.attrsOf (types.submodule ({ ... }:
{
options = {
name = mkOption {
type = types.str;
description = "User-friendly name";
};
fromUri = mkOption {
type = types.str;
description = "Git URI from which we need to sync";
};
fromRefspec = mkOption {
type = types.str;
description = "refspec for the fetch";
};
localRefspec = mkOption {
type = types.str;
default = "local refspec in the local repository to get the expected reference and avoid stale info";
};
timer = mkOption {
type = types.str;
description = "Calendar format everytime we need to run the sync";
};
};
}));
description = "Set of branches mapping from cl.forkos.org to other Git repositories";
};
};
config = mkIf cfg.enable {
systemd.timers = mapAttrs' (name: value: {
name = "ows-${value.name}";
value = mkSyncTimer value;
}) cfg.branches;
systemd.services = mapAttrs' (name: value: {
name = "ows-${value.name}";
value = mkSyncService name value;
}) cfg.branches;
};
}