merge: feature improvements

This commit is contained in:
2026-04-12 23:33:33 +02:00
44 changed files with 1147 additions and 702 deletions

40
features/bootloader.nix Normal file
View File

@@ -0,0 +1,40 @@
{
nixos =
{ config, lib, inputs, ... }:
let
cfg = config.features.bootloader;
in
{
imports = [ inputs.lanzaboote.nixosModules.lanzaboote ];
options.features.bootloader = {
enable = lib.mkEnableOption "bootloader";
mode = lib.mkOption {
type = lib.types.enum [
"systemd-boot"
"lanzaboote"
];
default = "systemd-boot";
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
boot.loader.efi.canTouchEfiVariables = true;
}
(lib.mkIf (cfg.mode == "systemd-boot") {
boot.loader.systemd-boot.enable = true;
})
(lib.mkIf (cfg.mode == "lanzaboote") {
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
})
]);
};
}

View File

@@ -1,22 +0,0 @@
{
nixos =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.calibre ];
# udev rules for kindle and mtp device access
# NOTE:(@janezicmatej) uses services.udev.packages instead of extraRules
# because extraRules writes to 99-local.rules which is too late for uaccess
# see https://github.com/NixOS/nixpkgs/issues/308681
services.udev.packages = [
pkgs.libmtp
(pkgs.writeTextFile {
name = "kindle-udev-rules";
text = ''
ACTION!="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="1949", TAG+="uaccess"
'';
destination = "/etc/udev/rules.d/70-kindle.rules";
})
];
};
}

View File

@@ -1,10 +1,21 @@
{
home =
{ pkgs, ... }:
nixos =
{ lib, ... }:
{
home.packages = [
pkgs.claude-code
pkgs.mcp-nixos
];
options.features.claude.enable = lib.mkEnableOption "claude";
};
home =
{ pkgs, lib, osConfig, ... }:
let
cfg = osConfig.features.claude;
in
{
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.claude-code
pkgs.mcp-nixos
];
};
};
}

View File

@@ -1,45 +0,0 @@
{
nixos =
{ pkgs, inputs, ... }:
{
imports = [ inputs.stylix.nixosModules.stylix ];
# audio
services.pipewire = {
enable = true;
pulse.enable = true;
};
security.polkit.enable = true;
services.dbus.enable = true;
services.playerctld.enable = true;
xdg.portal = {
enable = true;
xdgOpenUsePortal = true;
extraPortals = [
pkgs.xdg-desktop-portal-wlr
pkgs.xdg-desktop-portal-gtk
];
};
fonts.packages = with pkgs; [
font-awesome
nerd-fonts.jetbrains-mono
];
# theming
stylix = {
enable = true;
polarity = "dark";
image = "${inputs.assets}/wallpaper.png";
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
};
};
home =
{ inputs, ... }:
{
home.file.".assets".source = inputs.assets;
};
}

View File

@@ -1,85 +1,152 @@
{
nixos =
{ pkgs, inputs, ... }:
{ config, lib, pkgs, inputs, ... }:
let
cfg = config.features.desktop;
in
{
imports = [ inputs.stylix.nixosModules.stylix ];
options.features.desktop = {
enable = lib.mkEnableOption "desktop environment";
# audio
services.pipewire = {
enable = true;
pulse.enable = true;
audio.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
bluetooth.enable = lib.mkOption {
type = lib.types.bool;
default = false;
};
apps.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
theme = {
wallpaper = lib.mkOption {
type = lib.types.path;
default = "${inputs.assets}/wallpaper.png";
};
scheme = lib.mkOption {
type = lib.types.str;
default = "gruvbox-material-dark-medium";
};
polarity = lib.mkOption {
type = lib.types.enum [
"dark"
"light"
];
default = "dark";
};
};
internalCA.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
# bluetooth
hardware.bluetooth.enable = true;
services.blueman.enable = true;
config = lib.mkIf cfg.enable (lib.mkMerge [
# base desktop
{
security.polkit.enable = true;
services.dbus.enable = true;
services.playerctld.enable = true;
security.polkit.enable = true;
services.dbus.enable = true;
services.playerctld.enable = true;
xdg.portal = {
enable = true;
xdgOpenUsePortal = true;
extraPortals = with pkgs; [
xdg-desktop-portal-wlr
xdg-desktop-portal-gtk
];
};
xdg.portal = {
enable = true;
xdgOpenUsePortal = true;
extraPortals = [
pkgs.xdg-desktop-portal-wlr
pkgs.xdg-desktop-portal-gtk
];
};
fonts.packages = with pkgs; [
font-awesome
nerd-fonts.jetbrains-mono
];
fonts.packages = with pkgs; [
font-awesome
nerd-fonts.jetbrains-mono
];
stylix = {
enable = true;
polarity = cfg.theme.polarity;
image = cfg.theme.wallpaper;
base16Scheme = "${pkgs.base16-schemes}/share/themes/${cfg.theme.scheme}.yaml";
};
}
# theming
stylix = {
enable = true;
polarity = "dark";
image = "${inputs.assets}/wallpaper.png";
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
};
# audio
(lib.mkIf cfg.audio.enable {
services.pipewire = {
enable = true;
pulse.enable = true;
};
environment.systemPackages = with pkgs; [
pavucontrol
easyeffects
];
})
programs.thunderbird.enable = true;
programs._1password.enable = true;
programs._1password-gui.enable = true;
# bluetooth
(lib.mkIf cfg.bluetooth.enable {
hardware.bluetooth.enable = true;
services.blueman.enable = true;
})
environment.systemPackages = with pkgs; [
easyeffects
ghostty
google-chrome
zathura
pavucontrol
bolt-launcher
libnotify
bibata-cursors
vesktop
rocketchat-desktop
telegram-desktop
slack
jellyfin-media-player
cider-2
mpv
ffmpeg
wf-recorder
wl-mirror
protonmail-bridge
ledger-live-desktop
];
# apps
(lib.mkIf cfg.apps.enable {
programs.thunderbird.enable = true;
# internal CA
security.pki.certificateFiles = [
inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}.ca-matheo-si
];
environment.systemPackages = with pkgs; [
ghostty
google-chrome
zathura
calibre
bolt-launcher
libnotify
bibata-cursors
vesktop
rocketchat-desktop
telegram-desktop
slack
jellyfin-media-player
cider-2
mpv
ffmpeg
wf-recorder
wl-mirror
protonmail-bridge
ledger-live-desktop
];
xdg.mime.defaultApplications = {
"application/pdf" = "org.pwmt.zathura.desktop";
};
xdg.mime.defaultApplications = {
"application/pdf" = "org.pwmt.zathura.desktop";
};
# kindle udev rules for calibre
features.udev.kindle.enable = lib.mkDefault true;
})
# internal CA
(lib.mkIf cfg.internalCA.enable {
security.pki.certificateFiles = [
inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}.ca-matheo-si
];
})
]);
};
home =
{ inputs, ... }:
{ lib, inputs, osConfig, ... }:
let
cfg = osConfig.features.desktop;
in
{
home.file.".assets".source = inputs.assets;
config = lib.mkIf cfg.enable {
home.file.".assets".source = inputs.assets;
};
};
}

