nixos-rebuild{-ng,}: Don't eval nixos closure before validating image variants. (#395148)
This commit is contained in:
commit
b569b62759
@ -396,7 +396,7 @@ def execute(argv: list[str]) -> None:
|
||||
raise NRError(
|
||||
"please specify one of the following "
|
||||
+ "supported image variants via --image-variant:\n"
|
||||
+ "\n".join(f"- {v}" for v in variants.keys())
|
||||
+ "\n".join(f"- {v}" for v in variants)
|
||||
)
|
||||
|
||||
match action:
|
||||
@ -518,7 +518,19 @@ def execute(argv: list[str]) -> None:
|
||||
"Done. The virtual machine can be started by running", vm_path
|
||||
)
|
||||
case Action.BUILD_IMAGE:
|
||||
disk_path = path_to_config / variants[args.image_variant]
|
||||
if flake:
|
||||
image_name = nix.get_build_image_name_flake(
|
||||
flake,
|
||||
args.image_variant,
|
||||
eval_flags=flake_common_flags,
|
||||
)
|
||||
else:
|
||||
image_name = nix.get_build_image_name(
|
||||
build_attr,
|
||||
args.image_variant,
|
||||
instantiate_flags=flake_common_flags,
|
||||
)
|
||||
disk_path = path_to_config / image_name
|
||||
print_result("Done. The disk image can be found in", disk_path)
|
||||
|
||||
case Action.EDIT:
|
||||
|
@ -8,7 +8,7 @@ from typing import Any, Callable, ClassVar, Self, TypedDict, override
|
||||
|
||||
from .process import Remote, run_wrapper
|
||||
|
||||
type ImageVariants = dict[str, str]
|
||||
type ImageVariants = list[str]
|
||||
|
||||
|
||||
class NRError(Exception):
|
||||
|
@ -266,6 +266,59 @@ def find_file(file: str, nix_flags: Args | None = None) -> Path | None:
|
||||
return Path(r.stdout.strip())
|
||||
|
||||
|
||||
def get_build_image_name(
|
||||
build_attr: BuildAttr,
|
||||
image_variant: str,
|
||||
instantiate_flags: Args | None = None,
|
||||
) -> str:
|
||||
path = (
|
||||
f'"{build_attr.path.resolve()}"'
|
||||
if isinstance(build_attr.path, Path)
|
||||
else build_attr.path
|
||||
)
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix-instantiate",
|
||||
"--eval",
|
||||
"--strict",
|
||||
"--json",
|
||||
"--expr",
|
||||
textwrap.dedent(f"""
|
||||
let
|
||||
value = import {path};
|
||||
set = if builtins.isFunction value then value {{}} else value;
|
||||
in
|
||||
set.{build_attr.to_attr("config.system.build.images", image_variant, "passthru", "filePath")}
|
||||
"""),
|
||||
*dict_to_flags(instantiate_flags),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
j: str = json.loads(r.stdout.strip())
|
||||
return j
|
||||
|
||||
|
||||
def get_build_image_name_flake(
|
||||
flake: Flake,
|
||||
image_variant: str,
|
||||
eval_flags: Args | None = None,
|
||||
) -> str:
|
||||
r = run_wrapper(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--json",
|
||||
flake.to_attr(
|
||||
"config.system.build.images", image_variant, "passthru", "filePath"
|
||||
),
|
||||
*dict_to_flags(eval_flags),
|
||||
],
|
||||
stdout=PIPE,
|
||||
)
|
||||
j: str = json.loads(r.stdout.strip())
|
||||
return j
|
||||
|
||||
|
||||
def get_build_image_variants(
|
||||
build_attr: BuildAttr,
|
||||
instantiate_flags: Args | None = None,
|
||||
@ -287,7 +340,7 @@ def get_build_image_variants(
|
||||
value = import {path};
|
||||
set = if builtins.isFunction value then value {{}} else value;
|
||||
in
|
||||
builtins.mapAttrs (n: v: v.passthru.filePath) set.{build_attr.to_attr("config.system.build.images")}
|
||||
builtins.attrNames set.{build_attr.to_attr("config.system.build.images")}
|
||||
"""),
|
||||
*dict_to_flags(instantiate_flags),
|
||||
],
|
||||
@ -308,7 +361,7 @@ def get_build_image_variants_flake(
|
||||
"--json",
|
||||
flake.to_attr("config.system.build.images"),
|
||||
"--apply",
|
||||
"builtins.mapAttrs (n: v: v.passthru.filePath)",
|
||||
"builtins.attrNames",
|
||||
*dict_to_flags(eval_flags),
|
||||
],
|
||||
stdout=PIPE,
|
||||
|
@ -347,12 +347,7 @@ def test_execute_nix_build_image_flake(mock_run: Mock, tmp_path: Path) -> None:
|
||||
return CompletedProcess(
|
||||
[],
|
||||
0,
|
||||
"""
|
||||
{
|
||||
"azure": "nixos-image-azure-25.05.20250102.6df2492-x86_64-linux.vhd",
|
||||
"vmware": "nixos-image-vmware-25.05.20250102.6df2492-x86_64-linux.vmdk"
|
||||
}
|
||||
""",
|
||||
'"nixos-image-azure-25.05.20250102.6df2492-x86_64-linux.vhd"',
|
||||
)
|
||||
elif args[0] == "nix":
|
||||
return CompletedProcess([], 0, str(config_path))
|
||||
@ -372,7 +367,7 @@ def test_execute_nix_build_image_flake(mock_run: Mock, tmp_path: Path) -> None:
|
||||
]
|
||||
)
|
||||
|
||||
assert mock_run.call_count == 2
|
||||
assert mock_run.call_count == 3
|
||||
mock_run.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
@ -382,7 +377,7 @@ def test_execute_nix_build_image_flake(mock_run: Mock, tmp_path: Path) -> None:
|
||||
"--json",
|
||||
"/path/to/config#nixosConfigurations.hostname.config.system.build.images",
|
||||
"--apply",
|
||||
"builtins.mapAttrs (n: v: v.passthru.filePath)",
|
||||
"builtins.attrNames",
|
||||
],
|
||||
check=True,
|
||||
stdout=PIPE,
|
||||
@ -401,6 +396,17 @@ def test_execute_nix_build_image_flake(mock_run: Mock, tmp_path: Path) -> None:
|
||||
stdout=PIPE,
|
||||
**DEFAULT_RUN_KWARGS,
|
||||
),
|
||||
call(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--json",
|
||||
"/path/to/config#nixosConfigurations.hostname.config.system.build.images.azure.passthru.filePath",
|
||||
],
|
||||
check=True,
|
||||
stdout=PIPE,
|
||||
**DEFAULT_RUN_KWARGS,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -353,7 +353,7 @@ def test_get_build_image_variants(mock_run: Mock, tmp_path: Path) -> None:
|
||||
value = import <nixpkgs/nixos>;
|
||||
set = if builtins.isFunction value then value {} else value;
|
||||
in
|
||||
builtins.mapAttrs (n: v: v.passthru.filePath) set.config.system.build.images
|
||||
builtins.attrNames set.config.system.build.images
|
||||
"""),
|
||||
],
|
||||
stdout=PIPE,
|
||||
@ -376,7 +376,7 @@ def test_get_build_image_variants(mock_run: Mock, tmp_path: Path) -> None:
|
||||
value = import "{tmp_path}";
|
||||
set = if builtins.isFunction value then value {{}} else value;
|
||||
in
|
||||
builtins.mapAttrs (n: v: v.passthru.filePath) set.preAttr.config.system.build.images
|
||||
builtins.attrNames set.preAttr.config.system.build.images
|
||||
"""),
|
||||
"--inst-flag",
|
||||
],
|
||||
@ -411,7 +411,7 @@ def test_get_build_image_variants_flake(mock_run: Mock) -> None:
|
||||
"--json",
|
||||
"flake.nix#myAttr.config.system.build.images",
|
||||
"--apply",
|
||||
"builtins.mapAttrs (n: v: v.passthru.filePath)",
|
||||
"builtins.attrNames",
|
||||
"--eval-flag",
|
||||
],
|
||||
stdout=PIPE,
|
||||
|
@ -835,28 +835,50 @@ if [ -z "$rollback" ]; then
|
||||
"let
|
||||
value = import \"$(realpath $buildFile)\";
|
||||
set = if builtins.isFunction value then value {} else value;
|
||||
in builtins.mapAttrs (n: v: v.passthru.filePath) set.${attr:+$attr.}config.system.build.images" \
|
||||
in builtins.attrNames set.${attr:+$attr.}config.system.build.images" \
|
||||
"${extraBuildFlags[@]}"
|
||||
)"
|
||||
elif [[ -z $flake ]]; then
|
||||
variants="$(
|
||||
runCmd nix-instantiate --eval --strict --json --expr \
|
||||
"with import <nixpkgs/nixos> {}; builtins.mapAttrs (n: v: v.passthru.filePath) config.system.build.images" \
|
||||
"with import <nixpkgs/nixos> {}; builtins.attrNames config.system.build.images" \
|
||||
"${extraBuildFlags[@]}"
|
||||
)"
|
||||
else
|
||||
variants="$(
|
||||
runCmd nix "${flakeFlags[@]}" eval --json \
|
||||
"$flake#$flakeAttr.config.system.build.images" \
|
||||
--apply "builtins.mapAttrs (n: v: v.passthru.filePath)" "${evalArgs[@]}" "${extraBuildFlags[@]}"
|
||||
--apply "builtins.attrNames" "${evalArgs[@]}" "${extraBuildFlags[@]}"
|
||||
)"
|
||||
fi
|
||||
if ! echo "$variants" | jq -e --arg variant "$imageVariant" "keys | any(. == \$variant)" > /dev/null; then
|
||||
if ! echo "$variants" | jq -e --arg variant "$imageVariant" "any(. == \$variant)" > /dev/null; then
|
||||
echo -e "Please specify one of the following supported image variants via --image-variant:\n" >&2
|
||||
echo "$variants" | jq -r '. | keys | join ("\n")'
|
||||
echo "$variants" | jq -r 'join ("\n")'
|
||||
exit 1
|
||||
fi
|
||||
imageName="$(echo "$variants" | jq -r --arg variant "$imageVariant" ".[\$variant]")"
|
||||
|
||||
if [[ -z $buildingAttribute ]]; then
|
||||
imageName="$(
|
||||
runCmd nix-instantiate --eval --strict --json --expr \
|
||||
"let
|
||||
value = import \"$(realpath $buildFile)\";
|
||||
set = if builtins.isFunction value then value {} else value;
|
||||
in set.${attr:+$attr.}config.system.build.images.$imageVariant.v.passthru.filePath" \
|
||||
"${extraBuildFlags[@]}"
|
||||
)"
|
||||
elif [[ -z $flake ]]; then
|
||||
imageName="$(
|
||||
runCmd nix-instantiate --eval --strict --json --expr \
|
||||
"with import <nixpkgs/nixos> {}; config.system.build.images.$imageVariant.passthru.filePath" \
|
||||
"${extraBuildFlags[@]}"
|
||||
)"
|
||||
else
|
||||
imageName="$(
|
||||
runCmd nix "${flakeFlags[@]}" eval --json \
|
||||
"$flake#$flakeAttr.config.system.build.images.$imageVariant.passthru.filePath" \
|
||||
"${evalArgs[@]}" "${extraBuildFlags[@]}"
|
||||
)"
|
||||
fi
|
||||
|
||||
if [[ -z $buildingAttribute ]]; then
|
||||
pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.images.${imageVariant}" "${extraBuildFlags[@]}")"
|
||||
|
Loading…
Reference in New Issue
Block a user