feat: simplify flake-parts imports

This commit is contained in:
Leon Schwarzäugl 2026-03-31 17:44:24 +02:00
parent 3d3e8d450d
commit ff8dd91aef
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
24 changed files with 77 additions and 79 deletions

32
flake/apps.nix Normal file
View file

@ -0,0 +1,32 @@
{ self, ... }:
{
perSystem = { system, ... }:
let
mkApps = system: names: self: builtins.listToAttrs (map
(name: {
inherit name;
value = {
type = "app";
program = "${self.packages.${system}.${name}}/bin/${name}";
meta = {
description = "Custom app ${name}.";
};
};
})
names);
appNames = [
"swarsel-bootstrap"
"swarsel-install"
"swarsel-rebuild"
"swarsel-postinstall"
];
appSet = mkApps system appNames self;
in
{
apps = appSet // {
default = appSet.swarsel-bootstrap;
};
};
}

189
flake/devshell.nix Normal file
View file

@ -0,0 +1,189 @@
{ self, inputs, ... }:
{
imports = [
inputs.devshell.flakeModule
inputs.pre-commit-hooks.flakeModule
];
perSystem = { pkgs, config, system, ... }:
{
pre-commit = {
check.enable = true;
settings = {
addGcRoot = true;
hooks = {
check-added-large-files.enable = true;
check-case-conflicts.enable = true;
check-executables-have-shebangs.enable = true;
check-shebang-scripts-are-executable.enable = false;
check-merge-conflicts.enable = true;
deadnix.enable = true;
detect-private-keys.enable = true;
end-of-file-fixer.enable = true;
fix-byte-order-marker.enable = true;
flake-checker.enable = true;
forbid-new-submodules.enable = true;
mixed-line-endings.enable = true;
nixpkgs-fmt.enable = true;
statix.enable = true;
trim-trailing-whitespace.enable = true;
treefmt.enable = true;
destroyed-symlinks = {
enable = true;
entry = "${inputs.pre-commit-hooks.checks.${system}.pre-commit-hooks}/bin/destroyed-symlinks";
};
shellcheck = {
enable = true;
entry = "${pkgs.shellcheck}/bin/shellcheck --shell=bash";
};
shfmt = {
enable = true;
entry = "${pkgs.shfmt}/bin/shfmt -i 4 -sr -d -s -l";
};
};
};
};
devshells = {
deploy =
let
nix-version = "2_28";
in
{
packages = [
(builtins.trace "alarm: pinned nix_${nix-version}" pkgs.stable25_05.nixVersions."nix_${nix-version}")
pkgs.git
pkgs.just
pkgs.age
pkgs.ssh-to-age
pkgs.sops
];
env =
[
{
name = "NIX_CONFIG";
value = ''
plugin-files = ${pkgs.stable25_05.nix-plugins.overrideAttrs (o: {
buildInputs = [pkgs.stable25_05.nixVersions."nix_${nix-version}" pkgs.stable25_05.boost];
patches = (o.patches or []) ++ [./files/patches/nix-plugins.patch];
})}/lib/nix/plugins
extra-builtins-file = ${self + /files/nix/extra-builtins.nix}
'';
}
];
};
default =
let
nix-version = "2_30";
in
{
packages = [
(builtins.trace "alarm: pinned nix_${nix-version}" pkgs.nixVersions."nix_${nix-version}")
pkgs.git
pkgs.just
pkgs.age
pkgs.ssh-to-age
pkgs.sops
pkgs.nixpkgs-fmt
self.packages.${system}.swarsel-build
self.packages.${system}.swarsel-deploy
(pkgs.symlinkJoin {
name = "home-manager";
buildInputs = [ pkgs.makeWrapper ];
paths = [ pkgs.home-manager ];
postBuild = ''
wrapProgram $out/bin/home-manager \
--append-flags '--flake .#$(hostname)'
'';
})
];
commands = [
{
package = pkgs.statix;
help = "Lint flake";
}
{
package = pkgs.deadnix;
help = "Check flake for dead code";
}
{
package = pkgs.nix-tree;
help = "Interactively browse dependency graphs of Nix derivations";
}
{
package = pkgs.nvd;
help = "Diff two nix toplevels and show which packages were upgraded";
}
{
package = pkgs.nix-diff;
help = "Explain why two Nix derivations differ";
}
{
package = pkgs.nix-output-monitor;
help = "Nix Output Monitor (a drop-in alternative for `nix` which shows a build graph)";
name = "nom \"$@\"";
}
{
name = "hm";
help = "Manage home-manager config";
command = "home-manager \"$@\"";
}
{
name = "fmt";
help = "Format flake";
command = "nixpkgs-fmt --check \"$FLAKE\"";
}
{
name = "sd";
help = "Build and deploy this nix config to nodes";
command = "swarsel-deploy \"$@\"";
}
{
name = "sl";
help = "Build and deploy a config to nodes";
command = "swarsel-deploy \${1} switch";
}
{
name = "sw";
help = "Build and switch to the host's config locally";
command = "swarsel-deploy $(hostname) switch";
}
{
name = "bld";
help = "Build a number of configurations";
command = "swarsel-build \"$@\"";
}
{
name = "c";
help = "Work with the flake git repository";
command = "git --git-dir=$FLAKE/.git --work-tree=$FLAKE/ \"$@\"";
}
];
# devshell.startup.pre-commit-install.text = "pre-commit install";
devshell.startup.pre-commit.text = config.pre-commit.installationScript;
env =
let
nix-plugins = pkgs.nix-plugins.override {
nixComponents = pkgs.nixVersions."nixComponents_${nix-version}";
};
in
[
{
name = "NIX_CONFIG";
value = ''
plugin-files = ${nix-plugins}/lib/nix/plugins
extra-builtins-file = ${self + /files/nix/extra-builtins.nix}
'';
}
];
};
};
};
}

