stdenvNoCC + p7zip extraction; strips installer scripts and README, keeps Licenses/. dontFixup since the artifacts are Windows DLLs. meta.license is unfreeRedistributable to reflect the bundled XeSS (Intel SLA) alongside the GPL-3.0 source. Wires lib/overlays.nix into mkDesktopHost (was muffin-only) and adds "optiscaler" to the unfree allowlist on jovian hosts so yarn can consume it without flipping the global allowUnfree flag.
473 lines
17 KiB
Nix
473 lines
17 KiB
Nix
{
|
|
description = "Unified NixOS flake for mreow (laptop), yarn (desktop), muffin (server)";
|
|
|
|
inputs = {
|
|
# Two channels: unstable for desktops, 25.11 for server.
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
|
|
|
|
home-manager = {
|
|
url = "github:nix-community/home-manager";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
home-manager-stable = {
|
|
url = "github:nix-community/home-manager/release-25.11";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
|
|
# Shared across all hosts
|
|
lanzaboote = {
|
|
url = "github:nix-community/lanzaboote";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.rust-overlay.follows = "rust-overlay";
|
|
};
|
|
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
|
disko = {
|
|
url = "github:nix-community/disko/latest";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
impermanence = {
|
|
url = "github:nix-community/impermanence";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.home-manager.follows = "home-manager";
|
|
};
|
|
|
|
# Desktop (mreow + yarn)
|
|
rust-overlay = {
|
|
url = "github:oxalica/rust-overlay";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
zen-browser = {
|
|
url = "github:0xc000022070/zen-browser-flake";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.home-manager.follows = "home-manager";
|
|
};
|
|
firefox-addons = {
|
|
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
niri = {
|
|
url = "github:sodiboo/niri-flake";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.nixpkgs-stable.follows = "nixpkgs";
|
|
};
|
|
emacs-overlay = {
|
|
url = "github:nix-community/emacs-overlay";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.nixpkgs-stable.follows = "nixpkgs";
|
|
};
|
|
nix-flatpak.url = "github:gmodena/nix-flatpak/";
|
|
nix-doom-emacs-unstraightened = {
|
|
url = "github:marienz/nix-doom-emacs-unstraightened";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.emacs-overlay.follows = "emacs-overlay";
|
|
};
|
|
jovian-nixos = {
|
|
url = "github:Jovian-Experiments/Jovian-NixOS";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
noctalia = {
|
|
url = "github:noctalia-dev/noctalia-shell";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
nix-cachyos-kernel = {
|
|
url = "github:xddxdd/nix-cachyos-kernel/release";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
llm-agents = {
|
|
url = "github:numtide/llm-agents.nix";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
json2steamshortcut = {
|
|
url = "github:ChrisOboe/json2steamshortcut";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
# Google's official agent-skills for Android development (Apache 2.0).
|
|
# Consumed by home/progs/pi.nix and exposed under ~/.omp/agent/skills/.
|
|
android-skills = {
|
|
url = "github:android/skills";
|
|
flake = false;
|
|
};
|
|
|
|
# Server (muffin) — follows nixpkgs-stable
|
|
nix-minecraft = {
|
|
url = "github:Infinidoge/nix-minecraft";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
vpn-confinement.url = "github:Maroka-chan/VPN-Confinement";
|
|
llamacpp = {
|
|
url = "github:TheTom/llama-cpp-turboquant/feature/turboquant-kv-cache";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
srvos = {
|
|
url = "github:nix-community/srvos";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
deploy-rs = {
|
|
url = "github:serokell/deploy-rs";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
agenix = {
|
|
url = "github:ryantm/agenix";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
inputs.home-manager.follows = "home-manager-stable";
|
|
inputs.darwin.follows = "";
|
|
};
|
|
senior_project-website = {
|
|
url = "github:Titaniumtown/senior-project-website";
|
|
flake = false;
|
|
};
|
|
website = {
|
|
url = "git+https://git.sigkill.computer/titaniumtown/website";
|
|
flake = false;
|
|
};
|
|
trackerlist = {
|
|
url = "github:ngosang/trackerslist";
|
|
flake = false;
|
|
};
|
|
ytbn-graphing-software = {
|
|
url = "git+https://git.sigkill.computer/titaniumtown/YTBN-Graphing-Software";
|
|
};
|
|
arr-init = {
|
|
url = "git+ssh://gitea@git.gardling.com/titaniumtown/arr-init";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
nixpkgs-p2pool-module = {
|
|
url = "github:JacoMalan1/nixpkgs/create-p2pool-service";
|
|
flake = false;
|
|
};
|
|
qbittorrent-metrics-exporter = {
|
|
url = "git+https://codeberg.org/anriha/qbittorrent-metrics-exporter";
|
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
|
};
|
|
};
|
|
|
|
outputs =
|
|
inputs@{
|
|
self,
|
|
nixpkgs,
|
|
nixpkgs-stable,
|
|
home-manager,
|
|
home-manager-stable,
|
|
lanzaboote,
|
|
nixos-hardware,
|
|
disko,
|
|
impermanence,
|
|
nix-minecraft,
|
|
vpn-confinement,
|
|
srvos,
|
|
deploy-rs,
|
|
agenix,
|
|
arr-init,
|
|
nixpkgs-p2pool-module,
|
|
jovian-nixos,
|
|
...
|
|
}:
|
|
let
|
|
username = "primary";
|
|
system = "x86_64-linux";
|
|
|
|
niriPackage = inputs.niri.packages.${system}.niri-unstable;
|
|
|
|
# --- Desktop-channel pkgs (used by portable homeConfigurations) ---
|
|
desktopPkgs = import nixpkgs { inherit system; };
|
|
|
|
# --- Server (muffin) plumbing ---
|
|
bootstrapPkgs = import nixpkgs-stable { inherit system; };
|
|
patchedStableSrc = bootstrapPkgs.applyPatches {
|
|
name = "nixpkgs-stable-patched";
|
|
src = nixpkgs-stable;
|
|
patches = [
|
|
./patches/nixpkgs/0001-firefox-syncserver-add-postgresql-backend-support.patch
|
|
];
|
|
};
|
|
serverPkgs = import patchedStableSrc {
|
|
inherit system;
|
|
targetPlatform = system;
|
|
buildPlatform = builtins.currentSystem;
|
|
};
|
|
siteConfig = import ./site-config.nix;
|
|
serviceConfigs = import ./hosts/muffin/service-configs.nix { site_config = siteConfig; };
|
|
serverLib = import ./lib {
|
|
inherit inputs;
|
|
lib = nixpkgs-stable.lib;
|
|
pkgs = serverPkgs;
|
|
service_configs = serviceConfigs;
|
|
site_config = siteConfig;
|
|
};
|
|
testSuite = import ./tests/tests.nix {
|
|
pkgs = serverPkgs;
|
|
lib = serverLib;
|
|
inherit inputs;
|
|
site_config = siteConfig;
|
|
config = self.nixosConfigurations.muffin.config;
|
|
};
|
|
|
|
# --- Host builders ---
|
|
|
|
# Desktop: unstable + home-manager-unstable + niri-unstable
|
|
mkDesktopHost =
|
|
hostname:
|
|
nixpkgs.lib.nixosSystem {
|
|
specialArgs = {
|
|
inherit inputs username hostname;
|
|
niri-package = niriPackage;
|
|
site_config = siteConfig;
|
|
};
|
|
modules = [
|
|
home-manager.nixosModules.home-manager
|
|
(
|
|
{ config, ... }:
|
|
{
|
|
home-manager.useUserPackages = true;
|
|
home-manager.sharedModules = [
|
|
inputs.zen-browser.homeModules.twilight
|
|
];
|
|
home-manager.extraSpecialArgs = {
|
|
inherit
|
|
inputs
|
|
hostname
|
|
username
|
|
;
|
|
niri-package = niriPackage;
|
|
homeDirectory = "/home/${username}";
|
|
stateVersion = config.system.stateVersion;
|
|
site_config = siteConfig;
|
|
};
|
|
home-manager.users.${username} = import ./hosts/${hostname}/home.nix;
|
|
}
|
|
)
|
|
{ nixpkgs.overlays = [ (import ./lib/overlays.nix) ]; }
|
|
./hosts/${hostname}/default.nix
|
|
];
|
|
};
|
|
|
|
# Server: stable + home-manager-stable + srvos + agenix + patched pkgs
|
|
muffinHost = serverLib.nixosSystem {
|
|
inherit system;
|
|
specialArgs = {
|
|
inherit
|
|
username
|
|
inputs
|
|
;
|
|
hostname = "muffin";
|
|
eth_interface = "enp4s0";
|
|
service_configs = serviceConfigs;
|
|
site_config = siteConfig;
|
|
lib = serverLib;
|
|
};
|
|
modules = [
|
|
# SAFETY! port sanity checks
|
|
(
|
|
{ config, lib, ... }:
|
|
let
|
|
publicPorts = lib.attrValues serviceConfigs.ports.public;
|
|
privatePorts = lib.attrValues serviceConfigs.ports.private;
|
|
allPortNumbers = map (p: p.port) (publicPorts ++ privatePorts);
|
|
uniquePortNumbers = lib.unique allPortNumbers;
|
|
|
|
publicTcp = map (p: p.port) (lib.filter (p: p.proto == "tcp" || p.proto == "both") publicPorts);
|
|
publicUdp = map (p: p.port) (lib.filter (p: p.proto == "udp" || p.proto == "both") publicPorts);
|
|
privatePortNumbers = map (p: p.port) privatePorts;
|
|
|
|
fwTcp = config.networking.firewall.allowedTCPPorts;
|
|
fwUdp = config.networking.firewall.allowedUDPPorts;
|
|
|
|
missingTcp = lib.filter (p: !(builtins.elem p fwTcp)) publicTcp;
|
|
missingUdp = lib.filter (p: !(builtins.elem p fwUdp)) publicUdp;
|
|
leakedTcp = lib.filter (p: builtins.elem p fwTcp) privatePortNumbers;
|
|
leakedUdp = lib.filter (p: builtins.elem p fwUdp) privatePortNumbers;
|
|
in
|
|
{
|
|
config.assertions = [
|
|
{
|
|
assertion = (lib.length allPortNumbers) == (lib.length uniquePortNumbers);
|
|
message = "Duplicate port numbers detected in ports.public / ports.private";
|
|
}
|
|
{
|
|
assertion = missingTcp == [ ];
|
|
message = "Public ports missing from allowedTCPPorts: ${builtins.toString missingTcp}";
|
|
}
|
|
{
|
|
assertion = missingUdp == [ ];
|
|
message = "Public ports missing from allowedUDPPorts: ${builtins.toString missingUdp}";
|
|
}
|
|
{
|
|
assertion = leakedTcp == [ ] && leakedUdp == [ ];
|
|
message = "Private ports leaked into firewall allow-lists — TCP: ${builtins.toString leakedTcp}, UDP: ${builtins.toString leakedUdp}";
|
|
}
|
|
];
|
|
}
|
|
)
|
|
|
|
srvos.nixosModules.server
|
|
srvos.nixosModules.mixins-terminfo
|
|
|
|
./hosts/muffin/disk.nix
|
|
./hosts/muffin/default.nix
|
|
|
|
# Firefox-syncserver: swap upstream module + package for patched versions.
|
|
{
|
|
disabledModules = [ "services/networking/firefox-syncserver.nix" ];
|
|
imports = [
|
|
"${patchedStableSrc}/nixos/modules/services/networking/firefox-syncserver.nix"
|
|
];
|
|
nixpkgs.overlays = [
|
|
nix-minecraft.overlay
|
|
(import ./lib/overlays.nix)
|
|
(_final: prev: {
|
|
syncstorage-rs =
|
|
prev.callPackage "${patchedStableSrc}/pkgs/by-name/sy/syncstorage-rs/package.nix"
|
|
{ };
|
|
})
|
|
# NOTE: systemd patch is applied via `systemd.package` in the module
|
|
# list below, not via an overlay. An overlay replaces pkgs.systemd
|
|
# for every consumer, which cascades through udev-check-hook and
|
|
# causes the entire closure (fish, e2fsprogs, valkey, …) to rebuild
|
|
# and re-run flaky test suites in the sandbox. `systemd.package`
|
|
# only injects the patched systemd into the runtime init chain.
|
|
];
|
|
nixpkgs.config.allowUnfreePredicate =
|
|
pkg:
|
|
builtins.elem (nixpkgs-stable.lib.getName pkg) [
|
|
"minecraft-server"
|
|
];
|
|
}
|
|
|
|
# Runtime-only systemd patch: reset FreezerState on inactive/failed
|
|
# transitions so a SIGKILL to a frozen unit doesn't strand
|
|
# FreezerState=frozen (unrecoverable without a reboot, upstream issue
|
|
# #38517). PR #38528 closed only the watchdog path; this closes
|
|
# systemctl kill / OOM / segfault paths too.
|
|
#
|
|
# Applied via systemd.package, not via overlay, so pkgs.systemd stays
|
|
# untouched for every other consumer — no udev-check-hook cascade,
|
|
# no fish/e2fsprogs/valkey rebuild, no flaky-test fallout.
|
|
(
|
|
{ pkgs, ... }:
|
|
{
|
|
systemd.package = pkgs.systemd.overrideAttrs (old: {
|
|
patches = (old.patches or [ ]) ++ [
|
|
./patches/systemd/0001-core-unit-reset-freezer-state-on-inactive-failed.patch
|
|
];
|
|
});
|
|
}
|
|
)
|
|
|
|
lanzaboote.nixosModules.lanzaboote
|
|
arr-init.nixosModules.default
|
|
(import "${nixpkgs-p2pool-module}/nixos/modules/services/networking/p2pool.nix")
|
|
|
|
home-manager-stable.nixosModules.home-manager
|
|
(
|
|
{ ... }:
|
|
{
|
|
home-manager.extraSpecialArgs = {
|
|
site_config = siteConfig;
|
|
};
|
|
home-manager.users.${username} = import ./hosts/muffin/home.nix;
|
|
}
|
|
)
|
|
]
|
|
++ (with nixos-hardware.nixosModules; [
|
|
common-cpu-amd-pstate
|
|
common-cpu-amd-zenpower
|
|
common-pc-ssd
|
|
common-gpu-intel
|
|
]);
|
|
};
|
|
in
|
|
{
|
|
formatter.${system} = nixpkgs.legacyPackages.${system}.nixfmt-tree;
|
|
|
|
nixosConfigurations = {
|
|
mreow = mkDesktopHost "mreow";
|
|
yarn = mkDesktopHost "yarn";
|
|
patiodeck = mkDesktopHost "patiodeck";
|
|
muffin = muffinHost;
|
|
};
|
|
|
|
# Standalone home-manager profile — usable on any x86_64-linux machine
|
|
# with nix installed (NixOS or not). Activate with:
|
|
# nix run home-manager/master -- switch --flake ".#primary"
|
|
# Ships the shared terminal profile (fish, helix, modern CLI, git).
|
|
homeConfigurations.primary = home-manager.lib.homeManagerConfiguration {
|
|
pkgs = desktopPkgs;
|
|
extraSpecialArgs = {
|
|
site_config = siteConfig;
|
|
};
|
|
modules = [
|
|
./home/profiles/terminal.nix
|
|
{
|
|
home = {
|
|
username = username;
|
|
homeDirectory = "/home/${username}";
|
|
stateVersion = "24.11";
|
|
};
|
|
}
|
|
];
|
|
};
|
|
|
|
deploy.nodes.muffin = {
|
|
hostname = siteConfig.hosts.muffin.alias;
|
|
profiles.system = {
|
|
sshUser = "root";
|
|
user = "root";
|
|
# Deploy guard enforcement lives in the preflight driver (deploy.sh
|
|
# and .gitea/workflows/deploy.yml) — not in activation. Activation-
|
|
# time enforcement is unsafe: deploy-rs sets the new profile pointer
|
|
# before running deploy-rs-activate, so a non-zero activation exit
|
|
# triggers auto-rollback which re-runs switch-to-configuration on the
|
|
# previous generation. That re-activation rotates agenix secrets,
|
|
# reinstalls lanzaboote, and reloads systemd units — side effects we
|
|
# want to avoid when the deploy is supposed to be a no-op blocked by
|
|
# the guard. Blocking before the deploy-rs invocation is the only
|
|
# clean way to leave the running system untouched.
|
|
#
|
|
# Activation uses `switch-to-configuration boot` + a detached finalize
|
|
# (modules/server-deploy-finalize.nix) rather than the default
|
|
# `switch`. The gitea-actions runner driving CI deploys lives on
|
|
# muffin itself; a direct `switch` restarts gitea-runner-muffin mid-
|
|
# activation, killing the SSH session, the CI job, and deploy-rs's
|
|
# magic-rollback handshake. `boot` only touches the bootloader — no
|
|
# service restarts — and deploy-finalize schedules a pid1-owned
|
|
# transient unit that runs the real `switch` (or `systemctl reboot`
|
|
# when kernel/initrd/kernel-modules changed) ~60s later, surviving
|
|
# runner restart because it's decoupled from the SSH session.
|
|
path =
|
|
deploy-rs.lib.${system}.activate.custom self.nixosConfigurations.muffin.config.system.build.toplevel
|
|
''
|
|
# matches activate.nixos's workaround for NixOS/nixpkgs#73404
|
|
cd /tmp
|
|
|
|
$PROFILE/bin/switch-to-configuration boot
|
|
|
|
${nixpkgs-stable.lib.getExe self.nixosConfigurations.muffin.config.system.build.deployFinalize}
|
|
'';
|
|
};
|
|
};
|
|
|
|
checks.${system} = testSuite;
|
|
|
|
packages.${system} = {
|
|
tests = serverPkgs.linkFarm "all-tests" (
|
|
serverPkgs.lib.mapAttrsToList (name: test: {
|
|
name = name;
|
|
path = test;
|
|
}) testSuite
|
|
);
|
|
|
|
# Buildenv of every binary in the portable terminal profile. Install
|
|
# without home-manager via:
|
|
# nix profile install ".#cli-tools"
|
|
cli-tools = self.homeConfigurations.primary.config.home.path;
|
|
}
|
|
// (serverPkgs.lib.mapAttrs' (name: test: {
|
|
name = "test-${name}";
|
|
value = test;
|
|
}) testSuite);
|
|
|
|
lib = serverLib;
|
|
};
|
|
}
|