summary refs log tree commit diff stats
path: root/modules/by-name/ba/back
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/ba/back')
-rw-r--r--modules/by-name/ba/back/module.nix107
1 files changed, 107 insertions, 0 deletions
diff --git a/modules/by-name/ba/back/module.nix b/modules/by-name/ba/back/module.nix
new file mode 100644
index 0000000..c02b5b5
--- /dev/null
+++ b/modules/by-name/ba/back/module.nix
@@ -0,0 +1,107 @@
+{
+  config,
+  lib,
+  vhackPackages,
+  pkgs,
+  ...
+}: let
+  cfg = config.vhack.back;
+
+  mkUnit = repoPath: port: {
+    description = "Back service for ${repoPath}";
+    wants = ["network-online.target"];
+    after = ["network-online.target"];
+    wantedBy = ["default.target"];
+
+    environment = {
+      ROCKET_PORT = builtins.toString port;
+    };
+
+    serviceConfig = {
+      ExecStart = "${lib.getExe vhackPackages.back} ${lib.strings.escapeShellArg repoPath}";
+
+      # Ensure that the service can read the repository
+      # FIXME(@bpeetz): This has the implied assumption, that all the exposed git
+      # repositories are readable for the git group. This should not be necessary. <2024-12-23>
+      User = "git";
+      Group = "git";
+
+      DynamicUser = true;
+      Restart = "always";
+
+      # Sandboxing
+      ProtectSystem = "strict";
+      ProtectHome = true;
+      PrivateTmp = true;
+      PrivateDevices = true;
+      ProtectHostname = true;
+      ProtectClock = true;
+      ProtectKernelTunables = true;
+      ProtectKernelModules = true;
+      ProtectKernelLogs = true;
+      ProtectControlGroups = true;
+      RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
+      RestrictNamespaces = true;
+      LockPersonality = true;
+      MemoryDenyWriteExecute = true;
+      RestrictRealtime = true;
+      RestrictSUIDSGID = true;
+      RemoveIPC = true;
+      PrivateMounts = true;
+      # System Call Filtering
+      SystemCallArchitectures = "native";
+      SystemCallFilter = ["~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"];
+    };
+  };
+
+  mkVirtalHost = port: {
+    locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}";
+
+    enableACME = true;
+    forceSSL = true;
+  };
+
+  services =
+    lib.mapAttrs' (gitPath: config: {
+      name = builtins.replaceStrings ["/"] ["_"] "back-${gitPath}-${config.domain}";
+      value = mkUnit gitPath config.port;
+    })
+    cfg.repositories;
+
+  virtualHosts =
+    lib.mapAttrs' (gitPath: config: {
+      name = config.domain;
+      value = mkVirtalHost config.port;
+    })
+    cfg.repositories;
+in {
+  options.vhack.back = {
+    enable = lib.mkEnableOption "Back issue tracker (inspired by tvix's panettone)";
+
+    repositories = lib.mkOption {
+      description = "An attibute set of repos to launch `back` services for.";
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          enable = (lib.mkEnableOption "`back` for this repository.") // {default = true;};
+          domain = lib.mkOption {
+            type = lib.types.str;
+            description = "The domain to host this `back` instance on.";
+          };
+          port = lib.mkOption {
+            type = lib.types.port;
+
+            # TODO: This _should_ be an implementation detail, but I've no real approach to
+            # automatically generate them without encountering weird bugs. <2024-12-23>
+            description = "The port to use for this back instance. This must be unique.";
+          };
+        };
+      });
+      default = {};
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    systemd = {inherit services;};
+    services.nginx = {inherit virtualHosts;};
+  };
+}