View File

@@ -1,25 +1,29 @@
{
nixos =
{ lib, ... }:
{
options.features.dev.enable = lib.mkEnableOption "development tools";
};
home =
{ pkgs, inputs, ... }:
{ pkgs, lib, inputs, osConfig, ... }:
let
cfg = osConfig.features.dev;
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
in
{
home.packages = [
pkgs.git
packages.git-linearize
packages.ggman
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.python3
pkgs.osc
pkgs.python3
pkgs.osc
pkgs.google-cloud-sdk
pkgs.google-cloud-sql-proxy
packages.ahab
pkgs.just
pkgs.presenterm
];
pkgs.google-cloud-sdk
pkgs.google-cloud-sql-proxy
packages.ahab
pkgs.just
pkgs.presenterm
];
};
};
}

View File

@@ -1,26 +1,40 @@
{
nixos =
{ inputs, ... }:
{ config, lib, inputs, ... }:
let
cfg = config.features.direnv;
in
{
nix.registry.dev = {
from = {
type = "indirect";
id = "dev";
};
to = {
type = "path";
path = inputs.self.outPath;
options.features.direnv.enable = lib.mkEnableOption "direnv";
config = lib.mkIf cfg.enable {
nix.registry.dev = {
from = {
type = "indirect";
id = "dev";
};
to = {
type = "path";
path = inputs.self.outPath;
};
};
};
};
home = _: {
programs.direnv = {
enable = true;
nix-direnv.enable = true;
config.global.hide_env_diff = true;
};
home =
{ lib, osConfig, ... }:
let
cfg = osConfig.features.direnv;
in
{
config = lib.mkIf cfg.enable {
programs.direnv = {
enable = true;
nix-direnv.enable = true;
config.global.hide_env_diff = true;
};
xdg.configFile."direnv/lib/use_dev.sh".source = ./use_dev.sh;
};
xdg.configFile."direnv/lib/use_dev.sh".source = ./use_dev.sh;
};
};
}

View File

@@ -1,12 +1,19 @@
{
nixos =
{ user, ... }:
{ config, lib, user, ... }:
let
cfg = config.features.docker;
in
{
virtualisation.docker = {
enable = true;
logDriver = "json-file";
};
options.features.docker.enable = lib.mkEnableOption "docker";
users.users.${user}.extraGroups = [ "docker" ];
config = lib.mkIf cfg.enable {
virtualisation.docker = {
enable = true;
logDriver = "json-file";
};
users.users.${user}.extraGroups = [ "docker" ];
};
};
}

View File

@@ -1,42 +1,56 @@
{
nixos =
{ config, userKeys, ... }:
{ config, lib, userKeys, ... }:
let
cfg = config.features.filedrop;
in
{
sops.secrets.filedrop-authorized-keys = {
sopsFile = ../secrets/floo.yaml;
mode = "0444";
options.features.filedrop = {
enable = lib.mkEnableOption "filedrop sftp service";
sopsFile = lib.mkOption {
type = lib.types.path;
};
};
users.groups.filedrop = {
members = [ "matej" ];
config = lib.mkIf cfg.enable {
sops.secrets.filedrop-authorized-keys = {
inherit (cfg) sopsFile;
mode = "0444";
};
users.groups.filedrop = {
members = [ "matej" ];
};
users.users.filedrop = {
isSystemUser = true;
group = "filedrop";
home = "/home/filedrop";
shell = "/run/current-system/sw/bin/nologin";
openssh.authorizedKeys.keys = userKeys.sshAuthorizedKeys;
};
# chroot dir must be root-owned; incoming is writable by filedrop
systemd.tmpfiles.rules = [
"d /home/filedrop 0755 root root -"
"d /home/filedrop/incoming 2775 filedrop filedrop -"
"a+ /home/filedrop/incoming - - - - group:filedrop:rwx"
"a+ /home/filedrop/incoming - - - - default:group:filedrop:rwx"
"a+ /home/filedrop/incoming - - - - default:mask::rwx"
"L /home/matej/filedrop - - - - /home/filedrop/incoming"
];
# relaxed umask so default acl takes full effect
services.openssh.extraConfig = ''
Match User filedrop
ForceCommand internal-sftp -u 0002
ChrootDirectory /home/filedrop
AuthorizedKeysFile /etc/ssh/authorized_keys.d/filedrop %h/.ssh/authorized_keys ${config.sops.secrets.filedrop-authorized-keys.path}
AllowTcpForwarding no
X11Forwarding no
'';
};
users.users.filedrop = {
isSystemUser = true;
group = "filedrop";
home = "/home/filedrop";
shell = "/run/current-system/sw/bin/nologin";
openssh.authorizedKeys.keys = userKeys.sshAuthorizedKeys;
};
# chroot dir must be root-owned; incoming is writable by filedrop
systemd.tmpfiles.rules = [
"d /home/filedrop 0755 root root -"
"d /home/filedrop/incoming 2775 filedrop filedrop -"
"a+ /home/filedrop/incoming - - - - group:filedrop:rwx"
"a+ /home/filedrop/incoming - - - - default:group:filedrop:rwx"
"a+ /home/filedrop/incoming - - - - default:mask::rwx"
"L /home/matej/filedrop - - - - /home/filedrop/incoming"
];
# relaxed umask so default acl takes full effect
services.openssh.extraConfig = ''
Match User filedrop
ForceCommand internal-sftp -u 0002
ChrootDirectory /home/filedrop
AuthorizedKeysFile /etc/ssh/authorized_keys.d/filedrop %h/.ssh/authorized_keys ${config.sops.secrets.filedrop-authorized-keys.path}
AllowTcpForwarding no
X11Forwarding no
'';
};
}

View File

@@ -1,14 +1,21 @@
{
nixos =
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.features.gaming;
in
{
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
localNetworkGameTransfers.openFirewall = true;
};
options.features.gaming.enable = lib.mkEnableOption "gaming";
environment.systemPackages = [ pkgs.prismlauncher ];
config = lib.mkIf cfg.enable {
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
localNetworkGameTransfers.openFirewall = true;
};
environment.systemPackages = [ pkgs.prismlauncher ];
};
};
}

23
features/git.nix Normal file
View File

@@ -0,0 +1,23 @@
{
nixos =
{ lib, ... }:
{
options.features.git.enable = lib.mkEnableOption "git";
};
home =
{ pkgs, lib, inputs, osConfig, ... }:
let
cfg = osConfig.features.git;
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
in
{
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.git
packages.git-linearize
packages.ggman
];
};
};
}

View File

@@ -1,9 +1,36 @@
{
nixos = _: {
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
enableExtraSocket = true;
nixos =
{ config, lib, pkgs, ... }:
let
cfg = config.features.gnupg;
in
{
options.features.gnupg = {
enable = lib.mkEnableOption "gnupg";
yubikey.enable = lib.mkOption {
type = lib.types.bool;
default = false;
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
enableExtraSocket = true;
};
}
(lib.mkIf cfg.yubikey.enable {
environment.systemPackages = with pkgs; [
yubikey-personalization
yubikey-manager
];
services.pcscd.enable = true;
})
]);
};
};
}

View File

@@ -1,28 +0,0 @@
{
nixos =
{ lib, inputs, ... }:
{
programs.regreet = {
enable = true;
# single output to avoid stretching across monitors
cageArgs = [
"-s"
"-m"
"last"
];
font = {
name = lib.mkForce "JetBrainsMono Nerd Font";
size = lib.mkForce 14;
};
settings = {
background = {
path = lib.mkForce "${inputs.assets}/wallpaper.png";
fit = lib.mkForce "Cover";
};
GTK = {
application_prefer_dark_theme = lib.mkForce true;
};
};
};
};
}

View File

@@ -1,12 +1,14 @@
{
nixos =
{
pkgs,
config,
lib,
pkgs,
inputs,
...
}:
let
cfg = config.features.harmonia;
hosts = [
"fw16"
"tower"
@@ -17,34 +19,38 @@
flakeRef = inputs.self.outPath;
in
{
services.harmonia.cache = {
enable = true;
signKeyPaths = [ config.sops.secrets.nix-signing-key.path ];
};
options.features.harmonia.enable = lib.mkEnableOption "harmonia";
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 5000 ];
systemd.services.cache-builder = {
description = "Build all host closures for binary cache";
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.bash}/bin/bash ${./cache-builder.sh}";
config = lib.mkIf cfg.enable {
services.harmonia.cache = {
enable = true;
signKeyPaths = [ config.sops.secrets.nix-signing-key.path ];
};
environment = {
FLAKE_REF = flakeRef;
HOSTS = builtins.concatStringsSep " " hosts;
GC_ROOT_DIR = "/nix/var/nix/gcroots/cache-builder";
};
path = [ config.nix.package ];
};
systemd.timers.cache-builder = {
description = "Periodically build all host closures";
wantedBy = [ "timers.target" ];
timerConfig = {
OnUnitActiveSec = "15min";
OnBootSec = "5min";
Persistent = true;
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 5000 ];
systemd.services.cache-builder = {
description = "Build all host closures for binary cache";
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.bash}/bin/bash ${./cache-builder.sh}";
};
environment = {
FLAKE_REF = flakeRef;
HOSTS = builtins.concatStringsSep " " hosts;
GC_ROOT_DIR = "/nix/var/nix/gcroots/cache-builder";
};
path = [ config.nix.package ];
};
systemd.timers.cache-builder = {
description = "Periodically build all host closures";
wantedBy = [ "timers.target" ];
timerConfig = {
OnUnitActiveSec = "15min";
OnBootSec = "5min";
Persistent = true;
};
};
};
};

View File

