From 11ba75e40728e8b5735c9c7cefc7af1631c942af Mon Sep 17 00:00:00 2001 From: "Henry J. Webster" Date: Thu, 30 Jul 2026 10:38:54 -0500 Subject: Restructure into a multi-machine flake and add the enzo laptop Split the single-host config into a shared minimal base plus opt-in profiles, and add a second machine (enzo laptop) alongside kusanagi. - flake: add mkMachine helper; declare nixosConfigurations.kusanagi and .enzo; add the disko input; move overlays per-machine. - common/: minimal base only (boot, networking, tailscale, locale, nix settings, neovim editor). Old configuration.nix/programs.nix removed. - profiles/: coarse opt-in bundles (desktop, dev, apps). kusanagi imports all three and stays byte-for-byte identical to the running system. - machines/kusanagi/: all workstation-only config (ROCm, Scarlett audio, optical-disc archiving, NAS mounts, kavita/immich/ollama); hardware config moved here unchanged. User stays 'henz'. - machines/enzo/: new laptop. Declarative LUKS+btrfs via disko (LVM-on-LUKS, TPM2+PIN unlock, zram + encrypted swap for suspend-then-hibernate); its own minimal niri desktop with playback-only audio (no rtkit/jack); user 'hwebs'. Assisted-by: Claude:claude-opus-4-8 --- profiles/apps.nix | 30 +++++++++ profiles/desktop.nix | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++ profiles/dev.nix | 85 +++++++++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 profiles/apps.nix create mode 100644 profiles/desktop.nix create mode 100644 profiles/dev.nix (limited to 'profiles') diff --git a/profiles/apps.nix b/profiles/apps.nix new file mode 100644 index 0000000..279ef03 --- /dev/null +++ b/profiles/apps.nix @@ -0,0 +1,30 @@ +# Apps profile: GUI and personal applications, plus gaming. Opt-in per machine. +{ pkgs, ... }: + +{ + programs.steam.enable = true; + programs.firefox.enable = true; + + environment.systemPackages = with pkgs; [ + itch + ]; + + users.users.henz.packages = with pkgs; [ + discord + vlc + gimp + inkscape + darktable + protonmail-desktop + + # media tooling + imagemagick + ffmpeg + + flatpak + + # TUI apps + newsboat + castero + ]; +} diff --git a/profiles/desktop.nix b/profiles/desktop.nix new file mode 100644 index 0000000..b56ac68 --- /dev/null +++ b/profiles/desktop.nix @@ -0,0 +1,171 @@ +# Desktop profile: the GNOME+niri graphical shell, login manager, audio, fonts, +# graphics, printing, a terminal, and the gpg agent. Opt-in per machine. +{ pkgs, ... }: + +{ + # Enable the X11 windowing system. + services.xserver.enable = true; + + # Configure keymap in X11 + services.xserver.xkb = { + layout = "us"; + variant = ""; + }; + + # Enable the GNOME Desktop Environment. + services.displayManager.gdm.enable = false; + services.desktopManager.gnome.enable = true; + + programs.dconf.enable = true; + programs.niri.enable = true; + + # login screen + services.greetd = { + enable = true; + settings = { + default_session = { + command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd niri-session"; + user = "greeter"; + }; + }; + }; + + # This is required to let tuigreet write to its cache (for --remember) + systemd.services.greetd.serviceConfig = { + Type = "idle"; + StandardInput = "tty"; + StandardOutput = "tty"; + StandardError = "journal"; # Better for debugging + TTYReset = true; + TTYVHangup = true; + TTYVTDisallocate = true; + }; + + # prevent auto-mounting optical disks + services.udisks2.enable = true; + + # Enable CUPS to print documents. + services.printing = { + enable = true; + drivers = with pkgs; [ + gutenprint + ]; + }; + + # mDNS: printer discovery, and resolves kusanagi's *.local NAS names. + services.avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + + services.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber.enable = true; + }; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + fonts = { + enableDefaultPackages = true; + + packages = with pkgs; [ + noto-fonts-cjk-sans + noto-fonts-cjk-serif + inter + nerd-fonts.symbols-only + noto-fonts + ibm-plex + public-sans + adwaita-fonts + ]; + + fontconfig = { + enable = true; + + defaultFonts = { + monospace = [ + "Berkeley Mono" + "Liberation Mono" + "Symbols Nerd Font" + ]; + sansSerif = [ + "Liberation Sans" + "Noto Sans" + ]; + serif = [ "Liberation Serif" ]; + emoji = [ "Nerd Font Symbols Only" ]; + }; + + # Force ui-sans-serif and system-ui to resolve correctly + localConf = '' + + + + + system-ui + + Liberation Sans + + + + ui-sans-serif + + Liberation Sans + + + + ''; + }; + + fontDir.enable = true; + }; + + environment.sessionVariables = { + GSK_RENDERER = "gl"; + XCURSOR_THEME = "Bibata-Modern-Classic"; + XCURSOR_SIZE = "24"; + HYPRCURSOR_THEME = "Bibata-Modern-Classic"; + HYPRCURSOR_SIZE = "24"; + }; + + # Graphics setup + hardware.graphics = { + enable = true; + enable32Bit = true; + }; + + users.users.henz.extraGroups = [ + "audio" + "lp" + "input" + ]; + + environment.systemPackages = with pkgs; [ + # notifications (mako = wayland notification daemon, libnotify = notify-send) + mako + libnotify + ]; + + users.users.henz.packages = with pkgs; [ + ghostty # terminal — required to actually use the GUI + gnupg + pinentry-gnome3 + + # niri support tools + waybar + networkmanagerapplet + xwayland-satellite + fuzzel + swaybg + ]; +} diff --git a/profiles/dev.nix b/profiles/dev.nix new file mode 100644 index 0000000..e20fe5a --- /dev/null +++ b/profiles/dev.nix @@ -0,0 +1,85 @@ +# Dev profile: compilers, language servers, dev CLIs, and Emacs. Opt-in per machine. +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + zig + prettier + + (aspellWithDicts ( + dicts: with dicts; [ + en + en-computers + en-science + ] + )) + + pi-coding-agent + + (buildNpmPackage rec { + pname = "pi-acp"; + version = "0.0.31"; + src = fetchFromGitHub { + owner = "svkozak"; + repo = "pi-acp"; + rev = "v${version}"; + hash = "sha256-bM3V/3fxkY2Ib+OyfT82StIIRSLXGDuYUbt1CZKpTuo="; + }; + npmDepsHash = "sha256-qN+b/tMbnJLkWjotl3XrA0nfZ3KT/mT6gM+n3Qiz8Wk="; + }) + ]; + + users.users.henz.packages = with pkgs; [ + # toolchains / build + gcc + pkg-config + gnumake + autoconf + automake + libtool + cargo + nodejs + guile + direnv + gdb + + # language servers / formatters + lua-language-server + nil + clang-tools + marksman + gopls + ruff + basedpyright + zls + nixfmt + + # coding agents + opencode + claude-code + ]; + + services.emacs = { + enable = true; + package = + let + emacs = pkgs.emacs-pgtk.overrideAttrs (old: { + postInstall = (old.postInstall or "") + '' + # I only want the client version + rm -f $out/share/applications/emacs.desktop + ''; + }); + in + (pkgs.emacsPackagesFor emacs).withPackages (epkgs: [ + # NB: no g.tree-sitter-zig -- nixpkgs builds it from maxxnino/tree-sitter-zig, + # but zig-ts-mode requires the tree-sitter-grammars/tree-sitter-zig variant + # (different node names). The zig grammar is installed instead via + # `C-u M-x zig-ts-install-grammars' into ~/.config/emacs/tree-sitter/. + (epkgs.treesit-grammars.with-grammars (g: [ + g.tree-sitter-nix + g.tree-sitter-javascript + ])) + epkgs.vterm + ]); + }; +} -- cgit v1.3