nixos: allow more things to be disabled (#429695)

This commit is contained in:
Arian van Putten
2025-08-10 19:49:52 +02:00
committed by GitHub
10 changed files with 247 additions and 182 deletions

View File

@@ -8,41 +8,47 @@
}:
let
requiredPackages =
map (pkg: lib.setPrio ((pkg.meta.priority or lib.meta.defaultPriority) + 3) pkg)
[
pkgs.acl
pkgs.attr
pkgs.bashInteractive # bash with ncurses support
pkgs.bzip2
pkgs.coreutils-full
pkgs.cpio
pkgs.curl
pkgs.diffutils
pkgs.findutils
pkgs.gawk
pkgs.stdenv.cc.libc
pkgs.getent
pkgs.getconf
pkgs.gnugrep
pkgs.gnupatch
pkgs.gnused
pkgs.gnutar
pkgs.gzip
pkgs.xz
pkgs.less
pkgs.libcap
pkgs.ncurses
pkgs.netcat
config.programs.ssh.package
pkgs.mkpasswd
pkgs.procps
pkgs.su
pkgs.time
pkgs.util-linux
pkgs.which
pkgs.zstd
];
corePackageNames = [
"acl"
"attr"
"bashInteractive" # bash with ncurses support
"bzip2"
"coreutils-full"
"cpio"
"curl"
"diffutils"
"findutils"
"gawk"
"getent"
"getconf"
"gnugrep"
"gnupatch"
"gnused"
"gnutar"
"gzip"
"xz"
"less"
"libcap"
"ncurses"
"netcat"
"mkpasswd"
"procps"
"su"
"time"
"util-linux"
"which"
"zstd"
];
corePackages =
(map (
n:
let
pkg = pkgs.${n};
in
lib.setPrio ((pkg.meta.priority or lib.meta.defaultPriority) + 3) pkg
) corePackageNames)
++ [ pkgs.stdenv.cc.libc ];
corePackagesText = "[ ${lib.concatMapStringsSep " " (n: "pkgs.${n}") corePackageNames} ]";
defaultPackageNames = [
"perl"
@@ -80,6 +86,29 @@ in
'';
};
corePackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = corePackages;
defaultText = lib.literalMD ''
these packages, with their `meta.priority` numerically increased
(thus lowering their installation priority):
${corePackagesText}
'';
example = [ ];
description = ''
Set of core packages for a normal interactive system.
Only change this if you know what you're doing!
Like with systemPackages, packages are installed to
{file}`/run/current-system/sw`. They are
automatically available to all users, and are
automatically updated every time you rebuild the system
configuration.
'';
};
defaultPackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = defaultPackages;
@@ -151,7 +180,7 @@ in
config = {
environment.systemPackages = requiredPackages ++ config.environment.defaultPackages;
environment.systemPackages = config.environment.corePackages ++ config.environment.defaultPackages;
environment.pathsToLink = [
"/bin"

View File

@@ -23,28 +23,23 @@ let
in
{
imports = [
(lib.mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
];
options = {
programs.bash = {
/*
enable = lib.mkOption {
default = true;
description = ''
Whenever to configure Bash as an interactive shell.
Note that this tries to make Bash the default
{option}`users.defaultUserShell`,
which in turn means that you might need to explicitly
set this variable if you have another shell configured
with NixOS.
'';
type = lib.types.bool;
};
*/
enable = lib.mkOption {
default = true;
description = ''
Whenever to configure Bash as an interactive shell.
Note that this tries to make Bash the default
{option}`users.defaultUserShell`,
which in turn means that you might need to explicitly
set this variable if you have another shell configured
with NixOS.
'';
type = lib.types.bool;
};
shellAliases = lib.mkOption {
default = { };
@@ -129,121 +124,120 @@ in
};
config = # lib.mkIf cfg.enable
{
config = lib.mkIf cfg.enable {
programs.bash = {
programs.bash = {
shellAliases = builtins.mapAttrs (name: lib.mkDefault) cfge.shellAliases;
shellAliases = builtins.mapAttrs (name: lib.mkDefault) cfge.shellAliases;
shellInit = ''
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then
. ${config.system.build.setEnvironment}
fi
${cfge.shellInit}
'';
loginShellInit = cfge.loginShellInit;
interactiveShellInit = ''
# Check the window size after every command.
shopt -s checkwinsize
# Disable hashing (i.e. caching) of command lookups.
set +h
${cfg.promptInit}
${cfg.promptPluginInit}
${bashAliases}
${cfge.interactiveShellInit}
'';
};
environment.etc.profile.text = ''
# /etc/profile: DO NOT EDIT -- this file has been generated automatically.
# This file is read for login shells.
# Only execute this file once per shell.
if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi
__ETC_PROFILE_SOURCED=1
# Prevent this file from being sourced by interactive non-login child shells.
export __ETC_PROFILE_DONE=1
${cfg.shellInit}
${cfg.loginShellInit}
# Read system-wide modifications.
if test -f /etc/profile.local; then
. /etc/profile.local
shellInit = ''
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then
. ${config.system.build.setEnvironment}
fi
if [ -n "''${BASH_VERSION:-}" ]; then
. /etc/bashrc
fi
${cfge.shellInit}
'';
environment.etc.bashrc.text = ''
# /etc/bashrc: DO NOT EDIT -- this file has been generated automatically.
loginShellInit = cfge.loginShellInit;
# Only execute this file once per shell.
if [ -n "$__ETC_BASHRC_SOURCED" ] || [ -n "$NOSYSBASHRC" ]; then return; fi
__ETC_BASHRC_SOURCED=1
interactiveShellInit = ''
# Check the window size after every command.
shopt -s checkwinsize
# If the profile was not loaded in a parent process, source
# it. But otherwise don't do it because we don't want to
# clobber overridden values of $PATH, etc.
if [ -z "$__ETC_PROFILE_DONE" ]; then
. /etc/profile
fi
# Disable hashing (i.e. caching) of command lookups.
set +h
# We are not always an interactive shell.
if [ -n "$PS1" ]; then
${cfg.interactiveShellInit}
fi
${cfg.promptInit}
${cfg.promptPluginInit}
${bashAliases}
# Read system-wide modifications.
if test -f /etc/bashrc.local; then
. /etc/bashrc.local
fi
${cfge.interactiveShellInit}
'';
environment.etc.bash_logout.text = ''
# /etc/bash_logout: DO NOT EDIT -- this file has been generated automatically.
# Only execute this file once per shell.
if [ -n "$__ETC_BASHLOGOUT_SOURCED" ] || [ -n "$NOSYSBASHLOGOUT" ]; then return; fi
__ETC_BASHLOGOUT_SOURCED=1
${cfg.logout}
# Read system-wide modifications.
if test -f /etc/bash_logout.local; then
. /etc/bash_logout.local
fi
'';
# Configuration for readline in bash. We use "option default"
# priority to allow user override using both .text and .source.
environment.etc.inputrc.source = lib.mkOptionDefault ./inputrc;
users.defaultUserShell = lib.mkDefault pkgs.bashInteractive;
environment.pathsToLink = lib.optionals cfg.completion.enable [
"/etc/bash_completion.d"
"/share/bash-completion"
];
environment.shells = [
"/run/current-system/sw/bin/bash"
"/run/current-system/sw/bin/sh"
"${pkgs.bashInteractive}/bin/bash"
"${pkgs.bashInteractive}/bin/sh"
];
};
environment.etc.profile.text = ''
# /etc/profile: DO NOT EDIT -- this file has been generated automatically.
# This file is read for login shells.
# Only execute this file once per shell.
if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi
__ETC_PROFILE_SOURCED=1
# Prevent this file from being sourced by interactive non-login child shells.
export __ETC_PROFILE_DONE=1
${cfg.shellInit}
${cfg.loginShellInit}
# Read system-wide modifications.
if test -f /etc/profile.local; then
. /etc/profile.local
fi
if [ -n "''${BASH_VERSION:-}" ]; then
. /etc/bashrc
fi
'';
environment.etc.bashrc.text = ''
# /etc/bashrc: DO NOT EDIT -- this file has been generated automatically.
# Only execute this file once per shell.
if [ -n "$__ETC_BASHRC_SOURCED" ] || [ -n "$NOSYSBASHRC" ]; then return; fi
__ETC_BASHRC_SOURCED=1
# If the profile was not loaded in a parent process, source
# it. But otherwise don't do it because we don't want to
# clobber overridden values of $PATH, etc.
if [ -z "$__ETC_PROFILE_DONE" ]; then
. /etc/profile
fi
# We are not always an interactive shell.
if [ -n "$PS1" ]; then
${cfg.interactiveShellInit}
fi
# Read system-wide modifications.
if test -f /etc/bashrc.local; then
. /etc/bashrc.local
fi
'';
environment.etc.bash_logout.text = ''
# /etc/bash_logout: DO NOT EDIT -- this file has been generated automatically.
# Only execute this file once per shell.
if [ -n "$__ETC_BASHLOGOUT_SOURCED" ] || [ -n "$NOSYSBASHLOGOUT" ]; then return; fi
__ETC_BASHLOGOUT_SOURCED=1
${cfg.logout}
# Read system-wide modifications.
if test -f /etc/bash_logout.local; then
. /etc/bash_logout.local
fi
'';
# Configuration for readline in bash. We use "option default"
# priority to allow user override using both .text and .source.
environment.etc.inputrc.source = lib.mkOptionDefault ./inputrc;
users.defaultUserShell = lib.mkDefault pkgs.bashInteractive;
environment.pathsToLink = lib.optionals cfg.completion.enable [
"/etc/bash_completion.d"
"/share/bash-completion"
];
environment.shells = [
"/run/current-system/sw/bin/bash"
"/run/current-system/sw/bin/sh"
"${pkgs.bashInteractive}/bin/bash"
"${pkgs.bashInteractive}/bin/sh"
];
};
}

View File

@@ -1,4 +1,9 @@
{ config, lib, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.fuse;
@@ -7,6 +12,10 @@ in
meta.maintainers = with lib.maintainers; [ ];
options.programs.fuse = {
enable = lib.mkEnableOption "fuse" // {
default = true;
};
mountMax = lib.mkOption {
# In the C code it's an "int" (i.e. signed and at least 16 bit), but
# negative numbers obviously make no sense:
@@ -27,10 +36,30 @@ in
};
};
config = {
config = lib.mkIf cfg.enable {
environment.systemPackages = [
pkgs.fuse
pkgs.fuse3
];
security.wrappers =
let
mkSetuidRoot = source: {
setuid = true;
owner = "root";
group = "root";
inherit source;
};
in
{
fusermount = mkSetuidRoot "${lib.getBin pkgs.fuse}/bin/fusermount";
fusermount3 = mkSetuidRoot "${lib.getBin pkgs.fuse3}/bin/fusermount3";
};
environment.etc."fuse.conf".text = ''
${lib.optionalString (!cfg.userAllowOther) "#"}user_allow_other
mount_max = ${builtins.toString cfg.mountMax}
'';
};
}

View File

@@ -335,6 +335,8 @@ in
}
);
environment.corePackages = [ cfg.package ];
# SSH configuration. Slight duplication of the sshd_config
# generation in the sshd service.
environment.etc."ssh/ssh_config".text = ''

View File

@@ -266,8 +266,6 @@ in
in
{
# These are mount related wrappers that require the +s permission.
fusermount = mkSetuidRoot "${lib.getBin pkgs.fuse}/bin/fusermount";
fusermount3 = mkSetuidRoot "${lib.getBin pkgs.fuse3}/bin/fusermount3";
mount = mkSetuidRoot "${lib.getBin pkgs.util-linux}/bin/mount";
umount = mkSetuidRoot "${lib.getBin pkgs.util-linux}/bin/umount";
};

View File

@@ -317,7 +317,7 @@ in
source ${config.system.build.earlyMountScript}
'';
systemd.user = {
systemd.user = lib.mkIf config.system.activatable {
services.nixos-activation = {
description = "Run user-specific NixOS activation";
script = config.system.userActivationScripts.script;

View File

@@ -414,7 +414,9 @@ in
ln -s ${initrdPath} $out/initrd
ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out
${optionalString (config.boot.initrd.secrets != { }) ''
ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out
''}
ln -s ${config.hardware.firmware}/lib/firmware $out/firmware
'';

View File

@@ -1,7 +1,22 @@
{ pkgs, lib, ... }:
{
config = lib.mkIf (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.kexec-tools) {
config,
pkgs,
lib,
...
}:
let
cfg = config.boot.kexec;
in
{
options.boot.kexec = {
enable = lib.mkEnableOption "kexec" // {
default = lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.kexec-tools;
defaultText = lib.literalExpression ''lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.kexec-tools'';
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.kexec-tools ];
systemd.services.prepare-kexec = {

View File

@@ -461,13 +461,7 @@ in
# Add the mount helpers to the system path so that `mount' can find them.
system.fsPackages = [ pkgs.dosfstools ];
environment.systemPackages =
with pkgs;
[
fuse3
fuse
]
++ config.system.fsPackages;
environment.systemPackages = config.system.fsPackages;
environment.etc.fstab.text =
let

View File

@@ -1767,17 +1767,19 @@ in
text = cfg.hostName + "\n";
};
environment.systemPackages = [
pkgs.host
pkgs.hostname-debian
pkgs.iproute2
pkgs.iputils
]
++ optionals config.networking.wireless.enable [
pkgs.wirelesstools # FIXME: obsolete?
pkgs.iw
]
++ bridgeStp;
environment.corePackages = lib.mkOptionDefault (
[
pkgs.host
pkgs.hostname-debian
pkgs.iproute2
pkgs.iputils
]
++ optionals config.networking.wireless.enable [
pkgs.wirelesstools # FIXME: obsolete?
pkgs.iw
]
++ bridgeStp
);
# Wake-on-LAN configuration is shared by the scripted and networkd backends.
systemd.network.links = pipe interfaces [