git.iko.soy/typeable/nixpkgs
on master help sign in
Merge master into staging-next
commit38910351b753e23a1731fd95fa99765d3a21dcc5 authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> dateSun 13 Mar 2022, 18:01 (5 years ago) parent72b55bc2a72d02
46 files changed+757−349
nixos/doc/manual/development/unit-handling.section.md+5−1 nixos/doc/manual/from_md/development/unit-handling.section.xml+8−2 nixos/doc/manual/from_md/release-notes/rl-2205.section.xml+11 nixos/doc/manual/release-notes/rl-2205.section.md+2 nixos/modules/module-list.nix+1 nixos/modules/programs/captive-browser.nix+19−1 nixos/modules/services/audio/squeezelite.nix+17−21 nixos/modules/services/misc/jellyfin.nix+2−1 nixos/modules/services/system/earlyoom.nix+70−85 nixos/modules/services/system/systembus-notify.nix+27 nixos/modules/system/activation/switch-to-configuration.pl+168−91 nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py+16−5 nixos/tests/switch-test.nix+147 pkgs/applications/audio/squeezelite/default.nix+48−30 pkgs/applications/editors/sigil/default.nix+2−2 pkgs/applications/graphics/nsxiv/default.nix+2−2 pkgs/applications/misc/systembus-notify/default.nix+39−5 pkgs/applications/networking/cluster/cloudfoundry-cli/default.nix+3−3 pkgs/applications/networking/instant-messengers/qtox/default.nix+2−2 pkgs/applications/video/go-chromecast/default.nix+3−3 pkgs/applications/virtualization/docker-slim/default.nix+2−2 pkgs/applications/window-managers/berry/default.nix+1−1 pkgs/applications/window-managers/icewm/default.nix+9−8 pkgs/applications/window-managers/labwc/default.nix+3−8 pkgs/applications/window-managers/labwc/relax-the-version-constraint-for-wlroots.patch−29 pkgs/development/libraries/cimg/default.nix+2−2 pkgs/development/libraries/elpa/default.nix+2−2 pkgs/development/libraries/zchunk/default.nix+3−2 pkgs/development/python-modules/allure-behave/default.nix+38 pkgs/development/python-modules/wled/default.nix+2−2 pkgs/development/tools/analysis/actionlint/default.nix+3−3 pkgs/development/tools/analysis/flow/default.nix+2−2 pkgs/development/tools/buildkit/default.nix+2−2 pkgs/development/tools/cloud-nuke/default.nix+2−2 pkgs/development/tools/ocaml/dune/3.nix+2−2 pkgs/development/tools/wllvm/default.nix+2−3 pkgs/servers/sql/postgresql/ext/rum.nix+31 pkgs/servers/sql/postgresql/packages.nix+2 pkgs/shells/tcsh/default.nix+8−7 pkgs/tools/misc/nncp/default.nix+2−2 pkgs/tools/networking/minio-client/default.nix+3−3 pkgs/tools/networking/ytcc/default.nix+2−2 pkgs/tools/security/sops/default.nix+3−3 pkgs/tools/security/swtpm/default.nix+34−7 pkgs/top-level/all-packages.nix+3−1 pkgs/top-level/python-packages.nix+2
nixos/doc/manual/development/unit-handling.section.md+5−1
@@ -17,7 +17,8 @@ checks:
1717 them and comparing their contents. If they are different but only
1818 `X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit.
1919 The NixOS module system allows setting these triggers with the option
20− [systemd.services.\<name\>.reloadTriggers](#opt-systemd.services). If the
20+ [systemd.services.\<name\>.reloadTriggers](#opt-systemd.services). There are
21+ some additional keys in the `[Unit]` section that are ignored as well. If the
2122 unit files differ in any way, the following actions are performed:
2223
2324 - `.path` and `.slice` units are ignored. There is no need to restart them
@@ -33,6 +34,9 @@ checks:
3334 - The rest of the units (mostly `.service` units) are then **reload**ed if
3435 `X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed
3536 via [systemd.services.\<name\>.reloadIfChanged](#opt-systemd.services)).
37+ A little exception is done for units that were deactivated in the meantime,
38+ for example because they require a unit that got stopped before. These
39+ are **start**ed instead of reloaded.
3640
3741 - If the reload flag is not set, some more flags decide if the unit is
3842 skipped. These flags are `X-RestartIfChanged` in the `[Service]` section
nixos/doc/manual/from_md/development/unit-handling.section.xml+8−2
@@ -38,8 +38,9 @@
3838 <emphasis role="strong">reload</emphasis> the unit. The NixOS
3939 module system allows setting these triggers with the option
4040 <link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadTriggers</link>.
41− If the unit files differ in any way, the following actions are
42− performed:
41+ There are some additional keys in the <literal>[Unit]</literal>
42+ section that are ignored as well. If the unit files differ in
43+ any way, the following actions are performed:
4344 </para>
4445 <itemizedlist>
4546 <listitem>
@@ -71,6 +72,11 @@
7172 <literal>[Service]</literal> section is set to
7273 <literal>true</literal> (exposed via
7374 <link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadIfChanged</link>).
75+ A little exception is done for units that were deactivated
76+ in the meantime, for example because they require a unit
77+ that got stopped before. These are
78+ <emphasis role="strong">start</emphasis>ed instead of
79+ reloaded.
7480 </para>
7581 </listitem>
7682 <listitem>
nixos/doc/manual/from_md/release-notes/rl-2205.section.xml+11
@@ -249,6 +249,17 @@
249249 <link linkend="opt-services.prosody-filer.enable">services.prosody-filer</link>.
250250 </para>
251251 </listitem>
252+ <listitem>
253+ <para>
254+ <link xlink:href="https://github.com/rfjakob/systembus-notify">systembus-notify</link>,
255+ allow system level notifications to reach the users. Available
256+ as
257+ <link xlink:href="opt-services.systembus-notify.enable">services.systembus-notify</link>.
258+ Please keep in mind that this service should only be enabled
259+ on machines with fully trusted users, as any local user is
260+ able to DoS user sessions by spamming notifications.
261+ </para>
262+ </listitem>
252263 <listitem>
253264 <para>
254265 <link xlink:href="https://github.com/audreyt/ethercalc">ethercalc</link>,
nixos/doc/manual/release-notes/rl-2205.section.md+2
@@ -72,6 +72,8 @@ In addition to numerous new and upgraded packages, this release has the followin
7272
7373- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).
7474
75+- [systembus-notify](https://github.com/rfjakob/systembus-notify), allow system level notifications to reach the users. Available as [services.systembus-notify](opt-services.systembus-notify.enable). Please keep in mind that this service should only be enabled on machines with fully trusted users, as any local user is able to DoS user sessions by spamming notifications.
76+
7577- [ethercalc](https://github.com/audreyt/ethercalc), an online collaborative
7678 spreadsheet. Available as [services.ethercalc](options.html#opt-services.ethercalc.enable).
7779
nixos/modules/module-list.nix+1
@@ -987,6 +987,7 @@
987987 ./services/system/nscd.nix
988988 ./services/system/saslauthd.nix
989989 ./services/system/self-deploy.nix
990+ ./services/system/systembus-notify.nix
990991 ./services/system/uptimed.nix
991992 ./services/torrent/deluge.nix
992993 ./services/torrent/flexget.nix
nixos/modules/programs/captive-browser.nix+19−1
@@ -1,8 +1,12 @@
11{ config, lib, pkgs, ... }:
22
3−with lib;
43let
54 cfg = config.programs.captive-browser;
5+
6+ inherit (lib)
7+ concatStringsSep escapeShellArgs optionalString
8+ literalExpression mkEnableOption mkIf mkOption mkOptionDefault types;
9+
610 browserDefault = chromium: concatStringsSep " " [
711 ''env XDG_CONFIG_HOME="$PREV_CONFIG_HOME"''
812 ''${chromium}/bin/chromium''
@@ -15,6 +19,15 @@ let
1519 ''-no-default-browser-check''
1620 ''http://cache.nixos.org/''
1721 ];
22+
23+ desktopItem = pkgs.makeDesktopItem {
24+ name = "captive-browser";
25+ desktopName = "Captive Portal Browser";
26+ exec = "/run/wrappers/bin/captive-browser";
27+ icon = "nix-snowflake";
28+ categories = [ "Network" ];
29+ };
30+
1831in
1932{
2033 ###### interface
@@ -84,6 +97,11 @@ in
8497 ###### implementation
8598
8699 config = mkIf cfg.enable {
100+ environment.systemPackages = [
101+ (pkgs.runCommandNoCC "captive-browser-desktop-item" { } ''
102+ install -Dm444 -t $out/share/applications ${desktopItem}/share/applications/*.desktop
103+ '')
104+ ];
87105
88106 programs.captive-browser.dhcp-dns =
89107 let
nixos/modules/services/audio/squeezelite.nix+17−21
@@ -1,50 +1,46 @@
11{ config, lib, pkgs, ... }:
22
3−with lib;
4−
53let
4+ inherit (lib) mkEnableOption mkIf mkOption optionalString types;
5+
66 dataDir = "/var/lib/squeezelite";
77 cfg = config.services.squeezelite;
8+ pkg = if cfg.pulseAudio then pkgs.squeezelite-pulse else pkgs.squeezelite;
9+ bin = "${pkg}/bin/${pkg.pname}";
810
9−in {
11+in
12+{
1013
1114 ###### interface
1215
13− options = {
14−
15− services.squeezelite= {
16+ options.services.squeezelite = {
17+ enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
1618
17− enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
18−
19− extraArguments = mkOption {
20− default = "";
21− type = types.str;
22− description = ''
23− Additional command line arguments to pass to Squeezelite.
24− '';
25− };
19+ pulseAudio = mkEnableOption "pulseaudio support";
2620
21+ extraArguments = mkOption {
22+ default = "";
23+ type = types.str;
24+ description = ''
25+ Additional command line arguments to pass to Squeezelite.
26+ '';
2727 };
28−
2928 };
3029
3130
3231 ###### implementation
3332
3433 config = mkIf cfg.enable {
35−
36− systemd.services.squeezelite= {
34+ systemd.services.squeezelite = {
3735 wantedBy = [ "multi-user.target" ];
3836 after = [ "network.target" "sound.target" ];
3937 description = "Software Squeezebox emulator";
4038 serviceConfig = {
4139 DynamicUser = true;
42− ExecStart = "${pkgs.squeezelite}/bin/squeezelite -N ${dataDir}/player-name ${cfg.extraArguments}";
40+ ExecStart = "${bin} -N ${dataDir}/player-name ${cfg.extraArguments}";
4341 StateDirectory = builtins.baseNameOf dataDir;
4442 SupplementaryGroups = "audio";
4543 };
4644 };
47−
4845 };
49−
5046}
nixos/modules/services/misc/jellyfin.nix+2−1
@@ -70,7 +70,8 @@ in
7070 LockPersonality = true;
7171
7272 PrivateTmp = true;
73− PrivateDevices = true;
73+ # Disabled to allow Jellyfin to access hw accel devices endpoints
74+ # PrivateDevices = true;
7475 PrivateUsers = true;
7576
7677 # Disabled as it does not allow Jellyfin to interface with CUDA devices
nixos/modules/services/system/earlyoom.nix+70−85
@@ -1,81 +1,73 @@
11{ config, lib, pkgs, ... }:
22
3−with lib;
4−
53let
6− ecfg = config.services.earlyoom;
4+ cfg = config.services.earlyoom;
5+
6+ inherit (lib)
7+ mkDefault mkEnableOption mkIf mkOption types
8+ mkRemovedOptionModule
9+ concatStringsSep optional;
10+
711in
812{
9− options = {
10− services.earlyoom = {
13+ options.services.earlyoom = {
14+ enable = mkEnableOption "Early out of memory killing";
1115
12− enable = mkOption {
13− type = types.bool;
14− default = false;
15− description = ''
16− Enable early out of memory killing.
17− '';
18− };
16+ freeMemThreshold = mkOption {
17+ type = types.ints.between 1 100;
18+ default = 10;
19+ description = ''
20+ Minimum of availabe memory (in percent).
21+ If the free memory falls below this threshold and the analog is true for
22+ <option>services.earlyoom.freeSwapThreshold</option>
23+ the killing begins.
24+ '';
25+ };
1926
20− freeMemThreshold = mkOption {
21− type = types.int;
22− default = 10;
23− description = ''
24− Minimum of availabe memory (in percent).
25− If the free memory falls below this threshold and the analog is true for
26− <option>services.earlyoom.freeSwapThreshold</option>
27− the killing begins.
28− '';
29− };
27+ freeSwapThreshold = mkOption {
28+ type = types.ints.between 1 100;
29+ default = 10;
30+ description = ''
31+ Minimum of availabe swap space (in percent).
32+ If the available swap space falls below this threshold and the analog
33+ is true for <option>services.earlyoom.freeMemThreshold</option>
34+ the killing begins.
35+ '';
36+ };
3037
31− freeSwapThreshold = mkOption {
32− type = types.int;
33− default = 10;
34− description = ''
35− Minimum of availabe swap space (in percent).
36− If the available swap space falls below this threshold and the analog
37− is true for <option>services.earlyoom.freeMemThreshold</option>
38− the killing begins.
39− '';
40− };
38+ # TODO: remove or warn after 1.7 (https://github.com/rfjakob/earlyoom/commit/7ebc4554)
39+ ignoreOOMScoreAdjust = mkOption {
40+ type = types.bool;
41+ default = false;
42+ description = ''
43+ Ignore oom_score_adjust values of processes.
44+ '';
45+ };
4146
42− # TODO: remove or warn after 1.7 (https://github.com/rfjakob/earlyoom/commit/7ebc4554)
43− ignoreOOMScoreAdjust = mkOption {
44− type = types.bool;
45− default = false;
46− description = ''
47− Ignore oom_score_adjust values of processes.
48− '';
49− };
47+ enableDebugInfo = mkOption {
48+ type = types.bool;
49+ default = false;
50+ description = ''
51+ Enable debugging messages.
52+ '';
53+ };
5054
51− enableDebugInfo = mkOption {
52− type = types.bool;
53− default = false;
54− description = ''
55− Enable debugging messages.
56− '';
57− };
55+ enableNotifications = mkOption {
56+ type = types.bool;
57+ default = false;
58+ description = ''
59+ Send notifications about killed processes via the system d-bus.
5860
59− notificationsCommand = mkOption {
60− type = types.nullOr types.str;
61− default = null;
62− description = ''
63− This option is deprecated and ignored by earlyoom since 1.6.
64− Use <option>services.earlyoom.enableNotifications</option> instead.
65− '';
66− };
61+ WARNING: enabling this option (while convenient) should *not* be done on a
62+ machine where you do not trust the other users as it allows any other
63+ local user to DoS your session by spamming notifications.
6764
68− enableNotifications = mkOption {
69− type = types.bool;
70− default = false;
71− description = ''
72− Send notifications about killed processes via the system d-bus.
73− To actually see the notifications in your GUI session, you need to have
74− <literal>systembus-notify</literal> running as your user.
65+ To actually see the notifications in your GUI session, you need to have
66+ <literal>systembus-notify</literal> running as your user which this
67+ option handles.
7568
76− See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
77− '';
78− };
69+ See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
70+ '';
7971 };
8072 };
8173
@@ -83,37 +75,30 @@ in
8375 (mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] ''
8476 This option is deprecated and ignored by earlyoom since 1.2.
8577 '')
78+ (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] ''
79+ This option is deprecated and ignored by earlyoom since 1.6.
80+ '')
8681 ];
8782
88− config = mkIf ecfg.enable {
89− assertions = [
90− { assertion = ecfg.freeMemThreshold > 0 && ecfg.freeMemThreshold <= 100;
91− message = "Needs to be a positive percentage"; }
92− { assertion = ecfg.freeSwapThreshold > 0 && ecfg.freeSwapThreshold <= 100;
93− message = "Needs to be a positive percentage"; }
94− ];
95−
96− # TODO: reimplement this option as -N after 1.7 (https://github.com/rfjakob/earlyoom/commit/afe03606)
97− warnings = optional (ecfg.notificationsCommand != null)
98− "`services.earlyoom.notificationsCommand` is deprecated and ignored by earlyoom since 1.6.";
83+ config = mkIf cfg.enable {
84+ services.systembus-notify.enable = mkDefault cfg.enableNotifications;
9985
10086 systemd.services.earlyoom = {
10187 description = "Early OOM Daemon for Linux";
10288 wantedBy = [ "multi-user.target" ];
103− path = optional ecfg.enableNotifications pkgs.dbus;
89+ path = optional cfg.enableNotifications pkgs.dbus;
10490 serviceConfig = {
105− StandardOutput = "null";
10691 StandardError = "journal";
10792 ExecStart = concatStringsSep " " ([
10893 "${pkgs.earlyoom}/bin/earlyoom"
109− "-m ${toString ecfg.freeMemThreshold}"
110− "-s ${toString ecfg.freeSwapThreshold}"
111− ] ++ optional ecfg.ignoreOOMScoreAdjust "-i"
112− ++ optional ecfg.enableDebugInfo "-d"
113− ++ optional ecfg.enableNotifications "-n");
94+ "-m ${toString cfg.freeMemThreshold}"
95+ "-s ${toString cfg.freeSwapThreshold}"
96+ ]
97+ ++ optional cfg.ignoreOOMScoreAdjust "-i"
98+ ++ optional cfg.enableDebugInfo "-d"
99+ ++ optional cfg.enableNotifications "-n"
100+ );
114101 };
115102 };
116−
117− environment.systemPackages = optional ecfg.enableNotifications pkgs.systembus-notify;
118103 };
119104}
nixos/modules/services/system/systembus-notify.nixnew file+27
@@ -0,0 +1,27 @@
1+{ config, lib, pkgs, ... }:
2+
3+let
4+ cfg = config.services.systembus-notify;
5+
6+ inherit (lib) mkEnableOption mkIf;
7+
8+in
9+{
10+ options.services.systembus-notify = {
11+ enable = mkEnableOption ''
12+ System bus notification support
13+
14+ WARNING: enabling this option (while convenient) should *not* be done on a
15+ machine where you do not trust the other users as it allows any other
16+ local user to DoS your session by spamming notifications.
17+ '';
18+ };
19+
20+ config = mkIf cfg.enable {
21+ systemd = {
22+ packages = with pkgs; [ systembus-notify ];
23+
24+ user.services.systembus-notify.wantedBy = [ "graphical-session.target" ];
25+ };
26+ };
27+}
nixos/modules/system/activation/switch-to-configuration.pl+168−91
@@ -10,6 +10,8 @@ use Net::DBus;
1010use Sys::Syslog qw(:standard :macros);
1111use Cwd 'abs_path';
1212
13+## no critic(CodeLayout::ProhibitParensWithBuiltins)
14+
1315my $out = "@out@";
1416
1517my $curSystemd = abs_path("/run/current-system/sw/bin");
@@ -36,13 +38,13 @@ my $dryReloadByActivationFile = "/run/nixos/dry-activation-reload-list";
3638
3739make_path("/run/nixos", { mode => oct(755) });
3840
39−my $action = shift @ARGV;
41+my $action = shift(@ARGV);
4042
4143if ("@localeArchive@" ne "") {
4244 $ENV{LOCALE_ARCHIVE} = "@localeArchive@";
4345}
4446
45−if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
47+if (!defined($action) || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
4648 print STDERR <<EOF;
4749Usage: $0 [switch|boot|test]
4850
@@ -51,27 +53,27 @@ boot: make the configuration the boot default
5153test: activate the configuration, but don\'t make it the boot default
5254dry-activate: show what would be done if this configuration were activated
5355EOF
54− exit 1;
56+ exit(1);
5557}
5658
5759$ENV{NIXOS_ACTION} = $action;
5860
5961# This is a NixOS installation if it has /etc/NIXOS or a proper
6062# /etc/os-release.
61−die "This is not a NixOS installation!\n" unless
63+die("This is not a NixOS installation!\n") unless
6264 -f "/etc/NIXOS" || (read_file("/etc/os-release", err_mode => 'quiet') // "") =~ /ID="?nixos"?/s;
6365
6466openlog("nixos", "", LOG_USER);
6567
6668# Install or update the bootloader.
6769if ($action eq "switch" || $action eq "boot") {
68− system("@installBootLoader@ $out") == 0 or exit 1;
70+ system('@installBootLoader@', $out) == 0 or exit 1;
6971}
7072
7173# Just in case the new configuration hangs the system, do a sync now.
7274system("@coreutils@/bin/sync", "-f", "/nix/store") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1";
7375
74−exit 0 if $action eq "boot";
76+exit(0) if $action eq "boot";
7577
7678# Check if we can activate the new configuration.
7779my $oldVersion = read_file("/run/current-system/init-interface-version", err_mode => 'quiet') // "";
@@ -83,7 +85,7 @@ Warning: the new NixOS configuration has an ‘init’ that is
8385incompatible with the current configuration. The new configuration
8486won\'t take effect until you reboot the system.
8587EOF
86− exit 100;
88+ exit(100);
8789}
8890
8991# Ignore SIGHUP so that we're not killed if we're running on (say)
@@ -104,14 +106,27 @@ sub getActiveUnits {
104106 return $res;
105107}
106108
109+# Returns whether a systemd unit is active
110+sub unit_is_active {
111+ my ($unit_name) = @_;
112+
113+ my $mgr = Net::DBus->system->get_service('org.freedesktop.systemd1')->get_object('/org/freedesktop/systemd1');
114+ my $units = $mgr->ListUnitsByNames([$unit_name]);
115+ if (scalar(@{$units}) == 0) {
116+ return 0;
117+ }
118+ my $active_state = $units->[0]->[3]; ## no critic (ValuesAndExpressions::ProhibitMagicNumbers)
119+ return $active_state eq 'active' || $active_state eq 'activating';
120+}
121+
107122sub parseFstab {
108123 my ($filename) = @_;
109124 my ($fss, $swaps);
110125 foreach my $line (read_file($filename, err_mode => 'quiet')) {
111− chomp $line;
126+ chomp($line);
112127 $line =~ s/^\s*#.*//;
113128 next if $line =~ /^\s*$/;
114− my @xs = split / /, $line;
129+ my @xs = split(/ /, $line);
115130 if ($xs[2] eq "swap") {
116131 $swaps->{$xs[0]} = { options => $xs[3] // "" };
117132 } else {
@@ -133,17 +148,16 @@ sub parseFstab {
133148sub parseSystemdIni {
134149 my ($unitContents, $path) = @_;
135150 # Tie the ini file to a hash for easier access
136− my %fileContents;
137− tie %fileContents, "Config::IniFiles", (-file => $path, -allowempty => 1, -allowcontinue => 1);
151+ tie(my %fileContents, 'Config::IniFiles', (-file => $path, -allowempty => 1, -allowcontinue => 1)); ## no critic(Miscellanea::ProhibitTies)
138152
139153 # Copy over all sections
140− foreach my $sectionName (keys %fileContents) {
154+ foreach my $sectionName (keys(%fileContents)) {
141155 if ($sectionName eq "Install") {
142156 # Skip the [Install] section because it has no relevant keys for us
143157 next;
144158 }
145159 # Copy over all keys
146− foreach my $iniKey (keys %{$fileContents{$sectionName}}) {
160+ foreach my $iniKey (keys(%{$fileContents{$sectionName}})) {
147161 # Ensure the value is an array so it's easier to work with
148162 my $iniValue = $fileContents{$sectionName}{$iniKey};
149163 my @iniValues;
@@ -181,7 +195,7 @@ sub parse_unit {
181195 # Replace \ with \\ so glob() still works with units that have a \ in them
182196 # Valid characters in unit names are ASCII letters, digits, ":", "-", "_", ".", and "\"
183197 $unit_path =~ s/\\/\\\\/gmsx;
184− foreach (glob "${unit_path}{,.d/*.conf}") {
198+ foreach (glob("${unit_path}{,.d/*.conf}")) {
185199 parseSystemdIni(\%unit_data, "$_")
186200 }
187201 return %unit_data;
@@ -194,7 +208,7 @@ sub parseSystemdBool {
194208
195209 my @values = @{$unitConfig->{$sectionName}{$boolName} // []};
196210 # Return default if value is not set
197− if (scalar @values lt 1 || not defined $values[-1]) {
211+ if (scalar(@values) lt 1 || not defined($values[-1])) {
198212 return $default;
199213 }
200214 # If value is defined multiple times, use the last definition
@@ -211,7 +225,7 @@ sub recordUnit {
211225# The opposite of recordUnit, removes a unit name from a file
212226sub unrecord_unit {
213227 my ($fn, $unit) = @_;
214− edit_file { s/^$unit\n//msx } $fn if $action ne "dry-activate";
228+ edit_file(sub { s/^$unit\n//msx }, $fn) if $action ne "dry-activate";
215229}
216230
217231# Compare the contents of two unit files and return whether the unit
@@ -226,6 +240,16 @@ sub unrecord_unit {
226240sub compare_units {
227241 my ($old_unit, $new_unit) = @_;
228242 my $ret = 0;
243+ # Keys to ignore in the [Unit] section
244+ my %unit_section_ignores = map { $_ => 1 } qw(
245+ X-Reload-Triggers
246+ Description Documentation
247+ OnFailure OnSuccess OnFailureJobMode
248+ IgnoreOnIsolate StopWhenUnneeded
249+ RefuseManualStart RefuseManualStop
250+ AllowIsolate CollectMode
251+ SourcePath
252+ );
229253
230254 my $comp_array = sub {
231255 my ($a, $b) = @_;
@@ -233,11 +257,23 @@ sub compare_units {
233257 };
234258
235259 # Comparison hash for the sections
236− my %section_cmp = map { $_ => 1 } keys %{$new_unit};
260+ my %section_cmp = map { $_ => 1 } keys(%{$new_unit});
237261 # Iterate over the sections
238− foreach my $section_name (keys %{$old_unit}) {
262+ foreach my $section_name (keys(%{$old_unit})) {
239263 # Missing section in the new unit?
240− if (not exists $section_cmp{$section_name}) {
264+ if (not exists($section_cmp{$section_name})) {
265+ # If the [Unit] section was removed, make sure that only keys
266+ # were in it that are ignored
267+ if ($section_name eq 'Unit') {
268+ foreach my $ini_key (keys(%{$old_unit->{'Unit'}})) {
269+ if (not defined($unit_section_ignores{$ini_key})) {
270+ return 1;
271+ }
272+ }
273+ next; # check the next section
274+ } else {
275+ return 1;
276+ }
241277 if ($section_name eq 'Unit' and %{$old_unit->{'Unit'}} == 1 and defined(%{$old_unit->{'Unit'}}{'X-Reload-Triggers'})) {
242278 # If a new [Unit] section was removed that only contained X-Reload-Triggers,
243279 # do nothing.
@@ -248,15 +284,15 @@ sub compare_units {
248284 }
249285 delete $section_cmp{$section_name};
250286 # Comparison hash for the section contents
251− my %ini_cmp = map { $_ => 1 } keys %{$new_unit->{$section_name}};
287+ my %ini_cmp = map { $_ => 1 } keys(%{$new_unit->{$section_name}});
252288 # Iterate over the keys of the section
253− foreach my $ini_key (keys %{$old_unit->{$section_name}}) {
289+ foreach my $ini_key (keys(%{$old_unit->{$section_name}})) {
254290 delete $ini_cmp{$ini_key};
255291 my @old_value = @{$old_unit->{$section_name}{$ini_key}};
256292 # If the key is missing in the new unit, they are different...
257293 if (not $new_unit->{$section_name}{$ini_key}) {
258− # ... unless the key that is now missing was the reload trigger
259− if ($section_name eq 'Unit' and $ini_key eq 'X-Reload-Triggers') {
294+ # ... unless the key that is now missing is one of the ignored keys
295+ if ($section_name eq 'Unit' and defined($unit_section_ignores{$ini_key})) {
260296 next;
261297 }
262298 return 1;
@@ -264,19 +300,30 @@ sub compare_units {
264300 my @new_value = @{$new_unit->{$section_name}{$ini_key}};
265301 # If the contents are different, the units are different
266302 if (not $comp_array->(\@old_value, \@new_value)) {
267− # Check if only the reload triggers changed
268− if ($section_name eq 'Unit' and $ini_key eq 'X-Reload-Triggers') {
269− $ret = 2;
270− } else {
271− return 1;
303+ # Check if only the reload triggers changed or one of the ignored keys
304+ if ($section_name eq 'Unit') {
305+ if ($ini_key eq 'X-Reload-Triggers') {
306+ $ret = 2;
307+ next;
308+ } elsif (defined($unit_section_ignores{$ini_key})) {
309+ next;
310+ }
272311 }
312+ return 1;
273313 }
274314 }
275315 # A key was introduced that was missing in the old unit
276316 if (%ini_cmp) {
277− if ($section_name eq 'Unit' and %ini_cmp == 1 and defined($ini_cmp{'X-Reload-Triggers'})) {
278− # If the newly introduced key was the reload triggers, reload the unit
279− $ret = 2;
317+ if ($section_name eq 'Unit') {
318+ foreach my $ini_key (keys(%ini_cmp)) {
319+ if ($ini_key eq 'X-Reload-Triggers') {
320+ $ret = 2;
321+ } elsif (defined($unit_section_ignores{$ini_key})) {
322+ next;
323+ } else {
324+ return 1;
325+ }
326+ }
280327 } else {
281328 return 1;
282329 }
@@ -284,10 +331,14 @@ sub compare_units {
284331 }
285332 # A section was introduced that was missing in the old unit
286333 if (%section_cmp) {
287− if (%section_cmp == 1 and defined($section_cmp{'Unit'}) and %{$new_unit->{'Unit'}} == 1 and defined(%{$new_unit->{'Unit'}}{'X-Reload-Triggers'})) {
288− # If a new [Unit] section was introduced that only contains X-Reload-Triggers,
289− # reload instead of restarting
290− $ret = 2;
334+ if (%section_cmp == 1 and defined($section_cmp{'Unit'})) {
335+ foreach my $ini_key (keys(%{$new_unit->{'Unit'}})) {
336+ if (not defined($unit_section_ignores{$ini_key})) {
337+ return 1;
338+ } elsif ($ini_key eq 'X-Reload-Triggers') {
339+ $ret = 2;
340+ }
341+ }
291342 } else {
292343 return 1;
293344 }
@@ -343,11 +394,11 @@ sub handleModifiedUnit {
343394 my $socket_activated = 0;
344395 if ($unit =~ /\.service$/) {
345396 my @sockets = split(/ /, join(" ", @{$unitInfo{Service}{Sockets} // []}));
346− if (scalar @sockets == 0) {
397+ if (scalar(@sockets) == 0) {
347398 @sockets = ("$baseName.socket");
348399 }
349400 foreach my $socket (@sockets) {
350− if (defined $activePrev->{$socket}) {
401+ if (defined($activePrev->{$socket})) {
351402 # We can now be sure this is a socket-activate unit
352403
353404 $unitsToStop->{$socket} = 1;
@@ -355,7 +406,11 @@ sub handleModifiedUnit {
355406 # exist in new configuration:
356407 if (-e "$out/etc/systemd/system/$socket") {
357408 $unitsToStart->{$socket} = 1;
358− recordUnit($startListFile, $socket);
409+ if ($unitsToStart eq $unitsToRestart) {
410+ recordUnit($restartListFile, $socket);
411+ } else {
412+ recordUnit($startListFile, $socket);
413+ }
359414 $socket_activated = 1;
360415 }
361416 # Remove from units to reload so we don't restart and reload
@@ -373,7 +428,11 @@ sub handleModifiedUnit {
373428 # service gets restarted if we're interrupted.
374429 if (!$socket_activated) {
375430 $unitsToStart->{$unit} = 1;
376− recordUnit($startListFile, $unit);
431+ if ($unitsToStart eq $unitsToRestart) {
432+ recordUnit($restartListFile, $unit);
433+ } else {
434+ recordUnit($startListFile, $unit);
435+ }
377436 }
378437
379438 $unitsToStop->{$unit} = 1;
@@ -401,8 +460,8 @@ $unitsToRestart{$_} = 1 foreach
401460$unitsToReload{$_} = 1 foreach
402461 split('\n', read_file($reloadListFile, err_mode => 'quiet') // "");
403462
404−my $activePrev = getActiveUnits;
405−while (my ($unit, $state) = each %{$activePrev}) {
463+my $activePrev = getActiveUnits();
464+while (my ($unit, $state) = each(%{$activePrev})) {
406465 my $baseUnit = $unit;
407466
408467 my $prevUnitFile = "/etc/systemd/system/$baseUnit";
@@ -462,9 +521,9 @@ while (my ($unit, $state) = each %{$activePrev}) {
462521 my %old_unit_info = parse_unit($prevUnitFile);
463522 my %new_unit_info = parse_unit($newUnitFile);
464523 my $diff = compare_units(\%old_unit_info, \%new_unit_info);
465− if ($diff eq 1) {
524+ if ($diff == 1) {
466525 handleModifiedUnit($unit, $baseName, $newUnitFile, \%new_unit_info, $activePrev, \%unitsToStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, \%unitsToSkip);
467− } elsif ($diff eq 2 and not $unitsToRestart{$unit}) {
526+ } elsif ($diff == 2 and not $unitsToRestart{$unit}) {
468527 $unitsToReload{$unit} = 1;
469528 recordUnit($reloadListFile, $unit);
470529 }
@@ -475,11 +534,11 @@ while (my ($unit, $state) = each %{$activePrev}) {
475534sub pathToUnitName {
476535 my ($path) = @_;
477536 # Use current version of systemctl binary before daemon is reexeced.
478− open my $cmd, "-|", "$curSystemd/systemd-escape", "--suffix=mount", "-p", $path
537+ open(my $cmd, "-|", "$curSystemd/systemd-escape", "--suffix=mount", "-p", $path)
479538 or die "Unable to escape $path!\n";
480− my $escaped = join "", <$cmd>;
481− chomp $escaped;
482− close $cmd or die;
539+ my $escaped = join("", <$cmd>);
540+ chomp($escaped);
541+ close($cmd) or die('Unable to close systemd-escape pipe');
483542 return $escaped;
484543}
485544
@@ -488,13 +547,13 @@ sub pathToUnitName {
488547# automatically by starting local-fs.target. FIXME: might be nicer if
489548# we generated units for all mounts; then we could unify this with the
490549# unit checking code above.
491−my ($prevFss, $prevSwaps) = parseFstab "/etc/fstab";
492−my ($newFss, $newSwaps) = parseFstab "$out/etc/fstab";
493−foreach my $mountPoint (keys %$prevFss) {
550+my ($prevFss, $prevSwaps) = parseFstab("/etc/fstab");
551+my ($newFss, $newSwaps) = parseFstab("$out/etc/fstab");
552+foreach my $mountPoint (keys(%$prevFss)) {
494553 my $prev = $prevFss->{$mountPoint};
495554 my $new = $newFss->{$mountPoint};
496555 my $unit = pathToUnitName($mountPoint);
497− if (!defined $new) {
556+ if (!defined($new)) {
498557 # Filesystem entry disappeared, so unmount it.
499558 $unitsToStop{$unit} = 1;
500559 } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
@@ -510,10 +569,10 @@ foreach my $mountPoint (keys %$prevFss) {
510569}
511570
512571# Also handles swap devices.
513−foreach my $device (keys %$prevSwaps) {
572+foreach my $device (keys(%$prevSwaps)) {
514573 my $prev = $prevSwaps->{$device};
515574 my $new = $newSwaps->{$device};
516− if (!defined $new) {
575+ if (!defined($new)) {
517576 # Swap entry disappeared, so turn it off. Can't use
518577 # "systemctl stop" here because systemd has lots of alias
519578 # units that prevent a stop from actually calling
@@ -544,8 +603,8 @@ if ($prevSystemdSystemConfig ne $newSystemdSystemConfig) {
544603sub filterUnits {
545604 my ($units) = @_;
546605 my @res;
547− foreach my $unit (sort(keys %{$units})) {
548− push @res, $unit if !defined $unitsToFilter{$unit};
606+ foreach my $unit (sort(keys(%{$units}))) {
607+ push(@res, $unit) if !defined($unitsToFilter{$unit});
549608 }
550609 return @res;
551610}
@@ -556,9 +615,9 @@ my @unitsToStopFiltered = filterUnits(\%unitsToStop);
556615# Show dry-run actions.
557616if ($action eq "dry-activate") {
558617 print STDERR "would stop the following units: ", join(", ", @unitsToStopFiltered), "\n"
559− if scalar @unitsToStopFiltered > 0;
560− print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
561− if scalar(keys %unitsToSkip) > 0;
618+ if scalar(@unitsToStopFiltered) > 0;
619+ print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys(%unitsToSkip))), "\n"
620+ if scalar(keys(%unitsToSkip)) > 0;
562621
563622 print STDERR "would activate the configuration...\n";
564623 system("$out/dry-activate", "$out");
@@ -579,7 +638,7 @@ if ($action eq "dry-activate") {
579638 $baseName =~ s/\.[a-z]*$//;
580639
581640 # Start units if they were not active previously
582− if (not defined $activePrev->{$unit}) {
641+ if (not defined($activePrev->{$unit})) {
583642 $unitsToStart{$unit} = 1;
584643 next;
585644 }
@@ -599,28 +658,28 @@ if ($action eq "dry-activate") {
599658 unlink($dryReloadByActivationFile);
600659
601660 print STDERR "would restart systemd\n" if $restartSystemd;
602− print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
603− if scalar(keys %unitsToReload) > 0;
604− print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
605− if scalar(keys %unitsToRestart) > 0;
661+ print STDERR "would reload the following units: ", join(", ", sort(keys(%unitsToReload))), "\n"
662+ if scalar(keys(%unitsToReload)) > 0;
663+ print STDERR "would restart the following units: ", join(", ", sort(keys(%unitsToRestart))), "\n"
664+ if scalar(keys(%unitsToRestart)) > 0;
606665 my @unitsToStartFiltered = filterUnits(\%unitsToStart);
607666 print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
608− if scalar @unitsToStartFiltered;
667+ if scalar(@unitsToStartFiltered);
609668 exit 0;
610669}
611670
612671
613672syslog(LOG_NOTICE, "switching to system configuration $out");
614673
615−if (scalar (keys %unitsToStop) > 0) {
674+if (scalar(keys(%unitsToStop)) > 0) {
616675 print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
617− if scalar @unitsToStopFiltered;
676+ if scalar(@unitsToStopFiltered);
618677 # Use current version of systemctl binary before daemon is reexeced.
619− system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToStop));
678+ system("$curSystemd/systemctl", "stop", "--", sort(keys(%unitsToStop)));
620679}
621680
622−print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
623− if scalar(keys %unitsToSkip) > 0;
681+print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys(%unitsToSkip))), "\n"
682+ if scalar(keys(%unitsToSkip)) > 0;
624683
625684# Activate the new configuration (i.e., update /etc, make accounts,
626685# and so on).
@@ -644,7 +703,7 @@ foreach (split('\n', read_file($restartByActivationFile, err_mode => 'quiet') //
644703 $baseName =~ s/\.[a-z]*$//;
645704
646705 # Start units if they were not active previously
647− if (not defined $activePrev->{$unit}) {
706+ if (not defined($activePrev->{$unit})) {
648707 $unitsToStart{$unit} = 1;
649708 recordUnit($startListFile, $unit);
650709 next;
@@ -681,7 +740,7 @@ system("@systemd@/bin/systemctl", "reset-failed");
681740system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
682741
683742# Reload user units
684−open my $listActiveUsers, '-|', '@systemd@/bin/loginctl', 'list-users', '--no-legend';
743+open(my $listActiveUsers, '-|', '@systemd@/bin/loginctl', 'list-users', '--no-legend');
685744while (my $f = <$listActiveUsers>) {
686745 next unless $f =~ /^\s*(?<uid>\d+)\s+(?<user>\S+)/;
687746 my ($uid, $name) = ($+{uid}, $+{user});
@@ -693,25 +752,43 @@ while (my $f = <$listActiveUsers>) {
693752 "@systemd@/bin/systemctl --user start nixos-activation.service");
694753}
695754
696−close $listActiveUsers;
755+close($listActiveUsers);
697756
698757# Set the new tmpfiles
699758print STDERR "setting up tmpfiles\n";
700759system("@systemd@/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
701760
761+# Before reloading we need to ensure that the units are still active. They may have been
762+# deactivated because one of their requirements got stopped. If they are inactive
763+# but should have been reloaded, the user probably expects them to be started.
764+if (scalar(keys(%unitsToReload)) > 0) {
765+ for my $unit (keys(%unitsToReload)) {
766+ if (!unit_is_active($unit)) {
767+ # Figure out if we need to start the unit
768+ my %unit_info = parse_unit("$out/etc/systemd/system/$unit");
769+ if (!(parseSystemdBool(\%unit_info, 'Unit', 'RefuseManualStart', 0) || parseSystemdBool(\%unit_info, 'Unit', 'X-OnlyManualStart', 0))) {
770+ $unitsToStart{$unit} = 1;
771+ recordUnit($startListFile, $unit);
772+ }
773+ # Don't reload the unit, reloading would fail
774+ delete %unitsToReload{$unit};
775+ unrecord_unit($reloadListFile, $unit);
776+ }
777+ }
778+}
702779# Reload units that need it. This includes remounting changed mount
703780# units.
704−if (scalar(keys %unitsToReload) > 0) {
705− print STDERR "reloading the following units: ", join(", ", sort(keys %unitsToReload)), "\n";
706− system("@systemd@/bin/systemctl", "reload", "--", sort(keys %unitsToReload)) == 0 or $res = 4;
781+if (scalar(keys(%unitsToReload)) > 0) {
782+ print STDERR "reloading the following units: ", join(", ", sort(keys(%unitsToReload))), "\n";
783+ system("@systemd@/bin/systemctl", "reload", "--", sort(keys(%unitsToReload))) == 0 or $res = 4;
707784 unlink($reloadListFile);
708785}
709786
710787# Restart changed services (those that have to be restarted rather
711788# than stopped and started).
712−if (scalar(keys %unitsToRestart) > 0) {
713− print STDERR "restarting the following units: ", join(", ", sort(keys %unitsToRestart)), "\n";
714− system("@systemd@/bin/systemctl", "restart", "--", sort(keys %unitsToRestart)) == 0 or $res = 4;
789+if (scalar(keys(%unitsToRestart)) > 0) {
790+ print STDERR "restarting the following units: ", join(", ", sort(keys(%unitsToRestart))), "\n";
791+ system("@systemd@/bin/systemctl", "restart", "--", sort(keys(%unitsToRestart))) == 0 or $res = 4;
715792 unlink($restartListFile);
716793}
717794
@@ -723,17 +800,17 @@ if (scalar(keys %unitsToRestart) > 0) {
723800# systemd.
724801my @unitsToStartFiltered = filterUnits(\%unitsToStart);
725802print STDERR "starting the following units: ", join(", ", @unitsToStartFiltered), "\n"
726− if scalar @unitsToStartFiltered;
727−system("@systemd@/bin/systemctl", "start", "--", sort(keys %unitsToStart)) == 0 or $res = 4;
803+ if scalar(@unitsToStartFiltered);
804+system("@systemd@/bin/systemctl", "start", "--", sort(keys(%unitsToStart))) == 0 or $res = 4;
728805unlink($startListFile);
729806
730807
731808# Print failed and new units.
732809my (@failed, @new);
733−my $activeNew = getActiveUnits;
734−while (my ($unit, $state) = each %{$activeNew}) {
810+my $activeNew = getActiveUnits();
811+while (my ($unit, $state) = each(%{$activeNew})) {
735812 if ($state->{state} eq "failed") {
736− push @failed, $unit;
813+ push(@failed, $unit);
737814 next;
738815 }
739816
@@ -743,7 +820,7 @@ while (my ($unit, $state) = each %{$activeNew}) {
743820 chomp($main_status);
744821
745822 if ($main_status ne "0") {
746− push @failed, $unit;
823+ push(@failed, $unit);
747824 next;
748825 }
749826 }
@@ -751,19 +828,19 @@ while (my ($unit, $state) = each %{$activeNew}) {
751828 # Ignore scopes since they are not managed by this script but rather
752829 # created and managed by third-party services via the systemd dbus API.
753830 # This only lists units that are not failed (including ones that are in auto-restart but have not failed previously)
754− if ($state->{state} ne "failed" && !defined $activePrev->{$unit} && $unit !~ /\.scope$/msx) {
755− push @new, $unit;
831+ if ($state->{state} ne "failed" && !defined($activePrev->{$unit}) && $unit !~ /\.scope$/msx) {
832+ push(@new, $unit);
756833 }
757834}
758835
759−if (scalar @new > 0) {
836+if (scalar(@new) > 0) {
760837 print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
761838}
762839
763−if (scalar @failed > 0) {
764− my @failed_sorted = sort @failed;
840+if (scalar(@failed) > 0) {
841+ my @failed_sorted = sort(@failed);
765842 print STDERR "warning: the following units failed: ", join(", ", @failed_sorted), "\n\n";
766− system "@systemd@/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2";
843+ system("@systemd@/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2");
767844 $res = 4;
768845}
769846
@@ -773,4 +850,4 @@ if ($res == 0) {
773850 syslog(LOG_ERR, "switching to system configuration $out failed (status $res)");
774851}
775852
776−exit $res;
853+exit($res);
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py+16−5
@@ -15,9 +15,12 @@ import re
1515import datetime
1616import glob
1717import os.path
18−from typing import Tuple, List, Optional
18+from typing import NamedTuple, List, Optional
1919
20−SystemIdentifier = Tuple[Optional[str], int, Optional[str]]
20+class SystemIdentifier(NamedTuple):
21+ profile: Optional[str]
22+ generation: int
23+ specialisation: Optional[str]
2124
2225
2326def copy_if_not_exists(source: str, dest: str) -> None:
@@ -151,7 +154,14 @@ def get_generations(profile: Optional[str] = None) -> List[SystemIdentifier]:
151154 gen_lines.pop()
152155
153156 configurationLimit = @configurationLimit@
154− configurations: List[SystemIdentifier] = [ (profile, int(line.split()[0]), None) for line in gen_lines ]
157+ configurations = [
158+ SystemIdentifier(
159+ profile=profile,
160+ generation=int(line.split()[0]),
161+ specialisation=None
162+ )
163+ for line in gen_lines
164+ ]
155165 return configurations[-configurationLimit:]
156166
157167
@@ -160,7 +170,7 @@ def get_specialisations(profile: Optional[str], generation: int, _: Optional[str
160170 system_dir(profile, generation, None), "specialisation")
161171 if not os.path.exists(specialisations_dir):
162172 return []
163− return [(profile, generation, spec) for spec in os.listdir(specialisations_dir)]
173+ return [SystemIdentifier(profile, generation, spec) for spec in os.listdir(specialisations_dir)]
164174
165175
166176def remove_old_entries(gens: List[SystemIdentifier]) -> None:
@@ -271,7 +281,8 @@ def main() -> None:
271281 if os.readlink(system_dir(*gen)) == args.default_config:
272282 write_loader_conf(*gen)
273283 except OSError as e:
274− print("ignoring generation '{}' in the list of boot entries because of the following error:\n{}".format(*gen, e), file=sys.stderr)
284+ profile = f"profile '{gen.profile}'" if gen.profile else "default profile"
285+ print("ignoring {} in the list of boot entries because of the following error:\n{}".format(profile, e), file=sys.stderr)
275286
276287 for root, _, files in os.walk('@efiSysMountPoint@/efi/nixos/.extra-files', topdown=False):
277288 relative_root = root.removeprefix("@efiSysMountPoint@/efi/nixos/.extra-files").removeprefix("/")
nixos/tests/switch-test.nix+147
@@ -64,6 +64,11 @@ in {
6464 };
6565 };
6666
67+ simpleServiceDifferentDescription.configuration = {
68+ imports = [ simpleService.configuration ];
69+ systemd.services.test.description = "Test unit";
70+ };
71+
6772 simpleServiceModified.configuration = {
6873 imports = [ simpleService.configuration ];
6974 systemd.services.test.serviceConfig.X-Test = true;
@@ -203,6 +208,39 @@ in {
203208 systemd.services."escaped\\x2ddash".serviceConfig.X-Test = "test";
204209 };
205210
211+ unitWithRequirement.configuration = {
212+ systemd.services.required-service = {
213+ wantedBy = [ "multi-user.target" ];
214+ serviceConfig = {
215+ Type = "oneshot";
216+ RemainAfterExit = true;
217+ ExecStart = "${pkgs.coreutils}/bin/true";
218+ ExecReload = "${pkgs.coreutils}/bin/true";
219+ };
220+ };
221+ systemd.services.test-service = {
222+ wantedBy = [ "multi-user.target" ];
223+ requires = [ "required-service.service" ];
224+ serviceConfig = {
225+ Type = "oneshot";
226+ RemainAfterExit = true;
227+ ExecStart = "${pkgs.coreutils}/bin/true";
228+ ExecReload = "${pkgs.coreutils}/bin/true";
229+ };
230+ };
231+ };
232+
233+ unitWithRequirementModified.configuration = {
234+ imports = [ unitWithRequirement.configuration ];
235+ systemd.services.required-service.serviceConfig.X-Test = "test";
236+ systemd.services.test-service.reloadTriggers = [ "test" ];
237+ };
238+
239+ unitWithRequirementModifiedNostart.configuration = {
240+ imports = [ unitWithRequirement.configuration ];
241+ systemd.services.test-service.unitConfig.RefuseManualStart = true;
242+ };
243+
206244 restart-and-reload-by-activation-script.configuration = {
207245 systemd.services = rec {
208246 simple-service = {
@@ -350,6 +388,31 @@ in {
350388 systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00";
351389 };
352390
391+ hybridSleepModified.configuration = {
392+ systemd.targets.hybrid-sleep.unitConfig.X-Test = true;
393+ };
394+
395+ target.configuration = {
396+ systemd.targets.test-target.wantedBy = [ "multi-user.target" ];
397+ # We use this service to figure out whether the target was modified.
398+ # This is the only way because targets are filtered and therefore not
399+ # printed when they are started/stopped.
400+ systemd.services.test-service = {
401+ bindsTo = [ "test-target.target" ];
402+ serviceConfig.ExecStart = "${pkgs.coreutils}/bin/sleep infinity";
403+ };
404+ };
405+
406+ targetModified.configuration = {
407+ imports = [ target.configuration ];
408+ systemd.targets.test-target.unitConfig.X-Test = true;
409+ };
410+
411+ targetModifiedStopOnReconfig.configuration = {
412+ imports = [ target.configuration ];
413+ systemd.targets.test-target.unitConfig.X-StopOnReconfiguration = true;
414+ };
415+
353416 path.configuration = {
354417 systemd.paths.test-watch = {
355418 wantedBy = [ "paths.target" ];
@@ -472,6 +535,15 @@ in {
472535 assert_lacks(out, "\nstarting the following units:")
473536 assert_lacks(out, "the following new units were started:")
474537
538+ # Only changing the description does nothing
539+ out = switch_to_specialisation("${machine}", "simpleServiceDifferentDescription")
540+ assert_lacks(out, "stopping the following units:")
541+ assert_lacks(out, "NOT restarting the following changed units:")
542+ assert_lacks(out, "reloading the following units:")
543+ assert_lacks(out, "\nrestarting the following units:")
544+ assert_lacks(out, "\nstarting the following units:")
545+ assert_lacks(out, "the following new units were started:")
546+
475547 # Restart the simple service
476548 out = switch_to_specialisation("${machine}", "simpleServiceModified")
477549 assert_contains(out, "stopping the following units: test.service\n")
@@ -535,6 +607,32 @@ in {
535607 assert_contains(out, "\nstarting the following units: escaped\\x2ddash.service\n")
536608 assert_lacks(out, "the following new units were started:")
537609
610+ # Ensure units that require changed units are properly reloaded
611+ out = switch_to_specialisation("${machine}", "unitWithRequirement")
612+ assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n")
613+ assert_lacks(out, "NOT restarting the following changed units:")
614+ assert_lacks(out, "reloading the following units:")
615+ assert_lacks(out, "\nrestarting the following units:")
616+ assert_lacks(out, "\nstarting the following units:")
617+ assert_contains(out, "the following new units were started: required-service.service, test-service.service\n")
618+
619+ out = switch_to_specialisation("${machine}", "unitWithRequirementModified")
620+ assert_contains(out, "stopping the following units: required-service.service\n")
621+ assert_lacks(out, "NOT restarting the following changed units:")
622+ assert_lacks(out, "reloading the following units:")
623+ assert_lacks(out, "\nrestarting the following units:")
624+ assert_contains(out, "\nstarting the following units: required-service.service, test-service.service\n")
625+ assert_lacks(out, "the following new units were started:")
626+
627+ # Unless the unit asks to be not restarted
628+ out = switch_to_specialisation("${machine}", "unitWithRequirementModifiedNostart")
629+ assert_contains(out, "stopping the following units: required-service.service\n")
630+ assert_lacks(out, "NOT restarting the following changed units:")
631+ assert_lacks(out, "reloading the following units:")
632+ assert_lacks(out, "\nrestarting the following units:")
633+ assert_contains(out, "\nstarting the following units: required-service.service\n")
634+ assert_lacks(out, "the following new units were started:")
635+
538636 with subtest("failing units"):
539637 # Let the simple service fail
540638 switch_to_specialisation("${machine}", "simpleServiceModified")
@@ -821,6 +919,55 @@ in {
821919 out = machine.succeed("systemctl show test-timer.timer")
822920 assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00")
823921
922+ with subtest("targets"):
923+ # Modifying some special targets like hybrid-sleep.target does nothing
924+ out = switch_to_specialisation("${machine}", "hybridSleepModified")
925+ assert_contains(out, "stopping the following units: test-timer.timer\n")
926+ assert_lacks(out, "NOT restarting the following changed units:")
927+ assert_lacks(out, "reloading the following units:")
928+ assert_lacks(out, "\nrestarting the following units:")
929+ assert_lacks(out, "\nstarting the following units:")
930+ assert_lacks(out, "the following new units were started:")
931+
932+ # Adding a new target starts it
933+ out = switch_to_specialisation("${machine}", "target")
934+ assert_lacks(out, "stopping the following units:")
935+ assert_lacks(out, "NOT restarting the following changed units:")
936+ assert_lacks(out, "reloading the following units:")
937+ assert_lacks(out, "\nrestarting the following units:")
938+ assert_lacks(out, "\nstarting the following units:")
939+ assert_contains(out, "the following new units were started: test-target.target\n")
940+
941+ # Changing a target doesn't print anything because the unit is filtered
942+ machine.systemctl("start test-service.service")
943+ out = switch_to_specialisation("${machine}", "targetModified")
944+ assert_lacks(out, "stopping the following units:")
945+ assert_lacks(out, "NOT restarting the following changed units:")
946+ assert_lacks(out, "reloading the following units:")
947+ assert_lacks(out, "\nrestarting the following units:")
948+ assert_lacks(out, "\nstarting the following units:")
949+ assert_lacks(out, "the following new units were started:")
950+ machine.succeed("systemctl is-active test-service.service") # target was not restarted
951+
952+ # With X-StopOnReconfiguration, the target gets stopped and started
953+ out = switch_to_specialisation("${machine}", "targetModifiedStopOnReconfig")
954+ assert_lacks(out, "stopping the following units:")
955+ assert_lacks(out, "NOT restarting the following changed units:")
956+ assert_lacks(out, "reloading the following units:")
957+ assert_lacks(out, "\nrestarting the following units:")
958+ assert_lacks(out, "\nstarting the following units:")
959+ assert_lacks(out, "the following new units were started:")
960+ machine.fail("systemctl is-active test-service.servce") # target was restarted
961+
962+ # Remove the target by switching to the old specialisation
963+ out = switch_to_specialisation("${machine}", "timerModified")
964+ assert_contains(out, "stopping the following units: test-target.target\n")
965+ assert_lacks(out, "NOT restarting the following changed units:")
966+ assert_lacks(out, "reloading the following units:")
967+ assert_lacks(out, "\nrestarting the following units:")
968+ assert_lacks(out, "\nstarting the following units:")
969+ assert_contains(out, "the following new units were started: test-timer.timer\n")
970+
824971 with subtest("paths"):
825972 out = switch_to_specialisation("${machine}", "path")
826973 assert_contains(out, "stopping the following units: test-timer.timer\n")
pkgs/applications/audio/squeezelite/default.nix+48−30
@@ -1,39 +1,50 @@
1−{ lib, stdenv, fetchFromGitHub
2−, alsa-lib, flac, libmad, libvorbis, mpg123
1+{ lib
2+, stdenv
3+, fetchFromGitHub
4+, alsa-lib
5+, flac
6+, libmad
7+, libpulseaudio
8+, libvorbis
9+, mpg123
10+, audioBackend ? "alsa"
311, dsdSupport ? true
4−, faad2Support ? true, faad2
5−, ffmpegSupport ? true, ffmpeg
6−, opusSupport ? true, opusfile
7−, resampleSupport ? true, soxr
8−, sslSupport ? true, openssl
12+, faad2Support ? true
13+, faad2
14+, ffmpegSupport ? true
15+, ffmpeg
16+, opusSupport ? true
17+, opusfile
18+, resampleSupport ? true
19+, soxr
20+, sslSupport ? true
21+, openssl
922}:
1023
1124let
12− concatStringsSep = lib.concatStringsSep;
13− optional = lib.optional;
14− opts = [ "-DLINKALL" ]
15− ++ optional dsdSupport "-DDSD"
16− ++ optional (!faad2Support) "-DNO_FAAD"
17− ++ optional ffmpegSupport "-DFFMPEG"
18− ++ optional opusSupport "-DOPUS"
19− ++ optional resampleSupport "-DRESAMPLE"
20− ++ optional sslSupport "-DUSE_SSL";
25+ inherit (lib) optional optionalString;
2126
22−in stdenv.mkDerivation {
23− pname = "squeezelite";
27+ pulseSupport = audioBackend == "pulse";
2428
29+ binName = "squeezelite${optionalString pulseSupport "-pulse"}";
30+
31+in
32+stdenv.mkDerivation {
33+ # the nixos module uses the pname as the binary name
34+ pname = binName;
2535 # versions are specified in `squeezelite.h`
2636 # see https://github.com/ralph-irving/squeezelite/issues/29
27− version = "1.9.6.1196";
37+ version = "1.9.9.1401";
2838
2939 src = fetchFromGitHub {
30− owner = "ralph-irving";
31− repo = "squeezelite";
32− rev = "2b508464dce2cbdb2a3089c58df2a6fbc36328c0";
33− sha256 = "024ypr1da2r079k3hgiifzd3d3wcfprhbl5zdm40zm0c7frzmr8i";
40+ owner = "ralph-irving";
41+ repo = "squeezelite";
42+ rev = "894df3ea80f66a27a9ae5fab918acf62a6798b8b";
43+ hash = "sha256-LIi+9vb0+56AGvVrLx4gQaUkUNjIi6PmqrLViLT1DSU=";
3444 };
3545
36− buildInputs = [ alsa-lib flac libmad libvorbis mpg123 ]
46+ buildInputs = [ flac libmad libvorbis mpg123 ]
47+ ++ lib.singleton (if pulseSupport then libpulseaudio else alsa-lib)
3748 ++ optional faad2Support faad2
3849 ++ optional ffmpegSupport ffmpeg
3950 ++ optional opusSupport opusfile
@@ -47,15 +58,22 @@ in stdenv.mkDerivation {
4758 --replace "<opusfile.h>" "<opus/opusfile.h>"
4859 '';
4960
50− preBuild = ''
51− export OPTS="${concatStringsSep " " opts}"
52− '';
61+ EXECUTABLE = binName;
62+
63+ OPTS = [ "-DLINKALL" ]
64+ ++ optional dsdSupport "-DDSD"
65+ ++ optional (!faad2Support) "-DNO_FAAD"
66+ ++ optional ffmpegSupport "-DFFMPEG"
67+ ++ optional opusSupport "-DOPUS"
68+ ++ optional pulseSupport "-DPULSEAUDIO"
69+ ++ optional resampleSupport "-DRESAMPLE"
70+ ++ optional sslSupport "-DUSE_SSL";
5371
5472 installPhase = ''
5573 runHook preInstall
5674
57− install -Dm755 -t $out/bin squeezelite
58− install -Dm644 -t $out/share/doc/squeezelite *.txt *.md
75+ install -Dm555 -t $out/bin ${binName}
76+ install -Dm444 -t $out/share/doc/squeezelite *.txt *.md
5977
6078 runHook postInstall
6179 '';
@@ -63,7 +81,7 @@ in stdenv.mkDerivation {
6381 meta = with lib; {
6482 description = "Lightweight headless squeezebox client emulator";
6583 homepage = "https://github.com/ralph-irving/squeezelite";
66− license = with licenses; [ gpl3 ] ++ optional dsdSupport bsd2;
84+ license = with licenses; [ gpl3Plus ] ++ optional dsdSupport bsd2;
6785 maintainers = with maintainers; [ samdoshi ];
6886 platforms = platforms.linux;
6987 };
pkgs/applications/editors/sigil/default.nix+2−2
@@ -6,13 +6,13 @@
66
77mkDerivation rec {
88 pname = "sigil";
9− version = "1.9.1";
9+ version = "1.9.2";
1010
1111 src = fetchFromGitHub {
1212 repo = "Sigil";
1313 owner = "Sigil-Ebook";
1414 rev = version;
15− sha256 = "sha256-PsHliyJu61QFTFZUgDtxguu18GBVTOGMW6pPYjHhvG0=";
15+ sha256 = "sha256-LfP3qUzoHuYSpkTz1queVGTWOP9v9kbgbgvvtiMK6Eo=";
1616 };
1717
1818 pythonPath = with python3Packages; [ lxml ];
pkgs/applications/graphics/nsxiv/default.nix+2−2
@@ -11,13 +11,13 @@
1111
1212stdenv.mkDerivation rec {
1313 pname = "nsxiv";
14− version = "28";
14+ version = "29";
1515
1616 src = fetchFromGitHub {
1717 owner = "nsxiv";
1818 repo = pname;
1919 rev = "v${version}";
20− hash = "sha256-12RmEAzZdeanrRtnan96loXT7qSjIMjcWf296XmNE+A=";
20+ hash = "sha256-JUF2cF6QeAXk6G76uMu3reaMgxp2RcqHDbamkNufwqE=";
2121 };
2222
2323 buildInputs = [
pkgs/applications/misc/systembus-notify/default.nix+39−5
@@ -1,5 +1,30 @@
1−{ lib, stdenv, fetchFromGitHub, systemd }:
1+{ lib
2+, stdenv
3+, fetchFromGitHub
4+, formats
5+, systemd
6+}:
27
8+let
9+ ini = formats.ini { };
10+
11+ unit = ini.generate "systembus-notify.service" {
12+ Unit = {
13+ Description = "system bus notification daemon";
14+ };
15+
16+ Service = {
17+ Type = "exec";
18+ ExecStart = "@out@/bin/systembus-notify";
19+ PrivateTmp = true;
20+ ProtectHome = true;
21+ ProtectSystem = "strict";
22+ Restart = "on-failure";
23+ Slice = "background.slice";
24+ };
25+ };
26+
27+in
328stdenv.mkDerivation rec {
429 pname = "systembus-notify";
530 version = "1.1";
@@ -8,23 +33,32 @@ stdenv.mkDerivation rec {
833 owner = "rfjakob";
934 repo = "systembus-notify";
1035 rev = "v${version}";
11− sha256 = "1pdn45rfpwhrf20hs87qmk2j8sr7ab8161f81019wnypnb1q2fsv";
36+ sha256 = "sha256-WzuBw7LXW54CCMgFE9BSJ2skxaz4IA2BcBny63Ihtt0=";
1237 };
1338
1439 buildInputs = [ systemd ];
1540
1641 installPhase = ''
1742 runHook preInstall
18− install -Dm755 systembus-notify -t $out/bin
19− install -Dm644 systembus-notify.desktop -t $out/etc/xdg/autostart
43+
44+ install -Dm555 -t $out/bin systembus-notify
45+ install -Dm444 -t $out/share/systembus-notify systembus-notify.desktop
46+
47+ install -d $out/lib/systemd/user
48+ substitute ${unit} $out/lib/systemd/user/${unit.name} \
49+ --subst-var out
50+
2051 runHook postInstall
2152 '';
2253
54+ # requires a running dbus instance
55+ doCheck = false;
56+
2357 meta = with lib; {
2458 description = "System bus notification daemon";
2559 homepage = "https://github.com/rfjakob/systembus-notify";
2660 license = licenses.mit;
61+ maintainers = with maintainers; [ peterhoeg ];
2762 platforms = platforms.linux;
28− maintainers = with maintainers; [];
2963 };
3064}
pkgs/applications/networking/cluster/cloudfoundry-cli/default.nix+3−3
@@ -2,15 +2,15 @@
22
33buildGoModule rec {
44 pname = "cloudfoundry-cli";
5− version = "8.0.0";
5+ version = "8.3.0";
66
77 src = fetchFromGitHub {
88 owner = "cloudfoundry";
99 repo = "cli";
1010 rev = "v${version}";
11− sha256 = "00cwnfylra0msbb423ad21if98s6smzccsyidqsl4r2mrlkhahwm";
11+ sha256 = "sha256-tC9U0yvuMEwO4mzWyUC+v+/H0EzgwTu02waTQrx19Bs=";
1212 };
13− vendorSha256 = "0fcgyyd11xfhn8i11bqnaw3h51bj1y8s37b4d8wzv31dr8zswqsc";
13+ vendorSha256 = "sha256-aXq92SI4cgJrmo67SEfg8YKPEpO2UW2fcYnKq9TmAQg=";
1414
1515 subPackages = [ "." ];
1616
pkgs/applications/networking/instant-messengers/qtox/default.nix+2−2
@@ -28,13 +28,13 @@
2828
2929mkDerivation rec {
3030 pname = "qtox";
31− version = "1.17.5";
31+ version = "1.17.6";
3232
3333 src = fetchFromGitHub {
3434 owner = "qTox";
3535 repo = "qTox";
3636 rev = "v${version}";
37− sha256 = "sha256-H3qFEw/TkzOxEXtZs0k89wWMnhrOkF7VapUKtCUhGns=";
37+ sha256 = "sha256-naKWoodSMw0AEtACvkASFmw9t0H0d2pcqOW79NNTYF0=";
3838 };
3939
4040 buildInputs = [
pkgs/applications/video/go-chromecast/default.nix+3−3
@@ -2,16 +2,16 @@
22
33buildGoModule rec {
44 pname = "go-chromecast";
5− version = "0.2.11";
5+ version = "0.2.12";
66
77 src = fetchFromGitHub {
88 owner = "vishen";
99 repo = pname;
1010 rev = "v${version}";
11− sha256 = "sha256-BCOyeXo3uoR4ry/nFbF+//U62/hHnPK+tbG+8Rv6Rv0=";
11+ sha256 = "sha256-h8qWwMaEhXnj6ZSrKAXBVbrMR0je41EoOtFeN9XlCuk=";
1212 };
1313
14− vendorSha256 = "sha256-idxElk4Sy7SE9G1OMRw8YH4o8orBa80qhBXPA+ar620=";
14+ vendorSha256 = "sha256-PpMLHuJR6irp+QHhzguwGtBy30HM7DR0tNGiwB07M5E=";
1515
1616 ldflags = [ "-s" "-w" "-X main.version=${version}" "-X main.commit=${src.rev}" "-X main.date=unknown" ];
1717
pkgs/applications/virtualization/docker-slim/default.nix+2−2
@@ -6,7 +6,7 @@
66
77buildGoPackage rec {
88 pname = "docker-slim";
9− version = "1.37.3";
9+ version = "1.37.4";
1010
1111 goPackagePath = "github.com/docker-slim/docker-slim";
1212
@@ -14,7 +14,7 @@ buildGoPackage rec {
1414 owner = "docker-slim";
1515 repo = "docker-slim";
1616 rev = version;
17− sha256 = "sha256-jzwQ3nrhLDiQXcVkPiXrRAmpLQOD8ILBnoCEUiEbxzw=";
17+ sha256 = "sha256-iz1V+wcrJf0grOe81kwbXPBqnvXpHnh7IMDdugaUOH0=";
1818 };
1919
2020 subPackages = [ "cmd/docker-slim" "cmd/docker-slim-sensor" ];
pkgs/applications/window-managers/berry/default.nix+1−1
@@ -55,6 +55,7 @@ stdenv.mkDerivation rec {
5555 ];
5656
5757 meta = with lib; {
58+ homepage = "https://berrywm.org/";
5859 description = "A healthy, bite-sized window manager";
5960 longDescription = ''
6061 berry is a healthy, bite-sized window manager written in C for unix
@@ -69,7 +70,6 @@ stdenv.mkDerivation rec {
6970 - Intuitively place new windows in unoccupied spaces.
7071 - Virtual desktops.
7172 '';
72− homepage = "https://berrywm.org/";
7373 license = licenses.mit;
7474 maintainers = [ maintainers.AndersonTorres ];
7575 platforms = platforms.linux;
pkgs/applications/window-managers/icewm/default.nix+9−8
@@ -40,13 +40,13 @@
4040
4141stdenv.mkDerivation rec {
4242 pname = "icewm";
43− version = "2.9.4";
43+ version = "2.9.6";
4444
4545 src = fetchFromGitHub {
46− owner = "ice-wm";
46+ owner = "ice-wm";
4747 repo = pname;
4848 rev = version;
49− hash = "sha256-ne2lqo9CAhGgC8dd9R03zhFXy9nPBQR0NcfAY0DeVj4=";
49+ hash = "sha256-qC8gEVJ/cmsEbF8jMzv7zyvVcjlbXhgHU3ixe7RLcnA=";
5050 };
5151
5252 nativeBuildInputs = [
@@ -55,6 +55,7 @@ stdenv.mkDerivation rec {
5555 perl
5656 pkg-config
5757 ];
58+
5859 buildInputs = [
5960 expat
6061 fontconfig
@@ -108,11 +109,11 @@ stdenv.mkDerivation rec {
108109 system. Application windows can be managed by keyboard and mouse. Windows
109110 can be iconified to the taskbar, to the tray, to the desktop or be made
110111 hidden. They are controllable by a quick switch window (Alt+Tab) and in a
111− window list. A handful of configurable focus models are
112− menu-selectable. Setups with multiple monitors are supported by RandR and
113− Xinerama. IceWM is very configurable, themeable and well documented. It
114− includes an optional external background wallpaper manager with
115− transparency support, a simple session manager and a system tray.
112+ window list. A handful of configurable focus models are menu-selectable.
113+ Setups with multiple monitors are supported by RandR and Xinerama. IceWM
114+ is very configurable, themeable and well documented. It includes an
115+ optional external background wallpaper manager with transparency support,
116+ a simple session manager and a system tray.
116117 '';
117118 license = licenses.lgpl2Only;
118119 maintainers = [ maintainers.AndersonTorres ];
pkgs/applications/window-managers/labwc/default.nix+3−8
@@ -21,20 +21,15 @@
2121
2222stdenv.mkDerivation rec {
2323 pname = "labwc";
24− version = "0.4.0";
24+ version = "0.5.0";
2525
2626 src = fetchFromGitHub {
2727 owner = "labwc";
2828 repo = pname;
2929 rev = version;
30− hash = "sha256-O9jVDR7UROt5u8inUsZjbzB3dQTosiLYqXkeOyGrbaM=";
30+ hash = "sha256-G0EQuXSHftl4JLXKIro+tmhbApwAhlzcjPEL7DP6LHk=";
3131 };
3232
33− patches = [
34− # Required to fix the build with wlroots 0.15.1:
35− ./relax-the-version-constraint-for-wlroots.patch
36− ];
37−
3833 nativeBuildInputs = [
3934 meson
4035 ninja
@@ -64,6 +59,6 @@ stdenv.mkDerivation rec {
6459 description = "A Wayland stacking compositor, similar to Openbox";
6560 license = licenses.gpl2Plus;
6661 maintainers = with maintainers; [ AndersonTorres ];
67− platforms = platforms.unix;
62+ inherit (wayland.meta) platforms;
6863 };
6964}
pkgs/applications/window-managers/labwc/relax-the-version-constraint-for-wlroots.patchdeleted−29
@@ -1,29 +0,0 @@
1−From 21d8bfcf7899f5ec50b29f523ace4c19cbfbe919 Mon Sep 17 00:00:00 2001
2−From: Michael Weiss <dev.primeos@gmail.com>
3−Date: Fri, 4 Feb 2022 21:17:05 +0100
4−Subject: [PATCH] build: Relax the version constraint for wlroots to accept
5− patch releases
6−
7−Patch releases only contain backwards compatible changes (mainly bug
8−fixes) so we want to allow them. This fixes the build with the recently
9−released wlroots 0.15.1 and uses the same version constraints as other
10−projects that depend on wlroots (e.g., Sway).
11−---
12− meson.build | 2 +-
13− 1 file changed, 1 insertion(+), 1 deletion(-)
14−
15−diff --git a/meson.build b/meson.build
16−index f950b8e..1905dda 100644
17−--- a/meson.build
18−+++ b/meson.build
19−@@ -37,7 +37,7 @@ if git.found()
20− endif
21− add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c')
22−
23−-wlroots_version = ['=0.15.0']
24−+wlroots_version = ['>=0.15.0', '<0.16.0']
25− wlroots_proj = subproject(
26− 'wlroots',
27− default_options: ['default_library=static', 'examples=false'],
28−--
29−2.34.1
pkgs/development/libraries/cimg/default.nix+2−2
@@ -5,13 +5,13 @@
55
66stdenv.mkDerivation rec {
77 pname = "cimg";
8− version = "3.0.0";
8+ version = "3.0.2";
99
1010 src = fetchFromGitHub {
1111 owner = "dtschump";
1212 repo = "CImg";
1313 rev = "v.${version}";
14− hash = "sha256-dC4VuWTz0uyFxLjBQ+2ggndHaCErcoI7tJMfkqbWmeg=";
14+ hash = "sha256-OWpztnyVXCg+uoAb6e/2eUK2ebBalDlz6Qcjf17IeMk=";
1515 };
1616
1717 outputs = [ "out" "doc" ];
pkgs/development/libraries/elpa/default.nix+2−2
@@ -18,13 +18,13 @@ assert blas.isILP64 == scalapack.isILP64;
1818
1919stdenv.mkDerivation rec {
2020 pname = "elpa";
21− version = "2021.11.001";
21+ version = "2021.11.002";
2222
2323 passthru = { inherit (blas) isILP64; };
2424
2525 src = fetchurl {
2626 url = "https://elpa.mpcdf.mpg.de/software/tarball-archive/Releases/${version}/elpa-${version}.tar.gz";
27− sha256 = "0bw0nwzwvjfmijfwznmrghypd3q237a3h5g5fcdncilrqnk1sdpv";
27+ sha256 = "sha256-V28cru14g7gTlmQP2g9QQYOGbPbL1Lxx0Tg7oiCPH5c=";
2828 };
2929
3030 patches = [
pkgs/development/libraries/zchunk/default.nix+3−2
@@ -11,13 +11,13 @@
1111
1212stdenv.mkDerivation rec {
1313 pname = "zchunk";
14− version = "1.1.16";
14+ version = "1.2.0";
1515
1616 src = fetchFromGitHub {
1717 owner = "zchunk";
1818 repo = pname;
1919 rev = version;
20− hash = "sha256-+8FkivLTZXdu0+1wu+7T98y6rQzIHbG9l15Abrbln1o=";
20+ hash = "sha256-7H1WF5VkpA65xCdEa0Sw4r4jj+kGhDVCMr5AeE+3Ii4=";
2121 };
2222
2323 nativeBuildInputs = [
@@ -47,5 +47,6 @@ stdenv.mkDerivation rec {
4747 license = licenses.bsd2;
4848 maintainers = with maintainers; [ AndersonTorres ];
4949 platforms = platforms.unix;
50+ broken = stdenv.isDarwin; # does not find argp-standalone
5051 };
5152}
pkgs/development/python-modules/allure-behave/default.nixnew file+38
@@ -0,0 +1,38 @@
1+{ lib
2+, fetchPypi
3+, buildPythonPackage
4+, pythonOlder
5+, behave
6+, allure-python-commons
7+, setuptools-scm
8+}:
9+
10+buildPythonPackage rec {
11+ pname = "allure-behave";
12+ version = "2.9.45";
13+
14+ disabled = pythonOlder "3.4";
15+
16+ src = fetchPypi {
17+ inherit pname version;
18+ sha256 = "sha256-aK0SgQIXpuUoSTz8jg5IPKQM2Xvk2EfkSGigsy/GFNo=";
19+ };
20+
21+ nativeBuildInputs = [
22+ setuptools-scm
23+ ];
24+
25+ pythonImportsCheck = [ "allure_behave" ];
26+
27+ propagatedBuildInputs = [
28+ allure-python-commons
29+ behave
30+ ];
31+
32+ meta = with lib; {
33+ description = "Allure behave integration.";
34+ homepage = "https://github.com/allure-framework/allure-python";
35+ license = licenses.asl20;
36+ maintainers = with maintainers; [ happysalada ];
37+ };
38+}
pkgs/development/python-modules/wled/default.nix+2−2
@@ -15,7 +15,7 @@
1515
1616buildPythonPackage rec {
1717 pname = "wled";
18− version = "0.13.0";
18+ version = "0.13.1";
1919 format = "pyproject";
2020
2121 disabled = pythonOlder "3.8";
@@ -24,7 +24,7 @@ buildPythonPackage rec {
2424 owner = "frenck";
2525 repo = "python-wled";
2626 rev = "v${version}";
27− sha256 = "sha256-n+TIzlnyPeSywTQr7wlGNezsbQ2+S/WYt1H95+Id2Rw=";
27+ sha256 = "sha256-QQPrAfk+BX8mjqn9ISim9hLEZR2nbgxbkwCv+91yeRY=";
2828 };
2929
3030 nativeBuildInputs = [
pkgs/development/tools/analysis/actionlint/default.nix+3−3
@@ -2,7 +2,7 @@
22
33buildGoModule rec {
44 pname = "actionlint";
5− version = "1.6.9";
5+ version = "1.6.10";
66
77 subPackages = [ "cmd/actionlint" ];
88
@@ -10,10 +10,10 @@ buildGoModule rec {
1010 owner = "rhysd";
1111 repo = "actionlint";
1212 rev = "v${version}";
13− sha256 = "sha256-UDa/qFtRTED6d+lPbjNknX9qFZ3QZ9jiD0ByvLsGARk=";
13+ sha256 = "sha256-RFsNJiCeSAeEWOUnfBpeIZKoS2mlXazYMQd1M6yFLGU=";
1414 };
1515
16− vendorSha256 = "sha256-0tytdTZxnWYl8AxaquF0ArY3dy51j8H2kzw69qcSHzk=";
16+ vendorSha256 = "sha256-CxNER8aQftMG14M+x6bPwcXgUZRkUDYZtFg1cPxxg+I=";
1717
1818 nativeBuildInputs = [ ronn installShellFiles ];
1919
pkgs/development/tools/analysis/flow/default.nix+2−2
@@ -2,13 +2,13 @@
22
33stdenv.mkDerivation rec {
44 pname = "flow";
5− version = "0.172.0";
5+ version = "0.173.0";
66
77 src = fetchFromGitHub {
88 owner = "facebook";
99 repo = "flow";
1010 rev = "v${version}";
11− sha256 = "sha256-N3mP1dhul7Ljn278CJmge4IrVllQJsc73A3/7mTSU70=";
11+ sha256 = "sha256-F0t85/sq9p+eNEf2XAGxw+ZWeRgUbkhrKFdGASijuAs=";
1212 };
1313
1414 installPhase = ''
pkgs/development/tools/buildkit/default.nix+2−2
@@ -2,13 +2,13 @@
22
33buildGoModule rec {
44 pname = "buildkit";
5− version = "0.9.3";
5+ version = "0.10.0";
66
77 src = fetchFromGitHub {
88 owner = "moby";
99 repo = "buildkit";
1010 rev = "v${version}";
11− sha256 = "sha256-xjuHMjJjA4sx2Hrr6tPpvKtSmhGZ3AZka733DLxmYfk=";
11+ sha256 = "sha256-Pdnu0zG1LteAob0YUuG/XDh2pfBj5UO2GrkWFlMZeGY=";
1212 };
1313
1414 vendorSha256 = null;
pkgs/development/tools/cloud-nuke/default.nix+2−2
@@ -2,13 +2,13 @@
22
33buildGoModule rec {
44 pname = "cloud-nuke";
5− version = "0.10.0";
5+ version = "0.11.0";
66
77 src = fetchFromGitHub {
88 owner = "gruntwork-io";
99 repo = pname;
1010 rev = "v${version}";
11− sha256 = "sha256-y1YpPYTejeZjz4nJmyAPT8rYaEguaJpBfAAfF38dpA4=";
11+ sha256 = "sha256-G1RQEKb3vK8lg0jakCtIMgQXmWqfsq0QWHwU8TAbBbE=";
1212 };
1313
1414 vendorSha256 = "sha256-McCbogZvgm9pnVjay9O2CxAh+653JnDMcU4CHD0PTPI=";
pkgs/development/tools/ocaml/dune/3.nix+2−2
@@ -6,11 +6,11 @@ else
66
77stdenv.mkDerivation rec {
88 pname = "dune";
9− version = "3.0.2";
9+ version = "3.0.3";
1010
1111 src = fetchurl {
1212 url = "https://github.com/ocaml/dune/releases/download/${version}/fiber-${version}.tbz";
13− sha256 = "sha256-o108qIeWMOX0VU/wWdc5bg/UDCT2CCcw/Xx3nFiDbes=";
13+ sha256 = "sha256-1QRJmhZY8Nmcrvv/1zhvLjHUbOynMWcVf+RobEHlcy8=";
1414 };
1515
1616 nativeBuildInputs = [ ocaml findlib ];
pkgs/development/tools/wllvm/default.nix+2−3
@@ -1,13 +1,12 @@
11{ lib, python3Packages }:
22
33python3Packages.buildPythonApplication rec {
4− version = "1.2.8";
4+ version = "1.3.1";
55 pname = "wllvm";
6− name = "${pname}-${version}";
76
87 src = python3Packages.fetchPypi {
98 inherit pname version;
10− sha256 = "1d88fzg4ba4r3hwrinnv6agiyj3xxdy4yryb8wz2ml51nc6bi591";
9+ sha256 = "sha256-PgV6V18FyezIZpqMQEbyv98MaVM7h7T7/Kvg3yMMwzE=";
1110 };
1211
1312 meta = with lib; {
pkgs/servers/sql/postgresql/ext/rum.nixnew file+31
@@ -0,0 +1,31 @@
1+{ lib, stdenv, fetchFromGitHub, postgresql }:
2+
3+stdenv.mkDerivation rec {
4+ pname = "rum";
5+ version = "1.3.9";
6+
7+ src = fetchFromGitHub {
8+ owner = "postgrespro";
9+ repo = "rum";
10+ rev = version;
11+ sha256 = "sha256-xdCj9hzBg7VtAIHpIFpeeaK6U4aRrCsoQrPKdABSl+Y=";
12+ };
13+
14+ buildInputs = [ postgresql ];
15+
16+ makeFlags = [ "USE_PGXS=1" ];
17+
18+ installPhase = ''
19+ install -D -t $out/lib *.so
20+ install -D -t $out/share/postgresql/extension *.control
21+ install -D -t $out/share/postgresql/extension *.sql
22+ '';
23+
24+ meta = with lib; {
25+ description = "Full text search index method for PostgreSQL";
26+ homepage = "https://github.com/postgrespro/rum";
27+ license = licenses.postgresql;
28+ platforms = postgresql.meta.platforms;
29+ maintainers = with maintainers; [ DeeUnderscore ];
30+ };
31+}
pkgs/servers/sql/postgresql/packages.nix+2
@@ -61,4 +61,6 @@ self: super: {
6161 pg_safeupdate = super.callPackage ./ext/pg_safeupdate.nix { };
6262
6363 repmgr = super.callPackage ./ext/repmgr.nix { };
64+
65+ rum = super.callPackage ./ext/rum.nix { };
6466}
pkgs/shells/tcsh/default.nix+8−7
@@ -7,20 +7,21 @@
77
88stdenv.mkDerivation rec {
99 pname = "tcsh";
10− version = "6.23.02";
10+ version = "6.24.00";
1111
1212 src = fetchurl {
1313 urls = [
14− "https://astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
1514 "https://astron.com/pub/tcsh/${pname}-${version}.tar.gz"
16− "http://ftp.funet.fi/pub/mirrors/ftp.astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
15+ "https://astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
1716 "http://ftp.funet.fi/pub/mirrors/ftp.astron.com/pub/tcsh/${pname}-${version}.tar.gz"
18− "ftp://ftp.funet.fi/pub/unix/shells/tcsh/old/${pname}-${version}.tar.gz"
19− "ftp://ftp.funet.fi/pub/unix/shells/tcsh/${pname}-${version}.tar.gz"
20− "ftp://ftp.astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
17+ "http://ftp.funet.fi/pub/mirrors/ftp.astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
18+
2119 "ftp://ftp.astron.com/pub/tcsh/${pname}-${version}.tar.gz"
20+ "ftp://ftp.astron.com/pub/tcsh/old/${pname}-${version}.tar.gz"
21+ "ftp://ftp.funet.fi/pub/unix/shells/tcsh/${pname}-${version}.tar.gz"
22+ "ftp://ftp.funet.fi/pub/unix/shells/tcsh/old/${pname}-${version}.tar.gz"
2223 ];
23− hash = "sha256-wD+AQFE2cxswkdpzWoHN2EgAhRAySrMl8jWv9wnkRus=";
24+ hash = "sha256-YL4sUEvY8fpuQksZVkldfnztUqKslNtf0n9La/yPdPA=";
2425 };
2526
2627 buildInputs = [
pkgs/tools/misc/nncp/default.nix+2−2
@@ -3,12 +3,12 @@
33
44stdenv.mkDerivation rec {
55 pname = "nncp";
6− version = "8.7.1";
6+ version = "8.7.2";
77 outputs = [ "out" "doc" "info" ];
88
99 src = fetchurl {
1010 url = "http://www.nncpgo.org/download/${pname}-${version}.tar.xz";
11− hash = "sha256-zrTRl69ajZ6Tt0nVwPULU+Z0ajGK9Hs2S/XLMj1sTr0=";
11+ hash = "sha256-oO7JsPMwWd4z8TCEWZgF0PShyMN56SW6z+jclNHdwj0=";
1212 };
1313
1414 nativeBuildInputs = [ go redo-apenwarr ];
pkgs/tools/networking/minio-client/default.nix+3−3
@@ -2,16 +2,16 @@
22
33buildGoModule rec {
44 pname = "minio-client";
5− version = "2022-03-03T21-12-24Z";
5+ version = "2022-03-09T02-08-36Z";
66
77 src = fetchFromGitHub {
88 owner = "minio";
99 repo = "mc";
1010 rev = "RELEASE.${version}";
11− sha256 = "sha256-z+t8aMyGlqXcooCzJgn0xxOhuS+p3/qMTBJByDJPd40=";
11+ sha256 = "sha256-OaV0Xb3nNeZJLayGperQah0JQ7BlGFPWa1//Kt5+EiU=";
1212 };
1313
14− vendorSha256 = "sha256-mk0ga3o6LeZ4uwV3vlP6qyFXLiORwNQLhXoCxSmvXsU=";
14+ vendorSha256 = "sha256-Wdw9mZ3UupoJ4yDwS4f3mOmCn+7TvHmx4aRu+96pHM4=";
1515
1616 subPackages = [ "." ];
1717
pkgs/tools/networking/ytcc/default.nix+2−2
@@ -2,13 +2,13 @@
22
33python3Packages.buildPythonApplication rec {
44 pname = "ytcc";
5− version = "2.5.4";
5+ version = "2.5.5";
66
77 src = fetchFromGitHub {
88 owner = "woefe";
99 repo = "ytcc";
1010 rev = "v${version}";
11− sha256 = "sha256-nYHfmksZnIZGMSSFDhW7ajvv1F5h3aJo8IXw6yYOEw0=";
11+ sha256 = "sha256-DjyVcjU2dVku5ademm6DygMnzWHB7iMqPfU56BBjAwU=";
1212 };
1313
1414 nativeBuildInputs = [ gettext installShellFiles ];
pkgs/tools/security/sops/default.nix+3−3
@@ -2,16 +2,16 @@
22
33buildGoModule rec {
44 pname = "sops";
5− version = "3.7.1";
5+ version = "3.7.2";
66
77 src = fetchFromGitHub {
88 rev = "v${version}";
99 owner = "mozilla";
1010 repo = pname;
11− sha256 = "0z3jcyl245yjszzjf2h6l1dwa092vxzvfmnivmwi6jvpsdcv33h1";
11+ sha256 = "sha256-NMuYMvaBSxKHvpqFkMfnMDvcXxTstqzracuSTT1VB1A=";
1212 };
1313
14− vendorSha256 = "1mnwgsbpi56ql0lbpn7dkaps96x9b1lmhlk5cd6d40da7xj616n7";
14+ vendorSha256 = "sha256-00/7O9EcGojUExJPtYWndb16VqrNby/5GsVs8Ak/Isc=";
1515
1616 doCheck = false;
1717
pkgs/tools/security/swtpm/default.nix+34−7
@@ -16,35 +16,40 @@
1616
1717stdenv.mkDerivation rec {
1818 pname = "swtpm";
19− version = "0.7.1";
19+ version = "0.7.2";
2020
2121 src = fetchFromGitHub {
2222 owner = "stefanberger";
2323 repo = "swtpm";
2424 rev = "v${version}";
25− sha256 = "sha256-LJQF8PlRkhCJ8rjZzDetg1BFuTb7GBJ8lW6u5hO134k=";
25+ sha256 = "sha256-qeyPCJTNnwuaCosHzqnrQc0JNznGBfDTLsuDmuKREjU=";
2626 };
2727
2828 nativeBuildInputs = [
2929 pkg-config unixtools.netstat expect socat
3030 perl # for pod2man
31+ python3
3132 autoreconfHook
3233 ];
3334
3435 checkInputs = [
35− python3 which
36+ which
3637 ];
3738
3839 buildInputs = [
3940 libtpms
40− openssl libtasn1 libseccomp
41− fuse glib json-glib
41+ openssl libtasn1
42+ glib json-glib
4243 gnutls
44+ ] ++ lib.optionals stdenv.isLinux [
45+ fuse
46+ libseccomp
4347 ];
4448
4549 configureFlags = [
46− "--with-cuse"
4750 "--localstatedir=/var"
51+ ] ++ lib.optionals stdenv.isLinux [
52+ "--with-cuse"
4853 ];
4954
5055 postPatch = ''
@@ -56,9 +61,31 @@ stdenv.mkDerivation rec {
5661
5762 # Use the correct path to the certtool binary
5863 # instead of relying on it being in the environment
59− substituteInPlace src/swtpm_localca/swtpm_localca.c --replace \
64+ substituteInPlace src/swtpm_localca/swtpm_localca.c \
65+ --replace \
66+ '# define CERTTOOL_NAME "gnutls-certtool"' \
67+ '# define CERTTOOL_NAME "${gnutls}/bin/certtool"' \
68+ --replace \
6069 '# define CERTTOOL_NAME "certtool"' \
6170 '# define CERTTOOL_NAME "${gnutls}/bin/certtool"'
71+
72+ substituteInPlace tests/common --replace \
73+ 'CERTTOOL=gnutls-certtool;;' \
74+ 'CERTTOOL=certtool;;'
75+
76+ # Fix error on macOS:
77+ # stat: invalid option -- '%'
78+ # This is caused by the stat program not being the BSD version,
79+ # as is expected by the test
80+ substituteInPlace tests/common --replace \
81+ 'if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then' \
82+ 'if [[ "$(uname -s)" =~ (Linux|Darwin|CYGWIN_NT-) ]]; then'
83+
84+ # Otherwise certtool seems to pick up the system language on macOS,
85+ # which might cause a test to fail
86+ substituteInPlace tests/test_swtpm_setup_create_cert --replace \
87+ '$CERTTOOL' \
88+ 'LC_ALL=C.UTF-8 $CERTTOOL'
6289 '';
6390
6491 doCheck = true;
pkgs/top-level/all-packages.nix+3−1
@@ -29073,7 +29073,9 @@ with pkgs;
2907329073
2907429074 psst = callPackage ../applications/audio/psst { };
2907529075
29076− squeezelite = callPackage ../applications/audio/squeezelite { };
29076+ squeezelite = callPackage ../applications/audio/squeezelite { audioBackend = "alsa"; };
29077+
29078+ squeezelite-pulse = callPackage ../applications/audio/squeezelite { audioBackend = "pulse"; };
2907729079
2907829080 ltunify = callPackage ../tools/misc/ltunify { };
2907929081
pkgs/top-level/python-packages.nix+2
@@ -456,6 +456,8 @@ in {
456456
457457 allpairspy = callPackage ../development/python-modules/allpairspy { };
458458
459+ allure-behave = callPackage ../development/python-modules/allure-behave { };
460+
459461 allure-python-commons = callPackage ../development/python-modules/allure-python-commons { };
460462
461463 allure-python-commons-test = callPackage ../development/python-modules/allure-python-commons-test { };