@@ -2,6 +2,7 @@
nixos =
{ lib, config, ... }:
let
cfg = config.features.initrd-ssh;
keyDir = "/etc/secrets/initrd";
mkIpString =
@@ -15,44 +16,45 @@
"${address}::${gateway}:${netmask}::${interface}:none";
in
{
options = {
initrd-ssh = {
ip = {
enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)";
options.features.initrd-ssh = {
enable = lib.mkEnableOption "initrd ssh";
address = lib.mkOption {
type = lib.types.str;
};
ip = {
enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)";
gateway = lib.mkOption {
type = lib.types.str;
};
netmask = lib.mkOption {
type = lib.types.str;
default = "255.255.255.0";
};
interface = lib.mkOption {
type = lib.types.str;
};
address = lib.mkOption {
type = lib.types.str;
};
authorizedKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
gateway = lib.mkOption {
type = lib.types.str;
};
networkModule = lib.mkOption {
netmask = lib.mkOption {
type = lib.types.str;
default = "255.255.255.0";
};
interface = lib.mkOption {
type = lib.types.str;
};
};
authorizedKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
networkModule = lib.mkOption {
type = lib.types.str;
};
};
config = {
boot.initrd.kernelModules = [ config.initrd-ssh.networkModule ];
boot.kernelParams = lib.mkIf config.initrd-ssh.ip.enable [
"ip=${mkIpString config.initrd-ssh.ip}"
config = lib.mkIf cfg.enable {
boot.initrd.availableKernelModules = [ cfg.networkModule ];
boot.initrd.kernelModules = [ cfg.networkModule ];
boot.kernelParams = lib.mkIf cfg.ip.enable [
"ip=${mkIpString cfg.ip}"
];
boot.initrd.network = {
@@ -64,7 +66,7 @@
"${keyDir}/ssh_host_rsa_key"
"${keyDir}/ssh_host_ed25519_key"
];
inherit (config.initrd-ssh) authorizedKeys;
inherit (cfg) authorizedKeys;
};
postCommands = ''
echo 'cryptsetup-askpass' >> /root/.profile

View File

@@ -1,25 +1,30 @@
{
nixos =
{ lib, config, ... }:
let
cfg = config.features.localisation;
in
{
options = {
localisation = {
timeZone = lib.mkOption {
type = lib.types.str;
};
options.features.localisation = {
enable = lib.mkEnableOption "localisation";
defaultLocale = lib.mkOption {
type = lib.types.str;
};
timeZone = lib.mkOption {
type = lib.types.str;
default = "Europe/Ljubljana";
};
defaultLocale = lib.mkOption {
type = lib.types.str;
default = "en_US.UTF-8";
};
};
config = {
time.timeZone = config.localisation.timeZone;
i18n.defaultLocale = config.localisation.defaultLocale;
config = lib.mkIf cfg.enable {
time.timeZone = cfg.timeZone;
i18n.defaultLocale = cfg.defaultLocale;
# NOTE:(@janezicmatej) some apps (e.g. java) need TZ env var explicitly
environment.variables.TZ = config.localisation.timeZone;
environment.variables.TZ = cfg.timeZone;
};
};
}

View File

@@ -1,4 +1,17 @@
{
nixos =
{ lib, ... }:
{
options.features.neovim = {
enable = lib.mkEnableOption "neovim";
dotfiles = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
};
};
};
home =
{
config,
@@ -6,24 +19,21 @@
lib,
pkgs,
inputs,
osConfig,
...
}:
let
cfg = osConfig.features.neovim;
in
{
options = {
neovim.dotfiles = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
};
};
config = lib.mkMerge [
config = lib.mkIf cfg.enable (lib.mkMerge [
(lib.optionalAttrs (options ? stylix) {
# disable stylix neovim target when stylix is present (loaded by desktop feature)
# disable stylix neovim target when stylix is present
stylix.targets.neovim.enable = false;
})
{
xdg.configFile."nvim" = lib.mkIf (config.neovim.dotfiles != null) {
source = config.neovim.dotfiles;
xdg.configFile."nvim" = lib.mkIf (cfg.dotfiles != null) {
source = cfg.dotfiles;
};
programs.neovim = {
@@ -64,6 +74,6 @@
];
};
}
];
]);
};
}

View File

@@ -1,9 +1,18 @@
{
nixos = _: {
networking.networkmanager.enable = true;
networking.nameservers = [
"1.1.1.1"
"8.8.8.8"
];
};
nixos =
{ config, lib, ... }:
let
cfg = config.features.networkmanager;
in
{
options.features.networkmanager.enable = lib.mkEnableOption "networkmanager";
config = lib.mkIf cfg.enable {
networking.networkmanager.enable = true;
networking.nameservers = [
"1.1.1.1"
"8.8.8.8"
];
};
};
}

View File

@@ -1,5 +1,14 @@
{
nixos = _: {
programs.nix-ld.enable = true;
};
nixos =
{ config, lib, ... }:
let
cfg = config.features.nix-ld;
in
{
options.features.nix-ld.enable = lib.mkEnableOption "nix-ld";
config = lib.mkIf cfg.enable {
programs.nix-ld.enable = true;
};
};
}

71
features/nix-settings.nix Normal file
View File

@@ -0,0 +1,71 @@
{
nixos =
{ config, lib, ... }:
let
cfg = config.features.nix-settings;
in
{
options.features.nix-settings = {
enable = lib.mkEnableOption "nix settings";
towerCache.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
gc = {
dates = lib.mkOption {
type = lib.types.str;
default = "monthly";
};
olderThan = lib.mkOption {
type = lib.types.str;
default = "30d";
};
};
optimise.dates = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "monthly" ];
};
};
config = lib.mkIf cfg.enable {
nix = {
settings = {
experimental-features = [
"nix-command"
"flakes"
];
download-buffer-size = 2 * 1024 * 1024 * 1024;
warn-dirty = false;
substituters =
[
"https://cache.nixos.org"
"https://nix-community.cachix.org?priority=45"
]
++ lib.optional cfg.towerCache.enable "http://tower:5000?priority=50";
trusted-public-keys =
[
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
]
++ lib.optional cfg.towerCache.enable "matej.nix-1:TdbemLVYblvAxqJcwb3mVKmmr3cfzXbMcZHE5ILnZDE=";
};
gc = {
automatic = true;
dates = cfg.gc.dates;
options = "--delete-older-than ${cfg.gc.olderThan}";
};
optimise = {
automatic = true;
dates = cfg.optimise.dates;
};
};
};
};
}

18
features/onepassword.nix Normal file
View File

@@ -0,0 +1,18 @@
{
nixos =
{ config, lib, user, ... }:
let
cfg = config.features.onepassword;
in
{
options.features.onepassword.enable = lib.mkEnableOption "1password";
config = lib.mkIf cfg.enable {
programs._1password.enable = true;
programs._1password-gui = {
enable = true;
polkitPolicyOwners = [ user ];
};
};
};
}

View File

@@ -1,18 +1,23 @@
{
nixos =
{ lib, config, ... }:
let
cfg = config.features.openssh;
in
{
options = {
openssh.port = lib.mkOption {
options.features.openssh = {
enable = lib.mkEnableOption "openssh";
port = lib.mkOption {
type = lib.types.port;
default = 22;
};
};
config = {
config = lib.mkIf cfg.enable {
services.openssh = {
enable = true;
ports = [ config.openssh.port ];
ports = [ cfg.port ];
settings = {
PasswordAuthentication = false;
AllowUsers = null;

57
features/power.nix Normal file
View File

@@ -0,0 +1,57 @@
{
nixos =
{ config, lib, ... }:
let
cfg = config.features.power;
in
{
options.features.power = {
enable = lib.mkEnableOption "laptop power management";
resumeDevice = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
};
lidSwitch = lib.mkOption {
type = lib.types.str;
default = "suspend-then-hibernate";
};
powerKey = lib.mkOption {
type = lib.types.str;
default = "suspend-then-hibernate";
};
idleAction = lib.mkOption {
type = lib.types.str;
default = "suspend-then-hibernate";
};
idleActionSec = lib.mkOption {
type = lib.types.str;
default = "15min";
};
hibernateDelaySec = lib.mkOption {
type = lib.types.str;
default = "30min";
};
};
config = lib.mkIf cfg.enable {
boot.resumeDevice = lib.mkIf (cfg.resumeDevice != null) cfg.resumeDevice;
services.logind.settings.Login = {
HandleLidSwitch = cfg.lidSwitch;
HandlePowerKey = cfg.powerKey;
IdleAction = cfg.idleAction;
IdleActionSec = cfg.idleActionSec;
};
systemd.sleep.settings.Sleep = {
HibernateDelaySec = cfg.hibernateDelaySec;
};
};
};
}

View File

@@ -1,10 +1,19 @@
{
nixos = _: {
services.printing.enable = true;
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
nixos =
{ config, lib, ... }:
let
cfg = config.features.printing;
in
{
options.features.printing.enable = lib.mkEnableOption "printing";
config = lib.mkIf cfg.enable {
services.printing.enable = true;
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
};
};
};
}

View File

@@ -1,13 +1,20 @@
{
nixos =
{ config, user, ... }:
{ config, lib, user, ... }:
let
cfg = config.features.remote-base;
in
{
sops.secrets.user-password = {
sopsFile = ../secrets/common.yaml;
neededForUsers = true;
};
options.features.remote-base.enable = lib.mkEnableOption "remote-base";
users.mutableUsers = false;
users.users.${user}.hashedPasswordFile = config.sops.secrets.user-password.path;
config = lib.mkIf cfg.enable {
sops.secrets.user-password = {
sopsFile = ../secrets/common.yaml;
neededForUsers = true;
};
users.mutableUsers = false;
users.users.${user}.hashedPasswordFile = config.sops.secrets.user-password.path;
};
};
}

View File

@@ -1,16 +0,0 @@
{
nixos = _: {
programs.zsh.enable = true;
environment.etc."zshenv".text = ''
export ZDOTDIR=$HOME/.config/zsh
'';
};
home =
{ pkgs, ... }:
{
home.packages = with pkgs; [
starship
];
};
}

View File

@@ -1,25 +1,28 @@
{
nixos = _: {
programs.zsh.enable = true;
environment.etc."zshenv".text = ''
export ZDOTDIR=$HOME/.config/zsh
'';
};
nixos =
{ lib, ... }:
{
options.features.shell.enable = lib.mkEnableOption "shell extras";
};
home =
{ pkgs, ... }:
{ pkgs, lib, osConfig, ... }:
let
cfg = osConfig.features.shell;
in
{
home.packages = with pkgs; [
starship
fzf
htop
jc
jq
openssl
pv
ripgrep
fd
tmux
];
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
fzf
htop
jc
jq
openssl
pv
ripgrep
fd
tmux
];
};
};
}

View File

@@ -1,38 +1,91 @@
{
nixos =
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.features.sway;
desktopCfg = config.features.desktop;
in
{
programs.sway = {
enable = true;
package = pkgs.swayfx;
wrapperFeatures.gtk = true;
extraSessionCommands = ''
# fix for java awt apps not rendering
export _JAVA_AWT_WM_NONREPARENTING=1
'';
options.features.sway = {
enable = lib.mkEnableOption "sway window manager";
greeter.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
environment.systemPackages = with pkgs; [
waybar
mako
wob
playerctl
brightnessctl
foot
grim
pulseaudio
swayidle
swaylock-effects
jq
slurp
wl-clipboard
pamixer
wlsunset
satty
wayland-pipewire-idle-inhibit
fuzzel
cliphist
zenity
];
config = lib.mkIf cfg.enable (lib.mkMerge [
{
# soft dependency
features.desktop.enable = lib.mkDefault true;
# hard dependency
assertions = [
{
assertion = desktopCfg.enable;
message = "features.sway requires features.desktop";
}
];
programs.sway = {
enable = true;
package = pkgs.swayfx;
wrapperFeatures.gtk = true;
extraSessionCommands = ''
# fix for java awt apps not rendering
export _JAVA_AWT_WM_NONREPARENTING=1
'';
};
environment.systemPackages = with pkgs; [
waybar
mako
wob
playerctl
brightnessctl
foot
grim
pulseaudio
swayidle
swaylock-effects
jq
slurp
wl-clipboard
pamixer
wlsunset
satty
wayland-pipewire-idle-inhibit
fuzzel
cliphist
zenity
];
}
# greeter
(lib.mkIf cfg.greeter.enable {
programs.regreet = {
enable = true;
cageArgs = [
"-s"
"-m"
"last"
];
font = {
name = lib.mkForce "JetBrainsMono Nerd Font";
size = lib.mkForce 14;
};
settings = {
background = {
path = lib.mkForce (toString desktopCfg.theme.wallpaper);
fit = lib.mkForce "Cover";
};
GTK = {
application_prefer_dark_theme = lib.mkForce true;
};
};
};
})
]);
};
}

View File

@@ -1,8 +1,17 @@
{
nixos = _: {
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
nixos =
{ config, lib, ... }:
let
cfg = config.features.tailscale;
in
{
options.features.tailscale.enable = lib.mkEnableOption "tailscale";
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
};
};
};
};
}

52
features/udev.nix Normal file
View File

@@ -0,0 +1,52 @@
{
nixos =
{ config, lib, pkgs, ... }:
let
cfg = config.features.udev;
in
{
options.features.udev = {
enable = lib.mkEnableOption "custom udev rules";
kindle.enable = lib.mkOption {
type = lib.types.bool;
default = false;
};
ledger.enable = lib.mkOption {
type = lib.types.bool;
default = false;
};
keyboard-zsa.enable = lib.mkOption {
type = lib.types.bool;
default = false;
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
(lib.mkIf cfg.kindle.enable {
# NOTE:(@janezicmatej) uses services.udev.packages instead of extraRules
# because extraRules writes to 99-local.rules which is too late for uaccess
services.udev.packages = [
pkgs.libmtp
(pkgs.writeTextFile {
name = "kindle-udev-rules";
text = ''
ACTION!="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="1949", TAG+="uaccess"
'';
destination = "/etc/udev/rules.d/70-kindle.rules";
})
];
})
(lib.mkIf cfg.ledger.enable {
hardware.ledger.enable = true;
})
(lib.mkIf cfg.keyboard-zsa.enable {
hardware.keyboard.zsa.enable = true;
})
]);
};
}

View File

@@ -10,15 +10,12 @@ in
};
nixos =
{ pkgs, ... }:
{ ... }:
{
programs.zsh.enable = true;
users.users.matej = {
uid = 1000;
isNormalUser = true;
home = "/home/matej";
shell = pkgs.zsh;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = sshKeys;
};

View File

@@ -1,72 +0,0 @@
{
nixos =
{
pkgs,
lib,
config,
...
}:
let
inherit (config.vm-9p-automount) user;
inherit (config.users.users.${user}) home group;
in
{
options = {
vm-9p-automount = {
user = lib.mkOption {
type = lib.types.str;
};
prefix = lib.mkOption {
type = lib.types.str;
default = "m_";
};
basePath = lib.mkOption {
type = lib.types.str;
default = "${home}/mnt";
};
};
};
config = {
systemd.services.vm-9p-automount = {
description = "Auto-discover and mount 9p shares";
after = [
"local-fs.target"
"nss-user-lookup.target"
"systemd-modules-load.service"
];
wants = [ "systemd-modules-load.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "vm-9p-automount" ''
BASE="${config.vm-9p-automount.basePath}"
PREFIX="${config.vm-9p-automount.prefix}"
mkdir -p "$BASE"
chown ${user}:${group} "$BASE"
for tagfile in $(find /sys/devices -name mount_tag 2>/dev/null); do
[ -f "$tagfile" ] || continue
tag=$(tr -d '\0' < "$tagfile")
case "$tag" in
"$PREFIX"*) ;;
*) continue ;;
esac
name="''${tag#"$PREFIX"}"
target="$BASE/$name"
mkdir -p "$target"
${pkgs.util-linux}/bin/mount -t 9p "$tag" "$target" \
-o trans=virtio,version=9p2000.L || continue
done
'';
};
};
};
};
}

View File

@@ -6,42 +6,110 @@
config,
...
}:
let
cfg = config.features.vm-guest;
autoUser = cfg.automount.user;
autoHome = config.users.users.${autoUser}.home;
autoGroup = config.users.users.${autoUser}.group;
in
{
options = {
vm-guest.headless = lib.mkOption {
options.features.vm-guest = {
enable = lib.mkEnableOption "qemu vm guest";
headless = lib.mkOption {
type = lib.types.bool;
default = false;
};
};
config = {
services.qemuGuest.enable = true;
services.spice-vdagentd.enable = lib.mkIf (!config.vm-guest.headless) true;
automount = {
enable = lib.mkEnableOption "9p share automount";
boot.kernelParams = lib.mkIf config.vm-guest.headless [ "console=ttyS0,115200" ];
user = lib.mkOption {
type = lib.types.str;
};
boot.initrd.availableKernelModules = [
"9p"
"9pnet_virtio"
];
boot.kernelModules = [
"9p"
"9pnet_virtio"
];
prefix = lib.mkOption {
type = lib.types.str;
default = "m_";
};
networking = {
useDHCP = true;
firewall.allowedTCPPorts = [ 22 ];
basePath = lib.mkOption {
type = lib.types.str;
default = "${autoHome}/mnt";
};
};
security.sudo.wheelNeedsPassword = false;
environment.systemPackages = with pkgs; [
curl
wget
htop
sshfs
];
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
services.qemuGuest.enable = true;
services.spice-vdagentd.enable = lib.mkIf (!cfg.headless) true;
boot.kernelParams = lib.mkIf cfg.headless [ "console=ttyS0,115200" ];
boot.initrd.availableKernelModules = [
"9p"
"9pnet_virtio"
];
boot.kernelModules = [
"9p"
"9pnet_virtio"
];
networking = {
useDHCP = true;
firewall.allowedTCPPorts = [ 22 ];
};
security.sudo.wheelNeedsPassword = false;
environment.systemPackages = with pkgs; [
curl
wget
htop
sshfs
];
}
(lib.mkIf cfg.automount.enable {
systemd.services.vm-9p-automount = {
description = "Auto-discover and mount 9p shares";
after = [
"local-fs.target"
"nss-user-lookup.target"
"systemd-modules-load.service"
];
wants = [ "systemd-modules-load.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "vm-9p-automount" ''
BASE="${cfg.automount.basePath}"
PREFIX="${cfg.automount.prefix}"
mkdir -p "$BASE"
chown ${autoUser}:${autoGroup} "$BASE"
for tagfile in $(find /sys/devices -name mount_tag 2>/dev/null); do
[ -f "$tagfile" ] || continue
tag=$(tr -d '\0' < "$tagfile")
case "$tag" in
"$PREFIX"*) ;;
*) continue ;;
esac
name="''${tag#"$PREFIX"}"
target="$BASE/$name"
mkdir -p "$target"
${pkgs.util-linux}/bin/mount -t 9p "$tag" "$target" \
-o trans=virtio,version=9p2000.L || continue
done
'';
};
};
})
]);
};
}

View File

@@ -1,12 +0,0 @@
{
nixos =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
yubikey-personalization
yubikey-manager
];
services.pcscd.enable = true;
};
}

42
features/zsh.nix Normal file
View File

@@ -0,0 +1,42 @@
{
nixos =
{ config, lib, pkgs, user, ... }:
let
cfg = config.features.zsh;
in
{
options.features.zsh = {
enable = lib.mkEnableOption "zsh";
loginShell.enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
programs.zsh.enable = true;
environment.etc."zshenv".text = ''
export ZDOTDIR=$HOME/.config/zsh
'';
}
(lib.mkIf cfg.loginShell.enable {
users.users.${user}.shell = pkgs.zsh;
})
]);
};
home =
{ pkgs, lib, osConfig, ... }:
let
cfg = osConfig.features.zsh;
in
{
config = lib.mkIf cfg.enable {
home.packages = [ pkgs.starship ];
};
};
}

View File

@@ -15,25 +15,29 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"openssh"
"localisation"
"gnupg"
"shell"
"desktop"
"sway"
"greeter"
"printing"
"networkmanager"
"docker"
"tailscale"
"nix-ld"
"yubikey"
"calibre"
"gaming"
"direnv"
"neovim"
"dev"
"bootloader"
"claude"
"desktop"
"dev"
"direnv"
"docker"
"gaming"
"git"
"gnupg"
"localisation"
"neovim"
"networkmanager"
"nix-ld"
"nix-settings"
"onepassword"
"openssh"
"power"
"printing"
"shell"
"sway"
"tailscale"
"udev"
"zsh"
];
};
@@ -41,27 +45,30 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"openssh"
"localisation"
"gnupg"
"shell"
"desktop"
"sway"
"greeter"
"printing"
"networkmanager"
"docker"
"tailscale"
"nix-ld"
"yubikey"
"calibre"
"gaming"
"initrd-ssh"
"direnv"
"neovim"
"dev"
"bootloader"
"claude"
"desktop"
"dev"
"direnv"
"docker"
"gaming"
"git"
"gnupg"
"harmonia"
"initrd-ssh"
"localisation"
"neovim"
"networkmanager"
"nix-ld"
"nix-settings"
"onepassword"
"openssh"
"printing"
"shell"
"sway"
"tailscale"
"udev"
"zsh"
];
};
@@ -70,7 +77,9 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"nix-settings"
"openssh"
"zsh"
];
};
@@ -78,11 +87,14 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"openssh"
"bootloader"
"localisation"
"nix-settings"
"openssh"
"remote-base"
"shell"
"tailscale"
"remote-base"
"zsh"
];
};
@@ -91,12 +103,14 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"openssh"
"filedrop"
"localisation"
"nix-settings"
"openssh"
"remote-base"
"shell"
"tailscale"
"remote-base"
"filedrop"
"zsh"
];
};
@@ -104,14 +118,15 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"localisation"
"bootloader"
"desktop"
"gnupg"
"shell-minimal"
"desktop-minimal"
"sway"
"greeter"
"localisation"
"networkmanager"
"yubikey"
"nix-settings"
"sway"
"udev"
"zsh"
];
};
@@ -119,16 +134,18 @@ in
system = "x86_64-linux";
user = "matej";
features = [
"openssh"
"localisation"
"gnupg"
"shell"
"vm-guest"
"vm-9p-automount"
"docker"
"neovim"
"claude"
"dev"
"docker"
"git"
"gnupg"
"localisation"
"neovim"
"nix-settings"
"openssh"
"shell"
"vm-guest"
"zsh"
];
};
};

