nixos-rebuild-ng: validate NixOS config path in target host
In #418243 we started to validate NixOS config path to avoid a nasty bug in Nix, but this doesn't work in the `--build-host` and `--target-host` case because the configuration will not be available in the local host to check if it contains a `nixos-version`. This moves the check to `--target-host` instead, that is probably the correct choice anyway. Fix #418868.
This commit is contained in:
@@ -5,7 +5,6 @@ import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError, run
|
||||
from textwrap import dedent
|
||||
from typing import Final, assert_never
|
||||
|
||||
from . import nix, tmpdir
|
||||
@@ -338,29 +337,6 @@ def validate_image_variant(image_variant: str, variants: ImageVariants) -> None:
|
||||
)
|
||||
|
||||
|
||||
def validate_nixos_config(path_to_config: Path) -> None:
|
||||
if not (path_to_config / "nixos-version").exists() and not os.environ.get(
|
||||
"NIXOS_REBUILD_I_UNDERSTAND_THE_CONSEQUENCES_PLEASE_BREAK_MY_SYSTEM"
|
||||
):
|
||||
msg = dedent(
|
||||
# the lowercase for the first letter below is proposital
|
||||
f"""
|
||||
your NixOS configuration path seems to be missing essential files.
|
||||
To avoid corrupting your current NixOS installation, the activation will abort.
|
||||
|
||||
This could be caused by Nix bug: https://github.com/NixOS/nix/issues/13367.
|
||||
This is the evaluated NixOS configuration path: {path_to_config}.
|
||||
Change the directory to somewhere else (e.g., `cd $HOME`) before trying again.
|
||||
|
||||
If you think this is a mistake, you can set the environment variable
|
||||
NIXOS_REBUILD_I_UNDERSTAND_THE_CONSEQUENCES_PLEASE_BREAK_MY_SYSTEM to 1
|
||||
and re-run the command to continue.
|
||||
Please open an issue if this is the case.
|
||||
"""
|
||||
).strip()
|
||||
raise NixOSRebuildError(msg)
|
||||
|
||||
|
||||
def execute(argv: list[str]) -> None:
|
||||
args, args_groups = parse_args(argv)
|
||||
|
||||
@@ -514,7 +490,6 @@ def execute(argv: list[str]) -> None:
|
||||
copy_flags=copy_flags,
|
||||
)
|
||||
if action in (Action.SWITCH, Action.BOOT):
|
||||
validate_nixos_config(path_to_config)
|
||||
nix.set_profile(
|
||||
profile,
|
||||
path_to_config,
|
||||
|
||||
@@ -9,6 +9,7 @@ from importlib.resources import files
|
||||
from pathlib import Path
|
||||
from string import Template
|
||||
from subprocess import PIPE, CalledProcessError
|
||||
from textwrap import dedent
|
||||
from typing import Final, Literal
|
||||
|
||||
from . import tmpdir
|
||||
@@ -613,6 +614,33 @@ def set_profile(
|
||||
sudo: bool,
|
||||
) -> None:
|
||||
"Set a path as the current active Nix profile."
|
||||
if not os.environ.get(
|
||||
"NIXOS_REBUILD_I_UNDERSTAND_THE_CONSEQUENCES_PLEASE_BREAK_MY_SYSTEM"
|
||||
):
|
||||
r = run_wrapper(
|
||||
["test", "-f", path_to_config / "nixos-version"],
|
||||
remote=target_host,
|
||||
check=False,
|
||||
)
|
||||
if r.returncode:
|
||||
msg = dedent(
|
||||
# the lowercase for the first letter below is proposital
|
||||
f"""
|
||||
your NixOS configuration path seems to be missing essential files.
|
||||
To avoid corrupting your current NixOS installation, the activation will abort.
|
||||
|
||||
This could be caused by Nix bug: https://github.com/NixOS/nix/issues/13367.
|
||||
This is the evaluated NixOS configuration path: {path_to_config}.
|
||||
Change the directory to somewhere else (e.g., `cd $HOME`) before trying again.
|
||||
|
||||
If you think this is a mistake, you can set the environment variable
|
||||
NIXOS_REBUILD_I_UNDERSTAND_THE_CONSEQUENCES_PLEASE_BREAK_MY_SYSTEM to 1
|
||||
and re-run the command to continue.
|
||||
Please open an issue if this is the case.
|
||||
"""
|
||||
).strip()
|
||||
raise NixOSRebuildError(msg)
|
||||
|
||||
run_wrapper(
|
||||
["nix-env", "-p", profile.path, "--set", path_to_config],
|
||||
remote=target_host,
|
||||
|
||||
@@ -674,6 +674,8 @@ def test_rollback_temporary_profile(tmp_path: Path) -> None:
|
||||
def test_set_profile(mock_run: Mock) -> None:
|
||||
profile_path = Path("/path/to/profile")
|
||||
config_path = Path("/path/to/config")
|
||||
mock_run.return_value = CompletedProcess([], 0)
|
||||
|
||||
n.set_profile(
|
||||
m.Profile("system", profile_path),
|
||||
config_path,
|
||||
@@ -687,6 +689,19 @@ def test_set_profile(mock_run: Mock) -> None:
|
||||
sudo=False,
|
||||
)
|
||||
|
||||
mock_run.return_value = CompletedProcess([], 1)
|
||||
|
||||
with pytest.raises(m.NixOSRebuildError) as e:
|
||||
n.set_profile(
|
||||
m.Profile("system", profile_path),
|
||||
config_path,
|
||||
target_host=None,
|
||||
sudo=False,
|
||||
)
|
||||
assert str(e.value).startswith(
|
||||
"error: your NixOS configuration path seems to be missing essential files."
|
||||
)
|
||||
|
||||
|
||||
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
|
||||
def test_switch_to_configuration_without_systemd_run(
|
||||
|
||||
Reference in New Issue
Block a user