{ lib , pkgs , config , inputs , ... }: let # force some defaults even if they were set with mkDefault already... mkForceDefault = lib.mkOverride 999; cfg = config.common; in { options.common = with lib; mkOption { type = types.submodule { options = { minimal = mkOption { type = types.bool; default = true; description = "whether this is a minimal (no DE/WM) system"; }; useNixPlugins = mkOption { type = types.bool; default = !cfg.minimal; }; binaryCache.enable = mkOption { type = types.bool; default = !cfg.minimal; description = "enable binary cache"; }; mainUsername = mkOption { type = types.str; default = "user"; description = "main user's username"; }; gettyAutologin = mkOption { type = types.bool; default = false; description = "make getty autologin to the main user"; }; resolution = mkOption { type = with types; nullOr str; default = null; description = "resolution (none/1280x720/1920x1080)"; }; }; }; default = { }; }; config = lib.mkMerge [ { nix = { # nix.channel.enable is needed for NIX_PATH to work for some reason # channel.enable = false; settings = { allowed-users = [ cfg.mainUsername ]; auto-optimise-store = true; use-xdg-base-directories = true; experimental-features = [ "ca-derivations" "flakes" "nix-command" "no-url-literals" "repl-flake" ]; }; gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; }; }; systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity"; nix.daemonCPUSchedPolicy = lib.mkDefault "idle"; nix.daemonIOSchedClass = lib.mkDefault "idle"; boot.kernelParams = lib.optionals (cfg.resolution != null) [ "consoleblank=60" ] ++ lib.optionals (cfg.resolution == "1920x1080") [ "fbcon=font:TER16x32" ]; console.font = lib.mkIf (cfg.resolution == "1920x1080" || cfg.resolution == "1366x768") { "1920x1080" = "${pkgs.terminus_font}/share/consolefonts/ter-v32n.psf.gz"; "1366x768" = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz"; }.${cfg.resolution}; boot.loader.grub = lib.mkIf (cfg.resolution != null) { gfxmodeEfi = cfg.resolution; gfxmodeBios = cfg.resolution; }; networking.usePredictableInterfaceNames = lib.mkDefault true; hardware.enableRedistributableFirmware = true; services.openssh.settings.PasswordAuthentication = false; services.tlp.settings.USB_EXCLUDE_PHONE = 1; services.tlp.settings.START_CHARGE_THRESH_BAT0 = 75; services.tlp.settings.STOP_CHARGE_THRESH_BAT0 = 80; i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; i18n.supportedLocales = lib.mkDefault [ "C.UTF-8/UTF-8" "en_US.UTF-8/UTF-8" "en_DK.UTF-8/UTF-8" ]; # ISO-8601 i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8"; environment.systemPackages = with pkgs; [ bottom git rsync tmux wget ] ++ lib.optionals (!builtins.elem pkgs.system ["armv7l-linux"]) [ kitty.terminfo foot.terminfo # rxvt-unicode-unwrapped.terminfo ]; programs.fish.enable = true; users.users.${cfg.mainUsername} = { uid = 1000; isNormalUser = true; extraGroups = [ "wheel" ]; }; # nixos-hardware uses mkDefault here, so we use slightly higher priority services.libinput.enable = mkForceDefault (!cfg.minimal); programs.fuse.userAllowOther = true; # registry is used for the new flaky nix command nix.registry = builtins.mapAttrs (_: v: { flake = v; }) (lib.filterAttrs (k: v: (k != "self" || !cfg.minimal) && v?outputs) inputs); # add import'able flake inputs (like nixpkgs) to nix path # nix path is used for old nix commands (like nix-build, nix-shell) environment.etc = lib.mapAttrs' (name: value: { name = "nix/inputs/${name}"; value.source = value.outPath or "${value}"; }) (lib.filterAttrs (k: v: (k != "self" || !cfg.minimal) && builtins.pathExists "${v}/default.nix") inputs); } (lib.mkIf cfg.gettyAutologin { # autologin once after boot # --skip-login means directly call login instead of first asking for username # (normally login asks for username too, but getty prefers to do it by itself for whatever reason) services.getty.extraArgs = [ "--skip-login" ]; services.getty.loginProgram = let lockfile = "/tmp/login-once.lock"; in with pkgs; writeShellScript "login-once" '' if [ -f '${lockfile}' ]; then exec ${shadow}/bin/login $@ else ${coreutils}/bin/touch '${lockfile}' exec ${shadow}/bin/login -f user fi ''; }) (lib.mkIf cfg.minimal { programs.fish.interactiveShellInit = '' set -gx SHELL ${pkgs.zsh}/bin/zsh set -g fish_color_autosuggestion 777 brblack set -g fish_color_command green set -g fish_color_operator white set -g fish_color_param white set -g fish_key_bindings fish_vi_key_bindings set -g fish_cursor_insert line set -g fish_cursor_replace underscore ''; # this is supposed to default to false, but it doesn't because of nixos fish module documentation.man.generateCaches = mkForceDefault false; # we don't need stuff like html files (NixOS manual and so on) on minimal machines documentation.doc.enable = lib.mkDefault false; # conflicts with bash module's mkDefault # only override on minimal systems because on non-minimal systems # my fish config doesn't work well in fb/drm console users.defaultUserShell = mkForceDefault pkgs.fish; programs.vim = { enable = lib.mkDefault true; defaultEditor = lib.mkDefault config.programs.vim.enable; package = pkgs.vim-full.customize { vimrcConfig.customRC = '' syntax on au FileType markdown set colorcolumn=73 textwidth=72 au FileType gitcommit set colorcolumn=73 au BufReadPre * set foldmethod=syntax au BufReadPost * folddoc foldopen! autocmd BufReadPost * if @% !~# '\.git[\/\\]COMMIT_EDITMSG$' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif ''; vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; { start = [ vim-sleuth ]; }; }; }; }) (lib.mkIf (!cfg.minimal) { nix.nixPath = [ "/etc/nix/inputs" ]; hardware.pulseaudio.enable = false; services.pipewire = { enable = lib.mkDefault true; alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; jack.enable = true; }; security.polkit.enable = true; security.rtkit.enable = true; services.dbus.enable = true; programs.dconf.enable = true; }) (lib.mkIf (!cfg.useNixPlugins) { nix.package = pkgs.unpatchedNixForNixPlugins; }) (lib.mkIf cfg.useNixPlugins { nix.package = pkgs.nixForNixPlugins; nix.settings.plugin-files-2 = "${pkgs.nix-plugins.override { nix = config.nix.package; }}/lib/nix/plugins/libnix-extra-builtins.so"; environment.systemPackages = with pkgs; [ unixtools.xxd ]; }) (lib.mkIf cfg.binaryCache.enable { nix.settings = { netrc-file = "/secrets/netrc"; substituters = [ "https://binarycache.pavluk.org" "https://cache.nixos.org/" ]; trusted-public-keys = [ "binarycache.pavluk.org:Vk0ms/vSqoOV2JXeNVOroc8EfilgVxCCUtpCShGIKsQ=" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; }; }) ]; }