View File

@@ -2,9 +2,6 @@
{
imports = [ inputs.disko.nixosModules.disko ];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
disko.devices.disk.main = {
type = "disk";
device = "/dev/nvme0n1";
@@ -32,10 +29,5 @@
};
};
localisation = {
timeZone = "Europe/Ljubljana";
defaultLocale = "en_US.UTF-8";
};
system.stateVersion = "25.11";
}

View File

@@ -5,6 +5,7 @@
...
}:
{
features.nix-settings.towerCache.enable = false;
# no hardware firmware needed in a VM
hardware.enableRedistributableFirmware = lib.mkForce false;
hardware.wirelessRegulatoryDatabase = lib.mkForce false;
@@ -28,18 +29,12 @@
);
};
vm-guest.headless = true;
vm-9p-automount.user = "matej";
localisation = {
timeZone = "UTC";
defaultLocale = "en_US.UTF-8";
};
home-manager.users.matej = {
neovim.dotfiles = inputs.nvim;
features.vm-guest.headless = true;
features.vm-guest.automount = {
enable = true;
user = "matej";
};
features.neovim.dotfiles = inputs.nvim;
# ensure .config exists with correct ownership before automount
systemd.tmpfiles.rules = [ "d /home/matej/.config 0755 matej users -" ];

View File

@@ -2,6 +2,8 @@
{
imports = [ inputs.disko.nixosModules.disko ];
features.filedrop.sopsFile = ../../secrets/floo.yaml;
boot.loader.grub.enable = true;
disko.devices.disk.main = {
@@ -26,10 +28,5 @@
};
};
localisation = {
timeZone = "Europe/Ljubljana";
defaultLocale = "en_US.UTF-8";
};
system.stateVersion = "25.11";
}

