···48484949<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
50505151+- The Perl implementation of the `switch-to-configuration` program is removed. All switchable systems now use the Rust rewrite. Any prior usage of `system.switch.enableNg` must now be removed. If you have any outstanding issues with the new implementation, please open an issue on GitHub.
5252+5153- The `no-broken-symlink` build hook now also fails builds whose output derivation contains links to $TMPDIR (typically /build, which contains the build directory).
52545355- The `services.polipo` module has been removed as `polipo` is unmaintained and archived upstream.
···2424 pkgs.maliit-keyboard
2525 ];
26262727+ environment.plasma6.excludePackages = [
2828+ # Optional wallpapers that add 126 MiB to the graphical installer
2929+ # closure. They will still need to be downloaded when installing a
3030+ # Plasma system, though.
3131+ pkgs.kdePackages.plasma-workspace-wallpapers
3232+ ];
3333+3434+ # Avoid bundling an entire MariaDB installation on the ISO.
3535+ programs.kde-pim.enable = false;
3636+2737 system.activationScripts.installerDesktop =
2838 let
2939
···256256 description = ''
257257 A program that writes a bootloader installation script to the path passed in the first command line argument.
258258259259- See `nixos/modules/system/activation/switch-to-configuration.pl`.
259259+ See `pkgs/by-name/sw/switch-to-configuration-ng/src/src/main.rs`.
260260 '';
261261 type = types.unique {
262262 message = ''
···11-#! @perl@/bin/perl
22-33-# NOTE: This script has an alternative implementation at
44-# <nixpkgs/pkgs/by-name/sw/switch-to-configuration-ng>. Any behavioral
55-# modifications to this script should also be made to that implementation.
66-77-88-# Issue #166838 uncovered a situation in which a configuration not suitable
99-# for the target architecture caused a cryptic error message instead of
1010-# a clean failure. Due to this mismatch, the perl interpreter in the shebang
1111-# line wasn't able to be executed, causing this script to be misinterpreted
1212-# as a shell script.
1313-#
1414-# Let's detect this situation to give a more meaningful error
1515-# message. The following two lines are carefully written to be both valid Perl
1616-# and Bash.
1717-printf "Perl script erroneously interpreted as shell script,\ndoes target platform match nixpkgs.crossSystem platform?\n" && exit 1
1818- if 0;
1919-2020-use strict;
2121-use warnings;
2222-use Config::IniFiles;
2323-use File::Path qw(make_path);
2424-use File::Basename;
2525-use File::Slurp qw(read_file write_file edit_file);
2626-use JSON::PP;
2727-use IPC::Cmd;
2828-use Sys::Syslog qw(:standard :macros);
2929-use Cwd qw(abs_path);
3030-use Fcntl ':flock';
3131-3232-## no critic(ControlStructures::ProhibitDeepNests)
3333-## no critic(ErrorHandling::RequireCarping)
3434-## no critic(CodeLayout::ProhibitParensWithBuiltins)
3535-## no critic(Variables::ProhibitPunctuationVars, Variables::RequireLocalizedPunctuationVars)
3636-## no critic(InputOutput::RequireCheckedSyscalls, InputOutput::RequireBracedFileHandleWithPrint, InputOutput::RequireBriefOpen)
3737-## no critic(ValuesAndExpressions::ProhibitNoisyQuotes, ValuesAndExpressions::ProhibitMagicNumbers, ValuesAndExpressions::ProhibitEmptyQuotes, ValuesAndExpressions::ProhibitInterpolationOfLiterals)
3838-## no critic(RegularExpressions::ProhibitEscapedMetacharacters)
3939-4040-# Location of activation scripts
4141-my $out = "@out@";
4242-# System closure path to switch to
4343-my $toplevel = "@toplevel@";
4444-4545-# To be robust against interruption, record what units need to be started etc.
4646-# We read these files again every time this script starts to make sure we continue
4747-# where the old (interrupted) script left off.
4848-my $start_list_file = "/run/nixos/start-list";
4949-my $restart_list_file = "/run/nixos/restart-list";
5050-my $reload_list_file = "/run/nixos/reload-list";
5151-5252-# Parse restart/reload requests by the activation script.
5353-# Activation scripts may write newline-separated units to the restart
5454-# file and switch-to-configuration will handle them. While
5555-# `stopIfChanged = true` is ignored, switch-to-configuration will
5656-# handle `restartIfChanged = false` and `reloadIfChanged = true`.
5757-# This is the same as specifying a restart trigger in the NixOS module.
5858-#
5959-# The reload file asks the script to reload a unit. This is the same as
6060-# specifying a reload trigger in the NixOS module and can be ignored if
6161-# the unit is restarted in this activation.
6262-my $restart_by_activation_file = "/run/nixos/activation-restart-list";
6363-my $reload_by_activation_file = "/run/nixos/activation-reload-list";
6464-my $dry_restart_by_activation_file = "/run/nixos/dry-activation-restart-list";
6565-my $dry_reload_by_activation_file = "/run/nixos/dry-activation-reload-list";
6666-6767-# The action that is to be performed (like switch, boot, test, dry-activate)
6868-# Also exposed via environment variable from now on
6969-my $action = shift(@ARGV);
7070-$ENV{NIXOS_ACTION} = $action;
7171-7272-# Expose the locale archive as an environment variable for systemctl and the activation script
7373-if ("@localeArchive@" ne "") {
7474- $ENV{LOCALE_ARCHIVE} = "@localeArchive@";
7575-}
7676-7777-if (!defined($action) || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate" && $action ne "check")) {
7878- print STDERR <<"EOF";
7979-Usage: $0 [check|switch|boot|test|dry-activate]
8080-8181-check: run pre-switch checks and exit
8282-switch: make the configuration the boot default and activate now
8383-boot: make the configuration the boot default
8484-test: activate the configuration, but don\'t make it the boot default
8585-dry-activate: show what would be done if this configuration were activated
8686-EOF
8787- exit(1);
8888-}
8989-9090-# This is a NixOS installation if it has /etc/NIXOS or a proper
9191-# /etc/os-release.
9292-if (!-f "/etc/NIXOS" && (read_file("/etc/os-release", err_mode => "quiet") // "") !~ /^ID="?@distroId@"?/msx) {
9393- die("This is not a NixOS installation!\n");
9494-}
9595-9696-make_path("/run/nixos", { mode => oct(755) });
9797-open(my $stc_lock, '>>', '/run/nixos/switch-to-configuration.lock') or die "Could not open lock - $!";
9898-flock($stc_lock, LOCK_EX|LOCK_NB) or die "Could not acquire lock - $!";
9999-openlog("nixos", "", LOG_USER);
100100-101101-# run pre-switch checks
102102-if (($ENV{"NIXOS_NO_CHECK"} // "") ne "1") {
103103- chomp(my $pre_switch_checks = <<'EOFCHECKS');
104104-@preSwitchCheck@
105105-EOFCHECKS
106106- system("$pre_switch_checks $out $action") == 0 or exit 1;
107107- if ($action eq "check") {
108108- exit 0;
109109- }
110110-}
111111-112112-# Install or update the bootloader.
113113-if ($action eq "switch" || $action eq "boot") {
114114- chomp(my $install_boot_loader = <<'EOFBOOTLOADER');
115115-@installBootLoader@
116116-EOFBOOTLOADER
117117- system("$install_boot_loader $toplevel") == 0 or exit 1;
118118-}
119119-120120-# Just in case the new configuration hangs the system, do a sync now.
121121-if (($ENV{"NIXOS_NO_SYNC"} // "") ne "1") {
122122- system("@coreutils@/bin/sync", "-f", "/nix/store");
123123-}
124124-125125-if ($action eq "boot") {
126126- exit(0);
127127-}
128128-129129-# Path to the directory containing systemd tools of the old system
130130-# Needs to be after the "boot" action exits, as this directory will not exist when doing a NIXOS_LUSTRATE install
131131-my $cur_systemd = abs_path("/run/current-system/sw/bin");
132132-# Path to the systemd store path of the new system
133133-my $new_systemd = "@systemd@";
134134-135135-# Check if we can activate the new configuration.
136136-my $cur_init_interface_version = read_file("/run/current-system/init-interface-version", err_mode => "quiet") // "";
137137-my $new_init_interface_version = read_file("$toplevel/init-interface-version");
138138-139139-if ($new_init_interface_version ne $cur_init_interface_version) {
140140- print STDERR <<'EOF';
141141-Warning: the new NixOS configuration has an ‘init’ that is
142142-incompatible with the current configuration. The new configuration
143143-won't take effect until you reboot the system.
144144-EOF
145145- exit(100);
146146-}
147147-148148-# Ignore SIGHUP so that we're not killed if we're running on (say)
149149-# virtual console 1 and we restart the "tty1" unit.
150150-$SIG{PIPE} = "IGNORE";
151151-152152-# Replacement for Net::DBus that calls busctl of the current systemd, parses
153153-# it's json output and returns the response using only core modules to reduce
154154-# dependencies on perlPackages in baseSystem
155155-sub busctl_call_systemd1_mgr {
156156- my (@args) = @_;
157157- my $cmd = [
158158- "$cur_systemd/busctl", "--json=short", "call", "org.freedesktop.systemd1",
159159- "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager",
160160- @args
161161- ];
162162-163163- my ($ok, $err, undef, $stdout) = IPC::Cmd::run(command => $cmd);
164164- die $err unless $ok;
165165-166166- my $res = decode_json(join "", @$stdout);
167167- return $res;
168168-}
169169-170170-# Asks the currently running systemd instance via dbus which units are active.
171171-# Returns a hash where the key is the name of each unit and the value a hash
172172-# of load, state, substate.
173173-sub get_active_units {
174174- my $units = busctl_call_systemd1_mgr("ListUnitsByPatterns", "asas", 0, 0)->{data}->[0];
175175- my $res = {};
176176- for my $item (@{$units}) {
177177- my ($id, $description, $load_state, $active_state, $sub_state,
178178- $following, $unit_path, $job_id, $job_type, $job_path) = @{$item};
179179- if ($following ne "") {
180180- next;
181181- }
182182- if ($job_id == 0 and $active_state eq "inactive") {
183183- next;
184184- }
185185- $res->{$id} = { load => $load_state, state => $active_state, substate => $sub_state };
186186- }
187187- return $res;
188188-}
189189-190190-# Asks the currently running systemd instance whether a unit is currently active.
191191-# Takes the name of the unit as an argument and returns a bool whether the unit is active or not.
192192-sub unit_is_active {
193193- my ($unit_name) = @_;
194194- my $units = busctl_call_systemd1_mgr("ListUnitsByNames", "as", 1, , "--", $unit_name)->{data}->[0];
195195- if (scalar(@{$units}) == 0) {
196196- return 0;
197197- }
198198- my $active_state = $units->[0]->[3];
199199- return $active_state eq "active" || $active_state eq "activating";
200200-}
201201-202202-# Parse a fstab file, given its path.
203203-# Returns a tuple of filesystems and swaps.
204204-#
205205-# Filesystems is a hash of mountpoint and { device, fsType, options }
206206-# Swaps is a hash of device and { options }
207207-sub parse_fstab {
208208- my ($filename) = @_;
209209- my ($fss, $swaps);
210210- foreach my $line (read_file($filename, err_mode => "quiet")) {
211211- chomp($line);
212212- $line =~ s/^\s*\#.*//msx;
213213- if ($line =~ /^\s*$/msx) {
214214- next;
215215- }
216216- my @xs = split(/\s+/msx, $line);
217217- if ($xs[2] eq "swap") {
218218- $swaps->{$xs[0]} = { options => $xs[3] // "" };
219219- } else {
220220- $fss->{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] // "" };
221221- }
222222- }
223223- return ($fss, $swaps);
224224-}
225225-226226-# This subroutine takes a single ini file that specified systemd configuration
227227-# like unit configuration and parses it into a hash where the keys are the sections
228228-# of the unit file and the values are hashes themselves. These hashes have the unit file
229229-# keys as their keys (left side of =) and an array of all values that were set as their
230230-# values. If a value is empty (for example `ExecStart=`), then all current definitions are
231231-# removed.
232232-#
233233-# Instead of returning the hash, this subroutine takes a hashref to return the data in. This
234234-# allows calling the subroutine multiple times with the same hash to parse override files.
235235-sub parse_systemd_ini {
236236- my ($unit_contents, $path) = @_;
237237- # Tie the ini file to a hash for easier access
238238- tie(my %file_contents, "Config::IniFiles", (-file => $path, -allowempty => 1, -allowcontinue => 1)); ## no critic(Miscellanea::ProhibitTies)
239239-240240- # Copy over all sections
241241- foreach my $section_name (keys(%file_contents)) {
242242- if ($section_name eq "Install") {
243243- # Skip the [Install] section because it has no relevant keys for us
244244- next;
245245- }
246246- # Copy over all keys
247247- foreach my $ini_key (keys(%{$file_contents{$section_name}})) {
248248- # Ensure the value is an array so it's easier to work with
249249- my $ini_value = $file_contents{$section_name}{$ini_key};
250250- my @ini_values;
251251- if (ref($ini_value) eq "ARRAY") {
252252- @ini_values = @{$ini_value};
253253- } else {
254254- @ini_values = $ini_value;
255255- }
256256- # Go over all values
257257- for my $ini_value (@ini_values) {
258258- # If a value is empty, it's an override that tells us to clean the value
259259- if ($ini_value eq "") {
260260- delete $unit_contents->{$section_name}->{$ini_key};
261261- next;
262262- }
263263- push(@{$unit_contents->{$section_name}->{$ini_key}}, $ini_value);
264264- }
265265- }
266266- }
267267- return;
268268-}
269269-270270-# This subroutine takes the path to a systemd configuration file (like a unit configuration),
271271-# parses it, and returns a hash that contains the contents. The contents of this hash are
272272-# explained in the `parse_systemd_ini` subroutine. Neither the sections nor the keys inside
273273-# the sections are consistently sorted.
274274-#
275275-# If a directory with the same basename ending in .d exists next to the unit file, it will be
276276-# assumed to contain override files which will be parsed as well and handled properly.
277277-sub parse_unit {
278278- my ($unit_path, $base_unit_path) = @_;
279279-280280- # Parse the main unit and all overrides
281281- my %unit_data;
282282- # Replace \ with \\ so glob() still works with units that have a \ in them
283283- # Valid characters in unit names are ASCII letters, digits, ":", "-", "_", ".", and "\"
284284- $base_unit_path =~ s/\\/\\\\/gmsx;
285285- $unit_path =~ s/\\/\\\\/gmsx;
286286-287287- foreach (glob("${base_unit_path}{,.d/*.conf}")) {
288288- parse_systemd_ini(\%unit_data, "$_")
289289- }
290290- # Handle drop-in template-unit instance overrides
291291- if ($unit_path ne $base_unit_path) {
292292- foreach (glob("${unit_path}.d/*.conf")) {
293293- parse_systemd_ini(\%unit_data, "$_")
294294- }
295295- }
296296- return %unit_data;
297297-}
298298-299299-# Checks whether a specified boolean in a systemd unit is true
300300-# or false, with a default that is applied when the value is not set.
301301-sub parse_systemd_bool {
302302- my ($unit_config, $section_name, $bool_name, $default) = @_;
303303-304304- my @values = @{$unit_config->{$section_name}{$bool_name} // []};
305305- # Return default if value is not set
306306- if ((scalar(@values) < 1) || (not defined($values[-1]))) {
307307- return $default;
308308- }
309309- # If value is defined multiple times, use the last definition
310310- my $last_value = $values[-1];
311311- # These are valid values as of systemd.syntax(7)
312312- return $last_value eq "1" || $last_value eq "yes" || $last_value eq "true" || $last_value eq "on";
313313-}
314314-315315-# Writes a unit name into a given file to be more resilient against
316316-# crashes of the script. Does nothing when the action is dry-activate.
317317-sub record_unit {
318318- my ($fn, $unit) = @_;
319319- if ($action ne "dry-activate") {
320320- write_file($fn, { append => 1 }, "$unit\n");
321321- }
322322- return;
323323-}
324324-325325-# The opposite of record_unit, removes a unit name from a file
326326-sub unrecord_unit {
327327- my ($fn, $unit) = @_;
328328- if ($action ne "dry-activate") {
329329- edit_file(sub { s/^$unit\n//msx }, $fn);
330330- }
331331- return;
332332-}
333333-334334-# Compare the contents of two unit files and return whether the unit
335335-# needs to be restarted or reloaded. If the units differ, the service
336336-# is restarted unless the only difference is `X-Reload-Triggers` in the
337337-# `Unit` section. If this is the only modification, the unit is reloaded
338338-# instead of restarted. If the only difference is `Options` in the
339339-# `[Mount]` section, the unit is reloaded rather than restarted.
340340-# Returns:
341341-# - 0 if the units are equal
342342-# - 1 if the units are different and a restart action is required
343343-# - 2 if the units are different and a reload action is required
344344-sub compare_units { ## no critic(Subroutines::ProhibitExcessComplexity)
345345- my ($cur_unit, $new_unit) = @_;
346346- my $ret = 0;
347347- # Keys to ignore in the [Unit] section
348348- my %unit_section_ignores = map { $_ => 1 } qw(
349349- X-Reload-Triggers
350350- Description Documentation
351351- OnFailure OnSuccess OnFailureJobMode
352352- IgnoreOnIsolate StopWhenUnneeded
353353- RefuseManualStart RefuseManualStop
354354- AllowIsolate CollectMode
355355- SourcePath
356356- );
357357-358358- my $comp_array = sub {
359359- my ($a, $b) = @_;
360360- return join("\0", @{$a}) eq join("\0", @{$b});
361361- };
362362-363363- # Comparison hash for the sections
364364- my %section_cmp = map { $_ => 1 } keys(%{$new_unit});
365365- # Iterate over the sections
366366- foreach my $section_name (keys(%{$cur_unit})) {
367367- # Missing section in the new unit?
368368- if (not exists($section_cmp{$section_name})) {
369369- # If the [Unit] section was removed, make sure that only keys
370370- # were in it that are ignored
371371- if ($section_name eq "Unit") {
372372- foreach my $ini_key (keys(%{$cur_unit->{"Unit"}})) {
373373- if (not defined($unit_section_ignores{$ini_key})) {
374374- return 1;
375375- }
376376- }
377377- next; # check the next section
378378- } else {
379379- return 1;
380380- }
381381- if ($section_name eq "Unit" and %{$cur_unit->{"Unit"}} == 1 and defined(%{$cur_unit->{"Unit"}}{"X-Reload-Triggers"})) {
382382- # If a new [Unit] section was removed that only contained X-Reload-Triggers,
383383- # do nothing.
384384- next;
385385- } else {
386386- return 1;
387387- }
388388- }
389389- delete $section_cmp{$section_name};
390390- # Comparison hash for the section contents
391391- my %ini_cmp = map { $_ => 1 } keys(%{$new_unit->{$section_name}});
392392- # Iterate over the keys of the section
393393- foreach my $ini_key (keys(%{$cur_unit->{$section_name}})) {
394394- delete $ini_cmp{$ini_key};
395395- my @cur_value = @{$cur_unit->{$section_name}{$ini_key}};
396396- # If the key is missing in the new unit, they are different...
397397- if (not $new_unit->{$section_name}{$ini_key}) {
398398- # ... unless the key that is now missing is one of the ignored keys
399399- if ($section_name eq "Unit" and defined($unit_section_ignores{$ini_key})) {
400400- next;
401401- }
402402- return 1;
403403- }
404404- my @new_value = @{$new_unit->{$section_name}{$ini_key}};
405405- # If the contents are different, the units are different
406406- if (not $comp_array->(\@cur_value, \@new_value)) {
407407- # Check if only the reload triggers changed or one of the ignored keys
408408- if ($section_name eq "Unit") {
409409- if ($ini_key eq "X-Reload-Triggers") {
410410- $ret = 2;
411411- next;
412412- } elsif (defined($unit_section_ignores{$ini_key})) {
413413- next;
414414- }
415415- }
416416- # If this is a mount unit, check if it was only `Options`
417417- if ($section_name eq "Mount" and $ini_key eq "Options") {
418418- $ret = 2;
419419- next;
420420- }
421421- return 1;
422422- }
423423- }
424424- # A key was introduced that was missing in the previous unit
425425- if (%ini_cmp) {
426426- if ($section_name eq "Unit") {
427427- foreach my $ini_key (keys(%ini_cmp)) {
428428- if ($ini_key eq "X-Reload-Triggers") {
429429- $ret = 2;
430430- } elsif (defined($unit_section_ignores{$ini_key})) {
431431- next;
432432- } else {
433433- return 1;
434434- }
435435- }
436436- } else {
437437- return 1;
438438- }
439439- };
440440- }
441441- # A section was introduced that was missing in the previous unit
442442- if (%section_cmp) {
443443- if (%section_cmp == 1 and defined($section_cmp{"Unit"})) {
444444- foreach my $ini_key (keys(%{$new_unit->{"Unit"}})) {
445445- if (not defined($unit_section_ignores{$ini_key})) {
446446- return 1;
447447- } elsif ($ini_key eq "X-Reload-Triggers") {
448448- $ret = 2;
449449- }
450450- }
451451- } else {
452452- return 1;
453453- }
454454- }
455455-456456- return $ret;
457457-}
458458-459459-# Called when a unit exists in both the old systemd and the new system and the units
460460-# differ. This figures out of what units are to be stopped, restarted, reloaded, started, and skipped.
461461-sub handle_modified_unit { ## no critic(Subroutines::ProhibitManyArgs, Subroutines::ProhibitExcessComplexity)
462462- my ($unit, $base_name, $new_unit_file, $new_base_unit_file, $new_unit_info, $active_cur, $units_to_stop, $units_to_start, $units_to_reload, $units_to_restart, $units_to_skip) = @_;
463463-464464- if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target" || $unit =~ /\.path$/msx || $unit =~ /\.slice$/msx) {
465465- # Do nothing. These cannot be restarted directly.
466466-467467- # Slices and Paths don't have to be restarted since
468468- # properties (resource limits and inotify watches)
469469- # seem to get applied on daemon-reload.
470470- } elsif ($unit =~ /\.mount$/msx) {
471471- # Just restart the unit. We wouldn't have gotten into this subroutine
472472- # if only `Options` was changed, in which case the unit would be reloaded.
473473- # The only exception is / and /nix because it's very unlikely we can safely
474474- # unmount them so we reload them instead. This means that we may not get
475475- # all changes into the running system but it's better than crashing it.
476476- if ($unit eq "-.mount" or $unit eq "nix.mount") {
477477- $units_to_reload->{$unit} = 1;
478478- record_unit($reload_list_file, $unit);
479479- } else {
480480- $units_to_restart->{$unit} = 1;
481481- record_unit($restart_list_file, $unit);
482482- }
483483- } elsif ($unit =~ /\.socket$/msx) {
484484- # FIXME: do something?
485485- # Attempt to fix this: https://github.com/NixOS/nixpkgs/pull/141192
486486- # Revert of the attempt: https://github.com/NixOS/nixpkgs/pull/147609
487487- # More details: https://github.com/NixOS/nixpkgs/issues/74899#issuecomment-981142430
488488- } else {
489489- my %new_unit_info = $new_unit_info ? %{$new_unit_info} : parse_unit($new_unit_file, $new_base_unit_file);
490490- if (parse_systemd_bool(\%new_unit_info, "Service", "X-ReloadIfChanged", 0) and not $units_to_restart->{$unit} and not $units_to_stop->{$unit}) {
491491- $units_to_reload->{$unit} = 1;
492492- record_unit($reload_list_file, $unit);
493493- }
494494- elsif ($unit eq "dbus.service" || $unit eq "dbus-broker.service") {
495495- # dbus service should only ever be reloaded, not started/stoped/restarted as that would break the system.
496496- }
497497- elsif (!parse_systemd_bool(\%new_unit_info, "Service", "X-RestartIfChanged", 1) || parse_systemd_bool(\%new_unit_info, "Unit", "RefuseManualStop", 0) || parse_systemd_bool(\%new_unit_info, "Unit", "X-OnlyManualStart", 0)) {
498498- $units_to_skip->{$unit} = 1;
499499- } else {
500500- # It doesn't make sense to stop and start non-services because
501501- # they can't have ExecStop=
502502- if (!parse_systemd_bool(\%new_unit_info, "Service", "X-StopIfChanged", 1) || $unit !~ /\.service$/msx) {
503503- # This unit should be restarted instead of
504504- # stopped and started.
505505- $units_to_restart->{$unit} = 1;
506506- record_unit($restart_list_file, $unit);
507507- # Remove from units to reload so we don't restart and reload
508508- if ($units_to_reload->{$unit}) {
509509- delete $units_to_reload->{$unit};
510510- unrecord_unit($reload_list_file, $unit);
511511- }
512512- } else {
513513- # If this unit is socket-activated, then stop the
514514- # socket unit(s) as well, and restart the
515515- # socket(s) instead of the service.
516516- my $socket_activated = 0;
517517- if ($unit =~ /\.service$/msx) {
518518- my @sockets = split(/\s+/msx, join(" ", @{$new_unit_info{Service}{Sockets} // []}));
519519- if (scalar(@sockets) == 0) {
520520- @sockets = ("$base_name.socket");
521521- }
522522- foreach my $socket (@sockets) {
523523- if (defined($active_cur->{$socket})) {
524524- # We can now be sure this is a socket-activate unit
525525-526526- $units_to_stop->{$socket} = 1;
527527- # Only restart sockets that actually
528528- # exist in new configuration:
529529- if (-e "$toplevel/etc/systemd/system/$socket") {
530530- $units_to_start->{$socket} = 1;
531531- if ($units_to_start eq $units_to_restart) {
532532- record_unit($restart_list_file, $socket);
533533- } else {
534534- record_unit($start_list_file, $socket);
535535- }
536536- $socket_activated = 1;
537537- }
538538- # Remove from units to reload so we don't restart and reload
539539- if ($units_to_reload->{$unit}) {
540540- delete $units_to_reload->{$unit};
541541- unrecord_unit($reload_list_file, $unit);
542542- }
543543- }
544544- }
545545- }
546546-547547- if (parse_systemd_bool(\%new_unit_info, "Service", "X-NotSocketActivated", 0)) {
548548- # If the unit explicitly opts out of socket
549549- # activation, restart it as if it weren't (but do
550550- # restart its sockets, that's fine):
551551- $socket_activated = 0;
552552- }
553553-554554- # If the unit is not socket-activated, record
555555- # that this unit needs to be started below.
556556- # We write this to a file to ensure that the
557557- # service gets restarted if we're interrupted.
558558- if (!$socket_activated) {
559559- $units_to_start->{$unit} = 1;
560560- if ($units_to_start eq $units_to_restart) {
561561- record_unit($restart_list_file, $unit);
562562- } else {
563563- record_unit($start_list_file, $unit);
564564- }
565565- }
566566-567567- $units_to_stop->{$unit} = 1;
568568- # Remove from units to reload so we don't restart and reload
569569- if ($units_to_reload->{$unit}) {
570570- delete $units_to_reload->{$unit};
571571- unrecord_unit($reload_list_file, $unit);
572572- }
573573- }
574574- }
575575- }
576576- return;
577577-}
578578-579579-# Figure out what units need to be stopped, started, restarted or reloaded.
580580-my (%units_to_stop, %units_to_skip, %units_to_start, %units_to_restart, %units_to_reload);
581581-582582-my %units_to_filter; # units not shown
583583-584584-%units_to_start = map { $_ => 1 }
585585- split(/\n/msx, read_file($start_list_file, err_mode => "quiet") // "");
586586-587587-%units_to_restart = map { $_ => 1 }
588588- split(/\n/msx, read_file($restart_list_file, err_mode => "quiet") // "");
589589-590590-%units_to_reload = map { $_ => 1 }
591591- split(/\n/msx, read_file($reload_list_file, err_mode => "quiet") // "");
592592-593593-my $active_cur = get_active_units();
594594-while (my ($unit, $state) = each(%{$active_cur})) {
595595- my $cur_unit_file = "/etc/systemd/system/$unit";
596596- my $new_unit_file = "$toplevel/etc/systemd/system/$unit";
597597-598598- my $base_unit = $unit;
599599- my $cur_base_unit_file = $cur_unit_file;
600600- my $new_base_unit_file = $new_unit_file;
601601-602602- # Detect template instances.
603603- if (!-e $cur_unit_file && !-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
604604- $base_unit = "$1\@.$2";
605605- $cur_base_unit_file = "/etc/systemd/system/$base_unit";
606606- $new_base_unit_file = "$toplevel/etc/systemd/system/$base_unit";
607607- }
608608-609609- my $base_name = $base_unit;
610610- $base_name =~ s/\.[[:lower:]]*$//msx;
611611-612612- if (-e $cur_base_unit_file && ($state->{state} eq "active" || $state->{state} eq "activating")) {
613613- if (! -e $new_base_unit_file || abs_path($new_base_unit_file) eq "/dev/null") {
614614- my %cur_unit_info = parse_unit($cur_unit_file, $cur_base_unit_file);
615615- if (parse_systemd_bool(\%cur_unit_info, "Unit", "X-StopOnRemoval", 1)) {
616616- $units_to_stop{$unit} = 1;
617617- }
618618- }
619619-620620- elsif ($unit =~ /\.target$/msx) {
621621- my %new_unit_info = parse_unit($new_unit_file, $new_base_unit_file);
622622-623623- # Cause all active target units to be restarted below.
624624- # This should start most changed units we stop here as
625625- # well as any new dependencies (including new mounts and
626626- # swap devices). FIXME: the suspend target is sometimes
627627- # active after the system has resumed, which probably
628628- # should not be the case. Just ignore it.
629629- if ($unit ne "suspend.target" && $unit ne "hibernate.target" && $unit ne "hybrid-sleep.target") {
630630- if (!(parse_systemd_bool(\%new_unit_info, "Unit", "RefuseManualStart", 0) || parse_systemd_bool(\%new_unit_info, "Unit", "X-OnlyManualStart", 0))) {
631631- $units_to_start{$unit} = 1;
632632- record_unit($start_list_file, $unit);
633633- # Don't spam the user with target units that always get started.
634634- if (($ENV{"STC_DISPLAY_ALL_UNITS"} // "") ne "1") {
635635- $units_to_filter{$unit} = 1;
636636- }
637637- }
638638- }
639639-640640- # Stop targets that have X-StopOnReconfiguration set.
641641- # This is necessary to respect dependency orderings
642642- # involving targets: if unit X starts after target Y and
643643- # target Y starts after unit Z, then if X and Z have both
644644- # changed, then X should be restarted after Z. However,
645645- # if target Y is in the "active" state, X and Z will be
646646- # restarted at the same time because X's dependency on Y
647647- # is already satisfied. Thus, we need to stop Y first.
648648- # Stopping a target generally has no effect on other units
649649- # (unless there is a PartOf dependency), so this is just a
650650- # bookkeeping thing to get systemd to do the right thing.
651651- if (parse_systemd_bool(\%new_unit_info, "Unit", "X-StopOnReconfiguration", 0)) {
652652- $units_to_stop{$unit} = 1;
653653- }
654654- }
655655-656656- else {
657657- my %cur_unit_info = parse_unit($cur_unit_file, $cur_base_unit_file);
658658- my %new_unit_info = parse_unit($new_unit_file, $new_base_unit_file);
659659- my $diff = compare_units(\%cur_unit_info, \%new_unit_info);
660660- if ($diff == 1) {
661661- handle_modified_unit($unit, $base_name, $new_unit_file, $new_base_unit_file, \%new_unit_info, $active_cur, \%units_to_stop, \%units_to_start, \%units_to_reload, \%units_to_restart, \%units_to_skip);
662662- } elsif ($diff == 2 and not $units_to_restart{$unit}) {
663663- $units_to_reload{$unit} = 1;
664664- record_unit($reload_list_file, $unit);
665665- }
666666- }
667667- }
668668-}
669669-670670-# Converts a path to the name of a systemd mount unit that would be responsible
671671-# for mounting this path.
672672-sub path_to_unit_name {
673673- my ($path) = @_;
674674- # Use current version of systemctl binary before daemon is reexeced.
675675- open(my $cmd, "-|", "$cur_systemd/systemd-escape", "--suffix=mount", "-p", $path)
676676- or die "Unable to escape $path!\n";
677677- my $escaped = do { local $/ = undef; <$cmd> };
678678- chomp($escaped);
679679- close($cmd) or die("Unable to close systemd-escape pipe");
680680- return $escaped;
681681-}
682682-683683-# Compare the previous and new fstab to figure out which filesystems
684684-# need a remount or need to be unmounted. New filesystems are mounted
685685-# automatically by starting local-fs.target. FIXME: might be nicer if
686686-# we generated units for all mounts; then we could unify this with the
687687-# unit checking code above.
688688-my ($cur_fss, $cur_swaps) = parse_fstab("/etc/fstab");
689689-my ($new_fss, $new_swaps) = parse_fstab("$toplevel/etc/fstab");
690690-foreach my $mount_point (keys(%{$cur_fss})) {
691691- my $cur = $cur_fss->{$mount_point};
692692- my $new = $new_fss->{$mount_point};
693693- my $unit = path_to_unit_name($mount_point);
694694- if (!defined($new)) {
695695- # Filesystem entry disappeared, so unmount it.
696696- $units_to_stop{$unit} = 1;
697697- } elsif ($cur->{fsType} ne $new->{fsType} || $cur->{device} ne $new->{device}) {
698698- if ($mount_point eq '/' or $mount_point eq '/nix') {
699699- if ($cur->{options} ne $new->{options}) {
700700- # Mount options changed, so remount it.
701701- $units_to_reload{$unit} = 1;
702702- record_unit($reload_list_file, $unit);
703703- } else {
704704- # Don't unmount / or /nix if the device changed
705705- $units_to_skip{$unit} = 1;
706706- }
707707- } else {
708708- # Filesystem type or device changed, so unmount and mount it.
709709- $units_to_restart{$unit} = 1;
710710- record_unit($restart_list_file, $unit);
711711- }
712712- } elsif ($cur->{options} ne $new->{options}) {
713713- # Mount options changes, so remount it.
714714- $units_to_reload{$unit} = 1;
715715- record_unit($reload_list_file, $unit);
716716- }
717717-}
718718-719719-# Also handles swap devices.
720720-foreach my $device (keys(%{$cur_swaps})) {
721721- my $cur = $cur_swaps->{$device};
722722- my $new = $new_swaps->{$device};
723723- if (!defined($new)) {
724724- # Swap entry disappeared, so turn it off. Can't use
725725- # "systemctl stop" here because systemd has lots of alias
726726- # units that prevent a stop from actually calling
727727- # "swapoff".
728728- if ($action eq "dry-activate") {
729729- print STDERR "would stop swap device: $device\n";
730730- } else {
731731- print STDERR "stopping swap device: $device\n";
732732- system("@utillinux@/sbin/swapoff", $device);
733733- }
734734- }
735735- # FIXME: update swap options (i.e. its priority).
736736-}
737737-738738-739739-# Should we have systemd re-exec itself?
740740-my $cur_pid1_path = abs_path("/proc/1/exe") // "/unknown";
741741-my $cur_systemd_system_config = abs_path("/etc/systemd/system.conf") // "/unknown";
742742-my $new_pid1_path = abs_path("$new_systemd/lib/systemd/systemd") or die;
743743-my $new_systemd_system_config = abs_path("$toplevel/etc/systemd/system.conf") // "/unknown";
744744-745745-my $restart_systemd = $cur_pid1_path ne $new_pid1_path;
746746-if ($cur_systemd_system_config ne $new_systemd_system_config) {
747747- $restart_systemd = 1;
748748-}
749749-750750-# Takes an array of unit names and returns an array with the same elements,
751751-# except all units that are also in the global variable `unitsToFilter`.
752752-sub filter_units {
753753- my ($units) = @_;
754754- my @res;
755755- foreach my $unit (sort(keys(%{$units}))) {
756756- if (!defined($units_to_filter{$unit})) {
757757- push(@res, $unit);
758758- }
759759- }
760760- return @res;
761761-}
762762-763763-my @units_to_stop_filtered = filter_units(\%units_to_stop);
764764-765765-766766-# Show dry-run actions.
767767-if ($action eq "dry-activate") {
768768- if (scalar(@units_to_stop_filtered) > 0) {
769769- print STDERR "would stop the following units: ", join(", ", @units_to_stop_filtered), "\n";
770770- }
771771- if (scalar(keys(%units_to_skip)) > 0) {
772772- print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys(%units_to_skip))), "\n";
773773- }
774774-775775- print STDERR "would activate the configuration...\n";
776776- system("$out/dry-activate", "$out");
777777-778778- # Handle the activation script requesting the restart or reload of a unit.
779779- foreach (split(/\n/msx, read_file($dry_restart_by_activation_file, err_mode => "quiet") // "")) {
780780- my $unit = $_;
781781- my $new_unit_file = "$toplevel/etc/systemd/system/$unit";
782782- my $base_unit = $unit;
783783- my $new_base_unit_file = $new_unit_file;
784784-785785- # Detect template instances.
786786- if (!-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
787787- $base_unit = "$1\@.$2";
788788- $new_base_unit_file = "$toplevel/etc/systemd/system/$base_unit";
789789- }
790790-791791- my $base_name = $base_unit;
792792- $base_name =~ s/\.[[:lower:]]*$//msx;
793793-794794- # Start units if they were not active previously
795795- if (not defined($active_cur->{$unit})) {
796796- $units_to_start{$unit} = 1;
797797- next;
798798- }
799799-800800- handle_modified_unit($unit, $base_name, $new_unit_file, $new_base_unit_file, undef, $active_cur, \%units_to_restart, \%units_to_restart, \%units_to_reload, \%units_to_restart, \%units_to_skip);
801801- }
802802- unlink($dry_restart_by_activation_file);
803803-804804- foreach (split(/\n/msx, read_file($dry_reload_by_activation_file, err_mode => "quiet") // "")) {
805805- my $unit = $_;
806806-807807- if (defined($active_cur->{$unit}) and not $units_to_restart{$unit} and not $units_to_stop{$unit}) {
808808- $units_to_reload{$unit} = 1;
809809- record_unit($reload_list_file, $unit);
810810- }
811811- }
812812- unlink($dry_reload_by_activation_file);
813813-814814- if ($restart_systemd) {
815815- print STDERR "would restart systemd\n";
816816- }
817817- if (scalar(keys(%units_to_reload)) > 0) {
818818- print STDERR "would reload the following units: ", join(", ", sort(keys(%units_to_reload))), "\n";
819819- }
820820- if (scalar(keys(%units_to_restart)) > 0) {
821821- print STDERR "would restart the following units: ", join(", ", sort(keys(%units_to_restart))), "\n";
822822- }
823823- my @units_to_start_filtered = filter_units(\%units_to_start);
824824- if (scalar(@units_to_start_filtered)) {
825825- print STDERR "would start the following units: ", join(", ", @units_to_start_filtered), "\n";
826826- }
827827- exit 0;
828828-}
829829-830830-831831-syslog(LOG_NOTICE, "switching to system configuration $toplevel");
832832-833833-if (scalar(keys(%units_to_stop)) > 0) {
834834- if (scalar(@units_to_stop_filtered)) {
835835- print STDERR "stopping the following units: ", join(", ", @units_to_stop_filtered), "\n";
836836- }
837837- # Use current version of systemctl binary before daemon is reexeced.
838838- system("$cur_systemd/systemctl", "stop", "--", sort(keys(%units_to_stop)));
839839-}
840840-841841-if (scalar(keys(%units_to_skip)) > 0) {
842842- print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys(%units_to_skip))), "\n";
843843-}
844844-845845-# Activate the new configuration (i.e., update /etc, make accounts,
846846-# and so on).
847847-my $res = 0;
848848-print STDERR "activating the configuration...\n";
849849-system("$out/activate", "$out") == 0 or $res = 2;
850850-851851-# Handle the activation script requesting the restart or reload of a unit.
852852-foreach (split(/\n/msx, read_file($restart_by_activation_file, err_mode => "quiet") // "")) {
853853- my $unit = $_;
854854- my $new_unit_file = "$toplevel/etc/systemd/system/$unit";
855855- my $base_unit = $unit;
856856- my $new_base_unit_file = $new_unit_file;
857857-858858- # Detect template instances.
859859- if (!-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
860860- $base_unit = "$1\@.$2";
861861- $new_base_unit_file = "$toplevel/etc/systemd/system/$base_unit";
862862- }
863863-864864- my $base_name = $base_unit;
865865- $base_name =~ s/\.[[:lower:]]*$//msx;
866866-867867- # Start units if they were not active previously
868868- if (not defined($active_cur->{$unit})) {
869869- $units_to_start{$unit} = 1;
870870- record_unit($start_list_file, $unit);
871871- next;
872872- }
873873-874874- handle_modified_unit($unit, $base_name, $new_unit_file, $new_base_unit_file, undef, $active_cur, \%units_to_restart, \%units_to_restart, \%units_to_reload, \%units_to_restart, \%units_to_skip);
875875-}
876876-# We can remove the file now because it has been propagated to the other restart/reload files
877877-unlink($restart_by_activation_file);
878878-879879-foreach (split(/\n/msx, read_file($reload_by_activation_file, err_mode => "quiet") // "")) {
880880- my $unit = $_;
881881-882882- if (defined($active_cur->{$unit}) and not $units_to_restart{$unit} and not $units_to_stop{$unit}) {
883883- $units_to_reload{$unit} = 1;
884884- record_unit($reload_list_file, $unit);
885885- }
886886-}
887887-# We can remove the file now because it has been propagated to the other reload file
888888-unlink($reload_by_activation_file);
889889-890890-# Restart systemd if necessary. Note that this is done using the
891891-# current version of systemd, just in case the new one has trouble
892892-# communicating with the running pid 1.
893893-if ($restart_systemd) {
894894- print STDERR "restarting systemd...\n";
895895- system("$cur_systemd/systemctl", "daemon-reexec") == 0 or $res = 2;
896896-}
897897-898898-# Forget about previously failed services.
899899-system("$new_systemd/bin/systemctl", "reset-failed");
900900-901901-# Make systemd reload its units.
902902-system("$new_systemd/bin/systemctl", "daemon-reload") == 0 or $res = 3;
903903-904904-# Reload user units
905905-open(my $list_active_users, "-|", "$new_systemd/bin/loginctl", "list-users", "--no-legend") || die("Unable to call loginctl");
906906-while (my $f = <$list_active_users>) {
907907- if ($f !~ /^\s*(?<uid>\d+)\s+(?<user>\S+)/msx) {
908908- next;
909909- }
910910- my ($uid, $name) = ($+{uid}, $+{user});
911911- print STDERR "reloading user units for $name...\n";
912912-913913- system("@su@", "-s", "@shell@", "-l", $name, "-c",
914914- "export XDG_RUNTIME_DIR=/run/user/$uid; " .
915915- "$cur_systemd/systemctl --user daemon-reexec; " .
916916- "$new_systemd/bin/systemctl --user start nixos-activation.service");
917917-}
918918-919919-close($list_active_users) || die("Unable to close the file handle to loginctl");
920920-921921-# Restart sysinit-reactivation.target.
922922-# This target only exists to restart services ordered before sysinit.target. We
923923-# cannot use X-StopOnReconfiguration to restart sysinit.target because then ALL
924924-# services of the system would be restarted since all normal services have a
925925-# default dependency on sysinit.target. sysinit-reactivation.target ensures
926926-# that services ordered BEFORE sysinit.target get re-started in the correct
927927-# order. Ordering between these services is respected.
928928-print STDERR "restarting sysinit-reactivation.target\n";
929929-system("$new_systemd/bin/systemctl", "restart", "sysinit-reactivation.target") == 0 or $res = 4;
930930-931931-# Before reloading we need to ensure that the units are still active. They may have been
932932-# deactivated because one of their requirements got stopped. If they are inactive
933933-# but should have been reloaded, the user probably expects them to be started.
934934-if (scalar(keys(%units_to_reload)) > 0) {
935935- for my $unit (keys(%units_to_reload)) {
936936- if (!unit_is_active($unit)) {
937937- # Figure out if we need to start the unit
938938- my %unit_info = parse_unit("$toplevel/etc/systemd/system/$unit", "$toplevel/etc/systemd/system/$unit");
939939- if (!(parse_systemd_bool(\%unit_info, "Unit", "RefuseManualStart", 0) || parse_systemd_bool(\%unit_info, "Unit", "X-OnlyManualStart", 0))) {
940940- $units_to_start{$unit} = 1;
941941- record_unit($start_list_file, $unit);
942942- }
943943- # Don't reload the unit, reloading would fail
944944- delete %units_to_reload{$unit};
945945- unrecord_unit($reload_list_file, $unit);
946946- }
947947- }
948948-}
949949-# Reload units that need it. This includes remounting changed mount
950950-# units.
951951-if (scalar(keys(%units_to_reload)) > 0) {
952952- print STDERR "reloading the following units: ", join(", ", sort(keys(%units_to_reload))), "\n";
953953- system("$new_systemd/bin/systemctl", "reload", "--", sort(keys(%units_to_reload))) == 0 or $res = 4;
954954- unlink($reload_list_file);
955955-}
956956-957957-# Restart changed services (those that have to be restarted rather
958958-# than stopped and started).
959959-if (scalar(keys(%units_to_restart)) > 0) {
960960- print STDERR "restarting the following units: ", join(", ", sort(keys(%units_to_restart))), "\n";
961961- system("$new_systemd/bin/systemctl", "restart", "--", sort(keys(%units_to_restart))) == 0 or $res = 4;
962962- unlink($restart_list_file);
963963-}
964964-965965-# Start all active targets, as well as changed units we stopped above.
966966-# The latter is necessary because some may not be dependencies of the
967967-# targets (i.e., they were manually started). FIXME: detect units
968968-# that are symlinks to other units. We shouldn't start both at the
969969-# same time because we'll get a "Failed to add path to set" error from
970970-# systemd.
971971-my @units_to_start_filtered = filter_units(\%units_to_start);
972972-if (scalar(@units_to_start_filtered)) {
973973- print STDERR "starting the following units: ", join(", ", @units_to_start_filtered), "\n"
974974-}
975975-system("$new_systemd/bin/systemctl", "start", "--", sort(keys(%units_to_start))) == 0 or $res = 4;
976976-unlink($start_list_file);
977977-978978-979979-# Print failed and new units.
980980-my (@failed, @new);
981981-my $active_new = get_active_units();
982982-while (my ($unit, $state) = each(%{$active_new})) {
983983- if ($state->{state} eq "failed") {
984984- push(@failed, $unit);
985985- next;
986986- }
987987-988988- if ($state->{substate} eq "auto-restart") {
989989- # A unit in auto-restart substate is a failure *if* it previously failed to start
990990- open(my $main_status_fd, "-|", "$new_systemd/bin/systemctl", "show", "--value", "--property=ExecMainStatus", $unit) || die("Unable to call 'systemctl show'");
991991- my $main_status = do { local $/ = undef; <$main_status_fd> };
992992- close($main_status_fd) || die("Unable to close 'systemctl show' fd");
993993- chomp($main_status);
994994-995995- if ($main_status ne "0") {
996996- push(@failed, $unit);
997997- next;
998998- }
999999- }
10001000-10011001- # Ignore scopes since they are not managed by this script but rather
10021002- # created and managed by third-party services via the systemd dbus API.
10031003- # This only lists units that are not failed (including ones that are in auto-restart but have not failed previously)
10041004- if ($state->{state} ne "failed" && !defined($active_cur->{$unit}) && $unit !~ /\.scope$/msx) {
10051005- push(@new, $unit);
10061006- }
10071007-}
10081008-10091009-if (scalar(@new) > 0) {
10101010- print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
10111011-}
10121012-10131013-if (scalar(@failed) > 0) {
10141014- my @failed_sorted = sort(@failed);
10151015- print STDERR "warning: the following units failed: ", join(", ", @failed_sorted), "\n\n";
10161016- system("$new_systemd/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2");
10171017- $res = 4;
10181018-}
10191019-10201020-if ($res == 0) {
10211021- syslog(LOG_NOTICE, "finished switching to system configuration $toplevel");
10221022-} else {
10231023- syslog(LOG_ERR, "switching to system configuration $toplevel failed (status $res)");
10241024-}
10251025-10261026-close($stc_lock) or die "Could not close lock - $!";
10271027-exit($res);
···55 ...
66}:
7788-let
99- perlWrapped = pkgs.perl.withPackages (
1010- p: with p; [
1111- ConfigIniFiles
1212- FileSlurp
1313- ]
1414- );
1515-in
168{
1717- options.system.switch = {
1818- enable = lib.mkOption {
1919- type = lib.types.bool;
2020- default = true;
2121- description = ''
2222- Whether to include the capability to switch configurations.
99+ imports = [
1010+ (lib.mkRemovedOptionModule [ "system" "switch" "enableNg" ] ''
1111+ This option controlled the usage of the new switch-to-configuration-ng,
1212+ which is now the only switch-to-configuration implementation. This option
1313+ can be removed from configuration. If there are outstanding issues
1414+ preventing you from using the new implementation, please open an issue on
1515+ GitHub.
1616+ '')
1717+ ];
23182424- Disabling this makes the system unable to be reconfigured via `nixos-rebuild`.
1919+ options.system.switch.enable = lib.mkOption {
2020+ type = lib.types.bool;
2121+ default = true;
2222+ description = ''
2323+ Whether to include the capability to switch configurations.
25242626- This is good for image based appliances where updates are handled
2727- outside the image. Reducing features makes the image lighter and
2828- slightly more secure.
2929- '';
3030- };
2525+ Disabling this makes the system unable to be reconfigured via `nixos-rebuild`.
31263232- enableNg = lib.mkOption {
3333- type = lib.types.bool;
3434- default = config.system.switch.enable;
3535- defaultText = lib.literalExpression "config.system.switch.enable";
3636- description = ''
3737- Whether to use `switch-to-configuration-ng`, the Rust-based
3838- re-implementation of the original Perl `switch-to-configuration`.
3939- '';
4040- };
2727+ This is good for image based appliances where updates are handled
2828+ outside the image. Reducing features makes the image lighter and
2929+ slightly more secure.
3030+ '';
4131 };
42324343- config = lib.mkMerge [
4444- (lib.mkIf (config.system.switch.enable && !config.system.switch.enableNg) {
4545- warnings = [
4646- ''
4747- The Perl implementation of switch-to-configuration will be deprecated
4848- and removed in the 25.05 release of NixOS. Please migrate to the
4949- newer implementation by removing `system.switch.enableNg = false`
5050- from your configuration. If you are unable to migrate due to any
5151- issues with the new implementation, please create an issue and tag
5252- the maintainers of `switch-to-configuration-ng`.
5353- ''
5454- ];
3333+ config = lib.mkIf config.system.switch.enable {
3434+ # Use a subshell so we can source makeWrapper's setup hook without
3535+ # affecting the rest of activatableSystemBuilderCommands.
3636+ system.activatableSystemBuilderCommands = ''
3737+ (
3838+ source ${pkgs.buildPackages.makeWrapper}/nix-support/setup-hook
55395656- system.activatableSystemBuilderCommands = ''
5740 mkdir $out/bin
5858- substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \
5959- --subst-var out \
6060- --subst-var-by toplevel ''${!toplevelVar} \
6161- --subst-var-by coreutils "${pkgs.coreutils}" \
6262- --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \
6363- --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \
6464- --subst-var-by preSwitchCheck ${lib.escapeShellArg config.system.preSwitchChecksScript} \
6565- --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \
6666- --subst-var-by perl "${perlWrapped}" \
6767- --subst-var-by shell "${pkgs.bash}/bin/sh" \
6868- --subst-var-by su "${pkgs.shadow.su}/bin/su" \
6969- --subst-var-by systemd "${config.systemd.package}" \
7070- --subst-var-by utillinux "${pkgs.util-linux}" \
7171- ;
7272-7373- chmod +x $out/bin/switch-to-configuration
7474- ${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
7575- if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then
7676- echo "switch-to-configuration syntax is not valid:"
7777- echo "$output"
7878- exit 1
7979- fi
8080- ''}
8181- '';
8282- })
8383- (lib.mkIf config.system.switch.enableNg {
8484- # Use a subshell so we can source makeWrapper's setup hook without
8585- # affecting the rest of activatableSystemBuilderCommands.
8686- system.activatableSystemBuilderCommands = ''
8787- (
8888- source ${pkgs.buildPackages.makeWrapper}/nix-support/setup-hook
8989-9090- mkdir $out/bin
9191- ln -sf ${lib.getExe pkgs.switch-to-configuration-ng} $out/bin/switch-to-configuration
9292- wrapProgram $out/bin/switch-to-configuration \
9393- --set OUT $out \
9494- --set TOPLEVEL ''${!toplevelVar} \
9595- --set DISTRO_ID ${lib.escapeShellArg config.system.nixos.distroId} \
9696- --set INSTALL_BOOTLOADER ${lib.escapeShellArg config.system.build.installBootLoader} \
9797- --set PRE_SWITCH_CHECK ${lib.escapeShellArg config.system.preSwitchChecksScript} \
9898- --set LOCALE_ARCHIVE ${config.i18n.glibcLocales}/lib/locale/locale-archive \
9999- --set SYSTEMD ${config.systemd.package}
100100- )
101101- '';
102102- })
103103- ];
104104-4141+ ln -sf ${lib.getExe pkgs.switch-to-configuration-ng} $out/bin/switch-to-configuration
4242+ wrapProgram $out/bin/switch-to-configuration \
4343+ --set OUT $out \
4444+ --set TOPLEVEL ''${!toplevelVar} \
4545+ --set DISTRO_ID ${lib.escapeShellArg config.system.nixos.distroId} \
4646+ --set INSTALL_BOOTLOADER ${lib.escapeShellArg config.system.build.installBootLoader} \
4747+ --set PRE_SWITCH_CHECK ${lib.escapeShellArg config.system.preSwitchChecksScript} \
4848+ --set LOCALE_ARCHIVE ${config.i18n.glibcLocales}/lib/locale/locale-archive \
4949+ --set SYSTEMD ${config.systemd.package}
5050+ )
5151+ '';
5252+ };
10553}
···11-# This test does a basic functionality check for all bird variants and demonstrates a use
22-# of the preCheckConfig option.
33-41{
55- system ? builtins.currentSystem,
66- pkgs ? import ../.. {
77- inherit system;
88- config = { };
99- },
22+ runTest,
33+ package,
104}:
115126let
1313- inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
1414- inherit (pkgs.lib) optionalString;
1515-167 makeBirdHost =
178 hostId:
189 { pkgs, ... }:
···3324 };
34253526 services.bird = {
2727+ inherit package;
2828+3629 enable = true;
37303831 config = ''
···10699 ];
107100 };
108101in
109109-makeTest {
110110- name = "bird";
102102+{
103103+ twoNodeOSPF = runTest {
104104+ name = "bird-twoNodeOSPF";
111105112112- nodes.host1 = makeBirdHost "1";
113113- nodes.host2 = makeBirdHost "2";
106106+ nodes.host1 = makeBirdHost "1";
107107+ nodes.host2 = makeBirdHost "2";
114108115115- testScript = ''
116116- start_all()
109109+ testScript = ''
110110+ start_all()
117111118118- host1.wait_for_unit("bird.service")
119119- host2.wait_for_unit("bird.service")
120120- host1.succeed("systemctl reload bird.service")
112112+ host1.wait_for_unit("bird.service")
113113+ host2.wait_for_unit("bird.service")
121114122122- with subtest("Waiting for advertised IPv4 routes"):
123123- host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
124124- host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
125125- with subtest("Waiting for advertised IPv6 routes"):
126126- host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
127127- host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
115115+ host1.succeed("bird --version")
116116+ host2.succeed("bird --version")
128117129129- with subtest("Check fake routes in preCheckConfig do not exists"):
130130- host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
131131- host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
118118+ host1.succeed("systemctl reload bird.service")
132119133133- host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
134134- host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
135135- '';
120120+ with subtest("Waiting for advertised IPv4 routes"):
121121+ host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
122122+ host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
123123+ with subtest("Waiting for advertised IPv6 routes"):
124124+ host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
125125+ host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
126126+127127+ with subtest("Check fake routes in preCheckConfig do not exists"):
128128+ host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
129129+ host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
130130+131131+ host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
132132+ host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
133133+ '';
134134+ };
136135}
+1-1
nixos/tests/switch-test.nix
···663663 '';
664664665665 # Returns a comma separated representation of the given list in sorted
666666- # order, that matches the output format of switch-to-configuration.pl
666666+ # order, that matches the output format of switch-to-configuration
667667 sortedUnits = xs: lib.concatStringsSep ", " (builtins.sort builtins.lessThan xs);
668668669669 dbusService =
···6464K3s has a config setting `prefer-bundled-bin` (and CLI flag `--prefer-bundled-bin`) that makes k3s use binaries from the `/var/lib/rancher/k3s/data/current/bin/aux/` directory, as unpacked by the k3s binary, before the system `$PATH`.
6565This works with the official distribution of k3s but not with the package from nixpkgs, as it does not bundle the upstream binaries from [`k3s-root`](https://github.com/k3s-io/k3s-root) into the k3s binary.
6666Thus the `prefer-bundled-bin` setting **cannot** be used to work around issues (like [this `mount` regression](https://github.com/util-linux/util-linux/issues/3474)) with binaries used/called by the kubelet.
6767+6868+### Building from a different source
6969+7070+Because the package is split into multiple derivations and the build process is generally more complex, it is not very obvious how to build k3s from a different source (fork or arbitrary commit).
7171+7272+To build k3s from a different source, you must use `.override` together with `overrideBundleAttrs` (for the k3sBundle derivation) and another `.overrideAttrs` (for the final derivation):
7373+7474+```nix
7575+{ fetchgit, k3s }:
7676+let
7777+ k3sRepo = fetchgit {
7878+ url = "https://github.com/k3s-io/k3s";
7979+ rev = "99d91538b1327da933356c318dc8040335fbb66c";
8080+ hash = "sha256-vVqZzVp0Tea27s8HDVq4SgqlbHBdZcFzNKmPFi0Yktk=";
8181+ };
8282+ vendorHash = "sha256-jrPVY+FVZV9wlbik/I35W8ChcLrHlYbLAwUYU16mJLM=";
8383+in
8484+(k3s.override {
8585+ overrideBundleAttrs = {
8686+ src = k3sRepo;
8787+ inherit vendorHash;
8888+ };
8989+}).overrideAttrs
9090+ {
9191+ src = k3sRepo;
9292+ inherit vendorHash;
9393+ }
9494+```
9595+9696+- Additionally to `overrideBundleAttrs` there are also: `overrideCniPluginsAttrs` and `overrideContainerdAttrs`.
9797+- `k3s --version` still prints the commit SHA (`k3sCommit` passed into `builder.nix`) from the "base" package instead of the actually used `rev`.
9898+- Depending on the changes made in the fork / commit, the `k3s.override` (without the `overrideAttrs` of the final derivation) might already be enough.
9999+- If the commit is for a different version of k3s, make sure to use the correct "base" package, e.g., `k3s_1_31.override`. Otherwise the build fails with `Tagged version 'v1.33.1+k3s1' does not match expected version 'v1.31.9[+-]*'`
100100+- When adding an entirely new k3s version by calling `builder.nix`, keep in mind that the `k3sCommit` parameter is not used as the `k3sRepo` `rev` (it uses `v${k3sVersion}`). Therefore, you additionally must override the package, as shown above.
···75757676mkDerivation rec {
7777 pname = "recoll";
7878- version = "1.39.1";
7878+ version = "1.43.2";
79798080 src = fetchurl {
8181 url = "https://www.recoll.org/${pname}-${version}.tar.gz";
8282- hash = "sha256-Eeadj/AnuztCb7VIYEy4hKbduH3CzK53tADvI9+PWmQ=";
8282+ hash = "sha256-FbDXknumjktcikOfAe4FKtPmggJGGHasq8dpD+8mNzE=";
8383 };
84848585 mesonFlags =
···107107 ];
108108109109 env.NIX_CFLAGS_COMPILE = toString [
110110- "-DNIXPKGS"
111110 "-fpermissive" # libxml2-2.12 changed const qualifiers
112111 ];
113112114113 patches = [
115115- # fix "No/bad main configuration file" error
116116- ./fix-datadir.patch
117114 # use the same configure based build for darwin as linux
118115 ./0001-no-qtgui-darwin-bundle.patch
119116 ];
-13
pkgs/applications/search/recoll/fix-datadir.patch
···11-diff --git a/utils/rclutil.cpp b/utils/rclutil.cpp
22-index 6bafc119..d997cd17 100644
33---- a/utils/rclutil.cpp
44-+++ b/utils/rclutil.cpp
55-@@ -279,7 +279,7 @@ const string& path_pkgdatadir()
66- "a subfolder of the installation directory. \n"
77- "Please set the RECOLL_DATADIR environment variable to point to it\n"
88- "(e.g. setx RECOLL_DATADIR \"C:/Program Files (X86)/Recoll/Share)\"\n";
99--#elif defined(__APPLE__) && defined(RECOLL_AS_MAC_BUNDLE)
1010-+#elif defined(__APPLE__) && defined(RECOLL_AS_MAC_BUNDLE) && defined(NIXPKGS)
1111- // The package manager builds (Macports, Homebrew, Nixpkgs ...) all arrange to set a proper
1212- // compiled value for RECOLL_DATADIR. We can't do this when building a native bundle with
1313- // QCreator, in which case we use the executable location.
···129129 # Relies on FHS
130130 # Could not read ELF interpreter from any of the following paths: /bin/sh, /usr/bin/env, /bin/dash, /bin/ls
131131 "test_new_selected_python"
132132+133133+ # https://github.com/pypa/hatch/issues/2006
134134+ "test_project_location_basic_set_first_project"
135135+ "test_project_location_complex_set_first_project"
132136 ]
133137 ++ lib.optionals stdenv.hostPlatform.isDarwin [
134138 # This test assumes it is running on macOS with a system shell on the PATH.
···11-{
22- lib,
33- stdenv,
44- fetchurl,
55- pkg-config,
66- gtk2,
77- synergy,
88-}:
99-1010-stdenv.mkDerivation rec {
1111- pname = "quicksynergy";
1212- version = "0.9.0";
1313- src = fetchurl {
1414- url = "mirror://sourceforge/project/quicksynergy/Linux/${version}/quicksynergy-${version}.tar.gz";
1515- sha256 = "1pi8503bg8q1psw50y6d780i33nnvfjqiy9vnr3v52pdcfip8pix";
1616- };
1717-1818- nativeBuildInputs = [ pkg-config ];
1919- buildInputs = [
2020- gtk2
2121- synergy
2222- ];
2323- preBuild = "
2424- sed -i 's@/usr/bin@${synergy.out}/bin@' src/synergy_config.c
2525- ";
2626- meta = {
2727- description = "GUI application to share mouse and keyboard between computers";
2828- longDescription = "
2929- QuickSynergy is a graphical interface (GUI) for easily configuring
3030- Synergy2, an application that allows the user to share his mouse and
3131- keyboard between two or more computers.
3232-3333- Without the need for any external hardware, Synergy2 uses the TCP-IP
3434- protocol to share the resources, even between machines with different
3535- operating systems, such as Mac OS, Linux and Windows.
3636-3737- Remember to open port 24800 (used by synergys program) if you want to
3838- host mouse and keyboard.";
3939- homepage = "https://sourceforge.net/projects/quicksynergy/";
4040- license = lib.licenses.gpl2;
4141- maintainers = [ lib.maintainers.spinus ];
4242- platforms = lib.platforms.linux;
4343- mainProgram = "quicksynergy";
4444- };
4545-}
···5858 nativeCheckInputs = with python3Packages; [
5959 pytestCheckHook
6060 pytest-mock
6161- pytest-cov
6161+ pytest-cov-stub
6262 ];
63636464 # the -cli symlink is just to maintain compabilility with older versions where
···30303131 meta = with lib; {
3232 homepage = "https://adobe-fonts.github.io/source-sans/";
3333- description = "Sans serif font family for user interface environments";
3333+ description = "Sans serif font family for user interface environments (version of Source Sans before being renamed)";
3434 license = licenses.ofl;
3535 platforms = platforms.all;
3636 maintainers = with maintainers; [ ttuegel ];
···11# switch-to-configuration-ng
2233-This program is a reimplementation of [switch-to-configuration](/nixos/modules/system/activation/switch-to-configuration.pl) in Rust. The goal is to be compatible in as many ways as possible to the original implementation, at least as long as the original is still in nixpkgs. Any behavioral modifications to this program should also be implemented in the original, and vice versa.
33+This program implements the switching/updating of NixOS systems. It starts with the exising running configuration at `/run/current-system` and handles the migration to a new configuration, built from a NixOS configuration's `config.system.build.toplevel` derivation.
44+55+For more information on what happens during a switch, see [what-happens-during-a-system-switch](../../../../nixos/doc/manual/development/what-happens-during-a-system-switch.chapter.md).
4657## Build in a devshell
68
···11{
22- version = "2025.1";
22+ version = "2025.2";
3344 # To get these, run:
55 #
66 # ```
77- # for tool in alfred batctl batman-adv; do nix-prefetch-url https://downloads.open-mesh.org/batman/releases/batman-adv-2025.1/$tool-2025.1.tar.gz --type sha256 | xargs nix hash convert --hash-algo sha256 --to sri; done
77+ # for tool in alfred batctl batman-adv; do nix-prefetch-url https://downloads.open-mesh.org/batman/releases/batman-adv-2025.2/$tool-2025.2.tar.gz --type sha256 | xargs nix hash convert --hash-algo sha256 --to sri; done
88 # ```
99 sha256 = {
1010- alfred = "sha256-f7iz8cxOxIjo1D/ZFd2gp831thG/OdYN3rRIasACXxg=";
1111- batctl = "sha256-IPii4TWgeKrBblyK1TWhKhVc8Lea8YPeX7F9qVe8JHg=";
1212- batman-adv = "sha256-A61CkpeWH7Os2cLIBkMtA3sO16rA8KHmReMq9SELmOE=";
1010+ alfred = "sha256-Q0fR5LB5Svv2sXGoV7mjx9UaKR/FTxbNrZLH99HNtRo=";
1111+ batctl = "sha256-q2wDRqFvER57n9XOVczd633grXdCvi9FExfrQo9qCpY=";
1212+ batman-adv = "sha256-FsRfi7jzBTcc2Q6IhjDPslHCsYnlUypSepNvo1ukl/c=";
1313 };
1414}
+12-6
pkgs/os-specific/linux/fuse/common.nix
···6161 meson
6262 ninja
6363 pkg-config
6464- udevCheckHook
6564 ]
6565+ ++ lib.optionals (!stdenv.hostPlatform.isMusl) [ udevCheckHook ] # inf rec on musl, so skip
6666 else
6767 [
6868 autoreconfHook
···7676 "man"
7777 ] ++ lib.optional isFuse3 "udev";
78787979- mesonFlags = lib.optionals isFuse3 [
8080- "-Dudevrulesdir=/udev/rules.d"
8181- "-Duseroot=false"
8282- "-Dinitscriptdir="
8383- ];
7979+ mesonFlags = lib.optionals isFuse3 (
8080+ [
8181+ "-Dudevrulesdir=/udev/rules.d"
8282+ "-Duseroot=false"
8383+ "-Dinitscriptdir="
8484+ ]
8585+ # examples fail to build on musl
8686+ # error: ‘RENAME_NOREPLACE’ was not declared in this scope
8787+ # lib.optionals instead of lib.mesonBool to avoid rebuilds
8888+ ++ lib.optionals (stdenv.hostPlatform.isMusl) [ "-Dexamples=false" ]
8989+ );
84908591 # Ensure that FUSE calls the setuid wrapper, not
8692 # $out/bin/fusermount. It falls back to calling fusermount in
+3-3
pkgs/os-specific/linux/zfs/2_3.nix
···1111 # this attribute is the correct one for this package.
1212 kernelModuleAttribute = "zfs_2_3";
1313 # check the release notes for compatible kernels
1414- kernelCompatible = kernel: kernel.kernelOlder "6.15";
1414+ kernelCompatible = kernel: kernel.kernelOlder "6.16";
15151616 # this package should point to the latest release.
1717- version = "2.3.2";
1717+ version = "2.3.3";
18181919 tests =
2020 {
···2929 amarshall
3030 ];
31313232- hash = "sha256-+DqpIgHCVi0fDOqvKwaGXIiiXw8xEnlv2tgRwgLX9G8=";
3232+ hash = "sha256-NXAbyGBfpzWfm4NaP1/otTx8fOnoRV17343qUMdQp5U=";
3333}
+3-3
pkgs/os-specific/linux/zfs/unstable.nix
···99 # this attribute is the correct one for this package.
1010 kernelModuleAttribute = "zfs_unstable";
1111 # check the release notes for compatible kernels
1212- kernelCompatible = kernel: kernel.kernelOlder "6.15";
1212+ kernelCompatible = kernel: kernel.kernelOlder "6.16";
13131414 # this package should point to a version / git revision compatible with the latest kernel release
1515 # IMPORTANT: Always use a tagged release candidate or commits from the
1616 # zfs-<version>-staging branch, because this is tested by the OpenZFS
1717 # maintainers.
1818- version = "2.3.2";
1818+ version = "2.3.3";
1919 # rev = "";
20202121 tests = {
2222 inherit (nixosTests.zfs) unstable;
2323 };
24242525- hash = "sha256-+DqpIgHCVi0fDOqvKwaGXIiiXw8xEnlv2tgRwgLX9G8=";
2525+ hash = "sha256-NXAbyGBfpzWfm4NaP1/otTx8fOnoRV17343qUMdQp5U=";
26262727 extraLongDescription = ''
2828 This is "unstable" ZFS, and will usually be a pre-release version of ZFS.
···11{
22 lib,
33 stdenv,
44- fetchurl,
44+ fetchFromGitHub,
55 fetchpatch,
66 callPackage,
77 autoreconfHook,
88 pkg-config,
99 libtool,
1010+ bison,
1111+ flex,
1212+ perl,
1013 nixosTests,
1114 ...
1215}@args:
1316let
1417 plugins = callPackage ./plugins.nix args;
1518in
1616-stdenv.mkDerivation rec {
1919+stdenv.mkDerivation (finalAttrs: {
2020+ pname = "collectd";
1721 version = "5.12.0";
1818- pname = "collectd";
19222020- src = fetchurl {
2121- url = "https://collectd.org/files/${pname}-${version}.tar.bz2";
2222- sha256 = "1mh97afgq6qgmpvpr84zngh58m0sl1b4wimqgvvk376188q09bjv";
2323+ src = fetchFromGitHub {
2424+ owner = "collectd";
2525+ repo = "collectd";
2626+ tag = "collectd-${finalAttrs.version}";
2727+ hash = "sha256-UTlCY1GPRpbdQFLFUDjNr1PgEdGv4WNtjr8TYbxHK5A=";
2328 };
24293030+ # All of these are going to be included in the next release
2531 patches = [
2632 # fix -t never printing syntax errors
2733 # should be included in next release
2834 (fetchpatch {
3535+ name = "fix-broken-dash-t-option.patch";
2936 url = "https://github.com/collectd/collectd/commit/3f575419e7ccb37a3b10ecc82adb2e83ff2826e1.patch";
3030- sha256 = "0jwjdlfl0dp7mlbwygp6h0rsbaqfbgfm5z07lr5l26z6hhng2h2y";
3737+ hash = "sha256-XkDxLITmG0FLpgf8Ut1bDqulM4DmPs8Xrec2QB1tkks=";
3138 })
3239 (fetchpatch {
3340 name = "no_include_longintrepr.patch";
···3946 nativeBuildInputs = [
4047 pkg-config
4148 autoreconfHook
4949+ bison
5050+ flex
5151+ perl # for pod2man
4252 ];
5353+4354 buildInputs = [
4455 libtool
4556 ] ++ plugins.buildInputs;
···5263 ++ plugins.configureFlags
5364 ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ "--with-fp-layout=nothing" ];
54656666+ # Used in `src/virt.c`
6767+ env.NIX_CFLAGS_COMPILE = "-DATTRIBUTE_UNUSED=__attribute__((unused))";
6868+5569 # do not create directories in /var during installPhase
5670 postConfigure = ''
5757- substituteInPlace Makefile --replace '$(mkinstalldirs) $(DESTDIR)$(localstatedir)/' '#'
7171+ substituteInPlace Makefile --replace-fail '$(mkinstalldirs) $(DESTDIR)$(localstatedir)/' '#'
5872 '';
59736074 postInstall = ''
···6983 inherit (nixosTests) collectd;
7084 };
71857272- meta = with lib; {
8686+ meta = {
7387 description = "Daemon which collects system performance statistics periodically";
7488 homepage = "https://collectd.org";
7575- license = licenses.gpl2Plus;
7676- platforms = platforms.unix;
7777- maintainers = with maintainers; [ bjornfor ];
8989+ license = lib.licenses.gpl2Plus;
9090+ platforms = lib.platforms.unix;
9191+ maintainers = with lib.maintainers; [ bjornfor ];
7892 };
7979-}
9393+})
+1
pkgs/top-level/aliases.nix
···16811681 quicklispPackagesGCL = throw "Lisp packages have been redesigned. See 'lisp-modules' in the nixpkgs manual."; # Added 2024-05-07
16821682 quicklispPackagesSBCL = throw "Lisp packages have been redesigned. See 'lisp-modules' in the nixpkgs manual."; # Added 2024-05-07
16831683 quickserve = throw "'quickserve' has been removed because its upstream is unavailable"; # Added 2025-05-10
16841684+ quicksynergy = throw "'quicksynergy' has been removed due to lack of maintenance upstream. Consider using 'deskflow' instead."; # Added 2025-06-18
16841685 qv2ray = throw "'qv2ray' has been removed as it was unmaintained"; # Added 2025-06-03
16851686 qxw = throw "'qxw' has been removed due to lack of maintenance upstream. Consider using 'crosswords' instead"; # Added 2024-10-19
16861687