Skip to content

Commit 5df5ff8

Browse files
committed
nixos-rebuild-ng: fix non-flake remote build evaluation
Fix: #381457.
1 parent dcb8946 commit 5df5ff8

File tree

4 files changed

+211
-13
lines changed

4 files changed

+211
-13
lines changed

pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,6 @@ def execute(argv: list[str]) -> None:
389389

390390
dry_run = action == Action.DRY_BUILD
391391
no_link = action in (Action.SWITCH, Action.BOOT)
392-
build_flags |= {"no_out_link": no_link, "dry_run": dry_run}
393-
flake_build_flags |= {"no_link": no_link, "dry_run": dry_run}
394392
rollback = bool(args.rollback)
395393

396394
def validate_image_variant(variants: ImageVariants) -> None:
@@ -444,29 +442,32 @@ def validate_image_variant(variants: ImageVariants) -> None:
444442
flake,
445443
build_host,
446444
eval_flags=flake_common_flags,
447-
flake_build_flags=flake_build_flags,
445+
flake_build_flags=flake_build_flags
446+
| {"no_link": no_link, "dry_run": dry_run},
448447
copy_flags=copy_flags,
449448
)
450449
case (_, False, None, Flake(_)):
451450
path_to_config = nix.build_flake(
452451
attr,
453452
flake,
454-
flake_build_flags=flake_build_flags,
453+
flake_build_flags=flake_build_flags
454+
| {"no_link": no_link, "dry_run": dry_run},
455455
)
456456
case (_, False, Remote(_), None):
457457
path_to_config = nix.build_remote(
458458
attr,
459459
build_attr,
460460
build_host,
461-
instantiate_flags=common_flags,
461+
realise_flags=common_flags,
462+
instantiate_flags=build_flags,
462463
copy_flags=copy_flags,
463-
build_flags=build_flags,
464464
)
465465
case (_, False, None, None):
466466
path_to_config = nix.build(
467467
attr,
468468
build_attr,
469-
build_flags=build_flags,
469+
build_flags=build_flags
470+
| {"no_out_link": no_link, "dry_run": dry_run},
470471
)
471472
case never:
472473
# should never happen, but mypy is not smart enough to

pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/nix.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def build_remote(
7777
attr: str,
7878
build_attr: BuildAttr,
7979
build_host: Remote | None,
80-
build_flags: Args | None = None,
80+
realise_flags: Args | None = None,
8181
instantiate_flags: Args | None = None,
8282
copy_flags: Args | None = None,
8383
) -> Path:
@@ -112,7 +112,7 @@ def build_remote(
112112
drv,
113113
"--add-root",
114114
remote_tmpdir / uuid4().hex,
115-
*dict_to_flags(build_flags),
115+
*dict_to_flags(realise_flags),
116116
],
117117
remote=build_host,
118118
stdout=PIPE,

pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_main.py

Lines changed: 199 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import textwrap
3+
import uuid
34
from pathlib import Path
45
from subprocess import PIPE, CompletedProcess
56
from typing import Any
@@ -390,6 +391,202 @@ def run_side_effect(args: list[str], **kwargs: Any) -> CompletedProcess[str]:
390391
)
391392

392393

