Skip to content

Commit

Permalink
nixos-rebuild-ng: add --add-root in nix.remote_build
Browse files Browse the repository at this point in the history
Fix: #365225
  • Loading branch information
thiagokokada committed Dec 16, 2024
1 parent 927d182 commit 3c6acbe
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 13 deletions.
38 changes: 33 additions & 5 deletions pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/nix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from string import Template
from subprocess import PIPE, CalledProcessError
from typing import Final
from uuid import uuid4

from . import tmpdir
from .constants import WITH_NIX_2_18
from .models import (
Action,
Expand Down Expand Up @@ -76,24 +78,50 @@ def remote_build(
instantiate_flags: dict[str, Args] | None = None,
copy_flags: dict[str, Args] | None = None,
) -> Path:
# We need to use `--add-root` otherwise Nix will print this warning:
# > warning: you did not specify '--add-root'; the result might be removed
# > by the garbage collector
r = run_wrapper(
[
"nix-instantiate",
build_attr.path,
"--attr",
build_attr.to_attr(attr),
"--add-root",
tmpdir.TMPDIR_PATH / uuid4().hex,
*dict_to_flags(instantiate_flags or {}),
],
stdout=PIPE,
)
drv = Path(r.stdout.strip())
drv = Path(r.stdout.strip()).resolve()
copy_closure(drv, to_host=build_host, from_host=None, **(copy_flags or {}))

# Need a temporary directory in remote to use in `nix-store --add-root`
r = run_wrapper(
["nix-store", "--realise", drv, *dict_to_flags(build_flags or {})],
remote=build_host,
stdout=PIPE,
["mktemp", "-d", "-t", "nixos-rebuild.XXXXX"], remote=build_host, stdout=PIPE
)
return Path(r.stdout.strip())
remote_tmpdir = Path(r.stdout.strip())
try:
r = run_wrapper(
[
"nix-store",
"--realise",
drv,
"--add-root",
remote_tmpdir / uuid4().hex,
*dict_to_flags(build_flags or {}),
],
remote=build_host,
stdout=PIPE,
)
# When you use `--add-root`, `nix-store` returns the root and not the
# path inside Nix store
r = run_wrapper(
["readlink", "-f", r.stdout.strip()], remote=build_host, stdout=PIPE
)
return Path(r.stdout.strip())
finally:
run_wrapper(["rm", "-rf", remote_tmpdir], remote=build_host, check=False)


def remote_build_flake(
Expand Down
51 changes: 43 additions & 8 deletions pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_nix.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from unittest.mock import ANY, call, patch

import pytest
import uuid

import nixos_rebuild.models as m
import nixos_rebuild.nix as n
Expand Down Expand Up @@ -73,22 +74,36 @@ def test_build_flake(mock_run: Any) -> None:
)


@patch(
get_qualified_name(n.run_wrapper, n),
autospec=True,
return_value=CompletedProcess([], 0, stdout=" \n/path/to/file\n "),
)
def test_remote_build(mock_run: Any, monkeypatch: Any) -> None:
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
@patch(get_qualified_name(n.uuid4, n), autospec=True)
def test_remote_build(mock_uuid4: Any, mock_run: Any, monkeypatch: Any) -> None:
build_host = m.Remote("user@host", [], None)
monkeypatch.setenv("NIX_SSHOPTS", "--ssh opts")

def run_wrapper_side_effect(args, **kwargs): # type: ignore
if args[0] == "nix-instantiate":
return CompletedProcess([], 0, stdout=" \n/path/to/file\n ")
elif args[0] == "mktemp":
return CompletedProcess([], 0, stdout=" \n/tmp/tmpdir\n ")
elif args[0] == "nix-store":
return CompletedProcess([], 0, stdout=" \n/tmp/tmpdir/00000000000000000000000000000000\n ")
elif args[0] == "readlink":
return CompletedProcess([], 0, stdout=" \n/path/to/config\n ")
else:
return CompletedProcess([], 0)

mock_run.side_effect = run_wrapper_side_effect
mock_uuid4.return_value = uuid.UUID(int=0)

assert n.remote_build(
"config.system.build.toplevel",
m.BuildAttr("<nixpkgs/nixos>", "preAttr"),
build_host,
build_flags={"build": True},
instantiate_flags={"inst": True},
copy_flags={"copy": True},
) == Path("/path/to/file")
) == Path("/path/to/config")

mock_run.assert_has_calls(
[
call(
Expand All @@ -97,6 +112,8 @@ def test_remote_build(mock_run: Any, monkeypatch: Any) -> None:
"<nixpkgs/nixos>",
"--attr",
"preAttr.config.system.build.toplevel",
"--add-root",
n.tmpdir.TMPDIR_PATH / "00000000000000000000000000000000",
"--inst",
],
stdout=PIPE,
Expand All @@ -114,10 +131,28 @@ def test_remote_build(mock_run: Any, monkeypatch: Any) -> None:
},
),
call(
["nix-store", "--realise", Path("/path/to/file"), "--build"],
["mktemp", "-d", "-t", "nixos-rebuild.XXXXX"],
remote=build_host,
stdout=PIPE,
),
call(
[
"nix-store",
"--realise",
Path("/path/to/file"),
"--add-root",
Path("/tmp/tmpdir/00000000000000000000000000000000"),
"--build",
],
remote=build_host,
stdout=PIPE,
),
call(
["readlink", "-f", "/tmp/tmpdir/00000000000000000000000000000000"],
remote=build_host,
stdout=PIPE,
),
call(["rm", "-rf", Path("/tmp/tmpdir")], remote=build_host, check=False),
]
)

Expand Down

0 comments on commit 3c6acbe

Please sign in to comment.