diff --git a/flake.lock b/flake.lock index 61cde2d..9053311 100644 --- a/flake.lock +++ b/flake.lock @@ -746,6 +746,26 @@ "type": "github" } }, + "ofborg": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730127422, + "narHash": "sha256-mw03zyOQk0YFTWVuMuOMyEgbgOQgLqMIEHiiiGTYwvk=", + "ref": "refs/heads/main", + "rev": "829b4d2c458c1eaab932c1dcd62aa5873c68e208", + "revCount": 1450, + "type": "git", + "url": "https://git.lix.systems/the-distro/ofborg.git" + }, + "original": { + "type": "git", + "url": "https://git.lix.systems/the-distro/ofborg.git" + } + }, "pre-commit-hooks": { "flake": false, "locked": { @@ -794,6 +814,7 @@ ], "nix-gerrit": "nix-gerrit", "nixpkgs": "nixpkgs_2", + "ofborg": "ofborg", "stateless-uptime-kuma": "stateless-uptime-kuma", "terranix": "terranix" } diff --git a/flake.nix b/flake.nix index dfcb73f..7c5ab12 100644 --- a/flake.nix +++ b/flake.nix @@ -19,6 +19,9 @@ nix-gerrit.url = "git+https://git.lix.systems/the-distro/nix-gerrit.git?ref=refs/heads/bump-minor-3_10"; nix-gerrit.inputs.nixpkgs.follows = "nixpkgs"; + ofborg.url = "git+https://git.lix.systems/the-distro/ofborg.git"; + ofborg.inputs.nixpkgs.follows = "nixpkgs"; + gerrit-dashboard.url = "git+https://git.lix.systems/the-distro/gerrit-monitoring.git"; gerrit-dashboard.flake = false; @@ -58,6 +61,9 @@ inputs.lix.overlays.default inputs.nix-gerrit.overlays.default inputs.channel-scripts.overlays.default + (super: self: { + inherit (inputs.ofborg.packages.${system}) ofborg; + }) (import "${inputs.stateless-uptime-kuma}/overlay.nix") ]; }; diff --git a/hosts/bagel-box/default.nix b/hosts/bagel-box/default.nix index 201cb88..13d4360 100644 --- a/hosts/bagel-box/default.nix +++ b/hosts/bagel-box/default.nix @@ -37,7 +37,10 @@ bagel.services = { postgres.enable = true; - ofborg.enable = true; + ofborg = { + rabbitmq.enable = true; + builder.enable = true; + }; }; bagel.sysadmin.enable = true; diff --git a/secrets.nix b/secrets.nix index 193c217..bbeb35b 100644 --- a/secrets.nix +++ b/secrets.nix @@ -46,6 +46,7 @@ let postgres-ca-priv = [ machines.bagel-box ]; postgres-tls-priv = [ machines.bagel-box ]; + rabbitmq-password = [ machines.bagel-box ]; newsletter-secrets = [ machines.public01 ]; s3-revproxy-api-keys = [ machines.public01 ]; diff --git a/secrets/floral/rabbitmq-password.age b/secrets/floral/rabbitmq-password.age new file mode 100644 index 0000000..7f2434e --- /dev/null +++ b/secrets/floral/rabbitmq-password.age @@ -0,0 +1,20 @@ +age-encryption.org/v1 +-> ssh-ed25519 +HUDfA N/08Rh4cN52OOLk3Mp7n71mqU0zRvXeFr+HNXPVudSw +txBFV3BJLmUng4cq5AEuSHQ4wUozc82hbMH9eA4AcqU +-> ssh-ed25519 +qVung ryhY0CsF0pyJoCFGHdVaBS3S1rbEwPx6K/xEmKeI8js +2dvCxR1w1uEf1Qq7lRqZJfGRUw2gsKH5DgrPe5HWUk0 +-> ssh-rsa krWCLQ +adfK11ogZxXsenyFYgyIgOSsekwDTcMmOdTD4GXPjGGSOfXhxOTq9CsWfMksSDXq +HIPTZLK7oYSvlNxvnqITGv4ESJGQMBat3TjZ4TTb2+hczWpzg3CqMeNluPDX4A2h +dr+0TZH3XuHOuCrmukQ/EirBxnODBtSPqheZLqp562nrrpxDqqKdJkzwYWamu9H3 +S2pZFYtWe1YX0+1dooH/KqCTCR6yI7u0g9J/uxP2uPN2pgvD95mSpzd7nvfsKv7b +kejB/5Gg5w0WNYwqi7uTnrL8l7WVtYLdIziK83RGviau5Grtuv+18Mj/a8YeupiQ +B2tCRddiS/1DvlfobRtqtw +-> ssh-ed25519 /vwQcQ sHef1IQRAJXykiG82Madjb+FTaNZKg2PpJONHmEKsEU +NuBmo4GlVYc7Asy4gGiAE6Be2xS8t9ZYDgI8cF0rHms +-> ssh-ed25519 0R97PA wQLniyviNyifUhEIlFqk+kDKNo5AUy4Vrh/gGweGygM +7v/82hVu8d+RuZGxq9xmAiacv0ddUW7HDVGKVFgYrAw +-> ssh-ed25519 K3b7BA SUF2L0mvu+7Pn8NZArC3tT7sr4FivAUjFexWXnLfckc +QDnle9e13/Ch9DjXdYDzC1jsCH81HB2m+97CaRrZLAI +--- PMNk1z2Vk3cRHqaB3G1/giBnOVduxex6tfwR3ihc4pE +Mõשcý^•¯ˆà)5m÷"Hßïî¸þY7fs+RÖ£o/J 1N˜ˆe®æF£]¹Þ¥AöÔÐÆO¤¸£·&òþÖÁ \ No newline at end of file diff --git a/services/ofborg/default.nix b/services/ofborg/default.nix index d80d796..80f3d19 100644 --- a/services/ofborg/default.nix +++ b/services/ofborg/default.nix @@ -1,37 +1,101 @@ -{ config, lib, ... }: +{ pkgs, config, lib, ... }: let + inherit (lib) mkIf mkMerge; cfg = config.bagel.services.ofborg; amqpHost = "amqp.forkos.org"; amqpPort = 5671; + generators = pkgs.formats.json { }; + configFile = generators.generate "ofborg-config.json" config.bagel.services.ofborg.settings; + mkOfborgWorker = binaryName: extra: extra // { + wantedBy = [ "multi-user.target" ]; + description = "ofborg CI service - ${binaryName} worker"; + after = [ "rabbitmq.service" ]; + serviceConfig = { + DynamicUser = true; + ExecStart = "${cfg.package}/bin/${binaryName} ${configFile}"; + # TODO: more hardening. + StateDirectory = "ofborg"; + LogsDirectory = "ofborg"; + WorkingDirectory = "/var/lib/ofborg"; + LoadCredential = [ "rabbitmq-password:${config.age.secrets.rabbitmq-password.path}" ]; + }; + }; in { options.bagel.services.ofborg = with lib; { - enable = mkEnableOption "ofborg coordinator"; + rabbitmq.enable = mkEnableOption "ofborg AMQP queue"; + builder.enable = mkEnableOption "ofborg builder worker"; + + package = mkPackageOption pkgs "ofborg" { }; + + settings = mkOption { + type = generators.type; + }; }; - config = lib.mkIf cfg.enable { - services.rabbitmq = { - enable = true; - configItems = { - "listeners.tcp" = "none"; - "listeners.ssl.default" = builtins.toString amqpPort; + config = mkMerge [ + { + age.secrets.rabbitmq-password.file = ../../secrets/floral/rabbitmq-password.age; + # TODO: move this to global. + bagel.services.ofborg.settings = { + rabbitmq = { + ssl = true; + host = "amqp.forkos.org"; + virtualhost = "amqp.forkos.org"; + username = "worker"; + password_file = "$CREDENTIALS_DIRECTORY/rabbitmq-password"; + }; + feedback.full_logs = lib.mkDefault true; + log_storage.path = lib.mkDefault "/var/log/ofborg"; + runner = { + identity = config.networking.fqdn; + repos = lib.mkDefault [ + "nixpkgs" + "ofborg" + ]; - "ssl_options.certfile" = "${config.security.acme.certs.${amqpHost}.directory}/cert.pem"; - "ssl_options.keyfile" = "${config.security.acme.certs.${amqpHost}.directory}/key.pem"; + disable_trusted_users = true; + }; + checkout.root = lib.mkDefault "/var/lib/ofborg/checkouts"; + nix = { + system = "x86_64-linux"; + remote = "daemon"; + build_timeout_seconds = 3600; + initial_heap_size = "4g"; + }; + }; + } + (mkIf cfg.rabbitmq.enable { + services.nginx.enable = true; + services.rabbitmq = { + enable = true; + configItems = { + "listeners.tcp" = "none"; + "listeners.ssl.default" = builtins.toString amqpPort; + "ssl_options.certfile" = "${config.security.acme.certs.${amqpHost}.directory}/cert.pem"; + "ssl_options.keyfile" = "${config.security.acme.certs.${amqpHost}.directory}/key.pem"; + }; }; - }; - security.acme.certs.${amqpHost} = { - webroot = "/var/lib/acme/.challenges"; - group = "rabbitmq"; - }; + security.acme.certs.${amqpHost} = { + webroot = "/var/lib/acme/.challenges"; + group = "rabbitmq"; + }; + services.nginx.virtualHosts.${amqpHost}.locations."/.well-known/acme-challenge".root = + "/var/lib/acme/.challenges"; + systemd.services.rabbitmq.requires = ["acme-finished-${amqpHost}.target"]; - services.nginx.enable = true; - services.nginx.virtualHosts.${amqpHost}.locations."/.well-known/acme-challenge".root = - "/var/lib/acme/.challenges"; - systemd.services.rabbitmq.requires = ["acme-finished-${amqpHost}.target"]; - - networking.firewall.allowedTCPPorts = [ 80 443 amqpPort ]; - }; + networking.firewall.allowedTCPPorts = [ amqpPort ]; + }) + (mkIf cfg.builder.enable { + systemd.services.ofborg-builder = mkOfborgWorker "builder" { }; + }) + ]; + # systemd.services.ofborg-stats = {}; + # systemd.services.ofborg-log-message-collector = {}; + # systemd.services.ofborg-evaluation-filter = {}; + # systemd.services.ofborg-vcs-comment-filter = {}; + # systemd.services.ofborg-vcs-comment-poster = {}; + # systemd.services.ofborg-mass-rebuilder = {}; }