Skip to content

Commit 13c5ed9

Browse files
authored
nixos-rebuild-ng: move more code to services.py (#420826)
2 parents 8002819 + c2ba67a commit 13c5ed9

File tree

7 files changed

+197
-155
lines changed

7 files changed

+197
-155
lines changed

pkgs/by-name/ni/nixos-rebuild-ng/package.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ python3Packages.buildPythonApplication rec {
133133
};
134134

135135
inherit (nixosTests)
136-
nixos-rebuild-install-bootloader-ng
136+
# FIXME: this test is disabled since it times out in @ofborg
137+
# nixos-rebuild-install-bootloader-ng
137138
nixos-rebuild-specialisations-ng
138139
nixos-rebuild-target-host-ng
139140
;

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

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import argparse
2-
import json
32
import logging
43
import os
54
import sys
65
from subprocess import CalledProcessError, run
76
from typing import Final, assert_never
87

9-
from . import nix
8+
from . import nix, services
109
from .constants import EXECUTABLE, WITH_NIX_2_18, WITH_REEXEC, WITH_SHELL_FILES
1110
from .models import Action, BuildAttr, Flake, Profile
1211
from .process import Remote
13-
from .services import build_and_activate_system, reexec
14-
from .utils import LogFormatter, tabulate
12+
from .utils import LogFormatter
1513

1614
logger: Final = logging.getLogger(__name__)
1715
logger.setLevel(logging.INFO)
@@ -301,7 +299,7 @@ def execute(argv: list[str]) -> None:
301299
and not args.no_reexec
302300
and not os.environ.get("_NIXOS_REBUILD_REEXEC")
303301
):
304-
reexec(argv, args, build_flags, flake_build_flags)
302+
services.reexec(argv, args, build_flags, flake_build_flags)
305303

306304
profile = Profile.from_arg(args.profile_name)
307305
target_host = Remote.from_arg(args.target_host, args.ask_sudo_password)
@@ -310,10 +308,7 @@ def execute(argv: list[str]) -> None:
310308
flake = Flake.from_arg(args.flake, target_host)
311309

312310
if can_run and not flake:
313-
nixpkgs_path = nix.find_file("nixpkgs", build_flags)
314-
rev = nix.get_nixpkgs_rev(nixpkgs_path)
315-
if nixpkgs_path and rev:
316-
(nixpkgs_path / ".version-suffix").write_text(rev)
311+
services.write_version_suffix(build_flags)
317312

