forked from jan-leila/nix-config
		
	Compare commits
	
		
			62 commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e1a5ddde95 | |||
| c0e2e7ba4a | |||
| 69ccbffd86 | |||
| f9c27c82b6 | |||
| e57c1df6e5 | |||
| df663e5438 | |||
| f91f20be7c | |||
| ec802a2462 | |||
| bb5c94ec2c | |||
| 81a6588537 | |||
| 758cbd17f7 | |||
| f72a6da013 | |||
| 7ad6a83dfa | |||
| c97d43957d | |||
| 5114f52607 | |||
| 30a042d709 | |||
| 89793fca6a | |||
| a8af8930fa | |||
| ecec04a9ce | |||
| 7f74060713 | |||
| c2435883f1 | |||
| 0f5507c328 | |||
| ad04be6534 | |||
| 4dd285c122 | |||
| 466926b919 | |||
| db8d36dadc | |||
| b17f8d49d5 | |||
| 455a98810a | |||
| 3f107f8d1e | |||
| 539af51473 | |||
| f21777b1fb | |||
| 290c0692bb | |||
| d19d535d85 | |||
| e8f7331b6c | |||
| ebf7ea3cf7 | |||
| dd165d48fe | |||
| 260e37e016 | |||
| 0c88746da1 | |||
| 46890110f8 | |||
| 290db94f42 | |||
| b05bfc31fe | |||
| 85a6f4a006 | |||
| 69ec14ef79 | |||
| 5ccfe1a337 | |||
| 62bb650878 | |||
| 488ef1e94a | |||
| 59dc4a7ee1 | |||
| 6afdcce951 | |||
| e895fa5edd | |||
| f02cb08570 | |||
| 352ca6fccf | |||
| c953571f2f | |||
| d87462981e | |||
| 75dcac8d17 | |||
| 80ad498f94 | |||
| 6d5a07e08f | |||
| 337f03b4e7 | |||
| a51a364ce9 | |||
| ee6d48fe49 | |||
| c81fa77a29 | |||
| 32c7086394 | |||
| f80ae02e47 | 
					 153 changed files with 3089 additions and 1922 deletions
				
			
		|  | @ -3,4 +3,12 @@ | ||||||
| 
 | 
 | ||||||
| echo "restoring stashed changes" | echo "restoring stashed changes" | ||||||
| 
 | 
 | ||||||
| git stash pop -q | # Find the most recent pre-commit stash and restore it | ||||||
|  | recent_stash=$(git stash list | grep "pre-commit-stash-" | head -n 1 | cut -d: -f1) | ||||||
|  | 
 | ||||||
|  | if [ -n "$recent_stash" ]; then | ||||||
|  |     echo "Found recent pre-commit stash: $recent_stash" | ||||||
|  |     git stash pop -q "$recent_stash" | ||||||
|  | else | ||||||
|  |     echo "No pre-commit stash found to restore" | ||||||
|  | fi | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								.hooks/post-merge
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								.hooks/post-merge
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | #!/usr/bin/env nix-shell | ||||||
|  | #! nix-shell -i bash ../shell.nix | ||||||
|  | 
 | ||||||
|  | # Get current branch name | ||||||
|  | current_branch=$(git branch --show-current) | ||||||
|  | 
 | ||||||
|  | # Only perform actions if we're on main branch and a merge just completed | ||||||
|  | if [ "$current_branch" = "main" ]; then | ||||||
|  |     echo "Post-merge on main branch - running nix flake check" | ||||||
|  |      | ||||||
|  |     # Run nix flake check after merge into main | ||||||
|  |     nix flake check | ||||||
|  |      | ||||||
|  |     if [ ! $? -eq 0 ]; then | ||||||
|  |         echo "Warning: nix flake check failed after merge into main" | ||||||
|  |         echo "Please fix the issues as soon as possible" | ||||||
|  |     else | ||||||
|  |         echo "nix flake check passed after merge" | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     # Check if there are any pre-commit stashes to restore | ||||||
|  |     recent_stash=$(git stash list | grep "pre-commit-stash-" | head -n 1 | cut -d: -f1) | ||||||
|  |      | ||||||
|  |     if [ -n "$recent_stash" ]; then | ||||||
|  |         echo "Post-merge: restoring pre-commit stash on main branch" | ||||||
|  |         git stash pop -q "$recent_stash" | ||||||
|  |     else | ||||||
|  |         echo "Post-merge: no pre-commit stash to restore on main branch" | ||||||
|  |     fi | ||||||
|  | else | ||||||
|  |     echo "Post-merge: no action needed on branch '$current_branch'" | ||||||
|  | fi | ||||||
|  | @ -1,15 +1,25 @@ | ||||||
| #!/usr/bin/env nix-shell | #!/usr/bin/env nix-shell | ||||||
| #! nix-shell -i bash ../shell.nix | #! nix-shell -i bash ../shell.nix | ||||||
| 
 | 
 | ||||||
| echo "stashing all uncommitted changes" | # Get current branch name | ||||||
| git stash -q --keep-index | current_branch=$(git branch --show-current) | ||||||
| 
 | 
 | ||||||
| echo "checking flakes all compile" | echo "stashing all uncommitted changes with named stash (excluding hooks)" | ||||||
|  | git stash push -q --keep-index -m "pre-commit-stash-$(date +%s)" -- ':!.hooks/' | ||||||
|  | 
 | ||||||
|  | # Only run nix flake check if we're on main branch | ||||||
|  | if [ "$current_branch" = "main" ]; then | ||||||
|  |     echo "On main branch - checking flakes all compile" | ||||||
|     nix flake check |     nix flake check | ||||||
| 
 | 
 | ||||||
|     if [ ! $? -eq 0 ]; then |     if [ ! $? -eq 0 ]; then | ||||||
|  |         echo "Error: nix flake check failed on main branch" | ||||||
|         exit 1 |         exit 1 | ||||||
|     fi |     fi | ||||||
|  |     echo "nix flake check passed" | ||||||
|  | else | ||||||
|  |     echo "Not on main branch - skipping nix flake check" | ||||||
|  | fi | ||||||
| 
 | 
 | ||||||
| echo "running linter" | echo "running linter" | ||||||
| alejandra -q . | alejandra -q . | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								.hooks/pre-merge-commit
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										37
									
								
								.hooks/pre-merge-commit
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | #!/usr/bin/env nix-shell | ||||||
|  | #! nix-shell -i bash ../shell.nix | ||||||
|  | 
 | ||||||
|  | # Get the target branch (the branch being merged into) | ||||||
|  | target_branch="" | ||||||
|  | 
 | ||||||
|  | # Check if we're in the middle of a merge | ||||||
|  | if [ -f .git/MERGE_HEAD ]; then | ||||||
|  |     # We're in a merge, check if the current branch is main | ||||||
|  |     current_branch=$(git branch --show-current) | ||||||
|  |     if [ "$current_branch" = "main" ]; then | ||||||
|  |         target_branch="main" | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # If we're merging into main, run nix flake check | ||||||
|  | if [ "$target_branch" = "main" ]; then | ||||||
|  |     echo "Merging into main branch - running nix flake check..." | ||||||
|  |      | ||||||
|  |     echo "stashing all uncommitted changes with named stash (excluding hooks)" | ||||||
|  |     git stash push -q --keep-index -m "pre-merge-stash-$(date +%s)" -- ':!.hooks/' | ||||||
|  | 
 | ||||||
|  |     echo "checking flakes all compile" | ||||||
|  |     nix flake check | ||||||
|  | 
 | ||||||
