diff --git a/trivionomicon/flake.nix b/trivionomicon/flake.nix index f2ee049..2b53ebd 100644 --- a/trivionomicon/flake.nix +++ b/trivionomicon/flake.nix @@ -9,11 +9,11 @@ nixpkgs, flake-utils, }: let - mapOverlayOverride = namespace: overlay: final: prev: let + mapOverlayOverride = prefix: overlay: final: prev: let overlayPkgs = overlay final prev; in { - "${namespace}" = builtins.removeAttrs overlayPkgs ["override"]; + "${prefix}" = (prev.${prefix} or {}) // builtins.removeAttrs overlayPkgs ["override"]; } // (overlayPkgs.override or {}); @@ -30,7 +30,7 @@ packages = (import nixpkgs { inherit system; - overlays = [(mapOverlayOverride doctrineNoPkgs.prefix (import ./pkgs))]; + overlays = [self.overlays.default]; }).${ doctrineNoPkgs.prefix }; @@ -121,7 +121,7 @@ } # NB: Preserve the relative order { - overlay = self.overlays.default; + overlay = mapOverlayOverride prefix (import ./pkgs); condition = true; } { @@ -164,24 +164,12 @@ } // optionalAttrs (paths ? nixosSource) { nixosConfigurations = let - nixosSystem = {modules}: - lib.makeOverridable nixpkgs.lib.nixosSystem { - inherit modules pkgs system; - - specialArgs = { - inherit flakes; - - doctrine = mkDoctrine { - inherit pkgs; - namespace = "sys"; - }; - }; - }; - hostConfig = platform: - nixosSystem { + self.lib.mkSystem { + inherit flakes pkgs; + doctrine = doctrineNoPkgs; + modules = [ - self.nixosModules.default nixosSourcePath platform ]; @@ -213,6 +201,29 @@ in lib.mapAttrs home (importAll {root = hmPlatformsPath;}); }; + + mkSystem = { + pkgs, + flakes, + doctrine, + modules, + }: + flakes.nixpkgs.lib.makeOverridable flakes.nixpkgs.lib.nixosSystem { + inherit pkgs; + inherit (pkgs) system; + + modules = [self.nixosModules.default] ++ modules; + + specialArgs = { + inherit flakes; + + doctrine = self.lib.mkDoctrine { + inherit pkgs; + inherit (doctrine) prefix; + namespace = "sys"; + }; + }; + }; }; }; } diff --git a/trivionomicon/modules/soju/default.nix b/trivionomicon/modules/soju/default.nix new file mode 100644 index 0000000..2b302f0 --- /dev/null +++ b/trivionomicon/modules/soju/default.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + pkgs, + doctrine, + ... +}: +doctrine.lib.mkModule { + inherit config; + name = "soju"; + sys = ./sys.nix; + options = ./options.nix; +} diff --git a/trivionomicon/modules/soju/options.nix b/trivionomicon/modules/soju/options.nix new file mode 100644 index 0000000..06c3381 --- /dev/null +++ b/trivionomicon/modules/soju/options.nix @@ -0,0 +1,16 @@ +{lib, ...}: +with lib.types; { + sys = { + fullyQualifiedDomain = lib.mkOption { + type = str; + example = "soju.trivionomicon.com"; + description = "fully qualified domain name to be used by soju"; + }; + + port = lib.mkOption { + type = port; + default = 6697; + description = "port to be used by soju"; + }; + }; +} diff --git a/trivionomicon/modules/soju/sys.nix b/trivionomicon/modules/soju/sys.nix new file mode 100644 index 0000000..83c3560 --- /dev/null +++ b/trivionomicon/modules/soju/sys.nix @@ -0,0 +1,47 @@ +{ + config, + pkgs, + lib, + cfg, + doctrine, + ... +}: +with lib; { + security.acme.certs."${cfg.fullyQualifiedDomain}" = { + reloadServices = ["soju.service"]; + group = "soju"; + }; + + networking.firewall.allowedTCPPorts = [cfg.port]; + + services.soju = let + sojuCertDir = config.security.acme.certs."${cfg.fullyQualifiedDomain}".directory; + in { + enable = true; + hostName = "${cfg.fullyQualifiedDomain}"; + listen = ["ircs://[::]:${toString cfg.port}"]; + tlsCertificate = "${sojuCertDir}/fullchain.pem"; + tlsCertificateKey = "${sojuCertDir}/key.pem"; + }; + + systemd.services.soju = { + after = ["acme-${cfg.fullyQualifiedDomain}.service"]; + serviceConfig = { + DynamicUser = mkForce false; # fuck dynamic users + User = "soju"; + Group = "soju"; + ProtectSystem = "strict"; + ProtectHome = "read-only"; + PrivateTmp = true; + RemoveIPC = true; + }; + }; + + users = { + users.soju = { + isSystemUser = true; + group = "soju"; + }; + groups.soju = {}; + }; +} diff --git a/trivionomicon/pkgs/default.nix b/trivionomicon/pkgs/default.nix index 484ca77..4a275a3 100644 --- a/trivionomicon/pkgs/default.nix +++ b/trivionomicon/pkgs/default.nix @@ -5,5 +5,6 @@ in { override = {}; athena-bccr = callPackage ./athena-bccr {}; + snapborg = final.python3Packages.callPackage ./snapborg {}; spliit = callPackage ./spliit {}; } diff --git a/trivionomicon/pkgs/snapborg/0001-Remove-env-arg-from-subprocess-calls.patch b/trivionomicon/pkgs/snapborg/0001-Remove-env-arg-from-subprocess-calls.patch new file mode 100644 index 0000000..33f7a0c --- /dev/null +++ b/trivionomicon/pkgs/snapborg/0001-Remove-env-arg-from-subprocess-calls.patch @@ -0,0 +1,29 @@ +From c363931656938f9cc3354b8e2797fe9abac1b0e3 Mon Sep 17 00:00:00 2001 +From: Alejandro Soto +Date: Sun, 31 Aug 2025 13:30:45 -0600 +Subject: [PATCH] Remove "env" arg from subprocess calls + +--- + snapborg/borg.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/snapborg/borg.py b/snapborg/borg.py +index 89a3d84..b74ddf7 100644 +--- a/snapborg/borg.py ++++ b/snapborg/borg.py +@@ -173,11 +173,10 @@ def launch_borg(args, password=None, print_output=False, dryrun=False, cwd=None) + # TODO: parse output from JSON log lines + try: + if print_output: +- subprocess.run(cmd, env=env, check=True, cwd=cwd) ++ subprocess.run(cmd, check=True, cwd=cwd) + else: + subprocess.check_output(cmd, + stderr=subprocess.STDOUT, +- env=env, + cwd=cwd) + except CalledProcessError as e: + if e.returncode == 1: +-- +2.49.0 + diff --git a/trivionomicon/pkgs/snapborg/default.nix b/trivionomicon/pkgs/snapborg/default.nix new file mode 100644 index 0000000..271be5c --- /dev/null +++ b/trivionomicon/pkgs/snapborg/default.nix @@ -0,0 +1,34 @@ +{ + borgbackup, + buildPythonApplication, + fetchFromGitHub, + lib, + packaging, + pyyaml, +}: +buildPythonApplication { + pname = "snapborg"; + version = "0.1.0-unstable-20250331"; + + src = fetchFromGitHub { + repo = "snapborg"; + owner = "enzingerm"; + + rev = "7e860395319f995161a6e0c7954ce47635e3cd59"; + hash = "sha256-RzYL4IHulk1Q/ALWFs6YCTeCO8ohwqXH2NMHRctRVSA="; + }; + + patches = [ + ./0001-Remove-env-arg-from-subprocess-calls.patch # Fixes broken $PATH when calling borg + ]; + + propagatedBuildInputs = [ + borgbackup + packaging + pyyaml + ]; + + preFixup = '' + makeWrapperArgs+=(--prefix PATH : ${lib.makeBinPath [borgbackup]}) + ''; +}