From be9fb9278e18e48093693e74b894eccf96e1b549 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Fri, 11 Apr 2025 14:24:41 +0200 Subject: [PATCH 01/10] export symfony cli --- flake.lock | 36 ++++++++++----------- flake.nix | 14 +++++--- symfony-cli/package.nix | 72 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 symfony-cli/package.nix diff --git a/flake.lock b/flake.lock index 1f4c50c..af8f13e 100644 --- a/flake.lock +++ b/flake.lock @@ -95,11 +95,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1743783972, - "narHash": "sha256-5wPsNCnWmeLpLxavsftA9L7tnYgtlexV7FwLegxtpy4=", + "lastModified": 1744298740, + "narHash": "sha256-m5RnbHQqYQhQA4ntohXlJsiIsOAKx+pz/vOC+E+FmHg=", "owner": "cachix", "repo": "devenv", - "rev": "2f53e2f867e0c2ba18b880e66169366e5f8ca554", + "rev": "028c6a38fb0284c96691176bd31626bf36981129", "type": "github" }, "original": { @@ -350,11 +350,11 @@ }, "hardware": { "locked": { - "lastModified": 1743420942, - "narHash": "sha256-b/exDDQSLmENZZgbAEI3qi9yHkuXAXCPbormD8CSJXo=", + "lastModified": 1744366945, + "narHash": "sha256-OuLhysErPHl53BBifhesrRumJNhrlSgQDfYOTXfgIMg=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "de6fc5551121c59c01e2a3d45b277a6d05077bc4", + "rev": "1fe3cc2bc5d2dc9c81cb4e63d2f67c1543340df1", "type": "github" }, "original": { @@ -504,11 +504,11 @@ "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1744137608, - "narHash": "sha256-KEuKL7lM2ZqKzvaGIptVDAce29CAR4ZSgWtFD3PnpB0=", + "lastModified": 1744369853, + "narHash": "sha256-rVW9J8gMUFj8PsFV2TgNiNuJd8+O+FUizEQgl1ooQFY=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "d20b15f629985fe6900925bef462f947e4a75b2f", + "rev": "c2b4dd2f85d558c7147bc06c6417f87aa1775ad5", "type": "github" }, "original": { @@ -581,11 +581,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1743975612, - "narHash": "sha256-o4FjFOUmjSRMK7dn0TFdAT0RRWUWD+WsspPHa+qEQT8=", + "lastModified": 1744168086, + "narHash": "sha256-S9M4HddBCxbbX1CKSyDYgZ8NCVyHcbKnBfoUXeRu2jQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a880f49904d68b5e53338d1e8c7bf80f59903928", + "rev": "60e405b241edb6f0573f3d9f944617fe33ac4a73", "type": "github" }, "original": { @@ -677,11 +677,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1743964447, - "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", + "lastModified": 1744098102, + "narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", + "rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7", "type": "github" }, "original": { @@ -802,11 +802,11 @@ ] }, "locked": { - "lastModified": 1744079607, - "narHash": "sha256-5cog6Qd6w/bINdLO5mOysAHOHey8PwFXk4IWo+y+Czg=", + "lastModified": 1744338850, + "narHash": "sha256-pwMIVmsb8fjjT92n5XFDqCsplcX70qVMMT7NulumPXs=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "f6b62cc99c25e79a1c17e9fca91dc6b6faebec6c", + "rev": "5e64aecc018e6f775572609e7d7485fdba6985a7", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3ff0627..357ce0e 100644 --- a/flake.nix +++ b/flake.nix @@ -70,10 +70,16 @@ ]; }; - packages = lib.packagesFromDirectoryRecursive { - inherit (pkgs) callPackage; - directory = ./packages; - }; + packages = + lib.packagesFromDirectoryRecursive { + inherit (pkgs) callPackage; + directory = ./packages; + } + // { + symfony-cli = pkgs.callPackage ./symfony-cli/package.nix { + fossarPhps = inputs'.phps.packages; + }; + }; }; }; } diff --git a/symfony-cli/package.nix b/symfony-cli/package.nix new file mode 100644 index 0000000..4f2101c --- /dev/null +++ b/symfony-cli/package.nix @@ -0,0 +1,72 @@ +{ + lib, + fossarPhps, + symlinkJoin, + symfony-cli, + makeWrapper, +}: let + supportedPhps = [ + "php72" + "php73" + "php74" + "php80" + "php81" + "php82" + "php83" + "php84" + ]; + + extraConfig = '' + memory_limit = -1 + + xdebug.mode = develop,coverage,gcstats,profile,debug,trace + xdebug.discover_client_host = 1 + xdebug.client_host = localhost + ''; + + # Wrap all PHP versions with the extensions I need and bundle composer + phps = lib.genAttrs supportedPhps ( + phpName: let + phpBase = fossarPhps.${phpName}; + phpWithEnv = phpBase.buildEnv { + extensions = { + enabled, + all, + }: + enabled + ++ [all.xdebug] + ++ ( + if (lib.versionAtLeast phpBase.version "8") + then [all.amqp] + else [] + ); + inherit extraConfig; + }; + phpWithTools = symlinkJoin { + inherit (phpWithEnv) name version meta passthru; + paths = [ + phpWithEnv + phpWithEnv.packages.composer + ]; + }; + in + phpWithTools + ); + + package = symfony-cli; +in + # Tell Symfony's CLI where it can access the different PHP versions + symlinkJoin { + inherit (package) pname version meta; + + paths = [package]; + + buildInputs = [makeWrapper]; + + postBuild = '' + wrapProgram $out/bin/${package.meta.mainProgram} \ + --suffix PATH : ${lib.makeBinPath ( + builtins.attrValues phps + )} + ''; + } From b8af0e9761b8b819190c2507ad56bebab47948f4 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 11 May 2025 22:49:04 +0200 Subject: [PATCH 02/10] whatever --- .envrc | 10 +- classes/headful/clipboard.nix | 3 - classes/headful/codium.nix | 6 - classes/headful/cosmic.nix | 17 - classes/headful/devenv.nix | 3 - classes/headful/flatpak.nix | 7 - classes/headful/fonts.nix | 27 - classes/headful/hardware.nix | 10 - classes/headful/location.nix | 3 - classes/headful/mullvad.nix | 6 - classes/headful/networking.nix | 10 - classes/headful/pipewire.nix | 11 - classes/headful/printing.nix | 6 - classes/headful/wayland.nix | 6 - classes/headful/xdg.nix | 3 - classes/headless/networking.nix | 3 - classes/headless/time.nix | 3 - common/agenix.nix | 3 +- common/boot.nix | 11 +- common/bottom.nix | 5 +- common/fish.nix | 3 +- common/gc.nix | 7 - common/gitui.nix | 3 +- common/helix.nix | 25 +- common/networking.nix | 8 +- common/nh.nix | 17 + common/nix-index-database.nix | 3 +- common/nix.nix | 8 +- common/pubkeys.nix | 10 +- common/puter.nix | 12 - common/ripgrep.nix | 3 +- common/rsync.nix | 25 + common/shpool.nix | 6 + common/ssh.nix | 2 +- common/syncthing.nix | 6 +- common/tailscale.nix | 3 +- common/users.nix | 10 +- common/wheel.nix | 3 +- common/zellij.nix | 3 +- devenv.nix | 21 - flake.lock | 657 +++++++----------- flake.nix | 88 +-- hosts/{headless => }/abacus/acme.nix | 0 .../{headless => }/abacus/authorized-keys.nix | 3 +- hosts/{headless => }/abacus/filesystems.nix | 7 +- hosts/{headless => }/abacus/forgejo.nix | 46 +- hosts/{headless => }/abacus/hardware.nix | 11 +- hosts/{headless => }/abacus/headscale.nix | 16 +- hosts/{headless => }/abacus/mealie.nix | 16 +- hosts/{headless => }/abacus/navidrome.nix | 16 +- hosts/abacus/networking.nix | 23 + hosts/abacus/nginx.nix | 32 + hosts/{headless => }/abacus/postgresql.nix | 0 hosts/abacus/restic.nix | 41 ++ hosts/abacus/static-sites.nix | 34 + hosts/{headful/flamingo => abacus}/system.nix | 0 hosts/{headless => }/abacus/vaultwarden.nix | 18 +- .../work => flamingo}/filesystems.nix | 2 +- hosts/{headful => }/flamingo/hardware.nix | 12 +- .../{headful/glacier => flamingo}/system.nix | 0 .../flamingo => glacier}/filesystems.nix | 2 +- hosts/{headful => }/glacier/hardware.nix | 18 +- hosts/glacier/profiles.nix | 9 + .../{headful/insomniac => glacier}/system.nix | 0 hosts/{headful => }/glacier/users.nix | 0 hosts/headful/flamingo/libreoffice.nix | 5 - hosts/headful/flamingo/librewolf.nix | 5 - hosts/headful/flamingo/mpv.nix | 5 - hosts/headful/flamingo/supersonic.nix | 5 - hosts/headful/glacier/gimp.nix | 5 - hosts/headful/glacier/inkscape.nix | 5 - hosts/headful/glacier/lanzaboote.nix | 3 - hosts/headful/glacier/libreoffice.nix | 5 - hosts/headful/glacier/librewolf.nix | 5 - hosts/headful/glacier/mpv.nix | 5 - hosts/headful/glacier/steam.nix | 6 - hosts/headful/glacier/supersonic.nix | 5 - hosts/headful/insomniac/cosmic.nix | 17 - hosts/headful/insomniac/dolphin.nix | 5 - hosts/headful/insomniac/flatpak.nix | 6 - hosts/headful/insomniac/freetube.nix | 5 - hosts/headful/insomniac/rmg.nix | 5 - hosts/headful/insomniac/steam.nix | 5 - hosts/headful/insomniac/supersonic.nix | 5 - hosts/headful/work/kubectl.nix | 6 - hosts/headful/work/php.nix | 95 --- hosts/headful/work/supersonic.nix | 5 - hosts/headful/work/syncthing.nix | 3 - hosts/headless/abacus/backup.nix | 30 - hosts/headless/abacus/networking.nix | 18 - hosts/headless/abacus/nginx.nix | 30 - hosts/headless/abacus/static-sites.nix | 32 - hosts/headless/vessel/backup.nix | 61 -- hosts/headless/vessel/blocky.nix | 27 - hosts/headless/vessel/filesystems.nix | 14 - hosts/headless/vessel/musicomp.nix | 37 - hosts/headless/vessel/storage.nix | 27 - hosts/{headful => }/insomniac/filesystems.nix | 2 +- hosts/insomniac/freetube.nix | 6 + hosts/{headful => }/insomniac/hardware.nix | 15 +- hosts/{headful/work => insomniac}/system.nix | 0 hosts/{headful => }/insomniac/users.nix | 6 +- hosts/vessel/filesystems.nix | 24 + hosts/{headless => }/vessel/hardware.nix | 14 +- hosts/vessel/musicomp.nix | 45 ++ hosts/vessel/restic.nix | 56 ++ hosts/vessel/rsync.nix | 7 + hosts/vessel/storage.nix | 16 + hosts/{headless/abacus => vessel}/system.nix | 0 hosts/{headful => }/work/docker.nix | 3 +- .../{headful/glacier => work}/filesystems.nix | 2 +- hosts/{headful => }/work/hardware.nix | 17 +- hosts/{headful => }/work/hosts.nix | 0 hosts/work/php.nix | 22 + hosts/{headful => }/work/plasma.nix | 5 +- hosts/{headless/vessel => work}/system.nix | 0 hosts/{headful => }/work/tools.nix | 3 +- hosts/{headful => }/work/users.nix | 6 +- lib.nix | 97 ++- modules/gcadapter.nix | 27 + modules/main-user.nix | 6 +- modules/rsync.nix | 208 ++++++ modules/secure-boot.nix | 28 - modules/user-types.nix | 25 +- profiles/desktop/clipboard.nix | 16 + profiles/desktop/compat.nix | 33 + profiles/desktop/cosmic.nix | 29 + profiles/desktop/default.nix | 29 + profiles/desktop/firefox.nix | 25 + profiles/desktop/fonts.nix | 48 ++ profiles/desktop/hardware.nix | 22 + profiles/desktop/location.nix | 13 + profiles/desktop/networking.nix | 20 + profiles/desktop/pipewire.nix | 21 + profiles/desktop/printing.nix | 16 + profiles/desktop/supersonic.nix | 16 + profiles/desktop/vesktop.nix | 17 + profiles/desktop/wayland.nix | 16 + profiles/desktop/xdg.nix | 13 + profiles/desktop/zk.nix | 16 + profiles/emulation/cemu.nix | 16 + profiles/emulation/default.nix | 18 + profiles/emulation/dolphin.nix | 16 + profiles/emulation/rmg.nix | 16 + profiles/gaming/default.nix | 18 + .../headful => profiles/gaming}/gamemode.nix | 8 +- profiles/gaming/prismlauncher.nix | 16 + profiles/gaming/steam.nix | 20 + profiles/piracy/default.nix | 18 + profiles/piracy/mullvad.nix | 17 + profiles/piracy/qbittorrent.nix | 16 + profiles/productivity/default.nix | 18 + profiles/productivity/gimp.nix | 16 + profiles/productivity/inkscape.nix | 16 + profiles/productivity/libreoffice.nix | 16 + profiles/server/default.nix | 3 + .../headless => profiles/server}/grafana.nix | 2 +- .../headless => profiles/server}/loki.nix | 2 +- profiles/server/networking.nix | 13 + .../server}/prometheus.nix | 2 +- .../headless => profiles/server}/promtail.nix | 2 +- profiles/server/time.nix | 13 + pubkeys.nix | 6 +- secrets/secrets.nix | 22 +- symfony-cli/package.nix | 72 -- 165 files changed, 1815 insertions(+), 1431 deletions(-) delete mode 100644 classes/headful/clipboard.nix delete mode 100644 classes/headful/codium.nix delete mode 100644 classes/headful/cosmic.nix delete mode 100644 classes/headful/devenv.nix delete mode 100644 classes/headful/flatpak.nix delete mode 100644 classes/headful/fonts.nix delete mode 100644 classes/headful/hardware.nix delete mode 100644 classes/headful/location.nix delete mode 100644 classes/headful/mullvad.nix delete mode 100644 classes/headful/networking.nix delete mode 100644 classes/headful/pipewire.nix delete mode 100644 classes/headful/printing.nix delete mode 100644 classes/headful/wayland.nix delete mode 100644 classes/headful/xdg.nix delete mode 100644 classes/headless/networking.nix delete mode 100644 classes/headless/time.nix delete mode 100644 common/gc.nix create mode 100644 common/nh.nix delete mode 100644 common/puter.nix create mode 100644 common/rsync.nix create mode 100644 common/shpool.nix delete mode 100644 devenv.nix rename hosts/{headless => }/abacus/acme.nix (100%) rename hosts/{headless => }/abacus/authorized-keys.nix (82%) rename hosts/{headless => }/abacus/filesystems.nix (71%) rename hosts/{headless => }/abacus/forgejo.nix (65%) rename hosts/{headless => }/abacus/hardware.nix (52%) rename hosts/{headless => }/abacus/headscale.nix (68%) rename hosts/{headless => }/abacus/mealie.nix (61%) rename hosts/{headless => }/abacus/navidrome.nix (59%) create mode 100644 hosts/abacus/networking.nix create mode 100644 hosts/abacus/nginx.nix rename hosts/{headless => }/abacus/postgresql.nix (100%) create mode 100644 hosts/abacus/restic.nix create mode 100644 hosts/abacus/static-sites.nix rename hosts/{headful/flamingo => abacus}/system.nix (100%) rename hosts/{headless => }/abacus/vaultwarden.nix (71%) rename hosts/{headful/work => flamingo}/filesystems.nix (84%) rename hosts/{headful => }/flamingo/hardware.nix (68%) rename hosts/{headful/glacier => flamingo}/system.nix (100%) rename hosts/{headful/flamingo => glacier}/filesystems.nix (84%) rename hosts/{headful => }/glacier/hardware.nix (58%) create mode 100644 hosts/glacier/profiles.nix rename hosts/{headful/insomniac => glacier}/system.nix (100%) rename hosts/{headful => }/glacier/users.nix (100%) delete mode 100644 hosts/headful/flamingo/libreoffice.nix delete mode 100644 hosts/headful/flamingo/librewolf.nix delete mode 100644 hosts/headful/flamingo/mpv.nix delete mode 100644 hosts/headful/flamingo/supersonic.nix delete mode 100644 hosts/headful/glacier/gimp.nix delete mode 100644 hosts/headful/glacier/inkscape.nix delete mode 100644 hosts/headful/glacier/lanzaboote.nix delete mode 100644 hosts/headful/glacier/libreoffice.nix delete mode 100644 hosts/headful/glacier/librewolf.nix delete mode 100644 hosts/headful/glacier/mpv.nix delete mode 100644 hosts/headful/glacier/steam.nix delete mode 100644 hosts/headful/glacier/supersonic.nix delete mode 100644 hosts/headful/insomniac/cosmic.nix delete mode 100644 hosts/headful/insomniac/dolphin.nix delete mode 100644 hosts/headful/insomniac/flatpak.nix delete mode 100644 hosts/headful/insomniac/freetube.nix delete mode 100644 hosts/headful/insomniac/rmg.nix delete mode 100644 hosts/headful/insomniac/steam.nix delete mode 100644 hosts/headful/insomniac/supersonic.nix delete mode 100644 hosts/headful/work/kubectl.nix delete mode 100644 hosts/headful/work/php.nix delete mode 100644 hosts/headful/work/supersonic.nix delete mode 100644 hosts/headful/work/syncthing.nix delete mode 100644 hosts/headless/abacus/backup.nix delete mode 100644 hosts/headless/abacus/networking.nix delete mode 100644 hosts/headless/abacus/nginx.nix delete mode 100644 hosts/headless/abacus/static-sites.nix delete mode 100644 hosts/headless/vessel/backup.nix delete mode 100644 hosts/headless/vessel/blocky.nix delete mode 100644 hosts/headless/vessel/filesystems.nix delete mode 100644 hosts/headless/vessel/musicomp.nix delete mode 100644 hosts/headless/vessel/storage.nix rename hosts/{headful => }/insomniac/filesystems.nix (71%) create mode 100644 hosts/insomniac/freetube.nix rename hosts/{headful => }/insomniac/hardware.nix (65%) rename hosts/{headful/work => insomniac}/system.nix (100%) rename hosts/{headful => }/insomniac/users.nix (93%) create mode 100644 hosts/vessel/filesystems.nix rename hosts/{headless => }/vessel/hardware.nix (66%) create mode 100644 hosts/vessel/musicomp.nix create mode 100644 hosts/vessel/restic.nix create mode 100644 hosts/vessel/rsync.nix create mode 100644 hosts/vessel/storage.nix rename hosts/{headless/abacus => vessel}/system.nix (100%) rename hosts/{headful => }/work/docker.nix (97%) rename hosts/{headful/glacier => work}/filesystems.nix (84%) rename hosts/{headful => }/work/hardware.nix (62%) rename hosts/{headful => }/work/hosts.nix (100%) create mode 100644 hosts/work/php.nix rename hosts/{headful => }/work/plasma.nix (90%) rename hosts/{headless/vessel => work}/system.nix (100%) rename hosts/{headful => }/work/tools.nix (88%) rename hosts/{headful => }/work/users.nix (93%) create mode 100644 modules/gcadapter.nix create mode 100644 modules/rsync.nix delete mode 100644 modules/secure-boot.nix create mode 100644 profiles/desktop/clipboard.nix create mode 100644 profiles/desktop/compat.nix create mode 100644 profiles/desktop/cosmic.nix create mode 100644 profiles/desktop/default.nix create mode 100644 profiles/desktop/firefox.nix create mode 100644 profiles/desktop/fonts.nix create mode 100644 profiles/desktop/hardware.nix create mode 100644 profiles/desktop/location.nix create mode 100644 profiles/desktop/networking.nix create mode 100644 profiles/desktop/pipewire.nix create mode 100644 profiles/desktop/printing.nix create mode 100644 profiles/desktop/supersonic.nix create mode 100644 profiles/desktop/vesktop.nix create mode 100644 profiles/desktop/wayland.nix create mode 100644 profiles/desktop/xdg.nix create mode 100644 profiles/desktop/zk.nix create mode 100644 profiles/emulation/cemu.nix create mode 100644 profiles/emulation/default.nix create mode 100644 profiles/emulation/dolphin.nix create mode 100644 profiles/emulation/rmg.nix create mode 100644 profiles/gaming/default.nix rename {classes/headful => profiles/gaming}/gamemode.nix (82%) create mode 100644 profiles/gaming/prismlauncher.nix create mode 100644 profiles/gaming/steam.nix create mode 100644 profiles/piracy/default.nix create mode 100644 profiles/piracy/mullvad.nix create mode 100644 profiles/piracy/qbittorrent.nix create mode 100644 profiles/productivity/default.nix create mode 100644 profiles/productivity/gimp.nix create mode 100644 profiles/productivity/inkscape.nix create mode 100644 profiles/productivity/libreoffice.nix create mode 100644 profiles/server/default.nix rename {classes/headless => profiles/server}/grafana.nix (99%) rename {classes/headless => profiles/server}/loki.nix (99%) create mode 100644 profiles/server/networking.nix rename {classes/headless => profiles/server}/prometheus.nix (99%) rename {classes/headless => profiles/server}/promtail.nix (99%) create mode 100644 profiles/server/time.nix delete mode 100644 symfony-cli/package.nix diff --git a/.envrc b/.envrc index cb982f0..3550a30 100644 --- a/.envrc +++ b/.envrc @@ -1,9 +1 @@ -watch_file flake.nix -watch_file flake.lock - -DEVENV_ROOT_FILE="$(mktemp)" -printf %s "$PWD" > "$DEVENV_ROOT_FILE" -if ! use flake . --override-input devenv-root "file+file://$DEVENV_ROOT_FILE" -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi +use flake diff --git a/classes/headful/clipboard.nix b/classes/headful/clipboard.nix deleted file mode 100644 index cab0c1c..0000000 --- a/classes/headful/clipboard.nix +++ /dev/null @@ -1,3 +0,0 @@ -{pkgs, ...}: { - environment.systemPackages = [pkgs.wl-clipboard]; -} diff --git a/classes/headful/codium.nix b/classes/headful/codium.nix deleted file mode 100644 index 9361621..0000000 --- a/classes/headful/codium.nix +++ /dev/null @@ -1,6 +0,0 @@ -{pkgs, ...}: { - # TODO: wrap - environment.systemPackages = [ - pkgs.vscodium - ]; -} diff --git a/classes/headful/cosmic.nix b/classes/headful/cosmic.nix deleted file mode 100644 index 29a20ad..0000000 --- a/classes/headful/cosmic.nix +++ /dev/null @@ -1,17 +0,0 @@ -{inputs, ...}: { - imports = [ - inputs.nixos-cosmic.nixosModules.default - ]; - - nix.settings = { - substituters = ["https://cosmic.cachix.org"]; - trusted-public-keys = ["cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE="]; - }; - - services = { - desktopManager.cosmic.enable = true; - displayManager.cosmic-greeter.enable = true; - }; - - environment.sessionVariables.COSMIC_DATA_CONTROL_ENABLED = 1; -} diff --git a/classes/headful/devenv.nix b/classes/headful/devenv.nix deleted file mode 100644 index 32fb44b..0000000 --- a/classes/headful/devenv.nix +++ /dev/null @@ -1,3 +0,0 @@ -{pkgs, ...}: { - environment.systemPackages = [pkgs.devenv]; -} diff --git a/classes/headful/flatpak.nix b/classes/headful/flatpak.nix deleted file mode 100644 index 752a25e..0000000 --- a/classes/headful/flatpak.nix +++ /dev/null @@ -1,7 +0,0 @@ -{inputs, ...}: { - imports = [ - inputs.flatpak.nixosModules.nix-flatpak - ]; - - services.flatpak.enable = true; -} diff --git a/classes/headful/fonts.nix b/classes/headful/fonts.nix deleted file mode 100644 index bf59051..0000000 --- a/classes/headful/fonts.nix +++ /dev/null @@ -1,27 +0,0 @@ -{pkgs, ...}: { - fonts = { - enableDefaultPackages = true; - packages = [ - pkgs.noto-fonts - pkgs.noto-fonts-extra - pkgs.noto-fonts-cjk-sans - pkgs.noto-fonts-cjk-serif - pkgs.noto-fonts-monochrome-emoji - pkgs.noto-fonts-color-emoji - pkgs.nerd-fonts.fira-code - ]; - - fontconfig = { - enable = true; - - defaultFonts = { - monospace = ["FiraCode Nerd Font"]; - sansSerif = ["Noto Sans"]; - serif = ["Noto Serif"]; - emoji = ["Noto Color Emoji" "Noto Emoji"]; - }; - }; - - fontDir.enable = true; - }; -} diff --git a/classes/headful/hardware.nix b/classes/headful/hardware.nix deleted file mode 100644 index a49266b..0000000 --- a/classes/headful/hardware.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - hardware = { - bluetooth.enable = true; - steam-hardware.enable = true; - xone.enable = true; - xpadneo.enable = true; - opentabletdriver.enable = true; - graphics.enable = true; - }; -} diff --git a/classes/headful/location.nix b/classes/headful/location.nix deleted file mode 100644 index 474ee00..0000000 --- a/classes/headful/location.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - location.provider = "geoclue2"; -} diff --git a/classes/headful/mullvad.nix b/classes/headful/mullvad.nix deleted file mode 100644 index 31d3c05..0000000 --- a/classes/headful/mullvad.nix +++ /dev/null @@ -1,6 +0,0 @@ -{pkgs, ...}: { - services.mullvad-vpn = { - enable = true; - package = pkgs.mullvad-vpn; - }; -} diff --git a/classes/headful/networking.nix b/classes/headful/networking.nix deleted file mode 100644 index d7cd8c0..0000000 --- a/classes/headful/networking.nix +++ /dev/null @@ -1,10 +0,0 @@ -{config, ...}: { - services.resolved.enable = true; - - networking.networkmanager = { - enable = true; - dns = "systemd-resolved"; - }; - - users.groups.networkmanager.members = config.users.normalUsers; -} diff --git a/classes/headful/pipewire.nix b/classes/headful/pipewire.nix deleted file mode 100644 index 157b2af..0000000 --- a/classes/headful/pipewire.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - security.rtkit.enable = true; - - services.pipewire = { - enable = true; - wireplumber.enable = true; - alsa.enable = true; - pulse.enable = true; - jack.enable = true; - }; -} diff --git a/classes/headful/printing.nix b/classes/headful/printing.nix deleted file mode 100644 index cc77e7e..0000000 --- a/classes/headful/printing.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - services.printing = { - enable = true; - webInterface = true; - }; -} diff --git a/classes/headful/wayland.nix b/classes/headful/wayland.nix deleted file mode 100644 index d11e343..0000000 --- a/classes/headful/wayland.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - environment.sessionVariables = { - NIXOS_OZONE_WL = "1"; - SDL_VIDEODRIVER = "wayland"; - }; -} diff --git a/classes/headful/xdg.nix b/classes/headful/xdg.nix deleted file mode 100644 index a5a81d9..0000000 --- a/classes/headful/xdg.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - xdg.portal.xdgOpenUsePortal = true; -} diff --git a/classes/headless/networking.nix b/classes/headless/networking.nix deleted file mode 100644 index 027e7df..0000000 --- a/classes/headless/networking.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - networking.useNetworkd = true; -} diff --git a/classes/headless/time.nix b/classes/headless/time.nix deleted file mode 100644 index 47f2e72..0000000 --- a/classes/headless/time.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - time.timeZone = "UTC"; -} diff --git a/common/agenix.nix b/common/agenix.nix index aff3765..7e212a1 100644 --- a/common/agenix.nix +++ b/common/agenix.nix @@ -1,4 +1,5 @@ -{inputs, ...}: { +{ inputs, ... }: +{ imports = [ inputs.agenix.nixosModules.default ]; diff --git a/common/boot.nix b/common/boot.nix index ce488d2..d5a4930 100644 --- a/common/boot.nix +++ b/common/boot.nix @@ -1,5 +1,6 @@ +{ config, ... }: { - fileSystems."/boot" = { + fileSystems.${config.boot.loader.efi.efiSysMountPoint} = { label = "BOOT"; fsType = "vfat"; }; @@ -16,6 +17,12 @@ efiSysMountPoint = "/boot"; }; }; - tmp.cleanOnBoot = true; + + # TODO + tmp = { + useTmpfs = true; + tmpfsSize = "50%"; + cleanOnBoot = true; + }; }; } diff --git a/common/bottom.nix b/common/bottom.nix index fcb62d0..0dd6c8b 100644 --- a/common/bottom.nix +++ b/common/bottom.nix @@ -1,3 +1,4 @@ -{pkgs, ...}: { - environment.systemPackages = [pkgs.bottom]; +{ pkgs, ... }: +{ + environment.systemPackages = [ pkgs.bottom ]; } diff --git a/common/fish.nix b/common/fish.nix index b54be6e..1abe9c7 100644 --- a/common/fish.nix +++ b/common/fish.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ programs.fish.enable = true; users.defaultUserShell = pkgs.fish; diff --git a/common/gc.nix b/common/gc.nix deleted file mode 100644 index 62342bb..0000000 --- a/common/gc.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ - nix.gc = { - automatic = true; - dates = "daily"; - options = "--delete-older-than 7d"; - }; -} diff --git a/common/gitui.nix b/common/gitui.nix index e7d891e..5c91753 100644 --- a/common/gitui.nix +++ b/common/gitui.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ environment.systemPackages = [ pkgs.gitui ]; diff --git a/common/helix.nix b/common/helix.nix index 6cfd9fa..f654cc1 100644 --- a/common/helix.nix +++ b/common/helix.nix @@ -1,16 +1,21 @@ { + inputs, lib, pkgs, ... -}: let - package = pkgs.helix; -in { - environment.systemPackages = [package]; +}: +let + package = inputs.hxwrap.packages.${pkgs.system}.default; +in +{ + environment.systemPackages = [ package ]; - environment.sessionVariables = let - exe = builtins.baseNameOf (lib.getExe package); - in { - EDITOR = exe; - VISUAL = exe; - }; + environment.sessionVariables = + let + exe = builtins.baseNameOf (lib.getExe package); + in + { + EDITOR = exe; + VISUAL = exe; + }; } diff --git a/common/networking.nix b/common/networking.nix index 654e427..5f1a984 100644 --- a/common/networking.nix +++ b/common/networking.nix @@ -1,5 +1,9 @@ -{pkgs, ...}: { - networking.nftables.enable = true; +{ attrName, pkgs, ... }: +{ + networking = { + hostName = attrName; + nftables.enable = true; + }; environment.systemPackages = [ pkgs.nixos-firewall-tool diff --git a/common/nh.nix b/common/nh.nix new file mode 100644 index 0000000..92b865a --- /dev/null +++ b/common/nh.nix @@ -0,0 +1,17 @@ +{ + pkgs, + self, + ... +}: +{ + programs.nh = { + enable = true; + clean = { + enable = true; + extraArgs = "--keep 5 --keep-since 1w"; + dates = "weekly"; + }; + }; + + environment.sessionVariables.NH_FLAKE = "git+https://forgejo@forgejo.helveticanonstandard.net/helvetica/puter.git"; # TODO +} diff --git a/common/nix-index-database.nix b/common/nix-index-database.nix index c8b6d0d..d545e20 100644 --- a/common/nix-index-database.nix +++ b/common/nix-index-database.nix @@ -1,4 +1,5 @@ -{inputs, ...}: { +{ inputs, ... }: +{ imports = [ inputs.nix-index-database.nixosModules.nix-index ]; diff --git a/common/nix.nix b/common/nix.nix index fe2be20..806b91f 100644 --- a/common/nix.nix +++ b/common/nix.nix @@ -3,16 +3,17 @@ inputs, lib, ... -}: { +}: +{ nix = { - registry = lib.mapAttrs (_: value: {flake = value;}) inputs; + registry = lib.mapAttrs (_: value: { flake = value; }) inputs; nixPath = lib.mapAttrsToList (key: _: "${key}=flake:${key}") config.nix.registry; optimise.automatic = true; settings = { - trusted-users = ["root"] ++ config.users.normalUsers; + trusted-users = [ "root" ] ++ config.users.normalUsers; experimental-features = [ "nix-command" "flakes" @@ -24,5 +25,4 @@ }; nixpkgs.config.allowUnfree = true; - hardware.enableAllFirmware = true; } diff --git a/common/pubkeys.nix b/common/pubkeys.nix index 6672a26..46594fd 100644 --- a/common/pubkeys.nix +++ b/common/pubkeys.nix @@ -2,10 +2,12 @@ lib, self, ... -}: { - options.pubkeys = let - inherit (lib) types; - in +}: +{ + options.pubkeys = + let + inherit (lib) types; + in lib.mkOption { type = types.attrsOf (types.attrsOf types.str); description = '' diff --git a/common/puter.nix b/common/puter.nix deleted file mode 100644 index 9304941..0000000 --- a/common/puter.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ - pkgs, - self, - ... -}: { - environment = { - systemPackages = [ - self.packages.${pkgs.system}.puter - ]; - sessionVariables.PUTER_FLAKEREF = "git+https://forgejo@tea.wrz.one/lukas/puter.git"; - }; -} diff --git a/common/ripgrep.nix b/common/ripgrep.nix index 6094a55..26795af 100644 --- a/common/ripgrep.nix +++ b/common/ripgrep.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ environment.systemPackages = [ pkgs.ripgrep ]; diff --git a/common/rsync.nix b/common/rsync.nix new file mode 100644 index 0000000..5cdad8e --- /dev/null +++ b/common/rsync.nix @@ -0,0 +1,25 @@ +{ + lib, + pkgs, + ... +}: +{ + #services.rsync = { + # enable = true; + + # commonArgs = let + # rsh = "${lib.getExe pkgs.openssh} -i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; + # in [ + # "--verbose" + # "--verbose" + # "--archive" + # "--update" + # "--delete" + # "--mkpath" + # "--exclude" + # "lost+found" + # "--rsh" + # rsh + # ]; + #}; +} diff --git a/common/shpool.nix b/common/shpool.nix new file mode 100644 index 0000000..ba510bf --- /dev/null +++ b/common/shpool.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + environment.systemPackages = [ + pkgs.shpool + ]; +} diff --git a/common/ssh.nix b/common/ssh.nix index 29b1e6c..a80f958 100644 --- a/common/ssh.nix +++ b/common/ssh.nix @@ -1,5 +1,5 @@ { - age.identityPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + age.identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; services.openssh = { enable = true; diff --git a/common/syncthing.nix b/common/syncthing.nix index 7b6c8ad..647ee15 100644 --- a/common/syncthing.nix +++ b/common/syncthing.nix @@ -1,6 +1,8 @@ -{config, ...}: let +{ config, ... }: +let inherit (config.networking) hostName; -in { +in +{ services.syncthing = { enable = true; systemService = true; diff --git a/common/tailscale.nix b/common/tailscale.nix index 12922dd..1f87127 100644 --- a/common/tailscale.nix +++ b/common/tailscale.nix @@ -1,4 +1,5 @@ -{config, ...}: { +{ config, ... }: +{ services.tailscale = { enable = true; openFirewall = true; diff --git a/common/users.nix b/common/users.nix index 5ba4530..da7995a 100644 --- a/common/users.nix +++ b/common/users.nix @@ -2,10 +2,12 @@ config, lib, ... -}: let +}: +let inherit (config.users) mainUser; -in { - age.secrets = lib.mkSecrets {"user-${mainUser}" = {};}; +in +{ + age.secrets = lib.mkSecrets { "user-${mainUser}" = { }; }; users = { mutableUsers = false; @@ -20,7 +22,7 @@ in { isNormalUser = true; hashedPasswordFile = config.age.secrets."user-${mainUser}".path; openssh.authorizedKeys.keys = builtins.attrValues config.pubkeys.users; - extraGroups = ["wheel"]; #TODO remove + extraGroups = [ "wheel" ]; # TODO remove }; }; }; diff --git a/common/wheel.nix b/common/wheel.nix index 8481639..0c17216 100644 --- a/common/wheel.nix +++ b/common/wheel.nix @@ -1,3 +1,4 @@ -{config, ...}: { +{ config, ... }: +{ users.groups.wheel.members = config.users.normalUsers; } diff --git a/common/zellij.nix b/common/zellij.nix index c97e1f7..eaf8886 100644 --- a/common/zellij.nix +++ b/common/zellij.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ environment.systemPackages = [ pkgs.zellij ]; diff --git a/devenv.nix b/devenv.nix deleted file mode 100644 index a80aa4f..0000000 --- a/devenv.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - languages.python.enable = true; - - pre-commit.hooks = { - # Nix - alejandra.enable = true; - deadnix.enable = true; - statix.enable = true; - - # Flakes - flake-checker.enable = true; - - # Shell - shellcheck.enable = true; - - # Python - pyright.enable = true; - ruff.enable = true; - ruff-format.enable = true; - }; -} diff --git a/flake.lock b/flake.lock index af8f13e..6f17782 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1736955230, - "narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=", + "lastModified": 1745630506, + "narHash": "sha256-bHCFgGeu8XjWlVuaWzi3QONjDW3coZDqSHvnd4l7xus=", "owner": "ryantm", "repo": "agenix", - "rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c", + "rev": "96e078c646b711aee04b82ba01aefbff87004ded", "type": "github" }, "original": { @@ -21,49 +21,6 @@ "type": "github" } }, - "cachix": { - "inputs": { - "devenv": [ - "devenv" - ], - "flake-compat": [ - "devenv" - ], - "git-hooks": [ - "devenv" - ], - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1742042642, - "narHash": "sha256-D0gP8srrX0qj+wNYNPdtVJsQuFzIng3q43thnHXQ/es=", - "owner": "cachix", - "repo": "cachix", - "rev": "a624d3eaf4b1d225f918de8543ed739f2f574203", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "crane": { - "locked": { - "lastModified": 1731098351, - "narHash": "sha256-HQkYvKvaLQqNa10KEFGgWHfMAbWBfFp+4cAgkut+NNE=", - "owner": "ipetkov", - "repo": "crane", - "rev": "ef80ead953c1b28316cc3f8613904edc2eb90c28", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "darwin": { "inputs": { "nixpkgs": [ @@ -72,11 +29,11 @@ ] }, "locked": { - "lastModified": 1700795494, - "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", "type": "github" }, "original": { @@ -86,40 +43,6 @@ "type": "github" } }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat", - "git-hooks": "git-hooks", - "nix": "nix", - "nixpkgs": "nixpkgs_4" - }, - "locked": { - "lastModified": 1744298740, - "narHash": "sha256-m5RnbHQqYQhQA4ntohXlJsiIsOAKx+pz/vOC+E+FmHg=", - "owner": "cachix", - "repo": "devenv", - "rev": "028c6a38fb0284c96691176bd31626bf36981129", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "devenv-root": { - "flake": false, - "locked": { - "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", - "type": "file", - "url": "file:///dev/null" - }, - "original": { - "type": "file", - "url": "file:///dev/null" - } - }, "flake-compat": { "flake": false, "locked": { @@ -139,27 +62,11 @@ "flake-compat_2": { "flake": false, "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_3": { - "flake": false, - "locked": { - "lastModified": 1717312683, - "narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=", + "lastModified": 1746162366, + "narHash": "sha256-5SSSZ/oQkwfcAz/o/6TlejlVGqeK08wyREBQ5qFFPhM=", "owner": "nix-community", "repo": "flake-compat", - "rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea", + "rev": "0f158086a2ecdbb138cd0429410e44994f1b7e4b", "type": "github" }, "original": { @@ -168,45 +75,7 @@ "type": "github" } }, - "flake-compat_4": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "devenv", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, @@ -224,28 +93,7 @@ "type": "github" } }, - "flake-parts_3": { - "inputs": { - "nixpkgs-lib": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1730504689, - "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "506278e768c2a08bec68eb62932193e341f55c90", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_4": { + "flake-parts_2": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_2" }, @@ -263,98 +111,89 @@ "type": "github" } }, - "flatpak": { + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_3" + }, "locked": { - "lastModified": 1739444422, - "narHash": "sha256-iAVVHi7X3kWORftY+LVbRiStRnQEob2TULWyjMS6dWg=", - "owner": "gmodena", - "repo": "nix-flatpak", - "rev": "5e54c3ca05a7c7d968ae1ddeabe01d2a9bc1e177", + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", "type": "github" }, "original": { - "owner": "gmodena", - "ref": "latest", - "repo": "nix-flatpak", + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, - "git-hooks": { + "flake-parts_4": { "inputs": { - "flake-compat": [ - "devenv" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ] + "nixpkgs-lib": "nixpkgs-lib_4" }, "locked": { - "lastModified": 1742649964, - "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", "type": "github" }, "original": { - "owner": "cachix", - "repo": "git-hooks.nix", + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, - "gitignore": { + "flake-parts_5": { "inputs": { - "nixpkgs": [ - "devenv", - "git-hooks", - "nixpkgs" - ] + "nixpkgs-lib": "nixpkgs-lib_5" }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", "type": "github" }, "original": { "owner": "hercules-ci", - "repo": "gitignore.nix", + "repo": "flake-parts", "type": "github" } }, - "gitignore_2": { + "forgesync": { "inputs": { - "nixpkgs": [ - "lanzaboote", - "pre-commit-hooks-nix", - "nixpkgs" - ] + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_2", + "pyproject-build-systems": "pyproject-build-systems", + "pyproject-nix": "pyproject-nix", + "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" + "lastModified": 1746299148, + "narHash": "sha256-OL9j+S8m4zC2dCqjaWLt6Ooc7EzRjJC/olLVj7mqd/M=", + "ref": "refs/heads/main", + "rev": "e2e0f134da1444b298d4a4601390664124d0a5c4", + "revCount": 10, + "type": "git", + "url": "https://codeberg.org/helvetica/forgesync.git" }, "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" + "type": "git", + "url": "https://codeberg.org/helvetica/forgesync.git" } }, "hardware": { "locked": { - "lastModified": 1744366945, - "narHash": "sha256-OuLhysErPHl53BBifhesrRumJNhrlSgQDfYOTXfgIMg=", + "lastModified": 1746341346, + "narHash": "sha256-WjupK5Xpc+viJlJWiyPHp/dF4aJItp1BPuFsEdv2/fI=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "1fe3cc2bc5d2dc9c81cb4e63d2f67c1543340df1", + "rev": "0833dc8bbc4ffa9cf9b0cbfccf1c5ec8632fc66e", "type": "github" }, "original": { @@ -371,11 +210,11 @@ ] }, "locked": { - "lastModified": 1703113217, - "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", "owner": "nix-community", "repo": "home-manager", - "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", "type": "github" }, "original": { @@ -384,96 +223,62 @@ "type": "github" } }, - "lanzaboote": { + "hxwrap": { "inputs": { - "crane": "crane", - "flake-compat": "flake-compat_2", "flake-parts": "flake-parts_3", - "nixpkgs": "nixpkgs_5", - "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay" + "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1737639419, - "narHash": "sha256-AEEDktApTEZ5PZXNDkry2YV2k6t0dTgLPEmAZbnigXU=", - "owner": "nix-community", - "repo": "lanzaboote", - "rev": "a65905a09e2c43ff63be8c0e86a93712361f871e", - "type": "github" + "lastModified": 1745088587, + "narHash": "sha256-85AYHWayJVq/dxgk/S4RH7u6w59Akyr1fVttR8KBh8g=", + "ref": "refs/heads/main", + "rev": "8fa5d5d550add7bf6cfd0a619dfac0e8a03b2bae", + "revCount": 21, + "type": "git", + "url": "https://codeberg.org/helvetica/hxwrap.git" }, "original": { - "owner": "nix-community", - "ref": "v0.4.2", - "repo": "lanzaboote", - "type": "github" - } - }, - "libgit2": { - "flake": false, - "locked": { - "lastModified": 1697646580, - "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", - "owner": "libgit2", - "repo": "libgit2", - "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", - "type": "github" - }, - "original": { - "owner": "libgit2", - "repo": "libgit2", - "type": "github" + "type": "git", + "url": "https://codeberg.org/helvetica/hxwrap.git" } }, "musicomp": { "inputs": { "flake-parts": "flake-parts_4", - "nixpkgs": "nixpkgs_6" + "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1744068246, - "narHash": "sha256-ZrLuwXT0uRxa4hyMyCe/IG9lKZEqAM+lUgLKcCiZjbA=", + "lastModified": 1744916606, + "narHash": "sha256-6l7xP5DTAc7E+gO2xu9aX5BjyuDNLMdeS6oFFrpsulg=", "ref": "refs/heads/main", - "rev": "66aa356585132605e8bd9cc630fab7416f3caf3d", - "revCount": 2, + "rev": "0c6b26ce38dbc39d360904ddd98eab1159b922e1", + "revCount": 3, "type": "git", - "url": "https://codeberg.org/helveticanonstandard/musicomp.git" + "url": "https://codeberg.org/helvetica/musicomp.git" }, "original": { "type": "git", - "url": "https://codeberg.org/helveticanonstandard/musicomp.git" + "url": "https://codeberg.org/helvetica/musicomp.git" } }, - "nix": { + "myphps": { "inputs": { - "flake-compat": [ - "devenv" - ], - "flake-parts": "flake-parts", - "libgit2": "libgit2", - "nixpkgs": "nixpkgs_3", - "nixpkgs-23-11": [ - "devenv" - ], - "nixpkgs-regression": [ - "devenv" - ], - "pre-commit-hooks": [ - "devenv" - ] + "flake-parts": "flake-parts_5", + "nixpkgs": "nixpkgs_5", + "phps": "phps" }, "locked": { - "lastModified": 1741798497, - "narHash": "sha256-E3j+3MoY8Y96mG1dUIiLFm2tZmNbRvSiyN7CrSKuAVg=", - "owner": "domenkozar", - "repo": "nix", - "rev": "f3f44b2baaf6c4c6e179de8cbb1cc6db031083cd", - "type": "github" + "lastModified": 1746369841, + "narHash": "sha256-/k3MQPXdsXJ0FDEsT1YvBG9ugRXk1nuE9MCb1wAMGQc=", + "ref": "refs/heads/main", + "rev": "dbe35541ef6923f411685434cc535d0854b55b6a", + "revCount": 5, + "type": "git", + "url": "https://codeberg.org/helvetica/myphps.git" }, "original": { - "owner": "domenkozar", - "ref": "devenv-2.24", - "repo": "nix", - "type": "github" + "type": "git", + "url": "https://codeberg.org/helvetica/myphps.git" } }, "nix-index-database": { @@ -483,11 +288,11 @@ ] }, "locked": { - "lastModified": 1743911143, - "narHash": "sha256-4j4JPwr0TXHH4ZyorXN5yIcmqIQr0WYacsuPA4ktONo=", + "lastModified": 1746330942, + "narHash": "sha256-ShizFaJCAST23tSrHHtFFGF0fwd72AG+KhPZFFQX/0o=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "a36f6a7148aec2c77d78e4466215cceb2f5f4bfb", + "rev": "137fd2bd726fff343874f85601b51769b48685cc", "type": "github" }, "original": { @@ -498,17 +303,17 @@ }, "nixos-cosmic": { "inputs": { - "flake-compat": "flake-compat_3", + "flake-compat": "flake-compat_2", "nixpkgs": "nixpkgs_7", - "nixpkgs-stable": "nixpkgs-stable_2", - "rust-overlay": "rust-overlay_2" + "nixpkgs-stable": "nixpkgs-stable", + "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1744369853, - "narHash": "sha256-rVW9J8gMUFj8PsFV2TgNiNuJd8+O+FUizEQgl1ooQFY=", + "lastModified": 1746356902, + "narHash": "sha256-aV2pm+XKEoGE/BuqJwI1zDhtHclzC5BsbSO+SAMFEKk=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "c2b4dd2f85d558c7147bc06c6417f87aa1775ad5", + "rev": "22325997671e2a6f0a2e784db2746267868a33ed", "type": "github" }, "original": { @@ -519,11 +324,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1703013332, - "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", + "lastModified": 1745391562, + "narHash": "sha256-sPwcCYuiEopaafePqlG826tBhctuJsLx/mhKKM5Fmjo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", + "rev": "8a2f738d9d1f1d986b5a4cd2fd2061a7127237d7", "type": "github" }, "original": { @@ -563,29 +368,58 @@ "type": "github" } }, - "nixpkgs-stable": { + "nixpkgs-lib_3": { "locked": { - "lastModified": 1730741070, - "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixos-24.05", - "repo": "nixpkgs", + "owner": "nix-community", + "repo": "nixpkgs.lib", "type": "github" } }, - "nixpkgs-stable_2": { + "nixpkgs-lib_4": { "locked": { - "lastModified": 1744168086, - "narHash": "sha256-S9M4HddBCxbbX1CKSyDYgZ8NCVyHcbKnBfoUXeRu2jQ=", + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_5": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1746183838, + "narHash": "sha256-kwaaguGkAqTZ1oK0yXeQ3ayYjs8u/W7eEfrFpFfIDFA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "60e405b241edb6f0573f3d9f944617fe33ac4a73", + "rev": "bf3287dac860542719fe7554e21e686108716879", "type": "github" }, "original": { @@ -597,11 +431,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1733212471, - "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=", + "lastModified": 1745526057, + "narHash": "sha256-ITSpPDwvLBZBnPRS2bUcHY3gZSwis/uTe255QgMtTLA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776", + "rev": "f771eb401a46846c1aebd20552521b233dd7e18b", "type": "github" }, "original": { @@ -613,53 +447,21 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1717432640, - "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "lastModified": 1744932701, + "narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", + "rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-24.05", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_4": { - "locked": { - "lastModified": 1733477122, - "narHash": "sha256-qamMCz5mNpQmgBwc8SB5tVMlD5sbwVIToVZtSxMph9s=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1731919951, - "narHash": "sha256-vOM6ETpl1yu9KLi/icTmLJIPbbdJCdAVYUXZceO/Ce4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "04386ac325a813047fc314d4b4d838a5b1e3c7fe", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable-small", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { "locked": { "lastModified": 1743964447, "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", @@ -675,13 +477,13 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_5": { "locked": { - "lastModified": 1744098102, - "narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=", + "lastModified": 1744463964, + "narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7", + "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650", "type": "github" }, "original": { @@ -691,13 +493,13 @@ "type": "github" } }, - "nixpkgs_8": { + "nixpkgs_6": { "locked": { - "lastModified": 1743689281, - "narHash": "sha256-y7Hg5lwWhEOgflEHRfzSH96BOt26LaYfrYWzZ+VoVdg=", + "lastModified": 1744502386, + "narHash": "sha256-QAd1L37eU7ktL2WeLLLTmI6P9moz9+a/ONO8qNBYJgM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2bfc080955153be0be56724be6fa5477b4eefabb", + "rev": "f6db44a8daa59c40ae41ba6e5823ec77fe0d2124", "type": "github" }, "original": { @@ -707,18 +509,34 @@ "type": "github" } }, + "nixpkgs_7": { + "locked": { + "lastModified": 1746232882, + "narHash": "sha256-MHmBH2rS8KkRRdoU/feC/dKbdlMkcNkB5mwkuipVHeQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7a2622e2c0dbad5c4493cb268aba12896e28b008", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "phps": { "inputs": { - "flake-compat": "flake-compat_4", - "nixpkgs": "nixpkgs_8", + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs_6", "utils": "utils" }, "locked": { - "lastModified": 1744001863, - "narHash": "sha256-0pYw0Idtion++srUKsmGX7mq1weozdVE8gR+inoedUo=", + "lastModified": 1744527323, + "narHash": "sha256-2EyP6SxJsmBFMHArrTGw1J+Ned3aRMUZzbzmJZHDbNo=", "owner": "fossar", "repo": "nix-phps", - "rev": "220ed74315dc7cd64a6181efd3d583a3607ef01f", + "rev": "f6b53caf2b1c2d592cbac5156f729ef79495992a", "type": "github" }, "original": { @@ -727,74 +545,74 @@ "type": "github" } }, - "pre-commit-hooks-nix": { + "pyproject-build-systems": { "inputs": { - "flake-compat": [ - "lanzaboote", - "flake-compat" - ], - "gitignore": "gitignore_2", "nixpkgs": [ - "lanzaboote", + "forgesync", "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable" + "pyproject-nix": [ + "forgesync", + "pyproject-nix" + ], + "uv2nix": [ + "forgesync", + "uv2nix" + ] }, "locked": { - "lastModified": 1731363552, - "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", + "lastModified": 1744599653, + "narHash": "sha256-nysSwVVjG4hKoOjhjvE6U5lIKA8sEr1d1QzEfZsannU=", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "rev": "7dba6dbc73120e15b558754c26024f6c93015dd7", "type": "github" }, "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "forgesync", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743438845, + "narHash": "sha256-1GSaoubGtvsLRwoYwHjeKYq40tLwvuFFVhGrG8J9Oek=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "8063ec98edc459571d042a640b1c5e334ecfca1e", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", "type": "github" } }, "root": { "inputs": { "agenix": "agenix", - "devenv": "devenv", - "devenv-root": "devenv-root", - "flake-parts": "flake-parts_2", - "flatpak": "flatpak", + "flake-parts": "flake-parts", + "forgesync": "forgesync", "hardware": "hardware", - "lanzaboote": "lanzaboote", + "hxwrap": "hxwrap", "musicomp": "musicomp", + "myphps": "myphps", "nix-index-database": "nix-index-database", "nixos-cosmic": "nixos-cosmic", "nixpkgs": [ "nixos-cosmic", "nixpkgs" - ], - "phps": "phps" + ] } }, "rust-overlay": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1731897198, - "narHash": "sha256-Ou7vLETSKwmE/HRQz4cImXXJBr/k9gp4J4z/PF8LzTE=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "0be641045af6d8666c11c2c40e45ffc9667839b5", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "rust-overlay_2": { "inputs": { "nixpkgs": [ "nixos-cosmic", @@ -802,11 +620,11 @@ ] }, "locked": { - "lastModified": 1744338850, - "narHash": "sha256-pwMIVmsb8fjjT92n5XFDqCsplcX70qVMMT7NulumPXs=", + "lastModified": 1746326315, + "narHash": "sha256-IDqSls/r6yBfdOBRSMQ/noTUoigmsKnTQ7TqpsBtN4Y=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "5e64aecc018e6f775572609e7d7485fdba6985a7", + "rev": "dd280c436961ec5adccf0135efe5b66a23d84497", "type": "github" }, "original": { @@ -862,6 +680,31 @@ "repo": "flake-utils", "type": "github" } + }, + "uv2nix": { + "inputs": { + "nixpkgs": [ + "forgesync", + "nixpkgs" + ], + "pyproject-nix": [ + "forgesync", + "pyproject-nix" + ] + }, + "locked": { + "lastModified": 1745697651, + "narHash": "sha256-r4A/fkiCenEapHkjJWPiNUZEfviuXMCr6mRozJ5dC4o=", + "owner": "pyproject-nix", + "repo": "uv2nix", + "rev": "cb6508484d534dafd097713b575f2aebc3417de0", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "uv2nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 357ce0e..dfb9898 100644 --- a/flake.nix +++ b/flake.nix @@ -4,23 +4,18 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - devenv.url = "github:cachix/devenv"; hardware.url = "github:NixOS/nixos-hardware"; agenix.url = "github:ryantm/agenix"; - phps.url = "github:fossar/nix-phps"; - lanzaboote.url = "github:nix-community/lanzaboote/v0.4.2"; - flatpak.url = "github:gmodena/nix-flatpak?ref=latest"; nixpkgs.follows = "nixos-cosmic/nixpkgs"; nixos-cosmic.url = "github:lilyinstarlight/nixos-cosmic"; nix-index-database = { url = "github:nix-community/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; }; - musicomp.url = "git+https://codeberg.org/helveticanonstandard/musicomp.git"; + musicomp.url = "git+https://codeberg.org/helvetica/musicomp.git"; + hxwrap.url = "git+https://codeberg.org/helvetica/hxwrap.git"; + myphps.url = "git+https://codeberg.org/helvetica/myphps.git"; + forgesync.url = "git+https://codeberg.org/helvetica/forgesync.git"; }; nixConfig = { @@ -28,58 +23,43 @@ extra-trusted-public-keys = "cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE="; }; - outputs = { - self, - nixpkgs, - flake-parts, - ... - } @ inputs: - flake-parts.lib.mkFlake {inherit inputs;} { - imports = [ - inputs.devenv.flakeModule + outputs = + { + self, + nixpkgs, + flake-parts, + ... + }@inputs: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" ]; - systems = ["x86_64-linux" "aarch64-linux"]; - flake = { lib = nixpkgs.lib.extend (import ./lib.nix); - nixosConfigurations = self.lib.genNixosConfigurations {inherit inputs;}; + nixosConfigurations = self.lib.genNixosConfigurations inputs; }; - perSystem = { - pkgs, - inputs', - lib, - ... - }: { - devenv.shells.default = { - devenv.root = let - devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; - in - lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; - - name = "puter"; - - imports = [ - ./devenv.nix - ]; - - packages = [ - inputs'.agenix.packages.agenix - ]; - }; - - packages = - lib.packagesFromDirectoryRecursive { - inherit (pkgs) callPackage; - directory = ./packages; - } - // { - symfony-cli = pkgs.callPackage ./symfony-cli/package.nix { - fossarPhps = inputs'.phps.packages; - }; + perSystem = + { + pkgs, + inputs', + lib, + ... + }: + { + devShells.default = pkgs.mkShellNoCC { + packages = [ + inputs'.agenix.packages.default + ]; }; - }; + + packages = lib.packagesFromDirectoryRecursive { + inherit (pkgs) callPackage newScope; + directory = ./packages; + }; + }; }; } diff --git a/hosts/headless/abacus/acme.nix b/hosts/abacus/acme.nix similarity index 100% rename from hosts/headless/abacus/acme.nix rename to hosts/abacus/acme.nix diff --git a/hosts/headless/abacus/authorized-keys.nix b/hosts/abacus/authorized-keys.nix similarity index 82% rename from hosts/headless/abacus/authorized-keys.nix rename to hosts/abacus/authorized-keys.nix index 41d2c3f..a1c7a40 100644 --- a/hosts/headless/abacus/authorized-keys.nix +++ b/hosts/abacus/authorized-keys.nix @@ -1,4 +1,5 @@ -{config, ...}: { +{ config, ... }: +{ users.users.root.openssh.authorizedKeys.keys = [ config.pubkeys.hosts.vessel ]; diff --git a/hosts/headless/abacus/filesystems.nix b/hosts/abacus/filesystems.nix similarity index 71% rename from hosts/headless/abacus/filesystems.nix rename to hosts/abacus/filesystems.nix index e22a8dd..d6ca29a 100644 --- a/hosts/headless/abacus/filesystems.nix +++ b/hosts/abacus/filesystems.nix @@ -1,14 +1,15 @@ -{config, ...}: { +{ config, ... }: +{ fileSystems = { "/" = { fsType = "ext4"; label = "main"; - options = ["noatime"]; + options = [ "noatime" ]; }; ${config.services.navidrome.settings.MusicFolder} = { label = "music"; fsType = "ext4"; - options = ["noatime"]; + options = [ "noatime" ]; }; }; } diff --git a/hosts/headless/abacus/forgejo.nix b/hosts/abacus/forgejo.nix similarity index 65% rename from hosts/headless/abacus/forgejo.nix rename to hosts/abacus/forgejo.nix index 4cc5186..49268fd 100644 --- a/hosts/headless/abacus/forgejo.nix +++ b/hosts/abacus/forgejo.nix @@ -3,9 +3,11 @@ lib, pkgs, ... -}: let +}: +let virtualHostName = "forgejo.helveticanonstandard.net"; -in { +in +{ age.secrets = lib.mkSecrets { forgejo-mailer = { mode = "400"; @@ -19,6 +21,7 @@ in { services.forgejo = { enable = true; + package = pkgs.forgejo; database.type = "postgres"; lfs.enable = true; settings = { @@ -51,25 +54,28 @@ in { secrets.mailer.PASSWD = config.age.secrets.forgejo-mailer.path; }; + # TODO what systemd.services.forgejo.preStart = lib.getExe pkgs.writeShellApplication { name = "forgejo-init-admin"; runtimeInputs = [ config.services.forgejo.package ]; - text = let - passwordFile = config.age.secrets.forgejo-admin.path; - in '' - admins=$(admin user list --admin) - admins=$((admins - 1)) + text = + let + passwordFile = config.age.secrets.forgejo-admin.path; + in + '' + admins=$(admin user list --admin) + admins=$((admins - 1)) - if ((admins < 1)); then - gitea admin user create \ - --admin \ - --email helvetica@helveticanonstandard.net \ - --username helvetica \ - --password "$(cat -- ${passwordFile})" - fi - ''; + if ((admins < 1)); then + gitea admin user create \ + --admin \ + --email helvetica@helveticanonstandard.net \ + --username helvetica \ + --password "$(cat -- ${passwordFile})" + fi + ''; }; services.nginx.virtualHosts.${virtualHostName} = { @@ -80,9 +86,11 @@ in { client_max_body_size 512M; ''; - locations."/".proxyPass = let - host = config.services.forgejo.settings.server.HTTP_ADDR; - port = builtins.toString config.services.forgejo.settings.server.HTTP_PORT; - in "http://${host}:${port}"; + locations."/".proxyPass = + let + host = config.services.forgejo.settings.server.HTTP_ADDR; + port = builtins.toString config.services.forgejo.settings.server.HTTP_PORT; + in + "http://${host}:${port}"; }; } diff --git a/hosts/headless/abacus/hardware.nix b/hosts/abacus/hardware.nix similarity index 52% rename from hosts/headless/abacus/hardware.nix rename to hosts/abacus/hardware.nix index 8f2220e..0016566 100644 --- a/hosts/headless/abacus/hardware.nix +++ b/hosts/abacus/hardware.nix @@ -1,11 +1,18 @@ -{modulesPath, ...}: { +{ modulesPath, ... }: +{ imports = [ "${modulesPath}/profiles/qemu-guest.nix" ]; nixpkgs.hostPlatform = "aarch64-linux"; - boot.initrd.availableKernelModules = ["xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod"]; + boot.initrd.availableKernelModules = [ + "xhci_pci" + "virtio_pci" + "virtio_scsi" + "usbhid" + "sr_mod" + ]; powerManagement.cpuFreqGovernor = "performance"; } diff --git a/hosts/headless/abacus/headscale.nix b/hosts/abacus/headscale.nix similarity index 68% rename from hosts/headless/abacus/headscale.nix rename to hosts/abacus/headscale.nix index b17cece..4009020 100644 --- a/hosts/headless/abacus/headscale.nix +++ b/hosts/abacus/headscale.nix @@ -1,6 +1,8 @@ -{config, ...}: let +{ config, ... }: +let virtualHostName = "headscale.helveticanonstandard.net"; -in { +in +{ services.headscale = { enable = true; address = "127.0.0.1"; @@ -16,10 +18,12 @@ in { forceSSL = true; enableACME = true; locations."/" = { - proxyPass = let - host = config.services.headscale.address; - port = builtins.toString config.services.headscale.port; - in "http://${host}:${port}"; + proxyPass = + let + host = config.services.headscale.address; + port = builtins.toString config.services.headscale.port; + in + "http://${host}:${port}"; proxyWebsockets = true; }; }; diff --git a/hosts/headless/abacus/mealie.nix b/hosts/abacus/mealie.nix similarity index 61% rename from hosts/headless/abacus/mealie.nix rename to hosts/abacus/mealie.nix index 7601750..217ad63 100644 --- a/hosts/headless/abacus/mealie.nix +++ b/hosts/abacus/mealie.nix @@ -1,6 +1,8 @@ -{config, ...}: let +{ config, ... }: +let virtualHostName = "mealie.helveticanonstandard.net"; -in { +in +{ services.mealie = { enable = true; settings = { @@ -15,9 +17,11 @@ in { enableACME = true; forceSSL = true; - locations."/".proxyPass = let - host = config.services.mealie.listenAddress; - port = builtins.toString config.services.mealie.port; - in "http://${host}:${port}"; + locations."/".proxyPass = + let + host = config.services.mealie.listenAddress; + port = builtins.toString config.services.mealie.port; + in + "http://${host}:${port}"; }; } diff --git a/hosts/headless/abacus/navidrome.nix b/hosts/abacus/navidrome.nix similarity index 59% rename from hosts/headless/abacus/navidrome.nix rename to hosts/abacus/navidrome.nix index 3470813..56e030e 100644 --- a/hosts/headless/abacus/navidrome.nix +++ b/hosts/abacus/navidrome.nix @@ -1,6 +1,8 @@ -{config, ...}: let +{ config, ... }: +let virtualHostName = "navidrome.helveticanonstandard.net"; -in { +in +{ services.navidrome = { enable = true; settings = { @@ -15,9 +17,11 @@ in { enableACME = true; forceSSL = true; - locations."/".proxyPass = let - host = config.services.navidrome.settings.Address; - port = builtins.toString config.services.navidrome.settings.Port; - in "http://${host}:${port}"; + locations."/".proxyPass = + let + host = config.services.navidrome.settings.Address; + port = builtins.toString config.services.navidrome.settings.Port; + in + "http://${host}:${port}"; }; } diff --git a/hosts/abacus/networking.nix b/hosts/abacus/networking.nix new file mode 100644 index 0000000..6c07960 --- /dev/null +++ b/hosts/abacus/networking.nix @@ -0,0 +1,23 @@ +{ + networking = + let + interface = "enp1s0"; + in + { + domain = "wrz.one"; + interfaces.${interface}.ipv6.addresses = [ + { + address = "2a01:4f9:c012:92b5::2"; + prefixLength = 64; + } + ]; + defaultGateway6 = { + address = "fe80::1"; + inherit interface; + }; + firewall.allowedTCPPorts = [ + 80 + 443 + ]; + }; +} diff --git a/hosts/abacus/nginx.nix b/hosts/abacus/nginx.nix new file mode 100644 index 0000000..d601045 --- /dev/null +++ b/hosts/abacus/nginx.nix @@ -0,0 +1,32 @@ +{ + services.nginx = { + enable = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + + commonHttpConfig = '' + error_log stderr; + access_log /var/log/nginx/access.log; + ''; + + virtualHosts = + let + matchAll = ''~.*''; + matchWww = ''~^www\.(?.+)$''; + in + { + # Redirect anything that doesn't match any server name to networking.domain + ${matchAll} = { + default = true; + rejectSSL = true; + + globalRedirect = "wrz.one"; + }; + # Redirect www to non-www + ${matchWww}.globalRedirect = "$domain"; + }; + }; +} diff --git a/hosts/headless/abacus/postgresql.nix b/hosts/abacus/postgresql.nix similarity index 100% rename from hosts/headless/abacus/postgresql.nix rename to hosts/abacus/postgresql.nix diff --git a/hosts/abacus/restic.nix b/hosts/abacus/restic.nix new file mode 100644 index 0000000..14e8994 --- /dev/null +++ b/hosts/abacus/restic.nix @@ -0,0 +1,41 @@ +{ + attrName, + config, + lib, + ... +}: +let + secretName = "restic-${attrName}"; + secret = config.age.secrets.${secretName}; +in +{ + age.secrets = lib.mkSecrets { ${secretName} = { }; }; + + services.restic.backups.remote = { + repository = "sftp:u459482@u459482.your-storagebox.de:/${attrName}"; + initialize = true; + paths = [ + config.services.vaultwarden.backupDir + config.services.syncthing.dataDir + config.services.forgejo.stateDir + config.services.postgresqlBackup.location + config.services.postgresqlBackup.location + # TODO: Add stateDir options for these + "/var/lib/headscale" + "/var/lib/navidrome" + ]; + passwordFile = secret.path; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + ]; + timerConfig = { + OnCalendar = "*-*-* 03:00:00"; + Persistent = true; + }; + extraOptions = [ + "sftp.args='-i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'" + ]; + }; +} diff --git a/hosts/abacus/static-sites.nix b/hosts/abacus/static-sites.nix new file mode 100644 index 0000000..b47d33a --- /dev/null +++ b/hosts/abacus/static-sites.nix @@ -0,0 +1,34 @@ +{ + config, + lib, + ... +}: +let + parent = "/var/www"; + sites = [ + "wrz.one" + "helveticanonstandard.net" + ]; +in +lib.mkMerge ( + map ( + virtualHostName: + let + root = "${parent}/${virtualHostName}"; + in + { + services.nginx.virtualHosts.${virtualHostName} = { + enableACME = true; + forceSSL = true; + + inherit root; + }; + + systemd.tmpfiles.settings."10-static-sites".${root}.d = { + user = config.users.mainUser; + group = "users"; + mode = "0755"; + }; + } + ) sites +) diff --git a/hosts/headful/flamingo/system.nix b/hosts/abacus/system.nix similarity index 100% rename from hosts/headful/flamingo/system.nix rename to hosts/abacus/system.nix diff --git a/hosts/headless/abacus/vaultwarden.nix b/hosts/abacus/vaultwarden.nix similarity index 71% rename from hosts/headless/abacus/vaultwarden.nix rename to hosts/abacus/vaultwarden.nix index bd3bf96..f63b97b 100644 --- a/hosts/headless/abacus/vaultwarden.nix +++ b/hosts/abacus/vaultwarden.nix @@ -2,11 +2,13 @@ config, lib, ... -}: let +}: +let virtualHostName = "vault.wrz.one"; backupDir = "/srv/backup/vaultwarden"; -in { - age.secrets = lib.mkSecrets {vaultwarden = {};}; +in +{ + age.secrets = lib.mkSecrets { vaultwarden = { }; }; services.vaultwarden = { enable = true; @@ -37,10 +39,12 @@ in { forceSSL = true; locations."/" = { - proxyPass = let - host = config.services.vaultwarden.config.ROCKET_ADDRESS; - port = builtins.toString config.services.vaultwarden.config.ROCKET_PORT; - in "http://${host}:${port}"; + proxyPass = + let + host = config.services.vaultwarden.config.ROCKET_ADDRESS; + port = builtins.toString config.services.vaultwarden.config.ROCKET_PORT; + in + "http://${host}:${port}"; proxyWebsockets = true; }; }; diff --git a/hosts/headful/work/filesystems.nix b/hosts/flamingo/filesystems.nix similarity index 84% rename from hosts/headful/work/filesystems.nix rename to hosts/flamingo/filesystems.nix index 14ff284..52a1bfd 100644 --- a/hosts/headful/work/filesystems.nix +++ b/hosts/flamingo/filesystems.nix @@ -4,6 +4,6 @@ fileSystems."/" = { fsType = "ext4"; device = "/dev/mapper/main"; - options = ["noatime"]; + options = [ "noatime" ]; }; } diff --git a/hosts/headful/flamingo/hardware.nix b/hosts/flamingo/hardware.nix similarity index 68% rename from hosts/headful/flamingo/hardware.nix rename to hosts/flamingo/hardware.nix index bd39347..92f0ed5 100644 --- a/hosts/headful/flamingo/hardware.nix +++ b/hosts/flamingo/hardware.nix @@ -2,7 +2,8 @@ inputs, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/installer/scan/not-detected.nix" @@ -12,8 +13,13 @@ nixpkgs.hostPlatform = "x86_64-linux"; boot = { - initrd.availableKernelModules = ["xhci_pci" "nvme" "usb_storage" "sd_mod"]; - kernelModules = ["kvm-intel"]; + initrd.availableKernelModules = [ + "xhci_pci" + "nvme" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ "kvm-intel" ]; }; powerManagement.cpuFreqGovernor = "powersave"; diff --git a/hosts/headful/glacier/system.nix b/hosts/flamingo/system.nix similarity index 100% rename from hosts/headful/glacier/system.nix rename to hosts/flamingo/system.nix diff --git a/hosts/headful/flamingo/filesystems.nix b/hosts/glacier/filesystems.nix similarity index 84% rename from hosts/headful/flamingo/filesystems.nix rename to hosts/glacier/filesystems.nix index 14ff284..52a1bfd 100644 --- a/hosts/headful/flamingo/filesystems.nix +++ b/hosts/glacier/filesystems.nix @@ -4,6 +4,6 @@ fileSystems."/" = { fsType = "ext4"; device = "/dev/mapper/main"; - options = ["noatime"]; + options = [ "noatime" ]; }; } diff --git a/hosts/headful/glacier/hardware.nix b/hosts/glacier/hardware.nix similarity index 58% rename from hosts/headful/glacier/hardware.nix rename to hosts/glacier/hardware.nix index b55c9fc..7296c95 100644 --- a/hosts/headful/glacier/hardware.nix +++ b/hosts/glacier/hardware.nix @@ -2,7 +2,8 @@ inputs, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/installer/scan/not-detected.nix" @@ -15,11 +16,18 @@ boot = { initrd = { - availableKernelModules = ["nvme" "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod"]; - kernelModules = ["amdgpu"]; + availableKernelModules = [ + "nvme" + "ahci" + "xhci_pci" + "usbhid" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ "amdgpu" ]; }; - kernelModules = ["kvm-amd"]; - binfmt.emulatedSystems = ["aarch64-linux"]; + kernelModules = [ "kvm-amd" ]; + binfmt.emulatedSystems = [ "aarch64-linux" ]; }; powerManagement.cpuFreqGovernor = "performance"; diff --git a/hosts/glacier/profiles.nix b/hosts/glacier/profiles.nix new file mode 100644 index 0000000..016e2fa --- /dev/null +++ b/hosts/glacier/profiles.nix @@ -0,0 +1,9 @@ +{ + profiles = { + desktop = true; + emulation = true; + gaming = true; + piracy = true; + productivity = true; + }; +} diff --git a/hosts/headful/insomniac/system.nix b/hosts/glacier/system.nix similarity index 100% rename from hosts/headful/insomniac/system.nix rename to hosts/glacier/system.nix diff --git a/hosts/headful/glacier/users.nix b/hosts/glacier/users.nix similarity index 100% rename from hosts/headful/glacier/users.nix rename to hosts/glacier/users.nix diff --git a/hosts/headful/flamingo/libreoffice.nix b/hosts/headful/flamingo/libreoffice.nix deleted file mode 100644 index fd1b44d..0000000 --- a/hosts/headful/flamingo/libreoffice.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "org.libreoffice.LibreOffice" - ]; -} diff --git a/hosts/headful/flamingo/librewolf.nix b/hosts/headful/flamingo/librewolf.nix deleted file mode 100644 index 229aa0a..0000000 --- a/hosts/headful/flamingo/librewolf.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.gitlab.librewolf-community" - ]; -} diff --git a/hosts/headful/flamingo/mpv.nix b/hosts/headful/flamingo/mpv.nix deleted file mode 100644 index 24250ff..0000000 --- a/hosts/headful/flamingo/mpv.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.mpv.Mpv" - ]; -} diff --git a/hosts/headful/flamingo/supersonic.nix b/hosts/headful/flamingo/supersonic.nix deleted file mode 100644 index 8b4dba9..0000000 --- a/hosts/headful/flamingo/supersonic.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.github.dweymouth.supersonic" - ]; -} diff --git a/hosts/headful/glacier/gimp.nix b/hosts/headful/glacier/gimp.nix deleted file mode 100644 index 468fc89..0000000 --- a/hosts/headful/glacier/gimp.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "org.gimp.GIMP" - ]; -} diff --git a/hosts/headful/glacier/inkscape.nix b/hosts/headful/glacier/inkscape.nix deleted file mode 100644 index c274256..0000000 --- a/hosts/headful/glacier/inkscape.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "org.inkscape.Inkscape" - ]; -} diff --git a/hosts/headful/glacier/lanzaboote.nix b/hosts/headful/glacier/lanzaboote.nix deleted file mode 100644 index 9ede875..0000000 --- a/hosts/headful/glacier/lanzaboote.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - setups.secureBoot.enable = true; -} diff --git a/hosts/headful/glacier/libreoffice.nix b/hosts/headful/glacier/libreoffice.nix deleted file mode 100644 index fd1b44d..0000000 --- a/hosts/headful/glacier/libreoffice.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "org.libreoffice.LibreOffice" - ]; -} diff --git a/hosts/headful/glacier/librewolf.nix b/hosts/headful/glacier/librewolf.nix deleted file mode 100644 index 229aa0a..0000000 --- a/hosts/headful/glacier/librewolf.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.gitlab.librewolf-community" - ]; -} diff --git a/hosts/headful/glacier/mpv.nix b/hosts/headful/glacier/mpv.nix deleted file mode 100644 index 24250ff..0000000 --- a/hosts/headful/glacier/mpv.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.mpv.Mpv" - ]; -} diff --git a/hosts/headful/glacier/steam.nix b/hosts/headful/glacier/steam.nix deleted file mode 100644 index 50a8f9f..0000000 --- a/hosts/headful/glacier/steam.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - services.flatpak.packages = [ - "com.valvesoftware.Steam" - "com.github.Matoking.protontricks" - ]; -} diff --git a/hosts/headful/glacier/supersonic.nix b/hosts/headful/glacier/supersonic.nix deleted file mode 100644 index 8b4dba9..0000000 --- a/hosts/headful/glacier/supersonic.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.github.dweymouth.supersonic" - ]; -} diff --git a/hosts/headful/insomniac/cosmic.nix b/hosts/headful/insomniac/cosmic.nix deleted file mode 100644 index 629d9f9..0000000 --- a/hosts/headful/insomniac/cosmic.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: { - services.greetd.settings.initial_session = { - user = config.users.mainUser; - command = '' - ${lib.getExe' pkgs.coreutils "env"} XCURSOR_THEME="''${XCURSOR_THEME:-Pop}" systemd-cat --identifier start-cosmic ${lib.getExe' pkgs.cosmic-session "start-cosmic"} - ''; - }; - - environment.cosmic.excludePackages = [ - pkgs.cosmic-store - ]; -} diff --git a/hosts/headful/insomniac/dolphin.nix b/hosts/headful/insomniac/dolphin.nix deleted file mode 100644 index c37c31b..0000000 --- a/hosts/headful/insomniac/dolphin.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "org.DolphinEmu.dolphin-emu" - ]; -} diff --git a/hosts/headful/insomniac/flatpak.nix b/hosts/headful/insomniac/flatpak.nix deleted file mode 100644 index 9976199..0000000 --- a/hosts/headful/insomniac/flatpak.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - services.flatpak.update.auto = { - enable = true; - onCalendar = "weekly"; - }; -} diff --git a/hosts/headful/insomniac/freetube.nix b/hosts/headful/insomniac/freetube.nix deleted file mode 100644 index c56f588..0000000 --- a/hosts/headful/insomniac/freetube.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.freetubeapp.FreeTube" - ]; -} diff --git a/hosts/headful/insomniac/rmg.nix b/hosts/headful/insomniac/rmg.nix deleted file mode 100644 index c8771df..0000000 --- a/hosts/headful/insomniac/rmg.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "com.github.Rosalie241.RMG" - ]; -} diff --git a/hosts/headful/insomniac/steam.nix b/hosts/headful/insomniac/steam.nix deleted file mode 100644 index e51a6e8..0000000 --- a/hosts/headful/insomniac/steam.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "com.valvesoftware.Steam" - ]; -} diff --git a/hosts/headful/insomniac/supersonic.nix b/hosts/headful/insomniac/supersonic.nix deleted file mode 100644 index 8b4dba9..0000000 --- a/hosts/headful/insomniac/supersonic.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.github.dweymouth.supersonic" - ]; -} diff --git a/hosts/headful/work/kubectl.nix b/hosts/headful/work/kubectl.nix deleted file mode 100644 index a3937a4..0000000 --- a/hosts/headful/work/kubectl.nix +++ /dev/null @@ -1,6 +0,0 @@ -{pkgs, ...}: { - environment.systemPackages = [ - pkgs.kubectl - pkgs.awscli - ]; -} diff --git a/hosts/headful/work/php.nix b/hosts/headful/work/php.nix deleted file mode 100644 index 7e8e644..0000000 --- a/hosts/headful/work/php.nix +++ /dev/null @@ -1,95 +0,0 @@ -{ - lib, - inputs, - pkgs, - ... -}: let - supportedPhps = [ - "php72" - "php73" - "php74" - "php80" - "php81" - "php82" - "php83" - "php84" - ]; - - selectedPhp = lib.last supportedPhps; - - extraConfig = '' - memory_limit = -1 - - xdebug.mode = develop,coverage,gcstats,profile,debug,trace - xdebug.discover_client_host = 1 - xdebug.client_host = localhost - ''; - - # Wrap all PHP versions with the extensions I need and bundle composer - phps = lib.genAttrs supportedPhps ( - phpName: let - phpBase = inputs.phps.packages.${pkgs.system}.${phpName}; - phpWithEnv = phpBase.buildEnv { - extensions = { - enabled, - all, - }: - enabled - ++ [all.xdebug] - ++ ( - if (lib.versionAtLeast phpBase.version "8") - then [all.amqp] - else [] - ); - inherit extraConfig; - }; - phpWithTools = pkgs.symlinkJoin { - inherit (phpWithEnv) name version meta passthru; - paths = [ - phpWithEnv - phpWithEnv.packages.composer - ]; - }; - in - phpWithTools - ); - - prefix = "/var/lib/phps"; - - # Tell Symfony's CLI where it can access the different PHP versions - symfony-cli = let - package = pkgs.symfony-cli; - in - pkgs.symlinkJoin { - inherit (package) pname version meta; - - paths = [package]; - - buildInputs = [pkgs.makeWrapper]; - - postBuild = '' - wrapProgram $out/bin/${package.meta.mainProgram} \ - --suffix PATH : ${pkgs.lib.makeBinPath ( - builtins.attrValues phps - )} - ''; - }; -in { - nix.settings = { - substituters = ["https://fossar.cachix.org/"]; - trusted-public-keys = ["fossar.cachix.org-1:Zv6FuqIboeHPWQS7ysLCJ7UT7xExb4OE8c4LyGb5AsE="]; - }; - - # Link PHP installations so that PhpStorm knows about them - systemd.tmpfiles.settings = - builtins.mapAttrs (name: drv: { - "${prefix}/${name}"."L+".argument = drv.outPath; - }) - phps; - - environment.systemPackages = [ - pkgs.jetbrains.phpstorm - phps.${selectedPhp} - symfony-cli - ]; -} diff --git a/hosts/headful/work/supersonic.nix b/hosts/headful/work/supersonic.nix deleted file mode 100644 index 8b4dba9..0000000 --- a/hosts/headful/work/supersonic.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - services.flatpak.packages = [ - "io.github.dweymouth.supersonic" - ]; -} diff --git a/hosts/headful/work/syncthing.nix b/hosts/headful/work/syncthing.nix deleted file mode 100644 index 25c60a0..0000000 --- a/hosts/headful/work/syncthing.nix +++ /dev/null @@ -1,3 +0,0 @@ -{lib, ...}: { - services.syncthing.enable = lib.mkForce false; -} diff --git a/hosts/headless/abacus/backup.nix b/hosts/headless/abacus/backup.nix deleted file mode 100644 index d6cef2f..0000000 --- a/hosts/headless/abacus/backup.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - attrName, - config, - lib, - ... -}: { - age.secrets = lib.mkSecrets {"restic-${attrName}" = {};}; - - services.restic.backups.${attrName} = { - repository = "sftp:u385962@u385962.your-storagebox.de:/restic/${attrName}"; - initialize = true; - paths = [ - config.services.vaultwarden.backupDir - config.services.syncthing.dataDir - config.services.forgejo.stateDir - config.services.postgresqlBackup.location - config.services.postgresqlBackup.location - # TODO: Add stateDir options for these - "/var/lib/headscale" - "/var/lib/navidrome" - ]; - passwordFile = config.age.secrets."restic-${attrName}".path; - pruneOpts = ["--keep-daily 7" "--keep-weekly 5" "--keep-monthly 12"]; - timerConfig = { - OnCalendar = "*-*-* 03:00:00"; - Persistent = true; - }; - extraOptions = ["sftp.args='-i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'"]; - }; -} diff --git a/hosts/headless/abacus/networking.nix b/hosts/headless/abacus/networking.nix deleted file mode 100644 index a6f04a5..0000000 --- a/hosts/headless/abacus/networking.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - networking = let - interface = "enp1s0"; - in { - domain = "wrz.one"; - interfaces.${interface}.ipv6.addresses = [ - { - address = "2a01:4f9:c012:92b5::2"; - prefixLength = 64; - } - ]; - defaultGateway6 = { - address = "fe80::1"; - inherit interface; - }; - firewall.allowedTCPPorts = [80 443]; - }; -} diff --git a/hosts/headless/abacus/nginx.nix b/hosts/headless/abacus/nginx.nix deleted file mode 100644 index d4a8656..0000000 --- a/hosts/headless/abacus/nginx.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - services.nginx = { - enable = true; - - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - - commonHttpConfig = '' - error_log stderr; - access_log /var/log/nginx/access.log; - ''; - - virtualHosts = let - matchAll = ''~.*''; - matchWww = ''~^www\.(?.+)$''; - in { - # Redirect anything that doesn't match any server name to networking.domain - ${matchAll} = { - default = true; - rejectSSL = true; - - globalRedirect = "wrz.one"; - }; - # Redirect www to non-www - ${matchWww}.globalRedirect = "$domain"; - }; - }; -} diff --git a/hosts/headless/abacus/static-sites.nix b/hosts/headless/abacus/static-sites.nix deleted file mode 100644 index 4e0deda..0000000 --- a/hosts/headless/abacus/static-sites.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - config, - lib, - ... -}: let - parent = "/var/www"; - sites = [ - "wrz.one" - "helveticanonstandard.net" - ]; -in - lib.mkMerge ( - map ( - virtualHostName: let - root = "${parent}/${virtualHostName}"; - in { - services.nginx.virtualHosts.${virtualHostName} = { - enableACME = true; - forceSSL = true; - - inherit root; - }; - - systemd.tmpfiles.settings."10-static-sites".${root}.d = { - user = config.users.mainUser; - group = "users"; - mode = "0755"; - }; - } - ) - sites - ) diff --git a/hosts/headless/vessel/backup.nix b/hosts/headless/vessel/backup.nix deleted file mode 100644 index 02ae2b9..0000000 --- a/hosts/headless/vessel/backup.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - attrName, - config, - lib, - pkgs, - ... -}: let - backups = { - music = "/srv/music"; - safe = "/srv/safe"; - storage = "/srv/storage"; - sync = config.services.syncthing.dataDir; - }; -in { - systemd = lib.mkMerge (map ( - backupName: let - systemdName = "${backupName}-backup"; - in { - timers.${systemdName} = { - description = "Local rsync Backup ${backupName}"; - wantedBy = ["timers.target"]; - timerConfig = { - OnCalendar = "*-*-* 03:00:00"; # TODO - Persistent = true; - Unit = "${systemdName}.service"; # TODO - }; - }; - - services.${systemdName} = { - description = "Local rsync Backup ${backupName}"; - serviceConfig = { - Type = "oneshot"; - User = "root"; - Group = "root"; - }; - # TODO - script = '' - ${lib.getExe pkgs.rsync} --verbose --verbose --archive --update --delete --mkpath -- ${backups.${backupName}}/ /srv/backup/${backupName}/ - ''; - }; - } - ) (lib.attrNames backups)); - - age.secrets = lib.mkSecrets {"restic-${attrName}" = {};}; - - services.restic.backups.${attrName} = { - repository = "sftp:u385962@u385962.your-storagebox.de:/restic/${attrName}"; - initialize = true; - paths = [ - backups.safe - backups.sync - ]; - passwordFile = config.age.secrets."restic-${attrName}".path; - pruneOpts = ["--keep-daily 7" "--keep-weekly 5" "--keep-monthly 12"]; - timerConfig = { - OnCalendar = "*-*-* 03:00:00"; # TODO - Persistent = true; - }; - extraOptions = ["sftp.args='-i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'"]; - }; -} diff --git a/hosts/headless/vessel/blocky.nix b/hosts/headless/vessel/blocky.nix deleted file mode 100644 index 091c08d..0000000 --- a/hosts/headless/vessel/blocky.nix +++ /dev/null @@ -1,27 +0,0 @@ -let - upstream = "https://one.one.one.one/dns-query"; -in { - services = { - resolved.extraConfig = "DNSStubListener=no"; - blocky = { - enable = true; - settings = { - ports.dns = 53; - upstreams.groups.default = [upstream]; - bootstrapDns = { - inherit upstream; - ips = ["1.1.1.1" "1.0.0.1"]; - }; - blocking = { - denylists.ads = ["https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"]; - clientGroupsBlock.default = ["ads"]; - }; - caching = { - minTime = "5m"; - maxTime = "30m"; - prefetching = true; - }; - }; - }; - }; -} diff --git a/hosts/headless/vessel/filesystems.nix b/hosts/headless/vessel/filesystems.nix deleted file mode 100644 index 1da6965..0000000 --- a/hosts/headless/vessel/filesystems.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - fileSystems = { - "/" = { - fsType = "ext4"; - label = "main"; - options = ["noatime"]; - }; - "/srv/backup" = { - label = "backup"; - fsType = "ext4"; - options = ["noatime"]; - }; - }; -} diff --git a/hosts/headless/vessel/musicomp.nix b/hosts/headless/vessel/musicomp.nix deleted file mode 100644 index 56b75b2..0000000 --- a/hosts/headless/vessel/musicomp.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - inputs, - self, - lib, - pkgs, - ... -}: { - imports = [ - inputs.musicomp.nixosModules.default - ]; - - services.musicomp.jobs.main = { - music = "/srv/music"; - comp = "/srv/compmusic"; - timerConfig = { - OnCalendar = "daily"; - Persistent = true; - }; - inhibitsSleep = true; - post = let - remoteDir = self.nixosConfigurations.abacus.config.services.navidrome.settings.MusicFolder; - rsyncExe = lib.getExe pkgs.rsync; - rsh = "${lib.getExe pkgs.openssh} -i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; - in '' - ${rsyncExe} \ - --archive \ - --recursive \ - --delete \ - --update \ - --mkpath \ - --verbose --verbose \ - --exclude lost+found \ - --rsh ${lib.escapeShellArg rsh} \ - /srv/compmusic/ root@wrz.one:${remoteDir} - ''; - }; -} diff --git a/hosts/headless/vessel/storage.nix b/hosts/headless/vessel/storage.nix deleted file mode 100644 index e899606..0000000 --- a/hosts/headless/vessel/storage.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - systemd.tmpfiles.settings = { - "10-safe"."/srv/safe".d = { - user = "helvetica"; - group = "users"; - mode = "0755"; - }; - - "10-storage"."/srv/storage".d = { - user = "helvetica"; - group = "users"; - mode = "0755"; - }; - - "10-music"."/srv/music".d = { - user = "helvetica"; - group = "users"; - mode = "0755"; - }; - - "10-compmusic"."/srv/compmusic".d = { - user = "helvetica"; - group = "users"; - mode = "0755"; - }; - }; -} diff --git a/hosts/headful/insomniac/filesystems.nix b/hosts/insomniac/filesystems.nix similarity index 71% rename from hosts/headful/insomniac/filesystems.nix rename to hosts/insomniac/filesystems.nix index 5e977d8..07eb879 100644 --- a/hosts/headful/insomniac/filesystems.nix +++ b/hosts/insomniac/filesystems.nix @@ -2,6 +2,6 @@ fileSystems."/" = { fsType = "ext4"; label = "main"; - options = ["noatime"]; + options = [ "noatime" ]; }; } diff --git a/hosts/insomniac/freetube.nix b/hosts/insomniac/freetube.nix new file mode 100644 index 0000000..b24fd0d --- /dev/null +++ b/hosts/insomniac/freetube.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + environment.systemPackages = [ + pkgs.freetube + ]; +} diff --git a/hosts/headful/insomniac/hardware.nix b/hosts/insomniac/hardware.nix similarity index 65% rename from hosts/headful/insomniac/hardware.nix rename to hosts/insomniac/hardware.nix index 091424d..8bd84e9 100644 --- a/hosts/headful/insomniac/hardware.nix +++ b/hosts/insomniac/hardware.nix @@ -2,7 +2,8 @@ inputs, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/installer/scan/not-detected.nix" @@ -15,10 +16,16 @@ boot = { initrd = { - availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "sd_mod"]; - kernelModules = ["amdgpu"]; + availableKernelModules = [ + "nvme" + "xhci_pci" + "ahci" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ "amdgpu" ]; }; - kernelModules = ["kvm-amd"]; + kernelModules = [ "kvm-amd" ]; }; powerManagement.cpuFreqGovernor = "performance"; diff --git a/hosts/headful/work/system.nix b/hosts/insomniac/system.nix similarity index 100% rename from hosts/headful/work/system.nix rename to hosts/insomniac/system.nix diff --git a/hosts/headful/insomniac/users.nix b/hosts/insomniac/users.nix similarity index 93% rename from hosts/headful/insomniac/users.nix rename to hosts/insomniac/users.nix index e059585..1d93475 100644 --- a/hosts/headful/insomniac/users.nix +++ b/hosts/insomniac/users.nix @@ -2,9 +2,11 @@ config, lib, ... -}: let +}: +let inherit (config.users) mainUser; -in { +in +{ users = { mainUser = lib.mkForce "insomniac"; users.${mainUser}.description = lib.mkForce "Insomniac"; diff --git a/hosts/vessel/filesystems.nix b/hosts/vessel/filesystems.nix new file mode 100644 index 0000000..6daadbd --- /dev/null +++ b/hosts/vessel/filesystems.nix @@ -0,0 +1,24 @@ +{ + fileSystems = { + "/" = { + label = "white"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + "/srv/vault" = { + label = "black"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + "/srv/void" = { + label = "green"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + "/srv/sync" = { + label = "red"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + }; +} diff --git a/hosts/headless/vessel/hardware.nix b/hosts/vessel/hardware.nix similarity index 66% rename from hosts/headless/vessel/hardware.nix rename to hosts/vessel/hardware.nix index 82aab42..d75f671 100644 --- a/hosts/headless/vessel/hardware.nix +++ b/hosts/vessel/hardware.nix @@ -2,7 +2,8 @@ inputs, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/installer/scan/not-detected.nix" @@ -14,8 +15,15 @@ nixpkgs.hostPlatform = "x86_64-linux"; boot = { - initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"]; - kernelModules = ["kvm-intel"]; + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ "kvm-intel" ]; }; powerManagement.cpuFreqGovernor = "powersave"; diff --git a/hosts/vessel/musicomp.nix b/hosts/vessel/musicomp.nix new file mode 100644 index 0000000..4d61a8a --- /dev/null +++ b/hosts/vessel/musicomp.nix @@ -0,0 +1,45 @@ +{ + inputs, + self, + lib, + pkgs, + ... +}: +{ + imports = [ + inputs.musicomp.nixosModules.default + ]; + + services.musicomp.jobs.main = { + music = "/srv/music"; + comp = "/srv/compmusic"; + timerConfig = { + OnCalendar = "daily"; + Persistent = true; + }; + inhibitsSleep = true; + post = + let + remoteDir = self.nixosConfigurations.abacus.config.services.navidrome.settings.MusicFolder; + package = pkgs.writeShellApplication { + name = "sync"; + runtimeInputs = [ + pkgs.openssh + pkgs.rsync + ]; + text = '' + rsync \ + --archive \ + --recursive \ + --delete \ + --update \ + --mkpath \ + --verbose --verbose \ + --rsh 'ssh -i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' \ + /srv/void/compmusic/ root@wrz.one:${lib.escapeShellArg remoteDir} + ''; + }; + in + lib.getExe package; + }; +} diff --git a/hosts/vessel/restic.nix b/hosts/vessel/restic.nix new file mode 100644 index 0000000..fd22f6b --- /dev/null +++ b/hosts/vessel/restic.nix @@ -0,0 +1,56 @@ +{ + attrName, + config, + lib, + pkgs, + ... +}: +let + secretName = "restic-${attrName}"; + secret = config.age.secrets.${secretName}; +in +{ + age.secrets = lib.mkSecrets { ${secretName} = { }; }; + + services.restic.backups = { + local = { + repository = "/srv/backup/void"; + initialize = true; + paths = [ + "/srv/void" + ]; + passwordFile = secret.path; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + ]; + timerConfig = { + OnCalendar = "*-*-* 03:00:00"; + Persistent = true; + }; + }; + + remote = { + repository = "sftp:u459482@u459482.your-storagebox.de:/${attrName}"; + initialize = true; + paths = [ + config.services.syncthing.dataDir + "/srv/vault" + ]; + passwordFile = secret.path; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + ]; + timerConfig = { + OnCalendar = "*-*-* 03:00:00"; + Persistent = true; + }; + extraOptions = [ + "sftp.args='-i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'" + ]; + }; + }; +} diff --git a/hosts/vessel/rsync.nix b/hosts/vessel/rsync.nix new file mode 100644 index 0000000..9fe2546 --- /dev/null +++ b/hosts/vessel/rsync.nix @@ -0,0 +1,7 @@ +{ + services.rsync.jobs.vault = { + sources = [ "/srv/vault/" ]; + destination = "/srv/sync/"; + inhibitsSleep = true; + }; +} diff --git a/hosts/vessel/storage.nix b/hosts/vessel/storage.nix new file mode 100644 index 0000000..25c569c --- /dev/null +++ b/hosts/vessel/storage.nix @@ -0,0 +1,16 @@ +{ + systemd.tmpfiles.settings = { + music = { + "/srv/vault/music".d = { + user = "root"; + group = "users"; + mode = "0755"; + }; + "/srv/void/compmusic".d = { + user = "root"; + group = "users"; + mode = "0755"; + }; + }; + }; +} diff --git a/hosts/headless/abacus/system.nix b/hosts/vessel/system.nix similarity index 100% rename from hosts/headless/abacus/system.nix rename to hosts/vessel/system.nix diff --git a/hosts/headful/work/docker.nix b/hosts/work/docker.nix similarity index 97% rename from hosts/headful/work/docker.nix rename to hosts/work/docker.nix index 5f25fb5..34032f1 100644 --- a/hosts/headful/work/docker.nix +++ b/hosts/work/docker.nix @@ -2,7 +2,8 @@ config, pkgs, ... -}: { +}: +{ virtualisation.docker.enable = true; environment.systemPackages = [ diff --git a/hosts/headful/glacier/filesystems.nix b/hosts/work/filesystems.nix similarity index 84% rename from hosts/headful/glacier/filesystems.nix rename to hosts/work/filesystems.nix index 14ff284..52a1bfd 100644 --- a/hosts/headful/glacier/filesystems.nix +++ b/hosts/work/filesystems.nix @@ -4,6 +4,6 @@ fileSystems."/" = { fsType = "ext4"; device = "/dev/mapper/main"; - options = ["noatime"]; + options = [ "noatime" ]; }; } diff --git a/hosts/headful/work/hardware.nix b/hosts/work/hardware.nix similarity index 62% rename from hosts/headful/work/hardware.nix rename to hosts/work/hardware.nix index 24f1ac0..531c541 100644 --- a/hosts/headful/work/hardware.nix +++ b/hosts/work/hardware.nix @@ -2,7 +2,8 @@ inputs, modulesPath, ... -}: { +}: +{ imports = [ "${modulesPath}/installer/scan/not-detected.nix" @@ -16,10 +17,16 @@ boot = { initrd = { - availableKernelModules = ["nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod"]; - kernelModules = []; + availableKernelModules = [ + "nvme" + "xhci_pci" + "thunderbolt" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ ]; }; - kernelModules = ["kvm-amd"]; - extraModulePackages = []; + kernelModules = [ "kvm-amd" ]; + extraModulePackages = [ ]; }; } diff --git a/hosts/headful/work/hosts.nix b/hosts/work/hosts.nix similarity index 100% rename from hosts/headful/work/hosts.nix rename to hosts/work/hosts.nix diff --git a/hosts/work/php.nix b/hosts/work/php.nix new file mode 100644 index 0000000..ee7281a --- /dev/null +++ b/hosts/work/php.nix @@ -0,0 +1,22 @@ +{ + config, + inputs, + pkgs, + ... +}: +{ + imports = [ + inputs.myphps.nixosModules.default + ]; + + services.myphps = { + enable = true; + prefix = "/var/lib/phps"; + }; + + environment.systemPackages = [ + pkgs.jetbrains.phpstorm + config.services.myphps.phps.php + inputs.myphps.packages.${pkgs.system}.symfony-cli + ]; +} diff --git a/hosts/headful/work/plasma.nix b/hosts/work/plasma.nix similarity index 90% rename from hosts/headful/work/plasma.nix rename to hosts/work/plasma.nix index 03996b4..37ece95 100644 --- a/hosts/headful/work/plasma.nix +++ b/hosts/work/plasma.nix @@ -2,7 +2,8 @@ lib, pkgs, ... -}: { +}: +{ services = { desktopManager = { cosmic.enable = lib.mkForce false; @@ -30,6 +31,6 @@ xdg.portal = { xdgOpenUsePortal = true; - extraPortals = [pkgs.xdg-desktop-portal-gtk]; + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; }; } diff --git a/hosts/headless/vessel/system.nix b/hosts/work/system.nix similarity index 100% rename from hosts/headless/vessel/system.nix rename to hosts/work/system.nix diff --git a/hosts/headful/work/tools.nix b/hosts/work/tools.nix similarity index 88% rename from hosts/headful/work/tools.nix rename to hosts/work/tools.nix index 2c2281e..2dca47b 100644 --- a/hosts/headful/work/tools.nix +++ b/hosts/work/tools.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ environment.systemPackages = [ pkgs.gnumake pkgs.unzip diff --git a/hosts/headful/work/users.nix b/hosts/work/users.nix similarity index 93% rename from hosts/headful/work/users.nix rename to hosts/work/users.nix index 87c3ee3..078acbf 100644 --- a/hosts/headful/work/users.nix +++ b/hosts/work/users.nix @@ -2,9 +2,11 @@ config, lib, ... -}: let +}: +let inherit (config.users) mainUser; -in { +in +{ users = { mainUser = lib.mkForce "lukas"; users.${mainUser}.description = lib.mkForce "Lukas Wurzinger"; diff --git a/lib.nix b/lib.nix index c9acc8a..cd56dce 100644 --- a/lib.nix +++ b/lib.nix @@ -9,72 +9,59 @@ lib: _: { ]) paths; - mkIfElse = condition: trueContent: falseContent: + mkIfElse = + condition: trueContent: falseContent: lib.mkMerge [ (lib.mkIf condition trueContent) (lib.mkIf (!condition) falseContent) ]; - mkSecrets = secrets: let - mkSecret = { - name, - secret, - }: - secret - // { - file = ./secrets/${name}.age; - }; - in - builtins.mapAttrs (name: secret: mkSecret {inherit name secret;}) secrets; + mkSecrets = + secrets: + let + mkSecret = + { + name, + secret, + }: + secret + // { + file = ./secrets/${name}.age; + }; + in + builtins.mapAttrs (name: secret: mkSecret { inherit name secret; }) secrets; - genNixosConfigurations = { - inputs, - extraModules ? _: [], - }: let - modulesDir = ./modules; - commonDir = ./common; - classesDir = ./classes; - hostsDir = ./hosts; + genNixosConfigurations = + inputs: + let + modulesDir = ./modules; + profilesDir = ./profiles; + commonDir = ./common; + hostsDir = ./hosts; - commonNixosSystem = { - class, - name, - }: - lib.nixosSystem { - specialArgs = { - inherit (inputs) self; - inherit inputs lib; - attrName = name; + commonNixosSystem = + name: + lib.nixosSystem { + specialArgs = { + inherit (inputs) self; + inherit inputs lib; + attrName = name; + }; + + modules = + (lib.findModules [ + modulesDir + profilesDir + commonDir + (hostsDir + /${name}) + ]); }; - modules = - (lib.findModules [ - modulesDir - commonDir - ./classes/${class} - (classesDir + /${class}) - (hostsDir + /${class}/${name}) - ]) - ++ [ - {networking.hostName = lib.mkDefault name;} - ] - ++ (extraModules {inherit class name;}); - }; - - dirsIn = dir: - lib.pipe dir [ + hosts = lib.pipe hostsDir [ builtins.readDir (lib.filterAttrs (_: type: type == "directory")) builtins.attrNames ]; - in - lib.pipe (dirsIn hostsDir) [ - (classes: - builtins.concatMap ( - class: map (name: {inherit class name;}) (dirsIn (hostsDir + /${class})) - ) - classes) - (map (args: lib.nameValuePair args.name (commonNixosSystem args))) - builtins.listToAttrs - ]; + in + lib.genAttrs hosts commonNixosSystem; } diff --git a/modules/gcadapter.nix b/modules/gcadapter.nix new file mode 100644 index 0000000..3d3bba8 --- /dev/null +++ b/modules/gcadapter.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + ... +}: +let + cfg = config.hardware.gcadapter; +in +{ + options.hardware.gcadapter.enable = lib.mkEnableOption "GameCube Adapter support"; + + config = lib.mkIf cfg.enable { + services.udev.extraRules = '' + ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="666", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device" TAG+="uaccess" + ''; + + boot = { + extraModulePackages = [ + config.boot.kernelPackages.gcadapter-oc-kmod + ]; + + kernelModules = [ + "gcadapter_oc" + ]; + }; + }; +} diff --git a/modules/main-user.nix b/modules/main-user.nix index d714e79..4123a80 100644 --- a/modules/main-user.nix +++ b/modules/main-user.nix @@ -1,6 +1,8 @@ -{lib, ...}: let +{ lib, ... }: +let inherit (lib) types; -in { +in +{ options = { users.mainUser = lib.mkOption { type = types.passwdEntry types.str; diff --git a/modules/rsync.nix b/modules/rsync.nix new file mode 100644 index 0000000..d5d7a55 --- /dev/null +++ b/modules/rsync.nix @@ -0,0 +1,208 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: +let + cfg = config.services.rsync; + inherit (lib) types; + inherit (utils.systemdUtils.unitOptions) unitOption; + settingsToShell = lib.cli.toGNUCommandLineShell { + mkOptionName = k: "--${k}"; + }; + settingsType = + let + simples = [ + types.bool + types.str + types.int + types.float + ]; + in + types.attrsOf ( + types.oneOf ( + simples + ++ [ + (types.listOf (types.oneOf simples)) + ] + ) + ); +in +{ + options.services.rsync = { + enable = lib.mkEnableOption "periodic directory syncing via rsync"; + + package = lib.mkPackageOption pkgs "rsync" { }; + + # commonSettings = lib.mkOption { + # type = settingsType; + # default = { }; + # example = { + # archive = true; + # update = true; + # delete = true; + # mkpath = true; + # }; + # description = '' + # Common arguments to pass to the rsync command. + # ''; + # }; + + jobs = lib.mkOption { + description = '' + Synchronization jobs to run. + ''; + default = { }; + type = types.attrsOf ( + types.submodule { + options = { + sources = lib.mkOption { + type = types.listOf types.str; + example = [ + "/srv/src1/" + "/srv/src2/" + ]; + description = '' + Source directories. + ''; + }; + + destination = lib.mkOption { + type = types.str; + example = "/srv/dst/"; + description = '' + Destination directory. + ''; + }; + + settings = lib.mkOption { + type = settingsType; + default = { }; + example = { + verbose = true; + }; + description = '' + Extra arguments to pass to the rsync command. + ''; + }; + + user = lib.mkOption { + type = types.str; + default = "root"; + description = '' + The name of an existing user account under which the rsync process should run. + ''; + }; + + group = lib.mkOption { + type = types.str; + default = "root"; + description = '' + The name of an existing user group under which the rsync process should run. + ''; + }; + + timerConfig = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf unitOption); + default = { + OnCalendar = "daily"; + Persistent = true; + }; + description = '' + When to run the job. + ''; + }; + + inhibit = lib.mkOption { + default = [ ]; + type = types.listOf types.str; + example = [ + "sleep" + ]; + description = '' + Run the rsync process with an inhibition lock taken; + see {manpage}`systemd-inhibit(1)` for a list of possible operations. + ''; + }; + }; + } + ); + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = lib.all (job: job.sources != [ ]) (lib.attrValues cfg.jobs); + message = '' + At least one source directory must be provided to rsync. + ''; + } + ]; + + systemd = lib.mkMerge ( + lib.mapAttrsToList ( + jobName: job: + let + systemdName = "rsync-job-${jobName}"; + description = "Directory syncing via rsync job ${jobName}"; + in + { + timers.${systemdName} = { + wantedBy = [ + "timers.target" + ]; + inherit description; + inherit (job) timerConfig; + }; + + services.${systemdName} = { + inherit description; + + serviceConfig = { + Type = "oneshot"; + User = job.user; + Group = job.group; + + NoNewPrivileges = true; + PrivateDevices = true; + ProtectSystem = "full"; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + MemoryDenyWriteExecute = true; + LockPersonality = true; + }; + + script = + let + settingsShell = settingsToShell job.settings; + inhibitString = lib.concatStringsSep ":" job.inhibit; + in + '' + ${ + lib.optionalString (job.inhibit != [ ]) '' + ${lib.getExe' config.systemd.package "systemd-inhibit"} \ + --mode block \ + --who ${lib.escapeShellArg description} \ + --what ${lib.escapeShellArg inhibitString} \ + --why ${lib.escapeShellArg "Scheduled rsync job ${jobName}"} \ + -- \ + '' + } \ + ${lib.getExe cfg.package} ${settingsShell} -- \ + ${lib.escapeShellArgs job.sources} \ + ${lib.escapeShellArg job.destination} + ''; + }; + } + ) cfg.jobs + ); + }; + + meta.maintainers = [ + lib.maintainers.lukaswrz + ]; +} diff --git a/modules/secure-boot.nix b/modules/secure-boot.nix deleted file mode 100644 index 91955c3..0000000 --- a/modules/secure-boot.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - config, - lib, - # inputs, - # pkgs, - ... -}: let - cfg = config.setups.secureBoot; -in { - # imports = [ - # inputs.lanzaboote.nixosModules.lanzaboote - # ]; - - options.setups.secureBoot.enable = lib.mkEnableOption "Secure Boot"; - - config = lib.mkIf cfg.enable { - # environment.systemPackages = [ - # pkgs.sbctl - # ]; - - # boot.loader.systemd-boot.enable = lib.mkForce false; - - # boot.lanzaboote = { - # enable = lib.mkForce true; - # pkiBundle = lib.mkDefault "/var/lib/sbctl"; - # }; - }; -} diff --git a/modules/user-types.nix b/modules/user-types.nix index f9595f5..28b5188 100644 --- a/modules/user-types.nix +++ b/modules/user-types.nix @@ -2,15 +2,24 @@ config, lib, ... -}: { - options.users = let - inherit (lib) types; - in { +}: +let + inherit (lib) types; + filterUsers = + predicate: + (lib.pipe config.users.users [ + (lib.filterAttrs (_: predicate)) + builtins.attrNames + ]); +in +{ + options.users = { normalUsers = lib.mkOption { type = types.listOf (types.passwdEntry types.str); description = '' List of normal users. ''; + readOnly = true; }; systemUsers = lib.mkOption { @@ -18,15 +27,11 @@ description = '' List of system users. ''; + readOnly = true; }; }; - config.users = let - filterUsers = pred: (lib.pipe config.users.users [ - (lib.filterAttrs (_: pred)) - builtins.attrNames - ]); - in { + config.users = { normalUsers = filterUsers (user: user.isNormalUser); systemUsers = filterUsers (user: user.isSystemUser); }; diff --git a/profiles/desktop/clipboard.nix b/profiles/desktop/clipboard.nix new file mode 100644 index 0000000..2acb2df --- /dev/null +++ b/profiles/desktop/clipboard.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.wl-clipboard + ]; + }; +} diff --git a/profiles/desktop/compat.nix b/profiles/desktop/compat.nix new file mode 100644 index 0000000..a9a6477 --- /dev/null +++ b/profiles/desktop/compat.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + programs.appimage = { + enable = true; + binfmt = true; + package = pkgs.appimage-run.override { + extraPkgs = pkgs: [ + pkgs.curl + pkgs.zlib + pkgs.libmpg123 + ]; + }; + }; + + boot.binfmt.emulatedSystems = lib.remove pkgs.stdenv.hostPlatform.system [ + "x86_64-linux" + "aarch64-linux" + ]; + + environment.systemPackages = [ + pkgs.wineWow64Packages.waylandFull + ]; + }; +} diff --git a/profiles/desktop/cosmic.nix b/profiles/desktop/cosmic.nix new file mode 100644 index 0000000..8857cc5 --- /dev/null +++ b/profiles/desktop/cosmic.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + inputs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + imports = [ + inputs.nixos-cosmic.nixosModules.default + ]; + + config = lib.mkIf cfg.enable { + + nix.settings = { + substituters = [ "https://cosmic.cachix.org" ]; + trusted-public-keys = [ "cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE=" ]; + }; + + services = { + desktopManager.cosmic.enable = true; + displayManager.cosmic-greeter.enable = true; + }; + + environment.sessionVariables.COSMIC_DATA_CONTROL_ENABLED = 1; + }; +} diff --git a/profiles/desktop/default.nix b/profiles/desktop/default.nix new file mode 100644 index 0000000..f328857 --- /dev/null +++ b/profiles/desktop/default.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: +let + cfg = config.profiles.desktop; +in +{ + options.profiles.desktop = { + enable = lib.mkEnableOption "desktop"; + }; + + # imports = lib.optionals cfg.enable (lib.findModules {} [./profile]); + + config = lib.mkIf cfg.enable { + imports = lib.findModules { } [ ./profile ]; + + assertions = [ + { + assertion = config.profiles.server.enable == false; + message = "The desktop profile is not compatible with the server profile."; + } + ]; + }; + + # config.assertions = lib.mkIf cfg.enable [ + # { + # assertion = config.profiles.server.enable == false; + # message = "The desktop profile is not compatible with the server profile."; + # } + # ]; +} diff --git a/profiles/desktop/firefox.nix b/profiles/desktop/firefox.nix new file mode 100644 index 0000000..e5ba561 --- /dev/null +++ b/profiles/desktop/firefox.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + programs.firefox = { + enable = true; + package = pkgs.librewolf; + preferences = { + "webgl.disabled" = false; + "privacy.resistFingerprinting" = false; + "middlemouse.paste" = false; + "general.autoScroll" = true; + "privacy.clearOnShutdown.history" = false; + "privacy.clearOnShutdown.downloads" = false; + }; + }; + }; +} diff --git a/profiles/desktop/fonts.nix b/profiles/desktop/fonts.nix new file mode 100644 index 0000000..2a528be --- /dev/null +++ b/profiles/desktop/fonts.nix @@ -0,0 +1,48 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + fonts = { + enableDefaultPackages = true; + packages = [ + pkgs.noto-fonts + pkgs.noto-fonts-extra + pkgs.noto-fonts-cjk-sans + pkgs.noto-fonts-cjk-serif + pkgs.noto-fonts-monochrome-emoji + pkgs.noto-fonts-color-emoji + pkgs.nerd-fonts.fira-code + ]; + + fontconfig = { + enable = true; + + defaultFonts = { + monospace = [ + "FiraCode Nerd Font" + ]; + sansSerif = [ + "Noto Sans" + ]; + serif = [ + "Noto Serif" + ]; + emoji = [ + "Noto Color Emoji" + "Noto Emoji" + ]; + }; + }; + + # TODO + fontDir.enable = true; + }; + }; +} diff --git a/profiles/desktop/hardware.nix b/profiles/desktop/hardware.nix new file mode 100644 index 0000000..13163b5 --- /dev/null +++ b/profiles/desktop/hardware.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + hardware = { + bluetooth.enable = true; + steam-hardware.enable = true; + xone.enable = true; + xpadneo.enable = true; + opentabletdriver.enable = true; + gcadapter.enable = true; + graphics.enable = true; + enableAllFirmware = true; + }; + }; +} diff --git a/profiles/desktop/location.nix b/profiles/desktop/location.nix new file mode 100644 index 0000000..fffcb56 --- /dev/null +++ b/profiles/desktop/location.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + location.provider = "geoclue2"; + }; +} diff --git a/profiles/desktop/networking.nix b/profiles/desktop/networking.nix new file mode 100644 index 0000000..bdc6911 --- /dev/null +++ b/profiles/desktop/networking.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + services.resolved.enable = true; + + networking.networkmanager = { + enable = true; + dns = "systemd-resolved"; + }; + + users.groups.networkmanager.members = config.users.normalUsers; + }; +} diff --git a/profiles/desktop/pipewire.nix b/profiles/desktop/pipewire.nix new file mode 100644 index 0000000..7e6986f --- /dev/null +++ b/profiles/desktop/pipewire.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + security.rtkit.enable = true; + + services.pipewire = { + enable = true; + wireplumber.enable = true; + alsa.enable = true; + pulse.enable = true; + jack.enable = true; + }; + }; +} diff --git a/profiles/desktop/printing.nix b/profiles/desktop/printing.nix new file mode 100644 index 0000000..d251c14 --- /dev/null +++ b/profiles/desktop/printing.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + services.printing = { + enable = true; + webInterface = true; + }; + }; +} diff --git a/profiles/desktop/supersonic.nix b/profiles/desktop/supersonic.nix new file mode 100644 index 0000000..7eb28b0 --- /dev/null +++ b/profiles/desktop/supersonic.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.supersonic-wayland + ]; + }; +} diff --git a/profiles/desktop/vesktop.nix b/profiles/desktop/vesktop.nix new file mode 100644 index 0000000..f1b45fe --- /dev/null +++ b/profiles/desktop/vesktop.nix @@ -0,0 +1,17 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + # TODO + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.vesktop + ]; + }; +} diff --git a/profiles/desktop/wayland.nix b/profiles/desktop/wayland.nix new file mode 100644 index 0000000..e76d7fc --- /dev/null +++ b/profiles/desktop/wayland.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + environment.sessionVariables = { + NIXOS_OZONE_WL = "1"; + SDL_VIDEODRIVER = "wayland"; + }; + }; +} diff --git a/profiles/desktop/xdg.nix b/profiles/desktop/xdg.nix new file mode 100644 index 0000000..892a8dc --- /dev/null +++ b/profiles/desktop/xdg.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + xdg.portal.xdgOpenUsePortal = true; + }; +} diff --git a/profiles/desktop/zk.nix b/profiles/desktop/zk.nix new file mode 100644 index 0000000..d4f4a66 --- /dev/null +++ b/profiles/desktop/zk.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.desktop; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.zk + ]; + }; +} diff --git a/profiles/emulation/cemu.nix b/profiles/emulation/cemu.nix new file mode 100644 index 0000000..40ca12b --- /dev/null +++ b/profiles/emulation/cemu.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.emulation; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.cemu + ]; + }; +} diff --git a/profiles/emulation/default.nix b/profiles/emulation/default.nix new file mode 100644 index 0000000..f7b51d8 --- /dev/null +++ b/profiles/emulation/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +let + cfg = config.profiles.emulation; +in +{ + options.profiles.emulation = { + enable = lib.mkEnableOption "emulation"; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = config.profiles.desktop.enable; + message = "The emulation profile depends on the desktop profile."; + } + ]; + }; +} diff --git a/profiles/emulation/dolphin.nix b/profiles/emulation/dolphin.nix new file mode 100644 index 0000000..f103752 --- /dev/null +++ b/profiles/emulation/dolphin.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.emulation; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.dolphin-emu + ]; + }; +} diff --git a/profiles/emulation/rmg.nix b/profiles/emulation/rmg.nix new file mode 100644 index 0000000..4e7cd98 --- /dev/null +++ b/profiles/emulation/rmg.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.emulation; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.rmg-wayland + ]; + }; +} diff --git a/profiles/gaming/default.nix b/profiles/gaming/default.nix new file mode 100644 index 0000000..0694b00 --- /dev/null +++ b/profiles/gaming/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +let + cfg = config.profiles.gaming; +in +{ + options.profiles.gaming = { + enable = lib.mkEnableOption "gaming"; + }; + + imports = lib.optionals cfg.enable (lib.findModules { } [ ./profile ]); + + config.assertions = lib.mkIf cfg.enable [ + { + assertion = config.profiles.desktop.enable; + message = "The gaming profile depends on the desktop profile."; + } + ]; +} diff --git a/classes/headful/gamemode.nix b/profiles/gaming/gamemode.nix similarity index 82% rename from classes/headful/gamemode.nix rename to profiles/gaming/gamemode.nix index b3cd1d2..fa34276 100644 --- a/classes/headful/gamemode.nix +++ b/profiles/gaming/gamemode.nix @@ -3,7 +3,12 @@ lib, pkgs, ... -}: { +}: +let + cfg = config.profiles.gaming; +in +{ + config = lib.mkIf cfg.enable { programs.gamemode = { enable = true; settings = { @@ -18,4 +23,5 @@ }; users.groups.gamemode.members = config.users.normalUsers; + }; } diff --git a/profiles/gaming/prismlauncher.nix b/profiles/gaming/prismlauncher.nix new file mode 100644 index 0000000..4b16a95 --- /dev/null +++ b/profiles/gaming/prismlauncher.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.gaming; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.prismlauncher + ]; + }; +} diff --git a/profiles/gaming/steam.nix b/profiles/gaming/steam.nix new file mode 100644 index 0000000..ddd5d63 --- /dev/null +++ b/profiles/gaming/steam.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.gaming; +in +{ + config = lib.mkIf cfg.enable { + programs.steam = { + enable = true; + extest.enable = true; + protontricks.enable = true; + dedicatedServer.openFirewall = true; + remotePlay.openFirewall = true; + localNetworkGameTransfers.openFirewall = true; + }; + }; +} diff --git a/profiles/piracy/default.nix b/profiles/piracy/default.nix new file mode 100644 index 0000000..6d8ff03 --- /dev/null +++ b/profiles/piracy/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +let + cfg = config.profiles.piracy; +in +{ + options.profiles.piracy = { + enable = lib.mkEnableOption "piracy"; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = config.profiles.desktop.enable; + message = "The piracy profile depends on the desktop profile."; + } + ]; + }; +} diff --git a/profiles/piracy/mullvad.nix b/profiles/piracy/mullvad.nix new file mode 100644 index 0000000..f8a1542 --- /dev/null +++ b/profiles/piracy/mullvad.nix @@ -0,0 +1,17 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.gaming; +in +{ + config = lib.mkIf cfg.enable { + services.mullvad-vpn = { + enable = true; + package = pkgs.mullvad-vpn; + }; + }; +} diff --git a/profiles/piracy/qbittorrent.nix b/profiles/piracy/qbittorrent.nix new file mode 100644 index 0000000..e8ca0a5 --- /dev/null +++ b/profiles/piracy/qbittorrent.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.gaming; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.qbittorrent + ]; + }; +} diff --git a/profiles/productivity/default.nix b/profiles/productivity/default.nix new file mode 100644 index 0000000..88f6e36 --- /dev/null +++ b/profiles/productivity/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +let + cfg = config.profiles.productivity; +in +{ + options.profiles.productivity = { + enable = lib.mkEnableOption "productivity"; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = config.profiles.desktop.enable; + message = "The productivity profile depends on the desktop profile."; + } + ]; + }; +} diff --git a/profiles/productivity/gimp.nix b/profiles/productivity/gimp.nix new file mode 100644 index 0000000..1498376 --- /dev/null +++ b/profiles/productivity/gimp.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.productivity; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.gimp3-with-plugins + ]; + }; +} diff --git a/profiles/productivity/inkscape.nix b/profiles/productivity/inkscape.nix new file mode 100644 index 0000000..b883126 --- /dev/null +++ b/profiles/productivity/inkscape.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.productivity; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.inkscape-with-extensions + ]; + }; +} diff --git a/profiles/productivity/libreoffice.nix b/profiles/productivity/libreoffice.nix new file mode 100644 index 0000000..22897f6 --- /dev/null +++ b/profiles/productivity/libreoffice.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.profiles.productivity; +in +{ + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.libreoffice-fresh + ]; + }; +} diff --git a/profiles/server/default.nix b/profiles/server/default.nix new file mode 100644 index 0000000..0db3279 --- /dev/null +++ b/profiles/server/default.nix @@ -0,0 +1,3 @@ +{ + +} diff --git a/classes/headless/grafana.nix b/profiles/server/grafana.nix similarity index 99% rename from classes/headless/grafana.nix rename to profiles/server/grafana.nix index acd972f..38ccaaa 100644 --- a/classes/headless/grafana.nix +++ b/profiles/server/grafana.nix @@ -45,4 +45,4 @@ # # }; # # }; # } -{} +{ } diff --git a/classes/headless/loki.nix b/profiles/server/loki.nix similarity index 99% rename from classes/headless/loki.nix rename to profiles/server/loki.nix index 89d3b99..61a92e5 100644 --- a/classes/headless/loki.nix +++ b/profiles/server/loki.nix @@ -76,4 +76,4 @@ # }; # }; # } -{} +{ } diff --git a/profiles/server/networking.nix b/profiles/server/networking.nix new file mode 100644 index 0000000..6daa82c --- /dev/null +++ b/profiles/server/networking.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.server; +in +{ + config = lib.mkIf cfg.enable { + networking.useNetworkd = true; + }; +} diff --git a/classes/headless/prometheus.nix b/profiles/server/prometheus.nix similarity index 99% rename from classes/headless/prometheus.nix rename to profiles/server/prometheus.nix index d6bad74..502f9d6 100644 --- a/classes/headless/prometheus.nix +++ b/profiles/server/prometheus.nix @@ -27,4 +27,4 @@ # ]; # }; # } -{} +{ } diff --git a/classes/headless/promtail.nix b/profiles/server/promtail.nix similarity index 99% rename from classes/headless/promtail.nix rename to profiles/server/promtail.nix index c9954c4..88121cb 100644 --- a/classes/headless/promtail.nix +++ b/profiles/server/promtail.nix @@ -39,4 +39,4 @@ # }; # }; # } -{} +{ } diff --git a/profiles/server/time.nix b/profiles/server/time.nix new file mode 100644 index 0000000..1113447 --- /dev/null +++ b/profiles/server/time.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + ... +}: +let + cfg = config.profiles.server; +in +{ + config = lib.mkIf cfg.enable { + time.timeZone = "UTC"; + }; +} diff --git a/pubkeys.nix b/pubkeys.nix index 2af161c..cb6709e 100644 --- a/pubkeys.nix +++ b/pubkeys.nix @@ -1,7 +1,9 @@ { users = { - "lukas@flamingo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAztZgcRBHqX8Wb2nAlP1qCKF205M3un/D1YnREcO7Dy"; - "lukas@glacier" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK4U9RzV/gVGBfrCOye7BlS11g5BS7SmuZ36n2ZIJyAX"; + "helvetica@flamingo" = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAztZgcRBHqX8Wb2nAlP1qCKF205M3un/D1YnREcO7Dy"; + "helvetica@glacier" = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK4U9RzV/gVGBfrCOye7BlS11g5BS7SmuZ36n2ZIJyAX"; "lukas@work" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjvkQeQhAlS+e5EJOXW9Lqd3/uG9qNLIO0NaMFCA0Ew"; }; diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 0a37768..4ddb9bc 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -1,19 +1,21 @@ let pubkeys = import ../pubkeys.nix; inherit (pubkeys) users hosts; -in { - "user-helvetica.age".publicKeys = (builtins.attrValues users) ++ (builtins.attrValues (builtins.removeAttrs hosts ["insomniac"])); - "user-insomniac.age".publicKeys = (builtins.attrValues users) ++ [hosts.insomniac]; +in +{ + "user-helvetica.age".publicKeys = + (builtins.attrValues users) ++ (builtins.attrValues (builtins.removeAttrs hosts [ "insomniac" ])); + "user-insomniac.age".publicKeys = (builtins.attrValues users) ++ [ hosts.insomniac ]; - "miniflux.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + "miniflux.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "vaultwarden.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + "vaultwarden.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "forgejo-mailer.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; - "forgejo-admin.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + "forgejo-mailer.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + "forgejo-admin.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "restic-vessel.age".publicKeys = (builtins.attrValues users) ++ [hosts.vessel]; - "restic-abacus.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + "restic-vessel.age".publicKeys = (builtins.attrValues users) ++ [ hosts.vessel ]; + "restic-abacus.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "syncserver.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + "syncserver.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; } diff --git a/symfony-cli/package.nix b/symfony-cli/package.nix deleted file mode 100644 index 4f2101c..0000000 --- a/symfony-cli/package.nix +++ /dev/null @@ -1,72 +0,0 @@ -{ - lib, - fossarPhps, - symlinkJoin, - symfony-cli, - makeWrapper, -}: let - supportedPhps = [ - "php72" - "php73" - "php74" - "php80" - "php81" - "php82" - "php83" - "php84" - ]; - - extraConfig = '' - memory_limit = -1 - - xdebug.mode = develop,coverage,gcstats,profile,debug,trace - xdebug.discover_client_host = 1 - xdebug.client_host = localhost - ''; - - # Wrap all PHP versions with the extensions I need and bundle composer - phps = lib.genAttrs supportedPhps ( - phpName: let - phpBase = fossarPhps.${phpName}; - phpWithEnv = phpBase.buildEnv { - extensions = { - enabled, - all, - }: - enabled - ++ [all.xdebug] - ++ ( - if (lib.versionAtLeast phpBase.version "8") - then [all.amqp] - else [] - ); - inherit extraConfig; - }; - phpWithTools = symlinkJoin { - inherit (phpWithEnv) name version meta passthru; - paths = [ - phpWithEnv - phpWithEnv.packages.composer - ]; - }; - in - phpWithTools - ); - - package = symfony-cli; -in - # Tell Symfony's CLI where it can access the different PHP versions - symlinkJoin { - inherit (package) pname version meta; - - paths = [package]; - - buildInputs = [makeWrapper]; - - postBuild = '' - wrapProgram $out/bin/${package.meta.mainProgram} \ - --suffix PATH : ${lib.makeBinPath ( - builtins.attrValues phps - )} - ''; - } From 8164e92af6563f525650c47ee819f25ea13c9d6e Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 01:08:10 +0200 Subject: [PATCH 03/10] stuff --- README.md | 62 ++-- common/bash.nix | 5 - common/boot.nix | 28 +- common/bottom.nix | 4 +- common/comma.nix | 5 + common/command-not-found.nix | 4 - common/dbus.nix | 3 - common/editor.nix | 23 ++ common/fish.nix | 6 - common/gc.nix | 9 + common/git.nix | 6 +- common/gitui.nix | 6 - common/{fwupd.nix => hardware.nix} | 0 common/helix.nix | 21 -- common/nh.nix | 17 -- common/nini.nix | 10 + common/nix-index-database.nix | 6 - common/rsync.nix | 25 -- common/secure-boot.nix | 12 + common/shell.nix | 18 ++ common/starship.nix | 7 - common/sudo.nix | 4 +- common/swap.nix | 5 +- common/tailscale.nix | 11 +- common/tmp.nix | 6 + common/users.nix | 4 +- common/yazi.nix | 3 - common/zellij.nix | 6 - flake.lock | 288 ++++++++++++++++-- flake.nix | 10 +- hosts/abacus/forgejo.nix | 76 +++-- hosts/abacus/navidrome.nix | 5 + hosts/abacus/networking.nix | 2 +- hosts/abacus/nginx.nix | 3 +- hosts/abacus/profiles.nix | 3 + hosts/abacus/restic.nix | 3 +- hosts/abacus/system.nix | 2 +- hosts/abacus/vaultwarden.nix | 8 +- hosts/flamingo/profiles.nix | 9 + hosts/glacier/hardware.nix | 1 - hosts/glacier/profiles.nix | 10 +- hosts/insomniac/profiles.nix | 9 + hosts/vessel/filesystems.nix | 15 +- hosts/vessel/profiles.nix | 3 + hosts/vessel/restic.nix | 1 - hosts/work/profiles.nix | 6 + lib.nix | 27 +- {common => modules}/pubkeys.nix | 1 + packages/disk/{disk.bash => disk} | 0 packages/disk/package.nix | 2 +- packages/puter/package.nix | 11 - packages/puter/puter.bash | 192 ------------ profiles/desktop/default.nix | 13 +- profiles/emulation/dolphin.nix | 2 +- profiles/emulation/rmg.nix | 2 +- profiles/gaming/default.nix | 2 - profiles/gaming/gamemode.nix | 22 +- profiles/gaming/prismlauncher.nix | 6 +- profiles/gaming/steam.nix | 16 +- profiles/piracy/mullvad.nix | 8 +- profiles/piracy/qbittorrent.nix | 6 +- profiles/productivity/gimp.nix | 6 +- profiles/productivity/inkscape.nix | 6 +- profiles/productivity/libreoffice.nix | 6 +- profiles/server/default.nix | 15 + profiles/server/networking.nix | 2 +- profiles/server/time.nix | 2 +- secrets/forgejo-admin.age | 12 - secrets/forgejo-mailer.age | 11 - secrets/forgejo/admin.age | 11 + secrets/forgejo/mailer.age | 11 + secrets/restic-abacus.age | Bin 559 -> 559 bytes secrets/restic-vessel.age | 20 +- secrets/secrets.nix | 14 +- secrets/secure-boot/abacus.tar.age | Bin 0 -> 31262 bytes secrets/secure-boot/flamingo.tar.age | Bin 0 -> 31262 bytes secrets/secure-boot/glacier.tar.age | Bin 0 -> 31262 bytes secrets/syncserver.age | Bin 690 -> 690 bytes secrets/user-insomniac.age | 11 - secrets/user-lukas.age | Bin 1088 -> 0 bytes secrets/users/helvetica.age | 20 ++ secrets/users/insomniac.age | 14 + .../{user-helvetica.age => users/lukas.age} | Bin secrets/vaultwarden.age | Bin 867 -> 867 bytes 84 files changed, 674 insertions(+), 567 deletions(-) delete mode 100644 common/bash.nix delete mode 100644 common/command-not-found.nix delete mode 100644 common/dbus.nix create mode 100644 common/editor.nix delete mode 100644 common/fish.nix create mode 100644 common/gc.nix delete mode 100644 common/gitui.nix rename common/{fwupd.nix => hardware.nix} (100%) delete mode 100644 common/helix.nix delete mode 100644 common/nh.nix create mode 100644 common/nini.nix delete mode 100644 common/nix-index-database.nix delete mode 100644 common/rsync.nix create mode 100644 common/secure-boot.nix create mode 100644 common/shell.nix delete mode 100644 common/starship.nix create mode 100644 common/tmp.nix delete mode 100644 common/yazi.nix delete mode 100644 common/zellij.nix create mode 100644 hosts/abacus/profiles.nix create mode 100644 hosts/flamingo/profiles.nix create mode 100644 hosts/insomniac/profiles.nix create mode 100644 hosts/vessel/profiles.nix create mode 100644 hosts/work/profiles.nix rename {common => modules}/pubkeys.nix (92%) rename packages/disk/{disk.bash => disk} (100%) delete mode 100644 packages/puter/package.nix delete mode 100644 packages/puter/puter.bash delete mode 100644 secrets/forgejo-admin.age delete mode 100644 secrets/forgejo-mailer.age create mode 100644 secrets/forgejo/admin.age create mode 100644 secrets/forgejo/mailer.age create mode 100644 secrets/secure-boot/abacus.tar.age create mode 100644 secrets/secure-boot/flamingo.tar.age create mode 100644 secrets/secure-boot/glacier.tar.age delete mode 100644 secrets/user-insomniac.age delete mode 100644 secrets/user-lukas.age create mode 100644 secrets/users/helvetica.age create mode 100644 secrets/users/insomniac.age rename secrets/{user-helvetica.age => users/lukas.age} (100%) diff --git a/README.md b/README.md index 9f8cc50..e49996b 100644 --- a/README.md +++ b/README.md @@ -2,25 +2,51 @@ This is my cobbled together NixOS configuration. There are many like it, but this one is mine. Copy at your own risk. +## Structure + +* common: Sane defaults that make sense to use for every host. +* modules: Regular NixOS modules. +* profiles: Higher-level NixOS modules that conform to different roles that a host may have. +* packages: Packages that I couldn't fit anywhere else. +* secrets: Agenix secrets. +* hosts: Hosts exposed in `nixosConfigurations`. +* pubkeys.nix: Nix expression with all my SSH public keys, used for OpenSSH, Agenix and Restic. +* lib.nix: Nixpkgs' lib with some extra functionality. + +## Ports + +* 80X0: Public HTTP services that are proxied through nginx +* 40X0: Syncthing instances (4000 being the system instance, subsequent ones are for individual users) + +## Installation + +```bash +nix run git+https://codeberg.org/helvetica/puter.git#disk /path/to/disk +# TODO: Configure additional disks +mkdir -p /mnt/etc/ssh +cat > /mnt/etc/ssh/ssh_host_ed25519_key +chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key +ssh-keygen -f /mnt/etc/ssh/ssh_host_ed25519_key -y > /mnt/etc/ssh/ssh_host_ed25519_key.pub +nixos-install --no-root-password --flake git+https://codeberg.org/helvetica/puter.git#hostname +``` + +## systemd-cryptenroll + +```bash +systemd-cryptenroll /dev/sdX --tpm2-device=auto +``` + +## Create tar for sbctl + +```bash +sudo sbctl create-keys +sudo tar --create --directory /var/lib/sbctl . | agenix -e secure-boot/hostname.tar.age +``` + ## TODO -- [ ] lanzaboote -- [ ] monitoring (prometheus) -- [ ] logging (loki) -- [ ] kiosk -- [ ] tailscale and headscale -- [ ] game rom sync insomniac +- [ ] Lanzaboote +- [ ] Monitoring +- [ ] Rom sync - [ ] insomniac backups - [ ] nginx websites - -## port allocation - -* 80X0: public HTTP services that are proxied through nginx -* 40X0: syncthing instances (4000 being the system instance, subsequent ones are for individual users) -* 60X0: private HTTP services that are accessible via tailscale -* 20XX: Administrative stuff, like prometheus etc. - -* 8000: vaultwarden -* 8010: headscale - -* 4000: syncthing diff --git a/common/bash.nix b/common/bash.nix deleted file mode 100644 index 92b7e52..0000000 --- a/common/bash.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - programs.bash.interactiveShellInit = '' - shopt -s autocd globstar nullglob extglob checkwinsize - ''; -} diff --git a/common/boot.nix b/common/boot.nix index d5a4930..e9ca87b 100644 --- a/common/boot.nix +++ b/common/boot.nix @@ -1,28 +1,22 @@ -{ config, ... }: -{ +{config, inputs, ...}: { + imports = [ + inputs.lanzaboote.nixosModules.lanzaboote + ]; + fileSystems.${config.boot.loader.efi.efiSysMountPoint} = { label = "BOOT"; fsType = "vfat"; }; boot = { - loader = { - systemd-boot = { - enable = true; - consoleMode = "max"; - }; - - efi = { - canTouchEfiVariables = true; - efiSysMountPoint = "/boot"; - }; + lanzaboote = { + enable = true; + pkiBundle = "/var/lib/sbctl"; }; - # TODO - tmp = { - useTmpfs = true; - tmpfsSize = "50%"; - cleanOnBoot = true; + loader.efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot"; }; }; } diff --git a/common/bottom.nix b/common/bottom.nix index 0dd6c8b..52cfb51 100644 --- a/common/bottom.nix +++ b/common/bottom.nix @@ -1,4 +1,6 @@ { pkgs, ... }: { - environment.systemPackages = [ pkgs.bottom ]; + environment.systemPackages = [ + pkgs.bottom + ]; } diff --git a/common/comma.nix b/common/comma.nix index 05bde3a..ddc4348 100644 --- a/common/comma.nix +++ b/common/comma.nix @@ -1,3 +1,8 @@ +{ inputs, ... }: { + imports = [ + inputs.nix-index-database.nixosModules.nix-index + ]; + programs.nix-index-database.comma.enable = true; } diff --git a/common/command-not-found.nix b/common/command-not-found.nix deleted file mode 100644 index 5f8fcff..0000000 --- a/common/command-not-found.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ - # TODO - programs.command-not-found.enable = false; -} diff --git a/common/dbus.nix b/common/dbus.nix deleted file mode 100644 index 7d270b2..0000000 --- a/common/dbus.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - services.dbus.implementation = "broker"; -} diff --git a/common/editor.nix b/common/editor.nix new file mode 100644 index 0000000..84fe178 --- /dev/null +++ b/common/editor.nix @@ -0,0 +1,23 @@ +{ + inputs, + lib, + pkgs, + ... +}: +let + package = inputs.hxwrap.packages.${pkgs.system}.default; +in +{ + environment = { + systemPackages = [ package ]; + + sessionVariables = + let + exe = builtins.baseNameOf (lib.getExe package); + in + { + EDITOR = exe; + VISUAL = exe; + }; + }; +} diff --git a/common/fish.nix b/common/fish.nix deleted file mode 100644 index 1abe9c7..0000000 --- a/common/fish.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ pkgs, ... }: -{ - programs.fish.enable = true; - - users.defaultUserShell = pkgs.fish; -} diff --git a/common/gc.nix b/common/gc.nix new file mode 100644 index 0000000..2f9440d --- /dev/null +++ b/common/gc.nix @@ -0,0 +1,9 @@ +{ + nix.gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 30d"; + }; + + boot.loader.systemd-boot.configurationLimit = 5; +} diff --git a/common/git.nix b/common/git.nix index d8ac829..188b2e0 100644 --- a/common/git.nix +++ b/common/git.nix @@ -1,6 +1,10 @@ -{ +{pkgs, ...}: { programs.git = { enable = true; lfs.enable = true; }; + + environment.systemPackages = [ + pkgs.gitui + ]; } diff --git a/common/gitui.nix b/common/gitui.nix deleted file mode 100644 index 5c91753..0000000 --- a/common/gitui.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ pkgs, ... }: -{ - environment.systemPackages = [ - pkgs.gitui - ]; -} diff --git a/common/fwupd.nix b/common/hardware.nix similarity index 100% rename from common/fwupd.nix rename to common/hardware.nix diff --git a/common/helix.nix b/common/helix.nix deleted file mode 100644 index f654cc1..0000000 --- a/common/helix.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - inputs, - lib, - pkgs, - ... -}: -let - package = inputs.hxwrap.packages.${pkgs.system}.default; -in -{ - environment.systemPackages = [ package ]; - - environment.sessionVariables = - let - exe = builtins.baseNameOf (lib.getExe package); - in - { - EDITOR = exe; - VISUAL = exe; - }; -} diff --git a/common/nh.nix b/common/nh.nix deleted file mode 100644 index 92b865a..0000000 --- a/common/nh.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - pkgs, - self, - ... -}: -{ - programs.nh = { - enable = true; - clean = { - enable = true; - extraArgs = "--keep 5 --keep-since 1w"; - dates = "weekly"; - }; - }; - - environment.sessionVariables.NH_FLAKE = "git+https://forgejo@forgejo.helveticanonstandard.net/helvetica/puter.git"; # TODO -} diff --git a/common/nini.nix b/common/nini.nix new file mode 100644 index 0000000..b23037e --- /dev/null +++ b/common/nini.nix @@ -0,0 +1,10 @@ +{inputs, ...}: { + imports = [ + inputs.nini.nixosModules.default + ]; + + programs.nini = { + enable = true; + flakeref = "git+https://forgejo.helveticanonstandard.net/helvetica/puter.git"; + }; +} diff --git a/common/nix-index-database.nix b/common/nix-index-database.nix deleted file mode 100644 index d545e20..0000000 --- a/common/nix-index-database.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ inputs, ... }: -{ - imports = [ - inputs.nix-index-database.nixosModules.nix-index - ]; -} diff --git a/common/rsync.nix b/common/rsync.nix deleted file mode 100644 index 5cdad8e..0000000 --- a/common/rsync.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - lib, - pkgs, - ... -}: -{ - #services.rsync = { - # enable = true; - - # commonArgs = let - # rsh = "${lib.getExe pkgs.openssh} -i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; - # in [ - # "--verbose" - # "--verbose" - # "--archive" - # "--update" - # "--delete" - # "--mkpath" - # "--exclude" - # "lost+found" - # "--rsh" - # rsh - # ]; - #}; -} diff --git a/common/secure-boot.nix b/common/secure-boot.nix new file mode 100644 index 0000000..0570b0c --- /dev/null +++ b/common/secure-boot.nix @@ -0,0 +1,12 @@ +{self, attrName, config, lib, pkgs, ...}: let + inherit (config.age) secrets; +in{ + age.secrets.secure-boot.file = self + /secrets/secure-boot/${attrName}.tar.age; + + system.activationScripts.secureboot = let + target = config.boot.lanzaboote.pkiBundle; + in '' + mkdir --parents ${target} + ${lib.getExe pkgs.gnutar} --extract --file ${secrets.secure-boot.path} --directory ${target} + ''; +} diff --git a/common/shell.nix b/common/shell.nix new file mode 100644 index 0000000..1b0e0c2 --- /dev/null +++ b/common/shell.nix @@ -0,0 +1,18 @@ +{ config, ... }: +{ + programs = { + fish.enable = true; + + bash.interactiveShellInit = '' + shopt -s autocd globstar nullglob extglob checkwinsize + ''; + + starship = { + enable = true; + interactiveOnly = true; + settings.format = "$all"; + }; + }; + + users.defaultUserShell = config.programs.fish.package; +} diff --git a/common/starship.nix b/common/starship.nix deleted file mode 100644 index 491995c..0000000 --- a/common/starship.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ - programs.starship = { - enable = true; - interactiveOnly = true; - settings.format = "$all"; - }; -} diff --git a/common/sudo.nix b/common/sudo.nix index 4cac0ec..0d1ce03 100644 --- a/common/sudo.nix +++ b/common/sudo.nix @@ -3,6 +3,8 @@ enable = true; execWheelOnly = true; wheelNeedsPassword = true; - extraConfig = "Defaults lecture=\"never\""; + extraConfig = '' + Defaults lecture="never" + ''; }; } diff --git a/common/swap.nix b/common/swap.nix index f8ddd9c..71751cf 100644 --- a/common/swap.nix +++ b/common/swap.nix @@ -1,3 +1,6 @@ { - zramSwap.enable = true; + zramSwap = { + enable = true; + memoryPercent = 50; + }; } diff --git a/common/tailscale.nix b/common/tailscale.nix index 1f87127..915d195 100644 --- a/common/tailscale.nix +++ b/common/tailscale.nix @@ -3,13 +3,10 @@ services.tailscale = { enable = true; openFirewall = true; + useRoutingFeatures = "both"; # TODO }; - networking.firewall = { - trustedInterfaces = [ - config.services.tailscale.interfaceName - ]; - # Required to connect to Tailscale exit nodes - checkReversePath = "loose"; - }; + networking.firewall.trustedInterfaces = [ + config.services.tailscale.interfaceName + ]; } diff --git a/common/tmp.nix b/common/tmp.nix new file mode 100644 index 0000000..7f61ff5 --- /dev/null +++ b/common/tmp.nix @@ -0,0 +1,6 @@ +{ + boot.tmp = { + useTmpfs = true; + tmpfsSize = "50%"; + }; +} diff --git a/common/users.nix b/common/users.nix index da7995a..18680a7 100644 --- a/common/users.nix +++ b/common/users.nix @@ -1,13 +1,13 @@ { + self, config, - lib, ... }: let inherit (config.users) mainUser; in { - age.secrets = lib.mkSecrets { "user-${mainUser}" = { }; }; + age.secrets."user-${mainUser}".file = self + /secrets/users/${mainUser}.age; users = { mutableUsers = false; diff --git a/common/yazi.nix b/common/yazi.nix deleted file mode 100644 index 2ae4438..0000000 --- a/common/yazi.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - programs.yazi.enable = true; -} diff --git a/common/zellij.nix b/common/zellij.nix deleted file mode 100644 index eaf8886..0000000 --- a/common/zellij.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ pkgs, ... }: -{ - environment.systemPackages = [ - pkgs.zellij - ]; -} diff --git a/flake.lock b/flake.lock index 6f17782..eca4763 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,21 @@ "type": "github" } }, + "crane": { + "locked": { + "lastModified": 1731098351, + "narHash": "sha256-HQkYvKvaLQqNa10KEFGgWHfMAbWBfFp+4cAgkut+NNE=", + "owner": "ipetkov", + "repo": "crane", + "rev": "ef80ead953c1b28316cc3f8613904edc2eb90c28", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -44,6 +59,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1733328505, @@ -59,7 +90,7 @@ "type": "github" } }, - "flake-compat_2": { + "flake-compat_3": { "flake": false, "locked": { "lastModified": 1746162366, @@ -130,6 +161,27 @@ } }, "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730504689, + "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "506278e768c2a08bec68eb62932193e341f55c90", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_5": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_4" }, @@ -147,7 +199,7 @@ "type": "github" } }, - "flake-parts_5": { + "flake-parts_6": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_5" }, @@ -165,6 +217,24 @@ "type": "github" } }, + "flake-parts_7": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_6" + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "forgesync": { "inputs": { "flake-parts": "flake-parts_2", @@ -187,13 +257,35 @@ "url": "https://codeberg.org/helvetica/forgesync.git" } }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "hardware": { "locked": { - "lastModified": 1746341346, - "narHash": "sha256-WjupK5Xpc+viJlJWiyPHp/dF4aJItp1BPuFsEdv2/fI=", + "lastModified": 1747129300, + "narHash": "sha256-L3clA5YGeYCF47ghsI7Tcex+DnaaN/BbQ4dR2wzoiKg=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "0833dc8bbc4ffa9cf9b0cbfccf1c5ec8632fc66e", + "rev": "e81fd167b33121269149c57806599045fd33eeed", "type": "github" }, "original": { @@ -242,9 +334,35 @@ "url": "https://codeberg.org/helvetica/hxwrap.git" } }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts_4", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1737639419, + "narHash": "sha256-AEEDktApTEZ5PZXNDkry2YV2k6t0dTgLPEmAZbnigXU=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "a65905a09e2c43ff63be8c0e86a93712361f871e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "v0.4.2", + "repo": "lanzaboote", + "type": "github" + } + }, "musicomp": { "inputs": { - "flake-parts": "flake-parts_4", + "flake-parts": "flake-parts_5", "nixpkgs": "nixpkgs_4" }, "locked": { @@ -263,7 +381,7 @@ }, "myphps": { "inputs": { - "flake-parts": "flake-parts_5", + "flake-parts": "flake-parts_6", "nixpkgs": "nixpkgs_5", "phps": "phps" }, @@ -281,6 +399,25 @@ "url": "https://codeberg.org/helvetica/myphps.git" } }, + "nini": { + "inputs": { + "flake-parts": "flake-parts_7", + "nixpkgs": "nixpkgs_7" + }, + "locked": { + "lastModified": 1747493683, + "narHash": "sha256-SEszNrbvTzxjFM7apKnL8LaarvDAzcuuQXj8r+ikJdk=", + "ref": "refs/heads/main", + "rev": "a61825fc51a2b52cebd01ce58910707383e08b02", + "revCount": 2, + "type": "git", + "url": "https://codeberg.org/helvetica/nini.git" + }, + "original": { + "type": "git", + "url": "https://codeberg.org/helvetica/nini.git" + } + }, "nix-index-database": { "inputs": { "nixpkgs": [ @@ -288,11 +425,11 @@ ] }, "locked": { - "lastModified": 1746330942, - "narHash": "sha256-ShizFaJCAST23tSrHHtFFGF0fwd72AG+KhPZFFQX/0o=", + "lastModified": 1747470409, + "narHash": "sha256-R9TP2//BDKyjNzuZybplIZm7HQEnwL8khs7EmmTPYP4=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "137fd2bd726fff343874f85601b51769b48685cc", + "rev": "c1f63a0c3bf1b2fe05124ccb099333163e2184a7", "type": "github" }, "original": { @@ -303,17 +440,17 @@ }, "nixos-cosmic": { "inputs": { - "flake-compat": "flake-compat_2", - "nixpkgs": "nixpkgs_7", - "nixpkgs-stable": "nixpkgs-stable", - "rust-overlay": "rust-overlay" + "flake-compat": "flake-compat_3", + "nixpkgs": "nixpkgs_8", + "nixpkgs-stable": "nixpkgs-stable_2", + "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1746356902, - "narHash": "sha256-aV2pm+XKEoGE/BuqJwI1zDhtHclzC5BsbSO+SAMFEKk=", + "lastModified": 1747491978, + "narHash": "sha256-Jn7um1fnf2bI9N8gvG5jIHvIJxxLaXd+2+wHXyW0Frs=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "22325997671e2a6f0a2e784db2746267868a33ed", + "rev": "2a7be063557ffc19ab1d8ab18bfd1721df8355c5", "type": "github" }, "original": { @@ -413,13 +550,44 @@ "type": "github" } }, + "nixpkgs-lib_6": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, "nixpkgs-stable": { "locked": { - "lastModified": 1746183838, - "narHash": "sha256-kwaaguGkAqTZ1oK0yXeQ3ayYjs8u/W7eEfrFpFfIDFA=", + "lastModified": 1730741070, + "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bf3287dac860542719fe7554e21e686108716879", + "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1747335874, + "narHash": "sha256-IKKIXTSYJMmUtE+Kav5Rob8SgLPnfnq4Qu8LyT4gdqQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ba8b70ee098bc5654c459d6a95dfc498b91ff858", "type": "github" }, "original": { @@ -511,11 +679,27 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1746232882, - "narHash": "sha256-MHmBH2rS8KkRRdoU/feC/dKbdlMkcNkB5mwkuipVHeQ=", + "lastModified": 1743964447, + "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7a2622e2c0dbad5c4493cb268aba12896e28b008", + "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1747327360, + "narHash": "sha256-LSmTbiq/nqZR9B2t4MRnWG7cb0KVNU70dB7RT4+wYK4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e06158e58f3adee28b139e9c2bcfcc41f8625b46", "type": "github" }, "original": { @@ -527,7 +711,7 @@ }, "phps": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "nixpkgs": "nixpkgs_6", "utils": "utils" }, @@ -545,6 +729,33 @@ "type": "github" } }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": [ + "lanzaboote", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1731363552, + "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "pyproject-build-systems": { "inputs": { "nixpkgs": [ @@ -602,8 +813,10 @@ "forgesync": "forgesync", "hardware": "hardware", "hxwrap": "hxwrap", + "lanzaboote": "lanzaboote", "musicomp": "musicomp", "myphps": "myphps", + "nini": "nini", "nix-index-database": "nix-index-database", "nixos-cosmic": "nixos-cosmic", "nixpkgs": [ @@ -613,6 +826,27 @@ } }, "rust-overlay": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1731897198, + "narHash": "sha256-Ou7vLETSKwmE/HRQz4cImXXJBr/k9gp4J4z/PF8LzTE=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "0be641045af6d8666c11c2c40e45ffc9667839b5", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { "inputs": { "nixpkgs": [ "nixos-cosmic", @@ -620,11 +854,11 @@ ] }, "locked": { - "lastModified": 1746326315, - "narHash": "sha256-IDqSls/r6yBfdOBRSMQ/noTUoigmsKnTQ7TqpsBtN4Y=", + "lastModified": 1747449297, + "narHash": "sha256-veyXchTz6eWwvuW5X49UluHkheHkFcqHJSwGuKBhrmQ=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "dd280c436961ec5adccf0135efe5b66a23d84497", + "rev": "f44db7d7cea4528288780c6347756173a8248225", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index dfb9898..c60e029 100644 --- a/flake.nix +++ b/flake.nix @@ -16,11 +16,11 @@ hxwrap.url = "git+https://codeberg.org/helvetica/hxwrap.git"; myphps.url = "git+https://codeberg.org/helvetica/myphps.git"; forgesync.url = "git+https://codeberg.org/helvetica/forgesync.git"; - }; - - nixConfig = { - extra-substituters = "https://cosmic.cachix.org"; - extra-trusted-public-keys = "cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE="; + nini.url = "git+https://codeberg.org/helvetica/nini.git"; + lanzaboote = { + url = "github:nix-community/lanzaboote/v0.4.2"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = diff --git a/hosts/abacus/forgejo.nix b/hosts/abacus/forgejo.nix index 49268fd..6aebcc1 100644 --- a/hosts/abacus/forgejo.nix +++ b/hosts/abacus/forgejo.nix @@ -1,21 +1,26 @@ { + self, config, lib, pkgs, ... }: let - virtualHostName = "forgejo.helveticanonstandard.net"; + cfg = config.services.forgejo; + inherit (config.age) secrets; in { - age.secrets = lib.mkSecrets { + age.secrets = { forgejo-mailer = { + file = self + /secrets/forgejo/mailer.age; mode = "400"; - owner = "forgejo"; + owner = cfg.user; }; + forgejo-admin = { + file = self + /secrets/forgejo/admin.age; mode = "400"; - owner = "forgejo"; + owner = cfg.user; }; }; @@ -24,10 +29,15 @@ in package = pkgs.forgejo; database.type = "postgres"; lfs.enable = true; + dump = { + enable = true; + interval = "*-*-* 02:00:00"; + backupDir = "/srv/backup/forgejo"; + }; settings = { server = { - DOMAIN = virtualHostName; - ROOT_URL = "https://${virtualHostName}/"; + DOMAIN = "forgejo.helveticanonstandard.net"; + ROOT_URL = "https://${cfg.settings.server.DOMAIN}/"; HTTP_ADDR = "127.0.0.1"; HTTP_PORT = 8060; }; @@ -51,34 +61,36 @@ in }; }; - secrets.mailer.PASSWD = config.age.secrets.forgejo-mailer.path; + secrets.mailer.PASSWD = secrets.forgejo-mailer.path; }; - # TODO what - systemd.services.forgejo.preStart = lib.getExe pkgs.writeShellApplication { - name = "forgejo-init-admin"; - runtimeInputs = [ - config.services.forgejo.package - ]; - text = - let - passwordFile = config.age.secrets.forgejo-admin.path; - in - '' - admins=$(admin user list --admin) - admins=$((admins - 1)) + # TODO + systemd.services.forgejo.preStart = lib.getExe ( + pkgs.writeShellApplication { + name = "forgejo-init-admin"; + runtimeInputs = [ + cfg.package + ]; + text = + let + passwordFile = secrets.forgejo-admin.path; + in + '' + admins=$(admin user list --admin) + admins=$((admins - 1)) - if ((admins < 1)); then - gitea admin user create \ - --admin \ - --email helvetica@helveticanonstandard.net \ - --username helvetica \ - --password "$(cat -- ${passwordFile})" - fi - ''; - }; + if ((admins < 1)); then + gitea admin user create \ + --admin \ + --email helvetica@helveticanonstandard.net \ + --username helvetica \ + --password "$(cat -- ${passwordFile})" + fi + ''; + } + ); - services.nginx.virtualHosts.${virtualHostName} = { + services.nginx.virtualHosts.${cfg.settings.server.DOMAIN} = { enableACME = true; forceSSL = true; @@ -88,8 +100,8 @@ in locations."/".proxyPass = let - host = config.services.forgejo.settings.server.HTTP_ADDR; - port = builtins.toString config.services.forgejo.settings.server.HTTP_PORT; + host = cfg.settings.server.HTTP_ADDR; + port = builtins.toString cfg.settings.server.HTTP_PORT; in "http://${host}:${port}"; }; diff --git a/hosts/abacus/navidrome.nix b/hosts/abacus/navidrome.nix index 56e030e..c6d0ce9 100644 --- a/hosts/abacus/navidrome.nix +++ b/hosts/abacus/navidrome.nix @@ -10,6 +10,11 @@ in Port = 8050; MusicFolder = "/srv/music"; EnableSharing = true; + Backup = { + Path = "/srv/backup/navidrome"; + Count = 1; + Schedule = "0 2 * * *"; + }; }; }; diff --git a/hosts/abacus/networking.nix b/hosts/abacus/networking.nix index 6c07960..35e1b20 100644 --- a/hosts/abacus/networking.nix +++ b/hosts/abacus/networking.nix @@ -7,7 +7,7 @@ domain = "wrz.one"; interfaces.${interface}.ipv6.addresses = [ { - address = "2a01:4f9:c012:92b5::2"; + address = "2a01:4f8:c013:e64a::2"; prefixLength = 64; } ]; diff --git a/hosts/abacus/nginx.nix b/hosts/abacus/nginx.nix index d601045..e3cbee8 100644 --- a/hosts/abacus/nginx.nix +++ b/hosts/abacus/nginx.nix @@ -1,3 +1,4 @@ +{ config, ... }: { services.nginx = { enable = true; @@ -23,7 +24,7 @@ default = true; rejectSSL = true; - globalRedirect = "wrz.one"; + globalRedirect = config.networking.domain; }; # Redirect www to non-www ${matchWww}.globalRedirect = "$domain"; diff --git a/hosts/abacus/profiles.nix b/hosts/abacus/profiles.nix new file mode 100644 index 0000000..92e505a --- /dev/null +++ b/hosts/abacus/profiles.nix @@ -0,0 +1,3 @@ +{ + profiles.server.enable = true; +} diff --git a/hosts/abacus/restic.nix b/hosts/abacus/restic.nix index 14e8994..58fc9de 100644 --- a/hosts/abacus/restic.nix +++ b/hosts/abacus/restic.nix @@ -18,8 +18,9 @@ in config.services.vaultwarden.backupDir config.services.syncthing.dataDir config.services.forgejo.stateDir + config.services.forgejo.dump.backupDir config.services.postgresqlBackup.location - config.services.postgresqlBackup.location + config.services.navidrome.settings.Backup.Path # TODO: Add stateDir options for these "/var/lib/headscale" "/var/lib/navidrome" diff --git a/hosts/abacus/system.nix b/hosts/abacus/system.nix index a05de83..8033946 100644 --- a/hosts/abacus/system.nix +++ b/hosts/abacus/system.nix @@ -1,3 +1,3 @@ { - system.stateVersion = "24.11"; + system.stateVersion = "25.05"; } diff --git a/hosts/abacus/vaultwarden.nix b/hosts/abacus/vaultwarden.nix index f63b97b..af5b45b 100644 --- a/hosts/abacus/vaultwarden.nix +++ b/hosts/abacus/vaultwarden.nix @@ -5,26 +5,20 @@ }: let virtualHostName = "vault.wrz.one"; - backupDir = "/srv/backup/vaultwarden"; in { age.secrets = lib.mkSecrets { vaultwarden = { }; }; services.vaultwarden = { enable = true; - dbBackend = "sqlite"; - - inherit backupDir; + backupDir = "/srv/backup/vaultwarden"; config = { DOMAIN = "https://${virtualHostName}"; - SIGNUPS_ALLOWED = false; INVITATIONS_ALLOWED = false; - ENABLE_WEBSOCKET = true; - ROCKET_ADDRESS = "127.0.0.1"; ROCKET_PORT = 8000; }; diff --git a/hosts/flamingo/profiles.nix b/hosts/flamingo/profiles.nix new file mode 100644 index 0000000..b2f1fd3 --- /dev/null +++ b/hosts/flamingo/profiles.nix @@ -0,0 +1,9 @@ +{ + profiles = { + desktop.enable = true; + emulation.enable = true; + gaming.enable = true; + piracy.enable = true; + productivity.enable = true; + }; +} diff --git a/hosts/glacier/hardware.nix b/hosts/glacier/hardware.nix index 7296c95..84280eb 100644 --- a/hosts/glacier/hardware.nix +++ b/hosts/glacier/hardware.nix @@ -27,7 +27,6 @@ kernelModules = [ "amdgpu" ]; }; kernelModules = [ "kvm-amd" ]; - binfmt.emulatedSystems = [ "aarch64-linux" ]; }; powerManagement.cpuFreqGovernor = "performance"; diff --git a/hosts/glacier/profiles.nix b/hosts/glacier/profiles.nix index 016e2fa..b2f1fd3 100644 --- a/hosts/glacier/profiles.nix +++ b/hosts/glacier/profiles.nix @@ -1,9 +1,9 @@ { profiles = { - desktop = true; - emulation = true; - gaming = true; - piracy = true; - productivity = true; + desktop.enable = true; + emulation.enable = true; + gaming.enable = true; + piracy.enable = true; + productivity.enable = true; }; } diff --git a/hosts/insomniac/profiles.nix b/hosts/insomniac/profiles.nix new file mode 100644 index 0000000..b2f1fd3 --- /dev/null +++ b/hosts/insomniac/profiles.nix @@ -0,0 +1,9 @@ +{ + profiles = { + desktop.enable = true; + emulation.enable = true; + gaming.enable = true; + piracy.enable = true; + productivity.enable = true; + }; +} diff --git a/hosts/vessel/filesystems.nix b/hosts/vessel/filesystems.nix index 6daadbd..7f37877 100644 --- a/hosts/vessel/filesystems.nix +++ b/hosts/vessel/filesystems.nix @@ -1,22 +1,29 @@ { + boot.initrd.luks.devices = { + main.device = "/dev/disk/by-label/cryptmain"; + vault.device = "/dev/disk/by-label/cryptvault"; + void.device = "/dev/disk/by-label/cryptvoid"; + sync.device = "/dev/disk/by-label/cryptsync"; + }; + fileSystems = { "/" = { - label = "white"; + device = "/dev/mapper/main"; fsType = "ext4"; options = [ "noatime" ]; }; "/srv/vault" = { - label = "black"; + device = "/dev/mapper/vault"; fsType = "ext4"; options = [ "noatime" ]; }; "/srv/void" = { - label = "green"; + device = "/dev/mapper/void"; fsType = "ext4"; options = [ "noatime" ]; }; "/srv/sync" = { - label = "red"; + device = "/dev/mapper/sync"; fsType = "ext4"; options = [ "noatime" ]; }; diff --git a/hosts/vessel/profiles.nix b/hosts/vessel/profiles.nix new file mode 100644 index 0000000..92e505a --- /dev/null +++ b/hosts/vessel/profiles.nix @@ -0,0 +1,3 @@ +{ + profiles.server.enable = true; +} diff --git a/hosts/vessel/restic.nix b/hosts/vessel/restic.nix index fd22f6b..11031d5 100644 --- a/hosts/vessel/restic.nix +++ b/hosts/vessel/restic.nix @@ -2,7 +2,6 @@ attrName, config, lib, - pkgs, ... }: let diff --git a/hosts/work/profiles.nix b/hosts/work/profiles.nix new file mode 100644 index 0000000..c901b18 --- /dev/null +++ b/hosts/work/profiles.nix @@ -0,0 +1,6 @@ +{ + profiles = { + desktop.enable = true; + productivity.enable = true; + }; +} diff --git a/lib.nix b/lib.nix index cd56dce..745ec43 100644 --- a/lib.nix +++ b/lib.nix @@ -1,13 +1,13 @@ lib: _: { - findModules = paths: - builtins.concatMap (path: + findModules = + paths: + builtins.concatMap ( + path: lib.pipe path [ - (lib.fileset.fileFilter ( - file: file.hasExt "nix" - )) + (lib.fileset.fileFilter (file: file.hasExt "nix")) lib.fileset.toList - ]) - paths; + ] + ) paths; mkIfElse = condition: trueContent: falseContent: @@ -48,13 +48,12 @@ lib: _: { attrName = name; }; - modules = - (lib.findModules [ - modulesDir - profilesDir - commonDir - (hostsDir + /${name}) - ]); + modules = lib.findModules [ + modulesDir + profilesDir + commonDir + (hostsDir + /${name}) + ]; }; hosts = lib.pipe hostsDir [ diff --git a/common/pubkeys.nix b/modules/pubkeys.nix similarity index 92% rename from common/pubkeys.nix rename to modules/pubkeys.nix index 46594fd..137e51b 100644 --- a/common/pubkeys.nix +++ b/modules/pubkeys.nix @@ -13,6 +13,7 @@ description = '' Public keys. ''; + readOnly = true; }; config.pubkeys = lib.mkForce (import (self + /pubkeys.nix)); diff --git a/packages/disk/disk.bash b/packages/disk/disk similarity index 100% rename from packages/disk/disk.bash rename to packages/disk/disk diff --git a/packages/disk/package.nix b/packages/disk/package.nix index 0d292c1..a8466f7 100644 --- a/packages/disk/package.nix +++ b/packages/disk/package.nix @@ -15,5 +15,5 @@ writeShellApplication { dosfstools ]; - text = builtins.readFile ./disk.bash; + text = builtins.readFile ./disk; } diff --git a/packages/puter/package.nix b/packages/puter/package.nix deleted file mode 100644 index bfd5a2c..0000000 --- a/packages/puter/package.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - writeShellApplication, - nixos-rebuild, -}: -writeShellApplication { - name = "puter"; - runtimeInputs = [ - nixos-rebuild - ]; - text = builtins.readFile ./puter.bash; -} diff --git a/packages/puter/puter.bash b/packages/puter/puter.bash deleted file mode 100644 index 3f242ff..0000000 --- a/packages/puter/puter.bash +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -progname=$0 - -warn() { - local line - for line in "$@"; do - echo "$progname: $line" 1>&2 - done -} - -error() { - warn "$@" - - exit 1 -} - -args=$( - getopt \ - --options F:f:o:t:v \ - --longoptions flakeref:,flake:,on:,to:,verbose \ - --name "$progname" \ - -- "$@" -) - -eval set -- "$args" - -if [[ -v PUTER_FLAKEREF && -n $PUTER_FLAKEREF ]]; then - flakeref=$PUTER_FLAKEREF -fi -flags=( - --refresh - --use-remote-sudo - --no-write-lock-file -) -verbose=false -while true; do - case $1 in - -F | --flakeref) - flakeref=$2 - shift 2 - ;; - -f | --flake) - flake=$2 - shift 2 - ;; - -o | --on) - flags+=(--build-host "$2") - shift 2 - ;; - -t | --to) - host=$2 - flags+=(--target-host "$host") - shift 2 - ;; - -v | --verbose) - flags+=(--verbose) - verbose=true - shift - ;; - --) - shift - break - ;; - esac -done - -if [[ ! -v flake ]]; then - if [[ -v flakeref ]]; then - warn "using flake reference $flakeref" - if [[ -v host ]]; then - hostname=$(ssh -- "$host" hostname) - else - hostname=$(hostname) - fi - if [[ -z $hostname ]]; then - error 'hostname could not be resolved and no flake specified' - fi - flake=$flakeref#$hostname - warn "resolved to $flake" - else - error 'no flake or flake reference specified' - fi -fi - -flags+=(--flake "$flake") - -if (($# == 0)); then - error 'a subcommand is required' -fi - -run() { - cmd=(nixos-rebuild "${flags[@]}" "$@") - - if "$verbose"; then - warn "running ${cmd[*]}" - fi - - "${cmd[@]}" -} - -sub=$1 - -case $sub in -s | switch) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run switch - ;; -b | boot) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run boot - ;; -t | test) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run test - ;; -bld | build) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run build - ;; -dbld | dry-build) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run dry-build - ;; -da | dry-activate) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run dry-activate - ;; -vm | build-vm) - shift - - if (($# > 0)); then - error 'too many arguments' - fi - - run build-vm - ;; -i | img | build-image) - shift - - if (($# < 1)); then - error 'image variant is required' - fi - - if (($# > 1)); then - error 'too many arguments' - fi - - variant=$1 - - flags+=("$variant") - - run build-image - ;; -*) - error 'invalid subcommand' - ;; -esac diff --git a/profiles/desktop/default.nix b/profiles/desktop/default.nix index f328857..11e024f 100644 --- a/profiles/desktop/default.nix +++ b/profiles/desktop/default.nix @@ -7,23 +7,12 @@ in enable = lib.mkEnableOption "desktop"; }; - # imports = lib.optionals cfg.enable (lib.findModules {} [./profile]); - config = lib.mkIf cfg.enable { - imports = lib.findModules { } [ ./profile ]; - assertions = [ { - assertion = config.profiles.server.enable == false; + assertion = !config.profiles.server.enable; message = "The desktop profile is not compatible with the server profile."; } ]; }; - - # config.assertions = lib.mkIf cfg.enable [ - # { - # assertion = config.profiles.server.enable == false; - # message = "The desktop profile is not compatible with the server profile."; - # } - # ]; } diff --git a/profiles/emulation/dolphin.nix b/profiles/emulation/dolphin.nix index f103752..6376ad0 100644 --- a/profiles/emulation/dolphin.nix +++ b/profiles/emulation/dolphin.nix @@ -10,7 +10,7 @@ in { config = lib.mkIf cfg.enable { environment.systemPackages = [ - pkgs.dolphin-emu + pkgs.dolphin-emu ]; }; } diff --git a/profiles/emulation/rmg.nix b/profiles/emulation/rmg.nix index 4e7cd98..4ed9c74 100644 --- a/profiles/emulation/rmg.nix +++ b/profiles/emulation/rmg.nix @@ -10,7 +10,7 @@ in { config = lib.mkIf cfg.enable { environment.systemPackages = [ - pkgs.rmg-wayland + pkgs.rmg-wayland ]; }; } diff --git a/profiles/gaming/default.nix b/profiles/gaming/default.nix index 0694b00..9846529 100644 --- a/profiles/gaming/default.nix +++ b/profiles/gaming/default.nix @@ -7,8 +7,6 @@ in enable = lib.mkEnableOption "gaming"; }; - imports = lib.optionals cfg.enable (lib.findModules { } [ ./profile ]); - config.assertions = lib.mkIf cfg.enable [ { assertion = config.profiles.desktop.enable; diff --git a/profiles/gaming/gamemode.nix b/profiles/gaming/gamemode.nix index fa34276..921d7a2 100644 --- a/profiles/gaming/gamemode.nix +++ b/profiles/gaming/gamemode.nix @@ -9,19 +9,19 @@ let in { config = lib.mkIf cfg.enable { - programs.gamemode = { - enable = true; - settings = { - general = { - renice = 10; - }; - custom = { - start = "${lib.getExe pkgs.libnotify} 'GameMode started'"; - end = "${lib.getExe pkgs.libnotify} 'GameMode stopped'"; + programs.gamemode = { + enable = true; + settings = { + general = { + renice = 10; + }; + custom = { + start = "${lib.getExe pkgs.libnotify} 'GameMode started'"; + end = "${lib.getExe pkgs.libnotify} 'GameMode stopped'"; + }; }; }; - }; - users.groups.gamemode.members = config.users.normalUsers; + users.groups.gamemode.members = config.users.normalUsers; }; } diff --git a/profiles/gaming/prismlauncher.nix b/profiles/gaming/prismlauncher.nix index 4b16a95..c3888ec 100644 --- a/profiles/gaming/prismlauncher.nix +++ b/profiles/gaming/prismlauncher.nix @@ -9,8 +9,8 @@ let in { config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.prismlauncher - ]; + environment.systemPackages = [ + pkgs.prismlauncher + ]; }; } diff --git a/profiles/gaming/steam.nix b/profiles/gaming/steam.nix index ddd5d63..5195abf 100644 --- a/profiles/gaming/steam.nix +++ b/profiles/gaming/steam.nix @@ -8,13 +8,13 @@ let in { config = lib.mkIf cfg.enable { - programs.steam = { - enable = true; - extest.enable = true; - protontricks.enable = true; - dedicatedServer.openFirewall = true; - remotePlay.openFirewall = true; - localNetworkGameTransfers.openFirewall = true; - }; + programs.steam = { + enable = true; + extest.enable = true; + protontricks.enable = true; + dedicatedServer.openFirewall = true; + remotePlay.openFirewall = true; + localNetworkGameTransfers.openFirewall = true; + }; }; } diff --git a/profiles/piracy/mullvad.nix b/profiles/piracy/mullvad.nix index f8a1542..c59b5dc 100644 --- a/profiles/piracy/mullvad.nix +++ b/profiles/piracy/mullvad.nix @@ -9,9 +9,9 @@ let in { config = lib.mkIf cfg.enable { - services.mullvad-vpn = { - enable = true; - package = pkgs.mullvad-vpn; - }; + services.mullvad-vpn = { + enable = true; + package = pkgs.mullvad-vpn; + }; }; } diff --git a/profiles/piracy/qbittorrent.nix b/profiles/piracy/qbittorrent.nix index e8ca0a5..b099637 100644 --- a/profiles/piracy/qbittorrent.nix +++ b/profiles/piracy/qbittorrent.nix @@ -9,8 +9,8 @@ let in { config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.qbittorrent - ]; + environment.systemPackages = [ + pkgs.qbittorrent + ]; }; } diff --git a/profiles/productivity/gimp.nix b/profiles/productivity/gimp.nix index 1498376..0ce8ca9 100644 --- a/profiles/productivity/gimp.nix +++ b/profiles/productivity/gimp.nix @@ -9,8 +9,8 @@ let in { config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.gimp3-with-plugins - ]; + environment.systemPackages = [ + pkgs.gimp3-with-plugins + ]; }; } diff --git a/profiles/productivity/inkscape.nix b/profiles/productivity/inkscape.nix index b883126..d38e624 100644 --- a/profiles/productivity/inkscape.nix +++ b/profiles/productivity/inkscape.nix @@ -9,8 +9,8 @@ let in { config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.inkscape-with-extensions - ]; + environment.systemPackages = [ + pkgs.inkscape-with-extensions + ]; }; } diff --git a/profiles/productivity/libreoffice.nix b/profiles/productivity/libreoffice.nix index 22897f6..e7d4077 100644 --- a/profiles/productivity/libreoffice.nix +++ b/profiles/productivity/libreoffice.nix @@ -9,8 +9,8 @@ let in { config = lib.mkIf cfg.enable { - environment.systemPackages = [ - pkgs.libreoffice-fresh - ]; + environment.systemPackages = [ + pkgs.libreoffice-fresh + ]; }; } diff --git a/profiles/server/default.nix b/profiles/server/default.nix index 0db3279..555c4d0 100644 --- a/profiles/server/default.nix +++ b/profiles/server/default.nix @@ -1,3 +1,18 @@ +{ config, lib, ... }: +let + cfg = config.profiles.server; +in { + options.profiles.server = { + enable = lib.mkEnableOption "server"; + }; + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = !config.profiles.desktop.enable; + message = "The server profile is not compatible with the desktop profile."; + } + ]; + }; } diff --git a/profiles/server/networking.nix b/profiles/server/networking.nix index 6daa82c..597a7ed 100644 --- a/profiles/server/networking.nix +++ b/profiles/server/networking.nix @@ -8,6 +8,6 @@ let in { config = lib.mkIf cfg.enable { - networking.useNetworkd = true; + networking.useNetworkd = true; }; } diff --git a/profiles/server/time.nix b/profiles/server/time.nix index 1113447..0f4f76d 100644 --- a/profiles/server/time.nix +++ b/profiles/server/time.nix @@ -8,6 +8,6 @@ let in { config = lib.mkIf cfg.enable { - time.timeZone = "UTC"; + time.timeZone = "UTC"; }; } diff --git a/secrets/forgejo-admin.age b/secrets/forgejo-admin.age deleted file mode 100644 index f18cf68..0000000 --- a/secrets/forgejo-admin.age +++ /dev/null @@ -1,12 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 SFHVrw 1eOoURN0W33AUbKglRCVBNzW3RMTyLIwWMRdI/n0iHI -cE0GpXpRyHqxXotqgvEvYYue05yASNmKpPS7QDadVOQ --> ssh-ed25519 S+dwQQ YAhXTqFh18wXzQ02TUvfZJvYdyCZcNufvNTJ7ZjByGk -T3bb0jOs9SL1/5cmsHbYrxYsW4DBOXWN3Bc93/bQ+c4 --> ssh-ed25519 bPbvlw isx3ppsjOWxJgp6w7m1+a1W5DsMWSrYmcwD/I7kfREY -zZBV0iGYfF5kRdwnXzeUYCaNxrDAFn97072kg2d6uaM --> ssh-ed25519 ffmsLw K6sD34XppM8mIaFAB4h43J8miednzvR4W9KUczc0Hk0 -pxOWAsf24bCVDTXeLgayKgqWB512Dzx/1+Gx17RT31I ---- JvtcFW8QYtA1PViXec9je99Shc/KVbACsvDZEfBV5kU -D2ǵ,jqޤ 7LܭA -fGQ4S g᫃ \ No newline at end of file diff --git a/secrets/forgejo-mailer.age b/secrets/forgejo-mailer.age deleted file mode 100644 index c758379..0000000 --- a/secrets/forgejo-mailer.age +++ /dev/null @@ -1,11 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 SFHVrw rEjkYPlPge7UMzbYwPwH80iWaQqIhPHwq9UKpF1LdEE -hn+knYiTYUTobUnAx50E6S7kAwzOhJC3aTXp7tB6kVs --> ssh-ed25519 S+dwQQ JHScT9expJ30xkXY/QZZs6fttyiUz81+xCnt4FCyLQs -m1OykPIXU1WI/7rL/0AroNBp1alYCo7PsmKn6dMjiTM --> ssh-ed25519 bPbvlw IFnxf/jKXZptRpEY7F00agI3yEbztWL8jf8WK03bZ3U -djSqXIYLK+puHMUtVG2EOQyc1mwFRxUshkDPSNWVhkE --> ssh-ed25519 ffmsLw S325emLg33EycUbKCVzD8nLYbVOrQoOhnW5HnJXATC4 -IKBSnzg1BaHYtJhVc8FliY1XVB7P46GsuW/ffeuEa74 ---- QK8UE0WcbtpaBKOZJ/X9n+ZH9Uq1i+y2axyX+zjosXY -G*9k5>\u{ŏj ssh-ed25519 SFHVrw /Rn9mDfrW6WXvk2rHnvFRikKPKjytoZSxr7nIHfaYBQ +dk43RULffWoNdpcyg46PYoyp4+Se/P7hKOq9dlYKHQs +-> ssh-ed25519 S+dwQQ j6cPjS+jTJZ3vX3RtBgcdHDNYUpwHaK470znK3t2PAU +3x9YctUrApvED+9Z8RXRzYbYvzmWcY6OLySDViAAruY +-> ssh-ed25519 bPbvlw wLrlOsWNEhfkJS08IVvIRbuadsZj/mw+J3PmH9dlD1c +FZ2U3gdU2Y9LqCiQ1mz7beYSPyNY3tIEbsPGVfMjmHM +-> ssh-ed25519 ffmsLw aCodb4aiUqIlMGzR7YwQDb8eQh1BHvmUeQAcOaT7fgo +KxSrylhmv3aylhqUp4j9dO/z5judvI5CeRDXE0XqbyE +--- 3tsgl8nyTeB1+YqslwzwdENX1QbP47GZG4EbRPKy8r8 +qJIh.H'O-Ob_s6  \ No newline at end of file diff --git a/secrets/forgejo/mailer.age b/secrets/forgejo/mailer.age new file mode 100644 index 0000000..2475d67 --- /dev/null +++ b/secrets/forgejo/mailer.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 SFHVrw 6hEwUxHZ7YxTRZGxM+pGfKKtpt0KUME5onbtQqHdsxk +zUEng+GntP/LGygdZTPCsFK9Vmn++VODWR0lWCuC0kQ +-> ssh-ed25519 S+dwQQ eznFi6oeKUpS1VmkK3cVjcRFF3zI6o9zzFkukj1X6lY +KApBmW4r4AQwqv6DrBg8I4x2TCUjgGOzHOfsLP5NDx4 +-> ssh-ed25519 bPbvlw 86J2AsTVgm3GAbLmlOi5n73b8qgHxsIlDZKtM96zcQo +SYR28elHJA6Z0NCo90bZVQvixpKGTWmeafqr0CrLhcM +-> ssh-ed25519 ffmsLw LdxVlRNsqwSZc0qXWC7N+q69PTIXY0q49upfuEk5GwM +Z73ga/GtcdDUgAWRteHat0gmtISjTbVvzjUaugtYwCY +--- D065LOfAd9xDAc2QMAmEZQeduBgIaYtpC/W/wgcwY7Q +R~OZJwj]1~9QVm \ No newline at end of file diff --git a/secrets/restic-abacus.age b/secrets/restic-abacus.age index 3823dd8f2404aaf5c6a7c82f8822b9babaf87406..47478e410a315b030b77dda98fe745be72426176 100644 GIT binary patch delta 487 zcmZ3_vYusvPJL9dk+ExOiD`yKk!fnWMXF!0NkFQJMOtR1fk9MOR(3#`u}QvvSz(@0 zK37heqq}pZSAKG#pP5fcRe@KPzmb`1a>78S$ScB20mtKktL;pCSie-;~B;4T~mAli<1na zoWsm~%+gCdQ;Z|Sy#lk7&0W(f^~(*NLcEJY3bKM-J+dvh5>twk%krE}Tq<&1LoFkU ziwzx%vW>$mGV-F*i=ra3vOOaU4UHYs$}>H=baizVqC7HzVxwdcL8|Zv$){&(W2jZtR@+$HE?0%!C9U}en d!*_${5#JU3tTPz@2i-TEuY9{rXJS!iF96)ZsF?r& delta 487 zcmZ3_vYusvPQ6!fSwy8tkyoylk+*hIu2Wf2a8yC4duEP-#e%t5c@Cw|;uAwp(zhg?DATLB5lDvS*f|VOWrt zmw&LIMW#z6S9orkd5Ct2MX5olL2-IYR9;TGzj2t0QF>s0Vv34vUX}*V zsa~#@$%a0eMX5oh>8>V$iJtDoxnaSfmgPms8NLQ7J{d+4m6pkq;~B;4EyKLMatd-x zd~%!%v?HT@%e=iT3`!DEltx+xExZa^+wA*dUoffSmT<+O^;3+9gS%?aGPPR dNmFs8?cSNag)>VlyFz*wpO?PP8#*P{0sv4Ss2~6U diff --git a/secrets/restic-vessel.age b/secrets/restic-vessel.age index 5f33d9c..654cfad 100644 --- a/secrets/restic-vessel.age +++ b/secrets/restic-vessel.age @@ -1,11 +1,11 @@ age-encryption.org/v1 --> ssh-ed25519 SFHVrw IS1zLmLNl5l0+IJoZObLSKzjg12V9hPCYOuD0ZJphk8 -FipqdCWVqXZ9RdNPXUnyqM8xvktCbjUHyAbh8GRLLg0 --> ssh-ed25519 S+dwQQ 0oWHsd3MryyksSbUZEWdFw8kyLPaxko1bMUWbmSxlyM -xgu+2woj3pIRHcR3XasLaiMZqs2uj3VoDh8da9GQADs --> ssh-ed25519 bPbvlw JwdTUP9poe45VREZKqDcqmM4Sgr8BMB3CrTw6rS+VFI -WWkM2uC2uovhB5ZkQVQ4xnNKhY3B+2Lus+3Qd+SZFKE --> ssh-ed25519 Sm0lOA Nu0x8ec0G7N9Tc1JNRGzHWCCUIY9zUanTOgfZfxrUTQ -iueKqGbDunTkpgVsymj6yc7t7J1yhvg1ug0PJHRCyX4 ---- 2ZAyA0YLFKg9DgbtmN4TVJPc6dLhrvu8UJMR0+DZItc -ʡ;*(Kْ7Gy,ﮰ5dK>6g \ No newline at end of file +-> ssh-ed25519 SFHVrw nyWvoLnNXzbxV3pKyVFIJIdzO1WOCHThAEKe0dyDxgM +N6t8SrPsvLrIRG4iu9896ZN8Ebzez7/pLC4RnS1ZEhs +-> ssh-ed25519 S+dwQQ UPHt9CTJmM9VvubDx5XSnTusm4oSyq+/A2R5FLYKbj4 +n5wDmZwRmyjunS7njesVc0PZKhC51x5xqDlrD/9d1VE +-> ssh-ed25519 bPbvlw /2b8HRR2KzTiiVQKxN82oQ8PqVcRKEJ6hwNfMhFaf2I +1cDwbIcK9VI65Rb84wN87SdkyVP357+WrKk04PfXNhU +-> ssh-ed25519 Sm0lOA LZ2gX5nnMF3xbo/dhGQa6Ms5ifheF4ulag8mKJp6YEs +atOPulZBoi5Xf2uJ+bAXVo3I+XIitkaFM6eoMa7oqwo +--- R15O8zIkvnQHp0FOz24YB0DPOaPWfkt3G4GbBs+lY2o +V7]6 c: D*@z%M3=\B Z%2k \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 4ddb9bc..e93b6ad 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -3,19 +3,21 @@ let inherit (pubkeys) users hosts; in { - "user-helvetica.age".publicKeys = + "users/helvetica.age".publicKeys = (builtins.attrValues users) ++ (builtins.attrValues (builtins.removeAttrs hosts [ "insomniac" ])); - "user-insomniac.age".publicKeys = (builtins.attrValues users) ++ [ hosts.insomniac ]; - - "miniflux.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + "users/insomniac.age".publicKeys = (builtins.attrValues users) ++ [ hosts.insomniac ]; "vaultwarden.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "forgejo-mailer.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; - "forgejo-admin.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + "forgejo/mailer.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + "forgejo/admin.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; "restic-vessel.age".publicKeys = (builtins.attrValues users) ++ [ hosts.vessel ]; "restic-abacus.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; "syncserver.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + + "secure-boot/glacier.tar.age".publicKeys = (builtins.attrValues users) ++ [ hosts.glacier ]; + "secure-boot/abacus.tar.age".publicKeys = (builtins.attrValues users) ++ [ hosts.abacus ]; + "secure-boot/flamingo.tar.age".publicKeys = (builtins.attrValues users) ++ [ hosts.flamingo ]; } diff --git a/secrets/secure-boot/abacus.tar.age b/secrets/secure-boot/abacus.tar.age new file mode 100644 index 0000000000000000000000000000000000000000..b34def7ada003426c89a9e47eb68c612511e01d9 GIT binary patch literal 31262 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 C)5!t= literal 0 HcmV?d00001 diff --git a/secrets/secure-boot/flamingo.tar.age b/secrets/secure-boot/flamingo.tar.age new file mode 100644 index 0000000000000000000000000000000000000000..fdfc6e8c438d534c5f4defd63938ca9afd00a996 GIT binary patch literal 31262 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 I#{~}p0R0WNO8@`> literal 0 HcmV?d00001 diff --git a/secrets/secure-boot/glacier.tar.age b/secrets/secure-boot/glacier.tar.age new file mode 100644 index 0000000000000000000000000000000000000000..c428c59d84bb85ab9d45ed57af186099235a49e8 GIT binary patch literal 31262 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 literal 0 HcmV?d00001 diff --git a/secrets/syncserver.age b/secrets/syncserver.age index 6256bf7014827f8ddd8019b9ad86643b996aec24..3fa9b096fb80a35e585d9b6c4a6a7491006caee3 100644 GIT binary patch delta 619 zcmdnQx`}myPQ9n0TWL;Kd6i3~zok!JTBT2xsfBrJlwXvuW0iKLOJ;7CdA4t2T5)k+ zHkW0(K~$P+U{bnYN~yV9T6lS0L14a{pJia8S*eSqQJ#5nQBF#hb3|Z@0hg|wLUD11 zZfc5=si~o*La=s9d0?PIQi!u@wsvGuzMF4ud2X3@gqy!{l6zu^k9lBdMv_aZw`q`B zURAP3fnjDKmq}_yvRP6^nSVi%Ux8_)n_Ezrc4UrYiA9uivTJ&JR=#(so3E#vL4i;C z#E;_PVFBeqVcK4$85S9C9#Q70rf!~YnW<)F<)y{xQGtQ3ZoZ{Cra4)KRc`rQ?rFi< z=7DaNu2C5gq4~}M#g@4h-oYkO?!}gA5yftPN%^Hom6qkfxlxgm;~B;4bA2Pj(wv?A zOmYj7jEXYNiZe3ZGgFPtUGjpf!cEOf^9(%lJROar%0r5|T+O``BhxJ1qMY0kGjjsW z$|Fm&1C6zP%(A0Qz5IQ$-2(K311*CyT`UZ^baizV^2>@M0!_U9Q;LidEs9F>f^q`Q zeBI3)Q%y5Ujez%Rx#z58hby_hU<&J<%xy% z#&eyUvhB>qazhuJ@_SEx&TM5DXy*SvUu^ztaZZkQeYfoji(iO+J(eK;PP^v0$lk|K z8kAjj|1Yt2YrooRI96Y_DX6(vCj`Pi=)AYwT_uPrvtU z*A=U+Hi64thBYy--S}|Ur+}$4w^$E$CjOieo$z*Ia)6DCbLbDFGDVdH7w?`cD^9d- M6gYce>-Nuz0K+iq761SM delta 619 zcmdnQx`}myPJM+>X`rc3R93ceny-_usf)XFkcYR2r(ub9u1AGWW>le3M4D+yVx(D+ z1(#ojrALu@Ns?n;aE7a6QchJ!N|i9u3XQEq9rX_~&XQ@*paxno3lq>+1}Q;3VNb77U^ z#E;_PQKjyFrH%zgCFYd|o^ECSer3h!m8M>4KF&Grh6bK4hGy<1mFe0U`gs;yX-mHLU{j&5ES9vpB3<&o)=;~B;4-4cB=%RM8U zjRQl>eY~A>!-LYCEcE@|jfzczU6b{*4E=)&BYn$!ozkdFyg7Shq^v&G!GxH){Gc&TebaizVoT@xM9V?Quyp7ybwTpZ_BQlc= z^eqDm!c4u2(gXC}gF+nZU7`|;{ByI*xx8aeiC-?etJNpDI={V-l_6-)od)C7BNb2n z3a#W}E?M>c_sN#Dsu_E>t@K(f{BQc@Io+WxDQhEB&v^efz5Sk%BX?hTRibr5$ L{xS0fERUQ4$0*~e diff --git a/secrets/user-insomniac.age b/secrets/user-insomniac.age deleted file mode 100644 index af210ad..0000000 --- a/secrets/user-insomniac.age +++ /dev/null @@ -1,11 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 SFHVrw 5jjXKCP1LHhUGYyri1g04ZvmJCT3oaHKv3rrX17w2gc -7WncrC6u6edUne4VQGZb/9EnNsL4JRQ/7egfViuclpE --> ssh-ed25519 S+dwQQ KwH9DQOT0uLanFKUkbppGIX9Q5aDjjZZYO7gsF19K0c -ese8sLUSS8c5FgMRITavOj6bqPWV0M3/zOnbyaSj6as --> ssh-ed25519 bPbvlw ufEzOz5vppSomacvWoMe/RAKm6GKPNMjnGbhLpuID3o -HKh4+nBARw8pHhl1+p+hwdvXY+wG4448pnUarQp12rE --> ssh-ed25519 8l76Rg dMN8haWgW3i0EXv2ki8EySvdGVTQ36b6JKC4zSRNWmA -6hoVTll3E8cYkRM1gNV4OU65dcYS/Ufy58xNOgppms8 ---- jYMZqNR10eeeo2aUlSWM02A10ykvDB7mr+DZf7JxdDk --/ezG`[(K;~BUUZK|Hne_iVO?-45w7ձQ7 /|&hr(}OLC(VhW5 \ No newline at end of file diff --git a/secrets/user-lukas.age b/secrets/user-lukas.age deleted file mode 100644 index d500ab67bb571b48e647d1999b7bbc9cd3e2679a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1088 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCR+cJl};Dp&Aua}P>M z^-D=|^EJxOE6a;0cPw@^H?}kiEKT-tOH0Xesq#-s%}XgMH{mifuQc{Iu1u{mG7ih~ zji@ZmOEj%0ipb11&nY!1H_xa_b4m^j47Nzi&d0D#JEc4@P{G|PMLQ_6(ziS!*w57? z%-busDA&(4Db+Kv%DJjMA}gsZ-8Z7l&?z;`gv+?p-z}^l(96OjJkql~GBVRN)gZ;d zH@qw~!!x2F*|8|lqsS#I$TTg*1l_izfTXgVa)lHVpGf`m^n&ob&?4_d=TMiF!pdZA zNB3;^Y!9QT^kP#3pR&+EM<0L3WG??Q!z}%*!YKXH-2BXtFvp0XRPO-ue6vc=aP7z> zH{&W_KeznK;*u=aP;}eU(sGM^$`wk&tNaVxa}7#;BAwk`JX4K4a|82By~83?-5nFX zl0Cx1-Szzq4b9yui@7X4^Gcn)ElP^Ze7yt0OB^G7JzN7klKl;RBlRouP5qpF%-!;R zaw@}}Jkf1SF-r3;E>|#2Dl!W!_e?V=Fe)&~E3h>5^R4tr3NJ5Bu`Je44K;KQFw8J6 z)Aw*LkK{5)^D)bI3-=9k%*u+$H8jXhGzc-ZEH7}aEJ==X(XXs3bt%j7choK}OGmdY zG}z2B#8JUH!^ABj*~cxyM7umNts<$k)G(qfG}yzy$fYpI$*eFjJKVw|C^;!D(3Q(k z-_qBlG5EO3j!6weVw$E%Oi|U z3>?E9Eh8fhj54!*L#qNjOAEuoQuIR&3L*nMiVMr!GeWt{EX~rqgM&lD{mnCyD}9P8 zol{FHz0!+(tDG#Og52`VGn|5*QvFNyiz2ynb#)cYjFXD;qH>bM@(Yqvf(--8UD7HG z(|r@QeZ#%HBb=Sfyvi-|4fI1ZQarg#bh2X2CnoIe5xy;VI5PN|xMblA-zgk2wWa;f zc2@@`rWu`ECY>t0@q2r<`HcvM8WmA(%O4y?msZO)rkEBp{)y(_en5hM@5d?|sgv`a z LBozB?vrTF?Kg(N9H-Y>0JEnit4|GxR>r!>Y0D~I!U+%Baj#1>C&d(8Pq@DdN# Q{G#W-N>(hkS@?So0Fi=n2mk;8 diff --git a/secrets/users/helvetica.age b/secrets/users/helvetica.age new file mode 100644 index 0000000..28ad975 --- /dev/null +++ b/secrets/users/helvetica.age @@ -0,0 +1,20 @@ +age-encryption.org/v1 +-> ssh-ed25519 SFHVrw 5O32JjIL6EnnFpSEWuqYSnlQXCi86TjEGU5hKxEVfUk +mnI5nBEyM/M4hiOEl0lBdBt0v4cthrIlnWd6kvgud5s +-> ssh-ed25519 S+dwQQ bOtKQWynZxYPRukkGBVJ8p6d7mU6J1LxDc7RbxRjxn8 +ykEExNA0KIXWRS0oAME7c6lScb7P5PR6rcoao35dd6s +-> ssh-ed25519 bPbvlw mBeVkAPVjuPyiGZoWTtU9cZEJ7DjT06wS7+BbK8xrlY +l5yxGa/CH2pM6IL6SeWgtQg/nJvcU6vLZQp9f10eQCg +-> ssh-ed25519 ffmsLw LqpIMiGZF5DZwibH8hJD8V8yJfpaRddJRxFC+MWqaQQ +1mGrkOKPZ7ZOQ/kwHA0VigU9DUY8SYTxRiq5tZnaWqk +-> ssh-ed25519 d2fKsw L8PpoPH43jKLkC8tduV2ILAypnwfGP2eJUTjX5foLzs +/Hu7tHtq9m4MYV6K48KDk68HWJzzCCr1DL7dKCyvndo +-> ssh-ed25519 US6ATA XqSHAd4tAGQgfD5zZUgGi85F4WX3Uz3K72ZbSf1b7lI +EYfjkYeoG7fvskrKdUnp/Yz713QfF2Wb+zZyXC/0pHc +-> ssh-ed25519 Sm0lOA UTaaX0IZkosP/zU1s1a1ExcD0Y3lgru+RoAZq4vjaRY +CLFv9o3r3R5RFFlkglmvKQ0S1ROY6VI9yvMO43YjZf8 +-> ssh-ed25519 bgFypQ 6YB0i3QUbaAbTim7e+KSBYUUCRLCbrE+Tg9iW8MG/Uw +EN/o6IgKLUjsNkCNfEeThJZWEmglRis3yWTVWkq0ATg +--- 6oBNTwtiKyo7lhARYSWj1t3pudr+m5ESdA95+Ij3orc +6TB#gX4QUJV(32ZɟD縪 /&9 + ssh-ed25519 SFHVrw iq1lz1cbf7HgkH5Iglb9j9JChuJQALY3JPltoh0DcR4 +xHJ4UsmFymFb7f5mGR6Yj8GGqKQRmD8YLdqYv8wxJMU +-> ssh-ed25519 S+dwQQ wKenvkV4uWqPHN4PNBZ+hQhmtQwULS/Vft6UDYmeKhs +G6fLhpl3K4S/JREeUBnIPs+XOj1BO0S2pAhrOPeQSvI +-> ssh-ed25519 bPbvlw GRzNM9ZIwICpUEjEVl+3Sk4jBKTQ8LxmqLAyaILTUHU +2RLJirofLXeDyvYijMwW5VbDSq6a0iZpCZU7WYtvgFE +-> ssh-ed25519 8l76Rg KReunAJWnHAVMs6Se2MvkWtsnHJwyZA1ZXExvxD93zE +xJUkcjqO33R728mU0dmhBnmF45ZkuxXtW0XgwVf74HA +--- aNnE3YE/Oe/IcRUDuoMNNBeaIcEtPfCpy69bZX8TQg8 +}'C=vTЄq +b.Y?4Ye5|Ӱ7A]+3o2 + &'0ؔⰺU +x \ No newline at end of file diff --git a/secrets/user-helvetica.age b/secrets/users/lukas.age similarity index 100% rename from secrets/user-helvetica.age rename to secrets/users/lukas.age diff --git a/secrets/vaultwarden.age b/secrets/vaultwarden.age index 26cd857be559627253077382414492d5d1d6b9b5..2e8452bee35f0048a392ec3756aa4f95884a65e4 100644 GIT binary patch delta 797 zcmaFN_LyygPQ8~~NVvOqkVjr{T9CHCcUfRqj;n!ZZd6gZTcK%cW_V(0nyaU2d6_|_ z1y`tHs&RIDs&klYVtz$NNM?n~Kc7>a7k)uU^ zcu-E6Nl9)fmq}uHWq@mmn`NGxW1gE+S&^5Qmt{#tWJr)#P(-#@x^{p?L~w?2zQ1YU z#E;_PjzxZMNktXG`iU7HriMP+UM>c%RTa5D<(7E?UWG+Q#@W8kUP)zD0a<}ug&9dE z$pyZC`r6tNUOxG5#@_jPKE-8)1;+Ws$q^Q*{*LZ`LE63sQ6brr;~B;4EiFp3(+m{)GQF}qjH8NjD*Yl;T}%s$^8>ssL!C`iBP%V7Q!=u-e4R?NoFXklTv99Z%AMW) zOtUgvll=63T}xAPG6FKw^W8$ivyuZ!j7u!IbaizVs+@}|f-`*0vb0P5jH=9YGfa(x z-Td|4OWae-LVcW*oP)jU!?S|Yiz33xxsv8iwcgEJS#tF0yY&svgzKU_uQB{(czM>d z{0d*lRnEwxv(lb4FZbe2t}P7NyL{@-6iun>9ih&(`y{;>t zJ2^$M-49q*xBt|!s_-p;jDF~y{v>1GX}wV5&IcjOht<03ferBn*`52k@77O`3at>| z$D4YWA>_^GruFG>>wjhMD`NNEao}XS<;POt5EbQ#uTHbab|f>E2etD@EKBwd`+r{K z_ATe>MLL@qTG=iZ3uo3ovO6n2-(x<dq)Q^7!R5>7!pNed?Ef*ND3RdX4DkN%GfT-unNS zLG)XENy4Qcu5b3;<^CdLx!xho^GeeyZjBimm(L6GQjw7~67T$AWM+Bgugmw&;8cI^ qohmM_#kU@~2e`QHt?m$H5>VRue7>p1_B{3rhr^DT1&W+{J|6%AjXmuE delta 797 zcmaFN_LyygPJLpkM@~eJxvOhrQJ7~{rm2r%a!IO_Pg<%|Qevh{K(T+IwzIQAX{5HJ zFPFBTqoJ`|iBGVW|&v0d#0~JakgPqGMBEMLUD11 zZfc5=si~o*La=s9d0?PIlxcF2Q&nVoiA7qKsi#RwvRjm~Uq)`Cc6g>=Zb4q2S44Sb zq>pnzQGs(LSE-49s(Y5Rf1atQhhIizS$Mg5a)!UJi*JCZS7n}wQ?ienp>t_UiA$vC z#E;_P<^BbxzRnq;$rUD56}e%KP8N=Nu1N)njwx;xC6+;9WmW!u{ubG0`bOnk+HR)C z;iV;2MJ81xS>>fpo)wWEDJAY6Iqs2;0UjB?VQEHAiQZ}6Wq!qz;~B;4^}|dn1KiEC zDhiYHoDK6r^@B1D{aiysGO~lsgQ~(joSo9DLOjbX(gMr53f)bz0!+O!lJl}m(~W%% zEKNf)y|ewyO^l-Q-6Bh(Dl&pXE8NlooYOqHbaizVoP*4K3rrmS{VdB|%7U^Cy#hj9 zQghSXT#_OKjfYaUc9&TA%pY6ZCUYGz16#fb+>4{ zyl&i>*731^<-A=2dafKlbN1>?PYnP2&}z2ZzU6jt8WQi$vz_>Ge)7^KP7IZ-TCb5aM;OrMf-AH{f;S&jW#|%-ENz;Z>itKvuL-d z%|DKOxh-`f3CnzpUTlbe`os3@FaEvex=+F;+KSt<_407o%|0Q% zB!1`B_%H2uPAji=6+QHBtFx4{V!=N##1e(f5QW0OwW@SomN zaL(r3^uWK7ioZ_%5bl|#RB^(i>K#){-=i-V`n~1i{&i-STwFGxx7Kv}6G_$d%PYE- t?L-WhmTcN+PMRtMaJXh>dDKhLRL440{~GDMOXj; From 606b30ff7727a85b5e45493e4741b2680e80d316 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:04:45 +0200 Subject: [PATCH 04/10] stuff --- common/boot.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/boot.nix b/common/boot.nix index e9ca87b..5770446 100644 --- a/common/boot.nix +++ b/common/boot.nix @@ -14,6 +14,8 @@ pkiBundle = "/var/lib/sbctl"; }; + initrd.systemd.enable = true; + loader.efi = { canTouchEfiVariables = true; efiSysMountPoint = "/boot"; From 31316d0e198a156d9eafcc02d8e35445cade9e53 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:24:31 +0200 Subject: [PATCH 05/10] stuff --- hosts/abacus/navidrome.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hosts/abacus/navidrome.nix b/hosts/abacus/navidrome.nix index c6d0ce9..01fecc3 100644 --- a/hosts/abacus/navidrome.nix +++ b/hosts/abacus/navidrome.nix @@ -10,11 +10,11 @@ in Port = 8050; MusicFolder = "/srv/music"; EnableSharing = true; - Backup = { - Path = "/srv/backup/navidrome"; - Count = 1; - Schedule = "0 2 * * *"; - }; + # Backup = { + # Path = "/srv/backup/navidrome"; + # Count = 1; + # Schedule = "0 2 * * *"; + # }; }; }; From 2f6d67c64a14c98e697920885e0625e140bd93b3 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:25:16 +0200 Subject: [PATCH 06/10] stuff --- hosts/abacus/restic.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/abacus/restic.nix b/hosts/abacus/restic.nix index 58fc9de..8504c03 100644 --- a/hosts/abacus/restic.nix +++ b/hosts/abacus/restic.nix @@ -20,7 +20,7 @@ in config.services.forgejo.stateDir config.services.forgejo.dump.backupDir config.services.postgresqlBackup.location - config.services.navidrome.settings.Backup.Path + # config.services.navidrome.settings.Backup.Path # TODO: Add stateDir options for these "/var/lib/headscale" "/var/lib/navidrome" From 92e2152a1916adafc6177144bc0a1970cbec4f43 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:29:14 +0200 Subject: [PATCH 07/10] stuff --- hosts/abacus/mealie.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/abacus/mealie.nix b/hosts/abacus/mealie.nix index 217ad63..396bf64 100644 --- a/hosts/abacus/mealie.nix +++ b/hosts/abacus/mealie.nix @@ -7,7 +7,7 @@ in enable = true; settings = { BASE_URL = "https://${virtualHostName}"; - ALLOW_SIGNUP = false; + ALLOW_SIGNUP = "false"; }; listenAddress = "127.0.0.1"; port = 8040; From f9c8a7007a57459ec7998a4d0244545601f950a8 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:36:40 +0200 Subject: [PATCH 08/10] stuff --- hosts/abacus/forgejo.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/abacus/forgejo.nix b/hosts/abacus/forgejo.nix index 6aebcc1..12b9a2a 100644 --- a/hosts/abacus/forgejo.nix +++ b/hosts/abacus/forgejo.nix @@ -76,7 +76,7 @@ in passwordFile = secrets.forgejo-admin.path; in '' - admins=$(admin user list --admin) + admins=$(gitea admin user list --admin) admins=$((admins - 1)) if ((admins < 1)); then From e945e5c24ba28b25a4ed4cf76367af4c062e1e0b Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 04:41:30 +0200 Subject: [PATCH 09/10] stuff --- hosts/abacus/forgejo.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/abacus/forgejo.nix b/hosts/abacus/forgejo.nix index 12b9a2a..41ad4f5 100644 --- a/hosts/abacus/forgejo.nix +++ b/hosts/abacus/forgejo.nix @@ -76,7 +76,7 @@ in passwordFile = secrets.forgejo-admin.path; in '' - admins=$(gitea admin user list --admin) + admins=$(gitea admin user list --admin | wc --lines) admins=$((admins - 1)) if ((admins < 1)); then From b9db4fa6c097fb9385b59ddcc78776123f334368 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Sun, 18 May 2025 16:51:40 +0200 Subject: [PATCH 10/10] stuff --- hosts/abacus/forgejo.nix | 9 +- hosts/abacus/vaultwarden.nix | 4 +- hosts/vessel/musicomp.nix | 6 +- modules/rsync.nix | 208 ----------------------------------- 4 files changed, 10 insertions(+), 217 deletions(-) delete mode 100644 modules/rsync.nix diff --git a/hosts/abacus/forgejo.nix b/hosts/abacus/forgejo.nix index 41ad4f5..249e923 100644 --- a/hosts/abacus/forgejo.nix +++ b/hosts/abacus/forgejo.nix @@ -64,23 +64,20 @@ in secrets.mailer.PASSWD = secrets.forgejo-mailer.path; }; - # TODO systemd.services.forgejo.preStart = lib.getExe ( pkgs.writeShellApplication { name = "forgejo-init-admin"; - runtimeInputs = [ - cfg.package - ]; text = let + forgejoExe = lib.getExe cfg.package; passwordFile = secrets.forgejo-admin.path; in '' - admins=$(gitea admin user list --admin | wc --lines) + admins=$(${forgejoExe} admin user list --admin | wc --lines) admins=$((admins - 1)) if ((admins < 1)); then - gitea admin user create \ + ${forgejoExe} admin user create \ --admin \ --email helvetica@helveticanonstandard.net \ --username helvetica \ diff --git a/hosts/abacus/vaultwarden.nix b/hosts/abacus/vaultwarden.nix index af5b45b..22f076c 100644 --- a/hosts/abacus/vaultwarden.nix +++ b/hosts/abacus/vaultwarden.nix @@ -4,9 +4,11 @@ ... }: let - virtualHostName = "vault.wrz.one"; + virtualHostName = "vault.helveticanonstandard.net"; in { + # TODO: tailscale + age.secrets = lib.mkSecrets { vaultwarden = { }; }; services.vaultwarden = { diff --git a/hosts/vessel/musicomp.nix b/hosts/vessel/musicomp.nix index 4d61a8a..3cbb39e 100644 --- a/hosts/vessel/musicomp.nix +++ b/hosts/vessel/musicomp.nix @@ -20,7 +20,9 @@ inhibitsSleep = true; post = let - remoteDir = self.nixosConfigurations.abacus.config.services.navidrome.settings.MusicFolder; + abacusConfig = self.nixosConfigurations.abacus.config; + remoteDir = abacusConfig.services.navidrome.settings.MusicFolder; + remoteDomain = abacusConfig.networking.domain; package = pkgs.writeShellApplication { name = "sync"; runtimeInputs = [ @@ -36,7 +38,7 @@ --mkpath \ --verbose --verbose \ --rsh 'ssh -i /etc/ssh/ssh_host_ed25519_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' \ - /srv/void/compmusic/ root@wrz.one:${lib.escapeShellArg remoteDir} + /srv/void/compmusic/ root@${lib.escapeShellArg remoteDomain}:${lib.escapeShellArg remoteDir}/ ''; }; in diff --git a/modules/rsync.nix b/modules/rsync.nix deleted file mode 100644 index d5d7a55..0000000 --- a/modules/rsync.nix +++ /dev/null @@ -1,208 +0,0 @@ -{ - config, - lib, - pkgs, - utils, - ... -}: -let - cfg = config.services.rsync; - inherit (lib) types; - inherit (utils.systemdUtils.unitOptions) unitOption; - settingsToShell = lib.cli.toGNUCommandLineShell { - mkOptionName = k: "--${k}"; - }; - settingsType = - let - simples = [ - types.bool - types.str - types.int - types.float - ]; - in - types.attrsOf ( - types.oneOf ( - simples - ++ [ - (types.listOf (types.oneOf simples)) - ] - ) - ); -in -{ - options.services.rsync = { - enable = lib.mkEnableOption "periodic directory syncing via rsync"; - - package = lib.mkPackageOption pkgs "rsync" { }; - - # commonSettings = lib.mkOption { - # type = settingsType; - # default = { }; - # example = { - # archive = true; - # update = true; - # delete = true; - # mkpath = true; - # }; - # description = '' - # Common arguments to pass to the rsync command. - # ''; - # }; - - jobs = lib.mkOption { - description = '' - Synchronization jobs to run. - ''; - default = { }; - type = types.attrsOf ( - types.submodule { - options = { - sources = lib.mkOption { - type = types.listOf types.str; - example = [ - "/srv/src1/" - "/srv/src2/" - ]; - description = '' - Source directories. - ''; - }; - - destination = lib.mkOption { - type = types.str; - example = "/srv/dst/"; - description = '' - Destination directory. - ''; - }; - - settings = lib.mkOption { - type = settingsType; - default = { }; - example = { - verbose = true; - }; - description = '' - Extra arguments to pass to the rsync command. - ''; - }; - - user = lib.mkOption { - type = types.str; - default = "root"; - description = '' - The name of an existing user account under which the rsync process should run. - ''; - }; - - group = lib.mkOption { - type = types.str; - default = "root"; - description = '' - The name of an existing user group under which the rsync process should run. - ''; - }; - - timerConfig = lib.mkOption { - type = lib.types.nullOr (lib.types.attrsOf unitOption); - default = { - OnCalendar = "daily"; - Persistent = true; - }; - description = '' - When to run the job. - ''; - }; - - inhibit = lib.mkOption { - default = [ ]; - type = types.listOf types.str; - example = [ - "sleep" - ]; - description = '' - Run the rsync process with an inhibition lock taken; - see {manpage}`systemd-inhibit(1)` for a list of possible operations. - ''; - }; - }; - } - ); - }; - }; - - config = lib.mkIf cfg.enable { - assertions = [ - { - assertion = lib.all (job: job.sources != [ ]) (lib.attrValues cfg.jobs); - message = '' - At least one source directory must be provided to rsync. - ''; - } - ]; - - systemd = lib.mkMerge ( - lib.mapAttrsToList ( - jobName: job: - let - systemdName = "rsync-job-${jobName}"; - description = "Directory syncing via rsync job ${jobName}"; - in - { - timers.${systemdName} = { - wantedBy = [ - "timers.target" - ]; - inherit description; - inherit (job) timerConfig; - }; - - services.${systemdName} = { - inherit description; - - serviceConfig = { - Type = "oneshot"; - User = job.user; - Group = job.group; - - NoNewPrivileges = true; - PrivateDevices = true; - ProtectSystem = "full"; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectControlGroups = true; - MemoryDenyWriteExecute = true; - LockPersonality = true; - }; - - script = - let - settingsShell = settingsToShell job.settings; - inhibitString = lib.concatStringsSep ":" job.inhibit; - in - '' - ${ - lib.optionalString (job.inhibit != [ ]) '' - ${lib.getExe' config.systemd.package "systemd-inhibit"} \ - --mode block \ - --who ${lib.escapeShellArg description} \ - --what ${lib.escapeShellArg inhibitString} \ - --why ${lib.escapeShellArg "Scheduled rsync job ${jobName}"} \ - -- \ - '' - } \ - ${lib.getExe cfg.package} ${settingsShell} -- \ - ${lib.escapeShellArgs job.sources} \ - ${lib.escapeShellArg job.destination} - ''; - }; - } - ) cfg.jobs - ); - }; - - meta.maintainers = [ - lib.maintainers.lukaswrz - ]; -}