|  |     if [ ! $? -eq 0 ]; then | ||||||
|  |         echo "Error: nix flake check failed. Merge aborted." | ||||||
|  |         echo "Please fix the issues and try merging again." | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     echo "nix flake check passed. Merge can proceed." | ||||||
|  | else | ||||||
|  |     echo "Not merging into main branch, skipping nix flake check." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | exit 0 | ||||||
							
								
								
									
										91
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										91
									
								
								README.md
									
										
									
									
									
								
							|  | @ -43,39 +43,66 @@ nix multi user, multi system, configuration with `sops` secret management, `home | ||||||
| - Look into this for auto rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/` | - Look into this for auto rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/` | ||||||
| - Look into this for npins https://jade.fyi/blog/pinning-nixos-with-npins/ | - Look into this for npins https://jade.fyi/blog/pinning-nixos-with-npins/ | ||||||
| - https://nixos-and-flakes.thiscute.world/ | - https://nixos-and-flakes.thiscute.world/ | ||||||
|  | - proton mail now has an smtp server we could use that for our zfs and SMART test emails | ||||||
| 
 | 
 | ||||||
| # Tasks: | # Tasks: | ||||||
| 
 | 
 | ||||||
|  | ## Chores: | ||||||
|  | - [ ] test out crab hole service | ||||||
|  | 
 | ||||||
| ## Tech Debt | ## Tech Debt | ||||||
| - monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) | - [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/) | ||||||
| - nfs export should be backed by the same values for server and client | - [ ] migrate away from flakes and move to npins | ||||||
| ## New Features | 
 | ||||||
| - crab-hole | ## Broken things | ||||||
| - figure out why syncthing and jellyfins permissions don't propagate downwards | - [ ] figure out steam vr things? | ||||||
| - figure out steam vr things? | - [ ] whisper was having issues | ||||||
| - auto turn off on power loss - nut | 
 | ||||||
| - zfs email after scrubbing # TODO: test this | ## Data Integrity | ||||||
| - SMART test with email results | - [ ] zfs email after scrubbing # TODO: test this | ||||||
| - samba mounts | - [ ] SMART test with email results | ||||||
| - offline access for nfs mounts (overlay with rsync might be a good option here? https://www.spinics.net/lists/linux-unionfs/msg07105.html note about nfs4 and overlay fs) | - [ ] zfs encryption FIDO2 2fa (look into shavee) | ||||||
| - Create Tor guard/relay server | - [ ] rotate sops encryption keys periodically (and somehow sync between devices?) | ||||||
| - migrate away from flakes and move to npins | - [ ] Secure Boot - https://github.com/nix-community/lanzaboote | ||||||
| - whisper | - [ ] auto turn off on power loss - nut | ||||||
| - zfs encryption FIDO2 2fa (look into shavee) | - [ ] secondary server with data sync. Maybe a Pi with a usb hdd enclosure and use rtcwake to only turn on once a week to sync data over tailscale with connection initiated from pi's side. We could probably put this at LZ. Hoping for it to draw only like $1 of power a month. Initial sync should probably be done here before we move it over because that will take a while. Data should be encrypted so that devices doesn't have access to it. Project will prob cost like $1800 | ||||||
| - Secure Boot - https://github.com/nix-community/lanzaboote | 
 | ||||||
| - rotate sops encryption keys periodically (and somehow sync between devices?) | ## Data Access | ||||||
| - wake on LAN for updates | - [ ] nfs export should be backed by the same values for server and client | ||||||
| - remote distributed builds - https://nix.dev/tutorials/nixos/distributed-builds-setup.html | - [ ] samba mounts | ||||||
| - ISO target that contains authorized keys for nixos-anywhere https://github.com/diegofariasm/yggdrasil/blob/4acc43ebc7bcbf2e41376d14268e382007e94d78/hosts/bootstrap/default.nix | - [ ] offline access for nfs mounts (overlay with rsync might be a good option here? https://www.spinics.net/lists/linux-unionfs/msg07105.html note about nfs4 and overlay fs) | ||||||
| - panoramax instance | - [ ] figure out why syncthing and jellyfins permissions don't propagate downwards | ||||||
| - mastodon instance | - [ ] make radarr, sonarr, and bazarr accessible over vpn | ||||||
| - rework the reverse_proxy.nix file so that it is a normally named service. Then also change it so that we can hook into it with both a base domain and a subdomain to make migrating to vpn accessible services easier | - [ ] move searx, home-assistant, actual, vikunja, jellyfin, paperless, and immich to only be accessible via vpn | ||||||
| - move searx, home-assistant, actual, jellyfin, paperless, and immich to only be accessible via vpn | 
 | ||||||
| - make radarr, sonarr, and bazarr accessible over vpn | ## Services | ||||||
| - create some sort of service that allows uploading files to jellyfin | - [ ] vikunja service for project management | ||||||
| 	- auto sort files into where they should go with some combination of filebot cli and picard cli | - [ ] Penpot services (need to make this custom) | ||||||
| - graphana accessible though tailscale | - [ ] minecraft server with old world file | ||||||
| - fix panoramax package | - [ ] Create Tor guard/relay server | ||||||
| - actual instance | - [ ] mastodon instance | ||||||
| - intergrade radarr, sonarr, and bazarr | - [ ] screeps server | ||||||
| - claude code MCP servers should bundle node with them so they work in all environments | - [ ] storj server | ||||||
|  | 
 | ||||||
|  | ## DevOps | ||||||
|  | - [ ] wake on LAN for updates | ||||||
|  | - [ ] remote distributed builds - https://nix.dev/tutorials/nixos/distributed-builds-setup.html | ||||||
|  | - [ ] ISO target that contains authorized keys for nixos-anywhere https://github.com/diegofariasm/yggdrasil/blob/4acc43ebc7bcbf2e41376d14268e382007e94d78/hosts/bootstrap/default.nix | ||||||
|  | - [ ] fix panoramax package | ||||||
|  | - [ ] claude code MCP servers should bundle node with them so they work in all environments | ||||||
|  | 
 | ||||||
|  | ## Observability | ||||||
|  | - [ ] graphana for dashboards | ||||||
|  | - [ ] prometheus and loki for metric and log collection | ||||||
|  | 	- [ ] zfs storage usage | ||||||
|  | 	- [ ] zfs drive health status | ||||||
|  | 	- [ ] service version lag | ||||||
|  | 	- [ ] network/cpu/ram utilization | ||||||
|  | 	- [ ] http latency | ||||||
|  | 	- [ ] postgres db load | ||||||
|  | 	- [ ] nginx queries | ||||||
|  | - [ ] ntfy.sh for push notifications | ||||||
|  | - [ ] kuma for uptime visualization | ||||||
|  | 
 | ||||||
|  | ## Packages | ||||||
|  | - [ ] Custom private fork of MultiMC | ||||||
|  | @ -1,12 +1,39 @@ | ||||||
| {pkgs, ...}: { | { | ||||||
|  |   osConfig, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|   config = { |   config = { | ||||||
|     dconf = { |     gnome = lib.mkMerge [ | ||||||
|  |       { | ||||||
|  |         colorScheme = "prefer-dark"; | ||||||
|  |         accentColor = "slate"; | ||||||
|  |         clockFormat = "24h"; | ||||||
|  |         nightLight = { | ||||||
|           enable = true; |           enable = true; | ||||||
|       settings = { |           automatic = false; | ||||||
|         "org/gnome/shell".enabled-extensions = [ |           fromTime = 12.0; | ||||||
|           pkgs.gnomeExtensions.dash-to-panel.extensionUuid |           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; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ in { | ||||||
|     home.packages = lib.lists.optionals userConfig.isDesktopUser ( |     home.packages = lib.lists.optionals userConfig.isDesktopUser ( | ||||||
|       with pkgs; [ |       with pkgs; [ | ||||||
|         gnomeExtensions.dash-to-panel |         gnomeExtensions.dash-to-panel | ||||||
|  |         claude-code | ||||||
|       ] |       ] | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|  | @ -31,9 +32,11 @@ in { | ||||||
|       (lib.mkIf (config.user.isDesktopUser || config.user.isTerminalUser) { |       (lib.mkIf (config.user.isDesktopUser || config.user.isTerminalUser) { | ||||||
|         git = { |         git = { | ||||||
|           enable = true; |           enable = true; | ||||||
|           userName = "Eve"; |           settings = { | ||||||
|           userEmail = "evesnrobins@gmail.com"; |             user.name = "Eve"; | ||||||
|           extraConfig.init.defaultBranch = "main"; |             user.email = "evesnrobins@gmail.com"; | ||||||
|  |             init.defaultBranch = "main"; | ||||||
|  |           }; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         openssh = { |         openssh = { | ||||||
|  | @ -61,6 +64,22 @@ in { | ||||||
|         piper.enable = hardware.piperMouse.enable; |         piper.enable = hardware.piperMouse.enable; | ||||||
|         krita.enable = true; |         krita.enable = true; | ||||||
|         ungoogled-chromium.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; | ||||||
|  | 
 | ||||||
|  |         claude-code.enable = osConfig.host.ai.enable; | ||||||
|  | 
 | ||||||
|  |         # 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; | ||||||
|       }) |       }) | ||||||
|     ]; |     ]; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| {osConfig, ...}: { | {osConfig, ...}: { | ||||||
|  |   impermanence.fallbackPersistence.enable = false; | ||||||
|  | 
 | ||||||
|   home = { |   home = { | ||||||
|     username = osConfig.users.users.git.name; |     username = osConfig.users.users.git.name; | ||||||
|     homeDirectory = osConfig.users.users.git.home; |     homeDirectory = osConfig.users.users.git.home; | ||||||
|  |  | ||||||
|  | @ -1,31 +1,43 @@ | ||||||
| {pkgs, ...}: { | {...}: { | ||||||
|   config = { |   config = { | ||||||
|     gnome = { |     gnome = { | ||||||
|       extraWindowControls = true; |       extraWindowControls = true; | ||||||
|       colorScheme = "prefer-dark"; |       colorScheme = "prefer-dark"; | ||||||
|       clockFormat = "24h"; |       clockFormat = "24h"; | ||||||
|       extensions = [ |       nightLight = { | ||||||
|         pkgs.gnomeExtensions.dash-to-dock |         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 = { |       hotkeys = { | ||||||
|         "Open Terminal" = { |         "Open Terminal" = { | ||||||
|           binding = "<Super>t"; |           binding = "<Super>t"; | ||||||
|           command = "kgx"; |           command = "kgx"; | ||||||
|         }; |         }; | ||||||
|  |         "Open Firefox" = { | ||||||
|  |           binding = "<Super>f"; | ||||||
|  |           command = "firefox"; | ||||||
|  |         }; | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     dconf = { |     dconf = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       settings = { |       settings = { | ||||||
|         "org/gnome/shell/extensions/dash-to-dock" = { |  | ||||||
|           "dock-position" = "LEFT"; |  | ||||||
|           "intellihide-mode" = "ALL_WINDOWS"; |  | ||||||
|           "show-trash" = false; |  | ||||||
|           "require-pressure-to-show" = false; |  | ||||||
|           "show-mounts" = false; |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         "org/gnome/shell" = { |         "org/gnome/shell" = { | ||||||
|           favorite-apps = ["org.gnome.Nautilus.desktop" "firefox.desktop" "codium.desktop" "steam.desktop" "org.gnome.Console.desktop"]; |           favorite-apps = ["org.gnome.Nautilus.desktop" "firefox.desktop" "codium.desktop" "steam.desktop" "org.gnome.Console.desktop"]; | ||||||
|           # app-picker-layout = |           # app-picker-layout = | ||||||
|  |  | ||||||
|  | @ -12,6 +12,8 @@ | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   config = { |   config = { | ||||||
|  |     impermanence.enable = osConfig.host.impermanence.enable; | ||||||
|  | 
 | ||||||
|     # Home Manager needs a bit of information about you and the paths it should |     # Home Manager needs a bit of information about you and the paths it should | ||||||
|     # manage. |     # manage. | ||||||
|     home = { |     home = { | ||||||
|  | @ -87,7 +89,6 @@ | ||||||
|     # TODO: move this into a fonts module |     # TODO: move this into a fonts module | ||||||
|     home.packages = with pkgs; [ |     home.packages = with pkgs; [ | ||||||
|       aileron |       aileron | ||||||
|       nerd-fonts.open-dyslexic |  | ||||||
|     ]; |     ]; | ||||||
|     fonts.fontconfig.enable = true; |     fonts.fontconfig.enable = true; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -1,10 +1,9 @@ | ||||||
| { | { | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   config = lib.mkIf osConfig.host.impermanence.enable { |   config = lib.mkIf (config.impermanence.enable) { | ||||||
|     home.persistence."/persist/home/leyla" = { |     home.persistence."/persist/home/leyla" = { | ||||||
|       directories = [ |       directories = [ | ||||||
|         "desktop" |         "desktop" | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ | ||||||
| in { | in { | ||||||
|   imports = [ |   imports = [ | ||||||
|     ./vscode |     ./vscode | ||||||
|     ./firefox.nix |     ./firefox | ||||||
|     ./direnv.nix |     ./direnv.nix | ||||||
|     ./openssh.nix |     ./openssh.nix | ||||||
|     ./git.nix |     ./git.nix | ||||||
|  |  | ||||||
|  | @ -1,344 +0,0 @@ | ||||||
| { |  | ||||||
|   lib, |  | ||||||
|   pkgs, |  | ||||||
|   inputs, |  | ||||||
|   ... |  | ||||||
| }: { |  | ||||||
|   config = { |  | ||||||
|     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.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 |  | ||||||
| 
 |  | ||||||
|           deutsch-de-language-pack |  | ||||||
|           dictionary-german |  | ||||||
| 
 |  | ||||||
|           tab-session-manager |  | ||||||
| 
 |  | ||||||
|           # ( |  | ||||||
|           #   buildFirefoxXpiAddon rec { |  | ||||||
|           #     pname = "italiano-it-language-pack"; |  | ||||||
|           #     version = "132.0.20241110.231641"; |  | ||||||
|           #     addonId = "langpack-it@firefox.mozilla.org"; |  | ||||||
|           #     url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi"; |  | ||||||
|           #     sha256 = ""; |  | ||||||
|           #     meta = with lib; |  | ||||||
|           #     { |  | ||||||
|           #       description = "Firefox Language Pack for Italiano (it) – Italian"; |  | ||||||
|           #       license = licenses.mpl20; |  | ||||||
|           #       mozPermissions = []; |  | ||||||
|           #       platforms = platforms.all; |  | ||||||
|           #     }; |  | ||||||
|           #   } |  | ||||||
|           # ) |  | ||||||
|           # ( |  | ||||||
|           #   buildFirefoxXpiAddon rec { |  | ||||||
|           #     pname = "dizionario-italiano"; |  | ||||||
|           #     version = "5.1"; |  | ||||||
|           #     addonId = "it-IT@dictionaries.addons.mozilla.org"; |  | ||||||
|           #     url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi"; |  | ||||||
|           #     sha256 = ""; |  | ||||||
|           #     meta = with lib; |  | ||||||
|           #     { |  | ||||||
|           #       description = "Add support for Italian to spellchecking"; |  | ||||||
|           #       license = licenses.gpl3; |  | ||||||
|           #       mozPermissions = []; |  | ||||||
|           #       platforms = platforms.all; |  | ||||||
|           #     }; |  | ||||||
|           #   } |  | ||||||
|           # ) |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         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; |  | ||||||
| 
 |  | ||||||
|           # Security |  | ||||||
|           "privacy.trackingprotection.enabled" = true; |  | ||||||
|           "dom.security.https_only_mode" = true; |  | ||||||
| 
 |  | ||||||
|           "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" = ""; |  | ||||||
|           "dom.security.https_only_mode_pbm" = true; |  | ||||||
|           "dom.security.https_only_mode_error_page_user_suggestions" = true; |  | ||||||
| 
 |  | ||||||
|           # Disable telemetry |  | ||||||
|           "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; |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         bookmarks = { |  | ||||||
|           force = true; |  | ||||||
|           settings = [ |  | ||||||
|             { |  | ||||||
|               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 = "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 = [""]; |  | ||||||
|             } |  | ||||||
|             # Template |  | ||||||
|             # { |  | ||||||
|             #   name = ""; |  | ||||||
|             #   url = ""; |  | ||||||
|             #   keyword = ""; |  | ||||||
|             #   tags = [""]; |  | ||||||
|             # } |  | ||||||
|           ]; |  | ||||||
|         }; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
							
								
								
									
										149
									
								
								configurations/home-manager/leyla/packages/firefox/bookmarks.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								configurations/home-manager/leyla/packages/firefox/bookmarks.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,149 @@ | ||||||
|  | {...}: { | ||||||
|  |   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://budget.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 = [""]; | ||||||
|  |           } | ||||||
|  |           # Template | ||||||
|  |           # { | ||||||
|  |           #   name = ""; | ||||||
|  |           #   url = ""; | ||||||
|  |           #   keyword = ""; | ||||||
|  |           #   tags = [""]; | ||||||
|  |           # } | ||||||
|  |         ]; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   inputs, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|  |   imports = [ | ||||||
|  |     ./firefox.nix | ||||||
|  |     ./bookmarks.nix | ||||||
|  |     ./harden.nix | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   config = { | ||||||
|  |     programs.firefox = { | ||||||
|  |       enable = true; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										221
									
								
								configurations/home-manager/leyla/packages/firefox/firefox.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								configurations/home-manager/leyla/packages/firefox/firefox.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,221 @@ | ||||||
|  | { | ||||||
|  |   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.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 | ||||||
|  | 
 | ||||||
|  |         deutsch-de-language-pack | ||||||
|  |         dictionary-german | ||||||
|  | 
 | ||||||
|  |         tab-session-manager | ||||||
|  | 
 | ||||||
|  |         # (\ | ||||||
|  |         #   buildFirefoxXpiAddon rec {\ | ||||||
|  |         #     pname = "italiano-it-language-pack";\ | ||||||
|  |         #     version = "132.0.20241110.231641";\ | ||||||
|  |         #     addonId = "langpack-it@firefox.mozilla.org";\ | ||||||
|  |         #     url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi";\ | ||||||
|  |         #     sha256 = "";\ | ||||||
|  |         #     meta = with lib;\ | ||||||
|  |         #     {\ | ||||||
|  |         #       description = "Firefox Language Pack for Italiano (it) – Italian";\ | ||||||
|  |         #       license = licenses.mpl20;\ | ||||||
|  |         #       mozPermissions = [];\ | ||||||
|  |         #       platforms = platforms.all;\ | ||||||
|  |         #     };\ | ||||||
|  |         #   }\ | ||||||
|  |         # )\ | ||||||
|  |         # (\ | ||||||
|  |         #   buildFirefoxXpiAddon rec {\ | ||||||
|  |         #     pname = "dizionario-italiano";\ | ||||||
|  |         #     version = "5.1";\ | ||||||
|  |         #     addonId = "it-IT@dictionaries.addons.mozilla.org";\ | ||||||
|  |         #     url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi";\ | ||||||
|  |         #     sha256 = "";\ | ||||||
|  |         #     meta = with lib;\ | ||||||
|  |         #     {\ | ||||||
|  |         #       description = "Add support for Italian to spellchecking";\ | ||||||
|  |         #       license = licenses.gpl3;\ | ||||||
|  |         #       mozPermissions = [];\ | ||||||
|  |         #       platforms = platforms.all;\ | ||||||
|  |         #     };\ | ||||||
|  |         #   }\ | ||||||
|  |         # )\ | ||||||
|  |       ]; | ||||||
|  | 
 | ||||||
|  |       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; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,50 @@ | ||||||
|  | {...}: { | ||||||
|  |   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; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -2,9 +2,11 @@ | ||||||
|   config = { |   config = { | ||||||
|     programs = { |     programs = { | ||||||
|       git = { |       git = { | ||||||
|         userName = "Leyla Becker"; |         settings = { | ||||||
|         userEmail = "git@jan-leila.com"; |           user.name = "Leyla Becker"; | ||||||
|         extraConfig.init.defaultBranch = "main"; |           user.email = "git@jan-leila.com"; | ||||||
|  |           init.defaultBranch = "main"; | ||||||
|  |         }; | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ in { | ||||||
|               "javascript.updateImportsOnFileMove.enabled" = "always"; |               "javascript.updateImportsOnFileMove.enabled" = "always"; | ||||||
|               "editor.tabSize" = 2; |               "editor.tabSize" = 2; | ||||||
|               "editor.insertSpaces" = false; |               "editor.insertSpaces" = false; | ||||||
|  |               # "terminal.integrated.fontFamily" = "'Droid Sans Mono', 'monospace', monospace"; | ||||||
|             } |             } | ||||||
|           ]; |           ]; | ||||||
| 
 | 
 | ||||||
|  | @ -40,6 +41,7 @@ in { | ||||||
|             oneDark.enable = true; |             oneDark.enable = true; | ||||||
|             atomKeybindings.enable = true; |             atomKeybindings.enable = true; | ||||||
|             openRemoteSsh.enable = true; |             openRemoteSsh.enable = true; | ||||||
|  |             # openDyslexicFont.enable = false; | ||||||
| 
 | 
 | ||||||
|             # html development |             # html development | ||||||
|             autoRenameTag.enable = true; |             autoRenameTag.enable = true; | ||||||
|  | @ -67,6 +69,9 @@ in { | ||||||
|             # go development |             # go development | ||||||
|             go.enable = true; |             go.enable = true; | ||||||
| 
 | 
 | ||||||
|  |             # rust development | ||||||
|  |             rustAnalyzer.enable = true; | ||||||
|  | 
 | ||||||
|             # claude development |             # claude development | ||||||
|             claudeDev = lib.mkIf ai-tooling-enabled { |             claudeDev = lib.mkIf ai-tooling-enabled { | ||||||
|               enable = true; |               enable = true; | ||||||
|  |  | ||||||
|  | @ -57,7 +57,6 @@ | ||||||
|             "ata-ST18000NT001-3NF101_ZVTEF27J" |             "ata-ST18000NT001-3NF101_ZVTEF27J" | ||||||
|             "ata-ST18000NE000-3G6101_ZVTJ7359" |             "ata-ST18000NE000-3G6101_ZVTJ7359" | ||||||
|           ] |           ] | ||||||
|           # TODO: this needs to be configured manually |  | ||||||
|           [ |           [ | ||||||
|             "ata-ST4000NE001-2MA101_WS2275P3" |             "ata-ST4000NE001-2MA101_WS2275P3" | ||||||
|             "ata-ST4000NE001-2MA101_WS227B9F" |             "ata-ST4000NE001-2MA101_WS227B9F" | ||||||
|  | @ -103,18 +102,6 @@ | ||||||
|         directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; |         directories = ["leyla_documents" "eve_documents" "users_documents" "media"]; | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
|     reverse_proxy = { |  | ||||||
|       enable = true; |  | ||||||
|       enableACME = true; |  | ||||||
|       hostname = "jan-leila.com"; |  | ||||||
|     }; |  | ||||||
|     postgres = { |  | ||||||
|       extraUsers = { |  | ||||||
|         leyla = { |  | ||||||
|           isAdmin = true; |  | ||||||
|         }; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   systemd.network = { |   systemd.network = { | ||||||
|  | @ -226,6 +213,12 @@ | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   services = { |   services = { | ||||||
|  |     # PostgreSQL database server | ||||||
|  |     postgresql = { | ||||||
|  |       enable = true; | ||||||
|  |       adminUsers = ["leyla"]; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     # temp enable desktop environment for setup |     # temp enable desktop environment for setup | ||||||
|     # Enable the X11 windowing system. |     # Enable the X11 windowing system. | ||||||
|     xserver.enable = true; |     xserver.enable = true; | ||||||
|  | @ -238,6 +231,16 @@ | ||||||
|       gnome.enable = true; |       gnome.enable = true; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     # Enable new reverse proxy system | ||||||
|  |     reverseProxy = { | ||||||
|  |       enable = true; | ||||||
|  |       openFirewall = true; | ||||||
|  |       acme = { | ||||||
|  |         enable = true; | ||||||
|  |         email = "jan-leila@protonmail.com"; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     ollama = { |     ollama = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       exposePort = true; |       exposePort = true; | ||||||
|  | @ -295,35 +298,35 @@ | ||||||
| 
 | 
 | ||||||
|     jellyfin = { |     jellyfin = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "media"; |       domain = "media.jan-leila.com"; | ||||||
|       extraSubdomains = ["jellyfin"]; |       extraDomains = ["jellyfin.jan-leila.com"]; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     immich = { |     immich = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "photos"; |       domain = "photos.jan-leila.com"; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     forgejo = { |     forgejo = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "git"; |       reverseProxy.domain = "git.jan-leila.com"; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     searx = { |     searx = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "search"; |       domain = "search.jan-leila.com"; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     actual = { |     actual = { | ||||||
|       enable = false; |       enable = true; | ||||||
|       subdomain = "budget"; |       domain = "budget.jan-leila.com"; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     home-assistant = { |     home-assistant = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "home"; |       domain = "home.jan-leila.com"; | ||||||
|       openFirewall = true; |       openFirewall = true; | ||||||
|       database = "postgres"; |       postgres.enable = true; | ||||||
| 
 | 
 | ||||||
|       extensions = { |       extensions = { | ||||||
|         sonos.enable = true; |         sonos.enable = true; | ||||||
|  | @ -334,7 +337,7 @@ | ||||||
| 
 | 
 | ||||||
|     paperless = { |     paperless = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       subdomain = "documents"; |       domain = "documents.jan-leila.com"; | ||||||
|       passwordFile = config.sops.secrets."services/paperless_password".path; |       passwordFile = config.sops.secrets."services/paperless_password".path; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -343,6 +346,21 @@ | ||||||
|       openFirewall = true; |       openFirewall = true; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     crab-hole = { | ||||||
|  |       enable = true; | ||||||
|  |       port = 8085; | ||||||
|  |       openFirewall = true; | ||||||
|  |       show_doc = true; | ||||||
|  |       downstreams = { | ||||||
|  |         host = { | ||||||
|  |           enable = true; | ||||||
|  |           openFirewall = true; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       upstreams.cloudFlare.enable = true; | ||||||
|  |       blocklists.ad_malware.enable = true; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     qbittorrent = { |     qbittorrent = { | ||||||
|       enable = true; |       enable = true; | ||||||
|       mediaDir = "/srv/qbittorent"; |       mediaDir = "/srv/qbittorent"; | ||||||
|  | @ -350,21 +368,28 @@ | ||||||
|       webuiPort = 8084; |       webuiPort = 8084; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     filebot-cleanup = { |  | ||||||
|       enable = true; |  | ||||||
|       licenseFile = "/srv/jellyfin/filebot_license.psm"; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     sonarr = { |     sonarr = { | ||||||
|       enable = false; |       enable = true; | ||||||
|       openFirewall = true; |       openFirewall = true; | ||||||
|     }; |     }; | ||||||
|     radarr = { |     radarr = { | ||||||
|       enable = false; |       enable = true; | ||||||
|       openFirewall = true; |       openFirewall = true; | ||||||
|     }; |     }; | ||||||
|     bazarr = { |     bazarr = { | ||||||
|       enable = false; |       enable = true; | ||||||
|  |       openFirewall = true; | ||||||
|  |     }; | ||||||
|  |     lidarr = { | ||||||
|  |       enable = true; | ||||||
|  |       openFirewall = true; | ||||||
|  |     }; | ||||||
|  |     jackett = { | ||||||
|  |       enable = true; | ||||||
|  |       openFirewall = true; | ||||||
|  |     }; | ||||||
|  |     flaresolverr = { | ||||||
|  |       enable = true; | ||||||
|       openFirewall = true; |       openFirewall = true; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -4,6 +4,5 @@ | ||||||
|     ./hardware-configuration.nix |     ./hardware-configuration.nix | ||||||
|     ./configuration.nix |     ./configuration.nix | ||||||
|     ./packages.nix |     ./packages.nix | ||||||
|     ./filebot.nix |  | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,82 +0,0 @@ | ||||||
| { |  | ||||||
|   config, |  | ||||||
|   lib, |  | ||||||
|   pkgs, |  | ||||||
|   ... |  | ||||||
| }: |  | ||||||
| with lib; let |  | ||||||
|   cfg = config.services.filebot-cleanup; |  | ||||||
| in { |  | ||||||
|   options.services.filebot-cleanup = { |  | ||||||
|     enable = mkEnableOption "Filebot cleanup service"; |  | ||||||
| 
 |  | ||||||
|     licenseFile = mkOption { |  | ||||||
|       type = types.nullOr types.path; |  | ||||||
|       default = null; |  | ||||||
|       description = "Path to the Filebot license file"; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     cleanupDirectory = mkOption { |  | ||||||
|       type = types.str; |  | ||||||
|       default = "/srv/jellyfin/filebot_cleanup"; |  | ||||||
|       description = "Directory where cleaned up media files are stored"; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   config = mkIf cfg.enable { |  | ||||||
|     users.groups.filebot_cleanup = {}; |  | ||||||
|     users.users.filebot_cleanup = { |  | ||||||
|       isSystemUser = true; |  | ||||||
|       group = "filebot_cleanup"; |  | ||||||
|       extraGroups = ["jellyfin_media"]; |  | ||||||
|       home = cfg.cleanupDirectory; |  | ||||||
|       createHome = true; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     nixpkgs.config.allowUnfreePredicate = pkg: |  | ||||||
|       builtins.elem (lib.getName pkg) [ |  | ||||||
|         "filebot" |  | ||||||
|       ]; |  | ||||||
| 
 |  | ||||||
|     environment.systemPackages = with pkgs; [ |  | ||||||
|       filebot |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     systemd.services.filebot-cleanup = { |  | ||||||
|       description = "Filebot media cleanup service"; |  | ||||||
|       serviceConfig = { |  | ||||||
|         Type = "simple"; |  | ||||||
|         User = "filebot_cleanup"; |  | ||||||
|         Group = "filebot_cleanup"; |  | ||||||
|         ExecStart = pkgs.writeShellScript "filebot-cleanup" '' |  | ||||||
|           ${optionalString (cfg.licenseFile != null) '' |  | ||||||
|             ${pkgs.filebot}/bin/filebot --license "${cfg.licenseFile}" |  | ||||||
|           ''} |  | ||||||
|           ${pkgs.filebot}/bin/filebot -rename -r "/srv/jellyfin/media/Movies/" --output "${cfg.cleanupDirectory}/" --format "{jellyfin}" -non-strict --action duplicate |  | ||||||
|           ${pkgs.filebot}/bin/filebot -rename -r "/srv/jellyfin/media/Shows/" --output "${cfg.cleanupDirectory}/" --format "{jellyfin}" -non-strict --action duplicate |  | ||||||
|         ''; |  | ||||||
|         StandardOutput = "journal"; |  | ||||||
|         StandardError = "journal"; |  | ||||||
|       }; |  | ||||||
|       wantedBy = ["multi-user.target"]; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     environment.persistence = lib.mkIf config.host.impermanence.enable { |  | ||||||
|       "/persist/system/jellyfin" = { |  | ||||||
|         enable = true; |  | ||||||
|         hideMounts = true; |  | ||||||
|         files = [ |  | ||||||
|           cfg.licenseFile |  | ||||||
|         ]; |  | ||||||
|         directories = [ |  | ||||||
|           { |  | ||||||
|             directory = cfg.cleanupDirectory; |  | ||||||
|             user = "filebot_cleanup"; |  | ||||||
|             group = "filebot_cleanup"; |  | ||||||
|             mode = "1770"; |  | ||||||
|           } |  | ||||||
|         ]; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  | @ -41,12 +41,14 @@ | ||||||
| 
 | 
 | ||||||
|   # installed opentabletdriver |   # installed opentabletdriver | ||||||
|   hardware.opentabletdriver.enable = true; |   hardware.opentabletdriver.enable = true; | ||||||
|  |   hardware.keyboard.qmk.enable = true; | ||||||
| 
 | 
 | ||||||
|   # Enable the GNOME Desktop Environment. |   # Enable the GNOME Desktop Environment. | ||||||
|   services.displayManager.gdm.enable = true; |   services.displayManager.gdm.enable = true; | ||||||
|   services.desktopManager.gnome.enable = true; |   services.desktopManager.gnome.enable = true; | ||||||
| 
 | 
 | ||||||
|   host = { |   host = { | ||||||
|  |     ai.enable = true; | ||||||
|     users = { |     users = { | ||||||
|       eve = { |       eve = { | ||||||
|         isDesktopUser = true; |         isDesktopUser = true; | ||||||
|  | @ -68,6 +70,9 @@ | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   services.tailscale.enable = true; |   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 |   # Configure keymap in X11 | ||||||
|   # services.xserver.xkb.layout = "us"; |   # services.xserver.xkb.layout = "us"; | ||||||
|  |  | ||||||
							
								
								
									
										110
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										110
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							|  | @ -25,11 +25,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1758287904, |         "lastModified": 1760701190, | ||||||
|         "narHash": "sha256-IGmaEf3Do8o5Cwp1kXBN1wQmZwQN3NLfq5t4nHtVtcU=", |         "narHash": "sha256-y7UhnWlER8r776JsySqsbTUh2Txf7K30smfHlqdaIQw=", | ||||||
|         "owner": "nix-community", |         "owner": "nix-community", | ||||||
|         "repo": "disko", |         "repo": "disko", | ||||||
|         "rev": "67ff9807dd148e704baadbd4fd783b54282ca627", |         "rev": "3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -46,11 +46,11 @@ | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "dir": "pkgs/firefox-addons", |         "dir": "pkgs/firefox-addons", | ||||||
|         "lastModified": 1759403080, |         "lastModified": 1761797037, | ||||||
|         "narHash": "sha256-EteyL8KyG9R5xzqyOBzyag4n2cSemu61VFrl3opJSqE=", |         "narHash": "sha256-OqwAGit+3cdsG02K6+8WJniA2q0rqUVc6zbT5N9C1us=", | ||||||
|         "owner": "rycee", |         "owner": "rycee", | ||||||
|         "repo": "nur-expressions", |         "repo": "nur-expressions", | ||||||
|         "rev": "8af6dfcbcbf1115a4f5aeed77ff0db5d3c02caf0", |         "rev": "3d9f4de0988bcfa57e45e16e1ef9326c56bdf891", | ||||||
|         "type": "gitlab" |         "type": "gitlab" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -62,11 +62,11 @@ | ||||||
|     }, |     }, | ||||||
|     "flake-compat": { |     "flake-compat": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1747046372, |         "lastModified": 1761588595, | ||||||
|         "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", |         "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", | ||||||
|         "owner": "edolstra", |         "owner": "edolstra", | ||||||
|         "repo": "flake-compat", |         "repo": "flake-compat", | ||||||
|         "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", |         "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -111,24 +111,6 @@ | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "flake-utils_3": { |  | ||||||
|       "inputs": { |  | ||||||
|         "systems": "systems_3" |  | ||||||
|       }, |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1731533236, |  | ||||||
|         "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "flakey-profile": { |     "flakey-profile": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1712898590, |         "lastModified": 1712898590, | ||||||
|  | @ -151,11 +133,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759337100, |         "lastModified": 1761845621, | ||||||
|         "narHash": "sha256-CcT3QvZ74NGfM+lSOILcCEeU+SnqXRvl1XCRHenZ0Us=", |         "narHash": "sha256-d+R4MHsGmdebvSMsYUFWONsZSlUbOo8Zq/wjMdMiIac=", | ||||||
|         "owner": "nix-community", |         "owner": "nix-community", | ||||||
|         "repo": "home-manager", |         "repo": "home-manager", | ||||||
|         "rev": "004753ae6b04c4b18aa07192c1106800aaacf6c3", |         "rev": "97e3022a8d2c09313fa49847f6da4d76abcfc72d", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -182,11 +164,11 @@ | ||||||
|     "lix": { |     "lix": { | ||||||
|       "flake": false, |       "flake": false, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759624822, |         "lastModified": 1755787066, | ||||||
|         "narHash": "sha256-cf40qfsfpxJU/BnQ9PEj027LdPINNSsJqm+C6Ug93BA=", |         "narHash": "sha256-X2UwkUEban08GRSPXRr+kz8fckHqebr3P77qSvjoeOw=", | ||||||
|         "rev": "57333a0e600c5e096a609410a2f1059b97194b1e", |         "rev": "ac9721a92e8138d29707824dbedb484c76948493", | ||||||
|         "type": "tarball", |         "type": "tarball", | ||||||
|         "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/57333a0e600c5e096a609410a2f1059b97194b1e.tar.gz" |         "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/ac9721a92e8138d29707824dbedb484c76948493.tar.gz?rev=ac9721a92e8138d29707824dbedb484c76948493" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "type": "tarball", |         "type": "tarball", | ||||||
|  | @ -203,11 +185,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1756511062, |         "lastModified": 1759851320, | ||||||
|         "narHash": "sha256-IgD1JR7scSEwlK/YAbmrcTWpAYT30LPldCUHdzXkaMs=", |         "narHash": "sha256-n5dRAIC3/78drQtFxmQRrBLd6TKfotUnX7GWu0mAcSg=", | ||||||
|         "ref": "refs/heads/main", |         "ref": "refs/heads/main", | ||||||
|         "rev": "3f09a5eb772e02d98bb8878ab687d5b721f00d16", |         "rev": "7c31a18259b8358ac196cf803a26967c0fa1d3e4", | ||||||
|         "revCount": 162, |         "revCount": 163, | ||||||
|         "type": "git", |         "type": "git", | ||||||
|         "url": "https://git.lix.systems/lix-project/nixos-module.git" |         "url": "https://git.lix.systems/lix-project/nixos-module.git" | ||||||
|       }, |       }, | ||||||
|  | @ -225,11 +207,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759342933, |         "lastModified": 1760821194, | ||||||
|         "narHash": "sha256-mdlUFcrOfvT0Pm+Hko/6aR3xf1ao5JA2iem4KsEVjP4=", |         "narHash": "sha256-UCsJ8eDuHL14u2GFIYEY/drtZ6jht5zN/G/6QNlEy2g=", | ||||||
|         "owner": "utensils", |         "owner": "utensils", | ||||||
|         "repo": "mcp-nixos", |         "repo": "mcp-nixos", | ||||||
|         "rev": "50b02bcba32b941d2ec48fedef68641702ca5b0f", |         "rev": "0ae453f38d0f088c31d4678da3a12b183165986f", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -245,11 +227,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1758805352, |         "lastModified": 1761339987, | ||||||
|         "narHash": "sha256-BHdc43Lkayd+72W/NXRKHzX5AZ+28F3xaUs3a88/Uew=", |         "narHash": "sha256-IUaawVwItZKi64IA6kF6wQCLCzpXbk2R46dHn8sHkig=", | ||||||
|         "owner": "LnL7", |         "owner": "LnL7", | ||||||
|         "repo": "nix-darwin", |         "repo": "nix-darwin", | ||||||
|         "rev": "c48e963a5558eb1c3827d59d21c5193622a1477c", |         "rev": "7cd9aac79ee2924a85c211d21fafd394b06a38de", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -281,17 +263,16 @@ | ||||||
|     }, |     }, | ||||||
|     "nix-vscode-extensions": { |     "nix-vscode-extensions": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "flake-utils": "flake-utils_3", |  | ||||||
|         "nixpkgs": [ |         "nixpkgs": [ | ||||||
|           "nixpkgs" |           "nixpkgs" | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759369908, |         "lastModified": 1761789484, | ||||||
|         "narHash": "sha256-IIhaE6jAge64z+fIyi/8Vtu0JdTtapbp4CvwiuIkZ1E=", |         "narHash": "sha256-17gDUWloFXQlavqHRey/urQe6sQ3yP5hsQyYmcNOZyU=", | ||||||
|         "owner": "nix-community", |         "owner": "nix-community", | ||||||
|         "repo": "nix-vscode-extensions", |         "repo": "nix-vscode-extensions", | ||||||
|         "rev": "a66ad2141b1440a838ead278c6edfe8a4ce75e6c", |         "rev": "c47e683d236fa6e4c27dbda2af3468cb9aceb813", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -302,11 +283,11 @@ | ||||||
|     }, |     }, | ||||||
|     "nixos-hardware": { |     "nixos-hardware": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759261527, |         "lastModified": 1761827175, | ||||||
|         "narHash": "sha256-wPd5oGvBBpUEzMF0kWnXge0WITNsITx/aGI9qLHgJ4g=", |         "narHash": "sha256-XdPVSYyIBK4/ruoqujaQmmSGg3J2/EenexV9IEXhr6o=", | ||||||
|         "owner": "NixOS", |         "owner": "NixOS", | ||||||
|         "repo": "nixos-hardware", |         "repo": "nixos-hardware", | ||||||
|         "rev": "e087756cf4abbe1a34f3544c480fc1034d68742f", |         "rev": "43ffe9ac82567512abb83187cb673de1091bdfa8", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -334,11 +315,11 @@ | ||||||
|     }, |     }, | ||||||
|     "nixpkgs_2": { |     "nixpkgs_2": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759381078, |         "lastModified": 1761672384, | ||||||
|         "narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=", |         "narHash": "sha256-o9KF3DJL7g7iYMZq9SWgfS1BFlNbsm6xplRjVlOCkXI=", | ||||||
|         "owner": "nixos", |         "owner": "nixos", | ||||||
|         "repo": "nixpkgs", |         "repo": "nixpkgs", | ||||||
|         "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", |         "rev": "08dacfca559e1d7da38f3cf05f1f45ee9bfd213c", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -389,11 +370,11 @@ | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1759188042, |         "lastModified": 1760998189, | ||||||
|         "narHash": "sha256-f9QC2KKiNReZDG2yyKAtDZh0rSK2Xp1wkPzKbHeQVRU=", |         "narHash": "sha256-ee2e1/AeGL5X8oy/HXsZQvZnae6XfEVdstGopKucYLY=", | ||||||
|         "owner": "Mic92", |         "owner": "Mic92", | ||||||
|         "repo": "sops-nix", |         "repo": "sops-nix", | ||||||
|         "rev": "9fcfabe085281dd793589bdc770a2e577a3caa5d", |         "rev": "5a7d18b5c55642df5c432aadb757140edfeb70b3", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -431,21 +412,6 @@ | ||||||
|         "repo": "default", |         "repo": "default", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |  | ||||||
|     "systems_3": { |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1681028828, |  | ||||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", |  | ||||||
|         "owner": "nix-systems", |  | ||||||
|         "repo": "default", |  | ||||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "nix-systems", |  | ||||||
|         "repo": "default", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "root": "root", |   "root": "root", | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ | ||||||
|   src = fetchurl { |   src = fetchurl { | ||||||
|     url = "http://tools.mapillary.com/uploader/download/linux/${version}"; |     url = "http://tools.mapillary.com/uploader/download/linux/${version}"; | ||||||
|     name = "mapillary-uploader.AppImage"; |     name = "mapillary-uploader.AppImage"; | ||||||
|     sha256 = "sha256-Oyx7AIdA/2mwBaq7UzXOoyq/z2SU2sViMN40sY2RCQw="; |     sha256 = "sha256-hpWdfeuhYylO+SFD3BsKI0s/xtObCDd5OcuJ6i/aEuI="; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   appimageContents = appimageTools.extractType2 { |   appimageContents = appimageTools.extractType2 { | ||||||
|  | @ -23,9 +23,6 @@ in | ||||||
|       # Install desktop file |       # Install desktop file | ||||||
|       install -Dm644 ${appimageContents}/mapillary-desktop-uploader.desktop $out/share/applications/mapillary-uploader.desktop |       install -Dm644 ${appimageContents}/mapillary-desktop-uploader.desktop $out/share/applications/mapillary-uploader.desktop | ||||||
| 
 | 
 | ||||||
|       # Install icon |  | ||||||
|       install -Dm644 ${appimageContents}/usr/share/icons/hicolor/0x0/apps/mapillary-desktop-uploader.png $out/share/pixmaps/mapillary-uploader.png |  | ||||||
| 
 |  | ||||||
|       # Fix desktop file paths |       # Fix desktop file paths | ||||||
|       substituteInPlace $out/share/applications/mapillary-uploader.desktop \ |       substituteInPlace $out/share/applications/mapillary-uploader.desktop \ | ||||||
|         --replace 'Exec=AppRun' 'Exec=${pname}' |         --replace 'Exec=AppRun' 'Exec=${pname}' | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|   flutter332, |   flutter332, | ||||||
|   fetchFromGitLab, |   fetchFromGitLab, | ||||||
|   pkg-config, |   pkg-config, | ||||||
|   wrapGAppsHook, |   wrapGAppsHook3, | ||||||
|   gtk3, |   gtk3, | ||||||
|   glib, |   glib, | ||||||
|   glib-networking, |   glib-networking, | ||||||
|  | @ -65,7 +65,7 @@ flutter332.buildFlutterApplication rec { | ||||||
| 
 | 
 | ||||||
|   nativeBuildInputs = [ |   nativeBuildInputs = [ | ||||||
|     pkg-config |     pkg-config | ||||||
|     wrapGAppsHook |     wrapGAppsHook3 | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   buildInputs = [ |   buildInputs = [ | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
|     ./user.nix |     ./user.nix | ||||||
|     ./flipperzero.nix |     ./flipperzero.nix | ||||||
|     ./i18n.nix |     ./i18n.nix | ||||||
|  |     ./impermanence.nix | ||||||
|     ./openssh.nix |     ./openssh.nix | ||||||
|     ./gnome.nix |     ./gnome.nix | ||||||
|     ./programs |     ./programs | ||||||
|  |  | ||||||
|  | @ -1,8 +1,16 @@ | ||||||
| { | { | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|  |   pkgs, | ||||||
|   ... |   ... | ||||||
| }: { | }: let | ||||||
|  |   enabledExtensions = | ||||||
|  |     [] | ||||||
|  |     ++ lib.optional config.gnome.extensions.dash-to-dock.enable pkgs.gnomeExtensions.dash-to-dock | ||||||
|  |     ++ lib.optional config.gnome.extensions.dash-to-panel.enable pkgs.gnomeExtensions.dash-to-panel; | ||||||
|  | 
 | ||||||
|  |   extensions = config.gnome.extraExtensions ++ enabledExtensions; | ||||||
|  | in { | ||||||
|   options.gnome = { |   options.gnome = { | ||||||
|     extraWindowControls = lib.mkEnableOption "Should we add back in the minimize and maximize window controls?"; |     extraWindowControls = lib.mkEnableOption "Should we add back in the minimize and maximize window controls?"; | ||||||
|     clockFormat = lib.mkOption { |     clockFormat = lib.mkOption { | ||||||
|  | @ -34,7 +42,7 @@ | ||||||
|       ]; |       ]; | ||||||
|       default = "blue"; |       default = "blue"; | ||||||
|     }; |     }; | ||||||
|     extensions = lib.mkOption { |     extraExtensions = lib.mkOption { | ||||||
|       type = lib.types.listOf lib.types.package; |       type = lib.types.listOf lib.types.package; | ||||||
|       default = []; |       default = []; | ||||||
|       description = "The set of extensions to install and enable in the user environment."; |       description = "The set of extensions to install and enable in the user environment."; | ||||||
|  | @ -60,16 +68,80 @@ | ||||||
|       })); |       })); | ||||||
|       default = {}; |       default = {}; | ||||||
|     }; |     }; | ||||||
|  |     displayScaling = lib.mkOption { | ||||||
|  |       type = lib.types.nullOr (lib.types.enum [100 125 150 175 200]); | ||||||
|  |       default = null; | ||||||
|  |       description = "Display scaling percentage for GNOME"; | ||||||
|  |     }; | ||||||
|  |     experimentalFeatures = lib.mkOption { | ||||||
|  |       type = lib.types.submodule { | ||||||
|  |         options = { | ||||||
|  |           scaleMonitorFramebuffer = lib.mkEnableOption "scale-monitor-framebuffer experimental feature"; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       default = {}; | ||||||
|  |       description = "GNOME experimental features to enable"; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     nightLight = lib.mkOption { | ||||||
|  |       type = lib.types.submodule { | ||||||
|  |         options = { | ||||||
|  |           enable = lib.mkEnableOption "night light (blue light filter)"; | ||||||
|  |           automatic = lib.mkOption { | ||||||
|  |             type = lib.types.bool; | ||||||
|  |             default = true; | ||||||
|  |             description = "Whether to automatically schedule night light based on sunset/sunrise"; | ||||||
|  |           }; | ||||||
|  |           fromTime = lib.mkOption { | ||||||
|  |             type = lib.types.float; | ||||||
|  |             default = 20.0; | ||||||
|  |             description = "Start time for night light in 24-hour format (e.g., 20.0 for 8:00 PM)"; | ||||||
|  |           }; | ||||||
|  |           toTime = lib.mkOption { | ||||||
|  |             type = lib.types.float; | ||||||
|  |             default = 6.0; | ||||||
|  |             description = "End time for night light in 24-hour format (e.g., 6.0 for 6:00 AM)"; | ||||||
|  |           }; | ||||||
|  |           temperature = lib.mkOption { | ||||||
|  |             type = lib.types.int; | ||||||
|  |             default = 4000; | ||||||
|  |             description = "Color temperature for night light (1000-10000K, lower is warmer)"; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       default = {}; | ||||||
|  |       description = "Night light configuration"; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     extensions = { | ||||||
|  |       dash-to-dock = { | ||||||
|  |         enable = lib.mkEnableOption "Dash to Dock extension"; | ||||||
|  |         options = lib.mkOption { | ||||||
|  |           type = lib.types.nullOr lib.types.attrs; | ||||||
|  |           default = null; | ||||||
|  |           description = "Dash to Dock configuration options. If null, no custom configuration will be applied."; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       dash-to-panel = { | ||||||
|  |         enable = lib.mkEnableOption "Dash to Panel extension"; | ||||||
|  |         options = lib.mkOption { | ||||||
|  |           type = lib.types.nullOr lib.types.attrs; | ||||||
|  |           default = null; | ||||||
|  |           description = "Dash to Panel configuration options. If null, no custom configuration will be applied."; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   config = { |   config = { | ||||||
|     home.packages = config.gnome.extensions; |     home.packages = extensions; | ||||||
|     dconf = { |     dconf = { | ||||||
|       settings = lib.mkMerge [ |       settings = lib.mkMerge [ | ||||||
|         { |         { | ||||||
|           "org/gnome/shell" = { |           "org/gnome/shell" = { | ||||||
|             disable-user-extensions = false; # enables user extensions |             disable-user-extensions = false; # enables user extensions | ||||||
|             enabled-extensions = builtins.map (extension: extension.extensionUuid) config.gnome.extensions; |             enabled-extensions = builtins.map (extension: extension.extensionUuid) extensions; | ||||||
|           }; |           }; | ||||||
| 
 | 
 | ||||||
|           "org/gnome/desktop/wm/preferences".button-layout = lib.mkIf config.gnome.extraWindowControls ":minimize,maximize,close"; |           "org/gnome/desktop/wm/preferences".button-layout = lib.mkIf config.gnome.extraWindowControls ":minimize,maximize,close"; | ||||||
|  | @ -77,7 +149,23 @@ | ||||||
|           "org/gnome/desktop/interface".color-scheme = config.gnome.colorScheme; |           "org/gnome/desktop/interface".color-scheme = config.gnome.colorScheme; | ||||||
|           "org/gnome/desktop/interface".accent-color = config.gnome.accentColor; |           "org/gnome/desktop/interface".accent-color = config.gnome.accentColor; | ||||||
|           "org/gnome/desktop/interface".clock-format = config.gnome.clockFormat; |           "org/gnome/desktop/interface".clock-format = config.gnome.clockFormat; | ||||||
|  |           "org/gnome/desktop/interface".text-scaling-factor = lib.mkIf (config.gnome.displayScaling != null) (config.gnome.displayScaling / 100.0); | ||||||
|  | 
 | ||||||
|  |           "org/gnome/mutter".experimental-features = lib.mkIf (builtins.any (x: x) (builtins.attrValues config.gnome.experimentalFeatures)) ( | ||||||
|  |             lib.optional config.gnome.experimentalFeatures.scaleMonitorFramebuffer "scale-monitor-framebuffer" | ||||||
|  |           ); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         # Night light configuration | ||||||
|  |         (lib.mkIf config.gnome.nightLight.enable { | ||||||
|  |           "org/gnome/settings-daemon/plugins/color" = { | ||||||
|  |             night-light-enabled = true; | ||||||
|  |             night-light-schedule-automatic = config.gnome.nightLight.automatic; | ||||||
|  |             night-light-schedule-from = lib.mkIf (!config.gnome.nightLight.automatic) config.gnome.nightLight.fromTime; | ||||||
|  |             night-light-schedule-to = lib.mkIf (!config.gnome.nightLight.automatic) config.gnome.nightLight.toTime; | ||||||
|  |             night-light-temperature = config.gnome.nightLight.temperature; | ||||||
|  |           }; | ||||||
|  |         }) | ||||||
|         ( |         ( | ||||||
|           lib.mkMerge ( |           lib.mkMerge ( | ||||||
|             builtins.map (value: let |             builtins.map (value: let | ||||||
|  | @ -100,6 +188,15 @@ | ||||||
|             ) |             ) | ||||||
|           ) |           ) | ||||||
|         ) |         ) | ||||||
|  | 
 | ||||||
|  |         # Extension configurations | ||||||
|  |         (lib.mkIf (config.gnome.extensions.dash-to-dock.enable && config.gnome.extensions.dash-to-dock.options != null) { | ||||||
|  |           "org/gnome/shell/extensions/dash-to-dock" = config.gnome.extensions.dash-to-dock.options; | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|  |         (lib.mkIf (config.gnome.extensions.dash-to-panel.enable && config.gnome.extensions.dash-to-panel.options != null) { | ||||||
|  |           "org/gnome/shell/extensions/dash-to-panel" = config.gnome.extensions.dash-to-panel.options; | ||||||
|  |         }) | ||||||
|       ]; |       ]; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
							
								
								
									
										35
									
								
								modules/home-manager-modules/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								modules/home-manager-modules/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   osConfig, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.impermanence; | ||||||
|  | in { | ||||||
|  |   options.impermanence = { | ||||||
|  |     enable = lib.mkEnableOption "impermanence for home directory"; | ||||||
|  |     fallbackPersistence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = true; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkMerge [ | ||||||
|  |     (lib.mkIf config.impermanence.enable { | ||||||
|  |       assertions = [ | ||||||
|  |         { | ||||||
|  |           assertion = osConfig.host.impermanence.enable; | ||||||
|  |           message = "impermanence can not be enabled for a user when it is not enabled for the system"; | ||||||
|  |         } | ||||||
|  |       ]; | ||||||
|  |     }) | ||||||
|  |     # If impermanence is not enabled for this user but system impermanence is enabled, | ||||||
|  |     # persist the entire home directory as fallback | ||||||
|  |     (lib.mkIf (osConfig.host.impermanence.enable && !cfg.enable && cfg.fallbackPersistence.enable) { | ||||||
|  |       home.persistence."/persist/home/${config.home.username}" = { | ||||||
|  |         directories = ["."]; | ||||||
|  |         allowOther = true; | ||||||
|  |       }; | ||||||
|  |     }) | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | @ -95,7 +95,7 @@ | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
|       ) |       ) | ||||||
|       (lib.mkIf osConfig.host.impermanence.enable { |       (lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           files = lib.lists.flatten ( |           files = lib.lists.flatten ( | ||||||
|             builtins.map (hostKey: [".ssh/${hostKey.path}" ".ssh/${hostKey.path}.pub"]) config.programs.openssh.hostKeys |             builtins.map (hostKey: [".ssh/${hostKey.path}" ".ssh/${hostKey.path}.pub"]) config.programs.openssh.hostKeys | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.bitwarden = { |   options.programs.bitwarden = { | ||||||
|  | @ -12,11 +11,11 @@ | ||||||
|   config = lib.mkIf config.programs.bitwarden.enable (lib.mkMerge [ |   config = lib.mkIf config.programs.bitwarden.enable (lib.mkMerge [ | ||||||
|     { |     { | ||||||
|       home.packages = with pkgs; [ |       home.packages = with pkgs; [ | ||||||
|         bitwarden |         bitwarden-desktop | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/Bitwarden" |             "${config.xdg.configHome}/Bitwarden" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.bruno = { |   options.programs.bruno = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/bruno/" |             "${config.xdg.configHome}/bruno/" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.calibre = { |   options.programs.calibre = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/calibre" |             "${config.xdg.configHome}/calibre" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.davinci-resolve = { |   options.programs.davinci-resolve = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.dataHome}/DaVinciResolve" |             "${config.xdg.dataHome}/DaVinciResolve" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.dbeaver-bin = { |   options.programs.dbeaver-bin = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.dataHome}/DBeaverData/" |             "${config.xdg.dataHome}/DBeaverData/" | ||||||
|  |  | ||||||
|  | @ -12,11 +12,13 @@ | ||||||
|     ./obsidian.nix |     ./obsidian.nix | ||||||
|     ./prostudiomasters.nix |     ./prostudiomasters.nix | ||||||
|     ./idea.nix |     ./idea.nix | ||||||
|  |     ./kdenlive.nix | ||||||
|     ./krita.nix |     ./krita.nix | ||||||
|     ./protonvpn.nix |     ./protonvpn.nix | ||||||
|     ./calibre.nix |     ./calibre.nix | ||||||
|     ./bruno.nix |     ./bruno.nix | ||||||
|     ./dbeaver.nix |     ./dbeaver.nix | ||||||
|  |     ./dungeon-draft.nix | ||||||
|     ./steam.nix |     ./steam.nix | ||||||
|     ./vscode |     ./vscode | ||||||
|     ./ungoogled-chromium.nix |     ./ungoogled-chromium.nix | ||||||
|  | @ -24,6 +26,7 @@ | ||||||
|     ./mapillary-uploader.nix |     ./mapillary-uploader.nix | ||||||
|     ./inkscape.nix |     ./inkscape.nix | ||||||
|     ./gimp.nix |     ./gimp.nix | ||||||
|  |     ./guild-wars-2.nix | ||||||
|     ./proxmark3.nix |     ./proxmark3.nix | ||||||
|     ./freecad.nix |     ./freecad.nix | ||||||
|     ./onionshare.nix |     ./onionshare.nix | ||||||
|  | @ -33,11 +36,14 @@ | ||||||
|     ./qflipper.nix |     ./qflipper.nix | ||||||
|     ./openvpn.nix |     ./openvpn.nix | ||||||
|     ./noisetorch.nix |     ./noisetorch.nix | ||||||
|  |     ./olympus.nix | ||||||
|     ./openrgb.nix |     ./openrgb.nix | ||||||
|     ./via.nix |     ./via.nix | ||||||
|  |     ./vortex.nix | ||||||
|     ./davinci-resolve.nix |     ./davinci-resolve.nix | ||||||
|     ./gdx-liftoff.nix |     ./gdx-liftoff.nix | ||||||
|     ./tor-browser.nix |     ./tor-browser.nix | ||||||
|     ./polycule.nix |     ./polycule.nix | ||||||
|  |     ./vmware-workstation.nix | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.discord = { |   options.programs.discord = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/discord/" |             "${config.xdg.configHome}/discord/" | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								modules/home-manager-modules/programs/dungeon-draft.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								modules/home-manager-modules/programs/dungeon-draft.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.programs.dungeon-draft; | ||||||
|  | in { | ||||||
|  |   options.programs.dungeon-draft = { | ||||||
|  |     enable = lib.mkEnableOption "Dungeon Draft"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = !cfg.enable; | ||||||
|  |         message = '' | ||||||
|  |           Dungeon Draft module is not yet fully configured. | ||||||
|  |           Please download the Dungeon Draft executable (.exe) from the official website, | ||||||
|  |           then configure the Wine environment and executable path as needed. | ||||||
|  |         ''; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| { | { | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: let | }: let | ||||||
|   buildProfilePersistence = profile: { |   buildProfilePersistence = profile: { | ||||||
|  | @ -26,7 +25,7 @@ | ||||||
|     allowOther = true; |     allowOther = true; | ||||||
|   }; |   }; | ||||||
| in { | in { | ||||||
|   config = lib.mkIf (config.programs.firefox.enable && osConfig.host.impermanence.enable) { |   config = lib.mkIf (config.programs.firefox.enable && config.impermanence.enable) { | ||||||
|     home.persistence."/persist${config.home.homeDirectory}" = lib.mkMerge ( |     home.persistence."/persist${config.home.homeDirectory}" = lib.mkMerge ( | ||||||
|       ( |       ( | ||||||
|         lib.attrsets.mapAttrsToList |         lib.attrsets.mapAttrsToList | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.freecad = { |   options.programs.freecad = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/FreeCAD" |             "${config.xdg.configHome}/FreeCAD" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.gdx-liftoff = { |   options.programs.gdx-liftoff = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.gimp = { |   options.programs.gimp = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/GIMP" |             "${config.xdg.configHome}/GIMP" | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								modules/home-manager-modules/programs/guild-wars-2.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								modules/home-manager-modules/programs/guild-wars-2.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.programs.guild-wars-2; | ||||||
|  | in { | ||||||
|  |   options.programs.guild-wars-2 = { | ||||||
|  |     enable = lib.mkEnableOption "Guild Wars 2"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = !cfg.enable; | ||||||
|  |         message = '' | ||||||
|  |           Guild Wars 2 module is not yet fully configured. | ||||||
|  |           Please install Guild Wars 2 manually via Steam or the official client, | ||||||
|  |           then configure the Wine environment as needed. | ||||||
|  |         ''; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.jetbrains.idea-community = { |   options.programs.jetbrains.idea-community = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             # configuration |             # configuration | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.inkscape = { |   options.programs.inkscape = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/inkscape" |             "${config.xdg.configHome}/inkscape" | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								modules/home-manager-modules/programs/kdenlive.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								modules/home-manager-modules/programs/kdenlive.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.programs.kdenlive; | ||||||
|  | in { | ||||||
|  |   options.programs.kdenlive = { | ||||||
|  |     enable = lib.mkEnableOption "kdenlive"; | ||||||
|  |     package = lib.mkOption { | ||||||
|  |       type = lib.types.package; | ||||||
|  |       default = pkgs.kdePackages.kdenlive; | ||||||
|  |       description = "The kdenlive package to install."; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf cfg.enable (lib.mkMerge [ | ||||||
|  |     { | ||||||
|  |       home.packages = [ | ||||||
|  |         cfg.package | ||||||
|  |       ]; | ||||||
|  |     } | ||||||
|  |     ( | ||||||
|  |       lib.mkIf config.impermanence.enable { | ||||||
|  |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/kdenliverc" | ||||||
|  |             "${config.xdg.dataHome}/kdenlive" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|  |         }; | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.krita = { |   options.programs.krita = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/kritarc" |             "${config.xdg.configHome}/kritarc" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.libreoffice = { |   options.programs.libreoffice = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/libreoffice" |             "${config.xdg.configHome}/libreoffice" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.makemkv = { |   options.programs.makemkv = { | ||||||
|  | @ -30,7 +29,7 @@ | ||||||
|       home.file.".MakeMKV/settings.conf".source = config.lib.file.mkOutOfStoreSymlink config.sops.templates."MakeMKV.settings.conf".path; |       home.file.".MakeMKV/settings.conf".source = config.lib.file.mkOutOfStoreSymlink config.sops.templates."MakeMKV.settings.conf".path; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             ".MakeMKV" |             ".MakeMKV" | ||||||
|  |  | ||||||
|  | @ -11,7 +11,20 @@ in { | ||||||
|     enable = mkEnableOption "Mapillary Desktop Uploader"; |     enable = mkEnableOption "Mapillary Desktop Uploader"; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   config = mkIf cfg.enable { |   config = mkIf cfg.enable (mkMerge [ | ||||||
|  |     { | ||||||
|       home.packages = [pkgs.mapillary-uploader]; |       home.packages = [pkgs.mapillary-uploader]; | ||||||
|  |     } | ||||||
|  |     ( | ||||||
|  |       mkIf config.impermanence.enable { | ||||||
|  |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/mapillary-uploader" | ||||||
|  |             "${config.xdg.dataHome}/mapillary-uploader" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|         }; |         }; | ||||||
|       } |       } | ||||||
|  |     ) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.mfoc = { |   options.programs.mfoc = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.noisetorch = { |   options.programs.noisetorch = { | ||||||
|  |  | ||||||
|  | @ -1,13 +1,17 @@ | ||||||
| { | { | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   config = lib.mkIf config.programs.obs-studio.enable (lib.mkMerge [ |   config = lib.mkIf config.programs.obs-studio.enable (lib.mkMerge [ | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         # TODO: map impermanence for obs |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/obs-studio" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|  |         }; | ||||||
|       } |       } | ||||||
|     ) |     ) | ||||||
|   ]); |   ]); | ||||||
|  |  | ||||||
|  | @ -1,12 +1,11 @@ | ||||||
| { | { | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   config = lib.mkIf config.programs.obsidian.enable (lib.mkMerge [ |   config = lib.mkIf config.programs.obsidian.enable (lib.mkMerge [ | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/obsidian" |             "${config.xdg.configHome}/obsidian" | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								modules/home-manager-modules/programs/olympus.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								modules/home-manager-modules/programs/olympus.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.programs.olympus; | ||||||
|  | in { | ||||||
|  |   options.programs.olympus = { | ||||||
|  |     enable = lib.mkEnableOption "olympus"; | ||||||
|  |     package = lib.mkOption { | ||||||
|  |       type = lib.types.package; | ||||||
|  |       default = pkgs.olympus; | ||||||
|  |       description = "The olympus package to install."; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf cfg.enable (lib.mkMerge [ | ||||||
|  |     { | ||||||
|  |       home.packages = [ | ||||||
|  |         cfg.package | ||||||
|  |       ]; | ||||||
|  |     } | ||||||
|  |     ( | ||||||
|  |       lib.mkIf config.impermanence.enable { | ||||||
|  |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/olympus" | ||||||
|  |             "${config.xdg.dataHome}/olympus" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|  |         }; | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.onionshare = { |   options.programs.onionshare = { | ||||||
|  |  | ||||||
|  | @ -2,16 +2,27 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.openrgb = { |   options.programs.openrgb = { | ||||||
|     enable = lib.mkEnableOption "enable openrgb"; |     enable = lib.mkEnableOption "enable openrgb"; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   config = lib.mkIf config.programs.openrgb.enable { |   config = lib.mkIf config.programs.openrgb.enable (lib.mkMerge [ | ||||||
|  |     { | ||||||
|       home.packages = with pkgs; [ |       home.packages = with pkgs; [ | ||||||
|         openrgb |         openrgb | ||||||
|       ]; |       ]; | ||||||
|  |     } | ||||||
|  |     ( | ||||||
|  |       lib.mkIf config.impermanence.enable { | ||||||
|  |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/OpenRGB" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|         }; |         }; | ||||||
|       } |       } | ||||||
|  |     ) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.openvpn = { |   options.programs.openvpn = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.pdfarranger = { |   options.programs.pdfarranger = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.picard = { |   options.programs.picard = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/MusicBrainz" |             "${config.xdg.configHome}/MusicBrainz" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.piper = { |   options.programs.piper = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.polycule = { |   options.programs.polycule = { | ||||||
|  | @ -17,7 +16,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           # TODO: check that these are actually the correct folders |           # TODO: check that these are actually the correct folders | ||||||
|           # directories = [ |           # directories = [ | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.prostudiomasters = { |   options.programs.prostudiomasters = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/ProStudioMasters" |             "${config.xdg.configHome}/ProStudioMasters" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.protonvpn-gui = { |   options.programs.protonvpn-gui = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/protonvpn" |             "${config.xdg.configHome}/protonvpn" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.proxmark3 = { |   options.programs.proxmark3 = { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.qbittorrent = { |   options.programs.qbittorrent = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/qBittorrent" |             "${config.xdg.configHome}/qBittorrent" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.qflipper = { |   options.programs.qflipper = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/qFlipper" |             "${config.xdg.configHome}/qFlipper" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.signal-desktop-bin = { |   options.programs.signal-desktop-bin = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/Signal" |             "${config.xdg.configHome}/Signal" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.steam = { |   options.programs.steam = { | ||||||
|  | @ -18,7 +17,7 @@ | ||||||
|         ]; |         ]; | ||||||
|       } |       } | ||||||
|       ( |       ( | ||||||
|         lib.mkIf osConfig.host.impermanence.enable { |         lib.mkIf config.impermanence.enable { | ||||||
|           home.persistence."/persist${config.home.homeDirectory}" = { |           home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|             directories = [ |             directories = [ | ||||||
|               { |               { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.tor-browser = { |   options.programs.tor-browser = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.dataHome}/torbrowser" |             "${config.xdg.dataHome}/torbrowser" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.ungoogled-chromium = { |   options.programs.ungoogled-chromium = { | ||||||
|  | @ -16,7 +15,7 @@ | ||||||
|       ]; |       ]; | ||||||
|     } |     } | ||||||
|     ( |     ( | ||||||
|       lib.mkIf osConfig.host.impermanence.enable { |       lib.mkIf config.impermanence.enable { | ||||||
|         home.persistence."/persist${config.home.homeDirectory}" = { |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|           directories = [ |           directories = [ | ||||||
|             "${config.xdg.configHome}/chromium" |             "${config.xdg.configHome}/chromium" | ||||||
|  |  | ||||||
|  | @ -2,16 +2,28 @@ | ||||||
|   lib, |   lib, | ||||||
|   pkgs, |   pkgs, | ||||||
|   config, |   config, | ||||||
|   osConfig, |  | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.programs.via = { |   options.programs.via = { | ||||||
|     enable = lib.mkEnableOption "enable via"; |     enable = lib.mkEnableOption "enable via"; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   config = lib.mkIf config.programs.via.enable { |   config = lib.mkIf config.programs.via.enable (lib.mkMerge [ | ||||||
|  |     { | ||||||
|       home.packages = with pkgs; [ |       home.packages = with pkgs; [ | ||||||
|         via |         via | ||||||
|       ]; |       ]; | ||||||
|  |     } | ||||||
|  |     ( | ||||||
|  |       lib.mkIf config.impermanence.enable { | ||||||
|  |         home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |           directories = [ | ||||||
|  |             "${config.xdg.configHome}/via" | ||||||
|  |             "${config.xdg.dataHome}/via" | ||||||
|  |           ]; | ||||||
|  |           allowOther = true; | ||||||
|         }; |         }; | ||||||
|       } |       } | ||||||
|  |     ) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								modules/home-manager-modules/programs/vmware-workstation.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								modules/home-manager-modules/programs/vmware-workstation.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|  |   options.programs.vmware-workstation = { | ||||||
|  |     enable = lib.mkEnableOption "enable VMware Workstation"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.programs.vmware-workstation.enable ( | ||||||
|  |     lib.mkMerge [ | ||||||
|  |       { | ||||||
|  |         home.packages = with pkgs; [ | ||||||
|  |           vmware-workstation | ||||||
|  |         ]; | ||||||
|  |       } | ||||||
|  |       ( | ||||||
|  |         lib.mkIf config.impermanence.enable { | ||||||
|  |           home.persistence."/persist${config.home.homeDirectory}" = { | ||||||
|  |             directories = [ | ||||||
|  |               { | ||||||
|  |                 directory = ".vmware"; | ||||||
|  |                 method = "symlink"; | ||||||
|  |               } | ||||||
|  |               { | ||||||
|  |                 directory = "vmware"; | ||||||
|  |                 method = "symlink"; | ||||||
|  |               } | ||||||
|  |             ]; | ||||||
|  |             allowOther = true; | ||||||
|  |           }; | ||||||
|  |         } | ||||||
|  |       ) | ||||||
|  |     ] | ||||||
|  |   ); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								modules/home-manager-modules/programs/vortex.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								modules/home-manager-modules/programs/vortex.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.programs.vortex; | ||||||
|  | in { | ||||||
|  |   options.programs.vortex = { | ||||||
|  |     enable = lib.mkEnableOption "Vortex (Nexus Mods manager)"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = !cfg.enable; | ||||||
|  |         message = '' | ||||||
|  |           Vortex module is not yet fully configured. | ||||||
|  |           Please download and install Vortex manually from the Nexus Mods website, | ||||||
|  |           then configure the Wine environment and dependencies as needed. | ||||||
|  |         ''; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
|     ./go.nix |     ./go.nix | ||||||
|     ./evenBetterToml.nix |     ./evenBetterToml.nix | ||||||
|     ./openRemoteSsh.nix |     ./openRemoteSsh.nix | ||||||
|  |     ./rustAnalyzer.nix | ||||||
|     ./astroVscode.nix |     ./astroVscode.nix | ||||||
|     ./vscodeMdx.nix |     ./vscodeMdx.nix | ||||||
|     ./claudeDev.nix |     ./claudeDev.nix | ||||||
|  | @ -23,5 +24,6 @@ | ||||||
|     ./vitest.nix |     ./vitest.nix | ||||||
|     ./direnv.nix |     ./direnv.nix | ||||||
|     ./conventionalCommits.nix |     ./conventionalCommits.nix | ||||||
|  |     ./openDyslexicFont.nix | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,49 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|  |   options.programs.vscode.profiles = lib.mkOption { | ||||||
|  |     type = lib.types.attrsOf (lib.types.submodule ({config, ...}: { | ||||||
|  |       options = { | ||||||
|  |         extraExtensions.openDyslexicFont = { | ||||||
|  |           enable = lib.mkEnableOption "should OpenDyslexic font be set as the default font for VSCode"; | ||||||
|  |           package = lib.mkPackageOption pkgs "nerd-fonts.open-dyslexic" { | ||||||
|  |             default = ["nerd-fonts" "open-dyslexic"]; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       config = lib.mkIf config.extraExtensions.openDyslexicFont.enable { | ||||||
|  |         userSettings = { | ||||||
|  |           "editor.fontFamily" = "'OpenDyslexicM Nerd Font Mono', Droid Sans Mono, monospace"; | ||||||
|  |           "editor.fontSize" = 14; | ||||||
|  |           "editor.letterSpacing" = -0.3; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = let | ||||||
|  |     enabledProfiles = | ||||||
|  |       lib.filter (profile: profile.extraExtensions.openDyslexicFont.enable or false) | ||||||
|  |       (lib.attrValues config.programs.vscode.profiles); | ||||||
|  | 
 | ||||||
|  |     anyProfileUsesOpenDyslexicFont = enabledProfiles != []; | ||||||
|  | 
 | ||||||
|  |     fontPackages = lib.unique (map (profile: profile.extraExtensions.openDyslexicFont.package) enabledProfiles); | ||||||
|  |   in { | ||||||
|  |     # Ensure OpenDyslexic font packages are installed when any VSCode profile uses them | ||||||
|  |     home.packages = fontPackages; | ||||||
|  | 
 | ||||||
|  |     fonts.fontconfig.enable = lib.mkIf anyProfileUsesOpenDyslexicFont true; | ||||||
|  | 
 | ||||||
|  |     # Add assertion to ensure the fonts are available | ||||||
|  |     assertions = | ||||||
|  |       map (fontPkg: { | ||||||
|  |         assertion = lib.elem fontPkg config.home.packages; | ||||||
|  |         message = "OpenDyslexic font package '${fontPkg.name or "unknown"}' must be installed when using openDyslexicFont extension for VSCode."; | ||||||
|  |       }) | ||||||
|  |       fontPackages; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,27 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   pkgsRepositories = pkgs.nix-vscode-extensions.forVSCodeVersion config.programs.vscode.package.version; | ||||||
|  |   pkgsRepository = pkgsRepositories.open-vsx; | ||||||
|  | in { | ||||||
|  |   options.programs.vscode.profiles = lib.mkOption { | ||||||
|  |     type = lib.types.attrsOf (lib.types.submodule ({config, ...}: { | ||||||
|  |       options = { | ||||||
|  |         extraExtensions.rustAnalyzer = { | ||||||
|  |           enable = lib.mkEnableOption "should the rust-analyzer extension for vscode be enabled"; | ||||||
|  |           extension = lib.mkPackageOption pkgsRepository "rust-analyzer" { | ||||||
|  |             default = ["rust-lang" "rust-analyzer"]; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       config = lib.mkIf config.extraExtensions.rustAnalyzer.enable { | ||||||
|  |         extensions = [ | ||||||
|  |           config.extraExtensions.rustAnalyzer.extension | ||||||
|  |         ]; | ||||||
|  |       }; | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								modules/nixos-modules/server/actual/actual.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								modules/nixos-modules/server/actual/actual.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   const = import ./const.nix; | ||||||
|  |   dataDirectory = const.dataDirectory; | ||||||
|  | in { | ||||||
|  |   options.services.actual = { | ||||||
|  |     port = lib.mkOption { | ||||||
|  |       type = lib.types.port; | ||||||
|  |       description = "The port to listen on"; | ||||||
|  |       default = 5006; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  |   config = lib.mkIf config.services.actual.enable { | ||||||
|  |     services.actual = { | ||||||
|  |       settings = { | ||||||
|  |         port = config.services.actual.port; | ||||||
|  |         dataDir = dataDirectory; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -1,3 +1,3 @@ | ||||||
| { | { | ||||||
|   dataDirectory = "/var/lib/actual/"; |   dataDirectory = "/var/lib/private/actual"; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,26 +1,8 @@ | ||||||
| { | { | ||||||
|   lib, |  | ||||||
|   config, |  | ||||||
|   ... |  | ||||||
| }: let |  | ||||||
|   const = import ./const.nix; |  | ||||||
|   dataDirectory = const.dataDirectory; |  | ||||||
| in { |  | ||||||
|   imports = [ |   imports = [ | ||||||
|  |     ./actual.nix | ||||||
|     ./proxy.nix |     ./proxy.nix | ||||||
|     ./fail2ban.nix |     ./fail2ban.nix | ||||||
|     ./impermanence.nix |     ./impermanence.nix | ||||||
|   ]; |   ]; | ||||||
| 
 |  | ||||||
|   config = lib.mkIf config.services.actual.enable { |  | ||||||
|     systemd.tmpfiles.rules = [ |  | ||||||
|       "d ${dataDirectory} 2770 actual actual" |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     services.actual = { |  | ||||||
|       settings = { |  | ||||||
|         ACTUAL_DATA_DIR = dataDirectory; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,11 +6,22 @@ | ||||||
|   const = import ./const.nix; |   const = import ./const.nix; | ||||||
|   dataDirectory = const.dataDirectory; |   dataDirectory = const.dataDirectory; | ||||||
| in { | in { | ||||||
|   config = lib.mkIf (config.services.actual.enable && config.host.impermanence.enable) { |   options.services.actual = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.actual.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.actual.impermanence.enable { | ||||||
|     assertions = [ |     assertions = [ | ||||||
|       { |       { | ||||||
|         assertion = config.services.actual.settings.ACTUAL_DATA_DIR == dataDirectory; |         assertion = config.services.actual.settings.dataDir == dataDirectory; | ||||||
|         message = "actual data location does not match persistence"; |         message = "actual data location does not match persistence\nconfig directory: ${config.services.actual.settings.dataDir}\npersistence directory: ${dataDirectory}"; | ||||||
|  |       } | ||||||
|  |       { | ||||||
|  |         assertion = config.systemd.services.actual.serviceConfig.DynamicUser or false; | ||||||
|  |         message = "actual systemd service must have DynamicUser enabled to use private directory"; | ||||||
|       } |       } | ||||||
|     ]; |     ]; | ||||||
|     environment.persistence."/persist/system/root" = { |     environment.persistence."/persist/system/root" = { | ||||||
|  |  | ||||||
|  | @ -4,17 +4,30 @@ | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   options.services.actual = { |   options.services.actual = { | ||||||
|     subdomain = lib.mkOption { |     domain = lib.mkOption { | ||||||
|       type = lib.types.str; |       type = lib.types.str; | ||||||
|       default = "actual"; |       description = "domain that actual will be hosted at"; | ||||||
|       description = "subdomain of base domain that actual will be hosted at"; |       default = "actual.arpa"; | ||||||
|  |     }; | ||||||
|  |     extraDomains = lib.mkOption { | ||||||
|  |       type = lib.types.listOf lib.types.str; | ||||||
|  |       description = "extra domains that should be configured for actual"; | ||||||
|  |       default = []; | ||||||
|  |     }; | ||||||
|  |     reverseProxy.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.actual.enable && config.services.reverseProxy.enable; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   config = lib.mkIf (config.services.actual.enable && config.host.reverse_proxy.enable) { |   config = lib.mkIf config.services.actual.reverseProxy.enable { | ||||||
|     host = { |     services.reverseProxy.services.actual = { | ||||||
|       reverse_proxy.subdomains.${config.services.actual.subdomain} = { |  | ||||||
|       target = "http://localhost:${toString config.services.actual.settings.port}"; |       target = "http://localhost:${toString config.services.actual.settings.port}"; | ||||||
|  |       domain = config.services.actual.domain; | ||||||
|  |       extraDomains = config.services.actual.extraDomains; | ||||||
|  | 
 | ||||||
|  |       settings = { | ||||||
|  |         forwardHeaders.enable = true; | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| {...}: { | {...}: { | ||||||
|   imports = [ |   imports = [ | ||||||
|     ./proxy.nix |  | ||||||
|     ./impermanence.nix |     ./impermanence.nix | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,7 +5,14 @@ | ||||||
| }: let | }: let | ||||||
|   bazarr_data_directory = "/var/lib/bazarr"; |   bazarr_data_directory = "/var/lib/bazarr"; | ||||||
| in { | in { | ||||||
|   config = lib.mkIf (config.services.bazarr.enable && config.host.impermanence.enable) { |   options.services.bazarr = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.bazarr.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.bazarr.impermanence.enable { | ||||||
|     assertions = [ |     assertions = [ | ||||||
|       { |       { | ||||||
|         assertion = config.services.bazarr.dataDir == bazarr_data_directory; |         assertion = config.services.bazarr.dataDir == bazarr_data_directory; | ||||||
|  |  | ||||||
|  | @ -1,28 +0,0 @@ | ||||||
| { |  | ||||||
|   lib, |  | ||||||
|   config, |  | ||||||
|   ... |  | ||||||
| }: { |  | ||||||
|   options.services.bazarr = { |  | ||||||
|     subdomain = lib.mkOption { |  | ||||||
|       type = lib.types.nullOr lib.types.str; |  | ||||||
|       default = null; |  | ||||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; |  | ||||||
|     }; |  | ||||||
|     extraSubdomains = lib.mkOption { |  | ||||||
|       type = lib.types.listOf lib.types.str; |  | ||||||
|       default = []; |  | ||||||
|       description = "Extra subdomains for reverse proxy."; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   config = lib.mkIf (config.services.bazarr.enable && config.services.bazarr.subdomain != null) { |  | ||||||
|     host.reverse_proxy.subdomains.bazarr = { |  | ||||||
|       subdomain = config.services.bazarr.subdomain; |  | ||||||
|       extraSubdomains = config.services.bazarr.extraSubdomains; |  | ||||||
|       target = "http://127.0.0.1:6767"; |  | ||||||
|       websockets.enable = true; |  | ||||||
|       forwardHeaders.enable = true; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
							
								
								
									
										193
									
								
								modules/nixos-modules/server/crab-hole/crab-hole.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								modules/nixos-modules/server/crab-hole/crab-hole.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,193 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   cfg = config.services.crab-hole; | ||||||
|  | in { | ||||||
|  |   options.services.crab-hole = { | ||||||
|  |     port = lib.mkOption { | ||||||
|  |       type = lib.types.port; | ||||||
|  |       default = 8080; | ||||||
|  |       description = "Port for the crab-hole API to listen on."; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     openFirewall = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = false; | ||||||
|  |       description = "Whether to open the firewall for the crab-hole API port."; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     listen = lib.mkOption { | ||||||
|  |       type = lib.types.str; | ||||||
|  |       default = "0.0.0.0"; | ||||||
|  |       description = "Address for the crab-hole API to listen on."; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     show_doc = lib.mkEnableOption "OpenAPI documentation (loads content from third party websites)"; | ||||||
|  | 
 | ||||||
|  |     downstreams = { | ||||||
|  |       host = { | ||||||
|  |         enable = lib.mkEnableOption "host downstream DNS server accessible from network on all interfaces"; | ||||||
|  |         port = lib.mkOption { | ||||||
|  |           type = lib.types.port; | ||||||
|  |           default = 53; | ||||||
|  |           description = "Port for the host downstream DNS server to listen on."; | ||||||
|  |         }; | ||||||
|  |         openFirewall = lib.mkEnableOption "automatic port forwarding for the host downstream"; | ||||||
|  |         disableSystemdResolved = lib.mkOption { | ||||||
|  |           type = lib.types.bool; | ||||||
|  |           default = true; | ||||||
|  |           description = "Whether to automatically disable systemd-resolved when using port 53. Set to false if you want to handle the conflict manually."; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     extraDownstreams = lib.mkOption { | ||||||
|  |       type = lib.types.listOf (lib.types.submodule { | ||||||
|  |         options = { | ||||||
|  |           protocol = lib.mkOption { | ||||||
|  |             type = lib.types.enum ["udp" "tcp" "tls" "https" "quic"]; | ||||||
|  |             description = "Protocol for the downstream server."; | ||||||
|  |           }; | ||||||
|  | 
 | ||||||
|  |           listen = lib.mkOption { | ||||||
|  |             type = lib.types.str; | ||||||
|  |             description = "Address to listen on for downstream connections."; | ||||||
|  |           }; | ||||||
|  | 
 | ||||||
|  |           port = lib.mkOption { | ||||||
|  |             type = lib.types.port; | ||||||
|  |             description = "Port to listen on for downstream connections."; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }); | ||||||
|  |       default = []; | ||||||
|  |       description = "List of additional downstream DNS server configurations."; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     upstreams = { | ||||||
|  |       cloudFlare = { | ||||||
|  |         enable = lib.mkEnableOption "Cloudflare DNS over TLS upstream servers (1.1.1.1 and 1.0.0.1)"; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     extraUpstreams = lib.mkOption { | ||||||
|  |       type = lib.types.listOf (lib.types.submodule { | ||||||
|  |         options = { | ||||||
|  |           socket_addr = lib.mkOption { | ||||||
|  |             type = lib.types.str; | ||||||
|  |             description = "Socket address of the upstream DNS server (e.g., \"1.1.1.1:853\" or \"[2606:4700:4700::1111]:853\")."; | ||||||
|  |           }; | ||||||
|  | 
 | ||||||
|  |           protocol = lib.mkOption { | ||||||
|  |             type = lib.types.enum ["udp" "tcp" "tls" "https" "quic"]; | ||||||
|  |             description = "Protocol to use for upstream DNS queries."; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }); | ||||||
|  |       default = []; | ||||||
|  |       description = "List of additional upstream DNS server configurations."; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     blocklists = { | ||||||
|  |       ad_malware = { | ||||||
|  |         enable = lib.mkEnableOption "Host file for blocking ads and malware"; | ||||||
|  |         url = lib.mkOption { | ||||||
|  |           type = lib.types.str; | ||||||
|  |           default = "http://sbc.io/hosts/hosts"; | ||||||
|  |           description = "URL of the ad and malware blocklist host file"; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     extraBlocklists = lib.mkOption { | ||||||
|  |       type = lib.types.listOf lib.types.str; | ||||||
|  |       default = []; | ||||||
|  |       description = "Additional blocklist URLs to be added to the configuration"; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf cfg.enable { | ||||||
|  |     # Assertions for proper configuration | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = !(cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && config.services.resolved.enable && cfg.downstreams.host.disableSystemdResolved); | ||||||
|  |         message = "crab-hole host downstream cannot use port 53 while systemd-resolved is enabled. Either disable systemd-resolved or use a different port."; | ||||||
|  |       } | ||||||
|  |       { | ||||||
|  |         assertion = !(cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && !cfg.downstreams.host.disableSystemdResolved && config.services.resolved.enable); | ||||||
|  |         message = "crab-hole host downstream is configured to use port 53 but systemd-resolved is still enabled and disableSystemdResolved is false. Set disableSystemdResolved = true or manually disable systemd-resolved."; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     # Automatically disable systemd-resolved if using port 53 | ||||||
|  |     services.resolved.enable = lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && cfg.downstreams.host.disableSystemdResolved) (lib.mkForce false); | ||||||
|  | 
 | ||||||
|  |     # Configure DNS nameservers when disabling systemd-resolved | ||||||
|  |     networking.nameservers = lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.port == 53 && cfg.downstreams.host.disableSystemdResolved) (lib.mkDefault ["127.0.0.1" "1.1.1.1" "8.8.8.8"]); | ||||||
|  | 
 | ||||||
|  |     services.crab-hole.settings = lib.mkMerge [ | ||||||
|  |       { | ||||||
|  |         api = { | ||||||
|  |           port = cfg.port; | ||||||
|  |           listen = cfg.listen; | ||||||
|  |           show_doc = cfg.show_doc; | ||||||
|  |         }; | ||||||
|  |         downstream = cfg.extraDownstreams; | ||||||
|  |         upstream.name_servers = cfg.extraUpstreams; | ||||||
|  |         blocklist.lists = cfg.extraBlocklists; | ||||||
|  |       } | ||||||
|  |       (lib.mkIf cfg.blocklists.ad_malware.enable { | ||||||
|  |         blocklist.lists = [cfg.blocklists.ad_malware.url]; | ||||||
|  |       }) | ||||||
|  |       (lib.mkIf cfg.downstreams.host.enable { | ||||||
|  |         downstream = [ | ||||||
|  |           { | ||||||
|  |             protocol = "udp"; | ||||||
|  |             listen = "0.0.0.0"; | ||||||
|  |             port = cfg.downstreams.host.port; | ||||||
|  |           } | ||||||
|  |         ]; | ||||||
|  |       }) | ||||||
|  |       (lib.mkIf cfg.upstreams.cloudFlare.enable { | ||||||
|  |         upstream.name_servers = [ | ||||||
|  |           { | ||||||
|  |             socket_addr = "1.1.1.1:853"; | ||||||
|  |             protocol = "tls"; | ||||||
|  |             tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com"; | ||||||
|  |             trust_nx_responses = false; | ||||||
|  |           } | ||||||
|  |           { | ||||||
|  |             socket_addr = "1.0.0.1:853"; | ||||||
|  |             protocol = "tls"; | ||||||
|  |             tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com"; | ||||||
|  |             trust_nx_responses = false; | ||||||
|  |           } | ||||||
|  |           { | ||||||
|  |             socket_addr = "[2606:4700:4700::1111]:853"; | ||||||
|  |             protocol = "tls"; | ||||||
|  |             tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com"; | ||||||
|  |             trust_nx_responses = false; | ||||||
|  |           } | ||||||
|  |           { | ||||||
|  |             socket_addr = "[2606:4700:4700::1001]:853"; | ||||||
|  |             protocol = "tls"; | ||||||
|  |             tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com"; | ||||||
|  |             trust_nx_responses = false; | ||||||
|  |           } | ||||||
|  |         ]; | ||||||
|  |       }) | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     # Open firewall if requested | ||||||
|  |     networking.firewall = lib.mkMerge [ | ||||||
|  |       (lib.mkIf cfg.openFirewall { | ||||||
|  |         allowedTCPPorts = [cfg.port]; | ||||||
|  |       }) | ||||||
|  |       (lib.mkIf (cfg.downstreams.host.enable && cfg.downstreams.host.openFirewall) { | ||||||
|  |         allowedUDPPorts = [cfg.downstreams.host.port]; | ||||||
|  |       }) | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								modules/nixos-modules/server/crab-hole/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/nixos-modules/server/crab-hole/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | {...}: { | ||||||
|  |   imports = [ | ||||||
|  |     ./crab-hole.nix | ||||||
|  |     ./impermanence.nix | ||||||
|  |   ]; | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								modules/nixos-modules/server/crab-hole/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								modules/nixos-modules/server/crab-hole/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   workingDirectory = "/var/lib/private/crab-hole"; | ||||||
|  | in { | ||||||
|  |   options.services.crab-hole = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.crab-hole.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.crab-hole.impermanence.enable { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = | ||||||
|  |           config.systemd.services.crab-hole.serviceConfig.WorkingDirectory == (builtins.replaceStrings ["/private"] [""] workingDirectory); | ||||||
|  |         message = "crab-hole working directory does not match persistence"; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  |     environment.persistence."/persist/system/root" = { | ||||||
|  |       directories = [ | ||||||
|  |         { | ||||||
|  |           directory = workingDirectory; | ||||||
|  |           user = "crab-hole"; | ||||||
|  |           group = "crab-hole"; | ||||||
|  |         } | ||||||
|  |       ]; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -1,20 +1,23 @@ | ||||||
| {...}: { | {...}: { | ||||||
|   imports = [ |   imports = [ | ||||||
|     ./reverse_proxy.nix |     ./reverseProxy | ||||||
|     ./fail2ban.nix |     ./fail2ban | ||||||
|     ./postgres.nix |     ./postgres | ||||||
|     ./network_storage |     ./network_storage | ||||||
|     ./podman.nix |  | ||||||
| 
 | 
 | ||||||
|     ./actual |     ./actual | ||||||
|     ./bazarr |     ./bazarr | ||||||
|  |     ./crab-hole | ||||||
|  |     ./flaresolverr | ||||||
|     ./forgejo |     ./forgejo | ||||||
|     ./home-assistant |     ./home-assistant | ||||||
|     ./immich |     ./immich | ||||||
|  |     ./jackett | ||||||
|     ./jellyfin |     ./jellyfin | ||||||
|  |     ./lidarr | ||||||
|     ./panoramax |     ./panoramax | ||||||
|     ./paperless |     ./paperless | ||||||
|     ./qbittorent.nix |     ./qbittorent | ||||||
|     ./radarr |     ./radarr | ||||||
|     ./searx |     ./searx | ||||||
|     ./sonarr |     ./sonarr | ||||||
|  |  | ||||||
|  | @ -1,74 +0,0 @@ | ||||||
| { |  | ||||||
|   lib, |  | ||||||
|   pkgs, |  | ||||||
|   config, |  | ||||||
|   ... |  | ||||||
| }: let |  | ||||||
|   dataFolder = "/var/lib/fail2ban"; |  | ||||||
|   dataFile = "fail2ban.sqlite3"; |  | ||||||
| in { |  | ||||||
|   config = lib.mkIf config.services.fail2ban.enable (lib.mkMerge [ |  | ||||||
|     { |  | ||||||
|       environment.etc = { |  | ||||||
|         "fail2ban/filter.d/nginx.local".text = lib.mkIf config.services.nginx.enable ( |  | ||||||
|           pkgs.lib.mkDefault (pkgs.lib.mkAfter '' |  | ||||||
|             [Definition] |  | ||||||
|             failregex = "limiting requests, excess:.* by zone.*client: <HOST>" |  | ||||||
|           '') |  | ||||||
|         ); |  | ||||||
|       }; |  | ||||||
| 
 |  | ||||||
|       services.fail2ban = { |  | ||||||
|         maxretry = 5; |  | ||||||
|         ignoreIP = [ |  | ||||||
|           # Whitelist local networks |  | ||||||
|           "10.0.0.0/8" |  | ||||||
|           "172.16.0.0/12" |  | ||||||
|           "192.168.0.0/16" |  | ||||||
| 
 |  | ||||||
|           # tail scale tailnet |  | ||||||
|           "100.64.0.0/10" |  | ||||||
|           "fd7a:115c:a1e0::/48" |  | ||||||
|         ]; |  | ||||||
|         bantime = "24h"; # Ban IPs for one day on the first ban |  | ||||||
|         bantime-increment = { |  | ||||||
|           enable = true; # Enable increment of bantime after each violation |  | ||||||
|           formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)"; |  | ||||||
|           maxtime = "168h"; # Do not ban for more than 1 week |  | ||||||
|           overalljails = true; # Calculate the ban time based on all the violations |  | ||||||
|         }; |  | ||||||
|         jails = { |  | ||||||
|           nginx-iptables.settings = lib.mkIf config.services.nginx.enable { |  | ||||||
|             enabled = true; |  | ||||||
|             filter = "nginx"; |  | ||||||
|             action = ''iptables-multiport[name=HTTP, port="http,https"]''; |  | ||||||
|             backend = "auto"; |  | ||||||
|             findtime = 600; |  | ||||||
|             bantime = 600; |  | ||||||
|             maxretry = 5; |  | ||||||
|           }; |  | ||||||
|           # TODO; figure out if there is any fail2ban things we can do on searx |  | ||||||
|           # searx-iptables.settings = lib.mkIf config.services.searx.enable {}; |  | ||||||
|         }; |  | ||||||
|       }; |  | ||||||
|     } |  | ||||||
|     (lib.mkIf config.host.impermanence.enable { |  | ||||||
|       assertions = [ |  | ||||||
|         { |  | ||||||
|           assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}"; |  | ||||||
|           message = "fail2ban data file does not match persistence"; |  | ||||||
|         } |  | ||||||
|       ]; |  | ||||||
| 
 |  | ||||||
|       environment.persistence."/persist/system/root" = { |  | ||||||
|         directories = [ |  | ||||||
|           { |  | ||||||
|             directory = dataFolder; |  | ||||||
|             user = "fail2ban"; |  | ||||||
|             group = "fail2ban"; |  | ||||||
|           } |  | ||||||
|         ]; |  | ||||||
|       }; |  | ||||||
|     }) |  | ||||||
|   ]); |  | ||||||
| } |  | ||||||
							
								
								
									
										6
									
								
								modules/nixos-modules/server/fail2ban/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/nixos-modules/server/fail2ban/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | {...}: { | ||||||
|  |   imports = [ | ||||||
|  |     ./fail2ban.nix | ||||||
|  |     ./impermanence.nix | ||||||
|  |   ]; | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								modules/nixos-modules/server/fail2ban/fail2ban.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								modules/nixos-modules/server/fail2ban/fail2ban.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|  |   config = lib.mkIf config.services.fail2ban.enable { | ||||||
|  |     environment.etc = { | ||||||
|  |       "fail2ban/filter.d/nginx.local".text = lib.mkIf config.services.nginx.enable ( | ||||||
|  |         pkgs.lib.mkDefault (pkgs.lib.mkAfter '' | ||||||
|  |           [Definition] | ||||||
|  |           failregex = "limiting requests, excess:.* by zone.*client: <HOST>" | ||||||
|  |         '') | ||||||
|  |       ); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     services.fail2ban = { | ||||||
|  |       maxretry = 5; | ||||||
|  |       ignoreIP = [ | ||||||
|  |         # Whitelist local networks | ||||||
|  |         "10.0.0.0/8" | ||||||
|  |         "172.16.0.0/12" | ||||||
|  |         "192.168.0.0/16" | ||||||
|  | 
 | ||||||
|  |         # tail scale tailnet | ||||||
|  |         "100.64.0.0/10" | ||||||
|  |         "fd7a:115c:a1e0::/48" | ||||||
|  |       ]; | ||||||
|  |       bantime = "24h"; # Ban IPs for one day on the first ban | ||||||
|  |       bantime-increment = { | ||||||
|  |         enable = true; # Enable increment of bantime after each violation | ||||||
|  |         formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)"; | ||||||
|  |         maxtime = "168h"; # Do not ban for more than 1 week | ||||||
|  |         overalljails = true; # Calculate the ban time based on all the violations | ||||||
|  |       }; | ||||||
|  |       jails = { | ||||||
|  |         nginx-iptables.settings = lib.mkIf config.services.nginx.enable { | ||||||
|  |           enabled = true; | ||||||
|  |           filter = "nginx"; | ||||||
|  |           action = ''iptables-multiport[name=HTTP, port="http,https"]''; | ||||||
|  |           backend = "auto"; | ||||||
|  |           findtime = 600; | ||||||
|  |           bantime = 600; | ||||||
|  |           maxretry = 5; | ||||||
|  |         }; | ||||||
|  |         # TODO; figure out if there is any fail2ban things we can do on searx | ||||||
|  |         # searx-iptables.settings = lib.mkIf config.services.searx.enable {}; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								modules/nixos-modules/server/fail2ban/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								modules/nixos-modules/server/fail2ban/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   dataFolder = "/var/lib/fail2ban"; | ||||||
|  |   dataFile = "fail2ban.sqlite3"; | ||||||
|  | in { | ||||||
|  |   options.services.fail2ban = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.fail2ban.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.fail2ban.impermanence.enable { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}"; | ||||||
|  |         message = "fail2ban data file does not match persistence"; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     environment.persistence."/persist/system/root" = { | ||||||
|  |       directories = [ | ||||||
|  |         { | ||||||
|  |           directory = dataFolder; | ||||||
|  |           user = "fail2ban"; | ||||||
|  |           group = "fail2ban"; | ||||||
|  |         } | ||||||
|  |       ]; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								modules/nixos-modules/server/flaresolverr/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								modules/nixos-modules/server/flaresolverr/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | {...}: { | ||||||
|  |   imports = [ | ||||||
|  |     ./impermanence.nix | ||||||
|  |   ]; | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								modules/nixos-modules/server/flaresolverr/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								modules/nixos-modules/server/flaresolverr/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: { | ||||||
|  |   options.services.flaresolverr = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.flaresolverr.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.flaresolverr.impermanence.enable { | ||||||
|  |     # FlareSolverr typically doesn't need persistent storage as it's a proxy service | ||||||
|  |     # but we'll add basic structure in case it's needed for logs or configuration | ||||||
|  |     environment.persistence."/persist/system/root" = { | ||||||
|  |       directories = [ | ||||||
|  |         { | ||||||
|  |           directory = "/var/lib/flaresolverr"; | ||||||
|  |           user = "flaresolverr"; | ||||||
|  |           group = "flaresolverr"; | ||||||
|  |         } | ||||||
|  |       ]; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -2,40 +2,31 @@ | ||||||
|   lib, |   lib, | ||||||
|   config, |   config, | ||||||
|   ... |   ... | ||||||
| }: { | }: let | ||||||
|   config = lib.mkIf config.services.forgejo.enable ( |   usingPostgres = config.services.forgejo.database.type == "postgres"; | ||||||
|     lib.mkMerge [ | in { | ||||||
|       { |   config = lib.mkIf config.services.forgejo.enable { | ||||||
|         host = { |  | ||||||
|           postgres = { |  | ||||||
|             enable = true; |  | ||||||
|           }; |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|     assertions = [ |     assertions = [ | ||||||
|       { |       { | ||||||
|             assertion = config.services.forgejo.settings.database.DB_TYPE == "postgres"; |         assertion = !usingPostgres || config.services.postgresql.enable; | ||||||
|             message = "Forgejo database type must be postgres"; |         message = "PostgreSQL must be enabled when Forgejo database type is postgres"; | ||||||
|  |       } | ||||||
|  |       { | ||||||
|  |         assertion = !(usingPostgres && config.services.forgejo.database.createDatabase) || (builtins.any (db: db == "forgejo") config.services.postgresql.ensureDatabases); | ||||||
|  |         message = "Forgejo built-in database creation failed - expected 'forgejo' in ensureDatabases but got: ${builtins.toString config.services.postgresql.ensureDatabases}"; | ||||||
|  |       } | ||||||
|  |       { | ||||||
|  |         assertion = !(usingPostgres && config.services.forgejo.database.createDatabase) || (builtins.any (user: user.name == "forgejo") config.services.postgresql.ensureUsers); | ||||||
|  |         message = "Forgejo built-in user creation failed - expected user 'forgejo' in ensureUsers but got: ${builtins.toString (builtins.map (u: u.name) config.services.postgresql.ensureUsers)}"; | ||||||
|       } |       } | ||||||
|     ]; |     ]; | ||||||
|       } | 
 | ||||||
|       (lib.mkIf config.host.postgres.enable { |     services.forgejo.database.createDatabase = lib.mkDefault usingPostgres; | ||||||
|         host = { | 
 | ||||||
|           postgres = { |     systemd.services.forgejo = lib.mkIf usingPostgres { | ||||||
|             extraUsers = { |       requires = [ | ||||||
|               forgejo = { |         config.systemd.services.postgresql.name | ||||||
|                 isClient = true; |       ]; | ||||||
|                 createUser = true; |     }; | ||||||
|               }; |   }; | ||||||
|             }; |  | ||||||
|             extraDatabases = { |  | ||||||
|               forgejo = { |  | ||||||
|                 name = "forgejo"; |  | ||||||
|               }; |  | ||||||
|             }; |  | ||||||
|           }; |  | ||||||
|         }; |  | ||||||
|       }) |  | ||||||
|     ] |  | ||||||
|   ); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,53 +1,9 @@ | ||||||
| { | { | ||||||
|   lib, |  | ||||||
|   config, |  | ||||||
|   ... |  | ||||||
| }: let |  | ||||||
|   const = import ./const.nix; |  | ||||||
|   httpPort = const.httpPort; |  | ||||||
|   sshPort = const.sshPort; |  | ||||||
|   db_user = "forgejo"; |  | ||||||
| in { |  | ||||||
|   imports = [ |   imports = [ | ||||||
|  |     ./forgejo.nix | ||||||
|     ./proxy.nix |     ./proxy.nix | ||||||
|     ./database.nix |     ./database.nix | ||||||
|     ./fail2ban.nix |     ./fail2ban.nix | ||||||
|     ./impermanence.nix |     ./impermanence.nix | ||||||
|   ]; |   ]; | ||||||
| 
 |  | ||||||
|   config = lib.mkIf config.services.forgejo.enable { |  | ||||||
|     assertions = [ |  | ||||||
|       { |  | ||||||
|         assertion = config.services.forgejo.settings.server.BUILTIN_SSH_SERVER_USER == config.users.users.git.name; |  | ||||||
|         message = "Forgejo BUILTIN_SSH_SERVER_USER hardcoded value does not match expected git user name"; |  | ||||||
|       } |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     services.forgejo = { |  | ||||||
|       database = { |  | ||||||
|         type = "postgres"; |  | ||||||
|         socket = "/run/postgresql"; |  | ||||||
|       }; |  | ||||||
|       lfs.enable = true; |  | ||||||
|       settings = { |  | ||||||
|         server = { |  | ||||||
|           DOMAIN = "${config.services.forgejo.subdomain}.${config.host.reverse_proxy.hostname}"; |  | ||||||
|           HTTP_PORT = httpPort; |  | ||||||
|           START_SSH_SERVER = true; |  | ||||||
|           SSH_LISTEN_PORT = sshPort; |  | ||||||
|           SSH_PORT = 22; |  | ||||||
|           BUILTIN_SSH_SERVER_USER = "git"; |  | ||||||
|           ROOT_URL = "https://git.jan-leila.com"; |  | ||||||
|         }; |  | ||||||
|         service = { |  | ||||||
|           DISABLE_REGISTRATION = true; |  | ||||||
|         }; |  | ||||||
|         database = { |  | ||||||
|           DB_TYPE = "postgres"; |  | ||||||
|           NAME = db_user; |  | ||||||
|           USER = db_user; |  | ||||||
|         }; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,16 @@ | ||||||
|   pkgs, |   pkgs, | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   config = lib.mkIf (config.services.forgejo.enable && config.services.fail2ban.enable) { |   options.services.forgejo = { | ||||||
|  |     fail2ban = { | ||||||
|  |       enable = lib.mkOption { | ||||||
|  |         type = lib.types.bool; | ||||||
|  |         default = config.services.forgejo.enable && config.services.fail2ban.enable; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.forgejo.fail2ban.enable { | ||||||
|     environment.etc = { |     environment.etc = { | ||||||
|       "fail2ban/filter.d/forgejo.local".text = lib.mkIf config.services.forgejo.enable ( |       "fail2ban/filter.d/forgejo.local".text = lib.mkIf config.services.forgejo.enable ( | ||||||
|         pkgs.lib.mkDefault (pkgs.lib.mkAfter '' |         pkgs.lib.mkDefault (pkgs.lib.mkAfter '' | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								modules/nixos-modules/server/forgejo/forgejo.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								modules/nixos-modules/server/forgejo/forgejo.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   config, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   const = import ./const.nix; | ||||||
|  |   httpPort = const.httpPort; | ||||||
|  |   sshPort = const.sshPort; | ||||||
|  |   db_user = "forgejo"; | ||||||
|  | in { | ||||||
|  |   config = lib.mkIf config.services.forgejo.enable { | ||||||
|  |     assertions = [ | ||||||
|  |       { | ||||||
|  |         assertion = config.services.forgejo.settings.server.BUILTIN_SSH_SERVER_USER == config.users.users.git.name; | ||||||
|  |         message = "Forgejo BUILTIN_SSH_SERVER_USER hardcoded value does not match expected git user name"; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     services.forgejo = { | ||||||
|  |       database = { | ||||||
|  |         type = "postgres"; | ||||||
|  |         socket = "/run/postgresql"; | ||||||
|  |       }; | ||||||
|  |       lfs.enable = true; | ||||||
|  |       settings = { | ||||||
|  |         server = { | ||||||
|  |           DOMAIN = config.services.forgejo.reverseProxy.domain; | ||||||
|  |           HTTP_PORT = httpPort; | ||||||
|  |           START_SSH_SERVER = true; | ||||||
|  |           SSH_LISTEN_PORT = sshPort; | ||||||
|  |           SSH_PORT = 22; | ||||||
|  |           BUILTIN_SSH_SERVER_USER = "git"; | ||||||
|  |           ROOT_URL = "https://git.jan-leila.com"; | ||||||
|  |         }; | ||||||
|  |         service = { | ||||||
|  |           DISABLE_REGISTRATION = true; | ||||||
|  |         }; | ||||||
|  |         database = { | ||||||
|  |           DB_TYPE = "postgres"; | ||||||
|  |           NAME = db_user; | ||||||
|  |           USER = db_user; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -5,7 +5,14 @@ | ||||||
| }: let | }: let | ||||||
|   stateDir = "/var/lib/forgejo"; |   stateDir = "/var/lib/forgejo"; | ||||||
| in { | in { | ||||||
|   config = lib.mkIf (config.services.forgejo.enable && config.host.impermanence.enable) { |   options.services.forgejo = { | ||||||
|  |     impermanence.enable = lib.mkOption { | ||||||
|  |       type = lib.types.bool; | ||||||
|  |       default = config.services.forgejo.enable && config.host.impermanence.enable; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = lib.mkIf config.services.forgejo.impermanence.enable { | ||||||
|     assertions = [ |     assertions = [ | ||||||
|       { |       { | ||||||
|         assertion = config.services.forgejo.stateDir == stateDir; |         assertion = config.services.forgejo.stateDir == stateDir; | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue