- LUKS2 is the installer default; in exchange the generated config sets
the new nomarchy.system.greeter.autoLogin (greetd initial_session) —
the disk passphrase already gates the machine.
- @snapshots subvolume + nomarchy.system.snapper.enable: hourly/daily
timeline snapshots of / and the nixos-rebuild-snap helper, ported from
the previous iteration (3bdfc35), guarded to no-op on non-BTRFS roots.
- @swap subvolume with a swapfile sized to RAM by default (disko
mkswapfile handles NOCOW); the installer computes the resume offset
and wires boot.resumeDevice + resume_offset for hibernation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
140 lines
5.3 KiB
Nix
140 lines
5.3 KiB
Nix
# Nomarchy — reusable system layer (NixOS 26.05).
|
|
#
|
|
# This module is the distro: import it from any host (see
|
|
# nixosModules.nomarchy in flake.nix) and layer your machine specifics
|
|
# (bootloader, hostname, users, hardware) on top. Host concerns are
|
|
# deliberately NOT set here. Everything user-facing (Hyprland config,
|
|
# Waybar, Ghostty, theming) lives in modules/home.
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.nomarchy.system;
|
|
in
|
|
{
|
|
imports = [ ./options.nix ];
|
|
|
|
config = {
|
|
# ── Wayland session: Hyprland ────────────────────────────────────
|
|
# Installs the binary, registers the session, wires up
|
|
# xdg-desktop-portal-hyprland. Configuration is Home Manager's job.
|
|
programs.hyprland.enable = lib.mkDefault true;
|
|
|
|
xdg.portal = {
|
|
enable = lib.mkDefault true;
|
|
extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; # file pickers, etc.
|
|
};
|
|
|
|
services.greetd = lib.mkIf cfg.greeter.enable {
|
|
enable = lib.mkDefault true;
|
|
settings = {
|
|
default_session = {
|
|
command = lib.mkDefault "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd Hyprland";
|
|
user = "greeter";
|
|
};
|
|
# Boot straight into the session once; logout → normal greeter.
|
|
initial_session = lib.mkIf (cfg.greeter.autoLogin != null) {
|
|
command = "Hyprland";
|
|
user = cfg.greeter.autoLogin;
|
|
};
|
|
};
|
|
};
|
|
|
|
# ── Audio: Pipewire ──────────────────────────────────────────────
|
|
security.rtkit.enable = lib.mkDefault cfg.audio.enable;
|
|
services.pulseaudio.enable = lib.mkDefault false;
|
|
services.pipewire = lib.mkIf cfg.audio.enable {
|
|
enable = lib.mkDefault true;
|
|
alsa.enable = true;
|
|
alsa.support32Bit = true;
|
|
pulse.enable = true;
|
|
wireplumber.enable = true;
|
|
};
|
|
|
|
# ── Desktop services ─────────────────────────────────────────────
|
|
security.polkit.enable = lib.mkDefault true;
|
|
services.gnome.gnome-keyring.enable = lib.mkDefault true;
|
|
services.dbus.enable = lib.mkDefault true;
|
|
services.upower.enable = lib.mkDefault true;
|
|
networking.networkmanager.enable = lib.mkDefault true;
|
|
|
|
hardware.bluetooth.enable = lib.mkDefault cfg.bluetooth.enable;
|
|
services.blueman.enable = lib.mkDefault cfg.bluetooth.enable;
|
|
|
|
# ── BTRFS timeline snapshots (ported from the previous iteration) ─
|
|
# Guarded on the actual filesystem so enabling it on an ext4 machine
|
|
# is a clean no-op rather than a failing timer.
|
|
services.snapper.configs = lib.mkIf
|
|
(cfg.snapper.enable && (config.fileSystems."/".fsType or "") == "btrfs")
|
|
{
|
|
root = {
|
|
SUBVOLUME = "/";
|
|
TIMELINE_CREATE = true;
|
|
TIMELINE_CLEANUP = true;
|
|
TIMELINE_LIMIT_HOURLY = "5";
|
|
TIMELINE_LIMIT_DAILY = "7";
|
|
TIMELINE_LIMIT_WEEKLY = "0";
|
|
TIMELINE_LIMIT_MONTHLY = "0";
|
|
TIMELINE_LIMIT_YEARLY = "0";
|
|
};
|
|
};
|
|
|
|
# ── Fonts ────────────────────────────────────────────────────────
|
|
fonts = {
|
|
packages = with pkgs; [
|
|
nerd-fonts.jetbrains-mono
|
|
inter
|
|
noto-fonts
|
|
noto-fonts-color-emoji
|
|
];
|
|
fontconfig.defaultFonts = {
|
|
monospace = lib.mkDefault [ "JetBrainsMono Nerd Font" ];
|
|
sansSerif = lib.mkDefault [ "Inter" ];
|
|
emoji = lib.mkDefault [ "Noto Color Emoji" ];
|
|
};
|
|
};
|
|
|
|
# ── Essential packages ───────────────────────────────────────────
|
|
environment.systemPackages = with pkgs; [
|
|
nomarchy-theme-sync # provided by overlays.default
|
|
git
|
|
vim
|
|
wget
|
|
curl
|
|
jq
|
|
brightnessctl
|
|
playerctl
|
|
pamixer
|
|
wl-clipboard
|
|
grim
|
|
slurp
|
|
] ++ lib.optional (cfg.snapper.enable && (config.fileSystems."/".fsType or "") == "btrfs")
|
|
# Snapshot, then rebuild — rollback material for system changes
|
|
# (theme changes don't need it; HM generations already roll back).
|
|
(pkgs.writeShellScriptBin "nixos-rebuild-snap" ''
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "This script must be run as root (use sudo)" >&2
|
|
exit 1
|
|
fi
|
|
echo "Creating pre-rebuild snapshot..."
|
|
${pkgs.snapper}/bin/snapper -c root create \
|
|
-d "Pre-rebuild $(date +'%Y-%m-%d %H:%M:%S')" \
|
|
--cleanup-algorithm number
|
|
echo "Rebuilding..."
|
|
nixos-rebuild switch --flake /etc/nixos#default "$@"
|
|
'');
|
|
|
|
# ── Nix itself ───────────────────────────────────────────────────
|
|
nix = {
|
|
settings = {
|
|
experimental-features = [ "nix-command" "flakes" ];
|
|
auto-optimise-store = lib.mkDefault true;
|
|
};
|
|
gc = {
|
|
automatic = lib.mkDefault true;
|
|
dates = lib.mkDefault "weekly";
|
|
options = lib.mkDefault "--delete-older-than 14d";
|
|
};
|
|
};
|
|
};
|
|
}
|