summary refs log tree commit diff
diff options
context:
space:
mode:
authorJulien Moutinho <julm+nixpkgs@sourcephile.fr>2021-12-01 08:08:56 +0100
committerTom Bereknyei <tomberek@gmail.com>2021-12-28 22:18:45 -0500
commit42da4f78d8b6f33367cb884b725ba65e51f8342d (patch)
tree6a1977137c00c632858bb9b7f3ef1f4b4109a04c
parentccd317468607965c8fa9e80261400bd2a69db573 (diff)
downloadnixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar.gz
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar.bz2
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar.lz
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar.xz
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.tar.zst
nixpkgs-42da4f78d8b6f33367cb884b725ba65e51f8342d.zip
nixos/sourcehut: add more tests
-rw-r--r--nixos/modules/services/misc/sourcehut/default.nix26
-rw-r--r--nixos/modules/services/misc/sourcehut/service.nix2
-rw-r--r--nixos/tests/sourcehut.nix174
3 files changed, 186 insertions, 16 deletions
diff --git a/nixos/modules/services/misc/sourcehut/default.nix b/nixos/modules/services/misc/sourcehut/default.nix
index f482c352397..1bd21c278e0 100644
--- a/nixos/modules/services/misc/sourcehut/default.nix
+++ b/nixos/modules/services/misc/sourcehut/default.nix
@@ -36,7 +36,7 @@ let
     (recursiveUpdate cfg.settings {
       # Those paths are mounted using BindPaths= or BindReadOnlyPaths=
       # for services needing access to them.
-      "builds.sr.ht::worker".buildlogs = "/var/log/sourcehut/buildsrht/logs";
+      "builds.sr.ht::worker".buildlogs = "/var/log/sourcehut/buildsrht-worker";
       "git.sr.ht".post-update-script = "/usr/bin/gitsrht-update-hook";
       "git.sr.ht".repos = "/var/lib/sourcehut/gitsrht/repos";
       "hg.sr.ht".changegroup-script = "/usr/bin/hgsrht-hook-changegroup";
@@ -345,7 +345,7 @@ in
           buildlogs = mkOption {
             description = "Path to write build logs.";
             type = types.str;
-            default = "/var/log/sourcehut/buildsrht";
+            default = "/var/log/sourcehut/buildsrht-worker";
           };
           name = mkOption {
             description = ''
@@ -656,7 +656,17 @@ in
     };
 
     builds = {
-      enableWorker = mkEnableOption "worker for builds.sr.ht";
+      enableWorker = mkEnableOption ''
+        worker for builds.sr.ht
+
+        <warning><para>
+        For smaller deployments, job runners can be installed alongside the master server
+        but even if you only build your own software, integration with other services
+        may cause you to run untrusted builds
+        (e.g. automatic testing of patches via listssrht).
+        See <link xlink:href="https://man.sr.ht/builds.sr.ht/configuration.md#security-model"/>.
+        </para></warning>
+      '';
 
       images = mkOption {
         type = with types; attrsOf (attrsOf (attrsOf package));
@@ -917,10 +927,12 @@ in
         '';
         serviceConfig = {
           ExecStart = "${pkgs.sourcehut.buildsrht}/bin/builds.sr.ht-worker";
-          RuntimeDirectory = [ "sourcehut/${serviceName}/subdir" ];
-          # builds.sr.ht-worker looks up ../config.ini
+          BindPaths = [ cfg.settings."builds.sr.ht::worker".buildlogs ];
           LogsDirectory = [ "sourcehut/${serviceName}" ];
+          RuntimeDirectory = [ "sourcehut/${serviceName}/subdir" ];
           StateDirectory = [ "sourcehut/${serviceName}" ];
+          TimeoutStartSec = "1800s";
+          # builds.sr.ht-worker looks up ../config.ini
           WorkingDirectory = "-"+"/run/sourcehut/${serviceName}/subdir";
         };
       };
@@ -975,7 +987,7 @@ in
           # Allow nginx access to buildlogs
           users.users.${nginx.user}.extraGroups = [ cfg.builds.group ];
           systemd.services.nginx = {
-            serviceConfig.BindReadOnlyPaths = [ "${cfg.settings."builds.sr.ht::worker".buildlogs}:/var/log/nginx/buildsrht/logs" ];
+            serviceConfig.BindReadOnlyPaths = [ cfg.settings."builds.sr.ht::worker".buildlogs ];
           };
           services.nginx.virtualHosts."logs.${domain}" = mkMerge [ {
             /* FIXME: is a listen needed?
@@ -984,7 +996,7 @@ in
               let address = split ":" cfg.settings."builds.sr.ht::worker".name; in
               [{ addr = elemAt address 0; port = lib.toInt (elemAt address 2); }];
             */
-            locations."/logs/".alias = "/var/log/nginx/buildsrht/logs/";
+            locations."/logs/".alias = cfg.settings."builds.sr.ht::worker".buildlogs + "/";
           } cfg.nginx.virtualHost ];
         })
       ];
