about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-03-22 15:58:42 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-03-22 16:02:04 +0100
commitc633046cdda8e7a46ad7a9d85e0749f36e5ab0a8 (patch)
tree8be69736262c6c4b10b91cef6ec962d269eb8bb0
parentupdate.sh: Replace building and test running by the already existing scripts (diff)
downloadnixos-server-c633046cdda8e7a46ad7a9d85e0749f36e5ab0a8.zip
{modules,tests}/rocie: Init
-rw-r--r--flake.nix11
-rw-r--r--modules/by-name/co/constants/module.nix2
-rw-r--r--modules/by-name/ro/rocie/module.nix59
-rw-r--r--secrets.nix1
-rw-r--r--tests/by-name/ro/rocie/secrets/login.age16
-rw-r--r--tests/by-name/ro/rocie/test.nix106
6 files changed, 195 insertions, 0 deletions
diff --git a/flake.nix b/flake.nix
index 4c847b6..5263de7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -74,6 +74,15 @@
       url = "github:nix-community/impermanence";
       inputs = {};
     };
+    rocie = {
+      url = "git+https://git.foss-syndicate.org/bpeetz/rocie/nix?ref=prime";
+      inputs = {
+        nixpkgs.follows = "nixpkgs";
+        treefmt-nix.follows = "treefmt-nix";
+        crane.follows = "crane";
+        rust-overlay.follows = "rust-overlay";
+      };
+    };
     simple-nixos-mailserver = {
       url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.11";
       inputs = {
@@ -96,6 +105,7 @@
     disko,
     impermanence,
     simple-nixos-mailserver,
+    rocie,
     ...
   } @ attrs: let
     system = "x86_64-linux";
@@ -129,6 +139,7 @@
       disko.nixosModules.default
       impermanence.nixosModules.impermanence
       simple-nixos-mailserver.nixosModule
+      rocie.nixosModules.default
     ];
 
     tests = import ./tests {inherit pkgs specialArgs nixLib;};
diff --git a/modules/by-name/co/constants/module.nix b/modules/by-name/co/constants/module.nix
index 3de9608..b94020b 100644
--- a/modules/by-name/co/constants/module.nix
+++ b/modules/by-name/co/constants/module.nix
@@ -55,6 +55,7 @@
       grocy = 341;
       anubis = 342;
       postfix-tlspol = 343;
+      rocie = 344;
 
       # As per the NixOS file, the uids should not be greater or equal to 400;
     };
@@ -94,6 +95,7 @@
         systemd-coredump # matches systemd-coredump user
         resolvconf # This group is not matched to an user?
         stalwart-mail-certificates # This group is used to connect nginx and stalwart-mail
+        rocie
         ;
 
       # The gid should match the uid. Thus should not be >= 400;
diff --git a/modules/by-name/ro/rocie/module.nix b/modules/by-name/ro/rocie/module.nix
new file mode 100644
index 0000000..1e419b8
--- /dev/null
+++ b/modules/by-name/ro/rocie/module.nix
@@ -0,0 +1,59 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.vhack.rocie;
+  data = "/var/lib/rocie";
+in {
+  options.vhack.rocie = {
+    enable = lib.mkEnableOption "Rocie integration into vhack.eu";
+
+    domain = lib.mkOption {
+      type = lib.types.str;
+      description = "The domain where to deploy rocie";
+    };
+
+    loginSecret = lib.mkOption {
+      type = lib.types.path;
+      description = "The age encrypted secret file for rocie, passed to agenix";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    rocie = {
+      enable = true;
+      inherit (cfg) domain;
+
+      dbPath = "${data}/database.db";
+
+      secretKeyFile = config.age.secrets.rocie_secret.path;
+    };
+
+    vhack.persist.directories = [
+      {
+        directory = data;
+        user = "rocie";
+        group = "rocie";
+        mode = "0700";
+      }
+    ];
+
+    users = {
+      groups.rocie = {
+        gid = config.vhack.constants.ids.gids.rocie;
+      };
+      users.rocie = {
+        group = "rocie";
+        uid = config.vhack.constants.ids.uids.rocie;
+      };
+    };
+
+    age.secrets.rocie_secret = {
+      file = cfg.loginSecret;
+      mode = "700";
+      owner = "rocie";
+      group = "rocie";
+    };
+  };
+}
diff --git a/secrets.nix b/secrets.nix
index 8d3ae92..3af0afa 100644
--- a/secrets.nix
+++ b/secrets.nix
@@ -70,4 +70,5 @@ in
     "./tests/by-name/em/email-dns/secrets/dkim/bob.com/private.age".publicKeys = [soispha sils testingKey];
     "./tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/private.age".publicKeys = [soispha sils testingKey];
     "./tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/private.age".publicKeys = [soispha sils testingKey];
+    "./tests/by-name/ro/rocie/secrets/login.age".publicKeys = [soispha sils testingKey];
   }