318313
match action:
319314
case (
@@ -327,7 +322,7 @@ def execute(argv: list[str]) -> None:
327322
| Action.BUILD_VM
328323
| Action.BUILD_VM_WITH_BOOTLOADER
329324
):
330-
build_and_activate_system(
325+
services.build_and_activate_system(
331326
action=action,
332327
args=args,
333328
build_host=build_host,
@@ -343,32 +338,21 @@ def execute(argv: list[str]) -> None:
343338
)
344339

345340
case Action.EDIT:
346-
nix.edit(flake, flake_build_flags)
341+
services.edit(flake=flake, flake_build_flags=flake_build_flags)
347342

348343
case Action.DRY_RUN:
349344
raise AssertionError("DRY_RUN should be a DRY_BUILD alias")
350345

351346
case Action.LIST_GENERATIONS:
352-
generations = nix.list_generations(profile)
353-
if args.json:
354-
print(json.dumps(generations, indent=2))
355-
else:
356-
headers = {
357-
"generation": "Generation",
358-
"date": "Build-date",
359-
"nixosVersion": "NixOS version",
360-
"kernelVersion": "Kernel",
361-
"configurationRevision": "Configuration Revision",
362-
"specialisations": "Specialisation",
363-
"current": "Current",
364-
}
365-
print(tabulate(generations, headers=headers))
347+
services.list_generations(args=args, profile=profile)
366348

367349
case Action.REPL:
368-
if flake:
369-
nix.repl_flake(flake, flake_build_flags)
370-
else:
371-
nix.repl(build_attr, build_flags)
350+
services.repl(
351+
flake=flake,
352+
build_attr=build_attr,
353+
flake_build_flags=flake_build_flags,
354+
build_flags=build_flags,
355+
)
372356

373357
case _:
374358
assert_never(action)

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

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -242,33 +242,33 @@ def nix_copy(to_host: Remote, from_host: Remote) -> None:
242242
nix_copy_closure(to_host, to=True)
243243

244244

245-
def edit(flake: Flake | None, flake_flags: Args | None = None) -> None:
245+
def edit() -> None:
246246
"Try to find and open NixOS configuration file in editor."
247-
if flake:
248-
run_wrapper(
249-
[
250-
"nix",
251-
*FLAKE_FLAGS,
252-
"edit",
253-
*dict_to_flags(flake_flags),
254-
"--",
255-
str(flake),
256-
],
257-
check=False,
258-
)
247+
nixos_config = Path(
248+
os.getenv("NIXOS_CONFIG") or find_file("nixos-config") or "/etc/nixos"
249+
)
250+
if nixos_config.is_dir():
251+
nixos_config /= "default.nix"
252+
253+
if nixos_config.exists():
254+
run_wrapper([os.getenv("EDITOR", "nano"), nixos_config], check=False)
259255
else:
260-
if flake_flags:
261-
raise NixOSRebuildError("'edit' does not support extra Nix flags")
262-
nixos_config = Path(
263-
os.getenv("NIXOS_CONFIG") or find_file("nixos-config") or "/etc/nixos"
264-
)
265-
if nixos_config.is_dir():
266-
nixos_config /= "default.nix"
256+
raise NixOSRebuildError("cannot find NixOS config file")
267257

268-
if nixos_config.exists():
269-
run_wrapper([os.getenv("EDITOR", "nano"), nixos_config], check=False)
270-
else:
271-
raise NixOSRebuildError("cannot find NixOS config file")
258+
259+
def edit_flake(flake: Flake | None, flake_flags: Args | None = None) -> None:
260+
"Try to find and open NixOS configuration file in editor for Flake config."
261+
run_wrapper(
262+
[
263+
"nix",
264+
*FLAKE_FLAGS,
265+
"edit",
266+
*dict_to_flags(flake_flags),
267+
"--",
268+
str(flake),
269+
],
270+
check=False,
271+
)
272272

273273

274274
def find_file(file: str, nix_flags: Args | None = None) -> Path | None:

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import argparse
2+
import json
23
import logging
34
import os
45
import sys
@@ -10,7 +11,7 @@
1011
from .constants import EXECUTABLE
1112
from .models import Action, BuildAttr, Flake, ImageVariants, NixOSRebuildError, Profile
1213
from .process import Remote, cleanup_ssh
13-
from .utils import Args
14+
from .utils import Args, tabulate
1415

1516
NIXOS_REBUILD_ATTR: Final = "config.system.build.nixos-rebuild"
1617

@@ -315,3 +316,49 @@ def build_and_activate_system(
315316
common_flags=common_flags,
316317
flake_common_flags=flake_common_flags,
317318
)
319+
320+
321+
def edit(flake: Flake | None, flake_build_flags: Args | None = None) -> None:
322+
if flake:
323+
nix.edit_flake(flake, flake_build_flags)
324+
else:
325+
nix.edit()
326+
327+
328+
def list_generations(
329+
args: argparse.Namespace,
330+
profile: Profile,
331+
) -> None:
332+
generations = nix.list_generations(profile)
333+
if args.json:
334+
print(json.dumps(generations, indent=2))
335+
else:
336+
headers = {
337+
"generation": "Generation",
338+
"date": "Build-date",
339+
"nixosVersion": "NixOS version",
340+
"kernelVersion": "Kernel",
341+
"configurationRevision": "Configuration Revision",
342+
"specialisations": "Specialisation",
343+
"current": "Current",
344+
}
345+
print(tabulate(generations, headers=headers))
346+
347+
348+
def repl(
349+
flake: Flake | None,
350+
build_attr: BuildAttr,
351+
flake_build_flags: Args,
352+
build_flags: Args,
353+
) -> None:
354+
if flake:
355+
nix.repl_flake(flake, flake_build_flags)
356+
else:
357+
nix.repl(build_attr, build_flags)
358+
359+
360+
def write_version_suffix(build_flags: Args) -> None:
361+
nixpkgs_path = nix.find_file("nixpkgs", build_flags)
362+
rev = nix.get_nixpkgs_rev(nixpkgs_path)
363+
if nixpkgs_path and rev:
364+
(nixpkgs_path / ".version-suffix").write_text(rev)

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

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from unittest.mock import ANY, Mock, call, patch
99

1010
import pytest
11-
from pytest import MonkeyPatch
1211

1312
import nixos_rebuild as nr
1413
from nixos_rebuild.constants import WITH_NIX_2_18
@@ -128,92 +127,6 @@ def test_parse_args() -> None:
128127
]
129128

130129