43
flake/formatter.nix Normal file
View file

@ -0,0 +1,43 @@
{ inputs, ... }:
{
imports = [
inputs.treefmt-nix.flakeModule
];
perSystem = { pkgs, ... }: {
# formatter is set by treefmt to:
# formatter = lib.mkIf config.treefmt.flakeFormatter (lib.mkDefault config.treefmt.build.wrapper);
treefmt = {
projectRootFile = "flake.nix";
programs = {
nixfmt = {
enable = true;
package = pkgs.nixpkgs-fmt;
};
deadnix.enable = true;
statix.enable = true;
shfmt = {
enable = true;
indent_size = 4;
simplify = true;
# needed to replicate what my Emacs shfmt does
# there is no builtin option for space-redirects
package = pkgs.symlinkJoin {
name = "shfmt";
buildInputs = [ pkgs.makeWrapper ];
paths = [ pkgs.shfmt ];
postBuild = ''
wrapProgram $out/bin/shfmt \
--add-flags '-sr'
'';
};
};
shellcheck.enable = true;
};
settings.formatter.shellcheck.options = [
"--shell"
"bash"
];
};
};
}

75
flake/globals.nix Normal file
View file

@ -0,0 +1,75 @@
# adapted from https://github.com/oddlama/nix-config/blob/main/nix/globals.nix
{ self, inputs, ... }:
{
imports = [
(
{ lib, flake-parts-lib, ... }:
flake-parts-lib.mkTransposedPerSystemModule {
name = "globals";
file = ./globals.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
];
perSystem = { lib, pkgs, ... }:
{
globals =
let
globalsSystem = lib.evalModules {
prefix = [ "globals" ];
specialArgs = {
inherit (pkgs) lib;
inherit (self.outputs) nodes;
inherit inputs;
inherit (inputs.topologyPrivate) topologyPrivate;
};
modules = [
../modules/nixos/common/globals.nix
(
{ lib, ... }:
let
sopsImportEncrypted =
assert lib.assertMsg (builtins ? extraBuiltins.sopsImportEncrypted)
"The extra builtin 'sopsImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `./files/nix/extra-builtins.nix` ?";
builtins.extraBuiltins.sopsImportEncrypted;
in
{
imports = [
(sopsImportEncrypted ../secrets/repo/globals.nix.enc)
];
}
)
(
{ lib, ... }:
{
globals = lib.mkMerge (
lib.concatLists (
lib.flip lib.mapAttrsToList self.outputs.nodes (
name: cfg:
builtins.addErrorContext "while aggregating globals from nixosConfigurations.${name} into flake-level globals:" cfg.config._globalsDefs
)
)
);
}
)
];
};
in
{
inherit (globalsSystem.config.globals)
domains
services
networks
hosts
user
root
general
;
};
};
}

217
flake/hosts.nix Normal file
View file

@ -0,0 +1,217 @@
{ self, inputs, ... }:
{
flake = { config, ... }:
let
inherit (self) outputs;
inherit (outputs) lib homeLib;
# lib = (inputs.nixpkgs.lib // inputs.home-manager.lib).extend (_: _: { swarselsystems = import "${self}/lib" { inherit self lib inputs outputs; inherit (inputs) systems; }; });
mkNixosHost = { minimal }: configName: arch:
inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs outputs self minimal homeLib configName arch;
inherit (config.pkgs.${arch}) lib;
inherit (config) nodes topologyPrivate;
globals = config.globals.${arch};
type = "nixos";
withHomeManager = true;
extraModules = [ "${self}/modules/nixos/common/globals.nix" ];
};
modules = [
inputs.disko.nixosModules.disko
inputs.home-manager.nixosModules.home-manager
inputs.impermanence.nixosModules.impermanence
inputs.lanzaboote.nixosModules.lanzaboote
inputs.microvm.nixosModules.host
inputs.microvm.nixosModules.microvm
inputs.nix-index-database.nixosModules.nix-index
inputs.nix-minecraft.nixosModules.minecraft-servers
inputs.nix-topology.nixosModules.default
inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm
inputs.simple-nixos-mailserver.nixosModules.default
inputs.sops.nixosModules.sops
inputs.stylix.nixosModules.stylix
inputs.swarsel-nix.nixosModules.default
inputs.nixos-nftables-firewall.nixosModules.default
inputs.pia.nixosModules.default
inputs.niritiling.nixosModules.default
inputs.noctoggle.nixosModules.default
(inputs.nixos-extra-modules + "/modules/guests")
(inputs.nixos-extra-modules + "/modules/interface-naming.nix")
"${self}/hosts/nixos/${arch}/${configName}"
"${self}/profiles/nixos"
"${self}/modules/nixos"
{
_module.args.dns = inputs.dns;
microvm.guest.enable = lib.mkDefault false;
networking.hostName = lib.swarselsystems.mkStrong configName;
node = {
name = lib.mkForce configName;
arch = lib.mkForce arch;
type = lib.mkForce "nixos";
secretsDir = ../hosts/nixos/${arch}/${configName}/secrets;
configDir = ../hosts/nixos/${arch}/${configName};
lockFromBootstrapping = lib.mkIf (!minimal) (lib.swarselsystems.mkStrong true);
};
swarselprofiles = {
minimal = lib.mkIf minimal (lib.swarselsystems.mkStrong true);
};
swarselmodules.server = {
ssh = lib.mkIf (!minimal) (lib.swarselsystems.mkStrong true);
};
swarselsystems = {
mainUser = lib.swarselsystems.mkStrong "swarsel";
};
}
];
};
mkDarwinHost = { minimal }: configName: arch:
inputs.nix-darwin.lib.darwinSystem {
specialArgs = {
inherit inputs lib outputs self minimal configName;
inherit (config) nodes topologyPrivate;
withHomeManager = true;
globals = config.globals.${arch};
};
modules = [
# inputs.disko.nixosModules.disko
# inputs.sops.nixosModules.sops
# inputs.impermanence.nixosModules.impermanence
# inputs.lanzaboote.nixosModules.lanzaboote
# inputs.fw-fanctrl.nixosModules.default
# inputs.nix-topology.nixosModules.default
inputs.home-manager.darwinModules.home-manager
"${self}/hosts/darwin/${arch}/${configName}"
"${self}/modules/nixos/darwin"
# needed for infrastructure
"${self}/modules/shared/meta.nix"
"${self}/modules/nixos/common/globals.nix"
{
node = {
name = lib.mkForce configName;
arch = lib.mkForce arch;
type = lib.mkForce "darwin";
secretsDir = ../hosts/darwin/${arch}/${configName}/secrets;
};
}
];
};
mkHalfHost = configName: type: arch:
let
systemFunc = if (type == "home") then inputs.home-manager.lib.homeManagerConfiguration else inputs.nix-on-droid.lib.nixOnDroidConfiguration;
pkgs = lib.swarselsystems.pkgsFor.${arch};
in
systemFunc {
inherit pkgs;
extraSpecialArgs = {
inherit inputs lib outputs self configName arch type;
inherit (config) nodes topologyPrivate;
globals = config.globals.${arch};
minimal = false;
};
modules = [
inputs.stylix.homeModules.stylix
inputs.nix-index-database.homeModules.nix-index
inputs.sops.homeManagerModules.sops
inputs.spicetify-nix.homeManagerModules.default
inputs.swarsel-nix.homeModules.default
"${self}/hosts/${type}/${arch}/${configName}"
"${self}/profiles/home"
"${self}/modules/nixos/common/pii.nix"
{
node = {
name = lib.mkForce configName;
arch = lib.mkForce arch;
type = lib.mkForce type;
secretsDir = ../hosts/${type}/${arch}/${configName}/secrets;
};
}
];
};
linuxArches = [ "x86_64-linux" "aarch64-linux" ];
darwinArches = [ "x86_64-darwin" "aarch64-darwin" ];
mkArches = type: if (type == "nixos") then linuxArches else if (type == "darwin") then darwinArches else linuxArches ++ darwinArches;
readHostDirs = hostDir:
if builtins.pathExists hostDir then
builtins.attrNames
(
lib.filterAttrs (_: type: type == "directory")
(builtins.readDir hostDir)
) else [ ];
mkHalfHostsForArch = type: arch:
let
hostDir = "${self}/hosts/${type}/${arch}";
hosts = readHostDirs hostDir;
in
lib.genAttrs hosts (host: mkHalfHost host type arch);
mkHostsForArch = type: arch: minimal:
let
hostDir = "${self}/hosts/${type}/${arch}";
hosts = readHostDirs hostDir;
in
if (type == "nixos") then
lib.genAttrs hosts (host: mkNixosHost { inherit minimal; } host arch)
else if (type == "darwin") then
lib.genAttrs hosts (host: mkDarwinHost { inherit minimal; } host arch)
else { };
mkConfigurationsPerArch = type: minimal:
let
arches = mkArches type;
toMake = if (minimal == null) then (arch: _: mkHalfHostsForArch type arch) else (arch: _: mkHostsForArch type arch minimal);
in
lib.concatMapAttrs toMake
(lib.listToAttrs (map (a: { name = a; value = { }; }) arches));
halfConfigurationsPerArch = type: mkConfigurationsPerArch type null;
configurationsPerArch = type: minimal: mkConfigurationsPerArch type minimal;
in
rec {
nixosConfigurations = configurationsPerArch "nixos" false;
nixosConfigurationsMinimal = configurationsPerArch "nixos" true;
darwinConfigurations = configurationsPerArch "darwin" false;
darwinConfigurationsMinimal = configurationsPerArch "darwin" true;
homeConfigurations = halfConfigurationsPerArch "home";
nixOnDroidConfigurations = halfConfigurationsPerArch "android";
guestConfigurations = lib.flip lib.concatMapAttrs config.nixosConfigurations (
_: node:
lib.flip lib.mapAttrs' (node.config.guests or { }) (
guestName: guestDef:
lib.nameValuePair guestDef.nodeName node.config.microvm.vms.${guestName}.config
)
);
diskoConfigurations.default = import "${self}/files/templates/hosts/nixos/disk-config.nix";
nodes = config.nixosConfigurations
// config.darwinConfigurations
// config.guestConfigurations;
guestResources = lib.mapAttrs
(name: _:
let
f = arg: lib.foldr (base: acc: base + acc) 0 (map (node: nodes."${name}-${node}".config.microvm.${arg}) (builtins.attrNames nodes.${name}.config.guests));
in
{
mem = f "mem";
vcpu = f "vcpu";
})
nodes;
"@" = lib.mapAttrs (_: v: v.config.system.build.toplevel) config.nodes;
};
}