diff --git a/nixos/modules/services/misc/sourcehut/service.nix b/nixos/modules/services/misc/sourcehut/service.nix
index b3c0efc07dd..f1706ad0a6a 100644
--- a/nixos/modules/services/misc/sourcehut/service.nix
+++ b/nixos/modules/services/misc/sourcehut/service.nix
@@ -214,7 +214,7 @@ in
 
     services.nginx = mkIf cfg.nginx.enable {
       virtualHosts."${srv}.${cfg.settings."sr.ht".global-domain}" = mkMerge [ {
-        forceSSL = true;
+        forceSSL = mkDefault true;
         locations."/".proxyPass = "http://${cfg.listenAddress}:${toString srvCfg.port}";
         locations."/static" = {
           root = "${pkgs.sourcehut.${srvsrht}}/${pkgs.sourcehut.python.sitePackages}/${srvsrht}";
diff --git a/nixos/tests/sourcehut.nix b/nixos/tests/sourcehut.nix
index 6492250bd57..d1536c59322 100644
--- a/nixos/tests/sourcehut.nix
+++ b/nixos/tests/sourcehut.nix
@@ -1,27 +1,175 @@
-import ./make-test-python.nix ({ pkgs, ... }:
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+let
+  domain = "sourcehut.localdomain";
 
+  # Note that wildcard certificates just under the TLD (eg. *.com)
+  # would be rejected by clients like curl.
+  tls-cert = pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
+    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 36500 \
+      -subj '/CN=${domain}' -extensions v3_req \
+      -addext 'subjectAltName = DNS:*.${domain}'
+    install -D -t $out key.pem cert.pem
+  '';
+
+  images = {
+    nixos.unstable.x86_64 =
+      let
+        systemConfig = { pkgs, ... }: {
+          # passwordless ssh server
+          services.openssh = {
+            enable = true;
+            permitRootLogin = "yes";
+            extraConfig = "PermitEmptyPasswords yes";
+          };
+
+          users = {
+            mutableUsers = false;
+            # build user
+            extraUsers."build" = {
+              isNormalUser = true;
+              uid = 1000;
+              extraGroups = [ "wheel" ];
+              password = "";
+            };
+            users.root.password = "";
+          };
+
+          security.sudo.wheelNeedsPassword = false;
+          nix.trustedUsers = [ "root" "build" ];
+          documentation.nixos.enable = false;
+
+          # builds.sr.ht-image-specific network settings
+          networking = {
+            hostName = "build";
+            dhcpcd.enable = false;
+            defaultGateway.address = "10.0.2.2";
+            usePredictableInterfaceNames = false;
+            interfaces."eth0".ipv4.addresses = [{
+              address = "10.0.2.15";
+              prefixLength = 25;
+            }];
+            enableIPv6 = false;
+            nameservers = [
+              # OpenNIC anycast
+              "185.121.177.177"
+              "169.239.202.202"
+              # Google
+              "8.8.8.8"
+            ];
+            firewall.allowedTCPPorts = [ 22 ];
+          };
+
+          environment.systemPackages = [
+            pkgs.gitMinimal
+            #pkgs.mercurial
+            pkgs.curl
+            pkgs.gnupg
+          ];
+        };
+        qemuConfig = { pkgs, ... }: {
+          imports = [ systemConfig ];
+          fileSystems."/".device = "/dev/disk/by-label/nixos";
+          boot.initrd.availableKernelModules = [
+            "ahci"
+            "ehci_pci"
+            "sd_mod"
+            "usb_storage"
+            "usbhid"
+            "virtio_balloon"
+            "virtio_blk"
+            "virtio_pci"
+            "virtio_ring"
+            "xhci_pci"
+          ];
+          boot.loader = {
+            grub = {
+              version = 2;
+              device = "/dev/vda";
+            };
+            timeout = 0;
+          };
+        };
+        config = (import (pkgs.path + "/nixos/lib/eval-config.nix") {
+          inherit pkgs; modules = [ qemuConfig ];
+          system = "x86_64-linux";
+        }).config;
+      in
+      import (pkgs.path + "/nixos/lib/make-disk-image.nix") {
+        inherit pkgs lib config;
+        diskSize = 16000;
+        format = "qcow2-compressed";
+        contents = [
+          { source = pkgs.writeText "gitconfig" ''
+              [user]
+                name = builds.sr.ht
+                email = build@sr.ht
+            '';
+            target = "/home/build/.gitconfig";
+            user = "build";
+            group = "users";
+            mode = "644";
+          }
+        ];
+      };
+  };
+
+in
 {
   name = "sourcehut";
 
   meta.maintainers = [ pkgs.lib.maintainers.tomberek ];
 
-  machine = { config, pkgs, ... }: {
-    virtualisation.memorySize = 2048;
-    networking.firewall.allowedTCPPorts = [ 80 ];
+  machine = { config, pkgs, nodes, ... }: {
+    # buildsrht needs space
+    virtualisation.diskSize = 4 * 1024;
+    virtualisation.memorySize = 2 * 1024;
+    networking.domain = domain;
+    networking.extraHosts = ''
+      ${config.networking.primaryIPAddress} meta.${domain}
+      ${config.networking.primaryIPAddress} builds.${domain}
+    '';
 
     services.sourcehut = {
       enable = true;
-      services = [ "meta" ];
-      redis.enable = true;
+      services = [ "meta" "builds" ];
+      nginx.enable = true;
+      nginx.virtualHost = {
+        forceSSL = true;
+        sslCertificate = "${tls-cert}/cert.pem";
+        sslCertificateKey = "${tls-cert}/key.pem";
+      };
       postgresql.enable = true;
+      redis.enable = true;
+
       meta.enable = true;
+      builds = {
+        enable = true;
+        # FIXME: see why it does not seem to activate fully.
+        #enableWorker = true;
+        inherit images;
+      };
       settings."sr.ht" = {
-        global-domain = "sourcehut";
+        global-domain = config.networking.domain;
         service-key = pkgs.writeText "service-key" "8b327279b77e32a3620e2fc9aabce491cc46e7d821fd6713b2a2e650ce114d01";
         network-key = pkgs.writeText "network-key" "cEEmc30BRBGkgQZcHFksiG7hjc6_dK1XR2Oo5Jb9_nQ=";
       };
+      settings."builds.sr.ht" = {
+        oauth-client-secret = pkgs.writeText "buildsrht-oauth-client-secret" "2260e9c4d9b8dcedcef642860e0504bc";
+        oauth-client-id = "299db9f9c2013170";
+      };
       settings.webhooks.private-key = pkgs.writeText "webhook-key" "Ra3IjxgFiwG9jxgp4WALQIZw/BMYt30xWiOsqD0J7EA=";
     };
+
+    networking.firewall.allowedTCPPorts = [ 443 ];
+    security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
+    services.nginx = {
+      enable = true;
+      recommendedGzipSettings = true;
+      recommendedOptimisation = true;
+      recommendedTlsSettings = true;
+      recommendedProxySettings = true;
+    };
+
     services.postgresql = {
       enable = true;
       enableTCPIP = false;
@@ -32,8 +180,18 @@ import ./make-test-python.nix ({ pkgs, ... }:
   testScript = ''
     start_all()
     machine.wait_for_unit("multi-user.target")
+
+    # Testing metasrht
+    machine.wait_for_unit("metasrht-api.service")
     machine.wait_for_unit("metasrht.service")
     machine.wait_for_open_port(5000)
-    machine.succeed("curl -sL http://localhost:5000 | grep meta.sourcehut")
+    machine.succeed("curl -sL http://localhost:5000 | grep meta.${domain}")
+    machine.succeed("curl -sL http://meta.${domain} | grep meta.${domain}")
+
+    # Testing buildsrht
+    machine.wait_for_unit("buildsrht.service")
+    machine.wait_for_open_port(5002)
+    machine.succeed("curl -sL http://localhost:5002 | grep builds.${domain}")
+    #machine.wait_for_unit("buildsrht-worker.service")
   '';
 })