staging-nixos merge for 2026-03-12 (#499398)

This commit is contained in:
Alyssa Ross
2026-03-13 08:19:52 +00:00
committed by GitHub
8 changed files with 119 additions and 53 deletions
+23 -2
View File
@@ -104,7 +104,12 @@ in
description = "Pre-Sleep Actions";
wantedBy = [ "sleep.target" ];
before = [ "sleep.target" ];
script = cfg.powerDownCommands;
script = ''
# NixOS pre-sleep script
# config.powerManagement.powerDownCommands
${cfg.powerDownCommands}
'';
serviceConfig.Type = "oneshot";
};
@@ -114,8 +119,14 @@ in
# Pulled in by post-resume.service above
after = [ "sleep.target" ];
script = ''
# NixOS pre-resume script
/run/current-system/systemd/bin/systemctl try-restart --no-block post-resume.target
# config.powerManagement.resumeCommands
${cfg.resumeCommands}
# config.powerManagement.powerUpCommands
${cfg.powerUpCommands}
'';
serviceConfig.Type = "oneshot";
@@ -130,7 +141,12 @@ in
before = [
"shutdown.target"
];
script = cfg.powerDownCommands;
script = ''
# NixOS pre-shutdown script
# config.powerManagement.powerDownCommands
${cfg.powerDownCommands}
'';
serviceConfig.Type = "oneshot";
unitConfig.DefaultDependencies = false;
};
@@ -143,7 +159,12 @@ in
wantedBy = [ "multi-user.target" ];
restartIfChanged = false;
script = ''
# NixOS post-boot script
# config.powerManagement.bootCommands
${cfg.bootCommands}
# config.powerManagement.powerUpCommands
${cfg.powerUpCommands}
'';
serviceConfig = {
+10
View File
@@ -852,6 +852,16 @@ in
};
};
# Remove with systemd 259.4
security.polkit.extraConfig = mkIf config.security.polkit.enable ''
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.machine1.register-machine" &&
subject.user != "root") {
return polkit.Result.AUTH_ADMIN_KEEP;
}
});
'';
# run0 is supposed to authenticate the user via polkit and then run a command. Without this next
# part, run0 would fail to run the command even if authentication is successful and the user has
# permission to run the command. This next part is only enabled if polkit is enabled because the
@@ -193,13 +193,7 @@ def copy_closure(
Also supports copying a closure from a remote to another remote."""
sshopts = os.getenv("NIX_SSHOPTS", "")
# This command is always run locally and needs to keep its own environent
# while merging NIX_SSHOPTS and SSH_DEFAULT_OPTS together.
# E.g.: to preserve SSH_AUTH_SOCK
env = {
**os.environ,
"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(
@@ -210,7 +204,7 @@ def copy_closure(
host.host,
closure,
],
env=env,
append_local_env=env,
)
def nix_copy(to_host: Remote, from_host: Remote) -> None:
@@ -226,7 +220,7 @@ def copy_closure(
f"ssh://{to_host.host}",
closure,
],
env=env,
append_local_env=env,
)
match (to_host, from_host):
@@ -724,11 +718,11 @@ def _run_action_with_systemd(
try:
_run_action(
action,
path_to_config,
install_bootloader,
target_host,
sudo,
action=action,
path_to_config=path_to_config,
install_bootloader=install_bootloader,
target_host=target_host,
sudo=sudo,
prefix=[*SYSTEMD_RUN_CMD_PREFIX, f"--unit={unique_unit_name}"],
)
except KeyboardInterrupt:
@@ -767,11 +761,11 @@ def switch_to_configuration(
if _has_systemd(target_host):
_run_action_with_systemd(
action,
path_to_config,
install_bootloader,
target_host,
sudo,
action=action,
path_to_config=path_to_config,
install_bootloader=install_bootloader,
target_host=target_host,
sudo=sudo,
)
else:
logger.debug(
@@ -779,11 +773,11 @@ def switch_to_configuration(
"not working in target host"
)
_run_action(
action,
path_to_config,
install_bootloader,
target_host,
sudo,
action=action,
path_to_config=path_to_config,
install_bootloader=install_bootloader,
target_host=target_host,
sudo=sudo,
)
@@ -235,6 +235,7 @@ def run_wrapper(
*,
check: bool = True,
env: Mapping[str, EnvValue] | None = None,
append_local_env: Mapping[str, str] | None = None,
remote: Remote | None = None,
sudo: bool = False,
**kwargs: Unpack[RunKwargs],
@@ -245,12 +246,17 @@ def run_wrapper(
)
logger.debug(
"calling run with args=%r, kwargs=%r, env=%r",
"calling run with args=%r, kwargs=%r, env=%r, append_local_env=%r",
_sanitize_env_run_args(list(final_args)),
kwargs,
env,
append_local_env,
)
if append_local_env:
popen_env = dict(os.environ) if popen_env is None else dict(popen_env)
popen_env.update(append_local_env)
try:
r = subprocess.run(
final_args,
@@ -13,6 +13,7 @@ nixos-rebuild = "nixos_rebuild:main"
nixos_rebuild = ["*.nix.template"]
[tool.mypy]
files = ["nixos_rebuild", "tests"]
# `--strict` config, but explicit options to avoid breaking build when mypy is
# updated
warn_unused_configs = true
@@ -1,4 +1,3 @@
import os
import sys
import textwrap
import uuid
@@ -79,11 +78,6 @@ def test_build_flake(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) ->
)
@patch.dict(
os.environ,
{"NIX_SSHOPTS": "--ssh opts", "SSH_ASKPASS": "/run/user/1000/ssh-agent"},
clear=True,
)
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
@patch("uuid.uuid4", autospec=True)
def test_build_remote(
@@ -140,8 +134,7 @@ def test_build_remote(
"user@host",
Path("/path/to/file"),
],
env={
"SSH_ASKPASS": "/run/user/1000/ssh-agent",
append_local_env={
"NIX_SSHOPTS": " ".join(["--ssh opts", *p.SSH_DEFAULT_OPTS]),
},
),
@@ -172,11 +165,6 @@ def test_build_remote(
)
@patch.dict(
os.environ,
{"NIX_SSHOPTS": "--ssh opts", "SSH_ASKPASS": "/run/user/1000/ssh-agent"},
clear=True,
)
@patch(
get_qualified_name(n.run_wrapper, n),
autospec=True,
@@ -190,6 +178,7 @@ def test_build_remote_flake(
monkeypatch.chdir(tmpdir)
flake = m.Flake.parse("/flake.nix#hostname")
build_host = m.Remote("user@host", [], None)
monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts")
assert n.build_remote_flake(
"config.system.build.toplevel",
@@ -221,8 +210,7 @@ def test_build_remote_flake(
"user@host",
Path("/path/to/file"),
],
env={
"SSH_ASKPASS": "/run/user/1000/ssh-agent",
append_local_env={
"NIX_SSHOPTS": " ".join(["--ssh opts", *p.SSH_DEFAULT_OPTS]),
},
),
@@ -243,7 +231,6 @@ def test_build_remote_flake(
)
@patch.dict(os.environ, {}, clear=True)
def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
closure = Path("/path/to/closure")
with patch(get_qualified_name(n.run_wrapper, n), autospec=True) as mock_run:
@@ -256,7 +243,7 @@ def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
n.copy_closure(closure, target_host)
mock_run.assert_called_with(
["nix-copy-closure", "--to", "user@target.host", closure],
env={"NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS)},
append_local_env={"NIX_SSHOPTS": " ".join(p.SSH_DEFAULT_OPTS)},
)
monkeypatch.setenv("NIX_SSHOPTS", "--ssh build-opt")
@@ -264,7 +251,9 @@ def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
n.copy_closure(closure, None, build_host, {"copy_flag": True})
mock_run.assert_called_with(
["nix-copy-closure", "--copy-flag", "--from", "user@build.host", closure],
env={"NIX_SSHOPTS": " ".join(["--ssh build-opt", *p.SSH_DEFAULT_OPTS])},
append_local_env={
"NIX_SSHOPTS": " ".join(["--ssh build-opt", *p.SSH_DEFAULT_OPTS])
},
)
monkeypatch.setenv("NIX_SSHOPTS", "--ssh build-target-opt")
@@ -284,7 +273,7 @@ def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
"ssh://user@target.host",
closure,
],
env=env,
append_local_env=env,
)
@@ -29,7 +29,7 @@ def test_remote_shell_script() -> None:
@patch.dict(p.os.environ, {"PATH": "/path/to/bin"}, clear=True)
@patch("subprocess.run", autospec=True)
def test_run(mock_run: Any) -> None:
def test_run_wrapper(mock_run: Any) -> None:
p.run_wrapper(["test", "--with", "flags"], check=True)
mock_run.assert_called_with(
["test", "--with", "flags"],
@@ -64,6 +64,51 @@ def test_run(mock_run: Any) -> None:
input=None,
)
p.run_wrapper(
["test", "--with", "flags"],
check=False,
sudo=False,
append_local_env={"FOO": "bar"},
)
mock_run.assert_called_with(
[
"test",
"--with",
"flags",
],
check=False,
text=True,
errors="surrogateescape",
env={
"FOO": "bar",
"PATH": "/path/to/bin",
},
input=None,
)
p.run_wrapper(
["test", "--with", "flags"],
check=False,
sudo=False,
env={"PATH": "/"},
append_local_env={"FOO": "bar"},
)
mock_run.assert_called_with(
[
"test",
"--with",
"flags",
],
check=False,
text=True,
errors="surrogateescape",
env={
"FOO": "bar",
"PATH": "/",
},
input=None,
)
p.run_wrapper(
["test", "--with", "some flags"],
check=True,
@@ -1,7 +1,7 @@
{
"testing": {
"version": "7.0-rc2",
"hash": "sha256:11zw5rck5hg1w8jjjgc8hjmswzdv4k1wqnkg4zmzxg0ds447cd0b",
"version": "7.0-rc3",
"hash": "sha256:1f9rkk1h1m84yglxgicasmdgywim7zc2ndn0ya7wm27kc8f3whw5",
"lts": false
},
"6.1": {
@@ -30,13 +30,13 @@
"lts": true
},
"6.18": {
"version": "6.18.16",
"hash": "sha256:1qwfsbr315c6qh3hnqmyjwjcj0h8j3w56hbrxnrx3h849lgw08ag",
"version": "6.18.17",
"hash": "sha256:03gqbb33lbh6ip4dvsr645kjhj1jxzaqc8mqsp6mrg4h0nmrgzrb",
"lts": true
},
"6.19": {
"version": "6.19.6",
"hash": "sha256:051fq8mkb7sf3m24a45cacr73fmpljfdn0pgjh0qrxhl6bvkz7sd",
"version": "6.19.7",
"hash": "sha256:0blmc3gmqyg1fj390gjz3brjznyn7s9m4f6w107ypygmhf5qgh82",
"lts": false
}
}