44
flake/iso.nix Normal file
View file

@ -0,0 +1,44 @@
{ self, inputs, ... }:
{
perSystem = { pkgs, system, ... }:
{
packages = {
# nix build --print-out-paths --no-link .#live-iso
live-iso = inputs.nixos-generators.nixosGenerate {
inherit pkgs system;
specialArgs = { inherit self; };
modules = [
inputs.home-manager.nixosModules.home-manager
"${self}/install/installer-config.nix"
];
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};
};
keygen = inputs.nixos-generators.nixosGenerate {
inherit pkgs system;
modules = [
inputs.home-manager.nixosModules.home-manager
"${self}/install/keygen-config.nix"
];
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};
};
# nix build --print-out-paths --no-link .#pnap-kexec --system <system>
swarsel-kexec = (inputs.smallpkgs.legacyPackages.${system}.nixos [
{
imports = [ "${self}/install/kexec.nix" ];
_file = __curPos.file;
system.kexec-installer.name = "swarsel-kexec";
}
inputs.nixos-images.nixosModules.kexec-installer
]).config.system.build.kexecInstallerTarball;
};
};
}

101
flake/lib.nix Normal file
View file

@ -0,0 +1,101 @@
{ self, inputs, ... }:
let
swarselsystems =
let
inherit (inputs) systems;
inherit (inputs.nixpkgs) lib;
in
rec {
cidrToSubnetMask = cidr:
let
prefixLength = lib.toInt (lib.last (lib.splitString "/" cidr));
bits = lib.genList (i: if i < prefixLength then 1 else 0) 32;
octets = lib.genList
(i:
let
octetBits = lib.sublist (i * 8) 8 bits;
octetValue = lib.foldl (acc: bit: acc * 2 + bit) 0 octetBits;
in
octetValue
) 4;
subnetMask = lib.concatStringsSep "." (map toString octets);
in
subnetMask;
mkIfElseList = p: yes: no: lib.mkMerge [
(lib.mkIf p yes)
(lib.mkIf (!p) no)
];
mkIfElse = p: yes: no: if p then yes else no;
getSubDomain = domain:
let
parts = builtins.split "\\." domain;
domainParts = builtins.filter (x: builtins.isString x && x != "") parts;
in
if builtins.length domainParts > 0
then builtins.head domainParts
else "";
getBaseDomain = domain:
let
parts = builtins.split "\\." domain;
domainParts = builtins.filter (x: builtins.isString x && x != "") parts;
baseParts = builtins.tail domainParts;
in
builtins.concatStringsSep "." baseParts;
pkgsFor = lib.genAttrs (import systems) (system:
import inputs.nixpkgs {
inherit system;
overlays = [
self.overlays.default
self.overlays.stables
self.overlays.modifications
];
config.allowUnfree = true;
}
);
toCapitalized = str:
if builtins.stringLength str == 0 then
""
else
let
first = builtins.substring 0 1 str;
rest = builtins.substring 1 (builtins.stringLength str - 1) str;
upper = lib.toUpper first;
lower = lib.toLower rest;
in
upper + lower;
mkTrueOption = lib.mkOption {
type = lib.types.bool;
default = true;
};
mkStrong = lib.mkOverride 60;
# forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system});
forEachLinuxSystem = f: lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f pkgsFor.${system});
readHosts = type: lib.attrNames (builtins.readDir "${self}/hosts/${type}");
readNix = type: lib.filter (name: name != "default.nix" && name != "optional" && name != "darwin") (lib.attrNames (builtins.readDir "${self}/${type}"));
mkImports = names: baseDir: lib.map (name: "${self}/${baseDir}/${name}") names;
};
in
{
flake = _:
{
lib = inputs.nixpkgs.lib.extend (_: _: {
inherit (inputs.home-manager.lib) hm;
inherit swarselsystems;
});
swarselsystemsLib = swarselsystems;
homeLib = self.outputs.lib;
};
}