131-
@patch.dict(os.environ, {}, clear=True)
132-
@patch("os.execve", autospec=True)
133-
@patch(get_qualified_name(nr.nix.build), autospec=True)
134-
def test_reexec(mock_build: Mock, mock_execve: Mock, monkeypatch: MonkeyPatch) -> None:
135-
monkeypatch.setattr(nr.services, "EXECUTABLE", "nixos-rebuild-ng")
136-
argv = ["/path/bin/nixos-rebuild-ng", "switch", "--no-flake"]
137-
args, _ = nr.parse_args(argv)
138-
mock_build.return_value = Path("/path")
139-
140-
nr.reexec(argv, args, {"build": True}, {"flake": True})
141-
mock_build.assert_has_calls(
142-
[
143-
call(
144-
nr.services.NIXOS_REBUILD_ATTR,
145-
nr.models.BuildAttr(ANY, ANY),
146-
{"build": True, "no_out_link": True},
147-
)
148-
]
149-
)
150-
# do not exec if there is no new version
151-
mock_execve.assert_not_called()
152-
153-
mock_build.return_value = Path("/path/new")
154-
155-
nr.reexec(argv, args, {}, {})
156-
# exec in the new version successfully
157-
mock_execve.assert_called_once_with(
158-
Path("/path/new/bin/nixos-rebuild-ng"),
159-
["/path/bin/nixos-rebuild-ng", "switch", "--no-flake"],
160-
{"_NIXOS_REBUILD_REEXEC": "1"},
161-
)
162-
163-
mock_execve.reset_mock()
164-
mock_execve.side_effect = [OSError("BOOM"), None]
165-
166-
nr.reexec(argv, args, {}, {})
167-
# exec in the previous version if the new version fails
168-
mock_execve.assert_any_call(
169-
Path("/path/bin/nixos-rebuild-ng"),
170-
["/path/bin/nixos-rebuild-ng", "switch", "--no-flake"],
171-
{"_NIXOS_REBUILD_REEXEC": "1"},
172-
)
173-
174-
175-
@patch.dict(os.environ, {}, clear=True)
176-
@patch("os.execve", autospec=True)
177-
@patch(get_qualified_name(nr.nix.build_flake), autospec=True)
178-
def test_reexec_flake(
179-
mock_build: Mock, mock_execve: Mock, monkeypatch: MonkeyPatch
180-
) -> None:
181-
monkeypatch.setattr(nr.services, "EXECUTABLE", "nixos-rebuild-ng")
182-
argv = ["/path/bin/nixos-rebuild-ng", "switch", "--flake"]
183-
args, _ = nr.parse_args(argv)
184-
mock_build.return_value = Path("/path")
185-
186-
nr.reexec(argv, args, {"build": True}, {"flake": True})
187-
mock_build.assert_called_once_with(
188-
nr.services.NIXOS_REBUILD_ATTR,
189-
nr.models.Flake(ANY, ANY),
190-
{"flake": True, "no_link": True},
191-
)
192-
# do not exec if there is no new version
193-
mock_execve.assert_not_called()
194-
195-
mock_build.return_value = Path("/path/new")
196-
197-
nr.reexec(argv, args, {}, {})
198-
# exec in the new version successfully
199-
mock_execve.assert_called_once_with(
200-
Path("/path/new/bin/nixos-rebuild-ng"),
201-
["/path/bin/nixos-rebuild-ng", "switch", "--flake"],
202-
{"_NIXOS_REBUILD_REEXEC": "1"},
203-
)
204-
205-
mock_execve.reset_mock()
206-
mock_execve.side_effect = [OSError("BOOM"), None]
207-
208-
nr.reexec(argv, args, {}, {})
209-
# exec in the previous version if the new version fails
210-
mock_execve.assert_any_call(
211-
Path("/path/bin/nixos-rebuild-ng"),
212-
["/path/bin/nixos-rebuild-ng", "switch", "--flake"],
213-
{"_NIXOS_REBUILD_REEXEC": "1"},
214-
)
215-
216-
217130
@patch.dict(
218131
os.environ,
219132
{"NIXOS_REBUILD_I_UNDERSTAND_THE_CONSEQUENCES_PLEASE_BREAK_MY_SYSTEM": "1"},

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,21 @@ def test_copy_closure(monkeypatch: MonkeyPatch) -> None:
295295

296296
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
297297
def test_edit(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) -> None:
298-
# Flake
298+
with monkeypatch.context() as mp:
299+
default_nix = tmpdir / "default.nix"
300+
default_nix.write_text("{}", encoding="utf-8")
301+
302+
mp.setenv("NIXOS_CONFIG", str(tmpdir))
303+
mp.setenv("EDITOR", "editor")
304+
305+
n.edit()
306+
mock_run.assert_called_with(["editor", default_nix], check=False)
307+
308+
309+
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
310+
def test_editd_flake(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) -> None:
299311
flake = m.Flake.parse(f"{tmpdir}#attr")
300-
n.edit(flake, {"commit_lock_file": True})
312+
n.edit_flake(flake, {"commit_lock_file": True})
301313
mock_run.assert_called_with(
302314
[
303315
"nix",
@@ -311,17 +323,6 @@ def test_edit(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) -> None:
311323
check=False,
312324
)
313325

314-
# Classic
315-
with monkeypatch.context() as mp:
316-
default_nix = tmpdir / "default.nix"
317-
default_nix.write_text("{}", encoding="utf-8")
318-
319-
mp.setenv("NIXOS_CONFIG", str(tmpdir))
320-
mp.setenv("EDITOR", "editor")
321-
322-
n.edit(None)
323-
mock_run.assert_called_with(["editor", default_nix], check=False)
324-
325326

326327
@patch(
327328
get_qualified_name(n.run_wrapper, n),

0 commit comments

Comments
 (0)