diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix deleted file mode 100644 index f45f4ac..0000000 --- a/configurations/nixos/defiant/configuration.nix +++ /dev/null @@ -1,452 +0,0 @@ -# server nas -{ - inputs, - config, - ... -}: { - sops.secrets = { - "vpn-keys/tailscale-authkey/defiant" = { - sopsFile = "${inputs.secrets}/vpn-keys.yaml"; - }; - "vpn-keys/proton-wireguard/defiant-p2p" = { - sopsFile = "${inputs.secrets}/vpn-keys.yaml"; - mode = "0640"; - owner = "root"; - group = "systemd-network"; - }; - "services/zfs_smtp_token" = { - sopsFile = "${inputs.secrets}/defiant-services.yaml"; - }; - "services/paperless_password" = { - sopsFile = "${inputs.secrets}/defiant-services.yaml"; - mode = "0700"; - owner = "paperless"; - group = "paperless"; - }; - }; - - host = { - users = { - leyla = { - isDesktopUser = true; - isTerminalUser = true; - isPrincipleUser = true; - }; - }; - network_storage = { - enable = true; - directories = [ - { - folder = "leyla_documents"; - user = "leyla"; - group = "leyla"; - bind = "/home/leyla/documents"; - } - { - folder = "eve_documents"; - user = "eve"; - group = "eve"; - } - { - folder = "users_documents"; - user = "root"; - group = "users"; - } - { - folder = "media"; - user = "jellyfin"; - group = "jellyfin_media"; - bind = config.services.jellyfin.media_directory; - } - ]; - nfs = { - enable = true; - directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; - }; - }; - }; - - storage = { - zfs = { - enable = true; - notifications = { - enable = true; - host = "smtp.protonmail.ch"; - port = 587; - to = "leyla@jan-leila.com"; - user = "noreply@jan-leila.com"; - tokenFile = config.sops.secrets."services/zfs_smtp_token".path; - }; - pool = { - encryption = { - enable = true; - }; - vdevs = [ - [ - "ata-ST18000NE000-3G6101_ZVTCXVEB" - "ata-ST18000NE000-3G6101_ZVTCXWSC" - "ata-ST18000NE000-3G6101_ZVTD10EH" - "ata-ST18000NT001-3NF101_ZVTE0S3Q" - "ata-ST18000NT001-3NF101_ZVTEF27J" - "ata-ST18000NE000-3G6101_ZVTJ7359" - ] - [ - "ata-ST4000NE001-2MA101_WS2275P3" - "ata-ST4000NE001-2MA101_WS227B9F" - "ata-ST4000NE001-2MA101_WS227CEW" - "ata-ST4000NE001-2MA101_WS227CYN" - "ata-ST4000NE001-2MA101_WS23TBWV" - "ata-ST4000NE001-2MA101_WS23TC5F" - ] - ]; - # We are having to boot off of the nvm cache drive because I cant figure out how to boot via the HBA - cache = [ - { - device = "nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"; - boot = true; - } - ]; - }; - }; - impermanence = { - enable = true; - }; - }; - - # bond0 and wg0 are managed by systemd-networkd; tell NetworkManager to - # leave them alone so NM-wait-online doesn't time out waiting for them. - networking.networkmanager.unmanaged = ["bond0" "wg0" "eno1" "eno2"]; - - systemd.network = { - enable = true; - - netdevs = { - "10-bond0" = { - netdevConfig = { - Kind = "bond"; - Name = "bond0"; - }; - bondConfig = { - Mode = "active-backup"; - PrimaryReselectPolicy = "always"; - }; - }; - - "20-wg0" = { - netdevConfig = { - Kind = "wireguard"; - Name = "wg0"; - }; - wireguardConfig = { - PrivateKeyFile = config.sops.secrets."vpn-keys/proton-wireguard/defiant-p2p".path; - ListenPort = 51820; - }; - wireguardPeers = [ - { - PublicKey = "rRO6yJim++Ezz6scCLMaizI+taDjU1pzR2nfW6qKbW0="; - Endpoint = "185.230.126.146:51820"; - # Allow all traffic but use policy routing to prevent system-wide VPN - AllowedIPs = ["0.0.0.0/0"]; - PersistentKeepalive = 25; - } - ]; - }; - }; - networks = { - "40-bond0" = { - matchConfig.Name = "bond0"; - linkConfig = { - RequiredForOnline = "degraded-carrier"; - RequiredFamilyForOnline = "any"; - }; - networkConfig.DHCP = "yes"; - - address = [ - "192.168.1.2/24" - ]; - - # Set lower priority for default gateway to allow WireGuard interface binding - routes = [ - { - Destination = "0.0.0.0/0"; - Gateway = "192.168.1.1"; - Metric = 100; - } - ]; - dns = ["192.168.1.1"]; - }; - - "50-wg0" = { - matchConfig.Name = "wg0"; - # Don't block networkd-wait-online on the VPN tunnel coming up - linkConfig.RequiredForOnline = "no"; - networkConfig = { - DHCP = "no"; - }; - address = [ - "10.2.0.2/32" - ]; - # Configure routing for application binding - routingPolicyRules = [ - { - # Route traffic from VPN interface through VPN table - From = "10.2.0.2/32"; - Table = 200; - Priority = 100; - } - ]; - routes = [ - { - # Direct route to VPN gateway - Destination = "10.2.0.1/32"; - Scope = "link"; - } - { - # Route VPN subnet through VPN gateway in custom table - Destination = "10.2.0.0/16"; - Gateway = "10.2.0.1"; - Table = 200; - } - { - # Route all traffic through VPN gateway in custom table - Destination = "0.0.0.0/0"; - Gateway = "10.2.0.1"; - Table = 200; - } - ]; - }; - }; - }; - - # limit arc usage to 50gb because ollama doesn't play nice with zfs using up all of the memory - boot.kernelParams = ["zfs.zfs_arc_max=53687091200"]; - - # Enable policy routing and source routing for application-specific VPN binding - boot.kernel.sysctl = { - "net.ipv4.conf.all.rp_filter" = 2; - "net.ipv4.conf.default.rp_filter" = 2; - "net.ipv4.conf.wg0.rp_filter" = 2; - }; - - services = { - # PostgreSQL database server - postgresql = { - enable = true; - adminUsers = ["leyla"]; - impermanence.enable = false; - }; - - # temp enable desktop environment for setup - # Enable the X11 windowing system. - xserver.enable = true; - - # Enable the GNOME Desktop Environment. - displayManager = { - gdm.enable = true; - }; - desktopManager = { - gnome.enable = true; - }; - - # Enable new reverse proxy system - reverseProxy = { - enable = true; - openFirewall = true; - impermanence.enable = false; - acme = { - enable = true; - email = "jan-leila@protonmail.com"; - }; - }; - - ollama = { - enable = true; - exposePort = true; - impermanence.enable = false; - - environmentVariables = { - OLLAMA_KEEP_ALIVE = "24h"; - }; - - loadModels = [ - # conversation models - "llama3.1:8b" - "deepseek-r1:8b" - "deepseek-r1:32b" - "deepseek-r1:70b" - - # auto complete models - "qwen2.5-coder:1.5b-base" - "qwen2.5-coder:7b" - "deepseek-coder:6.7b" - "deepseek-coder:33b" - - # agent models - "qwen3:8b" - "qwen3:32b" - "qwen3:235b-a22b" - - "qwen3-coder:30b" - "qwen3-coder:30b-a3b-fp16" - - # embedding models - "nomic-embed-text:latest" - ]; - }; - tailscale = { - enable = true; - authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/defiant".path; - useRoutingFeatures = "server"; - impermanence.enable = false; - extraUpFlags = [ - "--advertise-exit-node" - "--advertise-routes=192.168.0.0/24" - "--accept-dns=false" - ]; - extraSetFlags = [ - "--advertise-exit-node" - "--advertise-routes=192.168.0.0/24" - "--accept-dns=false" - ]; - }; - - syncthing = { - enable = true; - impermanence.enable = false; - }; - - fail2ban = { - enable = true; - impermanence.enable = false; - }; - - jellyfin = { - enable = true; - domain = "media.jan-leila.com"; - extraDomains = ["jellyfin.jan-leila.com"]; - impermanence.enable = false; - }; - - immich = { - enable = true; - domain = "photos.jan-leila.com"; - impermanence.enable = false; - }; - - forgejo = { - enable = true; - reverseProxy.domain = "git.jan-leila.com"; - impermanence.enable = false; - }; - - searx = { - enable = true; - domain = "search.jan-leila.com"; - }; - - actual = { - enable = false; - domain = "budget.jan-leila.com"; - impermanence.enable = false; - }; - - home-assistant = { - enable = true; - domain = "home.jan-leila.com"; - openFirewall = true; - postgres.enable = true; - impermanence.enable = false; - - extensions = { - sonos.enable = true; - jellyfin.enable = true; - wyoming.enable = false; # Temporarily disabled due to dependency conflict in wyoming-piper - }; - }; - - paperless = { - enable = true; - domain = "documents.jan-leila.com"; - passwordFile = config.sops.secrets."services/paperless_password".path; - impermanence.enable = false; - }; - - panoramax = { - enable = false; - openFirewall = true; - impermanence.enable = false; - }; - - crab-hole = { - enable = true; - port = 8085; - openFirewall = true; - show_doc = true; - impermanence.enable = false; - downstreams = { - host = { - enable = true; - openFirewall = true; - }; - }; - upstreams.cloudFlare.enable = true; - blocklists.ad_malware.enable = true; - }; - - qbittorrent = { - enable = true; - mediaDir = "/srv/qbittorent"; - openFirewall = true; - webuiPort = 8084; - impermanence.enable = false; - }; - - sonarr = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - radarr = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - bazarr = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - lidarr = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - jackett = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - flaresolverr = { - enable = true; - openFirewall = true; - impermanence.enable = false; - }; - }; - - # disable computer sleeping - systemd.targets = { - sleep.enable = false; - suspend.enable = false; - hibernate.enable = false; - hybrid-sleep.enable = false; - }; - services.displayManager.gdm.autoSuspend = false; - - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It's perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "23.05"; # Did you read the comment? -} diff --git a/configurations/nixos/defiant/default.nix b/configurations/nixos/defiant/default.nix deleted file mode 100644 index dd2383f..0000000 --- a/configurations/nixos/defiant/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -# server nas -{...}: { - imports = [ - ./hardware-configuration.nix - ./configuration.nix - ./packages.nix - ./legacy-storage.nix - ./legacy-impermanence.nix - ]; -} diff --git a/configurations/nixos/defiant/hardware-configuration.nix b/configurations/nixos/defiant/hardware-configuration.nix deleted file mode 100644 index 56227b7..0000000 --- a/configurations/nixos/defiant/hardware-configuration.nix +++ /dev/null @@ -1,68 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ - config, - lib, - modulesPath, - ... -}: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot = { - initrd = { - availableKernelModules = ["xhci_pci" "aacraid" "ahci" "usbhid" "nvme" "usb_storage" "sd_mod"]; - kernelModules = []; - }; - kernelModules = ["kvm-amd"]; - extraModulePackages = []; - - # Bootloader. - loader = { - systemd-boot.enable = true; - efi = { - canTouchEfiVariables = true; - efiSysMountPoint = "/boot"; - }; - }; - supportedFilesystems = ["zfs"]; - - zfs.extraPools = ["rpool"]; - }; - - networking = { - hostName = "defiant"; # Define your hostname. - hostId = "c51763d6"; - useNetworkd = true; - }; - - systemd.network = { - enable = true; - - networks = { - "30-eno1" = { - matchConfig.Name = "eno1"; - networkConfig = { - Bond = "bond0"; - PrimarySlave = true; - }; - linkConfig.RequiredForOnline = "enslaved"; - }; - "30-eno2" = { - matchConfig.Name = "eno2"; - networkConfig.Bond = "bond0"; - linkConfig.RequiredForOnline = "enslaved"; - }; - }; - }; - - networking.networkmanager.enable = true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware = { - # TODO: hardware graphics - cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - }; -} diff --git a/configurations/nixos/defiant/legacy-impermanence.nix b/configurations/nixos/defiant/legacy-impermanence.nix deleted file mode 100644 index 4cfe18b..0000000 --- a/configurations/nixos/defiant/legacy-impermanence.nix +++ /dev/null @@ -1,296 +0,0 @@ -# Legacy impermanence module for defiant -# See legacy-storage.nix for the full incremental migration plan. -# -# This file is consumed in two phases: -# -# Phase 3 (after generateBase is enabled): -# Remove the SYSTEM-LEVEL entries marked [PHASE 3] below. These will be -# handled automatically by storage.nix, ssh.nix, and the impermanence module: -# - var-lib-private-permissions activation script -# - /etc/machine-id -# - SSH host keys -# - /var/lib/nixos -# - /var/lib/systemd/coredump -# - /persist/system/var/log persistence block -# -# Phase 4 (migrate services one at a time, any order): -# For each service: -# 1. Remove the service's section marked [PHASE 4] from this file -# 2. Remove `impermanence.enable = false` for that service in configuration.nix -# For jellyfin/qbittorrent, also remove the separate media persistence blocks. -# -# Phase 5: Delete this file once empty. -{ - config, - lib, - ... -}: { - config = lib.mkIf config.storage.impermanence.enable { - # [PHASE 3] Remove this activation script after enabling generateBase - system.activationScripts = { - "var-lib-private-permissions" = { - deps = ["specialfs"]; - text = '' - mkdir -p /persist/system/root/var/lib/private - chmod 0700 /persist/system/root/var/lib/private - ''; - }; - }; - - environment.persistence."/persist/system/root" = { - enable = true; - hideMounts = true; - # [PHASE 3] Remove this files block after enabling generateBase - files = lib.mkMerge [ - ["/etc/machine-id"] - # SSH host keys - (lib.mkIf config.services.openssh.enable ( - lib.lists.flatten ( - builtins.map (hostKey: [ - hostKey.path - "${hostKey.path}.pub" - ]) - config.services.openssh.hostKeys - ) - )) - ]; - directories = lib.mkMerge [ - # [PHASE 3] Remove these system directories after enabling generateBase - [ - "/var/lib/nixos" - "/var/lib/systemd/coredump" - ] - - # [PHASE 4] PostgreSQL - (lib.mkIf config.services.postgresql.enable [ - { - directory = "/var/lib/postgresql/16"; - user = "postgres"; - group = "postgres"; - } - ]) - - # [PHASE 4] Reverse Proxy (ACME) - (lib.mkIf config.services.reverseProxy.enable [ - { - directory = "/var/lib/acme"; - user = "acme"; - group = "acme"; - } - ]) - - # [PHASE 4] Ollama - (lib.mkIf config.services.ollama.enable [ - { - directory = "/var/lib/private/ollama"; - user = config.services.ollama.user; - group = config.services.ollama.group; - mode = "0700"; - } - ]) - - # [PHASE 4] Tailscale - (lib.mkIf config.services.tailscale.enable [ - { - directory = "/var/lib/tailscale"; - user = "root"; - group = "root"; - } - ]) - - # [PHASE 4] Syncthing - (lib.mkIf config.services.syncthing.enable [ - { - directory = "/mnt/sync"; - user = "syncthing"; - group = "syncthing"; - } - { - directory = "/etc/syncthing"; - user = "syncthing"; - group = "syncthing"; - } - ]) - - # [PHASE 4] Fail2ban - (lib.mkIf config.services.fail2ban.enable [ - { - directory = "/var/lib/fail2ban"; - user = "fail2ban"; - group = "fail2ban"; - } - ]) - - # [PHASE 4] Jellyfin (data/cache only - media is on separate dataset) - (lib.mkIf config.services.jellyfin.enable [ - { - directory = "/var/lib/jellyfin"; - user = "jellyfin"; - group = "jellyfin"; - } - { - directory = "/var/cache/jellyfin"; - user = "jellyfin"; - group = "jellyfin"; - } - ]) - - # [PHASE 4] Immich - (lib.mkIf config.services.immich.enable [ - { - directory = "/var/lib/immich"; - user = "immich"; - group = "immich"; - } - ]) - - # [PHASE 4] Forgejo - (lib.mkIf config.services.forgejo.enable [ - { - directory = "/var/lib/forgejo"; - user = "forgejo"; - group = "forgejo"; - } - ]) - - # [PHASE 4] Actual - (lib.mkIf config.services.actual.enable [ - { - directory = "/var/lib/private/actual"; - user = "actual"; - group = "actual"; - } - ]) - - # [PHASE 4] Home Assistant - (lib.mkIf config.services.home-assistant.enable [ - { - directory = "/var/lib/hass"; - user = "hass"; - group = "hass"; - } - ]) - - # [PHASE 4] Paperless - (lib.mkIf config.services.paperless.enable [ - { - directory = "/var/lib/paperless"; - user = "paperless"; - group = "paperless"; - } - ]) - - # [PHASE 4] Crab-hole - (lib.mkIf config.services.crab-hole.enable [ - { - directory = "/var/lib/private/crab-hole"; - user = "crab-hole"; - group = "crab-hole"; - } - ]) - - # [PHASE 4] qBittorrent (config only - media is on separate dataset) - (lib.mkIf config.services.qbittorrent.enable [ - { - directory = "/var/lib/qBittorrent/"; - user = "qbittorrent"; - group = "qbittorrent"; - } - ]) - - # [PHASE 4] Sonarr - (lib.mkIf config.services.sonarr.enable [ - { - directory = "/var/lib/sonarr/.config/NzbDrone"; - user = "sonarr"; - group = "sonarr"; - } - ]) - - # [PHASE 4] Radarr - (lib.mkIf config.services.radarr.enable [ - { - directory = "/var/lib/radarr/.config/Radarr"; - user = "radarr"; - group = "radarr"; - } - ]) - - # [PHASE 4] Bazarr - (lib.mkIf config.services.bazarr.enable [ - { - directory = "/var/lib/bazarr"; - user = "bazarr"; - group = "bazarr"; - } - ]) - - # [PHASE 4] Lidarr - (lib.mkIf config.services.lidarr.enable [ - { - directory = "/var/lib/lidarr/.config/Lidarr"; - user = "lidarr"; - group = "lidarr"; - } - ]) - - # [PHASE 4] Jackett - (lib.mkIf config.services.jackett.enable [ - { - directory = "/var/lib/jackett/.config/Jackett"; - user = "jackett"; - group = "jackett"; - } - ]) - - # [PHASE 4] FlareSolverr - (lib.mkIf config.services.flaresolverr.enable [ - { - directory = "/var/lib/flaresolverr"; - user = "flaresolverr"; - group = "flaresolverr"; - } - ]) - ]; - }; - - # [PHASE 4 - LAST] Jellyfin media on separate dataset - # Requires Phase 2 media dataset merge before migrating (several days of data copy) - environment.persistence."/persist/system/jellyfin" = lib.mkIf config.services.jellyfin.enable { - enable = true; - hideMounts = true; - directories = [ - { - directory = config.services.jellyfin.media_directory; - user = "jellyfin"; - group = "jellyfin_media"; - mode = "1770"; - } - ]; - }; - - # [PHASE 4 - LAST] qBittorrent media on separate dataset - # Requires Phase 2 media dataset merge before migrating (several days of data copy) - environment.persistence."/persist/system/qbittorrent" = lib.mkIf config.services.qbittorrent.enable { - enable = true; - hideMounts = true; - directories = [ - { - directory = config.services.qbittorrent.mediaDir; - user = "qbittorrent"; - group = "qbittorrent"; - mode = "1775"; - } - ]; - }; - - # [PHASE 3] /var/log persistence - handled by storage.nix after generateBase - environment.persistence."/persist/system/var/log" = { - enable = true; - hideMounts = true; - directories = [ - "/var/log" - ]; - }; - }; -} diff --git a/configurations/nixos/defiant/legacy-storage.nix b/configurations/nixos/defiant/legacy-storage.nix deleted file mode 100644 index 9ab79a6..0000000 --- a/configurations/nixos/defiant/legacy-storage.nix +++ /dev/null @@ -1,218 +0,0 @@ -# Legacy storage configuration for defiant -# This file manually defines ZFS datasets matching the existing on-disk layout -# to allow incremental migration to the new storage module (generateBase = true). -# -# ============================================================================ -# INCREMENTAL MIGRATION PLAN -# ============================================================================ -# -# Current disk usage (for reference): -# rpool/local/system/nix ~26G (renamed in place, no copy) -# rpool/local/system/sops ~328K (renamed in place, no copy) -# rpool/persist/system/jellyfin ~32T (renamed in place, no copy) -# rpool/persist/system/qbittorrent ~6.5T (copied into media dataset, ~6.5T temp) -# rpool free space ~30T -# -# Phase 1: Migrate base datasets on disk (boot from live USB or rescue) -# All operations in this phase are instant renames -- no data is copied. -# -# Unlock the pool: -# zfs load-key -a -# -# Step 1a: Move nix and sops out of local/ (they go to persist/local/) -# The -p flag auto-creates the parent datasets. -# -# zfs rename -p rpool/local/system/nix rpool/persist/local/nix -# zfs rename -p rpool/local/system/sops rpool/persist/local/system/sops -# -# Step 1b: Rename local/ -> ephemeral/ (takes remaining children with it) -# zfs rename rpool/local rpool/ephemeral -# # This moves: local/system/root -> ephemeral/system/root -# # local/home/leyla -> ephemeral/home/leyla -# -# Step 1c: Recreate blank snapshots on ephemeral datasets -# zfs destroy rpool/ephemeral/system/root@blank -# zfs snapshot rpool/ephemeral/system/root@blank -# zfs destroy rpool/ephemeral/home/leyla@blank -# zfs snapshot rpool/ephemeral/home/leyla@blank -# -# Step 1d: Move persist/ children under persist/replicate/ -# zfs create -o canmount=off rpool/persist/replicate -# zfs create -o canmount=off rpool/persist/replicate/system -# zfs rename rpool/persist/system/root rpool/persist/replicate/system/root -# zfs rename rpool/persist/system/var rpool/persist/replicate/system/var -# zfs rename rpool/persist/home/leyla rpool/persist/replicate/home -# # Clean up the now-empty home parent -# zfs destroy rpool/persist/home -# # NOTE: Do NOT destroy rpool/persist/system -- it still contains -# # persist/system/jellyfin and persist/system/qbittorrent which are -# # migrated in Phase 2. -# -# Verify the new layout: -# zfs list -r rpool -o name,used,mountpoint -# -# Phase 2: Merge media into a single dataset (do this last) -# Strategy: Rename the jellyfin dataset to become the shared media dataset -# (zero copy, instant), then copy qbittorrent data into it (~6.5T copy). -# This avoids duplicating the 32T jellyfin dataset. -# -# Step 2a: Rename jellyfin dataset to the shared media name -# zfs rename rpool/persist/system/jellyfin rpool/persist/replicate/system/media -# -# Step 2b: Copy qbittorrent data into the media dataset -# This copies ~6.5T and may take several hours/days depending on disk speed. -# The qbittorrent data is not critical to back up so no snapshot needed. -# -# systemctl stop qbittorrent -# rsync -avPHAX /persist/system/qbittorrent/ /persist/replicate/system/media/ -# -# Step 2c: Verify the data and clean up -# ls -la /persist/replicate/system/media/ -# zfs destroy rpool/persist/system/qbittorrent -# # persist/system should now be empty, clean it up: -# zfs destroy rpool/persist/system -# -# Phase 3: Enable generateBase -# In the nix config: -# - Delete this file (legacy-storage.nix) and remove its import from default.nix -# - Remove [PHASE 3] entries from legacy-impermanence.nix: -# - var-lib-private-permissions activation script -# - /etc/machine-id, SSH host keys (files block) -# - /var/lib/nixos, /var/lib/systemd/coredump (directories) -# - /persist/system/var/log persistence block -# These are now handled automatically by storage.nix and ssh.nix. -# Rebuild and verify: -# sudo nixos-rebuild switch --flake .#defiant -# # Verify mounts: findmnt -t fuse.bindfs,fuse -# # Verify persist: ls /persist/replicate/system/root/var/lib/nixos -# # Verify boot: reboot and confirm system comes up cleanly -# -# Phase 4: Migrate services (one at a time, any order) -# For each service (except jellyfin/qbittorrent): -# 1. Remove the service's [PHASE 4] section from legacy-impermanence.nix -# 2. Remove `impermanence.enable = false` for that service in configuration.nix -# 3. Rebuild: sudo nixos-rebuild switch --flake .#defiant -# 4. Verify: systemctl status , check the service's data is intact -# No data migration is needed -- the data already lives on the renamed -# dataset at the new path. -# -# Migrate jellyfin and qbittorrent LAST (after Phase 2 media merge): -# 1. Remove [PHASE 4 - LAST] jellyfin entries from legacy-impermanence.nix -# 2. Remove [PHASE 4 - LAST] qbittorrent entries from legacy-impermanence.nix -# 3. Remove `impermanence.enable = false` for both in configuration.nix -# 4. Rebuild: sudo nixos-rebuild switch --flake .#defiant -# 5. Verify: systemctl status jellyfin qbittorrent -# -# Phase 5: Cleanup -# Once all services are migrated and legacy-impermanence.nix is empty: -# - Delete legacy-impermanence.nix and remove its import from default.nix -# - Rebuild: sudo nixos-rebuild switch --flake .#defiant -# -# ============================================================================ -# -# Current on-disk dataset layout: -# rpool/local/ - ephemeral parent -# rpool/local/home/leyla - ephemeral user home (rolled back on boot) -# rpool/local/system/nix - nix store -# rpool/local/system/root - root filesystem (rolled back on boot) -# rpool/local/system/sops - sops age key -# rpool/persist/ - persistent parent -# rpool/persist/home/leyla - persistent user home -# rpool/persist/system/jellyfin - jellyfin media -# rpool/persist/system/qbittorrent - qbittorrent media -# rpool/persist/system/root - persistent root data -# rpool/persist/system/var/log - log persistence -{lib, ...}: { - # Disable automatic base dataset generation so we can define them manually - storage.generateBase = false; - - # Manually define ZFS datasets matching main's structure - storage.zfs.datasets = { - # Ephemeral datasets (local/) - "local" = { - type = "zfs_fs"; - mount = null; - }; - "local/home/leyla" = { - type = "zfs_fs"; - mount = "/home/leyla"; - snapshot = { - blankSnapshot = true; - }; - }; - "local/system/nix" = { - type = "zfs_fs"; - mount = "/nix"; - atime = "off"; - relatime = "off"; - snapshot = { - autoSnapshot = false; - }; - }; - "local/system/root" = { - type = "zfs_fs"; - mount = "/"; - snapshot = { - blankSnapshot = true; - }; - }; - "local/system/sops" = { - type = "zfs_fs"; - mount = "/var/lib/sops-nix"; - }; - - # Persistent datasets (persist/) - "persist" = { - type = "zfs_fs"; - mount = null; - }; - "persist/home/leyla" = { - type = "zfs_fs"; - mount = "/persist/home/leyla"; - snapshot = { - autoSnapshot = true; - }; - }; - "persist/system/jellyfin" = { - type = "zfs_fs"; - mount = "/persist/system/jellyfin"; - atime = "off"; - relatime = "off"; - }; - "persist/system/qbittorrent" = { - type = "zfs_fs"; - mount = "/persist/system/qbittorrent"; - atime = "off"; - relatime = "off"; - }; - "persist/system/root" = { - type = "zfs_fs"; - mount = "/persist/system/root"; - snapshot = { - autoSnapshot = true; - }; - }; - "persist/system/var/log" = { - type = "zfs_fs"; - mount = "/persist/system/var/log"; - }; - }; - - # Boot commands to rollback ephemeral root and user homes on boot - boot.initrd.postResumeCommands = lib.mkAfter '' - zfs rollback -r rpool/local/system/root@blank - zfs rollback -r rpool/local/home/leyla@blank - ''; - - # FileSystems needed for boot - fileSystems = { - "/".neededForBoot = true; - "/persist/system/root".neededForBoot = true; - "/persist/system/var/log".neededForBoot = true; - "/persist/system/jellyfin".neededForBoot = true; - "/persist/system/qbittorrent".neededForBoot = true; - "/var/lib/sops-nix".neededForBoot = true; - "/persist/home/leyla".neededForBoot = true; - "/home/leyla".neededForBoot = true; - }; -} diff --git a/configurations/nixos/defiant/packages.nix b/configurations/nixos/defiant/packages.nix deleted file mode 100644 index 45780b0..0000000 --- a/configurations/nixos/defiant/packages.nix +++ /dev/null @@ -1,9 +0,0 @@ -{pkgs, ...}: { - environment.systemPackages = with pkgs; [ - ffsubsync - sox - yt-dlp - ffmpeg - imagemagick - ]; -} diff --git a/configurations/nixos/emergent/configuration.nix b/configurations/nixos/emergent/configuration.nix deleted file mode 100644 index 35ef445..0000000 --- a/configurations/nixos/emergent/configuration.nix +++ /dev/null @@ -1,185 +0,0 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page, on -# https://search.nixos.org/options and in the NixOS manual (`nixos-help`). -{ - lib, - pkgs, - ... -}: { - imports = [ - ./nvidia-drivers.nix - ]; - - # Use the systemd-boot EFI boot loader. - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - - # networking.hostName = "nixos"; # Define your hostname. - # Pick only one of the below networking options. - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. - # networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. - - # Set your time zone. - # time.timeZone = "Europe/Amsterdam"; - - # Configure network proxy if necessary - # networking.proxy.default = "http://user:password@proxy:port/"; - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; - - # Select internationalisation properties. - # i18n.defaultLocale = "en_US.UTF-8"; - # console = { - # font = "Lat2-Terminus16"; - # keyMap = "us"; - # useXkbConfig = true; # use xkb.options in tty. - # }; - - # Enable the X11 windowing system. - services.xserver.enable = true; - # Enable wacom touchscreen device - services.xserver.wacom.enable = true; - - # installed opentabletdriver - # hardware.opentabletdriver.enable = true; - hardware.keyboard.qmk.enable = true; - - # Enable the GNOME Desktop Environment. - services.displayManager.gdm.enable = true; - services.desktopManager.gnome.enable = true; - - host = { - ai.enable = true; - users = { - eve = { - isDesktopUser = true; - isTerminalUser = true; - isPrincipleUser = true; - }; - }; - hardware = { - piperMouse.enable = true; - }; - }; - - storage = { - zfs = { - enable = true; - pool = { - mode = "stripe"; - vdevs = [ - [ - { - device = "wwn-0x5000039fd0cf05eb"; - boot = true; - } - ] - ]; - cache = []; - }; - }; - }; - - virtualisation.libvirtd.enable = true; - - users.users.eve = { - extraGroups = ["libvirtd"]; - }; - - services.tailscale.enable = true; - # We were having weird build errors so this is disabled right now - # error: The option `devices.emergent.folders.eve_records.path' was accessed but has no value defined. Try setting the option - services.syncthing.enable = false; - - # Configure keymap in X11 - # services.xserver.xkb.layout = "us"; - # services.xserver.xkb.options = "eurosign:e,caps:escape"; - - # Enable CUPS to print documents. - # services.printing.enable = true; - - # Enable sound. - # services.pulseaudio.enable = true; - # OR - # services.pipewire = { - # enable = true; - # pulse.enable = true; - # }; - - # Enable touchpad support (enabled default in most desktopManager). - # services.libinput.enable = true; - - # Define a user account. Don't forget to set a password with ‘passwd’. - # users.users.alice = { - # isNormalUser = true; - # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. - # packages = with pkgs; [ - # tree - # ]; - # }; - - # programs.firefox.enable = true; - - nixpkgs.config.allowUnfree = true; - - # Packages that can be installed without any extra configuration - # See https://search.nixos.org/packages for all options - environment.systemPackages = with pkgs; [ - wget - gnome-boxes - libvirt - ]; - - # Packages that need to be installed with some extra configuration - # See https://search.nixos.org/options for all options - programs = {}; - - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - # programs.gnupg.agent = { - # enable = true; - # enableSSHSupport = true; - # }; - - # List services that you want to enable: - - # Enable the OpenSSH daemon. - # services.openssh.enable = true; - - # Open ports in the firewall. - # networking.firewall.allowedTCPPorts = [ ... ]; - # networking.firewall.allowedUDPPorts = [ ... ]; - # Or disable the firewall altogether. - # networking.firewall.enable = false; - - networking = { - networkmanager.enable = true; - useDHCP = lib.mkDefault true; - hostId = "7e35eb97"; # arbitrary id number generated via this command: `head -c4 /dev/urandom | od -A none -t x4` - hostName = "emergent"; # Define your hostname. - }; - - # Copy the NixOS configuration file and link it from the resulting system - # (/run/current-system/configuration.nix). This is useful in case you - # accidentally delete configuration.nix. - # system.copySystemConfiguration = true; - - # This option defines the first version of NixOS you have installed on this particular machine, - # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. - # - # Most users should NEVER change this value after the initial install, for any reason, - # even if you've upgraded your system to a new NixOS release. - # - # This value does NOT affect the Nixpkgs version your packages and OS are pulled from, - # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how - # to actually do that. - # - # This value being lower than the current NixOS release does NOT mean your system is - # out of date, out of support, or vulnerable. - # - # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration, - # and migrated your data accordingly. - # - # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . - system.stateVersion = "25.05"; # Did you read the comment? -} diff --git a/configurations/nixos/emergent/default.nix b/configurations/nixos/emergent/default.nix deleted file mode 100644 index 3acaeda..0000000 --- a/configurations/nixos/emergent/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -# evs desktop -{...}: { - imports = [ - ./configuration.nix - ./hardware-configuration.nix - ./legacy-storage.nix - ]; -} diff --git a/configurations/nixos/emergent/hardware-configuration.nix b/configurations/nixos/emergent/hardware-configuration.nix deleted file mode 100644 index b077f9c..0000000 --- a/configurations/nixos/emergent/hardware-configuration.nix +++ /dev/null @@ -1,32 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ - config, - lib, - pkgs, - modulesPath, - ... -}: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "wacom" "kvm" "kvm_amd"]; - boot.initrd.kernelModules = []; - boot.kernelModules = []; - boot.extraModulePackages = []; - - swapDevices = []; - - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; - # networking.interfaces.enp42s0.useDHCP = lib.mkDefault true; - # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/nixos/emergent/legacy-storage.nix b/configurations/nixos/emergent/legacy-storage.nix deleted file mode 100644 index 2b24729..0000000 --- a/configurations/nixos/emergent/legacy-storage.nix +++ /dev/null @@ -1,51 +0,0 @@ -# Legacy storage configuration for emergent -# This file manually defines ZFS datasets matching the existing on-disk layout -# to allow incremental migration to the new storage module (generateBase = true). -# -# Current on-disk dataset layout: -# rpool/local/ - parent (canmount=off) -# rpool/local/system/nix - nix store -# rpool/local/system/root - root filesystem -# -# Migration plan: -# Phase 1: Rename datasets on disk (boot from live USB) -# zfs rename -p rpool/local/system/nix rpool/persist/local/nix -# zfs rename rpool/local rpool/persist/local -# # This moves: local/system/root -> persist/local/root (need to rename after) -# # Actually, since local/system/root needs to become persist/local/root: -# zfs rename rpool/persist/local/system/root rpool/persist/local/root -# zfs destroy rpool/persist/local/system # now empty -# # Recreate blank snapshot: -# zfs destroy rpool/persist/local/root@blank -# zfs snapshot rpool/persist/local/root@blank -# -# Phase 2: Delete this file, remove its import from default.nix, rebuild. -{...}: { - # Disable automatic base dataset generation so we can define them manually - storage.generateBase = false; - - # Manually define ZFS datasets matching the existing on-disk layout - storage.zfs.datasets = { - "local" = { - type = "zfs_fs"; - mount = null; - }; - "local/system/nix" = { - type = "zfs_fs"; - mount = "/nix"; - atime = "off"; - relatime = "off"; - snapshot = { - autoSnapshot = false; - }; - }; - "local/system/root" = { - type = "zfs_fs"; - mount = "/"; - snapshot = { - blankSnapshot = true; - autoSnapshot = true; - }; - }; - }; -} diff --git a/configurations/nixos/emergent/nvidia-drivers.nix b/configurations/nixos/emergent/nvidia-drivers.nix deleted file mode 100644 index 05b7205..0000000 --- a/configurations/nixos/emergent/nvidia-drivers.nix +++ /dev/null @@ -1,46 +0,0 @@ -{config, ...}: { - # Enable OpenGL - hardware.graphics = { - enable = true; - }; - - # Load nvidia driver for Xorg and Wayland - services = { - xserver = { - # Load nvidia driver for Xorg and Wayland - videoDrivers = ["nvidia"]; - }; - # Use X instead of wayland - displayManager.gdm.wayland = true; - }; - - hardware.nvidia = { - # Modesetting is required. - modesetting.enable = true; - - # Nvidia power management. Experimental, and can cause sleep/suspend to fail. - # Enable this if you have graphical corruption issues or application crashes after waking - # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead - # of just the bare essentials. - powerManagement.enable = true; - - # Fine-grained power management. Turns off GPU when not in use. - # Experimental and only works on modern Nvidia GPUs (Turing or newer). - powerManagement.finegrained = false; - - # Use the NVidia open source kernel module (not to be confused with the - # independent third-party "nouveau" open source driver). - # Support is limited to the Turing and later architectures. Full list of - # supported GPUs is at: - # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus - # Only available from driver 515.43.04+ - open = true; - - # Enable the Nvidia settings menu, - # accessible via `nvidia-settings`. - nvidiaSettings = true; - - # Optionally, you may need to select the appropriate driver version for your specific GPU. - package = config.boot.kernelPackages.nvidiaPackages.stable; - }; -} diff --git a/configurations/nixos/horizon/configuration.nix b/configurations/nixos/horizon/configuration.nix deleted file mode 100644 index b81a895..0000000 --- a/configurations/nixos/horizon/configuration.nix +++ /dev/null @@ -1,156 +0,0 @@ -{ - lib, - pkgs, - config, - inputs, - ... -}: { - imports = [ - inputs.nixos-hardware.nixosModules.framework-11th-gen-intel - ]; - - nixpkgs.config.allowUnfree = true; - - boot = { - initrd = { - availableKernelModules = ["usb_storage" "sd_mod"]; - }; - kernelModules = ["sg"]; - - # Bootloader. - loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; - }; - }; - - host = { - users = { - leyla = { - isDesktopUser = true; - isTerminalUser = true; - isPrincipleUser = true; - }; - eve.isDesktopUser = true; - }; - - hardware = { - directAccess.enable = true; - }; - - ai = { - enable = true; - models = { - "Llama 3.1 8B" = { - model = "llama3.1:8b"; - roles = ["chat" "edit" "apply"]; - apiBase = "http://defiant:11434"; - }; - "Deepseek Coder:6.7B" = { - model = "deepseek-coder:6.7b"; - roles = ["chat" "edit" "apply"]; - apiBase = "http://defiant:11434"; - }; - "Deepseek Coder:33B" = { - model = "deepseek-coder:33b"; - roles = ["chat" "edit" "apply"]; - apiBase = "http://defiant:11434"; - }; - - "Deepseek r1:8B" = { - model = "deepseek-r1:8b"; - roles = ["chat"]; - apiBase = "http://defiant:11434"; - }; - - "Deepseek r1:32B" = { - model = "deepseek-r1:32b"; - roles = ["chat"]; - apiBase = "http://defiant:11434"; - }; - - "qwen2.5-coder:1.5b-base" = { - model = "qwen2.5-coder:1.5b-base"; - roles = ["autocomplete"]; - apiBase = "http://defiant:11434"; - }; - - "nomic-embed-text:latest" = { - model = "nomic-embed-text:latest"; - roles = ["embed"]; - apiBase = "http://defiant:11434"; - }; - }; - }; - }; - - virtualisation.docker.enable = true; - - environment.systemPackages = with pkgs; [ - cachefilesd - webtoon-dl - android-tools - ]; - services.cachefilesd.enable = true; - - networking = { - networkmanager.enable = true; - hostName = "horizon"; # Define your hostname. - }; - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; - - hardware = { - graphics.enable = true; - }; - - sops.secrets = { - "vpn-keys/tailscale-authkey/horizon" = { - sopsFile = "${inputs.secrets}/vpn-keys.yaml"; - }; - }; - - services = { - # sudo fprintd-enroll - fprintd = { - enable = true; - }; - # firmware update tool - fwupd = { - enable = true; - }; - tailscale = { - enable = true; - authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/horizon".path; - useRoutingFeatures = "client"; - }; - - syncthing.enable = true; - - ollama = { - enable = true; - loadModels = [ - "llama3.1:8b" - ]; - }; - }; - - # Enable network-online.target for better network dependency handling - systemd.services.NetworkManager-wait-online.enable = true; - - # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; - - # Open ports in the firewall. - # networking.firewall.allowedTCPPorts = [ ... ]; - # networking.firewall.allowedUDPPorts = [ ... ]; - # Or disable the firewall altogether. - # networking.firewall.enable = false; - - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It's perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "23.05"; # Did you read the comment? -} diff --git a/configurations/nixos/horizon/default.nix b/configurations/nixos/horizon/default.nix deleted file mode 100644 index b916d82..0000000 --- a/configurations/nixos/horizon/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -# leyla laptop -{...}: { - imports = [ - ./configuration.nix - ./hardware-configuration.nix - # ./network-mount.nix - ]; -} diff --git a/configurations/nixos/horizon/hardware-configuration.nix b/configurations/nixos/horizon/hardware-configuration.nix deleted file mode 100644 index cec4914..0000000 --- a/configurations/nixos/horizon/hardware-configuration.nix +++ /dev/null @@ -1,45 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ - config, - lib, - modulesPath, - ... -}: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "nvme"]; - boot.initrd.kernelModules = []; - boot.kernelModules = ["kvm-intel"]; - boot.extraModulePackages = []; - - fileSystems = { - "/" = { - device = "/dev/disk/by-uuid/866d422b-f816-4ad9-9846-791839cb9337"; - fsType = "ext4"; - }; - - "/boot" = { - device = "/dev/disk/by-uuid/E138-65B5"; - fsType = "vfat"; - }; - }; - - swapDevices = [ - {device = "/dev/disk/by-uuid/be98e952-a072-4c3a-8c12-69500b5a2fff";} - ]; - - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; - # networking.interfaces.tailscale0.useDHCP = lib.mkDefault true; - # networking.interfaces.wlp170s0.useDHCP = lib.mkDefault true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/nixos/horizon/network-mount.nix b/configurations/nixos/horizon/network-mount.nix deleted file mode 100644 index fde16f5..0000000 --- a/configurations/nixos/horizon/network-mount.nix +++ /dev/null @@ -1,76 +0,0 @@ -{...}: { - boot.supportedFilesystems = ["nfs"]; - - fileSystems = { - "/mnt/leyla_documents" = { - device = "defiant:/exports/leyla_documents"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "noatime" - "nofail" - "soft" - "intr" # Allow interruption of NFS calls - "timeo=30" # 3 second timeout (30 deciseconds) - "retrans=2" # Only 2 retries before giving up - "x-systemd.idle-timeout=300" # 5 minute idle timeout for mobile - "x-systemd.device-timeout=15" # 15 second device timeout - "bg" # Background mount - don't block boot - "fsc" # Enable caching - "_netdev" # Network device - wait for network - "x-systemd.requires=network-online.target" # Require network to be online - "x-systemd.after=network-online.target" # Start after network is online - "x-systemd.mount-timeout=30" # 30 second mount timeout - ]; - }; - - "/mnt/users_documents" = { - device = "defiant:/exports/users_documents"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "nofail" - "soft" - "intr" - "timeo=30" - "retrans=2" - "x-systemd.idle-timeout=300" - "x-systemd.device-timeout=15" - "bg" - "fsc" - "_netdev" - "x-systemd.requires=network-online.target" - "x-systemd.after=network-online.target" - "x-systemd.mount-timeout=30" - ]; - }; - - "/mnt/media" = { - device = "defiant:/exports/media"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "noatime" - "nofail" - "soft" - "intr" - "timeo=30" - "retrans=2" - "x-systemd.idle-timeout=300" - "x-systemd.device-timeout=15" - "bg" - # Mobile-optimized read settings - "rsize=8192" # Smaller read size for mobile - "wsize=8192" # Smaller write size for mobile - "fsc" - "_netdev" - "x-systemd.requires=network-online.target" - "x-systemd.after=network-online.target" - "x-systemd.mount-timeout=30" - ]; - }; - }; -} diff --git a/configurations/nixos/twilight/configuration.nix b/configurations/nixos/twilight/configuration.nix deleted file mode 100644 index d02af0a..0000000 --- a/configurations/nixos/twilight/configuration.nix +++ /dev/null @@ -1,156 +0,0 @@ -{ - inputs, - config, - pkgs, - ... -}: { - nixpkgs.config.allowUnfree = true; - - boot.initrd.availableKernelModules = ["usb_storage"]; - boot.kernelModules = ["sg"]; - - boot.loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; - }; - - sops.secrets = { - "vpn-keys/tailscale-authkey/twilight" = { - sopsFile = "${inputs.secrets}/vpn-keys.yaml"; - }; - }; - host = { - users = { - leyla = { - isDesktopUser = true; - isTerminalUser = true; - isPrincipleUser = true; - }; - eve.isDesktopUser = true; - }; - hardware = { - piperMouse.enable = true; - viaKeyboard.enable = true; - openRGB.enable = true; - graphicsAcceleration.enable = true; - directAccess.enable = true; - }; - ai = { - enable = true; - # TODO: benchmark twilight against defiant and prune this list of models that are faster on defiant - models = { - # conversation models - "Llama 3.1 8B" = { - model = "lamma3.1:8b"; - roles = ["chat" "edit" "apply"]; - }; - "deepseek-r1:8b" = { - model = "deepseek-r1:8b"; - roles = ["chat" "edit" "apply"]; - }; - "deepseek-r1:32b" = { - model = "deepseek-r1:32b"; - roles = ["chat" "edit" "apply"]; - }; - - # auto complete models - "qwen2.5-coder:1.5b-base" = { - model = "qwen2.5-coder:1.5b-base"; - roles = ["autocomplete"]; - }; - "qwen2.5-coder:7b" = { - model = "qwen2.5-coder:7b"; - roles = ["autocomplete"]; - }; - "deepseek-coder:6.7b" = { - model = "deepseek-coder:6.7b"; - roles = ["autocomplete"]; - }; - "deepseek-coder:33b" = { - model = "deepseek-coder:33b"; - roles = ["autocomplete"]; - }; - - # agent models - "qwen3:32b" = { - model = "qwen3:32b"; - roles = ["chat" "edit" "apply"]; - }; - - # embedding models - "nomic-embed-text:latest" = { - model = "nomic-embed-text:latest"; - roles = ["embed"]; - }; - }; - }; - }; - services = { - ollama = { - enable = true; - exposePort = true; - - loadModels = [ - # conversation models - "llama3.1:8b" - "deepseek-r1:8b" - "deepseek-r1:32b" - - # auto complete models - "qwen2.5-coder:1.5b-base" - "qwen2.5-coder:7b" - "deepseek-coder:6.7b" - "deepseek-coder:33b" - - # agent models - "qwen3:32b" - - # embedding models - "nomic-embed-text:latest" - ]; - }; - - tailscale = { - enable = true; - authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/twilight".path; - useRoutingFeatures = "both"; - extraUpFlags = [ - "--advertise-exit-node" - "--advertise-routes=192.168.0.0/24" - ]; - extraSetFlags = [ - "--advertise-exit-node" - "--advertise-routes=192.168.0.0/24" - ]; - }; - - syncthing.enable = true; - }; - - # Enable network-online.target for better network dependency handling - systemd.services.NetworkManager-wait-online.enable = true; - - environment.systemPackages = with pkgs; [ - cachefilesd - ]; - hardware.steam-hardware.enable = true; # Provides udev rules for controller, HTC vive, and Valve Index - - networking = { - networkmanager.enable = true; - hostName = "twilight"; # Define your hostname. - }; - - # enabled virtualisation for docker - # virtualisation.docker.enable = true; - - # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; - - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It's perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "23.05"; # Did you read the comment? -} diff --git a/configurations/nixos/twilight/default.nix b/configurations/nixos/twilight/default.nix deleted file mode 100644 index aa841f8..0000000 --- a/configurations/nixos/twilight/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -# leyla desktop -{...}: { - imports = [ - ./configuration.nix - ./hardware-configuration.nix - ./nvidia-drivers.nix - # ./network-mount.nix - ]; -} diff --git a/configurations/nixos/twilight/hardware-configuration.nix b/configurations/nixos/twilight/hardware-configuration.nix deleted file mode 100644 index 1288343..0000000 --- a/configurations/nixos/twilight/hardware-configuration.nix +++ /dev/null @@ -1,42 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ - config, - lib, - modulesPath, - ... -}: { - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "sd_mod"]; - boot.initrd.kernelModules = []; - boot.kernelModules = ["kvm-amd"]; - boot.extraModulePackages = []; - - fileSystems = { - "/" = { - device = "/dev/disk/by-id/nvme-Samsung_SSD_980_500GB_S64ENJ0RA06463Z-part2"; - fsType = "ext4"; - }; - - "/boot" = { - device = "/dev/disk/by-id/nvme-Samsung_SSD_980_500GB_S64ENJ0RA06463Z-part1"; - fsType = "vfat"; - options = ["fmask=0022" "dmask=0022"]; - }; - }; - - swapDevices = []; - - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/nixos/twilight/network-mount.nix b/configurations/nixos/twilight/network-mount.nix deleted file mode 100644 index 9f84b04..0000000 --- a/configurations/nixos/twilight/network-mount.nix +++ /dev/null @@ -1,72 +0,0 @@ -{...}: { - boot.supportedFilesystems = ["nfs"]; - - fileSystems = { - "/mnt/leyla_documents" = { - device = "defiant:/exports/leyla_documents"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "noatime" - "nofail" - "soft" - "intr" # Allow interruption of NFS calls - "timeo=50" # 5 second timeout (50 deciseconds) - longer than mobile - "retrans=3" # 3 retries for desktop - "x-systemd.idle-timeout=600" # 10 minute idle timeout for desktop - "x-systemd.device-timeout=30" # 30 second device timeout - "bg" # Background mount - don't block boot - "fsc" # Enable caching - "_netdev" # Network device - wait for network - "x-systemd.requires=network-online.target" # Require network to be online - "x-systemd.after=network-online.target" # Start after network is online - ]; - }; - - "/mnt/users_documents" = { - device = "defiant:/exports/users_documents"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "nofail" - "soft" - "intr" - "timeo=50" - "retrans=3" - "x-systemd.idle-timeout=600" - "bg" - "fsc" - "_netdev" - "x-systemd.requires=network-online.target" - "x-systemd.after=network-online.target" - ]; - }; - - "/mnt/media" = { - device = "defiant:/exports/media"; - fsType = "nfs"; - options = [ - "x-systemd.automount" - "noauto" - "noatime" - "nofail" - "soft" - "intr" - "timeo=50" - "retrans=3" - "x-systemd.idle-timeout=600" - "x-systemd.device-timeout=30" - "bg" - # Desktop-optimized read settings - "rsize=32768" # Larger read size for desktop - "wsize=32768" # Larger write size for desktop - "fsc" - "_netdev" - "x-systemd.requires=network-online.target" - "x-systemd.after=network-online.target" - ]; - }; - }; -} diff --git a/flake.lock b/flake.lock index dbc4ca5..e787fe8 100644 --- a/flake.lock +++ b/flake.lock @@ -61,6 +61,24 @@ "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, + "locked": { + "lastModified": 1775087534, + "narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, "locked": { "lastModified": 1767609335, "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", @@ -151,6 +169,21 @@ "type": "github" } }, + "import-tree": { + "locked": { + "lastModified": 1773693634, + "narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=", + "owner": "vic", + "repo": "import-tree", + "rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, "lix": { "flake": false, "locked": { @@ -190,7 +223,7 @@ }, "mcp-nixos": { "inputs": { - "flake-parts": "flake-parts", + "flake-parts": "flake-parts_2", "nixpkgs": "nixpkgs" }, "locked": { @@ -301,6 +334,21 @@ } }, "nixpkgs-lib": { + "locked": { + "lastModified": 1774748309, + "narHash": "sha256-+U7gF3qxzwD5TZuANzZPeJTZRHS29OFQgkQ2kiTJBIQ=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "333c4e0545a6da976206c74db8773a1645b5870a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { "locked": { "lastModified": 1765674936, "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", @@ -373,8 +421,10 @@ "disko": "disko", "firefox-addons": "firefox-addons", "flake-compat": "flake-compat", + "flake-parts": "flake-parts", "home-manager": "home-manager", "impermanence": "impermanence", + "import-tree": "import-tree", "lix-module": "lix-module", "mcp-nixos": "mcp-nixos", "nix-darwin": "nix-darwin", diff --git a/flake.nix b/flake.nix index df5f6e9..a734ee4 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,10 @@ # base packages nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + # flake structure + flake-parts.url = "github:hercules-ci/flake-parts"; + import-tree.url = "github:vic/import-tree"; + lix-module = { url = "git+https://git.lix.systems/lix-project/nixos-module.git"; inputs.nixpkgs.follows = "nixpkgs"; @@ -87,95 +91,25 @@ }; }; - outputs = { - self, - nixpkgs, - sops-nix, - nix-syncthing, - home-manager, - impermanence, - ... - } @ inputs: let - util = import ./util {inherit inputs;}; - forEachPkgs = util.forEachPkgs; - - mkNixosSystem = util.mkNixosSystem; - mkDarwinSystem = util.mkDarwinSystem; - mkHome = util.mkHome; - - nixosSystems = { - horizon = mkNixosSystem "horizon"; - twilight = mkNixosSystem "twilight"; - defiant = mkNixosSystem "defiant"; - emergent = mkNixosSystem "emergent"; - }; - - darwinSystems = { - hesperium = mkDarwinSystem "hesperium"; - }; - - homeSystems = { - # stand alone home manager configurations here: - # name = mkHome "name" - }; - - systemsHomes = nixpkgs.lib.attrsets.mergeAttrsList ( - nixpkgs.lib.attrsets.mapAttrsToList (hostname: system: ( - nixpkgs.lib.attrsets.mapAttrs' (user: _: { - name = "${user}@${hostname}"; - value = mkHome { - user = user; - host = hostname; - system = system.pkgs.hostPlatform.system; - osConfig = system.config; + outputs = inputs: + inputs.flake-parts.lib.mkFlake {inherit inputs;} { + imports = [ + inputs.home-manager.flakeModules.home-manager + inputs.nix-darwin.flakeModules.default + ({lib, ...}: { + options.flake.darwinModules = lib.mkOption { + type = lib.types.attrsOf lib.types.unspecified; + default = {}; }; }) - system.config.home-manager.users - )) - (nixosSystems // darwinSystems) - ); - - homeConfigurations = - systemsHomes - // homeSystems; - in { - formatter = forEachPkgs (system: pkgs: pkgs.alejandra); - - # templates = import ./templates; - - devShells = forEachPkgs (system: pkgs: { - default = pkgs.mkShell { - packages = with pkgs; [ - # for version controlling this repo - git - # for formatting code in this repo - alejandra - # for editing secrets in the secrets repo - sops - # for viewing configuration options defined in this repo - nix-inspect - # for installing flakes from this repo onto other systems - nixos-anywhere - # for updating disko configurations - disko - # for viewing dconf entries - dconf-editor - # for MCP NixOS server support in development - inputs.mcp-nixos.packages.${system}.default - ]; - - SOPS_AGE_KEY_DIRECTORY = import ./const/sops_age_key_directory.nix; - - shellHook = '' - git config core.hooksPath .hooks - ''; - }; - }); - - nixosConfigurations = nixosSystems; - - darwinConfigurations = darwinSystems; - - homeConfigurations = homeConfigurations; - }; + ({...}: { + flake.syncthingConfiguration = inputs.nix-syncthing.lib.syncthingConfiguration { + modules = [ + (import ./configurations/syncthing) + ]; + }; + }) + (inputs.import-tree ./modules) + ]; + }; } diff --git a/modules/hosts/darwin/hesperium/configuration.nix b/modules/hosts/darwin/hesperium/configuration.nix new file mode 100644 index 0000000..306596c --- /dev/null +++ b/modules/hosts/darwin/hesperium/configuration.nix @@ -0,0 +1,18 @@ +{...}: { + flake.darwinModules.hesperiumConfiguration = {...}: { + host = { + users = { + leyla = { + isDesktopUser = true; + isTerminalUser = true; + isPrincipleUser = true; + }; + eve.isNormalUser = false; + }; + }; + + system.stateVersion = 5; + + nixpkgs.hostPlatform = "aarch64-darwin"; + }; +} diff --git a/modules/hosts/darwin/hesperium/default.nix b/modules/hosts/darwin/hesperium/default.nix new file mode 100644 index 0000000..8dcde58 --- /dev/null +++ b/modules/hosts/darwin/hesperium/default.nix @@ -0,0 +1,15 @@ +# leyla macbook +{ + inputs, + config, + ... +}: { + flake.darwinConfigurations.hesperium = inputs.nix-darwin.lib.darwinSystem { + system = "aarch64-darwin"; + modules = [ + config.flake.darwinModules.darwinModules + config.flake.darwinModules.hesperiumConfiguration + ]; + specialArgs = {inherit inputs;}; + }; +} diff --git a/modules/hosts/home/eve/configuration.nix b/modules/hosts/home/eve/configuration.nix new file mode 100644 index 0000000..c54d038 --- /dev/null +++ b/modules/hosts/home/eve/configuration.nix @@ -0,0 +1,53 @@ +{...}: { + flake.homeModules.eveBaseConfiguration = {osConfig, ...}: let + userConfig = osConfig.host.users.eve; + in { + home = { + username = userConfig.name; + homeDirectory = osConfig.users.users.eve.home; + + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + stateVersion = "23.11"; # Please read the comment before changing. + + # Home Manager is pretty good at managing dotfiles. The primary way to manage + # plain files is through 'home.file'. + file = { + # # Building this configuration will create a copy of 'dotfiles/screenrc' in + # # the Nix store. Activating the configuration will then make '~/.screenrc' a + # # symlink to the Nix store copy. + # ".screenrc".source = dotfiles/screenrc; + + # # You can also set the file content immediately. + # ".gradle/gradle.properties".text = '' + # org.gradle.console=verbose + # org.gradle.daemon.idletimeout=3600000 + # ''; + }; + + # Home Manager can also manage your environment variables through + # 'home.sessionVariables'. If you don't want to manage your shell through Home + # Manager then you have to manually source 'hm-session-vars.sh' located at + # either + # + # ~/.nix-profile/etc/profile.d/hm-session-vars.sh + # + # or + # + # ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh + # + # or + # + # /etc/profiles/per-user/leyla/etc/profile.d/hm-session-vars.sh + # + sessionVariables = { + # EDITOR = "emacs"; + }; + }; + }; +} diff --git a/modules/hosts/home/eve/default.nix b/modules/hosts/home/eve/default.nix new file mode 100644 index 0000000..0aa5a54 --- /dev/null +++ b/modules/hosts/home/eve/default.nix @@ -0,0 +1,11 @@ +{config, ...}: let + hm = config.flake.homeModules; +in { + flake.homeModules.eveConfiguration = {...}: { + imports = [ + hm.eveBaseConfiguration + hm.eveGnomeconf + hm.evePackages + ]; + }; +} diff --git a/modules/hosts/home/eve/gnomeconf.nix b/modules/hosts/home/eve/gnomeconf.nix new file mode 100644 index 0000000..7bb0fe1 --- /dev/null +++ b/modules/hosts/home/eve/gnomeconf.nix @@ -0,0 +1,41 @@ +{...}: { + flake.homeModules.eveGnomeconf = { + osConfig, + lib, + ... + }: { + config = { + gnome = lib.mkMerge [ + { + colorScheme = "prefer-dark"; + accentColor = "slate"; + clockFormat = "24h"; + nightLight = { + enable = true; + automatic = false; + fromTime = 12.0; + toTime = 11.999999999999; + temperature = 2700; + }; + extraWindowControls = true; + extensions = { + dash-to-panel = { + enable = true; + }; + }; + } + + (lib.mkIf (osConfig.networking.hostName == "horizon") { + displayScaling = 125; + experimentalFeatures = { + scaleMonitorFramebuffer = true; + }; + }) + ]; + + dconf = { + enable = true; + }; + }; + }; +} diff --git a/modules/hosts/home/eve/packages.nix b/modules/hosts/home/eve/packages.nix new file mode 100644 index 0000000..60ed98f --- /dev/null +++ b/modules/hosts/home/eve/packages.nix @@ -0,0 +1,93 @@ +{...}: { + flake.homeModules.evePackages = { + lib, + pkgs, + config, + osConfig, + ... + }: let + userConfig = osConfig.host.users.eve; + hardware = osConfig.host.hardware; + in { + config = { + nixpkgs.config = { + allowUnfree = true; + }; + + # Packages that can be installed without any extra configuration + # See https://search.nixos.org/packages for all options + home.packages = lib.lists.optionals userConfig.isDesktopUser ( + with pkgs; [ + gnomeExtensions.dash-to-panel + claude-code + friture + ] + ); + + # Packages that need to be installed with some extra configuration + # See https://home-manager-options.extranix.com/ for all options + programs = lib.mkMerge [ + { + # Let Home Manager install and manage itself. + home-manager.enable = true; + } + (lib.mkIf (config.user.isDesktopUser || config.user.isTerminalUser) { + git = { + enable = true; + signing.format = "openpgp"; + settings = { + user.name = "Eve"; + user.email = "evesnrobins@gmail.com"; + init.defaultBranch = "main"; + }; + }; + + openssh = { + enable = true; + hostKeys = [ + { + type = "ed25519"; + path = "${config.home.username}_${osConfig.networking.hostName}_ed25519"; + } + ]; + }; + }) + (lib.mkIf config.user.isDesktopUser { + vscode = { + enable = true; + package = pkgs.vscodium; + }; + + firefox.enable = true; + bitwarden.enable = true; + discord.enable = true; + makemkv.enable = true; + signal-desktop.enable = true; + steam.enable = true; + piper.enable = hardware.piperMouse.enable; + krita.enable = true; + ungoogled-chromium.enable = true; + + inkscape.enable = true; + obsidian.enable = true; + obs-studio.enable = true; + kdenlive.enable = true; + tor-browser.enable = true; + olympus.enable = true; + libreoffice.enable = true; + noita-entangled-worlds.enable = true; + + opencode.enable = osConfig.host.ai.enable; + + e621-downloader.enable = true; + + # Windows applications that we need to figure out how to install + guild-wars-2.enable = false; + vortex.enable = false; + dungeon-draft.enable = false; + vmware-workstation.enable = true; + }) + ]; + }; + }; +} diff --git a/modules/hosts/home/git/default.nix b/modules/hosts/home/git/default.nix new file mode 100644 index 0000000..b47b548 --- /dev/null +++ b/modules/hosts/home/git/default.nix @@ -0,0 +1,24 @@ +{...}: { + flake.homeModules.gitConfiguration = {osConfig, ...}: { + impermanence.fallbackPersistence.enable = false; + + home = { + username = osConfig.users.users.git.name; + homeDirectory = osConfig.users.users.git.home; + + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + stateVersion = "23.11"; # Please read the comment before changing. + }; + + programs.ssh.extraConfig = '' + AuthorizedKeysFile + /var/lib/forgejo/.ssh/authorized_keys + ''; + }; +} diff --git a/modules/hosts/home/leyla/configuration.nix b/modules/hosts/home/leyla/configuration.nix new file mode 100644 index 0000000..9f0093d --- /dev/null +++ b/modules/hosts/home/leyla/configuration.nix @@ -0,0 +1,90 @@ +{...}: { + flake.homeModules.leylaBaseConfiguration = { + pkgs, + config, + osConfig, + ... + }: { + config = { + impermanence.enable = osConfig.storage.impermanence.enable; + + # Home Manager needs a bit of information about you and the paths it should + # manage. + home = { + username = osConfig.host.users.leyla.name; + homeDirectory = osConfig.users.users.leyla.home; + + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + stateVersion = "23.11"; # Please read the comment before changing. + + # Home Manager is pretty good at managing dotfiles. The primary way to manage + # plain files is through 'home.file'. + file = { + # # Building this configuration will create a copy of 'dotfiles/screenrc' in + # # the Nix store. Activating the configuration will then make '~/.screenrc' a + # # symlink to the Nix store copy. + # ".screenrc".source = dotfiles/screenrc; + + # # You can also set the file content immediately. + # ".gradle/gradle.properties".text = '' + # org.gradle.console=verbose + # org.gradle.daemon.idletimeout=3600000 + # ''; + "${config.xdg.configHome}/user-dirs.dirs" = { + force = true; + text = '' + # This file is written by xdg-user-dirs-update + # If you want to change or add directories, just edit the line you're + # interested in. All local changes will be retained on the next run. + # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped + # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an + # absolute path. No other format is supported. + # + XDG_DESKTOP_DIR="$HOME/desktop" + XDG_DOWNLOAD_DIR="$HOME/downloads" + XDG_DOCUMENTS_DIR="$HOME/documents" + XDG_TEMPLATES_DIR="$HOME/documents/templates" + XDG_MUSIC_DIR="$HOME/documents/music" + XDG_PICTURES_DIR="$HOME/documents/photos" + XDG_VIDEOS_DIR="$HOME/documents/videos" + XDG_PUBLICSHARE_DIR="$HOME/documents/public" + ''; + }; + }; + + keyboard.layout = "us,it,de"; + + # Home Manager can also manage your environment variables through + # 'home.sessionVariables'. If you don't want to manage your shell through Home + # Manager then you have to manually source 'hm-session-vars.sh' located at + # either + # + # ~/.nix-profile/etc/profile.d/hm-session-vars.sh + # + # or + # + # ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh + # + # or + # + # /etc/profiles/per-user/leyla/etc/profile.d/hm-session-vars.sh + # + sessionVariables = { + # EDITOR = "emacs"; + }; + }; + + # TODO: move this into a fonts module + home.packages = with pkgs; [ + aileron + ]; + fonts.fontconfig.enable = true; + }; + }; +} diff --git a/modules/hosts/home/leyla/dconf.nix b/modules/hosts/home/leyla/dconf.nix new file mode 100644 index 0000000..3c61452 --- /dev/null +++ b/modules/hosts/home/leyla/dconf.nix @@ -0,0 +1,49 @@ +{...}: { + flake.homeModules.leylaDconf = {...}: { + config = { + gnome = { + extraWindowControls = true; + colorScheme = "prefer-dark"; + clockFormat = "24h"; + nightLight = { + enable = true; + automatic = false; + fromTime = 12.0; + toTime = 11.999999999999; + temperature = 2700; + }; + extensions = { + dash-to-dock = { + enable = true; + options = { + "dock-position" = "LEFT"; + "intellihide-mode" = "ALL_WINDOWS"; + "show-trash" = false; + "require-pressure-to-show" = false; + "show-mounts" = false; + }; + }; + }; + hotkeys = { + "Open Terminal" = { + binding = "t"; + command = "kgx"; + }; + "Open Firefox" = { + binding = "f"; + command = "firefox"; + }; + }; + }; + + dconf = { + enable = true; + settings = { + "org/gnome/shell" = { + favorite-apps = ["org.gnome.Nautilus.desktop" "firefox.desktop" "codium.desktop" "steam.desktop" "org.gnome.Console.desktop"]; + }; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/default.nix b/modules/hosts/home/leyla/default.nix new file mode 100644 index 0000000..daea8fc --- /dev/null +++ b/modules/hosts/home/leyla/default.nix @@ -0,0 +1,23 @@ +{config, ...}: let + hm = config.flake.homeModules; +in { + flake.homeModules.leylaConfiguration = {...}: { + imports = [ + hm.leylaBaseConfiguration + hm.leylaDconf + hm.leylaI18n + hm.leylaImpermanence + hm.leylaPackages + hm.leylaDirenv + hm.leylaGit + hm.leylaMakemkv + hm.leylaOpenssh + hm.leylaFirefox + hm.leylaFirefoxProfile + hm.leylaFirefoxBookmarks + hm.leylaFirefoxHarden + hm.leylaVscode + hm.leylaVscodeUserWords + ]; + }; +} diff --git a/modules/hosts/home/leyla/i18n.nix b/modules/hosts/home/leyla/i18n.nix new file mode 100644 index 0000000..3709756 --- /dev/null +++ b/modules/hosts/home/leyla/i18n.nix @@ -0,0 +1,14 @@ +{...}: { + flake.homeModules.leylaI18n = {...}: { + i18n = { + defaultLocale = "en_IE.UTF-8"; + + extraLocaleSettings = { + # LC_ADDRESS = "en_IE.UTF-8"; # lets just get used to this one now + # LC_TELEPHONE = "en_IE.UTF-8"; # lets just get used to this one now + LC_MONETARY = "en_US.UTF-8"; # to be changed once I move + LC_PAPER = "en_US.UTF-8"; # convenient for american printers until I move + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/impermanence.nix b/modules/hosts/home/leyla/impermanence.nix new file mode 100644 index 0000000..c21c13f --- /dev/null +++ b/modules/hosts/home/leyla/impermanence.nix @@ -0,0 +1,21 @@ +{...}: { + flake.homeModules.leylaImpermanence = { + lib, + config, + ... + }: { + config = lib.mkIf (config.impermanence.enable) { + home.persistence."${config.impermanence.persistencePath}" = { + directories = [ + "desktop" + "downloads" + "documents" + ]; + files = [ + ".bash_history" # keep shell history around + "${config.xdg.dataHome}/recently-used.xbel" # gnome recently viewed files + ]; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/default.nix b/modules/hosts/home/leyla/packages/default.nix new file mode 100644 index 0000000..b220ab9 --- /dev/null +++ b/modules/hosts/home/leyla/packages/default.nix @@ -0,0 +1,91 @@ +{...}: { + flake.homeModules.leylaPackages = { + lib, + pkgs, + config, + osConfig, + ... + }: let + hardware = osConfig.host.hardware; + in { + config = lib.mkMerge [ + { + programs = lib.mkMerge [ + { + # Let Home Manager install and manage itself. + home-manager.enable = true; + } + (lib.mkIf (config.user.isTerminalUser || config.user.isDesktopUser) { + bash.enable = true; + git.enable = true; + openssh.enable = true; + }) + (lib.mkIf config.user.isDesktopUser { + bitwarden.enable = true; + obs-studio.enable = hardware.graphicsAcceleration.enable; + qbittorrent.enable = true; + prostudiomasters.enable = true; + protonvpn-gui.enable = true; + dbeaver-bin.enable = true; + bruno.enable = true; + piper.enable = hardware.piperMouse.enable; + proxmark3.enable = true; + openrgb.enable = hardware.openRGB.enable; + via.enable = hardware.viaKeyboard.enable; + claude-code.enable = osConfig.host.ai.enable; + opencode.enable = osConfig.host.ai.enable; + davinci-resolve.enable = hardware.graphicsAcceleration.enable; + mfoc.enable = true; + }) + (lib.mkIf (hardware.directAccess.enable && config.user.isDesktopUser) { + anki.enable = true; + android-studio.enable = true; + makemkv.enable = true; + discord.enable = true; + signal-desktop.enable = true; + calibre.enable = true; + obsidian.enable = true; + jetbrains.idea-oss.enable = true; + vscode.enable = true; + firefox.enable = true; + steam.enable = true; + krita.enable = true; + ungoogled-chromium.enable = true; + libreoffice.enable = true; + mapillary-uploader.enable = true; + inkscape.enable = true; + gimp.enable = true; + freecad.enable = true; + onionshare.enable = true; + pdfarranger.enable = true; + picard.enable = true; + qflipper.enable = true; + openvpn.enable = true; + noisetorch.enable = true; + noita-entangled-worlds.enable = true; + tor-browser.enable = true; + gdx-liftoff.enable = true; + proton-mail-pwa.enable = true; + proton-calendar-pwa.enable = true; + matrix-cyberia-pwa.enable = true; + kicad.enable = true; + }) + ]; + } + (lib.mkIf config.user.isTerminalUser { + home.packages = with pkgs; [ + # command line tools + sox + yt-dlp + ffmpeg + imagemagick + ]; + }) + (lib.mkIf config.user.isDesktopUser { + nixpkgs.config = { + allowUnfree = true; + }; + }) + ]; + }; +} diff --git a/modules/hosts/home/leyla/packages/direnv.nix b/modules/hosts/home/leyla/packages/direnv.nix new file mode 100644 index 0000000..18033e7 --- /dev/null +++ b/modules/hosts/home/leyla/packages/direnv.nix @@ -0,0 +1,24 @@ +{...}: { + flake.homeModules.leylaDirenv = { + lib, + config, + osConfig, + ... + }: let + userConfig = osConfig.host.users.leyla; + in { + config = lib.mkIf userConfig.isDesktopUser { + programs = { + direnv = { + enable = true; + enableBashIntegration = true; + nix-direnv.enable = true; + config = { + global.hide_env_diff = true; + whitelist.exact = ["${config.home.homeDirectory}/documents/code/nix-config"]; + }; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/firefox/bookmarks.nix b/modules/hosts/home/leyla/packages/firefox/bookmarks.nix new file mode 100644 index 0000000..21da87f --- /dev/null +++ b/modules/hosts/home/leyla/packages/firefox/bookmarks.nix @@ -0,0 +1,163 @@ +{...}: { + flake.homeModules.leylaFirefoxBookmarks = {...}: { + programs.firefox = { + profiles.leyla = { + bookmarks = { + force = true; + settings = [ + # Personal Services + { + name = "Media"; + url = "https://media.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Photos"; + url = "https://photos.jan-leila.com"; + keyword = ""; + tags = [""]; + } + { + name = "Git"; + url = "https://git.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Home Automation"; + url = "https://home.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Search"; + url = "https://search.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Budget"; + url = "https://search.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Documents"; + url = "https://documents.jan-leila.com/"; + keyword = ""; + tags = [""]; + } + + # Defiant Server Services + { + name = "QBittorrent"; + url = "http://defiant:8084"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Sonarr"; + url = "http://defiant:8989"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Radarr"; + url = "http://defiant:7878"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Bazarr"; + url = "http://defiant:6767"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Lidarr"; + url = "http://defiant:8686"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Jackett"; + url = "http://defiant:9117"; + keyword = ""; + tags = ["defiant"]; + } + { + name = "Crab-hole DNS"; + url = "http://defiant:8085"; + keyword = ""; + tags = ["defiant"]; + } + + # External Services + { + name = "Mail"; + url = "https://mail.protonmail.com"; + keyword = ""; + tags = [""]; + } + { + name = "Open Street Map"; + url = "https://www.openstreetmap.org/"; + keyword = ""; + tags = [""]; + } + { + name = "Password Manager"; + url = "https://vault.bitwarden.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Mastodon"; + url = "https://mspsocial.net"; + keyword = ""; + tags = [""]; + } + { + name = "Linked In"; + url = "https://www.linkedin.com/"; + keyword = ""; + tags = [""]; + } + { + name = "Job Search"; + url = "https://www.jobsinnetwork.com/?state=cleaned_history&language%5B%5D=en&query=react&locations.countryCode%5B%5D=IT&locations.countryCode%5B%5D=DE&locations.countryCode%5B%5D=NL&experience%5B%5D=medior&experience%5B%5D=junior&page=1"; + keyword = ""; + tags = [""]; + } + { + name = "React Docs"; + url = "https://react.dev/"; + keyword = ""; + tags = [""]; + } + { + name = "Cyberia Matrix"; + url = "https://chat.cyberia.club"; + keyword = ""; + tags = [""]; + } + { + name = "Cyberia Git"; + url = "https://git.cyberia.club"; + keyword = ""; + tags = [""]; + } + # Template + # { + # name = ""; + # url = ""; + # keyword = ""; + # tags = [""]; + # } + ]; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/firefox/default.nix b/modules/hosts/home/leyla/packages/firefox/default.nix new file mode 100644 index 0000000..713e8c7 --- /dev/null +++ b/modules/hosts/home/leyla/packages/firefox/default.nix @@ -0,0 +1,9 @@ +{...}: { + flake.homeModules.leylaFirefox = {...}: { + config = { + programs.firefox = { + enable = true; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/firefox/firefox.nix b/modules/hosts/home/leyla/packages/firefox/firefox.nix new file mode 100644 index 0000000..e37992e --- /dev/null +++ b/modules/hosts/home/leyla/packages/firefox/firefox.nix @@ -0,0 +1,193 @@ +{...}: { + flake.homeModules.leylaFirefoxProfile = { + lib, + pkgs, + inputs, + ... + }: { + programs.firefox = { + profiles.leyla = { + settings = { + "browser.search.defaultenginename" = "Searx"; + "browser.search.order.1" = "Searx"; + }; + + search = { + force = true; + default = "Searx"; + engines = { + "Nix Packages" = { + urls = [ + { + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + } + ]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = ["@np"]; + }; + "NixOS Wiki" = { + urls = [{template = "https://nixos.wiki/index.php?search={searchTerms}";}]; + icon = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@nw"]; + }; + "Searx" = { + urls = [{template = "https://search.jan-leila.com/?q={searchTerms}";}]; + icon = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@searx"]; + }; + }; + }; + + extensions.packages = with inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [ + bitwarden + terms-of-service-didnt-read + multi-account-containers + shinigami-eyes + + ublock-origin + sponsorblock + dearrow + df-youtube + return-youtube-dislikes + + privacy-badger + decentraleyes + clearurls + localcdn + + snowflake + + pkgs.firefox-extensions.deutsch-de-language-pack + dictionary-german + + tab-session-manager + + pkgs.firefox-extensions.italiano-it-language-pack + pkgs.firefox-extensions.dizionario-italiano + ]; + + settings = { + # Disable irritating first-run stuff + "browser.disableResetPrompt" = true; + "browser.download.panel.shown" = true; + "browser.feeds.showFirstRunUI" = false; + "browser.messaging-system.whatsNewPanel.enabled" = false; + "browser.rights.3.shown" = true; + "browser.shell.checkDefaultBrowser" = false; + "browser.shell.defaultBrowserCheckCount" = 1; + "browser.startup.homepage_override.mstone" = "ignore"; + "browser.uitour.enabled" = false; + "startup.homepage_override_url" = ""; + "trailhead.firstrun.didSeeAboutWelcome" = true; + "browser.bookmarks.restore_default_bookmarks" = false; + "browser.bookmarks.addedImportButton" = true; + "browser.newtabpage.activity-stream.feeds.section.topstories" = false; + + # Usage Experience + "browser.startup.homepage" = "about:home"; + "browser.download.useDownloadDir" = false; + "browser.uiCustomization.state" = builtins.toJSON { + "currentVersion" = 20; + "newElementCount" = 6; + "dirtyAreaCache" = [ + "nav-bar" + "PersonalToolbar" + "toolbar-menubar" + "TabsToolbar" + "unified-extensions-area" + "vertical-tabs" + ]; + "placements" = { + "widget-overflow-fixed-list" = []; + "unified-extensions-area" = [ + # bitwarden + "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" + "ublock0_raymondhill_net-browser-action" + "sponsorblocker_ajay_app-browser-action" + "dearrow_ajay_app-browser-action" + "jid1-mnnxcxisbpnsxq_jetpack-browser-action" + "_testpilot-containers-browser-action" + "addon_simplelogin-browser-action" + "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" + "jid1-bofifl9vbdl2zq_jetpack-browser-action" + "dfyoutube_example_com-browser-action" + "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" + "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" + "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browse-action" + "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" + ]; + "nav-bar" = [ + "back-button" + "forward-button" + "stop-reload-button" + "urlbar-container" + "downloads-button" + "unified-extensions-button" + "reset-pbm-toolbar-button" + ]; + "toolbar-menubar" = [ + "menubar-items" + ]; + "TabsToolbar" = [ + "firefox-view-button" + "tabbrowser-tabs" + "new-tab-button" + "alltabs-button" + ]; + "vertical-tabs" = []; + "PersonalToolbar" = [ + "import-button" + "personal-bookmarks" + ]; + }; + "seen" = [ + "save-to-pocket-button" + "developer-button" + "privacy_privacy_com-browser-action" + "sponsorblocker_ajay_app-browser-action" + "ublock0_raymondhill_net-browser-action" + "addon_simplelogin-browser-action" + "dearrow_ajay_app-browser-action" + "_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" + "_74145f27-f039-47ce-a470-a662b129930a_-browser-action" + "jid1-bofifl9vbdl2zq_jetpack-browser-action" + "dfyoutube_example_com-browser-action" + "_testpilot-containers-browser-action" + "_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action" + "jid1-mnnxcxisbpnsxq_jetpack-browser-action" + "_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action" + "_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browser-action" + "jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action" + ]; + }; + "browser.newtabpage.activity-stream.feeds.topsites" = false; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false; + "browser.newtabpage.blocked" = lib.genAttrs [ + # Facebook + "4gPpjkxgZzXPVtuEoAL9Ig==" + # Reddit + "gLv0ja2RYVgxKdp0I5qwvA==" + # Amazon + "K00ILysCaEq8+bEqV/3nuw==" + # Twitter + "T9nJot5PurhJSy8n038xGA==" + ] (_: 1); + "identity.fxaccounts.enabled" = false; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/firefox/harden.nix b/modules/hosts/home/leyla/packages/firefox/harden.nix new file mode 100644 index 0000000..48841d6 --- /dev/null +++ b/modules/hosts/home/leyla/packages/firefox/harden.nix @@ -0,0 +1,52 @@ +{...}: { + flake.homeModules.leylaFirefoxHarden = {...}: { + programs.firefox = { + profiles.leyla = { + settings = { + # Security + "privacy.trackingprotection.enabled" = true; + "dom.security.https_only_mode" = true; + "dom.security.https_only_mode_pbm" = true; + "dom.security.https_only_mode_error_page_user_suggestions" = true; + + # Privacy & Data Protection + "extensions.formautofill.addresses.enabled" = false; + "extensions.formautofill.creditCards.enabled" = false; + "signon.rememberSignons" = false; + "privacy.sanitize.sanitizeOnShutdown" = true; + "privacy.clearOnShutdown_v2.cache" = true; + "privacy.clearOnShutdown_v2.cookiesAndStorage" = true; + "privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = true; + "urlclassifier.trackingSkipURLs" = ""; + "urlclassifier.features.socialtracking.skipURLs" = ""; + + # Disable telemetry and data collection + "app.shield.optoutstudies.enabled" = false; + "browser.discovery.enabled" = false; + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + "browser.ping-centre.telemetry" = false; + "datareporting.healthreport.service.enabled" = false; + "datareporting.healthreport.uploadEnabled" = false; + "datareporting.policy.dataSubmissionEnabled" = false; + "datareporting.sessions.current.clean" = true; + "devtools.onboarding.telemetry.logged" = false; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.hybridContent.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.prompted" = 2; + "toolkit.telemetry.rejected" = true; + "toolkit.telemetry.reportingpolicy.firstRun" = false; + "toolkit.telemetry.server" = ""; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.unifiedIsOptIn" = false; + "toolkit.telemetry.updatePing.enabled" = false; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/git.nix b/modules/hosts/home/leyla/packages/git.nix new file mode 100644 index 0000000..47689a1 --- /dev/null +++ b/modules/hosts/home/leyla/packages/git.nix @@ -0,0 +1,16 @@ +{...}: { + flake.homeModules.leylaGit = {...}: { + config = { + programs = { + git = { + signing.format = "openpgp"; + settings = { + user.name = "Leyla Becker"; + user.email = "git@jan-leila.com"; + init.defaultBranch = "main"; + }; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/makemkv.nix b/modules/hosts/home/leyla/packages/makemkv.nix new file mode 100644 index 0000000..9330730 --- /dev/null +++ b/modules/hosts/home/leyla/packages/makemkv.nix @@ -0,0 +1,19 @@ +{...}: { + flake.homeModules.leylaMakemkv = { + config, + inputs, + ... + }: { + config = { + sops.secrets = { + "application-keys/makemkv" = { + sopsFile = "${inputs.secrets}/application-keys.yaml"; + }; + }; + programs.makemkv = { + appKeyFile = config.sops.placeholder."application-keys/makemkv"; + destinationDir = "/home/leyla/downloads/makemkv"; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/openssh.nix b/modules/hosts/home/leyla/packages/openssh.nix new file mode 100644 index 0000000..1c5e6ec --- /dev/null +++ b/modules/hosts/home/leyla/packages/openssh.nix @@ -0,0 +1,25 @@ +{...}: { + flake.homeModules.leylaOpenssh = { + config, + osConfig, + ... + }: { + config = { + programs = { + openssh = { + authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJHeItmt8TRW43uNcOC+eIurYC7Eunc0V3LGocQqLaYj leyla@horizon" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIILimFIW2exEH/Xo7LtXkqgE04qusvnPNpPWSCeNrFkP leyla@defiant" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKBiZkg1c2aaNHiieBX4cEziqvJVj9pcDfzUrKU/mO0I leyla@twilight" + ]; + hostKeys = [ + { + type = "ed25519"; + path = "${config.home.username}_${osConfig.networking.hostName}_ed25519"; + } + ]; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/vscode/default.nix b/modules/hosts/home/leyla/packages/vscode/default.nix new file mode 100644 index 0000000..b49316a --- /dev/null +++ b/modules/hosts/home/leyla/packages/vscode/default.nix @@ -0,0 +1,140 @@ +{...}: { + flake.homeModules.leylaVscode = { + lib, + pkgs, + config, + osConfig, + ... + }: let + nix-development-enabled = osConfig.host.nix-development.enable; + ai-tooling-enabled = osConfig.host.ai.enable; + in { + config = lib.mkIf config.user.isDesktopUser { + programs = { + bash.shellAliases = { + code = "codium"; + }; + + vscode = { + package = pkgs.vscodium; + + mutableExtensionsDir = false; + + profiles.default = { + enableUpdateCheck = false; + enableExtensionUpdateCheck = false; + + userSettings = lib.mkMerge [ + { + "javascript.updateImportsOnFileMove.enabled" = "always"; + "editor.tabSize" = 2; + "editor.insertSpaces" = false; + # "terminal.integrated.fontFamily" = "'Droid Sans Mono', 'monospace', monospace"; + } + ]; + + extraExtensions = { + # vs code feel + oneDark.enable = true; + atomKeybindings.enable = true; + openRemoteSsh.enable = true; + # openDyslexicFont.enable = false; + + # html development + autoRenameTag.enable = true; + liveServer.enable = true; + + # js development + es7ReactJsSnippets.enable = true; + tauriVscode.enable = true; + vscodeEslint.enable = true; + vscodeJest.enable = true; + vitest.enable = true; + vscodeStandard.enable = true; + vscodeStylelint.enable = true; + + nearley.enable = true; + + # graphql + graphql.enable = true; + + # astro development + vscodeMdx.enable = true; + astroVscode.enable = true; + + # nix development + alejandra.enable = nix-development-enabled; + nixIde.enable = nix-development-enabled; + + # go development + go.enable = true; + + # rust development + rustAnalyzer.enable = true; + + # arduino development + platformIO.enable = false; + + # claude development + claudeDev = lib.mkIf ai-tooling-enabled { + enable = false; + mcp = { + nixos = { + enable = true; + autoApprove = { + nixos_search = true; + nixos_info = true; + home_manager_search = true; + home_manager_info = true; + darwin_search = true; + darwin_info = true; + nixos_flakes_search = true; + }; + }; + eslint = { + enable = true; + autoApprove = { + lint-files = true; + }; + }; + vitest = { + enable = true; + autoApprove = { + list_tests = true; + run_tests = true; + analyze_coverage = true; + set_project_root = true; + }; + }; + sleep = { + enable = true; + timeout = 18000; # 5 hours to match claude codes timeout + autoApprove = { + sleep = true; + }; + }; + }; + }; + + # misc extensions + evenBetterToml.enable = true; + direnv.enable = config.programs.direnv.enable; + conventionalCommits.enable = true; + }; + + extensions = let + extension-pkgs = pkgs.nix-vscode-extensions.forVSCodeVersion config.programs.vscode.package.version; + in ( + with extension-pkgs.open-vsx; [ + # vs code feel extensions + streetsidesoftware.code-spell-checker + streetsidesoftware.code-spell-checker-german + streetsidesoftware.code-spell-checker-italian + ] + ); + }; + }; + }; + }; + }; +} diff --git a/modules/hosts/home/leyla/packages/vscode/user-words.nix b/modules/hosts/home/leyla/packages/vscode/user-words.nix new file mode 100644 index 0000000..e22e458 --- /dev/null +++ b/modules/hosts/home/leyla/packages/vscode/user-words.nix @@ -0,0 +1,129 @@ +{...}: { + flake.homeModules.leylaVscodeUserWords = { + pkgs, + lib, + ... + }: { + config.programs.vscode.profiles.default.userSettings = { + "cSpell.userWords" = [ + "leyla" + "Cyberia" + ]; + + "cSpell.languageSettings" = [ + { + "languageId" = "nix"; + "locale" = "*"; + "dictionaries" = [ + "applications" + "ai-words" + "nix-words" + + # We need to include all other dictionaries in the nix language settings because they exist in this file + # TODO: see if there is a way to make this only apply for this file + "js-words" + ]; + } + { + "languageId" = "javascript,typescript,js,ts"; + "locale" = "*"; + "dictionaries" = [ + "js-words" + ]; + } + ]; + + "cSpell.customDictionaries" = { + applications = { + name = "applications"; + description = "application names"; + path = pkgs.writeText "applications.txt" (lib.strings.concatLines [ + "ollama" + "syncthing" + "immich" + "sonos" + "makemkv" + "hass" + "qbittorent" + "prostudiomasters" + "protonmail" + "pulseaudio" + ]); + }; + + ai-words = { + name = "ai-words"; + description = "common words used for ai development"; + path = pkgs.writeText "ai-words.txt" (lib.strings.concatLines [ + "ollama" + "deepseek" + "qwen" + ]); + }; + + nix-words = { + name = "nix-words"; + description = "words used in nix configurations"; + path = pkgs.writeText "nix-words.txt" (lib.strings.concatLines [ + "pname" + "direnv" + "tmpfiles" + "Networkd" + "networkmanager" + "dialout" + "adbusers" + "authkey" + "netdevs" + "atomix" + "geary" + "gedit" + "hitori" + "iagno" + "alsa" + "timezoned" + "pipewire" + "rtkit" + "disko" + "ashift" + "autotrim" + "canmount" + "mountpoint" + "xattr" + "acltype" + "relatime" + "keyformat" + "keylocation" + "vdevs" + + # codium extensions + "akamud" + "onedark" + "jeanp" + "dsznajder" + "dbaeumer" + "orta" + "tauri" + "unifiedjs" + "tamasfe" + "pinage" + "jnoortheen" + "kamadorueda" + "karyfoundation" + "nearley" + + # nix.optimise is spelled wrong + "optimise" + ]); + }; + + js-words = { + name = "js-words"; + description = "words used in js development"; + path = pkgs.writeText "js-words.txt" (lib.strings.concatLines [ + "webdav" + ]); + }; + }; + }; + }; +} diff --git a/modules/hosts/nixos/defiant/configuration.nix b/modules/hosts/nixos/defiant/configuration.nix new file mode 100644 index 0000000..c95280a --- /dev/null +++ b/modules/hosts/nixos/defiant/configuration.nix @@ -0,0 +1,454 @@ +{...}: { + # server nas + flake.nixosModules.defiantConfiguration = { + inputs, + config, + ... + }: { + sops.secrets = { + "vpn-keys/tailscale-authkey/defiant" = { + sopsFile = "${inputs.secrets}/vpn-keys.yaml"; + }; + "vpn-keys/proton-wireguard/defiant-p2p" = { + sopsFile = "${inputs.secrets}/vpn-keys.yaml"; + mode = "0640"; + owner = "root"; + group = "systemd-network"; + }; + "services/zfs_smtp_token" = { + sopsFile = "${inputs.secrets}/defiant-services.yaml"; + }; + "services/paperless_password" = { + sopsFile = "${inputs.secrets}/defiant-services.yaml"; + mode = "0700"; + owner = "paperless"; + group = "paperless"; + }; + }; + + host = { + users = { + leyla = { + isDesktopUser = true; + isTerminalUser = true; + isPrincipleUser = true; + }; + }; + network_storage = { + enable = true; + directories = [ + { + folder = "leyla_documents"; + user = "leyla"; + group = "leyla"; + bind = "/home/leyla/documents"; + } + { + folder = "eve_documents"; + user = "eve"; + group = "eve"; + } + { + folder = "users_documents"; + user = "root"; + group = "users"; + } + { + folder = "media"; + user = "jellyfin"; + group = "jellyfin_media"; + bind = config.services.jellyfin.media_directory; + } + ]; + nfs = { + enable = true; + directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; + }; + }; + }; + + storage = { + zfs = { + enable = true; + notifications = { + enable = true; + host = "smtp.protonmail.ch"; + port = 587; + to = "leyla@jan-leila.com"; + user = "noreply@jan-leila.com"; + tokenFile = config.sops.secrets."services/zfs_smtp_token".path; + }; + pool = { + encryption = { + enable = true; + }; + vdevs = [ + [ + "ata-ST18000NE000-3G6101_ZVTCXVEB" + "ata-ST18000NE000-3G6101_ZVTCXWSC" + "ata-ST18000NE000-3G6101_ZVTD10EH" + "ata-ST18000NT001-3NF101_ZVTE0S3Q" + "ata-ST18000NT001-3NF101_ZVTEF27J" + "ata-ST18000NE000-3G6101_ZVTJ7359" + ] + [ + "ata-ST4000NE001-2MA101_WS2275P3" + "ata-ST4000NE001-2MA101_WS227B9F" + "ata-ST4000NE001-2MA101_WS227CEW" + "ata-ST4000NE001-2MA101_WS227CYN" + "ata-ST4000NE001-2MA101_WS23TBWV" + "ata-ST4000NE001-2MA101_WS23TC5F" + ] + ]; + # We are having to boot off of the nvm cache drive because I cant figure out how to boot via the HBA + cache = [ + { + device = "nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"; + boot = true; + } + ]; + }; + }; + impermanence = { + enable = true; + }; + }; + + # bond0 and wg0 are managed by systemd-networkd; tell NetworkManager to + # leave them alone so NM-wait-online doesn't time out waiting for them. + networking.networkmanager.unmanaged = ["bond0" "wg0" "eno1" "eno2"]; + + systemd.network = { + enable = true; + + netdevs = { + "10-bond0" = { + netdevConfig = { + Kind = "bond"; + Name = "bond0"; + }; + bondConfig = { + Mode = "active-backup"; + PrimaryReselectPolicy = "always"; + }; + }; + + "20-wg0" = { + netdevConfig = { + Kind = "wireguard"; + Name = "wg0"; + }; + wireguardConfig = { + PrivateKeyFile = config.sops.secrets."vpn-keys/proton-wireguard/defiant-p2p".path; + ListenPort = 51820; + }; + wireguardPeers = [ + { + PublicKey = "rRO6yJim++Ezz6scCLMaizI+taDjU1pzR2nfW6qKbW0="; + Endpoint = "185.230.126.146:51820"; + # Allow all traffic but use policy routing to prevent system-wide VPN + AllowedIPs = ["0.0.0.0/0"]; + PersistentKeepalive = 25; + } + ]; + }; + }; + networks = { + "40-bond0" = { + matchConfig.Name = "bond0"; + linkConfig = { + RequiredForOnline = "degraded-carrier"; + RequiredFamilyForOnline = "any"; + }; + networkConfig.DHCP = "yes"; + + address = [ + "192.168.1.2/24" + ]; + + # Set lower priority for default gateway to allow WireGuard interface binding + routes = [ + { + Destination = "0.0.0.0/0"; + Gateway = "192.168.1.1"; + Metric = 100; + } + ]; + dns = ["192.168.1.1"]; + }; + + "50-wg0" = { + matchConfig.Name = "wg0"; + # Don't block networkd-wait-online on the VPN tunnel coming up + linkConfig.RequiredForOnline = "no"; + networkConfig = { + DHCP = "no"; + }; + address = [ + "10.2.0.2/32" + ]; + # Configure routing for application binding + routingPolicyRules = [ + { + # Route traffic from VPN interface through VPN table + From = "10.2.0.2/32"; + Table = 200; + Priority = 100; + } + ]; + routes = [ + { + # Direct route to VPN gateway + Destination = "10.2.0.1/32"; + Scope = "link"; + } + { + # Route VPN subnet through VPN gateway in custom table + Destination = "10.2.0.0/16"; + Gateway = "10.2.0.1"; + Table = 200; + } + { + # Route all traffic through VPN gateway in custom table + Destination = "0.0.0.0/0"; + Gateway = "10.2.0.1"; + Table = 200; + } + ]; + }; + }; + }; + + # limit arc usage to 50gb because ollama doesn't play nice with zfs using up all of the memory + boot.kernelParams = ["zfs.zfs_arc_max=53687091200"]; + + # Enable policy routing and source routing for application-specific VPN binding + boot.kernel.sysctl = { + "net.ipv4.conf.all.rp_filter" = 2; + "net.ipv4.conf.default.rp_filter" = 2; + "net.ipv4.conf.wg0.rp_filter" = 2; + }; + + services = { + # PostgreSQL database server + postgresql = { + enable = true; + adminUsers = ["leyla"]; + impermanence.enable = false; + }; + + # temp enable desktop environment for setup + # Enable the X11 windowing system. + xserver.enable = true; + + # Enable the GNOME Desktop Environment. + displayManager = { + gdm.enable = true; + }; + desktopManager = { + gnome.enable = true; + }; + + # Enable new reverse proxy system + reverseProxy = { + enable = true; + openFirewall = true; + impermanence.enable = false; + acme = { + enable = true; + email = "jan-leila@protonmail.com"; + }; + }; + + ollama = { + enable = true; + exposePort = true; + impermanence.enable = false; + + environmentVariables = { + OLLAMA_KEEP_ALIVE = "24h"; + }; + + loadModels = [ + # conversation models + "llama3.1:8b" + "deepseek-r1:8b" + "deepseek-r1:32b" + "deepseek-r1:70b" + + # auto complete models + "qwen2.5-coder:1.5b-base" + "qwen2.5-coder:7b" + "deepseek-coder:6.7b" + "deepseek-coder:33b" + + # agent models + "qwen3:8b" + "qwen3:32b" + "qwen3:235b-a22b" + + "qwen3-coder:30b" + "qwen3-coder:30b-a3b-fp16" + + # embedding models + "nomic-embed-text:latest" + ]; + }; + tailscale = { + enable = true; + authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/defiant".path; + useRoutingFeatures = "server"; + impermanence.enable = false; + extraUpFlags = [ + "--advertise-exit-node" + "--advertise-routes=192.168.0.0/24" + "--accept-dns=false" + ]; + extraSetFlags = [ + "--advertise-exit-node" + "--advertise-routes=192.168.0.0/24" + "--accept-dns=false" + ]; + }; + + syncthing = { + enable = true; + impermanence.enable = false; + }; + + fail2ban = { + enable = true; + impermanence.enable = false; + }; + + jellyfin = { + enable = true; + domain = "media.jan-leila.com"; + extraDomains = ["jellyfin.jan-leila.com"]; + impermanence.enable = false; + }; + + immich = { + enable = true; + domain = "photos.jan-leila.com"; + impermanence.enable = false; + }; + + forgejo = { + enable = true; + reverseProxy.domain = "git.jan-leila.com"; + impermanence.enable = false; + }; + + searx = { + enable = true; + domain = "search.jan-leila.com"; + }; + + actual = { + enable = false; + domain = "budget.jan-leila.com"; + impermanence.enable = false; + }; + + home-assistant = { + enable = true; + domain = "home.jan-leila.com"; + openFirewall = true; + postgres.enable = true; + impermanence.enable = false; + + extensions = { + sonos.enable = true; + jellyfin.enable = true; + wyoming.enable = false; # Temporarily disabled due to dependency conflict in wyoming-piper + }; + }; + + paperless = { + enable = true; + domain = "documents.jan-leila.com"; + passwordFile = config.sops.secrets."services/paperless_password".path; + impermanence.enable = false; + }; + + panoramax = { + enable = false; + openFirewall = true; + impermanence.enable = false; + }; + + crab-hole = { + enable = true; + port = 8085; + openFirewall = true; + show_doc = true; + impermanence.enable = false; + downstreams = { + host = { + enable = true; + openFirewall = true; + }; + }; + upstreams.cloudFlare.enable = true; + blocklists.ad_malware.enable = true; + }; + + qbittorrent = { + enable = true; + mediaDir = "/srv/qbittorent"; + openFirewall = true; + webuiPort = 8084; + impermanence.enable = false; + }; + + sonarr = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + radarr = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + bazarr = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + lidarr = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + jackett = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + flaresolverr = { + enable = true; + openFirewall = true; + impermanence.enable = false; + }; + }; + + # disable computer sleeping + systemd.targets = { + sleep.enable = false; + suspend.enable = false; + hibernate.enable = false; + hybrid-sleep.enable = false; + }; + services.displayManager.gdm.autoSuspend = false; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? + }; +} diff --git a/modules/hosts/nixos/defiant/default.nix b/modules/hosts/nixos/defiant/default.nix new file mode 100644 index 0000000..5f58a7d --- /dev/null +++ b/modules/hosts/nixos/defiant/default.nix @@ -0,0 +1,22 @@ +# server nas +{ + inputs, + config, + ... +}: { + flake.nixosConfigurations.defiant = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + config.flake.nixosModules.nixosModules + config.flake.nixosModules.defiantConfiguration + config.flake.nixosModules.defiantHardwareConfiguration + config.flake.nixosModules.defiantPackages + config.flake.nixosModules.defiantLegacyStorage + config.flake.nixosModules.defiantLegacyImpermanence + ]; + specialArgs = { + inherit inputs; + syncthingConfiguration = inputs.self.syncthingConfiguration; + }; + }; +} diff --git a/modules/hosts/nixos/defiant/hardware-configuration.nix b/modules/hosts/nixos/defiant/hardware-configuration.nix new file mode 100644 index 0000000..f85e31b --- /dev/null +++ b/modules/hosts/nixos/defiant/hardware-configuration.nix @@ -0,0 +1,70 @@ +{...}: { + # Do not modify this file! It was generated by 'nixos-generate-config' + # and may be overwritten by future invocations. Please make changes + # to /etc/nixos/configuration.nix instead. + flake.nixosModules.defiantHardwareConfiguration = { + config, + lib, + modulesPath, + ... + }: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot = { + initrd = { + availableKernelModules = ["xhci_pci" "aacraid" "ahci" "usbhid" "nvme" "usb_storage" "sd_mod"]; + kernelModules = []; + }; + kernelModules = ["kvm-amd"]; + extraModulePackages = []; + + # Bootloader. + loader = { + systemd-boot.enable = true; + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot"; + }; + }; + supportedFilesystems = ["zfs"]; + + zfs.extraPools = ["rpool"]; + }; + + networking = { + hostName = "defiant"; # Define your hostname. + hostId = "c51763d6"; + useNetworkd = true; + }; + + systemd.network = { + enable = true; + + networks = { + "30-eno1" = { + matchConfig.Name = "eno1"; + networkConfig = { + Bond = "bond0"; + PrimarySlave = true; + }; + linkConfig.RequiredForOnline = "enslaved"; + }; + "30-eno2" = { + matchConfig.Name = "eno2"; + networkConfig.Bond = "bond0"; + linkConfig.RequiredForOnline = "enslaved"; + }; + }; + }; + + networking.networkmanager.enable = true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware = { + # TODO: hardware graphics + cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; + }; +} diff --git a/modules/hosts/nixos/defiant/legacy-impermanence.nix b/modules/hosts/nixos/defiant/legacy-impermanence.nix new file mode 100644 index 0000000..684176b --- /dev/null +++ b/modules/hosts/nixos/defiant/legacy-impermanence.nix @@ -0,0 +1,298 @@ +{...}: { + # Legacy impermanence module for defiant + # See legacy-storage.nix for the full incremental migration plan. + # + # This file is consumed in two phases: + # + # Phase 3 (after generateBase is enabled): + # Remove the SYSTEM-LEVEL entries marked [PHASE 3] below. These will be + # handled automatically by storage.nix, ssh.nix, and the impermanence module: + # - var-lib-private-permissions activation script + # - /etc/machine-id + # - SSH host keys + # - /var/lib/nixos + # - /var/lib/systemd/coredump + # - /persist/system/var/log persistence block + # + # Phase 4 (migrate services one at a time, any order): + # For each service: + # 1. Remove the service's section marked [PHASE 4] from this file + # 2. Remove `impermanence.enable = false` for that service in configuration.nix + # For jellyfin/qbittorrent, also remove the separate media persistence blocks. + # + # Phase 5: Delete this file once empty. + flake.nixosModules.defiantLegacyImpermanence = { + config, + lib, + ... + }: { + config = lib.mkIf config.storage.impermanence.enable { + # [PHASE 3] Remove this activation script after enabling generateBase + system.activationScripts = { + "var-lib-private-permissions" = { + deps = ["specialfs"]; + text = '' + mkdir -p /persist/system/root/var/lib/private + chmod 0700 /persist/system/root/var/lib/private + ''; + }; + }; + + environment.persistence."/persist/system/root" = { + enable = true; + hideMounts = true; + # [PHASE 3] Remove this files block after enabling generateBase + files = lib.mkMerge [ + ["/etc/machine-id"] + # SSH host keys + (lib.mkIf config.services.openssh.enable ( + lib.lists.flatten ( + builtins.map (hostKey: [ + hostKey.path + "${hostKey.path}.pub" + ]) + config.services.openssh.hostKeys + ) + )) + ]; + directories = lib.mkMerge [ + # [PHASE 3] Remove these system directories after enabling generateBase + [ + "/var/lib/nixos" + "/var/lib/systemd/coredump" + ] + + # [PHASE 4] PostgreSQL + (lib.mkIf config.services.postgresql.enable [ + { + directory = "/var/lib/postgresql/16"; + user = "postgres"; + group = "postgres"; + } + ]) + + # [PHASE 4] Reverse Proxy (ACME) + (lib.mkIf config.services.reverseProxy.enable [ + { + directory = "/var/lib/acme"; + user = "acme"; + group = "acme"; + } + ]) + + # [PHASE 4] Ollama + (lib.mkIf config.services.ollama.enable [ + { + directory = "/var/lib/private/ollama"; + user = config.services.ollama.user; + group = config.services.ollama.group; + mode = "0700"; + } + ]) + + # [PHASE 4] Tailscale + (lib.mkIf config.services.tailscale.enable [ + { + directory = "/var/lib/tailscale"; + user = "root"; + group = "root"; + } + ]) + + # [PHASE 4] Syncthing + (lib.mkIf config.services.syncthing.enable [ + { + directory = "/mnt/sync"; + user = "syncthing"; + group = "syncthing"; + } + { + directory = "/etc/syncthing"; + user = "syncthing"; + group = "syncthing"; + } + ]) + + # [PHASE 4] Fail2ban + (lib.mkIf config.services.fail2ban.enable [ + { + directory = "/var/lib/fail2ban"; + user = "fail2ban"; + group = "fail2ban"; + } + ]) + + # [PHASE 4] Jellyfin (data/cache only - media is on separate dataset) + (lib.mkIf config.services.jellyfin.enable [ + { + directory = "/var/lib/jellyfin"; + user = "jellyfin"; + group = "jellyfin"; + } + { + directory = "/var/cache/jellyfin"; + user = "jellyfin"; + group = "jellyfin"; + } + ]) + + # [PHASE 4] Immich + (lib.mkIf config.services.immich.enable [ + { + directory = "/var/lib/immich"; + user = "immich"; + group = "immich"; + } + ]) + + # [PHASE 4] Forgejo + (lib.mkIf config.services.forgejo.enable [ + { + directory = "/var/lib/forgejo"; + user = "forgejo"; + group = "forgejo"; + } + ]) + + # [PHASE 4] Actual + (lib.mkIf config.services.actual.enable [ + { + directory = "/var/lib/private/actual"; + user = "actual"; + group = "actual"; + } + ]) + + # [PHASE 4] Home Assistant + (lib.mkIf config.services.home-assistant.enable [ + { + directory = "/var/lib/hass"; + user = "hass"; + group = "hass"; + } + ]) + + # [PHASE 4] Paperless + (lib.mkIf config.services.paperless.enable [ + { + directory = "/var/lib/paperless"; + user = "paperless"; + group = "paperless"; + } + ]) + + # [PHASE 4] Crab-hole + (lib.mkIf config.services.crab-hole.enable [ + { + directory = "/var/lib/private/crab-hole"; + user = "crab-hole"; + group = "crab-hole"; + } + ]) + + # [PHASE 4] qBittorrent (config only - media is on separate dataset) + (lib.mkIf config.services.qbittorrent.enable [ + { + directory = "/var/lib/qBittorrent/"; + user = "qbittorrent"; + group = "qbittorrent"; + } + ]) + + # [PHASE 4] Sonarr + (lib.mkIf config.services.sonarr.enable [ + { + directory = "/var/lib/sonarr/.config/NzbDrone"; + user = "sonarr"; + group = "sonarr"; + } + ]) + + # [PHASE 4] Radarr + (lib.mkIf config.services.radarr.enable [ + { + directory = "/var/lib/radarr/.config/Radarr"; + user = "radarr"; + group = "radarr"; + } + ]) + + # [PHASE 4] Bazarr + (lib.mkIf config.services.bazarr.enable [ + { + directory = "/var/lib/bazarr"; + user = "bazarr"; + group = "bazarr"; + } + ]) + + # [PHASE 4] Lidarr + (lib.mkIf config.services.lidarr.enable [ + { + directory = "/var/lib/lidarr/.config/Lidarr"; + user = "lidarr"; + group = "lidarr"; + } + ]) + + # [PHASE 4] Jackett + (lib.mkIf config.services.jackett.enable [ + { + directory = "/var/lib/jackett/.config/Jackett"; + user = "jackett"; + group = "jackett"; + } + ]) + + # [PHASE 4] FlareSolverr + (lib.mkIf config.services.flaresolverr.enable [ + { + directory = "/var/lib/flaresolverr"; + user = "flaresolverr"; + group = "flaresolverr"; + } + ]) + ]; + }; + + # [PHASE 4 - LAST] Jellyfin media on separate dataset + # Requires Phase 2 media dataset merge before migrating (several days of data copy) + environment.persistence."/persist/system/jellyfin" = lib.mkIf config.services.jellyfin.enable { + enable = true; + hideMounts = true; + directories = [ + { + directory = config.services.jellyfin.media_directory; + user = "jellyfin"; + group = "jellyfin_media"; + mode = "1770"; + } + ]; + }; + + # [PHASE 4 - LAST] qBittorrent media on separate dataset + # Requires Phase 2 media dataset merge before migrating (several days of data copy) + environment.persistence."/persist/system/qbittorrent" = lib.mkIf config.services.qbittorrent.enable { + enable = true; + hideMounts = true; + directories = [ + { + directory = config.services.qbittorrent.mediaDir; + user = "qbittorrent"; + group = "qbittorrent"; + mode = "1775"; + } + ]; + }; + + # [PHASE 3] /var/log persistence - handled by storage.nix after generateBase + environment.persistence."/persist/system/var/log" = { + enable = true; + hideMounts = true; + directories = [ + "/var/log" + ]; + }; + }; + }; +} diff --git a/modules/hosts/nixos/defiant/legacy-storage.nix b/modules/hosts/nixos/defiant/legacy-storage.nix new file mode 100644 index 0000000..9b8f7d3 --- /dev/null +++ b/modules/hosts/nixos/defiant/legacy-storage.nix @@ -0,0 +1,220 @@ +{...}: { + # Legacy storage configuration for defiant + # This file manually defines ZFS datasets matching the existing on-disk layout + # to allow incremental migration to the new storage module (generateBase = true). + # + # ============================================================================ + # INCREMENTAL MIGRATION PLAN + # ============================================================================ + # + # Current disk usage (for reference): + # rpool/local/system/nix ~26G (renamed in place, no copy) + # rpool/local/system/sops ~328K (renamed in place, no copy) + # rpool/persist/system/jellyfin ~32T (renamed in place, no copy) + # rpool/persist/system/qbittorrent ~6.5T (copied into media dataset, ~6.5T temp) + # rpool free space ~30T + # + # Phase 1: Migrate base datasets on disk (boot from live USB or rescue) + # All operations in this phase are instant renames -- no data is copied. + # + # Unlock the pool: + # zfs load-key -a + # + # Step 1a: Move nix and sops out of local/ (they go to persist/local/) + # The -p flag auto-creates the parent datasets. + # + # zfs rename -p rpool/local/system/nix rpool/persist/local/nix + # zfs rename -p rpool/local/system/sops rpool/persist/local/system/sops + # + # Step 1b: Rename local/ -> ephemeral/ (takes remaining children with it) + # zfs rename rpool/local rpool/ephemeral + # # This moves: local/system/root -> ephemeral/system/root + # # local/home/leyla -> ephemeral/home/leyla + # + # Step 1c: Recreate blank snapshots on ephemeral datasets + # zfs destroy rpool/ephemeral/system/root@blank + # zfs snapshot rpool/ephemeral/system/root@blank + # zfs destroy rpool/ephemeral/home/leyla@blank + # zfs snapshot rpool/ephemeral/home/leyla@blank + # + # Step 1d: Move persist/ children under persist/replicate/ + # zfs create -o canmount=off rpool/persist/replicate + # zfs create -o canmount=off rpool/persist/replicate/system + # zfs rename rpool/persist/system/root rpool/persist/replicate/system/root + # zfs rename rpool/persist/system/var rpool/persist/replicate/system/var + # zfs rename rpool/persist/home/leyla rpool/persist/replicate/home + # # Clean up the now-empty home parent + # zfs destroy rpool/persist/home + # # NOTE: Do NOT destroy rpool/persist/system -- it still contains + # # persist/system/jellyfin and persist/system/qbittorrent which are + # # migrated in Phase 2. + # + # Verify the new layout: + # zfs list -r rpool -o name,used,mountpoint + # + # Phase 2: Merge media into a single dataset (do this last) + # Strategy: Rename the jellyfin dataset to become the shared media dataset + # (zero copy, instant), then copy qbittorrent data into it (~6.5T copy). + # This avoids duplicating the 32T jellyfin dataset. + # + # Step 2a: Rename jellyfin dataset to the shared media name + # zfs rename rpool/persist/system/jellyfin rpool/persist/replicate/system/media + # + # Step 2b: Copy qbittorrent data into the media dataset + # This copies ~6.5T and may take several hours/days depending on disk speed. + # The qbittorrent data is not critical to back up so no snapshot needed. + # + # systemctl stop qbittorrent + # rsync -avPHAX /persist/system/qbittorrent/ /persist/replicate/system/media/ + # + # Step 2c: Verify the data and clean up + # ls -la /persist/replicate/system/media/ + # zfs destroy rpool/persist/system/qbittorrent + # # persist/system should now be empty, clean it up: + # zfs destroy rpool/persist/system + # + # Phase 3: Enable generateBase + # In the nix config: + # - Delete this file (legacy-storage.nix) and remove its import from default.nix + # - Remove [PHASE 3] entries from legacy-impermanence.nix: + # - var-lib-private-permissions activation script + # - /etc/machine-id, SSH host keys (files block) + # - /var/lib/nixos, /var/lib/systemd/coredump (directories) + # - /persist/system/var/log persistence block + # These are now handled automatically by storage.nix and ssh.nix. + # Rebuild and verify: + # sudo nixos-rebuild switch --flake .#defiant + # # Verify mounts: findmnt -t fuse.bindfs,fuse + # # Verify persist: ls /persist/replicate/system/root/var/lib/nixos + # # Verify boot: reboot and confirm system comes up cleanly + # + # Phase 4: Migrate services (one at a time, any order) + # For each service (except jellyfin/qbittorrent): + # 1. Remove the service's [PHASE 4] section from legacy-impermanence.nix + # 2. Remove `impermanence.enable = false` for that service in configuration.nix + # 3. Rebuild: sudo nixos-rebuild switch --flake .#defiant + # 4. Verify: systemctl status , check the service's data is intact + # No data migration is needed -- the data already lives on the renamed + # dataset at the new path. + # + # Migrate jellyfin and qbittorrent LAST (after Phase 2 media merge): + # 1. Remove [PHASE 4 - LAST] jellyfin entries from legacy-impermanence.nix + # 2. Remove [PHASE 4 - LAST] qbittorrent entries from legacy-impermanence.nix + # 3. Remove `impermanence.enable = false` for both in configuration.nix + # 4. Rebuild: sudo nixos-rebuild switch --flake .#defiant + # 5. Verify: systemctl status jellyfin qbittorrent + # + # Phase 5: Cleanup + # Once all services are migrated and legacy-impermanence.nix is empty: + # - Delete legacy-impermanence.nix and remove its import from default.nix + # - Rebuild: sudo nixos-rebuild switch --flake .#defiant + # + # ============================================================================ + # + # Current on-disk dataset layout: + # rpool/local/ - ephemeral parent + # rpool/local/home/leyla - ephemeral user home (rolled back on boot) + # rpool/local/system/nix - nix store + # rpool/local/system/root - root filesystem (rolled back on boot) + # rpool/local/system/sops - sops age key + # rpool/persist/ - persistent parent + # rpool/persist/home/leyla - persistent user home + # rpool/persist/system/jellyfin - jellyfin media + # rpool/persist/system/qbittorrent - qbittorrent media + # rpool/persist/system/root - persistent root data + # rpool/persist/system/var/log - log persistence + flake.nixosModules.defiantLegacyStorage = {lib, ...}: { + # Disable automatic base dataset generation so we can define them manually + storage.generateBase = false; + + # Manually define ZFS datasets matching main's structure + storage.zfs.datasets = { + # Ephemeral datasets (local/) + "local" = { + type = "zfs_fs"; + mount = null; + }; + "local/home/leyla" = { + type = "zfs_fs"; + mount = "/home/leyla"; + snapshot = { + blankSnapshot = true; + }; + }; + "local/system/nix" = { + type = "zfs_fs"; + mount = "/nix"; + atime = "off"; + relatime = "off"; + snapshot = { + autoSnapshot = false; + }; + }; + "local/system/root" = { + type = "zfs_fs"; + mount = "/"; + snapshot = { + blankSnapshot = true; + }; + }; + "local/system/sops" = { + type = "zfs_fs"; + mount = "/var/lib/sops-nix"; + }; + + # Persistent datasets (persist/) + "persist" = { + type = "zfs_fs"; + mount = null; + }; + "persist/home/leyla" = { + type = "zfs_fs"; + mount = "/persist/home/leyla"; + snapshot = { + autoSnapshot = true; + }; + }; + "persist/system/jellyfin" = { + type = "zfs_fs"; + mount = "/persist/system/jellyfin"; + atime = "off"; + relatime = "off"; + }; + "persist/system/qbittorrent" = { + type = "zfs_fs"; + mount = "/persist/system/qbittorrent"; + atime = "off"; + relatime = "off"; + }; + "persist/system/root" = { + type = "zfs_fs"; + mount = "/persist/system/root"; + snapshot = { + autoSnapshot = true; + }; + }; + "persist/system/var/log" = { + type = "zfs_fs"; + mount = "/persist/system/var/log"; + }; + }; + + # Boot commands to rollback ephemeral root and user homes on boot + boot.initrd.postResumeCommands = lib.mkAfter '' + zfs rollback -r rpool/local/system/root@blank + zfs rollback -r rpool/local/home/leyla@blank + ''; + + # FileSystems needed for boot + fileSystems = { + "/".neededForBoot = true; + "/persist/system/root".neededForBoot = true; + "/persist/system/var/log".neededForBoot = true; + "/persist/system/jellyfin".neededForBoot = true; + "/persist/system/qbittorrent".neededForBoot = true; + "/var/lib/sops-nix".neededForBoot = true; + "/persist/home/leyla".neededForBoot = true; + "/home/leyla".neededForBoot = true; + }; + }; +} diff --git a/modules/hosts/nixos/defiant/packages.nix b/modules/hosts/nixos/defiant/packages.nix new file mode 100644 index 0000000..4759e95 --- /dev/null +++ b/modules/hosts/nixos/defiant/packages.nix @@ -0,0 +1,11 @@ +{...}: { + flake.nixosModules.defiantPackages = {pkgs, ...}: { + environment.systemPackages = with pkgs; [ + ffsubsync + sox + yt-dlp + ffmpeg + imagemagick + ]; + }; +} diff --git a/modules/hosts/nixos/emergent/configuration.nix b/modules/hosts/nixos/emergent/configuration.nix new file mode 100644 index 0000000..24a5558 --- /dev/null +++ b/modules/hosts/nixos/emergent/configuration.nix @@ -0,0 +1,183 @@ +{...}: { + # Edit this configuration file to define what should be installed on + # your system. Help is available in the configuration.nix(5) man page, on + # https://search.nixos.org/options and in the NixOS manual (`nixos-help`). + flake.nixosModules.emergentConfiguration = { + lib, + pkgs, + ... + }: { + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # networking.hostName = "nixos"; # Define your hostname. + # Pick only one of the below networking options. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + # networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. + + # Set your time zone. + # time.timeZone = "Europe/Amsterdam"; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Select internationalisation properties. + # i18n.defaultLocale = "en_US.UTF-8"; + # console = { + # font = "Lat2-Terminus16"; + # keyMap = "us"; + # useXkbConfig = true; # use xkb.options in tty. + # }; + + # Enable the X11 windowing system. + services.xserver.enable = true; + # Enable wacom touchscreen device + services.xserver.wacom.enable = true; + + # installed opentabletdriver + # hardware.opentabletdriver.enable = true; + hardware.keyboard.qmk.enable = true; + + # Enable the GNOME Desktop Environment. + services.displayManager.gdm.enable = true; + services.desktopManager.gnome.enable = true; + + host = { + ai.enable = true; + users = { + eve = { + isDesktopUser = true; + isTerminalUser = true; + isPrincipleUser = true; + }; + }; + hardware = { + piperMouse.enable = true; + }; + }; + + storage = { + zfs = { + enable = true; + pool = { + mode = "stripe"; + vdevs = [ + [ + { + device = "wwn-0x5000039fd0cf05eb"; + boot = true; + } + ] + ]; + cache = []; + }; + }; + }; + + virtualisation.libvirtd.enable = true; + + users.users.eve = { + extraGroups = ["libvirtd"]; + }; + + services.tailscale.enable = true; + # We were having weird build errors so this is disabled right now + # error: The option `devices.emergent.folders.eve_records.path' was accessed but has no value defined. Try setting the option + services.syncthing.enable = false; + + # Configure keymap in X11 + # services.xserver.xkb.layout = "us"; + # services.xserver.xkb.options = "eurosign:e,caps:escape"; + + # Enable CUPS to print documents. + # services.printing.enable = true; + + # Enable sound. + # services.pulseaudio.enable = true; + # OR + # services.pipewire = { + # enable = true; + # pulse.enable = true; + # }; + + # Enable touchpad support (enabled default in most desktopManager). + # services.libinput.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + # users.users.alice = { + # isNormalUser = true; + # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + # packages = with pkgs; [ + # tree + # ]; + # }; + + # programs.firefox.enable = true; + + nixpkgs.config.allowUnfree = true; + + # Packages that can be installed without any extra configuration + # See https://search.nixos.org/packages for all options + environment.systemPackages = with pkgs; [ + wget + gnome-boxes + libvirt + ]; + + # Packages that need to be installed with some extra configuration + # See https://search.nixos.org/options for all options + programs = {}; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + + # List services that you want to enable: + + # Enable the OpenSSH daemon. + # services.openssh.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + networking = { + networkmanager.enable = true; + useDHCP = lib.mkDefault true; + hostId = "7e35eb97"; # arbitrary id number generated via this command: `head -c4 /dev/urandom | od -A none -t x4` + hostName = "emergent"; # Define your hostname. + }; + + # Copy the NixOS configuration file and link it from the resulting system + # (/run/current-system/configuration.nix). This is useful in case you + # accidentally delete configuration.nix. + # system.copySystemConfiguration = true; + + # This option defines the first version of NixOS you have installed on this particular machine, + # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. + # + # Most users should NEVER change this value after the initial install, for any reason, + # even if you've upgraded your system to a new NixOS release. + # + # This value does NOT affect the Nixpkgs version your packages and OS are pulled from, + # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how + # to actually do that. + # + # This value being lower than the current NixOS release does NOT mean your system is + # out of date, out of support, or vulnerable. + # + # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration, + # and migrated your data accordingly. + # + # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . + system.stateVersion = "25.05"; # Did you read the comment? + }; +} diff --git a/modules/hosts/nixos/emergent/default.nix b/modules/hosts/nixos/emergent/default.nix new file mode 100644 index 0000000..afc3735 --- /dev/null +++ b/modules/hosts/nixos/emergent/default.nix @@ -0,0 +1,21 @@ +# evs desktop +{ + inputs, + config, + ... +}: { + flake.nixosConfigurations.emergent = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + config.flake.nixosModules.nixosModules + config.flake.nixosModules.emergentConfiguration + config.flake.nixosModules.emergentHardwareConfiguration + config.flake.nixosModules.emergentLegacyStorage + config.flake.nixosModules.emergentNvidiaDriver + ]; + specialArgs = { + inherit inputs; + syncthingConfiguration = inputs.self.syncthingConfiguration; + }; + }; +} diff --git a/modules/hosts/nixos/emergent/hardware-configuration.nix b/modules/hosts/nixos/emergent/hardware-configuration.nix new file mode 100644 index 0000000..f88238b --- /dev/null +++ b/modules/hosts/nixos/emergent/hardware-configuration.nix @@ -0,0 +1,34 @@ +{...}: { + # Do not modify this file! It was generated by ‘nixos-generate-config’ + # and may be overwritten by future invocations. Please make changes + # to /etc/nixos/configuration.nix instead. + flake.nixosModules.emergentHardwareConfiguration = { + config, + lib, + pkgs, + modulesPath, + ... + }: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "wacom" "kvm" "kvm_amd"]; + boot.initrd.kernelModules = []; + boot.kernelModules = []; + boot.extraModulePackages = []; + + swapDevices = []; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp42s0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; +} diff --git a/modules/hosts/nixos/emergent/legacy-storage.nix b/modules/hosts/nixos/emergent/legacy-storage.nix new file mode 100644 index 0000000..ae64933 --- /dev/null +++ b/modules/hosts/nixos/emergent/legacy-storage.nix @@ -0,0 +1,53 @@ +{...}: { + # Legacy storage configuration for emergent + # This file manually defines ZFS datasets matching the existing on-disk layout + # to allow incremental migration to the new storage module (generateBase = true). + # + # Current on-disk dataset layout: + # rpool/local/ - parent (canmount=off) + # rpool/local/system/nix - nix store + # rpool/local/system/root - root filesystem + # + # Migration plan: + # Phase 1: Rename datasets on disk (boot from live USB) + # zfs rename -p rpool/local/system/nix rpool/persist/local/nix + # zfs rename rpool/local rpool/persist/local + # # This moves: local/system/root -> persist/local/root (need to rename after) + # # Actually, since local/system/root needs to become persist/local/root: + # zfs rename rpool/persist/local/system/root rpool/persist/local/root + # zfs destroy rpool/persist/local/system # now empty + # # Recreate blank snapshot: + # zfs destroy rpool/persist/local/root@blank + # zfs snapshot rpool/persist/local/root@blank + # + # Phase 2: Delete this file, remove its import from default.nix, rebuild. + flake.nixosModules.emergentLegacyStorage = {...}: { + # Disable automatic base dataset generation so we can define them manually + storage.generateBase = false; + + # Manually define ZFS datasets matching the existing on-disk layout + storage.zfs.datasets = { + "local" = { + type = "zfs_fs"; + mount = null; + }; + "local/system/nix" = { + type = "zfs_fs"; + mount = "/nix"; + atime = "off"; + relatime = "off"; + snapshot = { + autoSnapshot = false; + }; + }; + "local/system/root" = { + type = "zfs_fs"; + mount = "/"; + snapshot = { + blankSnapshot = true; + autoSnapshot = true; + }; + }; + }; + }; +} diff --git a/configurations/nixos/twilight/nvidia-drivers.nix b/modules/hosts/nixos/emergent/nvidia-drivers.nix similarity index 69% rename from configurations/nixos/twilight/nvidia-drivers.nix rename to modules/hosts/nixos/emergent/nvidia-drivers.nix index 2842d0a..e8759d2 100644 --- a/configurations/nixos/twilight/nvidia-drivers.nix +++ b/modules/hosts/nixos/emergent/nvidia-drivers.nix @@ -1,20 +1,21 @@ -{config, ...}: { - services = { - xserver = { - # Load nvidia driver for Xorg and Wayland - videoDrivers = ["nvidia"]; - }; - # Temporarily enable wayland to fix boot issue - # TODO: Investigate proper X11 session generation for gaming - displayManager.gdm.wayland = true; - }; - - hardware = { +{...}: { + flake.nixosModules.emergentNvidiaDriver = {config, ...}: { # Enable OpenGL - graphics.enable = true; + hardware.graphics = { + enable = true; + }; - # install graphics drivers - nvidia = { + # Load nvidia driver for Xorg and Wayland + services = { + xserver = { + # Load nvidia driver for Xorg and Wayland + videoDrivers = ["nvidia"]; + }; + # Use X instead of wayland + displayManager.gdm.wayland = true; + }; + + hardware.nvidia = { # Modesetting is required. modesetting.enable = true; @@ -34,7 +35,6 @@ # supported GPUs is at: # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus # Only available from driver 515.43.04+ - # Currently alpha-quality/buggy, so false is currently the recommended setting. open = true; # Enable the Nvidia settings menu, @@ -42,7 +42,7 @@ nvidiaSettings = true; # Optionally, you may need to select the appropriate driver version for your specific GPU. - package = config.boot.kernelPackages.nvidiaPackages.production; + package = config.boot.kernelPackages.nvidiaPackages.stable; }; }; } diff --git a/modules/hosts/nixos/horizon/configuration.nix b/modules/hosts/nixos/horizon/configuration.nix new file mode 100644 index 0000000..e5b41bf --- /dev/null +++ b/modules/hosts/nixos/horizon/configuration.nix @@ -0,0 +1,158 @@ +{...}: { + flake.nixosModules.horizonConfiguration = { + lib, + pkgs, + config, + inputs, + ... + }: { + imports = [ + inputs.nixos-hardware.nixosModules.framework-11th-gen-intel + ]; + + nixpkgs.config.allowUnfree = true; + + boot = { + initrd = { + availableKernelModules = ["usb_storage" "sd_mod"]; + }; + kernelModules = ["sg"]; + + # Bootloader. + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; + + host = { + users = { + leyla = { + isDesktopUser = true; + isTerminalUser = true; + isPrincipleUser = true; + }; + eve.isDesktopUser = true; + }; + + hardware = { + directAccess.enable = true; + }; + + ai = { + enable = true; + models = { + "Llama 3.1 8B" = { + model = "llama3.1:8b"; + roles = ["chat" "edit" "apply"]; + apiBase = "http://defiant:11434"; + }; + "Deepseek Coder:6.7B" = { + model = "deepseek-coder:6.7b"; + roles = ["chat" "edit" "apply"]; + apiBase = "http://defiant:11434"; + }; + "Deepseek Coder:33B" = { + model = "deepseek-coder:33b"; + roles = ["chat" "edit" "apply"]; + apiBase = "http://defiant:11434"; + }; + + "Deepseek r1:8B" = { + model = "deepseek-r1:8b"; + roles = ["chat"]; + apiBase = "http://defiant:11434"; + }; + + "Deepseek r1:32B" = { + model = "deepseek-r1:32b"; + roles = ["chat"]; + apiBase = "http://defiant:11434"; + }; + + "qwen2.5-coder:1.5b-base" = { + model = "qwen2.5-coder:1.5b-base"; + roles = ["autocomplete"]; + apiBase = "http://defiant:11434"; + }; + + "nomic-embed-text:latest" = { + model = "nomic-embed-text:latest"; + roles = ["embed"]; + apiBase = "http://defiant:11434"; + }; + }; + }; + }; + + virtualisation.docker.enable = true; + + environment.systemPackages = with pkgs; [ + cachefilesd + webtoon-dl + android-tools + ]; + services.cachefilesd.enable = true; + + networking = { + networkmanager.enable = true; + hostName = "horizon"; # Define your hostname. + }; + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + + hardware = { + graphics.enable = true; + }; + + sops.secrets = { + "vpn-keys/tailscale-authkey/horizon" = { + sopsFile = "${inputs.secrets}/vpn-keys.yaml"; + }; + }; + + services = { + # sudo fprintd-enroll + fprintd = { + enable = true; + }; + # firmware update tool + fwupd = { + enable = true; + }; + tailscale = { + enable = true; + authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/horizon".path; + useRoutingFeatures = "client"; + }; + + syncthing.enable = true; + + ollama = { + enable = true; + loadModels = [ + "llama3.1:8b" + ]; + }; + }; + + # Enable network-online.target for better network dependency handling + systemd.services.NetworkManager-wait-online.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + # services.xserver.libinput.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? + }; +} diff --git a/modules/hosts/nixos/horizon/default.nix b/modules/hosts/nixos/horizon/default.nix new file mode 100644 index 0000000..b5887f3 --- /dev/null +++ b/modules/hosts/nixos/horizon/default.nix @@ -0,0 +1,20 @@ +# leyla laptop +{ + inputs, + config, + ... +}: { + flake.nixosConfigurations.horizon = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + config.flake.nixosModules.nixosModules + config.flake.nixosModules.horizonConfiguration + config.flake.nixosModules.horizonHardwareConfiguration + # config.flake.nixosModules.horizonNetworkMount + ]; + specialArgs = { + inherit inputs; + syncthingConfiguration = inputs.self.syncthingConfiguration; + }; + }; +} diff --git a/modules/hosts/nixos/horizon/hardware-configuration.nix b/modules/hosts/nixos/horizon/hardware-configuration.nix new file mode 100644 index 0000000..edf08c6 --- /dev/null +++ b/modules/hosts/nixos/horizon/hardware-configuration.nix @@ -0,0 +1,47 @@ +{...}: { + # Do not modify this file! It was generated by 'nixos-generate-config' + # and may be overwritten by future invocations. Please make changes + # to /etc/nixos/configuration.nix instead. + flake.nixosModules.horizonHardwareConfiguration = { + config, + lib, + modulesPath, + ... + }: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "nvme"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/866d422b-f816-4ad9-9846-791839cb9337"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/E138-65B5"; + fsType = "vfat"; + }; + }; + + swapDevices = [ + {device = "/dev/disk/by-uuid/be98e952-a072-4c3a-8c12-69500b5a2fff";} + ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.tailscale0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp170s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; +} diff --git a/modules/hosts/nixos/horizon/network-mount.nix b/modules/hosts/nixos/horizon/network-mount.nix new file mode 100644 index 0000000..345b26c --- /dev/null +++ b/modules/hosts/nixos/horizon/network-mount.nix @@ -0,0 +1,78 @@ +{...}: { + flake.nixosModules.horizonNetworkMount = {...}: { + boot.supportedFilesystems = ["nfs"]; + + fileSystems = { + "/mnt/leyla_documents" = { + device = "defiant:/exports/leyla_documents"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "noatime" + "nofail" + "soft" + "intr" # Allow interruption of NFS calls + "timeo=30" # 3 second timeout (30 deciseconds) + "retrans=2" # Only 2 retries before giving up + "x-systemd.idle-timeout=300" # 5 minute idle timeout for mobile + "x-systemd.device-timeout=15" # 15 second device timeout + "bg" # Background mount - don't block boot + "fsc" # Enable caching + "_netdev" # Network device - wait for network + "x-systemd.requires=network-online.target" # Require network to be online + "x-systemd.after=network-online.target" # Start after network is online + "x-systemd.mount-timeout=30" # 30 second mount timeout + ]; + }; + + "/mnt/users_documents" = { + device = "defiant:/exports/users_documents"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "nofail" + "soft" + "intr" + "timeo=30" + "retrans=2" + "x-systemd.idle-timeout=300" + "x-systemd.device-timeout=15" + "bg" + "fsc" + "_netdev" + "x-systemd.requires=network-online.target" + "x-systemd.after=network-online.target" + "x-systemd.mount-timeout=30" + ]; + }; + + "/mnt/media" = { + device = "defiant:/exports/media"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "noatime" + "nofail" + "soft" + "intr" + "timeo=30" + "retrans=2" + "x-systemd.idle-timeout=300" + "x-systemd.device-timeout=15" + "bg" + # Mobile-optimized read settings + "rsize=8192" # Smaller read size for mobile + "wsize=8192" # Smaller write size for mobile + "fsc" + "_netdev" + "x-systemd.requires=network-online.target" + "x-systemd.after=network-online.target" + "x-systemd.mount-timeout=30" + ]; + }; + }; + }; +} diff --git a/modules/hosts/nixos/twilight/configuration.nix b/modules/hosts/nixos/twilight/configuration.nix new file mode 100644 index 0000000..7493e41 --- /dev/null +++ b/modules/hosts/nixos/twilight/configuration.nix @@ -0,0 +1,158 @@ +{...}: { + flake.nixosModules.twilightConfiguration = { + inputs, + config, + pkgs, + ... + }: { + nixpkgs.config.allowUnfree = true; + + boot.initrd.availableKernelModules = ["usb_storage"]; + boot.kernelModules = ["sg"]; + + boot.loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + sops.secrets = { + "vpn-keys/tailscale-authkey/twilight" = { + sopsFile = "${inputs.secrets}/vpn-keys.yaml"; + }; + }; + host = { + users = { + leyla = { + isDesktopUser = true; + isTerminalUser = true; + isPrincipleUser = true; + }; + eve.isDesktopUser = true; + }; + hardware = { + piperMouse.enable = true; + viaKeyboard.enable = true; + openRGB.enable = true; + graphicsAcceleration.enable = true; + directAccess.enable = true; + }; + ai = { + enable = true; + # TODO: benchmark twilight against defiant and prune this list of models that are faster on defiant + models = { + # conversation models + "Llama 3.1 8B" = { + model = "lamma3.1:8b"; + roles = ["chat" "edit" "apply"]; + }; + "deepseek-r1:8b" = { + model = "deepseek-r1:8b"; + roles = ["chat" "edit" "apply"]; + }; + "deepseek-r1:32b" = { + model = "deepseek-r1:32b"; + roles = ["chat" "edit" "apply"]; + }; + + # auto complete models + "qwen2.5-coder:1.5b-base" = { + model = "qwen2.5-coder:1.5b-base"; + roles = ["autocomplete"]; + }; + "qwen2.5-coder:7b" = { + model = "qwen2.5-coder:7b"; + roles = ["autocomplete"]; + }; + "deepseek-coder:6.7b" = { + model = "deepseek-coder:6.7b"; + roles = ["autocomplete"]; + }; + "deepseek-coder:33b" = { + model = "deepseek-coder:33b"; + roles = ["autocomplete"]; + }; + + # agent models + "qwen3:32b" = { + model = "qwen3:32b"; + roles = ["chat" "edit" "apply"]; + }; + + # embedding models + "nomic-embed-text:latest" = { + model = "nomic-embed-text:latest"; + roles = ["embed"]; + }; + }; + }; + }; + services = { + ollama = { + enable = true; + exposePort = true; + + loadModels = [ + # conversation models + "llama3.1:8b" + "deepseek-r1:8b" + "deepseek-r1:32b" + + # auto complete models + "qwen2.5-coder:1.5b-base" + "qwen2.5-coder:7b" + "deepseek-coder:6.7b" + "deepseek-coder:33b" + + # agent models + "qwen3:32b" + + # embedding models + "nomic-embed-text:latest" + ]; + }; + + tailscale = { + enable = true; + authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/twilight".path; + useRoutingFeatures = "both"; + extraUpFlags = [ + "--advertise-exit-node" + "--advertise-routes=192.168.0.0/24" + ]; + extraSetFlags = [ + "--advertise-exit-node" + "--advertise-routes=192.168.0.0/24" + ]; + }; + + syncthing.enable = true; + }; + + # Enable network-online.target for better network dependency handling + systemd.services.NetworkManager-wait-online.enable = true; + + environment.systemPackages = with pkgs; [ + cachefilesd + ]; + hardware.steam-hardware.enable = true; # Provides udev rules for controller, HTC vive, and Valve Index + + networking = { + networkmanager.enable = true; + hostName = "twilight"; # Define your hostname. + }; + + # enabled virtualisation for docker + # virtualisation.docker.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + # services.xserver.libinput.enable = true; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? + }; +} diff --git a/modules/hosts/nixos/twilight/default.nix b/modules/hosts/nixos/twilight/default.nix new file mode 100644 index 0000000..303c2cf --- /dev/null +++ b/modules/hosts/nixos/twilight/default.nix @@ -0,0 +1,21 @@ +# leyla desktop +{ + inputs, + config, + ... +}: { + flake.nixosConfigurations.twilight = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + config.flake.nixosModules.nixosModules + config.flake.nixosModules.twilightConfiguration + config.flake.nixosModules.twilightHardwareConfiguration + config.flake.nixosModules.twilightNvidiaDriver + # config.flake.nixosModules.twilightNetworkMount + ]; + specialArgs = { + inherit inputs; + syncthingConfiguration = inputs.self.syncthingConfiguration; + }; + }; +} diff --git a/modules/hosts/nixos/twilight/hardware-configuration.nix b/modules/hosts/nixos/twilight/hardware-configuration.nix new file mode 100644 index 0000000..cce7d45 --- /dev/null +++ b/modules/hosts/nixos/twilight/hardware-configuration.nix @@ -0,0 +1,44 @@ +{...}: { + # Do not modify this file! It was generated by 'nixos-generate-config' + # and may be overwritten by future invocations. Please make changes + # to /etc/nixos/configuration.nix instead. + flake.nixosModules.twilightHardwareConfiguration = { + config, + lib, + modulesPath, + ... + }: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "sd_mod"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-amd"]; + boot.extraModulePackages = []; + + fileSystems = { + "/" = { + device = "/dev/disk/by-id/nvme-Samsung_SSD_980_500GB_S64ENJ0RA06463Z-part2"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-id/nvme-Samsung_SSD_980_500GB_S64ENJ0RA06463Z-part1"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + }; + + swapDevices = []; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; +} diff --git a/modules/hosts/nixos/twilight/network-mount.nix b/modules/hosts/nixos/twilight/network-mount.nix new file mode 100644 index 0000000..83432d8 --- /dev/null +++ b/modules/hosts/nixos/twilight/network-mount.nix @@ -0,0 +1,74 @@ +{...}: { + flake.nixosModules.twilightNetworkMount = {...}: { + boot.supportedFilesystems = ["nfs"]; + + fileSystems = { + "/mnt/leyla_documents" = { + device = "defiant:/exports/leyla_documents"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "noatime" + "nofail" + "soft" + "intr" # Allow interruption of NFS calls + "timeo=50" # 5 second timeout (50 deciseconds) - longer than mobile + "retrans=3" # 3 retries for desktop + "x-systemd.idle-timeout=600" # 10 minute idle timeout for desktop + "x-systemd.device-timeout=30" # 30 second device timeout + "bg" # Background mount - don't block boot + "fsc" # Enable caching + "_netdev" # Network device - wait for network + "x-systemd.requires=network-online.target" # Require network to be online + "x-systemd.after=network-online.target" # Start after network is online + ]; + }; + + "/mnt/users_documents" = { + device = "defiant:/exports/users_documents"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "nofail" + "soft" + "intr" + "timeo=50" + "retrans=3" + "x-systemd.idle-timeout=600" + "bg" + "fsc" + "_netdev" + "x-systemd.requires=network-online.target" + "x-systemd.after=network-online.target" + ]; + }; + + "/mnt/media" = { + device = "defiant:/exports/media"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "noatime" + "nofail" + "soft" + "intr" + "timeo=50" + "retrans=3" + "x-systemd.idle-timeout=600" + "x-systemd.device-timeout=30" + "bg" + # Desktop-optimized read settings + "rsize=32768" # Larger read size for desktop + "wsize=32768" # Larger write size for desktop + "fsc" + "_netdev" + "x-systemd.requires=network-online.target" + "x-systemd.after=network-online.target" + ]; + }; + }; + }; +} diff --git a/modules/hosts/nixos/twilight/nvidia-drivers.nix b/modules/hosts/nixos/twilight/nvidia-drivers.nix new file mode 100644 index 0000000..ed69b05 --- /dev/null +++ b/modules/hosts/nixos/twilight/nvidia-drivers.nix @@ -0,0 +1,50 @@ +{...}: { + flake.nixosModules.twilightNvidiaDriver = {config, ...}: { + services = { + xserver = { + # Load nvidia driver for Xorg and Wayland + videoDrivers = ["nvidia"]; + }; + # Temporarily enable wayland to fix boot issue + # TODO: Investigate proper X11 session generation for gaming + displayManager.gdm.wayland = true; + }; + + hardware = { + # Enable OpenGL + graphics.enable = true; + + # install graphics drivers + nvidia = { + # Modesetting is required. + modesetting.enable = true; + + # Nvidia power management. Experimental, and can cause sleep/suspend to fail. + # Enable this if you have graphical corruption issues or application crashes after waking + # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead + # of just the bare essentials. + powerManagement.enable = true; + + # Fine-grained power management. Turns off GPU when not in use. + # Experimental and only works on modern Nvidia GPUs (Turing or newer). + powerManagement.finegrained = false; + + # Use the NVidia open source kernel module (not to be confused with the + # independent third-party "nouveau" open source driver). + # Support is limited to the Turing and later architectures. Full list of + # supported GPUs is at: + # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus + # Only available from driver 515.43.04+ + # Currently alpha-quality/buggy, so false is currently the recommended setting. + open = true; + + # Enable the Nvidia settings menu, + # accessible via `nvidia-settings`. + nvidiaSettings = true; + + # Optionally, you may need to select the appropriate driver version for your specific GPU. + package = config.boot.kernelPackages.nvidiaPackages.production; + }; + }; + }; +} diff --git a/modules/parts.nix b/modules/parts.nix new file mode 100644 index 0000000..3be84e6 --- /dev/null +++ b/modules/parts.nix @@ -0,0 +1,118 @@ +{inputs, ...}: let + home-manager = inputs.home-manager; + sops-nix = inputs.sops-nix; + nix-syncthing = inputs.nix-syncthing; + disko = inputs.disko; + impermanence = inputs.impermanence; + + common-modules = [ + ../legacy-modules/common-modules + ]; + + home-manager-modules = + common-modules + ++ [ + sops-nix.homeManagerModules.sops + ../legacy-modules/home-manager-modules + ]; + + home-manager-base = _: { + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + home-manager.extraSpecialArgs = { + inherit inputs; + }; + home-manager.sharedModules = home-manager-modules; + }; + + system-modules = + common-modules + ++ [ + home-manager-base + ../legacy-modules/system-modules + ]; +in { + systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; + + flake.homeModules.homeModules = {imports = home-manager-modules;}; + + flake.nixosModules.nixosModules = { + imports = + system-modules + ++ [ + sops-nix.nixosModules.sops + nix-syncthing.nixosModules.syncthing + impermanence.nixosModules.impermanence + home-manager.nixosModules.home-manager + disko.nixosModules.disko + # lix-module.nixosModules.default + ../legacy-modules/nixos-modules + ({ + lib, + config, + ... + }: { + home-manager.users = { + leyla = lib.mkIf config.host.users.leyla.isNormalUser inputs.self.homeModules.leylaConfiguration; + eve = lib.mkIf config.host.users.eve.isNormalUser inputs.self.homeModules.eveConfiguration; + git = lib.mkIf (config.services.forgejo.enable or false) inputs.self.homeModules.gitConfiguration; + }; + }) + ]; + }; + + flake.darwinModules.darwinModules = { + imports = + system-modules + ++ [ + sops-nix.darwinModules.sops + home-manager.darwinModules.home-manager + ../legacy-modules/darwin-modules + ({ + lib, + config, + ... + }: { + home-manager.users = { + leyla = lib.mkIf config.host.users.leyla.isNormalUser inputs.self.homeModules.leylaConfiguration; + eve = lib.mkIf config.host.users.eve.isNormalUser inputs.self.homeModules.eveConfiguration; + }; + }) + ]; + }; + + perSystem = { + pkgs, + system, + ... + }: { + formatter = pkgs.alejandra; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + # for version controlling this repo + git + # for formatting code in this repo + alejandra + # for editing secrets in the secrets repo + sops + # for viewing configuration options defined in this repo + nix-inspect + # for installing flakes from this repo onto other systems + nixos-anywhere + # for updating disko configurations + pkgs.disko + # for viewing dconf entries + dconf-editor + # for MCP NixOS server support in development + inputs.mcp-nixos.packages.${system}.default + ]; + + SOPS_AGE_KEY_DIRECTORY = import ../const/sops_age_key_directory.nix; + + shellHook = '' + git config core.hooksPath .hooks + ''; + }; + }; +} diff --git a/util/default.nix b/util/default.nix deleted file mode 100644 index af97927..0000000 --- a/util/default.nix +++ /dev/null @@ -1,117 +0,0 @@ -{inputs}: let - util = (import ./default.nix) {inherit inputs;}; - outputs = inputs.self.outputs; - - lib = inputs.lib; - nixpkgs = inputs.nixpkgs; - home-manager = inputs.home-manager; - nix-darwin = inputs.nix-darwin; - sops-nix = inputs.sops-nix; - nix-syncthing = inputs.nix-syncthing; - disko = inputs.disko; - impermanence = inputs.impermanence; - # lix-module = inputs.lix-module; - - systems = [ - "aarch64-darwin" - "aarch64-linux" - "x86_64-darwin" - "x86_64-linux" - ]; - forEachSystem = nixpkgs.lib.genAttrs systems; - pkgsFor = system: nixpkgs.legacyPackages.${system}; - - common-modules = [ - ../legacy-modules/common-modules - ]; - - home-manager-modules = - common-modules - ++ [ - sops-nix.homeManagerModules.sops - ../legacy-modules/home-manager-modules - ]; - - home-manager-config = nixpkgs: { - home-manager.useUserPackages = true; - home-manager.backupFileExtension = "backup"; - home-manager.extraSpecialArgs = { - inherit inputs outputs util; - }; - home-manager.users = import ../configurations/home-manager (nixpkgs - // { - osConfig = nixpkgs.config; - }); - home-manager.sharedModules = home-manager-modules; - }; - - system-modules = - common-modules - ++ [ - home-manager-config - ../legacy-modules/system-modules - ]; - - syncthingConfiguration = nix-syncthing.lib.syncthingConfiguration { - modules = [ - (import ../configurations/syncthing) - ]; - }; -in { - forEachPkgs = lambda: forEachSystem (system: lambda system (pkgsFor system)); - - mkUnless = condition: yes: (lib.mkIf (!condition) yes); - mkIfElse = condition: yes: no: - lib.mkMerge [ - (lib.mkIf condition yes) - (lib.mkUnless condition no) - ]; - - mkNixosSystem = host: - nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs outputs util syncthingConfiguration;}; - modules = - system-modules - ++ [ - sops-nix.nixosModules.sops - nix-syncthing.nixosModules.syncthing - impermanence.nixosModules.impermanence - home-manager.nixosModules.home-manager - disko.nixosModules.disko - # lix-module.nixosModules.default - ../legacy-modules/nixos-modules - ../configurations/nixos/${host} - ]; - }; - - mkDarwinSystem = host: - nix-darwin.lib.darwinSystem { - specialArgs = {inherit inputs outputs util;}; - modules = - system-modules - ++ [ - sops-nix.darwinModules.sops - home-manager.darwinModules.home-manager - ../legacy-modules/darwin-modules - ../configurations/darwin/${host} - ]; - }; - - mkHome = { - user, - host, - system, - osConfig, - }: - home-manager.lib.homeManagerConfiguration { - pkgs = pkgsFor system; - extraSpecialArgs = { - inherit inputs util outputs osConfig; - }; - modules = - home-manager-modules - ++ [ - ../configurations/home-manager/${user} - ]; - }; -}