From 8c6fefb95bf90e00713430447047fe4faed02b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Thu, 26 Mar 2026 23:10:56 +0100 Subject: [PATCH] feat: migrate from modules to features --- features/calibre.nix | 22 +++++ features/claude.nix | 10 +++ features/desktop.nix | 85 +++++++++++++++++++ features/dev.nix | 30 +++++++ features/docker.nix | 12 +++ features/gnupg.nix | 9 ++ features/greeter.nix | 28 ++++++ features/initrd-ssh.nix | 75 ++++++++++++++++ features/localisation.nix | 25 ++++++ {modules/home-manager => features}/neovim.nix | 56 ++++++------ features/networkmanager.nix | 9 ++ features/nix-ld.nix | 5 ++ features/openssh.nix | 25 ++++++ features/printing.nix | 10 +++ features/shell.nix | 25 ++++++ features/steam.nix | 10 +++ features/sway.nix | 38 +++++++++ features/tailscale.nix | 8 ++ features/user-matej.nix | 33 +++++++ features/vm-9p-automount.nix | 72 ++++++++++++++++ features/vm-guest.nix | 47 ++++++++++ features/yubikey.nix | 12 +++ flake.nix | 14 --- lib/mkHost.nix | 62 +++++++++----- modules/home-manager/claude.nix | 25 ------ modules/home-manager/default.nix | 1 - modules/home-manager/desktop.nix | 38 --------- modules/home-manager/dev.nix | 39 --------- modules/home-manager/shell.nix | 26 ------ modules/nixos/calibre.nix | 32 ------- modules/nixos/default.nix | 1 - modules/nixos/desktop.nix | 44 ---------- modules/nixos/gnupg.nix | 20 ----- modules/nixos/greeter.nix | 37 -------- modules/nixos/initrd-ssh.nix | 83 ------------------ modules/nixos/localisation.nix | 28 ------ modules/nixos/nvidia.nix | 23 ----- modules/nixos/openssh.nix | 29 ------- modules/nixos/printing.nix | 21 ----- modules/nixos/sway.nix | 54 ------------ modules/nixos/vm-9p-automount.nix | 74 ---------------- modules/nixos/vm-guest.nix | 49 ----------- modules/nixos/workstation.nix | 31 ------- modules/nixos/yubikey.nix | 23 ----- modules/nixos/zsh.nix | 19 ----- profiles/base.nix | 17 ---- profiles/default.nix | 1 - profiles/desktop.nix | 21 ----- profiles/server.nix | 15 ---- users/matej/home-manager.nix | 22 ----- users/matej/keys.nix | 6 -- users/matej/nixos.nix | 27 ------ 52 files changed, 657 insertions(+), 871 deletions(-) create mode 100644 features/calibre.nix create mode 100644 features/claude.nix create mode 100644 features/desktop.nix create mode 100644 features/dev.nix create mode 100644 features/docker.nix create mode 100644 features/gnupg.nix create mode 100644 features/greeter.nix create mode 100644 features/initrd-ssh.nix create mode 100644 features/localisation.nix rename {modules/home-manager => features}/neovim.nix (50%) create mode 100644 features/networkmanager.nix create mode 100644 features/nix-ld.nix create mode 100644 features/openssh.nix create mode 100644 features/printing.nix create mode 100644 features/shell.nix create mode 100644 features/steam.nix create mode 100644 features/sway.nix create mode 100644 features/tailscale.nix create mode 100644 features/user-matej.nix create mode 100644 features/vm-9p-automount.nix create mode 100644 features/vm-guest.nix create mode 100644 features/yubikey.nix delete mode 100644 modules/home-manager/claude.nix delete mode 100644 modules/home-manager/default.nix delete mode 100644 modules/home-manager/desktop.nix delete mode 100644 modules/home-manager/dev.nix delete mode 100644 modules/home-manager/shell.nix delete mode 100644 modules/nixos/calibre.nix delete mode 100644 modules/nixos/default.nix delete mode 100644 modules/nixos/desktop.nix delete mode 100644 modules/nixos/gnupg.nix delete mode 100644 modules/nixos/greeter.nix delete mode 100644 modules/nixos/initrd-ssh.nix delete mode 100644 modules/nixos/localisation.nix delete mode 100644 modules/nixos/nvidia.nix delete mode 100644 modules/nixos/openssh.nix delete mode 100644 modules/nixos/printing.nix delete mode 100644 modules/nixos/sway.nix delete mode 100644 modules/nixos/vm-9p-automount.nix delete mode 100644 modules/nixos/vm-guest.nix delete mode 100644 modules/nixos/workstation.nix delete mode 100644 modules/nixos/yubikey.nix delete mode 100644 modules/nixos/zsh.nix delete mode 100644 profiles/base.nix delete mode 100644 profiles/default.nix delete mode 100644 profiles/desktop.nix delete mode 100644 profiles/server.nix delete mode 100644 users/matej/home-manager.nix delete mode 100644 users/matej/keys.nix delete mode 100644 users/matej/nixos.nix diff --git a/features/calibre.nix b/features/calibre.nix new file mode 100644 index 0000000..e310fa7 --- /dev/null +++ b/features/calibre.nix @@ -0,0 +1,22 @@ +{ + 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"; + }) + ]; + }; +} diff --git a/features/claude.nix b/features/claude.nix new file mode 100644 index 0000000..6f5fd2a --- /dev/null +++ b/features/claude.nix @@ -0,0 +1,10 @@ +{ + home = + { pkgs, ... }: + { + home.packages = [ + pkgs.claude-code + pkgs.mcp-nixos + ]; + }; +} diff --git a/features/desktop.nix b/features/desktop.nix new file mode 100644 index 0000000..f2e06af --- /dev/null +++ b/features/desktop.nix @@ -0,0 +1,85 @@ +{ + nixos = + { pkgs, inputs, ... }: + { + imports = [ inputs.stylix.nixosModules.stylix ]; + + # audio + services.pipewire = { + enable = true; + pulse.enable = true; + }; + + # bluetooth + hardware.bluetooth.enable = true; + services.blueman.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"; + }; + + programs.thunderbird.enable = true; + programs._1password.enable = true; + programs._1password-gui.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 + ]; + + # internal CA + security.pki.certificateFiles = [ + inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}.ca-matheo-si + ]; + + xdg.mime.defaultApplications = { + "application/pdf" = "org.pwmt.zathura.desktop"; + }; + }; + + home = + { inputs, ... }: + { + home.file.".assets".source = inputs.assets; + }; +} diff --git a/features/dev.nix b/features/dev.nix new file mode 100644 index 0000000..c3cd8e3 --- /dev/null +++ b/features/dev.nix @@ -0,0 +1,30 @@ +{ + home = + { pkgs, inputs, ... }: + let + packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}; + in + { + home.packages = [ + pkgs.git + packages.git-linearize + packages.ggman + pkgs.go + pkgs.python3 + pkgs.mdbook + pkgs.marksman + pkgs.mdformat + pkgs.google-cloud-sdk + pkgs.google-cloud-sql-proxy + packages.ahab + pkgs.just + pkgs.presenterm + pkgs.osc + ]; + + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + }; +} diff --git a/features/docker.nix b/features/docker.nix new file mode 100644 index 0000000..16440ee --- /dev/null +++ b/features/docker.nix @@ -0,0 +1,12 @@ +{ + nixos = + { user, ... }: + { + virtualisation.docker = { + enable = true; + logDriver = "json-file"; + }; + + users.users.${user}.extraGroups = [ "docker" ]; + }; +} diff --git a/features/gnupg.nix b/features/gnupg.nix new file mode 100644 index 0000000..e39f156 --- /dev/null +++ b/features/gnupg.nix @@ -0,0 +1,9 @@ +{ + nixos = _: { + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + enableExtraSocket = true; + }; + }; +} diff --git a/features/greeter.nix b/features/greeter.nix new file mode 100644 index 0000000..54bddb6 --- /dev/null +++ b/features/greeter.nix @@ -0,0 +1,28 @@ +{ + 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; + }; + }; + }; + }; +} diff --git a/features/initrd-ssh.nix b/features/initrd-ssh.nix new file mode 100644 index 0000000..23e7056 --- /dev/null +++ b/features/initrd-ssh.nix @@ -0,0 +1,75 @@ +{ + nixos = + { lib, config, ... }: + let + keyDir = "/etc/secrets/initrd"; + + mkIpString = + { + address, + gateway, + netmask, + interface, + ... + }: + "${address}::${gateway}:${netmask}::${interface}:none"; + in + { + options = { + initrd-ssh = { + ip = { + enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)"; + + address = lib.mkOption { + type = lib.types.str; + }; + + 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; + }; + }; + + 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}" + ]; + + boot.initrd.network = { + enable = true; + ssh = { + enable = true; + port = 22; + hostKeys = [ + "${keyDir}/ssh_host_rsa_key" + "${keyDir}/ssh_host_ed25519_key" + ]; + inherit (config.initrd-ssh) authorizedKeys; + }; + postCommands = '' + echo 'cryptsetup-askpass' >> /root/.profile + ''; + }; + }; + }; +} diff --git a/features/localisation.nix b/features/localisation.nix new file mode 100644 index 0000000..df07cdc --- /dev/null +++ b/features/localisation.nix @@ -0,0 +1,25 @@ +{ + nixos = + { lib, config, ... }: + { + options = { + localisation = { + timeZone = lib.mkOption { + type = lib.types.str; + }; + + defaultLocale = lib.mkOption { + type = lib.types.str; + }; + }; + }; + + config = { + time.timeZone = config.localisation.timeZone; + i18n.defaultLocale = config.localisation.defaultLocale; + + # NOTE:(@janezicmatej) some apps (e.g. java) need TZ env var explicitly + environment.variables.TZ = config.localisation.timeZone; + }; + }; +} diff --git a/modules/home-manager/neovim.nix b/features/neovim.nix similarity index 50% rename from modules/home-manager/neovim.nix rename to features/neovim.nix index a6c162d..6d03685 100644 --- a/modules/home-manager/neovim.nix +++ b/features/neovim.nix @@ -1,36 +1,36 @@ { - config, - lib, - pkgs, - ... -}: -{ - options = { - neovim = { - enable = lib.mkEnableOption "neovim nightly with lsp support"; - package = lib.mkPackageOption pkgs "neovim" { }; - dotfiles = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = null; - description = "path to neovim config directory"; + home = + { + config, + options, + lib, + pkgs, + inputs, + ... + }: + { + options = { + neovim.dotfiles = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + }; }; - }; - }; - config = lib.mkIf config.neovim.enable ( - lib.mkMerge [ - (lib.mkIf (config.neovim.dotfiles != null) { - xdg.configFile."nvim".source = config.neovim.dotfiles; - }) - { + config = { + # only disable when stylix is present (loaded by desktop feature) + stylix.targets.neovim.enable = lib.mkIf (options ? stylix) false; + + xdg.configFile."nvim" = lib.mkIf (config.neovim.dotfiles != null) { + source = config.neovim.dotfiles; + }; + programs.neovim = { enable = true; vimAlias = true; defaultEditor = true; - inherit (config.neovim) package; + package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default; extraPackages = with pkgs; [ - # runtime deps gcc luajit nodejs_22 @@ -38,13 +38,11 @@ gnumake osc - # search and diff fd ripgrep bat delta - # language servers pyright typescript-language-server lua-language-server @@ -52,7 +50,6 @@ nil nixd - # formatters nixpkgs-fmt stylua ]; @@ -64,7 +61,6 @@ "${lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib ]}" ]; }; - } - ] - ); + }; + }; } diff --git a/features/networkmanager.nix b/features/networkmanager.nix new file mode 100644 index 0000000..05a10c2 --- /dev/null +++ b/features/networkmanager.nix @@ -0,0 +1,9 @@ +{ + nixos = _: { + networking.networkmanager.enable = true; + networking.nameservers = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; +} diff --git a/features/nix-ld.nix b/features/nix-ld.nix new file mode 100644 index 0000000..e81219c --- /dev/null +++ b/features/nix-ld.nix @@ -0,0 +1,5 @@ +{ + nixos = _: { + programs.nix-ld.enable = true; + }; +} diff --git a/features/openssh.nix b/features/openssh.nix new file mode 100644 index 0000000..7a03aef --- /dev/null +++ b/features/openssh.nix @@ -0,0 +1,25 @@ +{ + nixos = + { lib, config, ... }: + { + options = { + openssh.port = lib.mkOption { + type = lib.types.port; + default = 22; + }; + }; + + config = { + services.openssh = { + enable = true; + ports = [ config.openssh.port ]; + settings = { + PasswordAuthentication = false; + AllowUsers = null; + PermitRootLogin = "no"; + StreamLocalBindUnlink = "yes"; + }; + }; + }; + }; +} diff --git a/features/printing.nix b/features/printing.nix new file mode 100644 index 0000000..a564157 --- /dev/null +++ b/features/printing.nix @@ -0,0 +1,10 @@ +{ + nixos = _: { + services.printing.enable = true; + services.avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + }; +} diff --git a/features/shell.nix b/features/shell.nix new file mode 100644 index 0000000..23c2ce1 --- /dev/null +++ b/features/shell.nix @@ -0,0 +1,25 @@ +{ + nixos = _: { + programs.zsh.enable = true; + environment.etc."zshenv".text = '' + export ZDOTDIR=$HOME/.config/zsh + ''; + }; + + home = + { pkgs, ... }: + { + home.packages = with pkgs; [ + starship + fzf + htop + jc + jq + openssl + pv + ripgrep + fd + tmux + ]; + }; +} diff --git a/features/steam.nix b/features/steam.nix new file mode 100644 index 0000000..d1b76f7 --- /dev/null +++ b/features/steam.nix @@ -0,0 +1,10 @@ +{ + nixos = _: { + programs.steam = { + enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + localNetworkGameTransfers.openFirewall = true; + }; + }; +} diff --git a/features/sway.nix b/features/sway.nix new file mode 100644 index 0000000..6c8a94c --- /dev/null +++ b/features/sway.nix @@ -0,0 +1,38 @@ +{ + nixos = + { pkgs, ... }: + { + 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 + ]; + }; +} diff --git a/features/tailscale.nix b/features/tailscale.nix new file mode 100644 index 0000000..a6916ad --- /dev/null +++ b/features/tailscale.nix @@ -0,0 +1,8 @@ +{ + nixos = _: { + services.tailscale = { + enable = true; + useRoutingFeatures = "both"; + }; + }; +} diff --git a/features/user-matej.nix b/features/user-matej.nix new file mode 100644 index 0000000..ab0065f --- /dev/null +++ b/features/user-matej.nix @@ -0,0 +1,33 @@ +let + sshKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQGLdINKzs+sEy62Pefng0bcedgU396+OryFgeH99/c janezicmatej" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDk00+Km03epQXQs+xEwwH3zcurACzkEH+kDOPBw6RQe openpgp:0xB095D449" + ]; +in +{ + keys = { + sshAuthorizedKeys = sshKeys; + }; + + nixos = + { pkgs, ... }: + { + users.users.matej = { + uid = 1000; + isNormalUser = true; + home = "/home/matej"; + shell = pkgs.zsh; + extraGroups = [ "wheel" ]; + openssh.authorizedKeys.keys = sshKeys; + }; + + users.groups.matej = { + gid = 1000; + members = [ "matej" ]; + }; + }; + + home = _: { + home.stateVersion = "24.11"; + }; +} diff --git a/features/vm-9p-automount.nix b/features/vm-9p-automount.nix new file mode 100644 index 0000000..bfc9751 --- /dev/null +++ b/features/vm-9p-automount.nix @@ -0,0 +1,72 @@ +{ + 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 + ''; + }; + }; + }; + }; +} diff --git a/features/vm-guest.nix b/features/vm-guest.nix new file mode 100644 index 0000000..0d6e7af --- /dev/null +++ b/features/vm-guest.nix @@ -0,0 +1,47 @@ +{ + nixos = + { + pkgs, + lib, + config, + ... + }: + { + options = { + 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; + + boot.kernelParams = lib.mkIf config.vm-guest.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 + ]; + }; + }; +} diff --git a/features/yubikey.nix b/features/yubikey.nix new file mode 100644 index 0000000..966a1aa --- /dev/null +++ b/features/yubikey.nix @@ -0,0 +1,12 @@ +{ + nixos = + { pkgs, ... }: + { + environment.systemPackages = with pkgs; [ + yubikey-personalization + yubikey-manager + ]; + + services.pcscd.enable = true; + }; +} diff --git a/flake.nix b/flake.nix index 10563d7..abbbe9a 100644 --- a/flake.nix +++ b/flake.nix @@ -131,20 +131,6 @@ }; }; - nixosModules = import ./modules/nixos { - inherit my-lib; - inherit (nixpkgs) lib; - } { }; - - homeManagerModules = import ./modules/home-manager { - inherit my-lib; - inherit (nixpkgs) lib; - } { }; - - nixosProfiles = import ./profiles { - inherit my-lib; - inherit (nixpkgs) lib; - } { }; }; }; } diff --git a/lib/mkHost.nix b/lib/mkHost.nix index 80c67d3..bcb28ec 100644 --- a/lib/mkHost.nix +++ b/lib/mkHost.nix @@ -8,23 +8,47 @@ name: { system, user ? null, + features ? [ ], }: let - hostConfig = ../hosts/${name}/configuration.nix; - hostHWConfig = ../hosts/${name}/hardware-configuration.nix; - hasHWConfig = builtins.pathExists hostHWConfig; + inherit (nixpkgs) lib; hasUser = user != null; - userKeys = if hasUser then import ../users/${user}/keys.nix else { }; + # path helpers + featurePath = f: ../features/${f}.nix; + userFeaturePath = u: ../features/user-${u}.nix; + hostConfig = ../hosts/${name}/configuration.nix; + hostHWConfig = ../hosts/${name}/hardware-configuration.nix; - # auto-import all nixos modules and profiles - nixosModuleList = builtins.attrValues inputs.self.nixosModules; - nixosProfileList = builtins.attrValues inputs.self.nixosProfiles; + # load feature with path check + loadFeature = + f: + assert + builtins.pathExists (featurePath f) + || throw "feature '${f}' not found at ${toString (featurePath f)}"; + import (featurePath f); - # auto-import all home-manager modules - hmModuleList = builtins.attrValues inputs.self.homeManagerModules; + loadedFeatures = map loadFeature features; + # load user feature with path check + userFeature = + if hasUser then + assert + builtins.pathExists (userFeaturePath user) + || throw "user feature 'user-${user}' not found at ${toString (userFeaturePath user)}"; + import (userFeaturePath user) + else + null; + + allFeatures = loadedFeatures ++ lib.optional (userFeature != null) userFeature; + + # extract keys from user feature for specialArgs + userKeys = if userFeature != null then (userFeature.keys or { }) else { }; + + # 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); in nixpkgs.lib.nixosSystem { inherit system; @@ -33,27 +57,23 @@ nixpkgs.lib.nixosSystem { { nixpkgs.overlays = overlays; } { nixpkgs.config.allowUnfree = true; } + { networking.hostName = name; } hostConfig ] - ++ nixpkgs.lib.optional hasHWConfig hostHWConfig - ++ nixosModuleList - ++ nixosProfileList - ++ nixpkgs.lib.optional ( - hasUser && builtins.pathExists ../users/${user}/nixos.nix - ) ../users/${user}/nixos.nix - ++ [ + ++ 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 = nixpkgs.lib.mkIf hasUser { - ${user} = import ../users/${user}/home-manager.nix; - }; - home-manager.sharedModules = hmModuleList; + home-manager.users.${user}.imports = homeMods; home-manager.extraSpecialArgs = { inherit inputs; }; } ]; - specialArgs = { inherit inputs userKeys; }; + specialArgs = { + inherit inputs userKeys user; + }; } diff --git a/modules/home-manager/claude.nix b/modules/home-manager/claude.nix deleted file mode 100644 index 1cf9c6d..0000000 --- a/modules/home-manager/claude.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: -let - packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}; -in -{ - options = { - claude = { - enable = lib.mkEnableOption "claude code"; - package = lib.mkPackageOption pkgs "claude-code" { }; - }; - }; - - config = lib.mkIf config.claude.enable { - home.packages = [ - config.claude.package - pkgs.mcp-nixos - ]; - }; -} diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix deleted file mode 100644 index 70db651..0000000 --- a/modules/home-manager/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ lib, my-lib }: args: (my-lib.autoDir ./.) diff --git a/modules/home-manager/desktop.nix b/modules/home-manager/desktop.nix deleted file mode 100644 index a3b8ff1..0000000 --- a/modules/home-manager/desktop.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: -{ - options = { - desktop.enable = lib.mkEnableOption "desktop gui applications"; - }; - - config = lib.mkIf config.desktop.enable { - home.packages = with pkgs; [ - ghostty - google-chrome - zathura - pavucontrol - bolt-launcher - libnotify - bibata-cursors - vesktop - rocketchat-desktop - telegram-desktop - slack - jellyfin-media-player - cider-2 - protonmail-bridge - ledger-live-desktop - mpv - ffmpeg - wf-recorder - wl-mirror - ]; - - home.file.".assets".source = inputs.assets; - }; -} diff --git a/modules/home-manager/dev.nix b/modules/home-manager/dev.nix deleted file mode 100644 index 49f3340..0000000 --- a/modules/home-manager/dev.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: -let - packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}; -in -{ - options = { - dev.enable = lib.mkEnableOption "development tools"; - }; - - config = lib.mkIf config.dev.enable { - home.packages = [ - pkgs.git - packages.git-linearize - packages.ggman - pkgs.go - pkgs.python3 - pkgs.mdbook - pkgs.marksman - pkgs.mdformat - pkgs.google-cloud-sdk - pkgs.google-cloud-sql-proxy - packages.ahab - pkgs.just - pkgs.presenterm - pkgs.osc - ]; - - programs.direnv = { - enable = true; - nix-direnv.enable = true; - }; - }; -} diff --git a/modules/home-manager/shell.nix b/modules/home-manager/shell.nix deleted file mode 100644 index 5a4d4f7..0000000 --- a/modules/home-manager/shell.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -{ - options = { - shell.enable = lib.mkEnableOption "shell utilities"; - }; - - config = lib.mkIf config.shell.enable { - home.packages = with pkgs; [ - starship - fzf - htop - jc - jq - openssl - pv - ripgrep - fd - tmux - ]; - }; -} diff --git a/modules/nixos/calibre.nix b/modules/nixos/calibre.nix deleted file mode 100644 index fc0f806..0000000 --- a/modules/nixos/calibre.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -{ - options = { - calibre = { - enable = lib.mkEnableOption "Calibre e-book management with Kindle support"; - }; - }; - - config = lib.mkIf config.calibre.enable { - 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"; - }) - ]; - }; -} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix deleted file mode 100644 index 70db651..0000000 --- a/modules/nixos/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ lib, my-lib }: args: (my-lib.autoDir ./.) diff --git a/modules/nixos/desktop.nix b/modules/nixos/desktop.nix deleted file mode 100644 index d402c22..0000000 --- a/modules/nixos/desktop.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -{ - options = { - desktop = { - enable = lib.mkEnableOption "base desktop environment"; - }; - }; - - config = lib.mkIf config.desktop.enable { - services.pipewire = { - enable = true; - pulse.enable = true; - }; - - hardware.bluetooth.enable = true; - services.blueman.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 - maple-mono.NF - ]; - }; -} diff --git a/modules/nixos/gnupg.nix b/modules/nixos/gnupg.nix deleted file mode 100644 index e3cec8a..0000000 --- a/modules/nixos/gnupg.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - gnupg = { - enable = lib.mkEnableOption "GnuPG agent with SSH support"; - }; - }; - - config = lib.mkIf config.gnupg.enable { - programs.gnupg.agent = { - enable = true; - enableSSHSupport = true; - enableExtraSocket = true; - }; - }; -} diff --git a/modules/nixos/greeter.nix b/modules/nixos/greeter.nix deleted file mode 100644 index e371877..0000000 --- a/modules/nixos/greeter.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - lib, - config, - pkgs, - inputs, - ... -}: -{ - options = { - greeter.enable = lib.mkEnableOption "greetd with regreet"; - }; - - config = lib.mkIf config.greeter.enable { - 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; - }; - }; - }; - }; -} diff --git a/modules/nixos/initrd-ssh.nix b/modules/nixos/initrd-ssh.nix deleted file mode 100644 index 7801356..0000000 --- a/modules/nixos/initrd-ssh.nix +++ /dev/null @@ -1,83 +0,0 @@ -{ - lib, - config, - ... -}: -let - # generate host keys for new machines: ./scripts/initrd-ssh-keygen.sh - keyDir = "/etc/secrets/initrd"; - - mkIpString = - { - address, - gateway, - netmask, - interface, - ... - }: - "${address}::${gateway}:${netmask}::${interface}:none"; -in -{ - options = { - initrd-ssh = { - enable = lib.mkEnableOption "SSH in initrd for remote LUKS unlock"; - - ip = { - enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)"; - - address = lib.mkOption { - type = lib.types.str; - example = "10.222.0.247"; - }; - - gateway = lib.mkOption { - type = lib.types.str; - example = "10.222.0.1"; - }; - - netmask = lib.mkOption { - type = lib.types.str; - default = "255.255.255.0"; - }; - - interface = lib.mkOption { - type = lib.types.str; - example = "enp5s0"; - }; - }; - - authorizedKeys = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - - networkModule = lib.mkOption { - type = lib.types.str; - example = "r8169"; - }; - }; - }; - - config = lib.mkIf config.initrd-ssh.enable { - boot.initrd.kernelModules = [ config.initrd-ssh.networkModule ]; - boot.kernelParams = lib.mkIf config.initrd-ssh.ip.enable [ - "ip=${mkIpString config.initrd-ssh.ip}" - ]; - - boot.initrd.network = { - enable = true; - ssh = { - enable = true; - port = 22; - hostKeys = [ - "${keyDir}/ssh_host_rsa_key" - "${keyDir}/ssh_host_ed25519_key" - ]; - inherit (config.initrd-ssh) authorizedKeys; - }; - postCommands = '' - echo 'cryptsetup-askpass' >> /root/.profile - ''; - }; - }; -} diff --git a/modules/nixos/localisation.nix b/modules/nixos/localisation.nix deleted file mode 100644 index 85ceab0..0000000 --- a/modules/nixos/localisation.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - localisation = { - enable = lib.mkEnableOption "localisation defaults"; - - timeZone = lib.mkOption { - type = lib.types.str; - }; - - defaultLocale = lib.mkOption { - type = lib.types.str; - }; - }; - }; - - config = lib.mkIf config.localisation.enable { - time.timeZone = config.localisation.timeZone; - i18n.defaultLocale = config.localisation.defaultLocale; - - # NOTE:(@janezicmatej) some apps (e.g. java) need TZ env var explicitly - environment.variables.TZ = config.localisation.timeZone; - }; -} diff --git a/modules/nixos/nvidia.nix b/modules/nixos/nvidia.nix deleted file mode 100644 index 85164a4..0000000 --- a/modules/nixos/nvidia.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - nvidia.enable = lib.mkEnableOption "NVIDIA GPU support"; - }; - - config = lib.mkIf config.nvidia.enable { - hardware.graphics.enable = true; - - services.xserver.videoDrivers = [ "nvidia" ]; - - hardware.nvidia = { - modesetting.enable = true; - open = true; - nvidiaSettings = true; - package = config.boot.kernelPackages.nvidiaPackages.stable; - }; - }; -} diff --git a/modules/nixos/openssh.nix b/modules/nixos/openssh.nix deleted file mode 100644 index 5a1fabd..0000000 --- a/modules/nixos/openssh.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - openssh = { - enable = lib.mkEnableOption "hardened SSH server"; - port = lib.mkOption { - type = lib.types.port; - default = 22; - }; - }; - }; - - config = lib.mkIf config.openssh.enable { - services.openssh = { - enable = true; - ports = [ config.openssh.port ]; - settings = { - PasswordAuthentication = false; - AllowUsers = null; - PermitRootLogin = "no"; - StreamLocalBindUnlink = "yes"; - }; - }; - }; -} diff --git a/modules/nixos/printing.nix b/modules/nixos/printing.nix deleted file mode 100644 index 0b9c49c..0000000 --- a/modules/nixos/printing.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - printing = { - enable = lib.mkEnableOption "CUPS printing with Avahi discovery"; - }; - }; - - config = lib.mkIf config.printing.enable { - services.printing.enable = true; - services.avahi = { - enable = true; - nssmdns4 = true; - openFirewall = true; - }; - }; -} diff --git a/modules/nixos/sway.nix b/modules/nixos/sway.nix deleted file mode 100644 index 5a9e89a..0000000 --- a/modules/nixos/sway.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -{ - - options = { - sway = { - enable = lib.mkEnableOption "enable sway module"; - cmdFlags = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - }; - }; - - config = lib.mkIf config.sway.enable { - programs.sway = { - enable = true; - package = pkgs.swayfx; - wrapperFeatures.gtk = true; - extraOptions = config.sway.cmdFlags; - 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 - ]; - }; -} diff --git a/modules/nixos/vm-9p-automount.nix b/modules/nixos/vm-9p-automount.nix deleted file mode 100644 index 2fbe427..0000000 --- a/modules/nixos/vm-9p-automount.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -let - inherit (config.vm-9p-automount) user; - inherit (config.users.users.${user}) home group; -in -{ - options = { - vm-9p-automount = { - enable = lib.mkEnableOption "auto-discover and mount 9p shares"; - - user = lib.mkOption { - type = lib.types.str; - description = "user to own the mount points"; - }; - - prefix = lib.mkOption { - type = lib.types.str; - default = "m_"; - description = "9p mount tag prefix to match"; - }; - - basePath = lib.mkOption { - type = lib.types.str; - default = "${home}/mnt"; - description = "directory to mount shares under"; - }; - }; - }; - - config = lib.mkIf config.vm-9p-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="${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 - ''; - }; - }; - }; -} diff --git a/modules/nixos/vm-guest.nix b/modules/nixos/vm-guest.nix deleted file mode 100644 index d259a03..0000000 --- a/modules/nixos/vm-guest.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -{ - options = { - vm-guest = { - enable = lib.mkEnableOption "VM guest configuration"; - headless = lib.mkOption { - type = lib.types.bool; - default = false; - description = "run without display, serial console only"; - }; - }; - }; - - config = lib.mkIf config.vm-guest.enable { - services.qemuGuest.enable = true; - services.spice-vdagentd.enable = lib.mkIf (!config.vm-guest.headless) true; - - boot.kernelParams = lib.mkIf config.vm-guest.headless [ "console=ttyS0,115200" ]; - - # 9p for host file mounting - 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 - ]; - }; -} diff --git a/modules/nixos/workstation.nix b/modules/nixos/workstation.nix deleted file mode 100644 index ba736db..0000000 --- a/modules/nixos/workstation.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -{ - options = { - workstation = { - enable = lib.mkEnableOption "workstation utilities"; - }; - }; - - config = lib.mkIf config.workstation.enable { - programs.nix-ld.enable = true; - - virtualisation.docker = { - enable = true; - logDriver = "json-file"; - }; - - services.tailscale = { - enable = true; - useRoutingFeatures = "both"; - }; - - environment.systemPackages = with pkgs; [ - smartmontools - ]; - }; -} diff --git a/modules/nixos/yubikey.nix b/modules/nixos/yubikey.nix deleted file mode 100644 index 6fde5ac..0000000 --- a/modules/nixos/yubikey.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -{ - - options = { - yubikey = { - enable = lib.mkEnableOption "enable yubikey module"; - }; - }; - - config = lib.mkIf config.yubikey.enable { - environment.systemPackages = with pkgs; [ - yubikey-personalization - yubikey-manager - ]; - - services.pcscd.enable = true; - }; -} diff --git a/modules/nixos/zsh.nix b/modules/nixos/zsh.nix deleted file mode 100644 index 039b339..0000000 --- a/modules/nixos/zsh.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - zsh = { - enable = lib.mkEnableOption "zsh with ZDOTDIR in ~/.config/zsh"; - }; - }; - - config = lib.mkIf config.zsh.enable { - programs.zsh.enable = true; - environment.etc."zshenv".text = '' - export ZDOTDIR=$HOME/.config/zsh - ''; - }; -} diff --git a/profiles/base.nix b/profiles/base.nix deleted file mode 100644 index c6531d4..0000000 --- a/profiles/base.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - profiles.base.enable = lib.mkEnableOption "base profile for all machines"; - }; - - config = lib.mkIf config.profiles.base.enable { - openssh.enable = lib.mkDefault true; - zsh.enable = lib.mkDefault true; - localisation.enable = lib.mkDefault true; - gnupg.enable = lib.mkDefault true; - }; -} diff --git a/profiles/default.nix b/profiles/default.nix deleted file mode 100644 index 70db651..0000000 --- a/profiles/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ lib, my-lib }: args: (my-lib.autoDir ./.) diff --git a/profiles/desktop.nix b/profiles/desktop.nix deleted file mode 100644 index 3836a89..0000000 --- a/profiles/desktop.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - profiles.desktop.enable = lib.mkEnableOption "desktop profile (sway, audio, printing)"; - }; - - config = lib.mkIf config.profiles.desktop.enable { - profiles.base.enable = lib.mkDefault true; - desktop.enable = lib.mkDefault true; - sway.enable = lib.mkDefault true; - greeter.enable = lib.mkDefault true; - printing.enable = lib.mkDefault true; - workstation.enable = lib.mkDefault true; - yubikey.enable = lib.mkDefault true; - calibre.enable = lib.mkDefault true; - }; -} diff --git a/profiles/server.nix b/profiles/server.nix deleted file mode 100644 index 4dfcd38..0000000 --- a/profiles/server.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - lib, - config, - ... -}: -{ - options = { - profiles.server.enable = lib.mkEnableOption "headless server profile"; - }; - - config = lib.mkIf config.profiles.server.enable { - profiles.base.enable = lib.mkDefault true; - workstation.enable = lib.mkDefault true; - }; -} diff --git a/users/matej/home-manager.nix b/users/matej/home-manager.nix deleted file mode 100644 index a9b6f7d..0000000 --- a/users/matej/home-manager.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - pkgs, - inputs, - osConfig, - ... -}: - -{ - home.stateVersion = "24.11"; - - # always-on - shell.enable = true; - dev.enable = true; - neovim = { - enable = true; - package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default; - }; - claude.enable = true; - - # desktop-conditional - desktop.enable = osConfig.desktop.enable; -} diff --git a/users/matej/keys.nix b/users/matej/keys.nix deleted file mode 100644 index 4abff00..0000000 --- a/users/matej/keys.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - sshAuthorizedKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQGLdINKzs+sEy62Pefng0bcedgU396+OryFgeH99/c janezicmatej" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDk00+Km03epQXQs+xEwwH3zcurACzkEH+kDOPBw6RQe openpgp:0xB095D449" - ]; -} diff --git a/users/matej/nixos.nix b/users/matej/nixos.nix deleted file mode 100644 index 9b2a2c0..0000000 --- a/users/matej/nixos.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -let - keys = import ./keys.nix; -in -{ - users.users.matej = { - uid = 1000; - isNormalUser = true; - home = "/home/matej"; - shell = pkgs.zsh; - extraGroups = [ - "wheel" - "docker" - ]; - openssh.authorizedKeys.keys = keys.sshAuthorizedKeys; - }; - - users.groups.matej = { - gid = 1000; - members = [ "matej" ]; - }; -}