diff --git a/devShells.nix b/devShells.nix new file mode 100644 index 0000000..254d604 --- /dev/null +++ b/devShells.nix @@ -0,0 +1,14 @@ +{ ... }: + +{ + perSystem = + { pkgs, ... }: + { + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + nil + nixfmt-rfc-style + ]; + }; + }; +} diff --git a/flake.lock b/flake.lock index 10e0544..b19b2ca 100644 --- a/flake.lock +++ b/flake.lock @@ -147,6 +147,24 @@ "type": "github" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1759362264, + "narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "758cf7296bee11f1706a574c77d072b8a7baa881", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems_2" @@ -316,6 +334,21 @@ "type": "github" } }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, "nixpkgs-stable": { "locked": { "lastModified": 1759735786, @@ -390,6 +423,7 @@ "agenix": "agenix", "disko": "disko", "dms": "dms", + "flake-parts": "flake-parts", "home-manager": "home-manager_2", "home-manager-stable": "home-manager-stable", "impermanence": "impermanence", diff --git a/flake.nix b/flake.nix index 234a747..0d826a1 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,8 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05"; + flake-parts.url = "github:hercules-ci/flake-parts"; + home-manager = { url = "github:nix-community/home-manager/master"; inputs.nixpkgs.follows = "nixpkgs"; @@ -37,151 +39,19 @@ }; outputs = - inputs@{ - self, - nixpkgs, - nixpkgs-stable, - home-manager, - home-manager-stable, - disko, - dms, - agenix, - nixos-cli, - nix-flatpak, - impermanence, - ... - }: - let + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "aarch64-linux" ]; - forAllSystems = nixpkgs.lib.genAttrs systems; - forAllSystemsWithPkgs = - f: - forAllSystems ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - f system pkgs - ); - in - { - nixosConfigurations = - let - mkHost = - { - hostname, - type, # workstation|server - system ? "x86_64-linux", - extraModules ? [ ], - }: - let - pkgs = if type == "server" then nixpkgs-stable else nixpkgs; - hm = if type == "server" then home-manager-stable else home-manager; - hostTypeFlags = { - isServer = type == "server"; - isWorkstation = type == "workstation"; - }; - defaultModules = [ - ./hosts/${hostname}.nix - agenix.nixosModules.default - disko.nixosModules.default - dms.nixosModules.greeter - hm.nixosModules.default - impermanence.nixosModules.impermanence - nix-flatpak.nixosModules.nix-flatpak - nixos-cli.nixosModules.nixos-cli - { - nixpkgs.overlays = [ - agenix.overlays.default - ]; - } - ]; - workstationModules = [ - { - nixpkgs.overlays = [ - self.overlays.workstationOverlay - ]; - } - ]; - serverModules = [ - { - nixpkgs.overlays = [ - self.overlays.serverOverlay - ]; - } - ]; - typeModules = if type == "server" then serverModules else workstationModules; - allModules = defaultModules ++ typeModules ++ extraModules; - in - pkgs.lib.nixosSystem { - inherit system; - specialArgs = { - inherit inputs; - hostType = hostTypeFlags; - }; - modules = allModules; - }; - in - { - rotterdam = mkHost { - hostname = "rotterdam"; - type = "workstation"; - }; - io = mkHost { - hostname = "io"; - type = "workstation"; - }; - alexandria = mkHost { - hostname = "alexandria"; - type = "server"; - extraModules = [ - self.nixosModules.qbittorrent - ]; - }; - trantor = mkHost { - hostname = "trantor"; - type = "server"; - system = "aarch64-linux"; - }; - }; - devShells = forAllSystemsWithPkgs ( - system: pkgs: { - default = pkgs.mkShell { - packages = with pkgs; [ - nil - nixfmt-rfc-style - ]; - }; - } - ); - - packages = forAllSystemsWithPkgs ( - system: pkgs: - { - toggleaudiosink = pkgs.callPackage ./packages/toggleaudiosink.nix { }; - } - // nixpkgs.lib.optionalAttrs (system == "x86_64-linux") { - # plasticity = pkgs.callPackage ./packages/plasticity.nix { }; - } - ); - - overlays = { - overlay = final: prev: { - }; - workstationOverlay = final: prev: { - # plasticity = self.packages.${final.system}.plasticity; - toggleaudiosink = self.packages.${final.system}.toggleaudiosink; - }; - serverOverlay = final: prev: { - }; - }; - - nixosModules = { - qbittorrent = import ./modules/qbittorrent.nix; - }; + imports = [ + ./devShells.nix + ./homeConfigurations.nix + ./nixosConfigurations.nix + ./overlays.nix + ./packages.nix + ]; }; } diff --git a/homeConfigurations.nix b/homeConfigurations.nix new file mode 100644 index 0000000..3d3a950 --- /dev/null +++ b/homeConfigurations.nix @@ -0,0 +1,34 @@ +{ inputs, ... }: +let + utils = import ./utils.nix { inherit inputs; }; + inherit (utils) mkUser; +in +{ + flake.homeConfigurations = { + "user@rotterdam" = mkUser { + username = "user"; + tags = [ + "btop" + "desktop" + "direnv" + "gaming" + "helix" + "obs-studio" + "starship" + "tmux" + ]; + }; + + "user@io" = mkUser { + username = "user"; + tags = [ + "btop" + "desktop" + "direnv" + "helix" + "starship" + "tmux" + ]; + }; + }; +} diff --git a/hosts/alexandria.nix b/hosts/alexandria.nix deleted file mode 100644 index 6050904..0000000 --- a/hosts/alexandria.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: - -{ - networking.hostName = "alexandria"; - - imports = [ - ./modules/alexandria - ./modules - ]; - - nix.nixPath = [ "nixos-config=${./alexandria.nix}" ]; -} diff --git a/hosts/alexandria/firewall.nix b/hosts/alexandria/firewall.nix new file mode 100644 index 0000000..f6fded2 --- /dev/null +++ b/hosts/alexandria/firewall.nix @@ -0,0 +1,11 @@ +{ ... }: + +{ + networking.firewall = { + allowedTCPPorts = [ + 80 + 443 + ]; + allowedUDPPorts = [ ]; + }; +} diff --git a/hosts/alexandria/forgejo.nix b/hosts/alexandria/forgejo.nix new file mode 100644 index 0000000..0b9908e --- /dev/null +++ b/hosts/alexandria/forgejo.nix @@ -0,0 +1,21 @@ +{ ... }: + +{ + services.forgejo = { + enable = true; + repositoryRoot = "/data/forgejo"; + settings = { + session.COOKIE_SECURE = true; + server = { + PROTOCOL = "http+unix"; + DOMAIN = "git.baduhai.dev"; + ROOT_URL = "https://git.baduhai.dev"; + OFFLINE_MODE = true; # disable use of CDNs + SSH_DOMAIN = "baduhai.dev"; + }; + log.LEVEL = "Warn"; + mailer.ENABLED = false; + actions.ENABLED = false; + }; + }; +} diff --git a/hosts/modules/alexandria/hardware-configuration.nix b/hosts/alexandria/hardware-configuration.nix similarity index 100% rename from hosts/modules/alexandria/hardware-configuration.nix rename to hosts/alexandria/hardware-configuration.nix diff --git a/hosts/alexandria/jellyfin.nix b/hosts/alexandria/jellyfin.nix new file mode 100644 index 0000000..87a825f --- /dev/null +++ b/hosts/alexandria/jellyfin.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + services.jellyfin = { + enable = true; + openFirewall = true; + }; +} diff --git a/hosts/alexandria/librespeed.nix b/hosts/alexandria/librespeed.nix new file mode 100644 index 0000000..09e4768 --- /dev/null +++ b/hosts/alexandria/librespeed.nix @@ -0,0 +1,14 @@ +{ ... }: + +{ + virtualisation.oci-containers.containers."librespeed" = { + image = "lscr.io/linuxserver/librespeed:latest"; + environment = { + TZ = "America/Bahia"; + }; + extraOptions = [ + "--pull=newer" + "--label=io.containers.autoupdate=registry" + ]; + }; +} diff --git a/hosts/alexandria/nginx.nix b/hosts/alexandria/nginx.nix new file mode 100644 index 0000000..8c20d5d --- /dev/null +++ b/hosts/alexandria/nginx.nix @@ -0,0 +1,71 @@ +{ config, lib, ... }: + +{ + security.acme = { + acceptTerms = true; + defaults = { + email = "baduhai@proton.me"; + dnsResolver = "1.1.1.1:53"; + dnsProvider = "cloudflare"; + credentialsFile = config.age.secrets.cloudflare.path; + }; + certs."baduhai.dev" = { + extraDomainNames = [ "*.baduhai.dev" ]; + }; + }; + + age.secrets.cloudflare = { + file = ../../secrets/cloudflare.age; + owner = "nginx"; + group = "nginx"; + }; + + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + virtualHosts = + let + commonVHostConfig = { + useACMEHost = "baduhai.dev"; + forceSSL = true; + kTLS = true; + }; + in + lib.mapAttrs (_: lib.recursiveUpdate commonVHostConfig) { + "_".locations."/".return = "444"; + "dav.baduhai.dev".locations = { + "/caldav" = { + proxyPass = "http://unix:/run/radicale/radicale.sock:/"; + extraConfig = '' + proxy_set_header X-Script-Name /caldav; + proxy_pass_header Authorization; + ''; + }; + "/webdav" = { + proxyPass = "http://unix:/run/rclone-webdav/webdav.sock:/webdav/"; + extraConfig = '' + proxy_set_header X-Script-Name /webdav; + proxy_pass_header Authorization; + proxy_connect_timeout 300; # Increase timeouts for large file uploads + proxy_send_timeout 300; + proxy_read_timeout 300; + client_max_body_size 10G; # Allow large file uploads + proxy_buffering off; # Buffer settings for better performance + proxy_request_buffering off; + ''; + }; + }; + "git.baduhai.dev".locations."/".proxyPass = + "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/"; + "jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/"; + "pass.baduhai.dev".locations."/".proxyPass = + "http://unix:${config.services.vaultwarden.config.ROCKET_ADDRESS}:/"; + "speedtest.baduhai.dev".locations."/".proxyPass = "http://librespeed:80/"; + }; + }; + + users.users.nginx.extraGroups = [ "acme" ]; +} diff --git a/hosts/alexandria/radicale.nix b/hosts/alexandria/radicale.nix new file mode 100644 index 0000000..d81a228 --- /dev/null +++ b/hosts/alexandria/radicale.nix @@ -0,0 +1,17 @@ +{ ... }: + +{ + services.radicale = { + enable = true; + settings = { + server = { + hosts = [ "/run/radicale/radicale.sock" ]; + }; + auth = { + type = "htpasswd"; + htpasswd_filename = "/etc/radicale/users"; + htpasswd_encryption = "bcrypt"; + }; + }; + }; +} diff --git a/hosts/alexandria/rclone-webdav.nix b/hosts/alexandria/rclone-webdav.nix new file mode 100644 index 0000000..8324d31 --- /dev/null +++ b/hosts/alexandria/rclone-webdav.nix @@ -0,0 +1,82 @@ +{ config, pkgs, ... }: + +let + rclone-webdav-start = pkgs.writeShellScript "rclone-webdav-start.sh" '' + #!/bin/bash + + # Configuration + CREDS_FILE="/run/agenix/webdav" + SERVE_DIR="/data/webdav" + SOCKET_PATH="/run/rclone-webdav/webdav.sock" + + # Check if credentials file exists + if [ ! -f "$CREDS_FILE" ]; then + echo "Error: Credentials file $CREDS_FILE not found" + exit 1 + fi + + # Read credentials from file (format: username:password) + CREDENTIALS=$(cat "$CREDS_FILE") + USERNAME=$(echo "$CREDENTIALS" | cut -d':' -f1) + PASSWORD=$(echo "$CREDENTIALS" | cut -d':' -f2) + + # Validate credentials + if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then + echo "Error: Invalid credentials format. Expected username:password" + exit 1 + fi + + # Ensure serve directory exists + mkdir -p "$SERVE_DIR" + + # Remove existing socket if it exists + rm -f "$SOCKET_PATH" + + # Start rclone serve webdav + exec ${pkgs.rclone}/bin/rclone serve webdav "$SERVE_DIR" \ + --addr unix://"$SOCKET_PATH" \ + --user "$USERNAME" \ + --pass "$PASSWORD" \ + --config="" \ + --baseurl "/webdav" \ + --verbose + ''; +in + +{ + age.secrets.webdav = { + file = ../../secrets/webdav.age; + owner = "user"; + group = "users"; + }; + + systemd.services.rclone-webdav = { + description = "RClone WebDAV Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "exec"; + User = "user"; + Group = "nginx"; + ExecStart = "${rclone-webdav-start}"; + Restart = "always"; + RestartSec = "10"; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = true; + ReadWritePaths = [ + "/data/webdav" + "/run" + ]; + RuntimeDirectory = "rclone-webdav"; + RuntimeDirectoryMode = "0750"; + UMask = "0002"; + }; + preStart = '' + mkdir -p /data/webdav + chown user:users /data/webdav + chmod 755 /data/webdav + ''; + }; +} diff --git a/hosts/alexandria/vaultwarden.nix b/hosts/alexandria/vaultwarden.nix new file mode 100644 index 0000000..058c123 --- /dev/null +++ b/hosts/alexandria/vaultwarden.nix @@ -0,0 +1,12 @@ +{ ... }: + +{ + services.vaultwarden = { + enable = true; + config = { + DOMAIN = "https://pass.baduhai.dev"; + SIGNUPS_ALLOWED = false; + ROCKET_ADDRESS = "/run/vaultwarden/vaultwarden.sock"; + }; + }; +} diff --git a/hosts/io.nix b/hosts/io.nix deleted file mode 100644 index 3910dc1..0000000 --- a/hosts/io.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: - -{ - networking.hostName = "io"; - - imports = [ - ./modules/io - ./modules - ]; - - nix.nixPath = [ "nixos-config=${./io.nix}" ]; -} diff --git a/hosts/modules/io/boot.nix b/hosts/io/boot.nix similarity index 100% rename from hosts/modules/io/boot.nix rename to hosts/io/boot.nix diff --git a/hosts/modules/io/disko.nix b/hosts/io/disko.nix similarity index 97% rename from hosts/modules/io/disko.nix rename to hosts/io/disko.nix index 3dc3b31..edb1418 100644 --- a/hosts/modules/io/disko.nix +++ b/hosts/io/disko.nix @@ -1,6 +1,8 @@ -{ ... }: +{ inputs, ... }: { + imports = [ inputs.disko.nixosModules.default ]; + disko.devices = { disk = { main = { diff --git a/hosts/modules/io/hardware-configuration.nix b/hosts/io/hardware-configuration.nix similarity index 100% rename from hosts/modules/io/hardware-configuration.nix rename to hosts/io/hardware-configuration.nix diff --git a/hosts/modules/io/programs.nix b/hosts/io/programs.nix similarity index 73% rename from hosts/modules/io/programs.nix rename to hosts/io/programs.nix index f1286c7..e272d22 100644 --- a/hosts/modules/io/programs.nix +++ b/hosts/io/programs.nix @@ -19,19 +19,9 @@ in { environment = { systemPackages = with pkgs; [ - arduino-ide - esptool - # fritzing maliit-keyboard sof-firmware ]; sessionVariables.ALSA_CONFIG_UCM2 = "${cml-ucm-conf}/share/alsa/ucm2"; }; - - # TODO: remove once gmodena/nix-flatpak/issues/45 fixed - systemd.services."flatpak-managed-install" = { - serviceConfig = { - ExecStartPre = "${pkgs.coreutils}/bin/sleep 5"; - }; - }; } diff --git a/hosts/modules/io/services.nix b/hosts/io/services.nix similarity index 84% rename from hosts/modules/io/services.nix rename to hosts/io/services.nix index f9f82cf..3703ba3 100644 --- a/hosts/modules/io/services.nix +++ b/hosts/io/services.nix @@ -1,3 +1,5 @@ +{ pkgs, ... }: + { services = { keyd = { @@ -47,4 +49,11 @@ }; }; }; + + # TODO: remove once gmodena/nix-flatpak/issues/45 fixed + systemd.services."flatpak-managed-install" = { + serviceConfig = { + ExecStartPre = "${pkgs.coreutils}/bin/sleep 5"; + }; + }; } diff --git a/hosts/modules/alexandria/default.nix b/hosts/modules/alexandria/default.nix deleted file mode 100644 index 40a4da2..0000000 --- a/hosts/modules/alexandria/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: - -{ - imports = [ - ./hardware-configuration.nix - ./services.nix - ./users.nix - ]; -} diff --git a/hosts/modules/alexandria/networking.nix b/hosts/modules/alexandria/networking.nix deleted file mode 100644 index 2d59cbb..0000000 --- a/hosts/modules/alexandria/networking.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - networking = { - firewall = { - allowedTCPPorts = [ - 80 - 443 - ]; - allowedUDPPorts = [ ]; - }; - }; - - boot.kernel.sysctl = { - "net.ipv4.ip_forward" = 1; - "net.ipv6.conf.all.forwarding" = 1; - }; -} diff --git a/hosts/modules/alexandria/services.nix b/hosts/modules/alexandria/services.nix deleted file mode 100644 index 7de15d5..0000000 --- a/hosts/modules/alexandria/services.nix +++ /dev/null @@ -1,225 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -let - ports = { - jellyfin = "8096"; - librespeed = "8000"; - radicale = "8001"; - vaultwarden = "8002"; - }; - rclone-webdav-start = pkgs.writeShellScript "rclone-webdav-start.sh" '' - #!/bin/bash - - # Configuration - CREDS_FILE="/run/agenix/webdav" - SERVE_DIR="/data/webdav" - SOCKET_PATH="/run/rclone-webdav/webdav.sock" - - # Check if credentials file exists - if [ ! -f "$CREDS_FILE" ]; then - echo "Error: Credentials file $CREDS_FILE not found" - exit 1 - fi - - # Read credentials from file (format: username:password) - CREDENTIALS=$(cat "$CREDS_FILE") - USERNAME=$(echo "$CREDENTIALS" | cut -d':' -f1) - PASSWORD=$(echo "$CREDENTIALS" | cut -d':' -f2) - - # Validate credentials - if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then - echo "Error: Invalid credentials format. Expected username:password" - exit 1 - fi - - # Ensure serve directory exists - mkdir -p "$SERVE_DIR" - - # Remove existing socket if it exists - rm -f "$SOCKET_PATH" - - # Start rclone serve webdav - exec ${pkgs.rclone}/bin/rclone serve webdav "$SERVE_DIR" \ - --addr unix://"$SOCKET_PATH" \ - --user "$USERNAME" \ - --pass "$PASSWORD" \ - --config="" \ - --baseurl "/webdav" \ - --verbose - ''; -in - -{ - services = { - forgejo = { - enable = true; - repositoryRoot = "/data/forgejo"; - settings = { - session.COOKIE_SECURE = true; - server = { - PROTOCOL = "http+unix"; - DOMAIN = "git.baduhai.dev"; - ROOT_URL = "https://git.baduhai.dev"; - OFFLINE_MODE = true; # disable use of CDNs - SSH_DOMAIN = "baduhai.dev"; - }; - log.LEVEL = "Warn"; - mailer.ENABLED = false; - actions.ENABLED = false; - }; - }; - - jellyfin = { - enable = true; - openFirewall = true; - }; - - nginx = { - enable = true; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - virtualHosts = - let - commonVHostConfig = { - useACMEHost = "baduhai.dev"; - forceSSL = true; - kTLS = true; - }; - in - lib.mapAttrs (_: lib.recursiveUpdate commonVHostConfig) { - "_".locations."/".return = "444"; - "dav.baduhai.dev".locations = { - "/caldav" = { - proxyPass = "http://127.0.0.1:${ports.radicale}/"; - extraConfig = '' - proxy_set_header X-Script-Name /caldav; - proxy_pass_header Authorization; - ''; - }; - "/webdav" = { - proxyPass = "http://unix:/run/rclone-webdav/webdav.sock:/webdav/"; - extraConfig = '' - proxy_set_header X-Script-Name /webdav; - proxy_pass_header Authorization; - proxy_connect_timeout 300; # Increase timeouts for large file uploads - proxy_send_timeout 300; - proxy_read_timeout 300; - client_max_body_size 10G; # Allow large file uploads - proxy_buffering off; # Buffer settings for better performance - proxy_request_buffering off; - ''; - }; - }; - "git.baduhai.dev".locations."/".proxyPass = - "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/"; - "jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:${ports.jellyfin}/"; - "pass.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:${ports.vaultwarden}/"; - "speedtest.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:${ports.librespeed}/"; - }; - }; - - radicale = { - enable = true; - settings = { - server = { - hosts = [ - "127.0.0.1:${ports.radicale}" - "[::]:${ports.radicale}" - ]; - }; - auth = { - type = "htpasswd"; - htpasswd_filename = "/etc/radicale/users"; - htpasswd_encryption = "bcrypt"; - }; - }; - }; - - vaultwarden = { - enable = true; - config = { - DOMAIN = "https://pass.baduhai.dev"; - SIGNUPS_ALLOWED = false; - ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = "${ports.vaultwarden}"; - }; - }; - }; - - virtualisation.oci-containers.containers."librespeed" = { - image = "lscr.io/linuxserver/librespeed:latest"; - environment = { - TZ = "America/Bahia"; - }; - ports = [ "${ports.librespeed}:80" ]; - extraOptions = [ - "--pull=newer" - "--label=io.containers.autoupdate=registry" - ]; - }; - - security.acme = { - acceptTerms = true; - defaults = { - email = "baduhai@proton.me"; - dnsResolver = "1.1.1.1:53"; - dnsProvider = "cloudflare"; - credentialsFile = config.age.secrets.cloudflare.path; - }; - certs."baduhai.dev" = { - extraDomainNames = [ "*.baduhai.dev" ]; - }; - }; - - age.secrets = { - cloudflare = { - file = ../../../secrets/cloudflare.age; - owner = "nginx"; - group = "nginx"; - }; - webdav = { - file = ../../../secrets/webdav.age; - owner = "user"; - group = "users"; - }; - }; - - systemd.services = { - rclone-webdav = { - description = "RClone WebDAV Server"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "exec"; - User = "user"; - Group = "nginx"; - ExecStart = "${rclone-webdav-start}"; - Restart = "always"; - RestartSec = "10"; - NoNewPrivileges = true; - PrivateTmp = true; - ProtectSystem = "strict"; - ProtectHome = true; - ReadWritePaths = [ - "/data/webdav" - "/run" - ]; - RuntimeDirectory = "rclone-webdav"; - RuntimeDirectoryMode = "0750"; - UMask = "0002"; - }; - preStart = '' - mkdir -p /data/webdav - chown user:users /data/webdav - chmod 755 /data/webdav - ''; - }; - }; -} diff --git a/hosts/modules/alexandria/users.nix b/hosts/modules/alexandria/users.nix deleted file mode 100644 index 14e34c2..0000000 --- a/hosts/modules/alexandria/users.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - users.users.nginx.extraGroups = [ "acme" ]; -} diff --git a/hosts/modules/bluetooth.nix b/hosts/modules/bluetooth.nix new file mode 100644 index 0000000..fb6a06a --- /dev/null +++ b/hosts/modules/bluetooth.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + hardware.bluetooth.enable = true; +} diff --git a/hosts/modules/boot.nix b/hosts/modules/boot.nix deleted file mode 100644 index 049fad7..0000000 --- a/hosts/modules/boot.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - boot = { - loader = { - timeout = 1; - efi.canTouchEfiVariables = true; - systemd-boot = { - enable = true; - editor = false; - consoleMode = "max"; - sortKey = "aa"; - netbootxyz = { - enable = true; - sortKey = "zz"; - }; - }; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - boot.kernelPackages = pkgs.linuxPackages_hardened; - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - boot = { - plymouth.enable = true; - initrd.systemd.enable = true; - loader.efi.efiSysMountPoint = "/boot/efi"; - kernelPackages = pkgs.linuxPackages_xanmod; - extraModprobeConfig = '' - options bluetooth disable_ertm=1 - ''; - kernel.sysctl = { - "net.ipv4.tcp_mtu_probing" = 1; - }; - kernelParams = [ - "quiet" - "splash" - "i2c-dev" - "i2c-piix4" - "loglevel=3" - "udev.log_priority=3" - "rd.udev.log_level=3" - "rd.systemd.show_status=false" - ]; - }; - }) - ]; -} diff --git a/hosts/modules/common/boot.nix b/hosts/modules/common/boot.nix new file mode 100644 index 0000000..fbba278 --- /dev/null +++ b/hosts/modules/common/boot.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: + +{ + boot = { + loader = { + timeout = 1; + efi.canTouchEfiVariables = true; + systemd-boot = { + enable = true; + editor = false; + consoleMode = "max"; + sortKey = "aa"; + netbootxyz = { + enable = true; + sortKey = "zz"; + }; + }; + }; + }; +} diff --git a/hosts/modules/common/console.nix b/hosts/modules/common/console.nix new file mode 100644 index 0000000..9cb99d4 --- /dev/null +++ b/hosts/modules/common/console.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + console = { + useXkbConfig = true; + earlySetup = true; + }; +} diff --git a/hosts/modules/common/firewall.nix b/hosts/modules/common/firewall.nix new file mode 100644 index 0000000..910e803 --- /dev/null +++ b/hosts/modules/common/firewall.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + networking = { + firewall.enable = true; + nftables.enable = true; + }; +} diff --git a/hosts/modules/common/locale.nix b/hosts/modules/common/locale.nix new file mode 100644 index 0000000..7e07d85 --- /dev/null +++ b/hosts/modules/common/locale.nix @@ -0,0 +1,20 @@ +{ ... }: + +{ + time.timeZone = "America/Bahia"; + + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "pt_BR.utf8"; + LC_IDENTIFICATION = "pt_BR.utf8"; + LC_MEASUREMENT = "pt_BR.utf8"; + LC_MONETARY = "pt_BR.utf8"; + LC_NAME = "pt_BR.utf8"; + LC_NUMERIC = "pt_BR.utf8"; + LC_PAPER = "pt_BR.utf8"; + LC_TELEPHONE = "pt_BR.utf8"; + LC_TIME = "en_IE.utf8"; + }; + }; +} diff --git a/hosts/modules/common/nix.nix b/hosts/modules/common/nix.nix new file mode 100644 index 0000000..ff0b474 --- /dev/null +++ b/hosts/modules/common/nix.nix @@ -0,0 +1,40 @@ +{ inputs, ... }: + +{ + imports = [ inputs.nixos-cli.nixosModules.nixos-cli ]; + + nix = { + settings = { + auto-optimise-store = true; + connect-timeout = 10; + log-lines = 25; + min-free = 128000000; + max-free = 1000000000; + trusted-users = [ "@wheel" ]; + }; + extraOptions = "experimental-features = nix-command flakes"; + gc = { + automatic = true; + options = "--delete-older-than 8d"; + }; + }; + + nixpkgs.config = { + allowUnfree = true; + enableParallelBuilding = true; + buildManPages = false; + buildDocs = false; + }; + + services = { + nixos-cli = { + enable = true; + config = { + use_nvd = true; + ignore_dirty_tree = true; + }; + }; + }; + + system.stateVersion = "22.11"; +} diff --git a/hosts/modules/common/openssh.nix b/hosts/modules/common/openssh.nix new file mode 100644 index 0000000..07108ce --- /dev/null +++ b/hosts/modules/common/openssh.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + services.openssh = { + enable = true; + settings.PermitRootLogin = "no"; + }; +} diff --git a/hosts/modules/common/programs.nix b/hosts/modules/common/programs.nix new file mode 100644 index 0000000..9820149 --- /dev/null +++ b/hosts/modules/common/programs.nix @@ -0,0 +1,29 @@ +{ lib, pkgs, ... }: + +{ + environment = { + systemPackages = with pkgs; [ + ### Dev Tools ### + git + ### System Utilities ### + btop + nixos-firewall-tool + nvd + sysz + tmux + wget + yazi + ]; + shellAliases = { + cat = "${lib.getExe pkgs.bat} --paging=never --style=plain"; + ls = "${lib.getExe pkgs.eza} --icons --group-directories-first"; + neofetch = "${lib.getExe pkgs.fastfetch}"; + tree = "ls --tree"; + }; + }; + + programs = { + command-not-found.enable = false; + fish.enable = true; + }; +} diff --git a/hosts/modules/common/security.nix b/hosts/modules/common/security.nix new file mode 100644 index 0000000..33d4953 --- /dev/null +++ b/hosts/modules/common/security.nix @@ -0,0 +1,13 @@ +{ ... }: + +{ + security = { + unprivilegedUsernsClone = true; # Needed for rootless podman + sudo = { + wheelNeedsPassword = false; + extraConfig = '' + Defaults lecture = never + ''; + }; + }; +} diff --git a/hosts/modules/common/services.nix b/hosts/modules/common/services.nix new file mode 100644 index 0000000..89ac527 --- /dev/null +++ b/hosts/modules/common/services.nix @@ -0,0 +1,9 @@ +{ ... }: + +{ + services = { + dbus.implementation = "broker"; + irqbalance.enable = true; + fstrim.enable = true; + }; +} diff --git a/hosts/modules/common/tailscale.nix b/hosts/modules/common/tailscale.nix new file mode 100644 index 0000000..98bea97 --- /dev/null +++ b/hosts/modules/common/tailscale.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + services.tailscale = { + enable = true; + extraUpFlags = [ "--operator=user" ]; + }; +} diff --git a/hosts/modules/common/users.nix b/hosts/modules/common/users.nix new file mode 100644 index 0000000..076eb99 --- /dev/null +++ b/hosts/modules/common/users.nix @@ -0,0 +1,29 @@ +{ pkgs, ... }: + +{ + users.users = { + user = { + isNormalUser = true; + shell = pkgs.fish; + extraGroups = [ + "networkmanager" + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" + ]; + hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0"; + }; + root = { + shell = pkgs.fish; + hashedPassword = "!"; + }; + }; + programs.fish = { + enable = true; + interactiveShellInit = '' + set fish_greeting + ''; + }; +} diff --git a/hosts/modules/console.nix b/hosts/modules/console.nix deleted file mode 100644 index 042976d..0000000 --- a/hosts/modules/console.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ hostType, lib, ... }: - -{ - config = lib.mkMerge [ - # Common configuration - { - console = { - useXkbConfig = true; - earlySetup = true; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - }) - ]; -} diff --git a/hosts/modules/default.nix b/hosts/modules/default.nix deleted file mode 100644 index 99cf017..0000000 --- a/hosts/modules/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ ... }: - -{ - imports = [ - ./boot.nix - ./console.nix - ./desktop.nix - ./ephermal.nix - ./impermanence.nix - ./locale.nix - ./networking.nix - ./nix.nix - ./programs.nix - ./security.nix - ./services.nix - ./users.nix - ./virtualisation.nix - ]; -} diff --git a/hosts/modules/desktop.nix b/hosts/modules/desktop.nix deleted file mode 100644 index ae297e3..0000000 --- a/hosts/modules/desktop.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - services = { - pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - wireplumber.enable = true; - }; - greetd.settings.initial_session = { - command = "niri"; - user = "user"; - }; - }; - - programs = { - dankMaterialShell.greeter = { - enable = true; - compositor.name = "niri"; - }; - niri.enable = true; - }; - - hardware = { - xpadneo.enable = true; - bluetooth.enable = true; - steam-hardware.enable = true; # Allow steam client to manage controllers - graphics.enable32Bit = true; # For OpenGL games - i2c.enable = true; - }; - - security.rtkit.enable = true; # Needed for pipewire to acquire realtime priority - - xdg.portal = { - enable = true; - xdgOpenUsePortal = true; - extraPortals = with pkgs; [ - kdePackages.xdg-desktop-portal-kde - xdg-desktop-portal-gtk - xdg-desktop-portal-gnome - ]; - }; - }) - ]; -} diff --git a/hosts/modules/desktop/boot.nix b/hosts/modules/desktop/boot.nix new file mode 100644 index 0000000..0ac4847 --- /dev/null +++ b/hosts/modules/desktop/boot.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: + +{ + boot = { + plymouth.enable = true; + initrd.systemd.enable = true; + loader.efi.efiSysMountPoint = "/boot/efi"; + kernelPackages = pkgs.linuxPackages_xanmod_latest; + extraModprobeConfig = '' + options bluetooth disable_ertm=1 + ''; + kernel.sysctl = { + "net.ipv4.tcp_mtu_probing" = 1; + }; + kernelParams = [ + "quiet" + "splash" + "i2c-dev" + "i2c-piix4" + "loglevel=3" + "udev.log_priority=3" + "rd.udev.log_level=3" + "rd.systemd.show_status=false" + ]; + }; +} diff --git a/hosts/modules/desktop/desktop.nix b/hosts/modules/desktop/desktop.nix new file mode 100644 index 0000000..4a42772 --- /dev/null +++ b/hosts/modules/desktop/desktop.nix @@ -0,0 +1,136 @@ +{ inputs, pkgs, ... }: + +let + kwrite = pkgs.symlinkJoin { + name = "kwrite"; + paths = [ pkgs.kdePackages.kate ]; + postBuild = '' + rm -rf $out/bin/kate \ + $out/bin/.kate-wrapped \ + $out/share/applications/org.kde.kate.desktop \ + $out/share/man \ + $out/share/icons/hicolor/*/apps/kate.png \ + $out/share/icons/hicolor/scalable/apps/kate.svg \ + $out/share/appdata/org.kde.kate.appdata.xml + ''; + }; +in +{ + imports = [ inputs.nix-flatpak.nixosModules.nix-flatpak ]; + + environment = { + sessionVariables = { + KDEHOME = "$XDG_CONFIG_HOME/kde4"; # Stops kde from placing a .kde4 folder in the home dir + NIXOS_OZONE_WL = "1"; # Forces chromium and most electron apps to run in wayland + }; + systemPackages = + with pkgs; + [ + ### Web ### + bitwarden-desktop + brave + tor-browser + qbittorrent + vesktop + ### Office & Productivity ### + aspell + aspellDicts.de + aspellDicts.en + aspellDicts.en-computers + aspellDicts.pt_BR + kwrite + libreoffice-qt + onlyoffice-desktopeditors + rnote + ### Graphics & Design ### + gimp + inkscape + plasticity + ### System Utilities ### + adwaita-icon-theme + colloid-gtk-theme + junction + kara + kde-rounded-corners + libfido2 + mission-center + p7zip + rclone + toggleaudiosink + unrar + ### Media ### + mpv + obs-studio + qview + ] + ++ (with pkgs.kdePackages; [ + ark + dolphin + dolphin-plugins + kolourpaint + ]); + }; + + services = { + pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber.enable = true; + }; + greetd = { + settings = { + default_session.command = ''${pkgs.greetd.tuigreet}/bin/tuigreet --remember --asterisks --time --greeting "Welcome to NixOS" --cmd ${plasma}/bin/plasma''; + initial_session.user = "user"; + }; + }; + flatpak = { + enable = true; + packages = [ + ### Internet Browsers & Communication ### + "app.zen_browser.zen" + ### Graphics & Design ### + "com.boxy_svg.BoxySVG" + rec { + appId = "io.github.softfever.OrcaSlicer"; + sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; + bundle = "${pkgs.fetchurl { + url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; + inherit sha256; + }}"; + } + ### System Utilities ### + "com.github.tchx84.Flatseal" + "com.rustdesk.RustDesk" + ]; + uninstallUnmanaged = true; + update.auto.enable = true; + }; + }; + security.rtkit.enable = true; # Needed for pipewire to acquire realtime priority + + programs = { + niri.enable = true; + dconf.enable = true; + kdeconnect.enable = true; + partition-manager.enable = true; + appimage = { + enable = true; + binfmt = true; + }; + }; + + fonts = { + fontDir.enable = true; + packages = with pkgs; [ + corefonts + inter + nerd-fonts.fira-code + noto-fonts-cjk-sans + noto-fonts-color-emoji + roboto + ]; + }; +} diff --git a/hosts/modules/desktop/nix.nix b/hosts/modules/desktop/nix.nix new file mode 100644 index 0000000..54a3549 --- /dev/null +++ b/hosts/modules/desktop/nix.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: + +{ + environment.etc."channels/nixpkgs".source = inputs.nixpkgs.outPath; + + nix = { + registry.nixpkgs.flake = inputs.nixpkgs; + nixPath = [ + "nixpkgs=${inputs.nixpkgs}" + "/nix/var/nix/profiles/per-user/root/channels" + ]; + }; +} diff --git a/hosts/modules/desktop/services.nix b/hosts/modules/desktop/services.nix new file mode 100644 index 0000000..66b78f1 --- /dev/null +++ b/hosts/modules/desktop/services.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: + +{ + services = { + printing.enable = true; + udev.packages = with pkgs; [ yubikey-personalization ]; + keyd = { + enable = true; + keyboards.all = { + ids = [ "*" ]; + settings.main.capslock = "overload(meta, esc)"; + }; + }; + }; +} diff --git a/hosts/modules/dev.nix b/hosts/modules/dev.nix new file mode 100644 index 0000000..82908f2 --- /dev/null +++ b/hosts/modules/dev.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + bat + claude-code + lazygit + fd + fzf + glow + nixfmt-rfc-style + nix-init + nix-output-monitor + ripgrep + ]; + + programs.adb.enable = true; + + users.users.user.extraGroups = [ "adbusers" ]; +} diff --git a/hosts/modules/environment.nix b/hosts/modules/environment.nix deleted file mode 100644 index a67ca90..0000000 --- a/hosts/modules/environment.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ pkgs, ... }: - -{ -} diff --git a/hosts/modules/ephermal.nix b/hosts/modules/ephermal.nix index ff22557..adaf5af 100644 --- a/hosts/modules/ephermal.nix +++ b/hosts/modules/ephermal.nix @@ -1,64 +1,72 @@ -{ - hostType, - lib, - ... -}: +{ inputs, ... }: { - config = lib.mkMerge [ - # Common configuration - { - } + imports = [ inputs.impermanence.nixosModules.impermanence ]; - # Server specific configuration - (lib.mkIf hostType.isServer { - }) + boot.initrd.systemd.services.recreate-root = { + description = "Rolling over and creating new filesystem root"; + requires = [ "initrd-root-device.target" ]; + after = [ + "local-fs-pre.target" + "initrd-root-device.target" + ]; + requiredBy = [ "initrd-root-fs.target" ]; + before = [ "sysroot.mount" ]; + unitConfig = { + AssertPathExists = "/etc/initrd-release"; + DefaultDependencies = false; + }; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir /btrfs_tmp + mount /dev/mapper/cryptroot /btrfs_tmp - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - boot.initrd.systemd.services.recreate-root = { - description = "Rolling over and creating new filesystem root"; - requires = [ "initrd-root-device.target" ]; - after = [ - "local-fs-pre.target" - "initrd-root-device.target" - ]; - requiredBy = [ "initrd-root-fs.target" ]; - before = [ "sysroot.mount" ]; - unitConfig = { - AssertPathExists = "/etc/initrd-release"; - DefaultDependencies = false; - }; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - mkdir /btrfs_tmp - mount /dev/mapper/cryptroot /btrfs_tmp + if [[ -e /btrfs_tmp/@root ]]; then + mkdir -p /btrfs_tmp/old_roots + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/@root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/@root "/btrfs_tmp/old_roots/$timestamp" + fi - if [[ -e /btrfs_tmp/@root ]]; then - mkdir -p /btrfs_tmp/old_roots - timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/@root)" "+%Y-%m-%-d_%H:%M:%S") - mv /btrfs_tmp/@root "/btrfs_tmp/old_roots/$timestamp" - fi + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } - delete_subvolume_recursively() { - IFS=$'\n' - for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do - delete_subvolume_recursively "/btrfs_tmp/$i" - done - btrfs subvolume delete "$1" - } + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do + delete_subvolume_recursively "$i" + done - for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do - delete_subvolume_recursively "$i" - done + btrfs subvolume create /btrfs_tmp/@root + umount /btrfs_tmp + ''; + }; - btrfs subvolume create /btrfs_tmp/@root - umount /btrfs_tmp - ''; - }; - }) - ]; + environment.persistence.main = { + persistentStoragePath = "/persistent"; + files = [ + "/etc/machine-id" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + directories = [ + "/etc/NetworkManager/system-connections" + "/etc/nixos" + "/var/lib/bluetooth" + "/var/lib/flatpak" + "/var/lib/lxd" + "/var/lib/nixos" + "/var/lib/systemd/coredump" + "/var/lib/systemd/timers" + "/var/lib/tailscale" + "/var/log" + ]; + }; } diff --git a/hosts/modules/fwupd.nix b/hosts/modules/fwupd.nix new file mode 100644 index 0000000..52dc13e --- /dev/null +++ b/hosts/modules/fwupd.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + services.fwupd.enable = true; +} diff --git a/hosts/modules/gaming.nix b/hosts/modules/gaming.nix new file mode 100644 index 0000000..cf6217f --- /dev/null +++ b/hosts/modules/gaming.nix @@ -0,0 +1,36 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + clonehero + heroic + mangohud + prismlauncher + protonup + steam-run + ]; + + programs = { + steam = { + enable = true; + extraCompatPackages = [ pkgs.proton-ge-bin ]; + }; + gamemode.enable = true; + }; + + hardware = { + xpadneo.enable = true; + steam-hardware.enable = true; # Allow steam client to manage controllers + graphics.enable32Bit = true; # For OpenGL games + }; + + services.flatpak.packages = [ + "com.github.k4zmu2a.spacecadetpinball" + "com.steamgriddb.SGDBoop" + "io.github.Foldex.AdwSteamGtk" + "io.itch.itch" + "io.mrarm.mcpelauncher" + "net.retrodeck.retrodeck" + "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/24.08" + ]; +} diff --git a/hosts/modules/impermanence.nix b/hosts/modules/impermanence.nix deleted file mode 100644 index 7ce822f..0000000 --- a/hosts/modules/impermanence.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ - hostType, - lib, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - environment.persistence.main = { - persistentStoragePath = "/persistent"; - files = [ - "/etc/machine-id" - "/etc/ssh/ssh_host_ed25519_key" - "/etc/ssh/ssh_host_ed25519_key.pub" - "/etc/ssh/ssh_host_rsa_key" - "/etc/ssh/ssh_host_rsa_key.pub" - ]; - directories = [ - "/etc/NetworkManager/system-connections" - "/etc/nixos" - "/var/lib/bluetooth" - "/var/lib/flatpak" - "/var/lib/lxd" - "/var/lib/nixos" - "/var/lib/systemd/coredump" - "/var/lib/systemd/timers" - "/var/lib/tailscale" - "/var/log" - ]; - }; - }) - ]; -} diff --git a/hosts/modules/io/default.nix b/hosts/modules/io/default.nix deleted file mode 100644 index fb244cc..0000000 --- a/hosts/modules/io/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: - -{ - imports = [ - ./boot.nix - ./disko.nix - ./hardware-configuration.nix - ./programs.nix - ./services.nix - ]; -} diff --git a/hosts/modules/libvirtd.nix b/hosts/modules/libvirtd.nix new file mode 100644 index 0000000..41cfa27 --- /dev/null +++ b/hosts/modules/libvirtd.nix @@ -0,0 +1,12 @@ +{ ... }: + +{ + virtualisation.libvirtd.enable = true; + + programs.virt-manager.enable = true; + + users.users.user.extraGroups = [ + "libvirt" + "libvirtd" + ]; +} diff --git a/hosts/modules/locale.nix b/hosts/modules/locale.nix deleted file mode 100644 index 44204d5..0000000 --- a/hosts/modules/locale.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ hostType, lib, ... }: - -{ - config = lib.mkMerge [ - # Common configuration - { - time.timeZone = "America/Bahia"; - - i18n = { - defaultLocale = "en_US.UTF-8"; - extraLocaleSettings = { - LC_ADDRESS = "pt_BR.utf8"; - LC_IDENTIFICATION = "pt_BR.utf8"; - LC_MEASUREMENT = "pt_BR.utf8"; - LC_MONETARY = "pt_BR.utf8"; - LC_NAME = "pt_BR.utf8"; - LC_NUMERIC = "pt_BR.utf8"; - LC_PAPER = "pt_BR.utf8"; - LC_TELEPHONE = "pt_BR.utf8"; - LC_TIME = "en_IE.utf8"; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - }) - ]; -} diff --git a/hosts/modules/networking.nix b/hosts/modules/networking.nix deleted file mode 100644 index d80f42e..0000000 --- a/hosts/modules/networking.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - hostType, - lib, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - networking = { - networkmanager.enable = true; - firewall.enable = true; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - services.tailscale = { - extraSetFlags = [ "--advertise-exit-node" ]; - useRoutingFeatures = "server"; - }; - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - }) - ]; -} diff --git a/hosts/modules/networkmanager.nix b/hosts/modules/networkmanager.nix new file mode 100644 index 0000000..7634116 --- /dev/null +++ b/hosts/modules/networkmanager.nix @@ -0,0 +1,10 @@ +{ ... }: + +{ + networking.networkmanager = { + enable = true; + wifi.backend = "iwd"; + }; + + users.users.user.extraGroups = [ "networkmanager" ]; +} diff --git a/hosts/modules/nix.nix b/hosts/modules/nix.nix deleted file mode 100644 index ddc3b5b..0000000 --- a/hosts/modules/nix.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - inputs, - lib, - hostType, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - nix = { - settings = { - auto-optimise-store = true; - connect-timeout = 10; - log-lines = 25; - min-free = 128000000; - max-free = 1000000000; - trusted-users = [ "@wheel" ]; - }; - extraOptions = "experimental-features = nix-command flakes"; - gc = { - automatic = true; - options = "--delete-older-than 8d"; - }; - }; - - nixpkgs.config = { - allowUnfree = true; - enableParallelBuilding = true; - buildManPages = false; - buildDocs = false; - }; - - system.stateVersion = "22.11"; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - environment.etc."channels/nixpkgs".source = inputs.nixpkgs-stable.outPath; - - nix = { - registry.nixpkgs.flake = inputs.nixpkgs-stable; - nixPath = [ - "nixpkgs=/etc/channels/nixpkgs" - "/nix/var/nix/profiles/per-user/root/channels" - ]; - }; - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - environment.etc."channels/nixpkgs".source = inputs.nixpkgs.outPath; - - nix = { - registry.nixpkgs.flake = inputs.nixpkgs; - nixPath = [ - "nixpkgs=${inputs.nixpkgs}" - "/nix/var/nix/profiles/per-user/root/channels" - ]; - }; - }) - ]; -} diff --git a/hosts/modules/podman.nix b/hosts/modules/podman.nix new file mode 100644 index 0000000..99018cc --- /dev/null +++ b/hosts/modules/podman.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: + +{ + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + extraPackages = [ pkgs.podman-compose ]; + }; + + systemd = { + services.podman-auto-update.enable = true; + timers.podman-auto-update.enable = true; + }; +} diff --git a/hosts/modules/programs.nix b/hosts/modules/programs.nix deleted file mode 100644 index 0252863..0000000 --- a/hosts/modules/programs.nix +++ /dev/null @@ -1,202 +0,0 @@ -{ - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - environment = { - systemPackages = with pkgs; [ - ### Dev Tools ### - agenix - git - ### System Utilities ### - btop - nixos-firewall-tool - nvd - sysz - tmux - wget - yazi - ]; - shellAliases = { - ls = "${pkgs.eza}/bin/eza --icons --group-directories-first"; - neofetch = "${pkgs.fastfetch}/bin/fastfetch"; - tree = "ls --tree"; - vi = "${pkgs.evil-helix}/bin/hx"; - vim = "${pkgs.evil-helix}/bin/hx"; - nvim = "${pkgs.evil-helix}/bin/hx"; - }; - }; - - programs = { - fish.enable = true; - command-not-found.enable = false; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation ( - let - kdepkgs = with pkgs.kdePackages; [ - ark - dolphin - dolphin-plugins - kolourpaint - ]; - kwrite = pkgs.symlinkJoin { - name = "kwrite"; - paths = [ pkgs.kdePackages.kate ]; - postBuild = '' - rm -rf $out/bin/kate \ - $out/bin/.kate-wrapped \ - $out/share/applications/org.kde.kate.desktop \ - $out/share/man \ - $out/share/icons/hicolor/*/apps/kate.png \ - $out/share/icons/hicolor/scalable/apps/kate.svg \ - $out/share/appdata/org.kde.kate.appdata.xml - ''; - }; - in - { - environment = { - systemPackages = - with pkgs; - [ - ### Dev Tools ### - bat - claude-code - lazygit - fd - fzf - glow - nixfmt-rfc-style - nix-init - nix-output-monitor - ripgrep - ### Web ### - bitwarden-desktop - brave - tor-browser - qbittorrent - vesktop - ### Office & Productivity ### - aspell - aspellDicts.de - aspellDicts.en - aspellDicts.en-computers - aspellDicts.pt_BR - kwrite - libreoffice-qt - obsidian - onlyoffice-desktopeditors - rnote - ### Graphics & Design ### - gimp - inkscape - plasticity - ### Gaming & Entertainment ### - clonehero - heroic - mangohud - prismlauncher - protonup - ### System Utilities ### - adwaita-icon-theme - colloid-gtk-theme - junction - kara - kde-rounded-corners - libfido2 - mission-center - p7zip - rclone - steam-run - toggleaudiosink - unrar - ### Media ### - mpv - obs-studio - qview - ] - ++ kdepkgs; - }; - - programs = { - adb.enable = true; - steam = { - enable = true; - extraCompatPackages = [ pkgs.proton-ge-bin ]; - }; - virt-manager.enable = true; - dconf.enable = true; - nix-ld.enable = true; - kdeconnect.enable = true; - partition-manager.enable = true; - gamemode.enable = true; - appimage = { - enable = true; - binfmt = true; - }; - nh = { - enable = true; - flake = "/home/user/Projects/personal/nix-config"; - }; - }; - - fonts = { - fontDir.enable = true; - packages = with pkgs; [ - corefonts - inter - nerd-fonts.fira-code - noto-fonts-cjk-sans - noto-fonts-color-emoji - roboto - ]; - }; - - services.flatpak = { - enable = true; - packages = [ - ### Dev Tools ### - ### Internet Browsers & Communication ### - "app.zen_browser.zen" - ### Office & Productivity ### - ### Graphics & Design ### - "com.boxy_svg.BoxySVG" - rec { - appId = "io.github.softfever.OrcaSlicer"; - sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; - bundle = "${pkgs.fetchurl { - url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; - inherit sha256; - }}"; - } - ### Gaming & Entertainment ### - "com.github.k4zmu2a.spacecadetpinball" - "io.itch.itch" - "io.mrarm.mcpelauncher" - "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/24.08" - ### System Utilities ### - "com.github.tchx84.Flatseal" - "com.rustdesk.RustDesk" - "com.steamgriddb.SGDBoop" - "io.github.Foldex.AdwSteamGtk" - ### Media ### - ]; - uninstallUnmanaged = true; - update.auto.enable = true; - }; - } - )) - ]; -} diff --git a/hosts/modules/rotterdam/default.nix b/hosts/modules/rotterdam/default.nix deleted file mode 100644 index 0bc2cc8..0000000 --- a/hosts/modules/rotterdam/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: - -{ - imports = [ - ./boot.nix - ./hardware-configuration.nix - ./hardware.nix - ./programs.nix - ./services.nix - ]; -} diff --git a/hosts/modules/security.nix b/hosts/modules/security.nix deleted file mode 100644 index 5cb1786..0000000 --- a/hosts/modules/security.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ hostType, lib, ... }: - -{ - config = lib.mkMerge [ - # Common configuration - { - security = { - unprivilegedUsernsClone = true; # Needed for rootless podman - sudo = { - wheelNeedsPassword = false; - extraConfig = '' - Defaults lecture = never - ''; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - }) - ]; -} diff --git a/hosts/modules/server/boot.nix b/hosts/modules/server/boot.nix new file mode 100644 index 0000000..5d6e482 --- /dev/null +++ b/hosts/modules/server/boot.nix @@ -0,0 +1,5 @@ +{ pkgs, ... }: + +{ + boot.kernelPackages = pkgs.linuxPackages_hardened; +} diff --git a/hosts/modules/server/nix.nix b/hosts/modules/server/nix.nix new file mode 100644 index 0000000..af57cae --- /dev/null +++ b/hosts/modules/server/nix.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: + +{ + environment.etc."channels/nixpkgs".source = inputs.nixpkgs-stable.outPath; + + nix = { + registry.nixpkgs.flake = inputs.nixpkgs-stable; + nixPath = [ + "nixpkgs=/etc/channels/nixpkgs" + "/nix/var/nix/profiles/per-user/root/channels" + ]; + }; +} diff --git a/hosts/modules/server/tailscale.nix b/hosts/modules/server/tailscale.nix new file mode 100644 index 0000000..1f105ba --- /dev/null +++ b/hosts/modules/server/tailscale.nix @@ -0,0 +1,13 @@ +{ ... }: + +{ + services.tailscale = { + extraSetFlags = [ "--advertise-exit-node" ]; + useRoutingFeatures = "server"; + }; + + boot.kernel.sysctl = { + "net.ipv4.ip_forward" = 1; + "net.ipv6.conf.all.forwarding" = 1; + }; +} diff --git a/hosts/modules/services.nix b/hosts/modules/services.nix deleted file mode 100644 index 351e091..0000000 --- a/hosts/modules/services.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - services = { - tailscale = { - enable = true; - extraUpFlags = [ "--operator=user" ]; - }; - openssh = { - enable = true; - settings.PermitRootLogin = "no"; - }; - nixos-cli = { - enable = true; - config = { - use_nvd = true; - ignore_dirty_tree = true; - }; - }; - fwupd.enable = true; - fstrim.enable = true; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - services = { - printing.enable = true; - udev.packages = with pkgs; [ yubikey-personalization ]; - keyd = { - enable = true; - keyboards.all = { - ids = [ "*" ]; - settings.main.capslock = "overload(meta, esc)"; - }; - }; - }; - }) - ]; -} diff --git a/hosts/modules/stylix.nix b/hosts/modules/stylix.nix deleted file mode 100644 index b0345f2..0000000 --- a/hosts/modules/stylix.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - config, - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - stylix = { - enable = true; - polarity = "dark"; - base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-mocha.yaml"; - cursor = { - package = pkgs.kdePackages.breeze-icons; - name = "Breeze_Light"; - size = 24; - }; - opacity = { - applications = 1.0; - desktop = 0.8; - popups = config.stylix.opacity.desktop; - terminal = 1.0; - }; - fonts = { - serif = { - package = pkgs.source-serif; - name = "Source Serif 4 Display"; - }; - sansSerif = { - package = pkgs.inter; - name = "Inter"; - }; - monospace = { - package = pkgs.nerd-fonts.fira-code; - name = "FiraCode Nerd Font"; - }; - emoji = { - package = pkgs.noto-fonts-emoji; - name = "Noto Color Emoji"; - }; - sizes = { - applications = 11; - desktop = config.stylix.fonts.sizes.applications; - popups = config.stylix.fonts.sizes.applications; - terminal = 12; - }; - }; - }; - }) - ]; -} diff --git a/hosts/modules/trantor/default.nix b/hosts/modules/trantor/default.nix deleted file mode 100644 index 9bdb292..0000000 --- a/hosts/modules/trantor/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ ... }: - -{ - imports = [ - ./boot.nix - ./disko.nix - ./hardware-configuration.nix - ./networking.nix - ]; -} diff --git a/hosts/modules/users.nix b/hosts/modules/users.nix deleted file mode 100644 index 68ac26a..0000000 --- a/hosts/modules/users.nix +++ /dev/null @@ -1,81 +0,0 @@ -{ - hostType, - inputs, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - users.users = { - user = { - isNormalUser = true; - shell = pkgs.fish; - extraGroups = [ - "networkmanager" - "wheel" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" - ]; - hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0"; - }; - root = { - shell = pkgs.fish; - hashedPassword = "!"; - }; - }; - - home-manager = { - useGlobalPkgs = true; - useUserPackages = true; - backupFileExtension = "bkp"; - users = { - user = import ../../users/user.nix; - root = import ../../users/root.nix; - }; - extraSpecialArgs = { - inherit hostType; - inherit inputs; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - environment.sessionVariables = { - KDEHOME = "$XDG_CONFIG_HOME/kde4"; # Stops kde from placing a .kde4 folder in the home dir - NIXOS_OZONE_WL = "1"; # Forces chromium and most electron apps to run in wayland - }; - - users.users = { - user = { - description = "William"; - uid = 1000; - extraGroups = [ - "uaccess" # Needed for HID dev - "dialout" # Needed for arduino dev - "libvirt" - "libvirtd" - "adbusers" - "i2c" - ]; - }; - ewans = { - description = "Ewans"; - isNormalUser = true; - uid = 1001; - hashedPassword = "$y$j9T$yHLUDvj6bDIP19dchU.aA/$OY4qeFNtx/GvI.VUYx4LapHiiVwi0MEvs8AT0HN7j58"; - }; - }; - }) - ]; -} diff --git a/hosts/modules/virtualisation.nix b/hosts/modules/virtualisation.nix deleted file mode 100644 index e55a267..0000000 --- a/hosts/modules/virtualisation.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - virtualisation.podman = { - enable = true; - dockerCompat = true; - autoPrune.enable = true; - extraPackages = [ pkgs.podman-compose ]; - }; - - systemd = { - services.podman-auto-update.enable = true; - timers.podman-auto-update.enable = true; - }; - - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - virtualisation = { - libvirtd.enable = true; - }; - }) - ]; -} diff --git a/hosts/rotterdam.nix b/hosts/rotterdam.nix deleted file mode 100644 index ad95919..0000000 --- a/hosts/rotterdam.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: - -{ - networking.hostName = "rotterdam"; - - imports = [ - ./modules/rotterdam - ./modules - ]; - - nix.nixPath = [ "nixos-config=${./rotterdam.nix}" ]; -} diff --git a/hosts/modules/rotterdam/boot.nix b/hosts/rotterdam/boot.nix similarity index 100% rename from hosts/modules/rotterdam/boot.nix rename to hosts/rotterdam/boot.nix diff --git a/hosts/modules/rotterdam/hardware-configuration.nix b/hosts/rotterdam/hardware-configuration.nix similarity index 100% rename from hosts/modules/rotterdam/hardware-configuration.nix rename to hosts/rotterdam/hardware-configuration.nix diff --git a/hosts/modules/rotterdam/hardware.nix b/hosts/rotterdam/hardware.nix similarity index 100% rename from hosts/modules/rotterdam/hardware.nix rename to hosts/rotterdam/hardware.nix diff --git a/hosts/modules/rotterdam/programs.nix b/hosts/rotterdam/programs.nix similarity index 94% rename from hosts/modules/rotterdam/programs.nix rename to hosts/rotterdam/programs.nix index 9f624a1..b4dcfd9 100644 --- a/hosts/modules/rotterdam/programs.nix +++ b/hosts/rotterdam/programs.nix @@ -27,7 +27,5 @@ in { environment.systemPackages = [ reboot-into-qubes ]; - services.flatpak.packages = [ "net.retrodeck.retrodeck" ]; - programs.steam.dedicatedServer.openFirewall = true; } diff --git a/hosts/modules/rotterdam/services.nix b/hosts/rotterdam/services.nix similarity index 100% rename from hosts/modules/rotterdam/services.nix rename to hosts/rotterdam/services.nix diff --git a/hosts/trantor.nix b/hosts/trantor.nix deleted file mode 100644 index 4a02556..0000000 --- a/hosts/trantor.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ ... }: - -{ - networking.hostName = "trantor"; - - imports = [ - ./modules/trantor - ./modules - ]; - - nix.nixPath = [ "nixos-config=${./trantor.nix}" ]; -} - diff --git a/hosts/modules/trantor/boot.nix b/hosts/trantor/boot.nix similarity index 68% rename from hosts/modules/trantor/boot.nix rename to hosts/trantor/boot.nix index b724550..a031ce9 100644 --- a/hosts/modules/trantor/boot.nix +++ b/hosts/trantor/boot.nix @@ -2,6 +2,5 @@ boot = { loader.efi.efiSysMountPoint = "/boot"; initrd.systemd.enable = true; - kernel.sysctl."net.ipv4.ip_forward" = 1; }; } diff --git a/hosts/modules/trantor/disko.nix b/hosts/trantor/disko.nix similarity index 91% rename from hosts/modules/trantor/disko.nix rename to hosts/trantor/disko.nix index a535e47..a70383e 100644 --- a/hosts/modules/trantor/disko.nix +++ b/hosts/trantor/disko.nix @@ -1,6 +1,8 @@ -{ ... }: +{ inputs, ... }: { + imports = [ inputs.disko.nixosModules.default ]; + disko.devices = { disk = { main = { diff --git a/hosts/modules/trantor/hardware-configuration.nix b/hosts/trantor/hardware-configuration.nix similarity index 100% rename from hosts/modules/trantor/hardware-configuration.nix rename to hosts/trantor/hardware-configuration.nix diff --git a/hosts/modules/trantor/networking.nix b/hosts/trantor/networking.nix similarity index 100% rename from hosts/modules/trantor/networking.nix rename to hosts/trantor/networking.nix diff --git a/modules/qbittorrent.nix b/modules/qbittorrent.nix deleted file mode 100644 index a496c54..0000000 --- a/modules/qbittorrent.nix +++ /dev/null @@ -1,123 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -with lib; -let - cfg = config.services.qbittorrent; - configDir = "${cfg.dataDir}/.config"; - openFilesLimit = 4096; -in -{ - options.services.qbittorrent = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Run qBittorrent headlessly as systemwide daemon - ''; - }; - - dataDir = mkOption { - type = types.path; - default = "/var/lib/qbittorrent"; - description = '' - The directory where qBittorrent will create files. - ''; - }; - - user = mkOption { - type = types.str; - default = "qbittorrent"; - description = '' - User account under which qBittorrent runs. - ''; - }; - - group = mkOption { - type = types.str; - default = "qbittorrent"; - description = '' - Group under which qBittorrent runs. - ''; - }; - - port = mkOption { - type = types.port; - default = 8080; - description = '' - qBittorrent web UI port. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open services.qBittorrent.port to the outside network. - ''; - }; - - openFilesLimit = mkOption { - default = openFilesLimit; - description = '' - Number of files to allow qBittorrent to open. - ''; - }; - }; - - config = mkIf cfg.enable { - - environment.systemPackages = [ pkgs.qbittorrent ]; - - nixpkgs.overlays = [ - (final: prev: { - qbittorrent = prev.qbittorrent.override { guiSupport = false; }; - }) - ]; - - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.port ]; - allowedUDPPorts = [ cfg.port ]; - }; - - systemd.services.qbittorrent = { - after = [ "network.target" ]; - description = "qBittorrent Daemon"; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.qbittorrent ]; - serviceConfig = { - ExecStart = '' - ${pkgs.qbittorrent}/bin/qbittorrent-nox \ - --profile=${configDir} \ - --webui-port=${toString cfg.port} - ''; - # To prevent "Quit & shutdown daemon" from working; we want systemd to - # manage it! - Restart = "on-success"; - User = cfg.user; - Group = cfg.group; - UMask = "0002"; - LimitNOFILE = cfg.openFilesLimit; - }; - }; - - users.users = mkIf (cfg.user == "qbittorrent") { - qbittorrent = { - inherit group; - home = cfg.dataDir; - createHome = true; - description = "qBittorrent Daemon user"; - }; - }; - - users.groups = mkIf (cfg.group == "qbittorrent") { - qbittorrent = { - gid = null; - }; - }; - }; -} diff --git a/nixosConfigurations.nix b/nixosConfigurations.nix new file mode 100644 index 0000000..65a9e14 --- /dev/null +++ b/nixosConfigurations.nix @@ -0,0 +1,50 @@ +{ inputs, ... }: +let + utils = import ./utils.nix { inherit inputs; }; + inherit (utils) mkHost; +in +{ + flake.nixosConfigurations = { + rotterdam = mkHost { + hostname = "rotterdam"; + tags = [ + "desktop" + "bluetooth" + "dev" + "ephermal" + "fwupd" + "gaming" + "libvirtd" + "networkmanager" + "podman" + ]; + }; + + io = mkHost { + hostname = "io"; + tags = [ + "desktop" + "bluetooth" + "dev" + "ephermal" + "networkmanager" + "podman" + ]; + }; + + alexandria = mkHost { + hostname = "alexandria"; + tags = [ + "fwupd" + "podman" + ]; + }; + + trantor = mkHost { + hostname = "trantor"; + system = "aarch64-linux"; + tags = [ + ]; + }; + }; +} diff --git a/overlays.nix b/overlays.nix new file mode 100644 index 0000000..3bc87b1 --- /dev/null +++ b/overlays.nix @@ -0,0 +1,10 @@ +{ inputs, ... }: + +{ + flake.overlays = { + default = final: prev: { + # plasticity = inputs.self.packages.${final.system}.plasticity; + toggleaudiosink = inputs.self.packages.${final.system}.toggleaudiosink; + }; + }; +} diff --git a/packages.nix b/packages.nix new file mode 100644 index 0000000..4ae6a5e --- /dev/null +++ b/packages.nix @@ -0,0 +1,11 @@ +{ ... }: + +{ + perSystem = + { pkgs, system, ... }: + { + packages = { + toggleaudiosink = pkgs.callPackage ./packages/toggleaudiosink.nix { }; + }; + }; +} diff --git a/packages/plasticity.nix b/packages/plasticity.nix deleted file mode 100644 index 4325e5f..0000000 --- a/packages/plasticity.nix +++ /dev/null @@ -1,122 +0,0 @@ -{ - alsa-lib, - at-spi2-atk, - autoPatchelfHook, - cairo, - cups, - dbus, - desktop-file-utils, - expat, - fetchurl, - gdk-pixbuf, - gtk3, - gvfs, - hicolor-icon-theme, - lib, - libdrm, - libglvnd, - libnotify, - libsForQt5, - libxkbcommon, - libgbm, - nspr, - nss, - openssl, - pango, - rpmextract, - stdenv, - systemd, - trash-cli, - vulkan-loader, - wrapGAppsHook3, - xdg-utils, - xorg, -}: -stdenv.mkDerivation rec { - pname = "plasticity"; - version = "25.1.8"; - - src = fetchurl { - url = "https://github.com/nkallen/plasticity/releases/download/v${version}/Plasticity-${version}-1.x86_64.rpm"; - hash = "sha256-5PjjEsHchryUhmzqyQ4XqwiycNEVCefmpSW/9jZEzpg="; - }; - - nativeBuildInputs = [ - wrapGAppsHook3 - autoPatchelfHook - rpmextract - libgbm - ]; - - buildInputs = [ - alsa-lib - at-spi2-atk - cairo - cups - dbus - desktop-file-utils - expat - gdk-pixbuf - gtk3 - gvfs - hicolor-icon-theme - libdrm - libnotify - libsForQt5.kde-cli-tools - libxkbcommon - nspr - nss - openssl - pango - (lib.getLib stdenv.cc.cc) - trash-cli - xdg-utils - ]; - - runtimeDependencies = [ - systemd - libglvnd - vulkan-loader # may help with nvidia users - xorg.libX11 - xorg.libxcb - xorg.libXcomposite - xorg.libXdamage - xorg.libXext - xorg.libXfixes - xorg.libXrandr - xorg.libXtst - ]; - - dontUnpack = true; - - # can't find anything on the internet about these files, no clue what they do - autoPatchelfIgnoreMissingDeps = [ - "ACCAMERA.tx" - "AcMPolygonObj15.tx" - "ATEXT.tx" - "ISM.tx" - "RText.tx" - "SCENEOE.tx" - "TD_DbEntities.tx" - "TD_DbIO.tx" - "WipeOut.tx" - ]; - - installPhase = '' - runHook preInstall - - mkdir $out - cd $out - rpmextract $src - mv $out/usr/* $out - rm -r $out/usr - rm -r $out/lib/.build-id - - runHook postInstall - ''; - - #--use-gl=egl for it to use hardware rendering it seems. Otherwise there are terrible framerates - preFixup = '' - gappsWrapperArgs+=(--add-flags "--use-gl=egl") - ''; -} diff --git a/users/modules/btop.nix b/users/modules/btop.nix new file mode 100644 index 0000000..c19c4bb --- /dev/null +++ b/users/modules/btop.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: + +{ + programs.btop = { + enable = true; + settings = { + theme_background = false; + proc_sorting = "cpu direct"; + update_ms = 500; + }; + }; +} \ No newline at end of file diff --git a/users/modules/common/bash.nix b/users/modules/common/bash.nix new file mode 100644 index 0000000..a5a0823 --- /dev/null +++ b/users/modules/common/bash.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: + +{ + programs.bash = { + enable = true; + historyFile = "~/.cache/bash_history"; + }; +} \ No newline at end of file diff --git a/users/modules/common/fish.nix b/users/modules/common/fish.nix new file mode 100644 index 0000000..8de52c3 --- /dev/null +++ b/users/modules/common/fish.nix @@ -0,0 +1,38 @@ +{ pkgs, lib, ... }: + +{ + programs.fish = { + enable = true; + interactiveShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source"; + loginShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source"; + plugins = [ + { + name = "bang-bang"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "plugin-bang-bang"; + rev = "f969c618301163273d0a03d002614d9a81952c1e"; + sha256 = "sha256-A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; + }; + } + { + name = "sponge"; + src = pkgs.fetchFromGitHub { + owner = "meaningful-ooo"; + repo = "sponge"; + rev = "384299545104d5256648cee9d8b117aaa9a6d7be"; + sha256 = "sha256-MdcZUDRtNJdiyo2l9o5ma7nAX84xEJbGFhAVhK+Zm1w="; + }; + } + { + name = "z"; + src = pkgs.fetchFromGitHub { + owner = "jethrokuan"; + repo = "z"; + rev = "85f863f20f24faf675827fb00f3a4e15c7838d76"; + sha256 = "sha256-+FUBM7CodtZrYKqU542fQD+ZDGrd2438trKM0tIESs0="; + }; + } + ]; + }; +} \ No newline at end of file diff --git a/users/modules/default.nix b/users/modules/default.nix deleted file mode 100644 index 5ef9e0a..0000000 --- a/users/modules/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ ... }: - -{ - imports = [ - ./programs.nix - ]; -} diff --git a/users/modules/desktop.nix b/users/modules/desktop.nix new file mode 100644 index 0000000..d98edc9 --- /dev/null +++ b/users/modules/desktop.nix @@ -0,0 +1,55 @@ +{ inputs, pkgs, ... }: + +{ + imports = [ inputs.dms.homeModules.dankMaterialShell.default ]; + + fonts.fontconfig.enable = true; + + programs = { + dankMaterialShell = { + enable = true; + enableVPN = false; + }; + +rio = { + enable = true; + settings = { + theme = "catppuccin-mocha"; + fonts = { + family = "FiraCode Nerd Font"; + size = 16.0; + emoji.family = "Noto Color Emoji"; + }; + confirm-before-quit = false; + window = { + width = 1121; + height = 633; + }; + }; + + password-store = { + enable = true; + package = pkgs.pass-wayland; + }; + }; + + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + extraPortals = with pkgs; [ + kdePackages.xdg-desktop-portal-kde + xdg-desktop-portal-gtk + xdg-desktop-portal-gnome + ]; + }; + + gtk = { + enable = true; + gtk3.extraConfig = { + gtk-decoration-layout = "appmenu:"; + }; + gtk4.extraConfig = { + gtk-decoration-layout = "appmenu:"; + }; + }; +} diff --git a/users/modules/direnv.nix b/users/modules/direnv.nix new file mode 100644 index 0000000..c91d0af --- /dev/null +++ b/users/modules/direnv.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: + +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; +} \ No newline at end of file diff --git a/users/modules/gaming.nix b/users/modules/gaming.nix new file mode 100644 index 0000000..df33b11 --- /dev/null +++ b/users/modules/gaming.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + programs.mangohud.enable = true; +} diff --git a/users/modules/helix.nix b/users/modules/helix.nix new file mode 100644 index 0000000..b71799b --- /dev/null +++ b/users/modules/helix.nix @@ -0,0 +1,50 @@ +{ pkgs, ... }: + +{ + home.sessionVariables = { + EDITOR = "hx"; + }; + + programs.helix = { + enable = true; + settings = { + theme = "base16_transparent"; + editor = { + file-picker.hidden = false; + idle-timeout = 0; + line-number = "relative"; + cursor-shape = { + normal = "block"; + insert = "bar"; + select = "underline"; + }; + soft-wrap.enable = true; + auto-format = true; + indent-guides.render = true; + }; + keys.normal = { + space = { + o = "file_picker_in_current_buffer_directory"; + esc = [ + "collapse_selection" + "keep_primary_selection" + ]; + }; + }; + }; + languages = { + language = [ + { + name = "nix"; + auto-format = true; + formatter.command = "nixfmt"; + } + { + name = "typst"; + auto-format = true; + formatter.command = "typstyle -c 1000 -i"; + } + ]; + }; + }; +} \ No newline at end of file diff --git a/users/modules/obs-studio.nix b/users/modules/obs-studio.nix new file mode 100644 index 0000000..da268c5 --- /dev/null +++ b/users/modules/obs-studio.nix @@ -0,0 +1,13 @@ +{ ... }: + +{ + programs.obs-studio = { + enable = true; + plugins = [ + pkgs.obs-studio-plugins.obs-vkcapture + pkgs.obs-studio-plugins.obs-backgroundremoval + pkgs.obs-studio-plugins.obs-pipewire-audio-capture + ]; + }; + +} diff --git a/users/modules/programs.nix b/users/modules/programs.nix deleted file mode 100644 index 8420dce..0000000 --- a/users/modules/programs.nix +++ /dev/null @@ -1,114 +0,0 @@ -{ - config, - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - home = { - sessionVariables = { - EDITOR = "hx"; - }; - }; - - programs = { - bash = { - enable = true; - historyFile = "~/.cache/bash_history"; - }; - - helix = { - enable = true; - settings = { - theme = "base16_transparent"; - editor = { - file-picker.hidden = false; - idle-timeout = 0; - line-number = "relative"; - cursor-shape = { - normal = "block"; - insert = "bar"; - select = "underline"; - }; - soft-wrap.enable = true; - auto-format = true; - indent-guides.render = true; - }; - keys.normal = { - space = { - o = "file_picker_in_current_buffer_directory"; - esc = [ - "collapse_selection" - "keep_primary_selection" - ]; - }; - }; - }; - }; - - fish = { - enable = true; - functions.fish_greeting = ""; - plugins = [ - { - name = "bang-bang"; - src = pkgs.fetchFromGitHub { - owner = "oh-my-fish"; - repo = "plugin-bang-bang"; - rev = "f969c618301163273d0a03d002614d9a81952c1e"; - sha256 = "sha256-A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; - }; - } - { - name = "sponge"; - src = pkgs.fetchFromGitHub { - owner = "meaningful-ooo"; - repo = "sponge"; - rev = "384299545104d5256648cee9d8b117aaa9a6d7be"; - sha256 = "sha256-MdcZUDRtNJdiyo2l9o5ma7nAX84xEJbGFhAVhK+Zm1w="; - }; - } - { - name = "z"; - src = pkgs.fetchFromGitHub { - owner = "jethrokuan"; - repo = "z"; - rev = "85f863f20f24faf675827fb00f3a4e15c7838d76"; - sha256 = "sha256-+FUBM7CodtZrYKqU542fQD+ZDGrd2438trKM0tIESs0="; - }; - } - ]; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - programs.rio = { - enable = true; - settings = { - theme = "catppuccin-mocha"; - fonts = { - family = "FiraCode Nerd Font"; - size = 16.0; - emoji.family = "Noto Color Emoji"; - }; - confirm-before-quit = false; - window = { - width = 1121; - height = 633; - }; - }; - }; - }) - ]; -} diff --git a/users/modules/root/default.nix b/users/modules/root/default.nix deleted file mode 100644 index adc92a0..0000000 --- a/users/modules/root/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ ... }: - -{ - imports = [ ]; -} diff --git a/users/modules/starship.nix b/users/modules/starship.nix new file mode 100644 index 0000000..8b9a14c --- /dev/null +++ b/users/modules/starship.nix @@ -0,0 +1,40 @@ +{ pkgs, ... }: + +{ + programs.starship = { + enable = true; + enableBashIntegration = true; + enableFishIntegration = true; + settings = { + add_newline = false; + format = '' + $hostname$directory$git_branch$git_status$nix_shell + [ ❯ ](bold green) + ''; + right_format = "$cmd_duration$character"; + hostname = { + ssh_symbol = " "; + }; + character = { + error_symbol = "[](red)"; + success_symbol = "[󱐋](green)"; + }; + cmd_duration = { + format = "[󰄉 $duration ]($style)"; + style = "yellow"; + min_time = 500; + }; + git_branch = { + symbol = " "; + style = "purple"; + }; + git_status.style = "red"; + nix_shell = { + format = "via [$symbol$state]($style)"; + heuristic = true; + style = "blue"; + symbol = "󱄅 "; + }; + }; + }; +} \ No newline at end of file diff --git a/users/modules/tmux.nix b/users/modules/tmux.nix new file mode 100644 index 0000000..4268e7a --- /dev/null +++ b/users/modules/tmux.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: + +{ + programs.tmux = { + enable = true; + clock24 = true; + terminal = "xterm-256color"; + mouse = true; + keyMode = "vi"; + }; +} \ No newline at end of file diff --git a/users/modules/user/default.nix b/users/modules/user/default.nix deleted file mode 100644 index 660553d..0000000 --- a/users/modules/user/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ ... }: - -{ - imports = [ - ./programs.nix - ./home.nix - ]; -} diff --git a/users/modules/user/home.nix b/users/modules/user/home.nix deleted file mode 100644 index 38311a6..0000000 --- a/users/modules/user/home.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - gtk = { - enable = true; - gtk3.extraConfig = { - gtk-decoration-layout = "appmenu:"; - }; - gtk4.extraConfig = { - gtk-decoration-layout = "appmenu:"; - }; - }; -} diff --git a/users/modules/user/programs.nix b/users/modules/user/programs.nix deleted file mode 100644 index 4cebeda..0000000 --- a/users/modules/user/programs.nix +++ /dev/null @@ -1,147 +0,0 @@ -{ - config, - hostType, - lib, - pkgs, - ... -}: - -{ - config = lib.mkMerge [ - # Common configuration - { - home = { - packages = with pkgs; [ nix-your-shell ]; - }; - - programs = { - helix.languages = { - language = [ - { - name = "nix"; - auto-format = true; - formatter.command = "nixfmt"; - } - { - name = "typst"; - auto-format = true; - formatter.command = "typstyle -c 1000 -i"; - } - ]; - }; - - password-store.enable = true; - - direnv = { - enable = true; - nix-direnv.enable = true; - }; - - fish = { - interactiveShellInit = "nix-your-shell fish | source"; - loginShellInit = "nix-your-shell fish | source"; - }; - - tmux = { - enable = true; - clock24 = true; - terminal = "xterm-256color"; - mouse = true; - keyMode = "vi"; - }; - - starship = { - enable = true; - enableBashIntegration = true; - enableFishIntegration = true; - settings = { - add_newline = false; - format = '' - $hostname$directory$git_branch$git_status$nix_shell - [ ❯ ](bold green) - ''; - right_format = "$cmd_duration$character"; - hostname = { - ssh_symbol = " "; - }; - character = { - error_symbol = "[](red)"; - success_symbol = "[󱐋](green)"; - }; - cmd_duration = { - format = "[󰄉 $duration ]($style)"; - style = "yellow"; - min_time = 500; - }; - git_branch = { - symbol = " "; - style = "purple"; - }; - git_status.style = "red"; - nix_shell = { - format = "via [$symbol$state]($style)"; - heuristic = true; - style = "blue"; - symbol = "󱄅 "; - }; - }; - }; - - git = { - enable = true; - diff-so-fancy.enable = true; - userName = "William"; - userEmail = "baduhai@proton.me"; - }; - - btop = { - enable = true; - settings = { - theme_background = false; - proc_sorting = "cpu direct"; - update_ms = 500; - }; - }; - }; - } - - # Server specific configuration - (lib.mkIf hostType.isServer { - - }) - - # Workstation specific configuration - (lib.mkIf hostType.isWorkstation { - fonts.fontconfig.enable = true; - - programs = { - dankMaterialShell = { - enable = true; - enableVPN = false; - }; - password-store.package = pkgs.pass-wayland; - - mangohud.enable = true; - - obs-studio = { - enable = true; - plugins = [ - pkgs.obs-studio-plugins.obs-vkcapture - pkgs.obs-studio-plugins.obs-backgroundremoval - pkgs.obs-studio-plugins.obs-pipewire-audio-capture - ]; - }; - }; - - xdg.portal = { - enable = true; - xdgOpenUsePortal = true; - extraPortals = with pkgs; [ - kdePackages.xdg-desktop-portal-kde - xdg-desktop-portal-gtk - xdg-desktop-portal-gnome - ]; - }; - }) - ]; -} diff --git a/users/root.nix b/users/root.nix deleted file mode 100644 index be5e00b..0000000 --- a/users/root.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ ... }: - -{ - home = { - username = "root"; - homeDirectory = "/root"; - stateVersion = "22.05"; - }; - - imports = [ - ./modules - ./modules/root - ]; -} diff --git a/users/user.nix b/users/user.nix deleted file mode 100644 index a5832cc..0000000 --- a/users/user.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ inputs, ... }: - -{ - home = { - username = "user"; - homeDirectory = "/home/user"; - stateVersion = "22.05"; - }; - - imports = [ - ./modules - ./modules/user - inputs.dms.homeModules.dankMaterialShell.default - ]; -} diff --git a/users/user/git.nix b/users/user/git.nix new file mode 100644 index 0000000..fcafc00 --- /dev/null +++ b/users/user/git.nix @@ -0,0 +1,10 @@ +{ pkgs, ... }: + +{ + programs.git = { + enable = true; + diff-so-fancy.enable = true; + userName = "William"; + userEmail = "baduhai@proton.me"; + }; +} \ No newline at end of file diff --git a/utils.nix b/utils.nix new file mode 100644 index 0000000..23f92d0 --- /dev/null +++ b/utils.nix @@ -0,0 +1,171 @@ +{ inputs }: +let + inherit (inputs) + self + nixpkgs + nixpkgs-stable + home-manager + agenix + ; +in +{ + # Tag-based host configuration system + mkHost = + { + hostname, + tags ? [ ], + system ? "x86_64-linux", + extraModules ? [ ], + }: + let + # Validate that server and desktop tags are mutually exclusive + hasServer = builtins.elem "server" tags; + hasDesktop = builtins.elem "desktop" tags; + + # Always include "common" tag implicitly + allTags = + if hasServer && hasDesktop then + throw "Error: 'server' and 'desktop' tags are mutually exclusive for host '${hostname}'" + else + [ "common" ] ++ tags; + + # Choose nixpkgs based on server tag + pkgs = if builtins.elem "server" allTags then nixpkgs-stable else nixpkgs; + + # Tag-specific modules: each tag can be either: + # 1. A file: hosts/modules/${tag}.nix + # 2. A directory: hosts/modules/${tag}/*.nix (all .nix files imported) + tagModuleFiles = builtins.concatMap ( + tag: + let + filePath = ./hosts/modules/${tag}.nix; + dirPath = ./hosts/modules/${tag}; + in + # Check if it's a file first + if builtins.pathExists filePath then + [ filePath ] + # Then check if it's a directory + else if builtins.pathExists dirPath then + let + entries = builtins.readDir dirPath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: dirPath + "/${name}") (builtins.attrNames nixFiles) + else + [ ] + ) allTags; + + # Automatically import all .nix files from hosts/${hostname}/ + hostModulePath = ./hosts/${hostname}; + hostModuleFiles = + if builtins.pathExists hostModulePath then + let + entries = builtins.readDir hostModulePath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name && name != "${hostname}.nix" + ) entries; + in + map (name: hostModulePath + "/${name}") (builtins.attrNames nixFiles) + else + [ ]; + + # Combine all modules + allModules = [ + agenix.nixosModules.default + { + networking.hostName = hostname; + nix.nixPath = [ "nixos-config=${self.outPath}/nixosConfigurations/${hostname}" ]; + nixpkgs.overlays = [ + agenix.overlays.default + self.overlays.default + ]; + } + ] + ++ tagModuleFiles + ++ hostModuleFiles + ++ extraModules; + in + pkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs; + hostTags = allTags; + }; + modules = allModules; + }; + + # Tag-based user configuration system + mkUser = + { + username, + homeDirectory ? "/home/${username}", + tags ? [ ], + extraModules ? [ ], + }: + let + pkgs = nixpkgs.legacyPackages.x86_64-linux; + + # Always include "common" tag implicitly + allTags = [ "common" ] ++ tags; + + # Tag-specific modules: each tag maps to users/modules/${tag}.nix if it exists + tagModuleFiles = builtins.concatMap ( + tag: + let + filePath = ./users/modules/${tag}.nix; + dirPath = ./users/modules/${tag}; + in + # Check if it's a file first + if builtins.pathExists filePath then + [ filePath ] + # Then check if it's a directory + else if builtins.pathExists dirPath then + let + entries = builtins.readDir dirPath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: dirPath + "/${name}") (builtins.attrNames nixFiles) + else + [ ] + ) allTags; + + # Automatically import all .nix files from users/modules/${username}/ + userModulePath = ./users/${username}; + userModuleFiles = + if builtins.pathExists userModulePath then + let + entries = builtins.readDir userModulePath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: userModulePath + "/${name}") (builtins.attrNames nixFiles) + else + [ ]; + + # Combine all modules + allModules = [ + { + home = { + inherit username homeDirectory; + stateVersion = "22.05"; + }; + } + ] + ++ tagModuleFiles + ++ userModuleFiles + ++ extraModules; + in + home-manager.lib.homeManagerConfiguration { + inherit pkgs; + extraSpecialArgs = { + inherit inputs; + userTags = allTags; + }; + modules = allModules; + }; +}