11
flake/modules.nix Normal file
View file

@ -0,0 +1,11 @@
{ self, ... }:
{
flake = _:
let
inherit (self.outputs) lib;
in
{
nixosModules.default = import "${self}/modules/nixos" { inherit lib; };
homeModules = import "${self}/modules/home" { inherit lib; };
};
}

165
flake/overlays.nix Normal file
View file

@ -0,0 +1,165 @@
{ self, inputs, ... }:
let
inherit (self) outputs;
inherit (outputs) lib;
in
{
flake = _:
{
overlays =
let
nixpkgs-stable-versions = final: _:
let
nixpkgsInputs =
lib.filterAttrs
(name: _v: builtins.match "^nixpkgs-.*" name != null)
inputs;
rename = name: builtins.replaceStrings [ "nixpkgs-" ] [ "" ] name;
mkPkgs = src:
import src {
inherit (final.stdenv.hostPlatform) system;
config.allowUnfree = true;
};
in
builtins.listToAttrs (map
(name: {
name = rename name;
value = mkPkgs nixpkgsInputs.${name};
})
(builtins.attrNames nixpkgsInputs));
in
rec {
default = additions;
additions = final: prev:
let
additions = final: _: import "${self}/pkgs/flake" { pkgs = final; inherit self lib; }
// {
swarsel-nix = import inputs.swarsel-nix {
pkgs = prev;
};
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
};
in
(additions final prev)
// (nixpkgs-stable-versions final prev)
// (inputs.niri-flake.overlays.niri final prev)
// (inputs.noctalia.overlays.default final prev)
// (inputs.vbc-nix.overlays.default final prev)
// (inputs.nur.overlays.default final prev)
// (inputs.emacs-overlay.overlay final prev)
// (inputs.nix-topology.overlays.default final prev)
// (inputs.nix-index-database.overlays.nix-index final prev)
// (inputs.nixgl.overlay final prev)
// (inputs.nix-minecraft.overlay final prev)
// (inputs.nixos-extra-modules.overlays.default final prev);
stables = final: prev:
let
mkUsePkgsFrom = pkgsFrom: names:
builtins.listToAttrs (map
(name: {
inherit name;
value = pkgsFrom.${name};
})
names);
from =
let
stablePackages = nixpkgs-stable-versions final prev;
in
key:
stablePackages.${key} or (throw "Missing nixpkgs input nixpkgs-${key}");
in
(mkUsePkgsFrom (from "dev") [
# "swayosd"
"firezone-relay"
"firezone-server-web"
"firezone-server-api"
"firezone-server-domain"
])
// (mkUsePkgsFrom (from "stable24_05") [
"awscli2"
])
// (mkUsePkgsFrom (from "stable24_11") [
"python39"
"spotify"
"vieb"
])
// (mkUsePkgsFrom (from "stable25_05") [
"steam-fhsenv-without-steam"
"transmission_3"
])
// (mkUsePkgsFrom (from "stable") [
# "anki"
"azure-cli"
# "bat-extras.batgrep"
# "bluez"
"calibre"
# "chromium"
"dwarfs"
"gotenberg"
"khal"
"libreoffice"
"libreoffice-qt"
"nerd-fonts-symbols-only"
"noto-fonts-color-emoji"
# "pipewire"
"podman"
"teams-for-linux"
# "vesktop"
"virtualbox"
]);
modifications = final: prev:
let
modifications = final: prev: {
# vesktop = prev.vesktop.override {
# withSystemVencord = true;
# };
lib = prev.lib // {
swarselsystems = self.outputs.swarselsystemsLib;
hm = self.outputs.homeLib;
};
firefox = prev.firefox.override {
nativeMessagingHosts = [
prev.tridactyl-native
prev.browserpass
# prev.plasma5Packages.plasma-browser-integration
];
};
isync = prev.isync.override {
withCyrusSaslXoauth2 = true;
};
mgba = final.swarsel-mgba;
noctalia-shell = prev.noctalia-shell.override {
calendarSupport = true;
};
retroarch = prev.retroarch.withCores (cores: with cores; [
snes9x # snes
nestopia # nes
dosbox # dos
scummvm # scumm
vba-m # gb/a
mgba # gb/a
melonds # ds
dolphin # gc/wii
]);
};
in
modifications final prev;
};
};
}

