diff --git a/nixos/doc/manual/development/running-nixos-tests-interactively.section.md b/nixos/doc/manual/development/running-nixos-tests-interactively.section.md index 121abd51c804..78df8d3d77c7 100644 --- a/nixos/doc/manual/development/running-nixos-tests-interactively.section.md +++ b/nixos/doc/manual/development/running-nixos-tests-interactively.section.md @@ -43,6 +43,11 @@ test script). ## Shell access to VMs in interactive mode {#sec-nixos-test-shell-access} +::: {.warning} +Using `shell_interact()` is deprecated. Use the +[interactive SSH backdoor](#sec-nixos-test-ssh-access) instead. +::: + The function `.shell_interact()` grants access to a shell running inside a virtual machine. To use it, replace `` with the name of a virtual machine defined in the test, for example: `machine.shell_interact()`. diff --git a/nixos/doc/manual/release-notes/rl-2611.section.md b/nixos/doc/manual/release-notes/rl-2611.section.md index 3ec838a06844..01507338ec5f 100644 --- a/nixos/doc/manual/release-notes/rl-2611.section.md +++ b/nixos/doc/manual/release-notes/rl-2611.section.md @@ -75,6 +75,8 @@ - `komodo` has been updated to the v2 release line (2.x). See the [upstream v1 → v2 upgrade guide](https://github.com/moghtech/komodo/releases/tag/v2.0.0). +- The `shell_interact()` function on interactive runs of NixOS VM tests has been deprecated. Use the SSH backdoor instead. + - `security.run0.enableSudoAlias` now uses the `run0-sudo-shim` instead of a shell-script to improve compatibility. - With `system.etc.overlay.mutable = false`, NixOS now ships an empty `/etc/machine-id` in the image. Previously the file was absent and systemd logged `System cannot boot: Missing /etc/machine-id and /etc/ is read-only` while `ConditionFirstBoot` fired on every boot. With this change, systemd now overlays a transient ID from `/run/machine-id` for the session, and `systemd-machine-id-commit.service` has `ConditionFirstBoot` so it writes the machine-id through to a persistent backing file when one is bind-mounted over `/etc/machine-id`. To persist the machine-id across reboots, bind-mount a writable file containing `uninitialized` over `/etc/machine-id` from the initrd, or set `systemd.machine_id=` on the kernel command line (use `systemd.machine_id=firmware` to derive a stable ID on hardware that supports it). diff --git a/nixos/lib/test-driver/src/test_driver/__init__.py b/nixos/lib/test-driver/src/test_driver/__init__.py index 62c2a6073e6c..774f3afdf49e 100644 --- a/nixos/lib/test-driver/src/test_driver/__init__.py +++ b/nixos/lib/test-driver/src/test_driver/__init__.py @@ -6,6 +6,7 @@ import warnings from pathlib import Path import ptpython.ipython +import ptpython.repl from colorama import Fore, Style from test_driver.debug import Debug, DebugAbstract, DebugNop @@ -174,6 +175,7 @@ def main() -> None: if args.interactive: history_dir = os.getcwd() history_path = os.path.join(history_dir, ".nixos-test-history") + ptpython.repl.enable_deprecation_warnings() ptpython.ipython.embed( user_ns=driver.test_symbols(), history_filename=history_path, diff --git a/nixos/lib/test-driver/src/test_driver/machine/__init__.py b/nixos/lib/test-driver/src/test_driver/machine/__init__.py index 7a572b44367f..9ddf7fa2d947 100644 --- a/nixos/lib/test-driver/src/test_driver/machine/__init__.py +++ b/nixos/lib/test-driver/src/test_driver/machine/__init__.py @@ -908,6 +908,7 @@ class QemuMachine(BaseMachine): return (rc, output.decode(errors="replace")) + @warnings.deprecated("Use the SSH backdoor instead") def shell_interact(self, address: str | None = None) -> None: """ Allows you to directly interact with the guest shell. This should @@ -1450,6 +1451,7 @@ class NspawnMachine(BaseMachine): machine_sock_path: Path machine_sock: socket.socket | None + notify_thread: threading.Thread | None @staticmethod def machine_name_from_start_command(start_command: str) -> str: @@ -1480,6 +1482,12 @@ class NspawnMachine(BaseMachine): self.start_command = start_command self.process = None + self.notify_thread = None + # State maintained by the notify-socket drainer thread (see + # `_drain_notify_socket`). Guarded by `_notify_lock`. + self._notify_lock = threading.Lock() + self._notify_ready = False + self._notify_leader_pid: int | None = None self.machine_sock_path = self.tmp_dir / f"{self.name}-nspawn.sock" @@ -1514,43 +1522,76 @@ class NspawnMachine(BaseMachine): def is_up(self) -> bool: return self.process is not None - def _poll_socket(self) -> tuple[bool, int | None]: - """Non-blocking check of container status via socket. - Returns (is_ready, leader_pid). + def _drain_notify_socket(self) -> None: + """Continuously drain the container's `sd_notify` socket (NOTIFY_SOCKET) + for the whole lifetime of the container, recording readiness and the + leader PID as they arrive. + + Draining must not stop after boot: the container's PID 1 re-sends + `READY=1` on every `systemctl daemon-reexec` (the same Manager.Reexecute + that switch-to-configuration issues on a systemd change). If nothing + reads the socket, its receive buffer fills and PID 1 blocks in + `sendmsg()` to NOTIFY_SOCKET while re-executing -- it never finishes + re-initializing, and every later `systemctl` call inside the container + hangs or fails with `Transport endpoint is not connected`. """ assert self.machine_sock is not None - ready = False - leader_pid = None - try: - data, _ = self.machine_sock.recvfrom(4096) - msg = data.decode() - for line in msg.splitlines(): + sock = self.machine_sock + proc = self.process + assert proc is not None + # Bound the thread to the container's lifetime: on + # `wait_for_shutdown()` only non-None `proc.poll()` ends the loop. + # On exit of PID 1, any datagrams still queued are stale, so drop them. + while proc.poll() is None: + try: + # Block (with a timeout so we notice the container exiting) + # rather than busy-poll; we just need to keep the buffer empty. + sock.settimeout(0.5) + data, _ = sock.recvfrom(4096) + except (TimeoutError, BlockingIOError): + continue + except OSError: + break + ready = False + leader_pid = None + for line in data.decode(errors="replace").splitlines(): if line == "READY=1": ready = True if line.startswith("X_NSPAWN_LEADER_PID="): leader_pid = int(line.split("=")[1]) - except OSError: - pass - return ready, leader_pid + if ready or leader_pid is not None: + with self._notify_lock: + if ready: + self._notify_ready = True + if leader_pid is not None: + self._notify_leader_pid = leader_pid @cached_property def get_systemd_process(self) -> int: - """Block until startup is complete and return the PID of the container's systemd process.""" - assert self.process is not None + """Block until startup is complete and return the PID of the container's systemd process. - container_pid: int | None = None - is_ready = False + Readiness and the leader PID are reported over NOTIFY_SOCKET, which is + drained by `_drain_notify_socket` (started in `start()`); we just wait + for that thread to record both. + """ + assert self.process is not None start_time = time.monotonic() last_warning = start_time delay = 0.01 max_delay = 0.5 - while not is_ready or container_pid is None: - # Poll the socket until we have the container leader PID + # Poll the socket until we have the container leader PID + while True: if self.process.poll() is not None: raise MachineError("systemd-nspawn process exited unexpectedly") + with self._notify_lock: + is_ready = self._notify_ready + container_pid = self._notify_leader_pid + if is_ready and container_pid is not None: + return container_pid + # Print periodic warnings every 10s so the user knows we aren't deadlocked now = time.monotonic() if now - last_warning > 10.0: @@ -1559,18 +1600,8 @@ class NspawnMachine(BaseMachine): ) last_warning = now - # Poll and update our local tracking variables - ready_now, pid_now = self._poll_socket() - if ready_now: - is_ready = True - if pid_now: - container_pid = pid_now - - if not (is_ready and container_pid): - time.sleep(delay) - delay = min(delay * 2, max_delay) - - return container_pid + time.sleep(delay) + delay = min(delay * 2, max_delay) def _execute( self, @@ -1684,7 +1715,6 @@ class NspawnMachine(BaseMachine): self.machine_sock = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_DGRAM) self.machine_sock.bind(str(self.machine_sock_path)) - self.machine_sock.setblocking(False) self.process = subprocess.Popen( [self.start_command], @@ -1700,6 +1730,13 @@ class NspawnMachine(BaseMachine): self.log(f"systemd-nspawn running (pid {self.process.pid})") + # Keep the notify socket drained for the container's whole lifetime, so + # PID 1 never blocks re-sending `READY=1` on `daemon-reexec`. + self.notify_thread = threading.Thread( + target=self._drain_notify_socket, daemon=True + ) + self.notify_thread.start() + journal_thread = threading.Thread(target=self._stream_journal, daemon=True) journal_thread.start() diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 310d43533c31..2a92d910a25a 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -152,6 +152,7 @@ in ssh-backdoor = runTestOn [ "x86_64-linux" ] ./nixos-test-driver/ssh-backdoor.nix; console-log = runTest ./nixos-test-driver/console-log.nix; containers = runTest ./nixos-test-driver/containers.nix; + nspawn-daemon-reexec-dbus = runTest ./nspawn-daemon-reexec-dbus.nix; skip-typecheck = runTest ./nixos-test-driver/skip-typecheck.nix; options-doc-regression = import ./nixos-test-driver/options-doc-regression.nix { inherit pkgs; }; driver-timeout = diff --git a/nixos/tests/nspawn-daemon-reexec-dbus.nix b/nixos/tests/nspawn-daemon-reexec-dbus.nix new file mode 100644 index 000000000000..115deb778bb5 --- /dev/null +++ b/nixos/tests/nspawn-daemon-reexec-dbus.nix @@ -0,0 +1,79 @@ +# Regression test for an nspawn-only systemd re-exec failure that broke D-Bus. +# +# Demonstrates `systemctl show` keeps working on `daemon-reexec`. +# +# Trigger: `systemctl daemon-reexec` issues a D-Bus `Manager.Reexecute`, like +# `switch-to-configuration-ng` on a systemd package change. +# +# Root cause: inside nspawn test containers PID 1 re-send `READY=1` on the +# `NOTIFY_SOCKET` on re-exec. The test driver stopped draining that socket +# after boot, so until drained its receive buffer filled and `systemctl` hung / +# errored `Failed to connect to bus: Transport endpoint is not connected`. +{ ... }: +{ + name = "nspawn-daemon-reexec-dbus"; + + # `containers.` => systemd-nspawn machine (vs `nodes.` => QEMU). + # An empty container boots full systemd + D-Bus, which is all we need. + containers.machine = { }; + + testScript = # python + '' + import re + + BUS_BROKEN = re.compile( + r"Transport endpoint is not connected|Failed to connect to bus" + ) + + # Without the fix the notify socket's receive buffer fills after 10 + # undrained `READY=1` resends, so PID 1 blocks then. + REEXECS = 10 + + + def bus_broken(): + """Whether the in-container D-Bus is unusable. A broken bus prints a + transport error or hangs until `timeout` kills it (status 124); both + count as broken.""" + status, out = machine.execute( + "timeout 10 systemctl show -p ActiveState --value " + "multi-user.target 2>&1", + check_return=False, + timeout=20, + ) + return status != 0 or bool(BUS_BROKEN.search(out)), status, out + + + machine.start() + machine.wait_for_unit("multi-user.target", timeout=120) + + # Pre-reexec sanity: the bus works and shows no break. + broken, status, out = bus_broken() + assert not broken, ( + f"bus already broken before any reexec: status={status} out={out!r}" + ) + machine.log(f"pre-reexec sanity OK: {out.strip()!r}") + + broke_at = None + for i in range(1, REEXECS + 1): + # The same D-Bus Manager.Reexecute that switch-to-configuration issues + # on a systemd change. + machine.execute( + "timeout 30 systemctl daemon-reexec", + check_return=False, + timeout=45, + ) + broken, status, out = bus_broken() + machine.log(f"[reexec {i}] status={status} out={out.strip()!r}") + if broken: + broke_at = i + break + + assert broke_at is None, ( + f"nspawn D-Bus broke after daemon-reexec #{broke_at} of {REEXECS} " + "(systemctl hung or returned a bus transport error). The re-exec'd " + "PID 1 never finished re-initialising -- the test driver stopped " + "draining the notify socket, so PID 1's READY=1 resend blocked. " + "Never observed on QEMU." + ) + ''; +} diff --git a/pkgs/by-name/dt/dtc/package.nix b/pkgs/by-name/dt/dtc/package.nix index ae581df6a81c..17fe8f5653e3 100644 --- a/pkgs/by-name/dt/dtc/package.nix +++ b/pkgs/by-name/dt/dtc/package.nix @@ -49,8 +49,6 @@ stdenv.mkDerivation (finalAttrs: { } ); - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - nativeBuildInputs = [ meson ninja diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py index d848709ef8f1..7ba809d4cb9c 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py @@ -25,7 +25,7 @@ SSH_DEFAULT_OPTS: Final = [ "-o", "ControlMaster=auto", "-o", - f"ControlPath={tmpdir.TMPDIR_PATH / 'ssh-%C'}", + f"ControlPath={tmpdir.SSH_CONTROL_PATH}", "-o", "ControlPersist=60", ] diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/tmpdir.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/tmpdir.py index 9db6e310a4d2..1df30dcad7eb 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/tmpdir.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/tmpdir.py @@ -1,38 +1,86 @@ import logging +import os from pathlib import Path -from tempfile import TemporaryDirectory, gettempdir +from tempfile import TemporaryDirectory from typing import Final logger: Final = logging.getLogger(__name__) +# The Linux kernel hardcodes a limit of 108 bytes for Unix sockets [0], +# but that includes one NULL byte at the very end, so the logical max +# length is 107 bytes. +# [0]: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/uapi/linux/un.h?h=v6.18.37#n7 +LINUX_MAX_SOCKET_LENGTH: Final = 107 -# Very long tmp dirs lead to "too long for Unix domain socket" -# SSH ControlPath errors. Especially macOS sets long TMPDIR paths. -# This is also required for Linux, if the user tries to build -# from inside a shell using `--target-host`, which will cause -# ssh to fail with "ControlPath too long" +# OpenSSH expands %C to `conn_hash_hex` [0], +# which is the result of calling `ssh_connection_hash` [1], +# which computes a sha1 digest [2], +# which is 20 bytes long [3]. +# which gets hex encoded [4] to double that length [5]. # -# The constant is based on a worst case example FQDN, e.g.: -# `ec2-123-123-123-123.ap-southeast-2.compute.amazonaws.com` (56 bytes). -# The `ControlPath` can maximum be 108 bytes. Given the prefix -# that is used for the tempdir, ie. `nixos-rebuild.47i6dz8c` (22 bytes), -# we have 30 bytes left to work with. -# This should be fine for the usual temp folders: -# /tmp/tmp.7hBqN2Fm5H (19) -# /var/tmp/tmp.7hBqN2Fm5H (23) -# /run/user/1000/tmp.7hBqN2Fm5H (29) +# [0]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/sshconnect.h#L70 +# [1]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/ssh.c#L1464-L1465 +# [2]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/readconf.c#L345 +# [3]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/openbsd-compat/sha1.h#L15 +# [4]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/readconf.c#L360 +# [5]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/misc.c#L1627 +OPENSSH_PERCENT_C_LENGTH: Final = 40 + +# OpenSSH adds a suffix to the given control path [0]. +# There's 1 character for a `.` separator, followed by 16 random characters [1]. +# [0]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/mux.c#L1348 +# [1]: https://github.com/openssh/openssh-portable/blob/V_10_3_P1/mux.c#L1324 +OPENSSH_CONTROL_PATH_SUFFIX_LENGTH: Final = 1 + 16 + +# Carefully compute a maximum allowed length for a tmpdir, otherwise ssh crashes with errors like this: +# > unix_listener: path "/home/runner/work/_temp/nixos-rebuild.aw8hzmq7/ssh-ea7c10de83787b1dec3f06ef20ee26b38c6bb0a5.x9MDykk4gmASsl3R" +# > too long for Unix domain socket +# +# The full path to our tmpdir must be short enough for the resulting Unix domain +# sockets that OpenSSH creates to fit within `LINUX_MAX_SOCKET_LENGTH`. +# It's common for system configured temp dirs to be more +# than a few characters: +# - macOS sets long TMPDIR paths. +# - Nix dev shells set a longer TMPDIR +# - GitHub actions set TMPDIR to something like `/home/runner/work/_temp`. +# +# Breaking down the socket path into its component pieces: +# +# /home/runner/work/_temp/nixos-rebuild.aw8hzmq7/ssh-ea7c10de83787b1dec3f06ef20ee26b38c6bb0a5.x9MDykk4gmASsl3R +# |-------------- TMPDIR ----------------------|^|----------------- ssh-%C -----------------||---------------| +# | | +# Note the path separator character. OPENSSH_CONTROL_PATH_SUFFIX_LENGTH +# +MAX_TMPDIR_LENGTH: Final = ( + LINUX_MAX_SOCKET_LENGTH + - 1 # Path separator between tmpdir and the socket name. + # Keep the following in sync with `SSH_CONTROL_PATH`. + - len("ssh-") + - OPENSSH_PERCENT_C_LENGTH + - OPENSSH_CONTROL_PATH_SUFFIX_LENGTH +) + + def make_tmpdir() -> TemporaryDirectory[str]: - tmp = gettempdir() - if len(tmp) >= 30: + prefix = "nixos-rebuild." + tmpdir = TemporaryDirectory(prefix=prefix) + if len(os.fsencode(tmpdir.name)) > MAX_TMPDIR_LENGTH: + short_tmpdir = TemporaryDirectory(prefix=prefix, dir="/tmp") logger.debug( - "tempdir '%s' exceeds 30 bytes limit, defaulting to /tmp instead", - tmp, + "tempdir '%s' exceeds %s bytes limit, defaulting to '%s' instead", + tmpdir, + MAX_TMPDIR_LENGTH, + short_tmpdir, ) - return TemporaryDirectory(prefix="nixos-rebuild.", dir="/tmp") + tmpdir.cleanup() + return short_tmpdir - return TemporaryDirectory(prefix="nixos-rebuild.") + return tmpdir TMPDIR: Final = make_tmpdir() TMPDIR_PATH: Final = Path(TMPDIR.name) + +# Keep this in sync with `MAX_TMPDIR_LENGTH`! +SSH_CONTROL_PATH: Final = str(TMPDIR_PATH / "ssh-%C") diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_tmpdir.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_tmpdir.py new file mode 100644 index 000000000000..5735e7b979f3 --- /dev/null +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/tests/test_tmpdir.py @@ -0,0 +1,56 @@ +import contextlib +import os +import tempfile +import typing +from pathlib import Path + +from nixos_rebuild.tmpdir import MAX_TMPDIR_LENGTH, make_tmpdir + + +@contextlib.contextmanager +def system_tempdir(path: Path) -> typing.Generator[None]: + path.mkdir(exist_ok=True) + + # `tempfile` caches the tempdir, you must clear it for it to recompute. + tempfile.tempdir = None + + og_tmpdir = os.environ.get("TMPDIR") + + try: + os.environ["TMPDIR"] = str(path) + assert Path(tempfile.gettempdir()) == path + yield + finally: + if og_tmpdir is None: + del os.environ["TMPDIR"] + else: + os.environ["TMPDIR"] = og_tmpdir + + +def test_make_tmpdir() -> None: + # Basic test: whatever the default system temp dir happens to be. + tmpdir = make_tmpdir() + tmp = Path(tmpdir.name) + assert tmp.exists() + assert tmp.is_dir() + assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH + + # Test with a short system temp dir. We should use it unmodified. + with system_tempdir(Path("/tmp/not-too-long")): + tmpdir = make_tmpdir() + tmp = Path(tmpdir.name) + + assert tmp.exists() + assert tmp.is_dir() + assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH + + # Test with a long system temp dir. We should ignore + # it and fall back to something short enough for OpenSSH to + # create sockets in. + with system_tempdir(Path("/tmp/long" + ("g" * MAX_TMPDIR_LENGTH))): + tmpdir = make_tmpdir() + tmp = Path(tmpdir.name) + + assert tmp.exists() + assert tmp.is_dir() + assert len(os.fsencode(str(tmp))) <= MAX_TMPDIR_LENGTH diff --git a/pkgs/by-name/sa/savepagenow/package.nix b/pkgs/by-name/sa/savepagenow/package.nix index 230db6ed68d7..4a7f20ade31e 100644 --- a/pkgs/by-name/sa/savepagenow/package.nix +++ b/pkgs/by-name/sa/savepagenow/package.nix @@ -16,8 +16,6 @@ python3Packages.buildPythonApplication (finalAttrs: { sha256 = "sha256-ztM1g71g8SN1LTyFF7sxaLhC3+nVsC9fJwfYPjkUsdE="; }; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - build-system = with python3Packages; [ setuptools-scm ]; dependencies = with python3Packages; [ diff --git a/pkgs/by-name/sk/skypilot/package.nix b/pkgs/by-name/sk/skypilot/package.nix index 71df3b03526f..7dca34a57abf 100644 --- a/pkgs/by-name/sk/skypilot/package.nix +++ b/pkgs/by-name/sk/skypilot/package.nix @@ -46,8 +46,6 @@ python3Packages.buildPythonApplication (finalAttrs: { writableTmpDirAsHomeHook ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - postPatch = '' substituteInPlace sky/setup_files/dependencies.py --replace-fail 'casbin' 'pycasbin' substituteInPlace pyproject.toml --replace-fail 'buildkite-test-collector' "" diff --git a/pkgs/by-name/ty/ty/package.nix b/pkgs/by-name/ty/ty/package.nix index 187daf164c61..b8a81fe0f97a 100644 --- a/pkgs/by-name/ty/ty/package.nix +++ b/pkgs/by-name/ty/ty/package.nix @@ -17,7 +17,7 @@ rustPlatform.buildRustPackage (finalAttrs: { pname = "ty"; - version = "0.0.54"; + version = "0.0.56"; __structuredAttrs = true; src = fetchFromGitHub { @@ -25,7 +25,7 @@ rustPlatform.buildRustPackage (finalAttrs: { repo = "ty"; tag = finalAttrs.version; fetchSubmodules = true; - hash = "sha256-hbVH0dCUHkWKD9IG/CYhYI4TfLgpk++tPOkCD36eVSg="; + hash = "sha256-H5Tin3+OFSmlC2b86gPISE0ZK6+vR+ijYtJBzeyBgL4="; }; # For Darwin platforms, remove the integration test for file notifications, @@ -39,7 +39,7 @@ rustPlatform.buildRustPackage (finalAttrs: { cargoBuildFlags = [ "--package=ty" ]; - cargoHash = "sha256-Bf6nsUnNMYapP0YN0SBkTPoP1czmj35tPwN1awyKhUw="; + cargoHash = "sha256-suXPAZAQ4dddcHBwmdrpC4cUEs7CgTmW9Bn/v9Roe0U="; nativeBuildInputs = [ installShellFiles ]; buildInputs = [ rust-jemalloc-sys ]; diff --git a/pkgs/by-name/un/unifont/package.nix b/pkgs/by-name/un/unifont/package.nix index 30b81d2741be..804f326281cf 100644 --- a/pkgs/by-name/un/unifont/package.nix +++ b/pkgs/by-name/un/unifont/package.nix @@ -9,21 +9,21 @@ stdenv.mkDerivation (finalAttrs: { pname = "unifont"; - version = "17.0.04"; + version = "17.0.05"; otf = fetchurl { url = "mirror://gnu/unifont/unifont-${finalAttrs.version}/unifont-${finalAttrs.version}.otf"; - hash = "sha256-0fZkqXU7nGt/81cSh0njK10+7pDHwDYYNj+r1Do5tbc="; + hash = "sha256-hXAaubHiUe4W9N8AsT8i6sMR1yt9q0J6fZdf5/UGRwI="; }; pcf = fetchurl { url = "mirror://gnu/unifont/unifont-${finalAttrs.version}/unifont-${finalAttrs.version}.pcf.gz"; - hash = "sha256-21hNQMglGdfPrx8VWP3lMT+/Guga7uoKbm72MqXjxJY="; + hash = "sha256-kld9gZ/QPhsu7IcqtFghB4qed4B6+Gp9IbbaOP72HNw="; }; bdf = fetchurl { url = "mirror://gnu/unifont/unifont-${finalAttrs.version}/unifont-${finalAttrs.version}.bdf.gz"; - hash = "sha256-mi3kgmOIJCdxEhx/4A5BJSPDGDGLjuOOa+bNRU5+yAI="; + hash = "sha256-2wERwGbt/nWD8Nd62+y7pGPwBkOjfcO5ZRrpNJVDSH8="; }; nativeBuildInputs = [ diff --git a/pkgs/development/python-modules/amd-aiter/default.nix b/pkgs/development/python-modules/amd-aiter/default.nix index 021d39ae5836..fdd23f47e654 100644 --- a/pkgs/development/python-modules/amd-aiter/default.nix +++ b/pkgs/development/python-modules/amd-aiter/default.nix @@ -90,7 +90,6 @@ buildPythonPackage (finalAttrs: { BUILD_TARGET = "rocm"; PREBUILD_KERNELS = "0"; ROCM_PATH = "${rocmPackages.clr}"; - SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; }; build-system = [ diff --git a/pkgs/development/python-modules/cvxopt/default.nix b/pkgs/development/python-modules/cvxopt/default.nix index 6e1fd821ef09..9d9b77eb7da9 100644 --- a/pkgs/development/python-modules/cvxopt/default.nix +++ b/pkgs/development/python-modules/cvxopt/default.nix @@ -45,7 +45,6 @@ buildPythonPackage rec { CVXOPT_BUILD_DSDP = "0"; CVXOPT_SUITESPARSE_LIB_DIR = "${lib.getLib suitesparse}/lib"; CVXOPT_SUITESPARSE_INC_DIR = "${lib.getDev suitesparse}/include"; - SETUPTOOLS_SCM_PRETEND_VERSION = version; } // lib.optionalAttrs withGsl { CVXOPT_BUILD_GSL = "1"; diff --git a/pkgs/development/python-modules/fastjet/default.nix b/pkgs/development/python-modules/fastjet/default.nix index 943823bc22f2..da7a6cb1a206 100644 --- a/pkgs/development/python-modules/fastjet/default.nix +++ b/pkgs/development/python-modules/fastjet/default.nix @@ -76,8 +76,6 @@ buildPythonPackage rec { pytestCheckHook ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - meta = { description = "Jet-finding in the Scikit-HEP ecosystem"; homepage = "https://github.com/scikit-hep/fastjet"; diff --git a/pkgs/development/python-modules/flash-attn-4/default.nix b/pkgs/development/python-modules/flash-attn-4/default.nix index d17f7bd27c80..aa38a657141a 100644 --- a/pkgs/development/python-modules/flash-attn-4/default.nix +++ b/pkgs/development/python-modules/flash-attn-4/default.nix @@ -36,8 +36,6 @@ buildPythonPackage (finalAttrs: { # The top-level setup.py builds the classic compiled flash-attn and excludes flash_attn.cute. sourceRoot = "${finalAttrs.src.name}/flash_attn/cute"; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - build-system = [ setuptools setuptools-scm diff --git a/pkgs/development/python-modules/formulaic/default.nix b/pkgs/development/python-modules/formulaic/default.nix index d0c49c3c3e0c..eabc06ccbe82 100644 --- a/pkgs/development/python-modules/formulaic/default.nix +++ b/pkgs/development/python-modules/formulaic/default.nix @@ -29,6 +29,7 @@ buildPythonPackage rec { hash = "sha256-C4IUuyxBbW2DUxF4at8/736ZMmVZrFRRp+RxrJfmLkY="; }; + # project uses a version-file that is not present in tagged releases env.SETUPTOOLS_SCM_PRETEND_VERSION = version; build-system = [ diff --git a/pkgs/development/python-modules/geoarrow-c/default.nix b/pkgs/development/python-modules/geoarrow-c/default.nix index 8537e250bbe9..98d374798857 100644 --- a/pkgs/development/python-modules/geoarrow-c/default.nix +++ b/pkgs/development/python-modules/geoarrow-c/default.nix @@ -41,8 +41,6 @@ buildPythonPackage rec { rm -v ./bootstrap.py ''; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - nativeCheckInputs = [ pytestCheckHook pyarrow diff --git a/pkgs/development/python-modules/geoarrow-pandas/default.nix b/pkgs/development/python-modules/geoarrow-pandas/default.nix index 057522cc5437..e0753524a633 100644 --- a/pkgs/development/python-modules/geoarrow-pandas/default.nix +++ b/pkgs/development/python-modules/geoarrow-pandas/default.nix @@ -25,8 +25,6 @@ buildPythonPackage rec { build-system = [ setuptools-scm ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - dependencies = [ geoarrow-pyarrow geoarrow-types diff --git a/pkgs/development/python-modules/geoarrow-pyarrow/default.nix b/pkgs/development/python-modules/geoarrow-pyarrow/default.nix index 75cf29cddb3d..e3017464cafe 100644 --- a/pkgs/development/python-modules/geoarrow-pyarrow/default.nix +++ b/pkgs/development/python-modules/geoarrow-pyarrow/default.nix @@ -51,8 +51,6 @@ buildPythonPackage rec { pyarrow-hotfix ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - nativeCheckInputs = [ pytestCheckHook ]; diff --git a/pkgs/development/python-modules/geoarrow-types/default.nix b/pkgs/development/python-modules/geoarrow-types/default.nix index a9ff0259fe30..75bb2a0ed51e 100644 --- a/pkgs/development/python-modules/geoarrow-types/default.nix +++ b/pkgs/development/python-modules/geoarrow-types/default.nix @@ -22,8 +22,6 @@ buildPythonPackage rec { build-system = [ setuptools-scm ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - nativeCheckInputs = [ pytestCheckHook ]; diff --git a/pkgs/development/python-modules/icalendar-compatibility/default.nix b/pkgs/development/python-modules/icalendar-compatibility/default.nix index 0bd535a1d91f..fdbfe2ad54a4 100644 --- a/pkgs/development/python-modules/icalendar-compatibility/default.nix +++ b/pkgs/development/python-modules/icalendar-compatibility/default.nix @@ -46,8 +46,6 @@ buildPythonPackage rec { pythonImportsCheck = [ "icalendar_compatibility" ]; - # env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - meta = { homepage = "https://icalendar-compatibility.readthedocs.io/en/latest/"; changelog = "https://icalendar-compatibility.readthedocs.io/en/latest/changes.html"; diff --git a/pkgs/development/python-modules/linearmodels/default.nix b/pkgs/development/python-modules/linearmodels/default.nix index d67690e48774..5245dd64f9a3 100644 --- a/pkgs/development/python-modules/linearmodels/default.nix +++ b/pkgs/development/python-modules/linearmodels/default.nix @@ -34,6 +34,10 @@ buildPythonPackage (finalAttrs: { hash = "sha256-/unFszNGaEPsoXDtaS3tsLnsX4A6e7Y88O8pDrf4nKc="; }; + # tries to execute linearmodels/_build/git_version.py at build time + # which would require keeping the .git tree + env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; + postPatch = '' substituteInPlace pyproject.toml \ --replace-fail "setuptools_scm>=9.2.0,<10" "setuptools_scm" @@ -46,8 +50,6 @@ buildPythonPackage (finalAttrs: { setuptools-scm ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - dependencies = [ formulaic mypy-extensions diff --git a/pkgs/development/python-modules/nipreps-versions/default.nix b/pkgs/development/python-modules/nipreps-versions/default.nix index b746e0026ecb..163acc5cbfb2 100644 --- a/pkgs/development/python-modules/nipreps-versions/default.nix +++ b/pkgs/development/python-modules/nipreps-versions/default.nix @@ -20,8 +20,6 @@ buildPythonPackage rec { hash = "sha256-B2wtLurzgk59kTooH51a2dewK7aEyA0dAm64Wp+tqhM="; }; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - nativeBuildInputs = [ flit-scm setuptools-scm diff --git a/pkgs/development/python-modules/niworkflows/default.nix b/pkgs/development/python-modules/niworkflows/default.nix index ef715c969fb3..102570ee3581 100644 --- a/pkgs/development/python-modules/niworkflows/default.nix +++ b/pkgs/development/python-modules/niworkflows/default.nix @@ -52,6 +52,9 @@ buildPythonPackage (finalAttrs: { hash = "sha256-AMUOiIL33kcJtlKT+L5QwcUh8mBBkf80uzOQZFKDauo="; }; + # fails to determine the version automatically + env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; + pythonRelaxDeps = [ "traits" ]; build-system = [ @@ -84,8 +87,6 @@ buildPythonPackage (finalAttrs: { transforms3d ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - nativeCheckInputs = [ pytest-cov-stub pytest-env diff --git a/pkgs/development/python-modules/pandera/default.nix b/pkgs/development/python-modules/pandera/default.nix index 711093d7e89a..94d0c990ca52 100644 --- a/pkgs/development/python-modules/pandera/default.nix +++ b/pkgs/development/python-modules/pandera/default.nix @@ -59,8 +59,6 @@ buildPythonPackage (finalAttrs: { setuptools-scm ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - dependencies = [ packaging pydantic diff --git a/pkgs/development/python-modules/pillow-jpls/default.nix b/pkgs/development/python-modules/pillow-jpls/default.nix index c7553ab64007..94d490ff54e2 100644 --- a/pkgs/development/python-modules/pillow-jpls/default.nix +++ b/pkgs/development/python-modules/pillow-jpls/default.nix @@ -30,8 +30,6 @@ buildPythonPackage (finalAttrs: { hash = "sha256-Rc4/S8BrYoLdn7eHDBaoUt1Qy+h0TMAN5ixCAuRmfPU="; }; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - dontUseCmakeConfigure = true; postPatch = '' diff --git a/pkgs/development/python-modules/pyfatfs/default.nix b/pkgs/development/python-modules/pyfatfs/default.nix index 0d1914c58efa..4b66ee31a406 100644 --- a/pkgs/development/python-modules/pyfatfs/default.nix +++ b/pkgs/development/python-modules/pyfatfs/default.nix @@ -40,8 +40,6 @@ buildPythonPackage rec { pytest-mock ]; - env.SETUPTOOLS_SCM_PRETEND_VERSION = version; - passthru.updateScript = gitUpdater { rev-prefix = "v"; }; meta = { diff --git a/pkgs/development/python-modules/riscv-model/default.nix b/pkgs/development/python-modules/riscv-model/default.nix index 459d9f670303..7794af60b127 100644 --- a/pkgs/development/python-modules/riscv-model/default.nix +++ b/pkgs/development/python-modules/riscv-model/default.nix @@ -20,8 +20,6 @@ buildPythonPackage (finalAttrs: { hash = "sha256-H4N9Z8aK/xV5gCCdsL+oiR+XQfYtCfBRBGLqvuztX+o="; }; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - build-system = [ setuptools setuptools-scm diff --git a/pkgs/development/python-modules/trsfile/default.nix b/pkgs/development/python-modules/trsfile/default.nix index c33bbb3e1050..83ae9c24b837 100644 --- a/pkgs/development/python-modules/trsfile/default.nix +++ b/pkgs/development/python-modules/trsfile/default.nix @@ -20,8 +20,6 @@ buildPythonPackage (finalAttrs: { pyproject = true; - env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version; - build-system = [ setuptools setuptools-scm diff --git a/pkgs/os-specific/linux/kernel/kernels-org.json b/pkgs/os-specific/linux/kernel/kernels-org.json index b1bbd932a1ee..5da7c32252b6 100644 --- a/pkgs/os-specific/linux/kernel/kernels-org.json +++ b/pkgs/os-specific/linux/kernel/kernels-org.json @@ -5,43 +5,38 @@ "lts": false }, "6.1": { - "version": "6.1.176", - "hash": "sha256:1xj4ms4gd8ghd0l0dzsyi762dgpdrmqhc3f0arrp7sa0p8npf6da", + "version": "6.1.177", + "hash": "sha256:0c0ayz4nygcmz4865r7mcgmh7hic4fi7zysnj6vdlyj53bz9nlpn", "lts": true }, "5.15": { - "version": "5.15.210", - "hash": "sha256:008a55av0x9fa3fspcz43sycik143gqxg2agcalrax2yw5ma82wi", + "version": "5.15.211", + "hash": "sha256:0qfry534wl5sbm6b4hf6fxqrr6mzf1k9pa2435sqp4hp6vjm9fdy", "lts": true }, "5.10": { - "version": "5.10.259", - "hash": "sha256:02dn8rf9p0afkl8kbdv28ijq974zfnv8zdsqcqbmapjm19c8wpma", + "version": "5.10.260", + "hash": "sha256:113bka32apz5pfqjfnv97k9hf9arkn5asfcd6cw7snsh65qjka27", "lts": true }, "6.6": { - "version": "6.6.143", - "hash": "sha256:0ci9b6kjp7r2xwqifs2963l9ihk2rllk4zpl2kgzbny0r66izkns", + "version": "6.6.144", + "hash": "sha256:1hzcax2ypzhrjzmq4b0jyqyc4al0ncyfcj9pq36phl29gcqbh6gc", "lts": true }, "6.12": { - "version": "6.12.94", - "hash": "sha256:1ln83ljmc7wr1nrjjq1hp1m1vx54j7i6i15m3hqb73a1p4ra5679", + "version": "6.12.95", + "hash": "sha256:1xmrsi0kimirky4cailnkkrbd72pp9n8irfx6lfmss8yrcgwbs59", "lts": true }, "6.18": { - "version": "6.18.37", - "hash": "sha256:0maj2ap1m09bxl6a3g9wc65h9sdr6y8rwc5qcqlbavb4wq0d4g58", + "version": "6.18.38", + "hash": "sha256:0igh9xy1lk2hv2jni00dqyy27j4zqh86waw7i65ryvnmmc4fa9mc", "lts": true }, - "7.0": { - "version": "7.0.14", - "hash": "sha256:160ggaq9rh50a39gz02fpia8maq85bwxhqlwsc03yafjhjvrk6fy", - "lts": false - }, "7.1": { - "version": "7.1.2", - "hash": "sha256:0gw8nnq6nix9xk2dhb1jwmhnqjayrn3bn2akzg4lgqkvfa9qq69p", + "version": "7.1.3", + "hash": "sha256:1p6iknvzmd04alrf49zn8mxw863v0yzgznyckfhl4llgx1lc0hdy", "lts": false } } diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix index ccd896e616ee..e6ca68d1640b 100644 --- a/pkgs/top-level/linux-kernels.nix +++ b/pkgs/top-level/linux-kernels.nix @@ -92,14 +92,6 @@ in ]; }; - linux_7_0 = callPackage ../os-specific/linux/kernel/mainline.nix { - branch = "7.0"; - kernelPatches = [ - kernelPatches.bridge_stp_helper - kernelPatches.request_key_helper - ]; - }; - linux_7_1 = callPackage ../os-specific/linux/kernel/mainline.nix { branch = "7.1"; kernelPatches = [ @@ -175,6 +167,7 @@ in linux_6_16 = throw "linux 6.16 was removed because it has reached its end of life upstream"; linux_6_17 = throw "linux 6.17 was removed because it has reached its end of life upstream"; linux_6_19 = throw "linux 6.19 was removed because it has reached its end of life upstream"; + linux_7_0 = throw "linux 7.0 was removed because it has reached its end of life upstream"; linux_5_10_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; linux_5_15_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; @@ -674,7 +667,6 @@ in linux_6_6 = recurseIntoAttrs (packagesFor kernels.linux_6_6); linux_6_12 = recurseIntoAttrs (packagesFor kernels.linux_6_12); linux_6_18 = recurseIntoAttrs (packagesFor kernels.linux_6_18); - linux_7_0 = recurseIntoAttrs (packagesFor kernels.linux_7_0); linux_7_1 = recurseIntoAttrs (packagesFor kernels.linux_7_1); } // lib.optionalAttrs config.allowAliases { @@ -689,6 +681,7 @@ in linux_6_16 = throw "linux 6.16 was removed because it reached its end of life upstream"; # Added 2025-10-22 linux_6_17 = throw "linux 6.17 was removed because it reached its end of life upstream"; # Added 2025-12-22 linux_6_19 = throw "linux 6.19 was removed because it reached its end of life upstream"; # Added 2026-04-23 + linux_7_0 = throw "linux 7.0 was removed because it has reached its end of life upstream"; # Added 2026-06-27 }; rpiPackages = {