View File

@@ -10,13 +10,11 @@
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
];
localisation = {
timeZone = "Europe/Ljubljana";
defaultLocale = "en_US.UTF-8";
features.desktop = {
apps.enable = false;
internalCA.enable = false;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
features.gnupg.yubikey.enable = true;
disko.devices.disk.main = {
type = "disk";

View File

@@ -1,8 +1,7 @@
{
lib,
pkgs,
inputs,
options,
inputs,
...
}:
@@ -11,37 +10,22 @@
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
];
localisation = {
timeZone = "Europe/Ljubljana";
defaultLocale = "en_US.UTF-8";
features.desktop.bluetooth.enable = true;
features.gnupg.yubikey.enable = true;
features.udev = {
ledger.enable = true;
keyboard-zsa.enable = true;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
features.power.resumeDevice = "/dev/disk/by-uuid/ff4750e7-3a9f-42c2-bb68-c458a6560540";
boot.kernelParams = [ "pcie_aspm.policy=powersupersave" ];
boot.resumeDevice = "/dev/disk/by-uuid/ff4750e7-3a9f-42c2-bb68-c458a6560540";
services.logind.settings.Login = {
HandleLidSwitch = "suspend-then-hibernate";
HandlePowerKey = "suspend-then-hibernate";
IdleAction = "suspend-then-hibernate";
IdleActionSec = "15min";
};
systemd.sleep.settings.Sleep = {
HibernateDelaySec = "30min";
};
programs.nix-ld.libraries = options.programs.nix-ld.libraries.default;
services.gnome.gnome-keyring.enable = true;
services.teamviewer.enable = true;
services.hardware.bolt.enable = true;
hardware.keyboard.zsa.enable = true;
hardware.ledger.enable = true;
hardware.bluetooth.powerOnBoot = true;
hardware.inputmodule.enable = true;

View File

@@ -1,15 +1,13 @@
{ lib, ... }:
{ lib, userKeys, ... }:
{
features.nix-settings.towerCache.enable = false;
image.modules.iso-installer = {
isoImage.squashfsCompression = "zstd -Xcompression-level 6";
};
# live iso: passwordless login and sudo
users.users.matej.initialHashedPassword = "";
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQGLdINKzs+sEy62Pefng0bcedgU396+OryFgeH99/c janezicmatej"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDk00+Km03epQXQs+xEwwH3zcurACzkEH+kDOPBw6RQe openpgp:0xB095D449"
];
users.users.root.openssh.authorizedKeys.keys = userKeys.sshAuthorizedKeys;
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
security.sudo.wheelNeedsPassword = false;

View File

@@ -1,38 +1,28 @@
{
config,
lib,
inputs,
userKeys,
...
}:
{
imports = [
inputs.lanzaboote.nixosModules.lanzaboote
];
features.nix-settings.towerCache.enable = false;
features.bootloader.mode = "lanzaboote";
features.desktop.bluetooth.enable = true;
features.gnupg.yubikey.enable = true;
features.udev = {
ledger.enable = true;
keyboard-zsa.enable = true;
};
features.initrd-ssh = {
networkModule = "r8169";
authorizedKeys = userKeys.sshAuthorizedKeys;
};
# nix store signing
sops.secrets.nix-signing-key.sopsFile = ../../secrets/tower.yaml;
nix.settings.secret-key-files = [ config.sops.secrets.nix-signing-key.path ];
localisation = {
timeZone = "Europe/Ljubljana";
defaultLocale = "en_US.UTF-8";
};
initrd-ssh = {
networkModule = "r8169";
authorizedKeys = userKeys.sshAuthorizedKeys;
};
# lanzaboote secure boot
boot.kernelParams = [ "btusb.reset=1" ];
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
services.udisks2.enable = true;

View File

@@ -27,7 +27,19 @@ let
hostConfig = ../hosts/${name}/configuration.nix;
hostHWConfig = ../hosts/${name}/hardware-configuration.nix;
# load feature with path check
# auto-discover all features, excluding user-* and default.nix
featureDir = builtins.readDir ../features;
allFeatureNames = lib.pipe featureDir [
(lib.filterAttrs (
n: t:
(t == "regular" && lib.hasSuffix ".nix" n && n != "default.nix" && !lib.hasPrefix "user-" n)
|| (t == "directory" && builtins.pathExists ../features/${n}/default.nix)
))
builtins.attrNames
(map (n: lib.removeSuffix ".nix" n))
];
# load all features unconditionally
loadFeature =
f:
assert
@@ -35,7 +47,7 @@ let
|| throw "feature '${f}' not found at ${toString (featurePath f)}";
import (featurePath f);
loadedFeatures = map loadFeature features;
loadedFeatures = map loadFeature allFeatureNames;
# load user feature with path check
userFeature =
@@ -55,31 +67,42 @@ let
# collect nixos and home modules from all features
nixosMods = map (f: f.nixos) (builtins.filter (f: f ? nixos) allFeatures);
homeMods = map (f: f.home) (builtins.filter (f: f ? home) allFeatures);
# translate features list to enable flags
featureEnableModule =
{ lib, ... }:
{
config.features = lib.genAttrs features (_: {
enable = true;
});
};
in
nixpkgs.lib.nixosSystem {
inherit system;
modules = [
../nix.nix
inputs.sops-nix.nixosModules.sops
modules =
[
inputs.sops-nix.nixosModules.sops
inputs.stylix.nixosModules.stylix
{ nixpkgs.overlays = overlays; }
{ nixpkgs.config.allowUnfree = true; }
{ networking.hostName = name; }
{ nixpkgs.overlays = overlays; }
{ nixpkgs.config.allowUnfree = true; }
{ networking.hostName = name; }
hostConfig
]
++ lib.optional (builtins.pathExists hostHWConfig) hostHWConfig
++ nixosMods
++ lib.optionals hasUser [
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.backupFileExtension = "backup";
home-manager.users.${user}.imports = homeMods;
home-manager.extraSpecialArgs = { inherit inputs; };
}
];
featureEnableModule
hostConfig
]
++ lib.optional (builtins.pathExists hostHWConfig) hostHWConfig
++ nixosMods
++ lib.optionals hasUser [
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.backupFileExtension = "backup";
home-manager.users.${user}.imports = homeMods;
home-manager.extraSpecialArgs = { inherit inputs; };
}
];
specialArgs = {
inherit inputs userKeys user;
};