staging-nixos merge for 2026-07-05 (#538512)
This commit is contained in:
@@ -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 `<yourmachine>.shell_interact()` grants access to a shell running
|
||||
inside a virtual machine. To use it, replace `<yourmachine>` with the name of a
|
||||
virtual machine defined in the test, for example: `machine.shell_interact()`.
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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.<name>` => systemd-nspawn machine (vs `nodes.<name>` => 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."
|
||||
)
|
||||
'';
|
||||
}
|
||||
@@ -49,8 +49,6 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
}
|
||||
);
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version;
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
@@ -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; [
|
||||
|
||||
@@ -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' ""
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -90,7 +90,6 @@ buildPythonPackage (finalAttrs: {
|
||||
BUILD_TARGET = "rocm";
|
||||
PREBUILD_KERNELS = "0";
|
||||
ROCM_PATH = "${rocmPackages.clr}";
|
||||
SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version;
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -41,8 +41,6 @@ buildPythonPackage rec {
|
||||
rm -v ./bootstrap.py
|
||||
'';
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
pyarrow
|
||||
|
||||
@@ -25,8 +25,6 @@ buildPythonPackage rec {
|
||||
|
||||
build-system = [ setuptools-scm ];
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
dependencies = [
|
||||
geoarrow-pyarrow
|
||||
geoarrow-types
|
||||
|
||||
@@ -51,8 +51,6 @@ buildPythonPackage rec {
|
||||
pyarrow-hotfix
|
||||
];
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
@@ -22,8 +22,6 @@ buildPythonPackage rec {
|
||||
|
||||
build-system = [ setuptools-scm ];
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,8 +20,6 @@ buildPythonPackage rec {
|
||||
hash = "sha256-B2wtLurzgk59kTooH51a2dewK7aEyA0dAm64Wp+tqhM=";
|
||||
};
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
nativeBuildInputs = [
|
||||
flit-scm
|
||||
setuptools-scm
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -59,8 +59,6 @@ buildPythonPackage (finalAttrs: {
|
||||
setuptools-scm
|
||||
];
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version;
|
||||
|
||||
dependencies = [
|
||||
packaging
|
||||
pydantic
|
||||
|
||||
@@ -30,8 +30,6 @@ buildPythonPackage (finalAttrs: {
|
||||
hash = "sha256-Rc4/S8BrYoLdn7eHDBaoUt1Qy+h0TMAN5ixCAuRmfPU=";
|
||||
};
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version;
|
||||
|
||||
dontUseCmakeConfigure = true;
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -40,8 +40,6 @@ buildPythonPackage rec {
|
||||
pytest-mock
|
||||
];
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = version;
|
||||
|
||||
passthru.updateScript = gitUpdater { rev-prefix = "v"; };
|
||||
|
||||
meta = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,8 +20,6 @@ buildPythonPackage (finalAttrs: {
|
||||
|
||||
pyproject = true;
|
||||
|
||||
env.SETUPTOOLS_SCM_PRETEND_VERSION = finalAttrs.version;
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
setuptools-scm
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user