394+
@patch.dict(nr.process.os.environ, {}, clear=True)
395+
@patch(get_qualified_name(nr.process.subprocess.run), autospec=True)
396+
@patch(get_qualified_name(nr.cleanup_ssh, nr), autospec=True)
397+
@patch(get_qualified_name(nr.nix.uuid4, nr.nix), autospec=True)
398+
def test_execute_nix_switch_build_target_host(
399+
mock_uuid4: Any,
400+
mock_cleanup_ssh: Any,
401+
mock_run: Any,
402+
tmp_path: Path,
403+
) -> None:
404+
config_path = tmp_path / "test"
405+
config_path.touch()
406+
407+
def run_side_effect(args: list[str], **kwargs: Any) -> CompletedProcess[str]:
408+
if args[0] == "nix":
409+
return CompletedProcess([], 0, str(config_path))
410+
elif args[0] == "nix-instantiate" and "--find-file" in args:
411+
return CompletedProcess([], 1)
412+
elif args[0] == "nix-instantiate":
413+
return CompletedProcess([], 0, str(config_path))
414+
elif args[0] == "ssh" and "nix-store" in args:
415+
return CompletedProcess([], 0, "/tmp/tmpdir/config")
416+
elif args[0] == "ssh" and "mktemp" in args:
417+
return CompletedProcess([], 0, "/tmp/tmpdir")
418+
elif args[0] == "ssh" and "readlink" in args:
419+
return CompletedProcess([], 0, str(config_path))
420+
else:
421+
return CompletedProcess([], 0)
422+
423+
mock_run.side_effect = run_side_effect
424+
mock_uuid4.return_value = uuid.UUID(int=0)
425+
426+
nr.execute(
427+
[
428+
"nixos-rebuild",
429+
"switch",
430+
"--no-flake",
431+
"--sudo",
432+
"--build-host",
433+
"user@build-host",
434+
"--target-host",
435+
"user@target-host",
436+
"--no-reexec",
437+
# https://github.com/NixOS/nixpkgs/issues/381457
438+
"-I",
439+
"nixos-config=./configuration.nix",
440+
"-I",
441+
"nixpkgs=$HOME/.nix-defexpr/channels/pinned_nixpkgs",
442+
]
443+
)
444+
445+
assert mock_run.call_count == 10
446+
mock_run.assert_has_calls(
447+
[
448+
call(
449+
[
450+
"nix-instantiate",
451+
"--find-file",
452+
"nixpkgs",
453+
"--include",
454+
"nixos-config=./configuration.nix",
455+
"--include",
456+
"nixpkgs=$HOME/.nix-defexpr/channels/pinned_nixpkgs",
457+
],
458+
check=False,
459+
stdout=PIPE,
460+
**DEFAULT_RUN_KWARGS,
461+
),
462+
call(
463+
[
464+
"nix-instantiate",
465+
"<nixpkgs/nixos>",
466+
"--attr",
467+
"config.system.build.toplevel",
468+
"--add-root",
469+
nr.tmpdir.TMPDIR_PATH / "00000000000000000000000000000000",
470+
"--include",
471+
"nixos-config=./configuration.nix",
472+
"--include",
473+
"nixpkgs=$HOME/.nix-defexpr/channels/pinned_nixpkgs",
474+
],
475+
check=True,
476+
stdout=PIPE,
477+
**DEFAULT_RUN_KWARGS,
478+
),
479+
call(
480+
["nix-copy-closure", "--to", "user@build-host", config_path],
481+
check=True,
482+
**DEFAULT_RUN_KWARGS,
483+
),
484+
call(
485+
[
486+
"ssh",
487+
*nr.process.SSH_DEFAULT_OPTS,
488+
"user@build-host",
489+
"--",
490+
"mktemp",
491+
"-d",
492+
"-t",
493+
"nixos-rebuild.XXXXX",
494+
],
495+
check=True,
496+
stdout=PIPE,
497+
**DEFAULT_RUN_KWARGS,
498+
),
499+
call(
500+
[
501+
"ssh",
502+
*nr.process.SSH_DEFAULT_OPTS,
503+
"user@build-host",
504+
"--",
505+
"nix-store",
506+
"--realise",
507+
str(config_path),
508+
"--add-root",
509+
"/tmp/tmpdir/00000000000000000000000000000000",
510+
],
511+
check=True,
512+
stdout=PIPE,
513+
**DEFAULT_RUN_KWARGS,
514+
),
515+
call(
516+
[
517+
"ssh",
518+
*nr.process.SSH_DEFAULT_OPTS,
519+
"user@build-host",
520+
"--",
521+
"readlink",
522+
"-f",
523+
"/tmp/tmpdir/config",
524+
],
525+
check=True,
526+
stdout=PIPE,
527+
**DEFAULT_RUN_KWARGS,
528+
),
529+
call(
530+
[
531+
"ssh",
532+
*nr.process.SSH_DEFAULT_OPTS,
533+
"user@build-host",
534+
"--",
535+
"rm",
536+
"-rf",
537+
"/tmp/tmpdir",
538+
],
539+
check=False,
540+
**DEFAULT_RUN_KWARGS,
541+
),
542+
call(
543+
[
544+
"nix",
545+
"copy",
546+
"--from",
547+
"ssh://user@build-host",
548+
"--to",
549+
"ssh://user@target-host",
550+
config_path,
551+
],
552+
check=True,
553+
**DEFAULT_RUN_KWARGS,
554+
),
555+
call(
556+
[
557+
"ssh",
558+
*nr.process.SSH_DEFAULT_OPTS,
559+
"user@target-host",
560+
"--",
561+
"sudo",
562+
"nix-env",
563+
"-p",
564+
"/nix/var/nix/profiles/system",
565+
"--set",
566+
str(config_path),
567+
],
568+
check=True,
569+
**DEFAULT_RUN_KWARGS,
570+
),
571+
call(
572+
[
573+
"ssh",
574+
*nr.process.SSH_DEFAULT_OPTS,
575+
"user@target-host",
576+
"--",
577+
"sudo",
578+
"env",
579+
"NIXOS_INSTALL_BOOTLOADER=0",
580+
str(config_path / "bin/switch-to-configuration"),
581+
"switch",
582+
],
583+
check=True,
584+
**DEFAULT_RUN_KWARGS,
585+
),
586+
]
587+
)
588+
589+
393590
@patch.dict(nr.process.os.environ, {}, clear=True)
394591
@patch(get_qualified_name(nr.process.subprocess.run), autospec=True)
395592
@patch(get_qualified_name(nr.cleanup_ssh, nr), autospec=True)
@@ -469,7 +666,7 @@ def run_side_effect(args: list[str], **kwargs: Any) -> CompletedProcess[str]:
469666
"sudo",
470667
"env",
471668
"NIXOS_INSTALL_BOOTLOADER=0",
472-
f"{config_path / 'bin/switch-to-configuration'}",
669+
str(config_path / "bin/switch-to-configuration"),
473670
"switch",
474671
],
475672
check=True,
@@ -493,7 +690,7 @@ def test_execute_nix_switch_flake_build_host(
493690
def run_side_effect(args: list[str], **kwargs: Any) -> CompletedProcess[str]:
494691
if args[0] == "nix" and "eval" in args:
495692
return CompletedProcess([], 0, str(config_path))
496-
if args[0] == "ssh" and "nix" in args:
693+
elif args[0] == "ssh" and "nix" in args:
497694
return CompletedProcess([], 0, str(config_path))
498695
else:
499696
return CompletedProcess([], 0)

pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_nix.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def run_wrapper_side_effect(
104104
"config.system.build.toplevel",
105105
m.BuildAttr("<nixpkgs/nixos>", "preAttr"),
106106
build_host,
107-
build_flags={"build": True},
107+
realise_flags={"realise": True},
108108
instantiate_flags={"inst": True},
109109
copy_flags={"copy": True},
110110
) == Path("/path/to/config")
@@ -147,7 +147,7 @@ def run_wrapper_side_effect(
147147
Path("/path/to/file"),
148148
"--add-root",
149149
Path("/tmp/tmpdir/00000000000000000000000000000002"),
150-
"--build",
150+
"--realise",
151151
],
152152
remote=build_host,
153153
stdout=PIPE,

0 commit comments

Comments
 (0)