196 lines
7.9 KiB
Nix
196 lines
7.9 KiB
Nix
# Common.nix
|
|
{ config, pkgs, lib, inputs, ... }:
|
|
|
|
let
|
|
isMacbook = config.networking.hostName == "FredOS-Macbook";
|
|
|
|
# nom's Haskell renderer measured 91% CPU during a rebuild — a full core of
|
|
# the Macbook's four, spent drawing a progress tree, while nix itself wanted
|
|
# 146%. Plain `-L` output there; the other hosts can afford the pretty one.
|
|
buildLog = lib.optionalString (!isMacbook)
|
|
" --log-format internal-json 2>&1 | nom --json";
|
|
|
|
flake = "git+https://forg.gregersen.it/rope/nixos";
|
|
|
|
post = "nvd diff $OLD_SYSTEM /run/current-system && (command -v record-update &>/dev/null && record-update $OLD_SYSTEM /run/current-system || true)";
|
|
|
|
# The server evaluates and builds for itself.
|
|
localUpdate = "bash -c 'set -o pipefail && OLD_SYSTEM=$(readlink /run/current-system) && sudo nixos-rebuild switch $@ --refresh --flake ${flake} -L${buildLog} && ${post}' --";
|
|
|
|
# The clients offload the *evaluation* too, not just the build. nixos-rebuild
|
|
# always evaluates on the machine it runs on (--build-host ships the
|
|
# derivation, not the expression), so the only way to move eval off a client
|
|
# is to run nix on the server over SSH and hand the resulting closure to
|
|
# --store-path, which skips eval and build entirely. Same lantian substituter
|
|
# as services/prebuild.nix, and --out-link keeps a gc root on the server so
|
|
# `clean` there can't reap the closure mid-copy. SSH and the copy run as
|
|
# fred, not root: root has no key on the server, and require-sigs = false
|
|
# below is a daemon setting, so the daemon takes the unsigned closure from an
|
|
# untrusted user just fine. Only the activation needs sudo.
|
|
remoteUpdate = "bash -c 'set -o pipefail && OLD_SYSTEM=$(readlink /run/current-system) && NEW=$(ssh fred@nordhammer.it \"nix build --refresh --print-out-paths --out-link prebuild-${config.networking.hostName} --option extra-substituters https://attic.xuyh0120.win/lantian --option extra-trusted-public-keys lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc= ${flake}#nixosConfigurations.${config.networking.hostName}.config.system.build.toplevel\") && nix copy --from ssh://fred@nordhammer.it $NEW && sudo nixos-rebuild switch --no-reexec --store-path $NEW && ${post}'";
|
|
in
|
|
{
|
|
imports = [
|
|
# Host modules are imported per-host by mkHost in flake.nix.
|
|
|
|
# Generic settings #
|
|
./settings/desktop.nix
|
|
./settings/hyprland.nix
|
|
./settings/quickshell.nix
|
|
./settings/locale.nix
|
|
./settings/audio.nix
|
|
./settings/users.nix
|
|
./settings/shell.nix
|
|
./apps/zen.nix
|
|
|
|
# Services #
|
|
./services/server-permissions.nix
|
|
./services/game-servers.nix
|
|
./services/pelican.nix
|
|
# ./services/dr-server.nix
|
|
./services/qbittorrent-nox.nix
|
|
./services/nginx.nix
|
|
./services/go2rtc.nix
|
|
# ./services/frigate.nix
|
|
./services/sonarr.nix
|
|
./services/radarr.nix
|
|
./services/prowlarr.nix
|
|
./services/jellyfin.nix
|
|
./services/seerr.nix
|
|
./services/bazarr.nix
|
|
./services/bazarr-sync.nix
|
|
./services/cloudflare-ddns.nix
|
|
./services/authelia.nix
|
|
./services/homepage.nix
|
|
./services/arr-interconnect.nix
|
|
./services/profilarr.nix
|
|
./services/shelfarr.nix
|
|
./services/adguard.nix
|
|
./services/router.nix
|
|
./services/crowdsec.nix
|
|
./services/service-health.nix
|
|
./services/sabnzbd.nix
|
|
./services/forgejo-runner.nix
|
|
./services/code-server.nix
|
|
./services/memos.nix
|
|
./services/hardware-health.nix
|
|
./services/wan-watchdog.nix
|
|
./services/prebuild.nix
|
|
];
|
|
|
|
### Make build time quicker
|
|
documentation.nixos.enable = false;
|
|
|
|
# Home Manager #
|
|
home-manager.useGlobalPkgs = true;
|
|
home-manager.useUserPackages = true;
|
|
home-manager.backupFileExtension = "hm-bak";
|
|
home-manager.extraSpecialArgs = { inherit inputs; };
|
|
home-manager.users.fred = import ./home-manager/fred.nix;
|
|
|
|
#############################################################################
|
|
# Kill all user processes on logout so systemd user services don't linger
|
|
# in broken states across sessions (e.g. waybar failing to start on re-login).
|
|
services.logind.settings.Login.KillUserProcesses = true;
|
|
|
|
# Shorten shutdown stop timeout to avoid long "stop job" waits
|
|
systemd.settings.Manager.DefaultTimeoutStopSec = "10s";
|
|
|
|
# Make boot time quicker
|
|
boot.loader.timeout = lib.mkDefault 5;
|
|
systemd.services.NetworkManager-wait-online.enable = false;
|
|
systemd.services.systemd-udev-settle.enable = false;
|
|
systemd.services.firewall = {
|
|
wantedBy = lib.mkForce [ ];
|
|
after = [ "multi-user.target" ];
|
|
};
|
|
|
|
boot.initrd.verbose = false;
|
|
#############################################################################
|
|
|
|
# Compressed in-memory swap as a safety net during local build storms.
|
|
# Cheap when idle; without it a transient OOM during an uncached build
|
|
# can stall AdGuard/Jellyfin to the point of freezing the box.
|
|
zramSwap = {
|
|
enable = true;
|
|
memoryPercent = 50;
|
|
};
|
|
|
|
# Use latest kernel
|
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
|
|
|
# Allow unfree packages
|
|
nixpkgs.config.allowUnfree = true;
|
|
|
|
# vesktop (multiple hosts) builds with pnpm via fetchPnpmDeps, which nixpkgs
|
|
# marks insecure (build-time only, hash-pinned FOD — not in PATH). broadcom-sta
|
|
# is Macbook-only Wi-Fi but allowing it everywhere is harmless (absent on others).
|
|
nixpkgs.config.allowInsecurePredicate = pkg:
|
|
lib.any (p: lib.hasPrefix p (lib.getName pkg)) [ "broadcom-sta" "pnpm" ];
|
|
|
|
# Flakes — nixos-rebuild self-enables these, but plain `nix eval` /
|
|
# `nix flake check` on the hosts need them too.
|
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
|
|
|
# Enable network-manager
|
|
networking.networkmanager.enable = true;
|
|
|
|
# Fish shell
|
|
programs.fish.enable = true;
|
|
users.defaultUserShell = pkgs.fish;
|
|
|
|
# Shell aliases (work in both bash and fish)
|
|
environment.shellAliases = {
|
|
update =
|
|
if config.networking.hostName == "FredOS-Mediaserver"
|
|
then localUpdate
|
|
else remoteUpdate;
|
|
clean = "sudo nix-collect-garbage -d";
|
|
# Throw away the VM's disk first so every run is a real first boot —
|
|
# greeter, Plasma first-run, the lot. Builds into ./result in $PWD.
|
|
kaylavm = "rm -f FredOS-Kayla.qcow2 && nixos-rebuild build-vm --refresh --flake git+https://forg.gregersen.it/rope/nixos#kayla-vm && ./result/bin/run-FredOS-Kayla-vm";
|
|
ll = "ls -alh";
|
|
clear = "command clear";
|
|
reboot = "bash -c 'if [ \"$(hostname)\" = \"FredOS-Mediaserver\" ]; then read -r -p \"Reboot $(hostname)? [y/N] \" confirm; case \"$confirm\" in [Yy]) ;; *) exit 0 ;; esac; fi; sudo systemctl reboot'";
|
|
};
|
|
|
|
# Add packages
|
|
environment.systemPackages = with pkgs; [
|
|
git
|
|
localsend
|
|
nvd
|
|
nix-output-monitor
|
|
jq
|
|
dnsutils
|
|
busybox
|
|
];
|
|
|
|
# Hard-link identical files in the store as new paths are added, so the
|
|
# store de-duplicates itself on every build instead of drifting.
|
|
# Off on the Macbook: it hashes and relinks every file the daemon writes,
|
|
# which lands on top of the substitution writes on a slow SATA blade —
|
|
# measured io pressure full avg60=57% during a rebuild. Run `nix store
|
|
# optimise` by hand there if the store ever gets fat.
|
|
nix.settings.auto-optimise-store = !isMacbook;
|
|
|
|
# Offload builds to the media server. Excluded on the server itself to
|
|
# avoid a pointless SSH round-trip to localhost.
|
|
nix.distributedBuilds =
|
|
lib.mkIf (config.networking.hostName != "FredOS-Mediaserver") true;
|
|
|
|
nix.buildMachines =
|
|
lib.mkIf (config.networking.hostName != "FredOS-Mediaserver") [{
|
|
hostName = "nordhammer.it";
|
|
systems = [ "x86_64-linux" "i686-linux" ];
|
|
sshUser = "fred";
|
|
sshKey = "/root/.ssh/id_ed25519";
|
|
maxJobs = 4;
|
|
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
|
}];
|
|
|
|
# Accept unsigned paths copied back from the remote builder.
|
|
nix.extraOptions =
|
|
lib.mkIf (config.networking.hostName != "FredOS-Mediaserver") ''
|
|
require-sigs = false
|
|
'';
|
|
}
|