staging-nixos merge for 2026-07-18 (#543276)

This commit is contained in:
K900
2026-07-18 17:07:39 +00:00
committed by GitHub
22 changed files with 174 additions and 128 deletions
+2 -1
View File
@@ -54,7 +54,8 @@ let
BUG_REPORT_URL = optionalString isNixos "https://github.com/NixOS/nixpkgs/issues";
ANSI_COLOR = optionalString isNixos "0;38;2;126;186;228";
IMAGE_ID = optionalString (config.system.image.id != null) config.system.image.id;
IMAGE_VERSION = optionalString (config.system.image.version != null) config.system.image.version;
${if config.system.image.version != null then "IMAGE_VERSION" else null} =
config.system.image.version;
VARIANT = optionalString (cfg.variantName != null) cfg.variantName;
VARIANT_ID = optionalString (cfg.variant_id != null) cfg.variant_id;
DEFAULT_HOSTNAME = config.system.nixos.distroId;
+20 -6
View File
@@ -1832,11 +1832,6 @@ let
else
config.users.motdFile;
makePAMService = name: service: {
name = "pam.d/${name}";
value.source = pkgs.writeText "${name}.pam" service.text;
};
optionalSudoConfigForSSHAgentAuth =
lib.optionalString (config.security.pam.sshAgentAuth.enable || config.security.pam.rssh.enable)
''
@@ -2648,7 +2643,26 @@ in
};
};
environment.etc = lib.mapAttrs' makePAMService enabledServices;
environment.etc =
let
# Write all pam config in a single derivation for performance
pamd =
pkgs.runCommand "pam.d"
{
__structuredAttrs = true;
services = lib.mapAttrs (_: svc: svc.text) enabledServices;
}
''
mkdir $out
for i in "''${!services[@]}"; do
printf '%s' "''${services[$i]}" > "$out/$i"
done
'';
in
lib.mapAttrs' (name: service: {
name = "pam.d/${name}";
value.source = "${pamd}/${name}";
}) enabledServices;
systemd =
lib.mkIf (lib.any (service: service.lastlog.enable) (lib.attrValues config.security.pam.services))
@@ -27,6 +27,8 @@ in
"${cfg.package}/lib/udev/fido_id"
"${cfg.package}/lib/cryptsetup/libcryptsetup-token-systemd-fido2.so"
"${pkgs.libfido2}/lib/libfido2.so.1"
# dlopened by the libpcsclite.so.1 shim, invisible to make-initrd-ng
"${lib.getLib pkgs.pcsclite}/lib/libpcsclite_real.so.1"
];
};
}
@@ -45,6 +45,7 @@
"systemd-tpm2-setup.service"
"systemd-pcrextend.socket"
"systemd-pcrextend@.service"
"systemd-pcrlogin@.service"
];
}
)
@@ -81,34 +81,6 @@ in
which is prohibited within the Nix build sandbox where the test is run.
'';
}
{
# Check every interface defined in allInterfaces.
# Containers try to create a bridge "${config.system.name}-${interfaceName}"
assertion = lib.all (
iface:
let
hostName = "${config.system.name}-${iface.name}";
in
lib.stringLength hostName <= 15
) (lib.attrValues cfg.allInterfaces);
message =
let
offendingInterfaces = lib.filter (
iface: lib.stringLength "${config.system.name}-${iface.name}" > 15
) (lib.attrValues cfg.allInterfaces);
offenderList = map (
i:
"${config.system.name}-${i.name} (${toString (lib.stringLength "${config.system.name}-${i.name}")} chars)"
) offendingInterfaces;
in
''
The following generated host interface names exceed the Linux 15-character limit:
${lib.concatStringsSep "\n " offenderList}
Please shorten 'config.system.name' or the interface names in 'virtualisation.interfaces'.
'';
}
];
virtualisation.systemd-nspawn.options = [
@@ -1,6 +1,7 @@
import contextlib
import dataclasses
import fcntl
import hashlib
import logging
import os
import signal
@@ -124,6 +125,13 @@ def mk_veth(
vlan: int,
) -> typing.Generator[None, None, None]:
host_intf_name = f"{container_name}-{container_intf_name}"
# If the names for systemd-nspawn containers are too long,
# the generated bridge interface names will surpass the
# kernel limit IFNAMSIZ (15 characters + '\0').
if len(host_intf_name) > 15:
hashed = hashlib.sha256(host_intf_name.encode()).hexdigest()[:6]
host_intf_name = f"{host_intf_name[:8]}-{hashed}"
with ensure_vlan_bridge(vlan) as bridge_name:
logger.info("creating interface %s", host_intf_name)
run_ip(
+2 -2
View File
@@ -84,7 +84,7 @@ import ../make-test-python.nix (
};
};
nodes = builtins.mapAttrs (
containers = builtins.mapAttrs (
_: val:
mkMerge [
val
@@ -97,7 +97,7 @@ import ../make-test-python.nix (
meta.maintainers = [ ];
inherit nodes;
inherit containers;
testScript = ''
start_all()
+2 -2
View File
@@ -183,7 +183,7 @@ import ../../make-test-python.nix (
};
};
nodes = builtins.mapAttrs (
containers = builtins.mapAttrs (
_: val:
mkMerge [
val
@@ -196,7 +196,7 @@ import ../../make-test-python.nix (
meta.maintainers = [ ];
inherit nodes;
inherit containers;
testScript = ''
start_all()
+2 -1
View File
@@ -13,7 +13,8 @@
}:
stdenvNoCC.mkDerivation {
name = "nixos-option";
pname = "nixos-option";
version = lib.trivial.release;
src = ./nixos-option.sh;
@@ -379,6 +379,11 @@ NIX_PATH
NIX_SSHOPTS
Additional options to be passed to ssh on the command line.
NIXOS_REBUILD_SSH_DEFAULT_OPTS
Replaces the built-in default ssh options (connection sharing via a
private _ControlMaster_ that is closed on exit). If empty, no
default options are added.
NIX_SUDOOPTS
Additional options to be passed to sudo on the command line.
@@ -240,7 +240,7 @@ def parse_args(
}
)
if args.help or args.action is None:
if args.help:
if WITH_SHELL_FILES:
r = run(["man", "8", EXECUTABLE], check=False)
parser.exit(r.returncode)
@@ -248,6 +248,11 @@ def parse_args(
parser.print_help()
parser.exit()
if args.action is None:
parser.error(
f"No valid subcommands. Type {parser.prog} --help for more information"
)
def parser_warn(msg: str) -> None:
print(f"{parser.prog}: warning: {msg}", file=sys.stderr)
@@ -26,7 +26,7 @@ from .models import (
Profile,
Remote,
)
from .process import SSH_DEFAULT_OPTS, run_wrapper
from .process import run_wrapper, ssh_default_opts
from .utils import Args, dict_to_flags
FLAKE_FLAGS: Final = ["--extra-experimental-features", "nix-command flakes"]
@@ -193,7 +193,7 @@ def copy_closure(
Also supports copying a closure from a remote to another remote."""
sshopts = os.getenv("NIX_SSHOPTS", "")
env = {"NIX_SSHOPTS": " ".join(filter(lambda x: x, [sshopts, *SSH_DEFAULT_OPTS]))}
env = {"NIX_SSHOPTS": " ".join(filter(lambda x: x, [sshopts, *ssh_default_opts()]))}
def nix_copy_closure(host: Remote, to: bool) -> None:
run_wrapper(
@@ -31,6 +31,14 @@ SSH_DEFAULT_OPTS: Final = [
]
def ssh_default_opts() -> list[str]:
"Default ssh options appended after NIX_SSHOPTS."
env = os.getenv("NIXOS_REBUILD_SSH_DEFAULT_OPTS")
if env is None:
return SSH_DEFAULT_OPTS
return shlex.split(env)
@dataclass(frozen=True)
class Remote:
host: str
@@ -133,7 +141,7 @@ def run_wrapper(
ssh_args: list[Arg] = [
"ssh",
*remote.opts,
*SSH_DEFAULT_OPTS,
*ssh_default_opts(),
remote.ssh_host(),
"--",
*[_quote_remote_arg(a) for a in remote_run_args],
@@ -282,7 +290,7 @@ def _kill_long_running_ssh_process(args: Args, remote: Remote) -> None:
[
"ssh",
*remote.opts,
*SSH_DEFAULT_OPTS,
*ssh_default_opts(),
remote.ssh_host(),
"--",
"pkill",
@@ -275,6 +275,17 @@ def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
},
)
# NIXOS_REBUILD_SSH_DEFAULT_OPTS replaces the ControlMaster defaults
monkeypatch.setenv("NIX_SSHOPTS", "-oControlPath=/run/user/1000/%C")
monkeypatch.setenv("NIXOS_REBUILD_SSH_DEFAULT_OPTS", "")
with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run:
n.copy_closure(closure, target_host)
mock_run.assert_called_with(
["nix-copy-closure", "--to", "user@target.host", closure],
append_local_env={"NIX_SSHOPTS": "-oControlPath=/run/user/1000/%C"},
)
monkeypatch.delenv("NIXOS_REBUILD_SSH_DEFAULT_OPTS")
monkeypatch.setenv("NIX_SSHOPTS", "--ssh build-target-opt")
env = {"NIX_SSHOPTS": " ".join(["--ssh build-target-opt", *p.SSH_DEFAULT_OPTS])}
with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run:
@@ -234,6 +234,52 @@ def test_remote_from_name(monkeypatch: MonkeyPatch) -> None:
)
def test_ssh_default_opts(monkeypatch: MonkeyPatch) -> None:
monkeypatch.delenv("NIXOS_REBUILD_SSH_DEFAULT_OPTS", raising=False)
assert p.ssh_default_opts() == p.SSH_DEFAULT_OPTS
monkeypatch.setenv(
"NIXOS_REBUILD_SSH_DEFAULT_OPTS", "-o ControlPath=/run/user/1000/%C"
)
assert p.ssh_default_opts() == ["-o", "ControlPath=/run/user/1000/%C"]
monkeypatch.setenv("NIXOS_REBUILD_SSH_DEFAULT_OPTS", "")
assert p.ssh_default_opts() == []
@patch.dict(
p.os.environ,
{"PATH": "/path/to/bin", "NIXOS_REBUILD_SSH_DEFAULT_OPTS": ""},
clear=True,
)
@patch("subprocess.run", autospec=True)
def test_run_wrapper_ssh_default_opts_override(mock_run: Any) -> None:
p.run_wrapper(
["test"],
check=True,
remote=m.Remote("user@localhost", ["-p", "2222"], "ssh"),
)
mock_run.assert_called_with(
[
"ssh",
"-p",
"2222",
"user@localhost",
"--",
"/bin/sh",
"-c",
"""'exec /usr/bin/env -i PATH="${PATH-}" "$@"'""",
"sh",
"test",
],
check=True,
text=True,
errors="surrogateescape",
env=None,
input=None,
)
def test_ssh_host() -> None:
ssh_remotes = {
"user@[fe80::1%25eth0]": "user@fe80::1%eth0",
@@ -8,49 +8,43 @@ from nixos_rebuild.tmpdir import MAX_TMPDIR_LENGTH, make_tmpdir
@contextlib.contextmanager
def system_tempdir(path: Path) -> typing.Generator[None]:
path.mkdir(exist_ok=True)
# `tempfile` caches the tempdir, you must clear it for it to recompute.
tempfile.tempdir = None
og_tmpdir = os.environ.get("TMPDIR")
def tempfile_tempdir(path: str) -> typing.Generator[None]:
Path(path).mkdir(exist_ok=True)
og_tmpdir = tempfile.tempdir
try:
os.environ["TMPDIR"] = str(path)
assert Path(tempfile.gettempdir()) == path
tempfile.tempdir = path
assert tempfile.gettempdir() == path
yield
finally:
if og_tmpdir is None:
del os.environ["TMPDIR"]
else:
os.environ["TMPDIR"] = og_tmpdir
tempfile.tempdir = og_tmpdir
def test_make_tmpdir() -> None:
# Basic test: whatever the default system temp dir happens to be.
tmpdir = make_tmpdir()
tmp = Path(tmpdir.name)
assert tmp.exists()
assert tmp.is_dir()
assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH
# Test with a short system temp dir. We should use it unmodified.
with system_tempdir(Path("/tmp/not-too-long")):
tmpdir = make_tmpdir()
tmp = Path(tmpdir.name)
def assert_tmpdir(tmp: Path) -> None:
assert tmp.exists()
assert tmp.is_dir()
assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH
# Basic test: whatever the default system temp dir happens to be.
tmpdir = make_tmpdir()
tmp = Path(tmpdir.name)
assert_tmpdir(tmp)
# Test with a short system temp dir. We should use it unmodified.
short_tempdir = "/tmp/not-too-long"
with tempfile_tempdir(short_tempdir):
tmpdir = make_tmpdir()
tmp = Path(tmpdir.name)
assert tmp.parent == Path(short_tempdir)
assert_tmpdir(tmp)
# Test with a long system temp dir. We should ignore
# it and fall back to something short enough for OpenSSH to
# create sockets in.
with system_tempdir(Path("/tmp/long" + ("g" * MAX_TMPDIR_LENGTH))):
with tempfile_tempdir("/tmp/long" + ("g" * MAX_TMPDIR_LENGTH)):
tmpdir = make_tmpdir()
tmp = Path(tmpdir.name)
assert tmp.exists()
assert tmp.is_dir()
assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH
assert_tmpdir(tmp)
+6 -2
View File
@@ -99,6 +99,8 @@
capstone,
valgrindSupport ? false,
valgrind-light,
brlttySupport ? !minimal,
brltty,
pluginsSupport ? !stdenv.hostPlatform.isStatic,
enableDocs ? !minimal || toolsOnly,
enableTools ? !minimal || toolsOnly,
@@ -144,11 +146,11 @@ stdenv.mkDerivation (finalAttrs: {
+ lib.optionalString nixosTestRunner "-for-vm-tests"
+ lib.optionalString toolsOnly "-utils"
+ lib.optionalString userOnly "-user";
version = "11.0.1";
version = "11.0.2";
src = fetchurl {
url = "https://download.qemu.org/qemu-${finalAttrs.version}.tar.xz";
hash = "sha256-DSNfWCAnjZFKMVXsJ6+OQljWl+qJKJVXCAfWnAy4zWQ=";
hash = "sha256-N0X26oji6H/g3IOLKx1OCncL9I4BodWhhoQqH/92zPU=";
};
depsBuildBuild = [
@@ -259,6 +261,7 @@ stdenv.mkDerivation (finalAttrs: {
++ lib.optionals u2fEmuSupport [ libu2f-emu ]
++ lib.optionals capstoneSupport [ capstone ]
++ lib.optionals valgrindSupport [ valgrind-light ]
++ lib.optionals brlttySupport [ brltty ]
++ lib.optionals stdenv.hostPlatform.isDarwin [ apple-sdk_15 ];
dontUseMesonConfigure = true; # meson's configurePhase isn't compatible with qemu build
@@ -344,6 +347,7 @@ stdenv.mkDerivation (finalAttrs: {
++ lib.optional canokeySupport "--enable-canokey"
++ lib.optional u2fEmuSupport "--enable-u2f"
++ lib.optional capstoneSupport "--enable-capstone"
++ lib.optional brlttySupport "--enable-brlapi"
++ lib.optional (!pluginsSupport) "--disable-plugins"
++ lib.optional (!enableBlobs) "--disable-install-blobs"
++ lib.optional userOnly "--disable-system"
+3 -3
View File
@@ -16,7 +16,7 @@
rustPlatform.buildRustPackage (finalAttrs: {
pname = "ruff";
version = "0.15.20";
version = "0.15.22";
__structuredAttrs = true;
@@ -24,12 +24,12 @@ rustPlatform.buildRustPackage (finalAttrs: {
owner = "astral-sh";
repo = "ruff";
tag = finalAttrs.version;
hash = "sha256-8PFMGKG15kWBpG4YXg37940WtSe/e5pQDqIe3iJRh5A=";
hash = "sha256-pa42J3M5iwSjfnuatqOOR9DEqzyVtdBbMk6JIRbu12Q=";
};
cargoBuildFlags = [ "--package=ruff" ];
cargoHash = "sha256-Bf6nsUnNMYapP0YN0SBkTPoP1czmj35tPwN1awyKhUw=";
cargoHash = "sha256-jDm0pIrq09ETU+djMLsKSFZJzRx0lKSUx6kjJ4hAkvE=";
nativeBuildInputs = [ installShellFiles ];
+3 -3
View File
@@ -17,7 +17,7 @@
rustPlatform.buildRustPackage (finalAttrs: {
pname = "ty";
version = "0.0.56";
version = "0.0.60";
__structuredAttrs = true;
src = fetchFromGitHub {
@@ -25,7 +25,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
repo = "ty";
tag = finalAttrs.version;
fetchSubmodules = true;
hash = "sha256-H5Tin3+OFSmlC2b86gPISE0ZK6+vR+ijYtJBzeyBgL4=";
hash = "sha256-9sD0xtxtw9hAOvWM0UkCARjwUe/lJw+KdqC7O1o7o6s=";
};
# For Darwin platforms, remove the integration test for file notifications,
@@ -39,7 +39,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
cargoBuildFlags = [ "--package=ty" ];
cargoHash = "sha256-suXPAZAQ4dddcHBwmdrpC4cUEs7CgTmW9Bn/v9Roe0U=";
cargoHash = "sha256-r8GvyK9gWryKdCVGzfYzDGJ2DH4H5A693aGA5DyNDZc=";
nativeBuildInputs = [ installShellFiles ];
buildInputs = [ rust-jemalloc-sys ];
@@ -25,18 +25,18 @@
"lts": true
},
"6.12": {
"version": "6.12.95",
"hash": "sha256:1xmrsi0kimirky4cailnkkrbd72pp9n8irfx6lfmss8yrcgwbs59",
"version": "6.12.96",
"hash": "sha256:1hapz6xz7plq56jc0drbzcsfcm1amlnphwbfhl0klsxkb9finbkx",
"lts": true
},
"6.18": {
"version": "6.18.38",
"hash": "sha256:0igh9xy1lk2hv2jni00dqyy27j4zqh86waw7i65ryvnmmc4fa9mc",
"version": "6.18.39",
"hash": "sha256:1c4c3wf00pb8x4kxxrmn46n7mgpnnm78sfi2jx0yg5cxmv9f79x7",
"lts": true
},
"7.1": {
"version": "7.1.3",
"hash": "sha256:1p6iknvzmd04alrf49zn8mxw863v0yzgznyckfhl4llgx1lc0hdy",
"version": "7.1.4",
"hash": "sha256:0blfl34vi6vlcdjxd7mbhskl2p7i0zpgdy707a7d6xcn24m94qqw",
"lts": false
}
}
-32
View File
@@ -16,7 +16,6 @@
# package without splicing See: https://github.com/NixOS/nixpkgs/pull/107606
pkgs,
fetchurl,
fetchpatch,
autoreconfHook,
withAudit ? false,
audit,
@@ -72,37 +71,6 @@ stdenv.mkDerivation (finalAttrs: {
# See discussion in https://github.com/NixOS/nixpkgs/pull/16966
./dont_create_privsep_path.patch
]
++ lib.optionals (lib.versionOlder finalAttrs.version "10.3") [
# See discussion in https://github.com/NixOS/nixpkgs/issues/466049 and
# https://gitlab.archlinux.org/archlinux/packaging/packages/openssh/-/issues/23
(fetchpatch {
name = "pkcs11-fetchkey-error-to-debug.patch";
url = "https://github.com/openssh/openssh-portable/commit/607f337637f2077b34a9f6f96fc24237255fe175.patch";
hunks = [ "2-" ];
hash = "sha256-rdvKL6/rwrdhGKlcmdy6fxVgJgaaRsmngX0KkShXAhQ=";
})
(fetchpatch {
name = "pkcs11-fix-pinentry.patch";
url = "https://github.com/openssh/openssh-portable/commit/434ba7684054c0637ce8f2486aaacafe65d9b8aa.patch";
# only applies to Makefile.in (which doesn't have a date header) so no hunks= needed
hash = "sha256-3JQ3IJurngXclORrfC2Bx7xvmGA6w2nIh+eZ0zd0bLY=";
})
# See discussion in https://github.com/NixOS/nixpkgs/issues/453782 and
# https://github.com/openssh/openssh-portable/pull/602
(fetchpatch {
name = "pkcs11-tests-allow-module-path.patch";
url = "https://github.com/openssh/openssh-portable/commit/5e7c3f33b2693b668ecfbac84b85f2c0c84410c2.patch";
hunks = [ "2-" ];
hash = "sha256-mGpRGXurg8K9Wp8qoojG5MQ+3sZW2XKy2z0RDXLHaEc=";
})
(fetchpatch {
name = "ssh-agent-tests-increase-timeout.patch";
url = "https://github.com/openssh/openssh-portable/commit/1fdc3c61194819c16063dc430eeb84b81bf42dcf.patch";
hunks = [ "2-" ];
hash = "sha256-b9YCOav32kY5VEvIG3W1fyD87HaQxof6Zwq9Oo+/Lac=";
})
]
++ extraPatches;
postPatch =
+13 -7
View File
@@ -14,11 +14,11 @@ in
{
openssh = common rec {
pname = "openssh";
version = "10.3p1";
version = "10.4p1";
src = fetchurl {
url = urlFor version;
hash = "sha256-VmgqNruS3PS08Bb9jsjnQFm3mo3iXBXWcNcx59GORfQ=";
hash = "sha256-72Am3SrqjVYFljjV0yYpAsiSzrqfiDlYNeDQbT+2Mjg=";
};
extraPatches = [
@@ -94,21 +94,27 @@ in
openssh_gssapi = common rec {
pname = "openssh-with-gssapi";
version = "10.3p1";
version = "10.4p1";
extraDesc = " with GSSAPI support";
src = fetchurl {
url = urlFor version;
hash = "sha256-VmgqNruS3PS08Bb9jsjnQFm3mo3iXBXWcNcx59GORfQ=";
hash = "sha256-72Am3SrqjVYFljjV0yYpAsiSzrqfiDlYNeDQbT+2Mjg=";
};
extraPatches = [
./ssh-keysign-8.5.patch
(fetchpatch {
name = "openssh-gssapi.patch";
url = "https://salsa.debian.org/ssh-team/openssh/raw/debian/1%2510.3p1-1/debian/patches/gssapi.patch";
hash = "sha256-gs5Vw4f/TDxmme1DbrtgwvWcPGGmYIWE/A4JWa551zA=";
name = "servconf-fix-gssapi.patch";
url = "https://salsa.debian.org/ssh-team/openssh/raw/debian/1%2510.4p1-1/debian/patches/servconf-fix-gssapi.patch";
hash = "sha256-ypyaoEhwxo7SYVpjMkCQnrcFgY2ouWJQlrbJy50Lidk=";
})
(fetchpatch {
name = "gssapi.patch";
url = "https://salsa.debian.org/ssh-team/openssh/raw/debian/1%2510.4p1-1/debian/patches/gssapi.patch";
hash = "sha256-K12AE4C0zMdRdMsRMQCMRIFvN+NhNvCgyt0NDZp7n24=";
})
];