51
flake/packages.nix Normal file
View file

@ -0,0 +1,51 @@
{ self, inputs, ... }:
{
imports = [
(
{ lib, flake-parts-lib, ... }:
flake-parts-lib.mkTransposedPerSystemModule {
name = "pkgs";
file = ./packages.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
];
flake = _:
let
inherit (self.outputs) lib;
in
{
packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs/flake" { inherit self lib pkgs; });
};
perSystem = { pkgs, system, ... }:
{
# see https://flake.parts/module-arguments.html?highlight=modulewith#persystem-module-parameters
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config = {
allowUnfree = true;
permittedInsecurePackages = [
# matrix
"olm-3.2.16"
# sonarr
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
#
"SDL_ttf-2.0.11"
];
};
overlays = [
self.overlays.default
self.overlays.stables
self.overlays.modifications
];
};
inherit pkgs;
};
}

26
flake/templates.nix Normal file
View file

@ -0,0 +1,26 @@
{ self, ... }:
{
flake = _: {
templates =
let
mkTemplates = names: builtins.listToAttrs (map
(name: {
inherit name;
value = {
path = "${self}/files/templates/${name}";
description = "${name} project ";
};
})
names);
templateNames = [
"python"
"rust"
"go"
"cpp"
"latex"
"default"
];
in
mkTemplates templateNames;
};
}

276
flake/topology.nix Normal file
View file

@ -0,0 +1,276 @@
{ self, inputs, ... }:
{
imports = [
inputs.nix-topology.flakeModule
];
perSystem = { system, ... }:
let
inherit (self.outputs) lib;
in
{
topology.modules = [
({ config, ... }:
let
globals = self.outputs.globals.${system};
inherit (config.lib.topology)
mkInternet
mkDevice
mkSwitch
mkRouter
mkConnection
;
in
{
renderer = "elk";
networks = {
fritz-lan = {
name = "Fritz!Box LAN";
inherit (globals.networks.home-lan) cidrv4 cidrv6;
};
services = {
name = "VLAN: Services";
inherit (globals.networks.home-lan.vlans.services) cidrv4 cidrv6;
};
home = {
name = "VLAN: Home";
inherit (globals.networks.home-lan.vlans.home) cidrv4 cidrv6;
};
devices = {
name = "VLAN: Devices";
inherit (globals.networks.home-lan.vlans.devices) cidrv4 cidrv6;
};
guests = {
name = "VLAN: Guests";
inherit (globals.networks.home-lan.vlans.guests) cidrv4 cidrv6;
};
fritz-wg = {
name = "WireGuard: Fritz!Box tunnel";
inherit (globals.networks.fritz-wg) cidrv4 cidrv6;
};
wgProxy = {
name = "WireGuard: Web proxy tunnel";
inherit (globals.networks.twothreetunnel-wgProxy) cidrv4 cidrv6;
};
wgHome = {
name = "WireGuard: Home proxy tunnel";
inherit (globals.networks.home-wgHome) cidrv4 cidrv6;
};
};
nodes = {
internet = mkInternet {
connections = [
(mkConnection "fritzbox" "dsl")
(mkConnection "magicant" "wifi")
(mkConnection "liliputsteps" "lan")
(mkConnection "treehouse" "eth1")
(mkConnection "toto" "bootstrapper")
(mkConnection "hotel" "demo host")
];
};
fritzbox = mkRouter "FRITZ!Box" {
info = "FRITZ!Box 7682";
image = "${self}/files/topology-images/Fritz!Box_7682.png";
interfaceGroups = [
[
"eth1"
"eth2"
"eth3"
"eth-wan"
"wifi"
]
[ "dsl" ]
];
connections = {
eth1 = mkConnection "winters" "eth1";
eth-wan = mkConnection "hintbooth" "lan";
};
interfaces = {
eth1 = {
addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ];
network = "fritz-lan";
};
eth2 = { };
eth3 = { };
eth-wan = {
addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ];
network = "fritz-lan";
};
wifi = {
addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ];
virtual = true;
renderer.hidePhysicalConnections = true;
network = "fritz-lan";
physicalConnections = [
(mkConnection "pyramid" "wifi")
(mkConnection "bakery" "wifi")
(mkConnection "machpizza" "wifi")
];
};
fritz-wg = {
addresses = [ globals.networks.fritz-wg.hosts.fritzbox.ipv4 ];
network = "fritz-wg";
virtual = true;
renderer.hidePhysicalConnections = true;
type = "wireguard";
physicalConnections = [
(mkConnection "pyramid" "fritz-wg")
(mkConnection "magicant" "fritz-wg")
];
};
};
};
switch-livingroom = mkSwitch "Switch Livingroom" {
info = "TL-SG108E";
image = "${self}/files/topology-images/TL-SG108E.png";
interfaceGroups = [
# trunk
[ "eth1" ]
# devices
[ "eth2" "eth5" "eth6" ]
# home
[ "eth3" "eth8" ]
# guests
[ "eth4" "eth7" ]
];
interfaces = {
eth2 = { network = lib.mkForce "devices"; };
eth3 = { network = lib.mkForce "home"; };
eth5 = { network = lib.mkForce "devices"; };
eth6 = { network = lib.mkForce "devices"; };
eth7 = { network = lib.mkForce "guests"; };
eth8 = { network = lib.mkForce "home"; };
};
connections = {
eth2 = mkConnection "nswitch" "eth1";
eth3 = mkConnection "bakery" "eth1";
eth5 = mkConnection "ps4" "eth1";
eth6 = mkConnection "ender3" "eth1";
eth7 = mkConnection "pc" "eth1";
eth8 = mkConnection "pyramid" "eth1";
};
};
switch-bedroom = mkSwitch "Switch Bedroom" {
info = "Cisco SG 200-08";
image = "${self}/files/topology-images/Cisco_SG_200-08.png";
interfaceGroups = [
# trunk
[ "eth1" ]
# devices
[ "eth2" ]
# guests
[ "eth3" "eth4" "eth5" "eth6" "eth7" "eth8" ]
];
interfaces = {
eth2 = { network = lib.mkForce "devices"; };
eth3 = { network = lib.mkForce "guests"; };
};
connections = {
eth2 = mkConnection "printer" "eth1";
eth3 = mkConnection "machpizza" "eth1";
};
};
nswitch = mkDevice "Nintendo Switch" {
info = "Atmosphère 1.3.2 @ FW 19.0.1";
image = "${self}/files/topology-images/nintendo-switch.png";
interfaces.eth1 = { };
};
ps4 = mkDevice "PlayStation 4" {
info = "GoldHEN @ FW 5.05";
image = "${self}/files/topology-images/ps4.png";
interfaces.eth1 = { };
};
ender3 = mkDevice "Ender 3" {
info = "SKR V1.3, TMC2209 (Dual), TFT35";
deviceIcon = "${self}/files/topology-images/ender3.png";
icon = "${self}/files/topology-images/raspi.png";
interfaces.eth1 = { };
services = {
octoprint = {
name = "OctoPrint";
icon = "${self}/files/topology-images/octoprint.png";
};
};
};
magicant = mkDevice "magicant" {
icon = "${self}/files/topology-images/phone.png";
info = "Samsung Z Flip 6";
image = "${self}/files/topology-images/zflip6.png";
interfaces = {
wifi = { };
fritz-wg.network = "fritz-wg";
};
};
machpizza = mkDevice "machpizza" {
info = "MacBook Pro 2016";
icon = "devices.laptop";
deviceIcon = "${self}/files/topology-images/mac.png";
interfaces = {
eth1.network = "guests";
wifi = { };
};
};
treehouse = mkDevice "treehouse" {
info = "NVIDIA DGX Spark";
icon = "${self}/files/topology-images/home-manager.png";
deviceIcon = "${self}/files/topology-images/dgxos.png";
interfaces = {
eth1 = { };
wifi = { };
};
services = {
ollama = {
name = "Ollama";
icon = "services.ollama";
};
openwebui = {
name = "Open WebUI";
icon = "services.open-webui";
};
comfyui = {
name = "Comfy UI";
icon = "${self}/files/topology-images/comfyui.png";
};
};
};
pc = mkDevice "Chaostheater" {
info = "ASUS Z97-A, i7-4790k, GTX970, 32GB RAM";
icon = "${self}/files/topology-images/windows.png";
deviceIcon = "${self}/files/topology-images/atlasos.png";
services = {
sunshine = {
name = "Sunshine";
icon = "${self}/files/topology-images/sunshine.png";
};
};
interfaces.eth1.network = "guests";
};
printer = mkDevice "Printer" {
info = "DELL C2665dnf";
image = "${self}/files/topology-images/DELL-C2665dnf.png";
interfaces.eth1 = { };
};
};
})
];
};
}