diff --git a/tests/by-name/ro/rocie/secrets/login.age b/tests/by-name/ro/rocie/secrets/login.age
new file mode 100644
index 0000000..33d63be
--- /dev/null
+++ b/tests/by-name/ro/rocie/secrets/login.age
@@ -0,0 +1,16 @@
+-----BEGIN AGE ENCRYPTED FILE-----
+YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzMWE5dTBiU0hDUC9jUi93
+Y1phYllHRk9YSHBzUGQ2YmF5ZC9ydXNGV0JrClRpTjZZUHZ5MEFFa0VrYVVhTkE2
+eCtSaEU1YVlhNjFNYlRRYzNCdjhYRWMKLT4gWDI1NTE5IDUrZWdDUmpQcFBOcE0x
+UE5QRDR5NXVXUHdQOVk3UGV1S3lCc0pUQmZIZ00KUldVSVF3TzB0cHFVaDZuNlZR
+b2FoT0lVSTZydHFTNHhnQ3U0NGdSR1k1MAotPiBzc2gtZWQyNTUxOSBSc2dXcFEg
+dldGZU15UXgrRTMxRkp2MEVKUllWQ3VFdnJDMnM4OS8wc202WW9lNW5BYwpPWjV0
+cmNuaDlPZndtUVVScm5TaGlvVUhHa0JiN1MvbDhCTTUxYzNhM3RRCi0+IDxXeEhv
+cC1ncmVhc2UKM3N5OHRLNTJEY1NIeGlWYm9yR096Y1NpSlVOM1lYQk9jOHkxU3N2
+K2c3QitDYnR6QTJOOWczV0xBa2dEUE1PTQpYU2Z1elZwRzU0Tm1RVDE2VWVqekUw
+bFROLzU0c2NNTXYwL2N5QkxTaGtXUWxKVVF6SE0KLS0tIGlYMHIvUkJpZUR0SHo4
+cldLSTdnbU90SGJTcGZGaHkyOTZON0hka3BLdlEKeP4nHmKWvJfqgEXuiLBMzldi
+n1qIsnlF3IU1EA0abJg/RK1BFwWlx4wBlLmViw6UTL+VEw8lv23PuZl2t7UtXVzQ
+smXDapW8nInNmTaElBPdwJ072/dD0Ly+KF95Qr0FDDv+jlKG/D/Mw+xD4jvuJHSo
+2HQnPF6MLTjCxpyPPggleWgKrBQggHBjm/pHtOKmPC5qfp+LAjmQoJXny/0X6cA=
+-----END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/ro/rocie/test.nix b/tests/by-name/ro/rocie/test.nix
new file mode 100644
index 0000000..c2ba97a
--- /dev/null
+++ b/tests/by-name/ro/rocie/test.nix
@@ -0,0 +1,106 @@
+{
+  nixos-lib,
+  pkgsUnstable,
+  nixpkgs-unstable,
+  vhackPackages,
+  pkgs,
+  extraModules,
+  nixLib,
+  ...
+}:
+nixos-lib.runTest {
+  hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+  name = "rocie";
+
+  node = {
+    specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
+
+    # Use the nixpkgs as constructed by the `nixpkgs.*` options
+    pkgs = null;
+  };
+
+  nodes = {
+    acme = {...}: {
+      imports = [
+        ../../../common/acme/server.nix
+        ../../../common/dns/client.nix
+      ];
+    };
+    name_server = {nodes, ...}: {
+      imports =
+        extraModules
+        ++ [
+          ../../../common/acme/client.nix
+          ../../../common/dns/server.nix
+        ];
+
+      vhack.dns.zones = {
+        "rocie.server" = {
+          SOA = {
+            nameServer = "ns";
+            adminEmail = "admin@server.com";
+            serial = 2025012301;
+          };
+          useOrigin = false;
+
+          A = [
+            nodes.server.networking.primaryIPAddress
+          ];
+          AAAA = [
+            nodes.server.networking.primaryIPv6Address
+          ];
+        };
+      };
+    };
+
+    server = {config, ...}: {
+      imports =
+        extraModules
+        ++ [
+          ../../../../modules
+          ../../../common/acme/client.nix
+          ../../../common/dns/client.nix
+        ];
+
+      age.identityPaths = ["${../../../common/email/hostKey}"];
+
+      vhack = {
+        persist.enable = true;
+        nginx.enable = true;
+        rocie = {
+          enable = true;
+          domain = "rocie.server";
+          loginSecret = ./secrets/login.age;
+        };
+      };
+    };
+
+    client = {...}: {
+      imports = [
+        ../../../common/acme/client.nix
+        ../../../common/dns/client.nix
+      ];
+    };
+  };
+
+  testScript = {nodes, ...}: let
+    acme = import ../../../common/acme {inherit pkgs;};
+  in
+    acme.prepare ["server" "client"]
+    # Python
+    ''
+      server.wait_for_unit("rocie.service")
+
+      with subtest("All services running"):
+        import json
+        def all_services_running(host):
+          (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+          host_failed = json.loads(output)
+          assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+        all_services_running(server)
+
+      client.wait_until_succeeds("curl --verbose https://rocie.server/api/can-be-provisioned > out.file")
+      client.copy_from_vm("out.file")
+    '';
+}