From bb8556fc558f4aff6557018f554bc3317ba37a9a Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 18 Dec 2024 19:11:34 +0000 Subject: [PATCH] nixos-rebuild-ng: re-exec in the current version if re-exec to a new one fails --- .../src/nixos_rebuild/__init__.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py index 2faa0771f870..f2adccb9ed9e 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py @@ -276,7 +276,10 @@ def reexec( build_attr = BuildAttr.from_arg(args.attr, args.file) drv = nix.build(attr, build_attr, **build_flags, no_out_link=True) except CalledProcessError: - logger.warning("could not build a newer version of nixos-rebuild") + logger.warning( + "could not build a newer version of nixos-rebuild, " + + "using current version" + ) if drv: new = drv / f"bin/{EXECUTABLE}" @@ -284,14 +287,27 @@ def reexec( if new != current: logging.debug( "detected newer version of script, re-exec'ing, current=%s, new=%s", - argv[0], + current, new, ) # Manually call clean-up functions since os.execve() will replace # the process immediately cleanup_ssh() tmpdir.TMPDIR.cleanup() - os.execve(new, argv, os.environ | {"_NIXOS_REBUILD_REEXEC": "1"}) + try: + os.execve(new, argv, os.environ | {"_NIXOS_REBUILD_REEXEC": "1"}) + except Exception: + # Possible errors that we can have here: + # - Missing the binary + # - Exec format error (e.g.: another OS/CPU arch) + logger.warning( + "could not re-exec in a newer version of nixos-rebuild, " + + "using current version" + ) + logger.debug("re-exec exception", exc_info=True) + # We already run clean-up, let's re-exec in the current version + # to avoid issues + os.execve(current, argv, os.environ | {"_NIXOS_REBUILD_REEXEC": "1"}) def execute(argv: list[str]) -> None: