···1568 encapsulation.
1569 </para>
1570 </listitem>
1571+ <listitem>
1572+ <para>
1573+ Changing systemd <literal>.socket</literal> units now restarts
1574+ them and stops the service that is activated by them.
1575+ Additionally, services with
1576+ <literal>stopOnChange = false</literal> don’t break anymore
1577+ when they are socket-activated.
1578+ </para>
1579+ </listitem>
1580 </itemizedlist>
1581 </section>
1582</section>
+2
nixos/doc/manual/release-notes/rl-2111.section.md
···453- The `networking` module has a new `networking.fooOverUDP` option to configure Foo-over-UDP encapsulations.
454455- `networking.sits` now supports Foo-over-UDP encapsulation.
00
···453- The `networking` module has a new `networking.fooOverUDP` option to configure Foo-over-UDP encapsulations.
454455- `networking.sits` now supports Foo-over-UDP encapsulation.
456+457+- Changing systemd `.socket` units now restarts them and stops the service that is activated by them. Additionally, services with `stopOnChange = false` don't break anymore when they are socket-activated.
···1112my $out = "@out@";
1314-# FIXME: maybe we should use /proc/1/exe to get the current systemd.
15my $curSystemd = abs_path("/run/current-system/sw/bin");
1617# To be robust against interruption, record what units need to be started etc.
···19my $restartListFile = "/run/nixos/restart-list";
20my $reloadListFile = "/run/nixos/reload-list";
2122-# Parse restart/reload requests by the activation script
0000023my $restartByActivationFile = "/run/nixos/activation-restart-list";
24-my $reloadByActivationFile = "/run/nixos/activation-reload-list";
25my $dryRestartByActivationFile = "/run/nixos/dry-activation-restart-list";
26-my $dryReloadByActivationFile = "/run/nixos/dry-activation-reload-list";
2728-make_path("/run/nixos", { mode => 0755 });
2930my $action = shift @ARGV;
31···147 return abs_path($s) . (-f "${s}.d/overrides.conf" ? " " . abs_path "${s}.d/overrides.conf" : "");
148}
14900000000000000000000000000000000000000000000000000000000000000000000000000000000000000150# Figure out what units need to be stopped, started, restarted or reloaded.
151my (%unitsToStop, %unitsToSkip, %unitsToStart, %unitsToRestart, %unitsToReload);
152···219 }
220221 elsif (fingerprintUnit($prevUnitFile) ne fingerprintUnit($newUnitFile)) {
222- if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
223- # Do nothing. These cannot be restarted directly.
224- } elsif ($unit =~ /\.mount$/) {
225- # Reload the changed mount unit to force a remount.
226- $unitsToReload{$unit} = 1;
227- recordUnit($reloadListFile, $unit);
228- } elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/ || $unit =~ /\.slice$/) {
229- # FIXME: do something?
230- } else {
231- my $unitInfo = parseUnit($newUnitFile);
232- if (boolIsTrue($unitInfo->{'X-ReloadIfChanged'} // "no")) {
233- $unitsToReload{$unit} = 1;
234- recordUnit($reloadListFile, $unit);
235- }
236- elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes") || boolIsTrue($unitInfo->{'RefuseManualStop'} // "no") || boolIsTrue($unitInfo->{'X-OnlyManualStart'} // "no")) {
237- $unitsToSkip{$unit} = 1;
238- } else {
239- if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) {
240- # This unit should be restarted instead of
241- # stopped and started.
242- $unitsToRestart{$unit} = 1;
243- recordUnit($restartListFile, $unit);
244- } else {
245- # If this unit is socket-activated, then stop the
246- # socket unit(s) as well, and restart the
247- # socket(s) instead of the service.
248- my $socketActivated = 0;
249- if ($unit =~ /\.service$/) {
250- my @sockets = split / /, ($unitInfo->{Sockets} // "");
251- if (scalar @sockets == 0) {
252- @sockets = ("$baseName.socket");
253- }
254- foreach my $socket (@sockets) {
255- if (defined $activePrev->{$socket}) {
256- $unitsToStop{$socket} = 1;
257- # Only restart sockets that actually
258- # exist in new configuration:
259- if (-e "$out/etc/systemd/system/$socket") {
260- $unitsToStart{$socket} = 1;
261- recordUnit($startListFile, $socket);
262- $socketActivated = 1;
263- }
264- }
265- }
266- }
267-268- # If the unit is not socket-activated, record
269- # that this unit needs to be started below.
270- # We write this to a file to ensure that the
271- # service gets restarted if we're interrupted.
272- if (!$socketActivated) {
273- $unitsToStart{$unit} = 1;
274- recordUnit($startListFile, $unit);
275- }
276-277- $unitsToStop{$unit} = 1;
278- }
279- }
280- }
281 }
282 }
283}
···362}
363364my @unitsToStopFiltered = filterUnits(\%unitsToStop);
365-my @unitsToStartFiltered = filterUnits(\%unitsToStart);
366-367368# Show dry-run actions.
369if ($action eq "dry-activate") {
···375 print STDERR "would activate the configuration...\n";
376 system("$out/dry-activate", "$out");
377378- $unitsToRestart{$_} = 1 foreach
379- split('\n', read_file($dryRestartByActivationFile, err_mode => 'quiet') // "");
00000380381- $unitsToReload{$_} = 1 foreach
382- split('\n', read_file($dryReloadByActivationFile, err_mode => 'quiet') // "");
0000000000000000000383384 print STDERR "would restart systemd\n" if $restartSystemd;
00385 print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
386 if scalar(keys %unitsToRestart) > 0;
0387 print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
388 if scalar @unitsToStartFiltered;
389- print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
390- if scalar(keys %unitsToReload) > 0;
391- unlink($dryRestartByActivationFile);
392- unlink($dryReloadByActivationFile);
393 exit 0;
394}
395···400 print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
401 if scalar @unitsToStopFiltered;
402 # Use current version of systemctl binary before daemon is reexeced.
403- system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
404}
405406print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
···414415# Handle the activation script requesting the restart or reload of a unit.
416# We can only restart and reload (not stop/start) because the units to be
417-# stopped are already stopped before the activation script is run.
418-$unitsToRestart{$_} = 1 foreach
419- split('\n', read_file($restartByActivationFile, err_mode => 'quiet') // "");
00000000000000000000000000420421-$unitsToReload{$_} = 1 foreach
422- split('\n', read_file($reloadByActivationFile, err_mode => 'quiet') // "");
423424# Restart systemd if necessary. Note that this is done using the
425# current version of systemd, just in case the new one has trouble
···460 print STDERR "reloading the following units: ", join(", ", sort(keys %unitsToReload)), "\n";
461 system("@systemd@/bin/systemctl", "reload", "--", sort(keys %unitsToReload)) == 0 or $res = 4;
462 unlink($reloadListFile);
463- unlink($reloadByActivationFile);
464}
465466# Restart changed services (those that have to be restarted rather
467# than stopped and started).
468if (scalar(keys %unitsToRestart) > 0) {
469 print STDERR "restarting the following units: ", join(", ", sort(keys %unitsToRestart)), "\n";
470- system("@systemd@/bin/systemctl", "restart", "--", sort(keys %unitsToRestart)) == 0 or $res = 4;
000000000000000000000000000471 unlink($restartListFile);
472 unlink($restartByActivationFile);
473}
···478# that are symlinks to other units. We shouldn't start both at the
479# same time because we'll get a "Failed to add path to set" error from
480# systemd.
0481print STDERR "starting the following units: ", join(", ", @unitsToStartFiltered), "\n"
482 if scalar @unitsToStartFiltered;
483system("@systemd@/bin/systemctl", "start", "--", sort(keys %unitsToStart)) == 0 or $res = 4;
···485486487# Print failed and new units.
488-my (@failed, @new, @restarting);
489my $activeNew = getActiveUnits;
490while (my ($unit, $state) = each %{$activeNew}) {
491 if ($state->{state} eq "failed") {
···501 push @failed, $unit;
502 }
503 }
504- elsif ($state->{state} ne "failed" && !defined $activePrev->{$unit}) {
00505 push @new, $unit;
506 }
507}
···1112my $out = "@out@";
13014my $curSystemd = abs_path("/run/current-system/sw/bin");
1516# To be robust against interruption, record what units need to be started etc.
···18my $restartListFile = "/run/nixos/restart-list";
19my $reloadListFile = "/run/nixos/reload-list";
2021+# Parse restart/reload requests by the activation script.
22+# Activation scripts may write newline-separated units to this
23+# file and switch-to-configuration will handle them. While
24+# `stopIfChanged = true` is ignored, switch-to-configuration will
25+# handle `restartIfChanged = false` and `reloadIfChanged = true`.
26+# This also works for socket-activated units.
27my $restartByActivationFile = "/run/nixos/activation-restart-list";
028my $dryRestartByActivationFile = "/run/nixos/dry-activation-restart-list";
02930+make_path("/run/nixos", { mode => oct(755) });
3132my $action = shift @ARGV;
33···149 return abs_path($s) . (-f "${s}.d/overrides.conf" ? " " . abs_path "${s}.d/overrides.conf" : "");
150}
151152+sub handleModifiedUnit {
153+ my ($unit, $baseName, $newUnitFile, $activePrev, $unitsToStop, $unitsToStart, $unitsToReload, $unitsToRestart, $unitsToSkip) = @_;
154+155+ if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target" || $unit =~ /\.slice$/ || $unit =~ /\.path$/) {
156+ # Do nothing. These cannot be restarted directly.
157+ # Slices and Paths don't have to be restarted since
158+ # properties (resource limits and inotify watches)
159+ # seem to get applied on daemon-reload.
160+ } elsif ($unit =~ /\.mount$/) {
161+ # Reload the changed mount unit to force a remount.
162+ $unitsToReload->{$unit} = 1;
163+ recordUnit($reloadListFile, $unit);
164+ } else {
165+ my $unitInfo = parseUnit($newUnitFile);
166+ if (boolIsTrue($unitInfo->{'X-ReloadIfChanged'} // "no")) {
167+ $unitsToReload->{$unit} = 1;
168+ recordUnit($reloadListFile, $unit);
169+ }
170+ elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes") || boolIsTrue($unitInfo->{'RefuseManualStop'} // "no") || boolIsTrue($unitInfo->{'X-OnlyManualStart'} // "no")) {
171+ $unitsToSkip->{$unit} = 1;
172+ } else {
173+ # If this unit is socket-activated, then stop it instead
174+ # of restarting it to make sure the new version of it is
175+ # socket-activated.
176+ my $socketActivated = 0;
177+ if ($unit =~ /\.service$/) {
178+ my @sockets = split / /, ($unitInfo->{Sockets} // "");
179+ if (scalar @sockets == 0) {
180+ @sockets = ("$baseName.socket");
181+ }
182+ foreach my $socket (@sockets) {
183+ if (-e "$out/etc/systemd/system/$socket") {
184+ $socketActivated = 1;
185+ $unitsToStop->{$unit} = 1;
186+ # If the socket was not running previously,
187+ # start it now.
188+ if (not defined $activePrev->{$socket}) {
189+ $unitsToStart->{$socket} = 1;
190+ }
191+ }
192+ }
193+ }
194+195+ # Don't do the rest of this for socket-activated units
196+ # because we handled these above where we stop the unit.
197+ # Since only services can be socket-activated, the
198+ # following condition always evaluates to `true` for
199+ # non-service units.
200+ if ($socketActivated) {
201+ return;
202+ }
203+204+ # If we are restarting a socket, also stop the corresponding
205+ # service. This is required because restarting a socket
206+ # when the service is already activated fails.
207+ if ($unit =~ /\.socket$/) {
208+ my $service = $unitInfo->{Service} // "";
209+ if ($service eq "") {
210+ $service = "$baseName.service";
211+ }
212+ if (defined $activePrev->{$service}) {
213+ $unitsToStop->{$service} = 1;
214+ }
215+ $unitsToRestart->{$unit} = 1;
216+ recordUnit($restartListFile, $unit);
217+ } else {
218+ # Always restart non-services instead of stopping and starting them
219+ # because it doesn't make sense to stop them with a config from
220+ # the old evaluation.
221+ if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes") || $unit !~ /\.service$/) {
222+ # This unit should be restarted instead of
223+ # stopped and started.
224+ $unitsToRestart->{$unit} = 1;
225+ recordUnit($restartListFile, $unit);
226+ } else {
227+ # We write to a file to ensure that the
228+ # service gets restarted if we're interrupted.
229+ $unitsToStart->{$unit} = 1;
230+ recordUnit($startListFile, $unit);
231+ $unitsToStop->{$unit} = 1;
232+ }
233+ }
234+ }
235+ }
236+}
237+238# Figure out what units need to be stopped, started, restarted or reloaded.
239my (%unitsToStop, %unitsToSkip, %unitsToStart, %unitsToRestart, %unitsToReload);
240···307 }
308309 elsif (fingerprintUnit($prevUnitFile) ne fingerprintUnit($newUnitFile)) {
310+ handleModifiedUnit($unit, $baseName, $newUnitFile, $activePrev, \%unitsToStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, %unitsToSkip);
0000000000000000000000000000000000000000000000000000000000311 }
312 }
313}
···392}
393394my @unitsToStopFiltered = filterUnits(\%unitsToStop);
00395396# Show dry-run actions.
397if ($action eq "dry-activate") {
···403 print STDERR "would activate the configuration...\n";
404 system("$out/dry-activate", "$out");
405406+ # Handle the activation script requesting the restart or reload of a unit.
407+ my %unitsToAlsoStop;
408+ my %unitsToAlsoSkip;
409+ foreach (split('\n', read_file($dryRestartByActivationFile, err_mode => 'quiet') // "")) {
410+ my $unit = $_;
411+ my $baseUnit = $unit;
412+ my $newUnitFile = "$out/etc/systemd/system/$baseUnit";
413414+ # Detect template instances.
415+ if (!-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) {
416+ $baseUnit = "$1\@.$2";
417+ $newUnitFile = "$out/etc/systemd/system/$baseUnit";
418+ }
419+420+ my $baseName = $baseUnit;
421+ $baseName =~ s/\.[a-z]*$//;
422+423+ handleModifiedUnit($unit, $baseName, $newUnitFile, $activePrev, \%unitsToAlsoStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, %unitsToAlsoSkip);
424+ }
425+ unlink($dryRestartByActivationFile);
426+427+ my @unitsToAlsoStopFiltered = filterUnits(\%unitsToAlsoStop);
428+ if (scalar(keys %unitsToAlsoStop) > 0) {
429+ print STDERR "would stop the following units as well: ", join(", ", @unitsToAlsoStopFiltered), "\n"
430+ if scalar @unitsToAlsoStopFiltered;
431+ }
432+433+ print STDERR "would NOT restart the following changed units as well: ", join(", ", sort(keys %unitsToAlsoSkip)), "\n"
434+ if scalar(keys %unitsToAlsoSkip) > 0;
435436 print STDERR "would restart systemd\n" if $restartSystemd;
437+ print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
438+ if scalar(keys %unitsToReload) > 0;
439 print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
440 if scalar(keys %unitsToRestart) > 0;
441+ my @unitsToStartFiltered = filterUnits(\%unitsToStart);
442 print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
443 if scalar @unitsToStartFiltered;
0000444 exit 0;
445}
446···451 print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
452 if scalar @unitsToStopFiltered;
453 # Use current version of systemctl binary before daemon is reexeced.
454+ system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToStop));
455}
456457print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
···465466# Handle the activation script requesting the restart or reload of a unit.
467# We can only restart and reload (not stop/start) because the units to be
468+# stopped are already stopped before the activation script is run. We do however
469+# make an exception for services that are socket-activated and that have to be stopped
470+# instead of being restarted.
471+my %unitsToAlsoStop;
472+my %unitsToAlsoSkip;
473+foreach (split('\n', read_file($restartByActivationFile, err_mode => 'quiet') // "")) {
474+ my $unit = $_;
475+ my $baseUnit = $unit;
476+ my $newUnitFile = "$out/etc/systemd/system/$baseUnit";
477+478+ # Detect template instances.
479+ if (!-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) {
480+ $baseUnit = "$1\@.$2";
481+ $newUnitFile = "$out/etc/systemd/system/$baseUnit";
482+ }
483+484+ my $baseName = $baseUnit;
485+ $baseName =~ s/\.[a-z]*$//;
486+487+ handleModifiedUnit($unit, $baseName, $newUnitFile, $activePrev, \%unitsToAlsoStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, %unitsToAlsoSkip);
488+}
489+unlink($restartByActivationFile);
490+491+my @unitsToAlsoStopFiltered = filterUnits(\%unitsToAlsoStop);
492+if (scalar(keys %unitsToAlsoStop) > 0) {
493+ print STDERR "stopping the following units as well: ", join(", ", @unitsToAlsoStopFiltered), "\n"
494+ if scalar @unitsToAlsoStopFiltered;
495+ system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToAlsoStop));
496+}
497498+print STDERR "NOT restarting the following changed units as well: ", join(", ", sort(keys %unitsToAlsoSkip)), "\n"
499+ if scalar(keys %unitsToAlsoSkip) > 0;
500501# Restart systemd if necessary. Note that this is done using the
502# current version of systemd, just in case the new one has trouble
···537 print STDERR "reloading the following units: ", join(", ", sort(keys %unitsToReload)), "\n";
538 system("@systemd@/bin/systemctl", "reload", "--", sort(keys %unitsToReload)) == 0 or $res = 4;
539 unlink($reloadListFile);
0540}
541542# Restart changed services (those that have to be restarted rather
543# than stopped and started).
544if (scalar(keys %unitsToRestart) > 0) {
545 print STDERR "restarting the following units: ", join(", ", sort(keys %unitsToRestart)), "\n";
546+547+ # We split the units to be restarted into sockets and non-sockets.
548+ # This is because restarting sockets may fail which is not bad by
549+ # itself but which will prevent changes on the sockets. We usually
550+ # restart the socket and stop the service before that. Restarting
551+ # the socket will fail however when the service was re-activated
552+ # in the meantime. There is no proper way to prevent that from happening.
553+ my @unitsWithErrorHandling = grep { $_ !~ /\.socket$/ } sort(keys %unitsToRestart);
554+ my @unitsWithoutErrorHandling = grep { $_ =~ /\.socket$/ } sort(keys %unitsToRestart);
555+556+ if (scalar(@unitsWithErrorHandling) > 0) {
557+ system("@systemd@/bin/systemctl", "restart", "--", @unitsWithErrorHandling) == 0 or $res = 4;
558+ }
559+ if (scalar(@unitsWithoutErrorHandling) > 0) {
560+ # Don't print warnings from systemctl
561+ no warnings 'once';
562+ open(OLDERR, ">&", \*STDERR);
563+ close(STDERR);
564+565+ my $ret = system("@systemd@/bin/systemctl", "restart", "--", @unitsWithoutErrorHandling);
566+567+ # Print stderr again
568+ open(STDERR, ">&OLDERR");
569+570+ if ($ret ne 0) {
571+ print STDERR "warning: some sockets failed to restart. Please check your journal (journalctl -eb) and act accordingly.\n";
572+ }
573+ }
574 unlink($restartListFile);
575 unlink($restartByActivationFile);
576}
···581# that are symlinks to other units. We shouldn't start both at the
582# same time because we'll get a "Failed to add path to set" error from
583# systemd.
584+my @unitsToStartFiltered = filterUnits(\%unitsToStart);
585print STDERR "starting the following units: ", join(", ", @unitsToStartFiltered), "\n"
586 if scalar @unitsToStartFiltered;
587system("@systemd@/bin/systemctl", "start", "--", sort(keys %unitsToStart)) == 0 or $res = 4;
···589590591# Print failed and new units.
592+my (@failed, @new);
593my $activeNew = getActiveUnits;
594while (my ($unit, $state) = each %{$activeNew}) {
595 if ($state->{state} eq "failed") {
···605 push @failed, $unit;
606 }
607 }
608+ # Ignore scopes since they are not managed by this script but rather
609+ # created and managed by third-party services via the systemd dbus API.
610+ elsif ($state->{state} ne "failed" && !defined $activePrev->{$unit} && $unit !~ /\.scope$/) {
611 push @new, $unit;
612 }
613}
···7 };
89 nodes = {
10+ machine = { config, pkgs, lib, ... }: {
11+ environment.systemPackages = [ pkgs.socat ]; # for the socket activation stuff
12 users.mutableUsers = false;
13+14+ specialisation = {
15+ # A system with a simple socket-activated unit
16+ simple-socket.configuration = {
17+ systemd.services.socket-activated.serviceConfig = {
18+ ExecStart = pkgs.writeScript "socket-test.py" /* python */ ''
19+ #!${pkgs.python3}/bin/python3
20+21+ from socketserver import TCPServer, StreamRequestHandler
22+ import socket
23+24+ class Handler(StreamRequestHandler):
25+ def handle(self):
26+ self.wfile.write("hello".encode("utf-8"))
27+28+ class Server(TCPServer):
29+ def __init__(self, server_address, handler_cls):
30+ # Invoke base but omit bind/listen steps (performed by systemd activation!)
31+ TCPServer.__init__(
32+ self, server_address, handler_cls, bind_and_activate=False)
33+ # Override socket
34+ self.socket = socket.fromfd(3, self.address_family, self.socket_type)
35+36+ if __name__ == "__main__":
37+ server = Server(("localhost", 1234), Handler)
38+ server.serve_forever()
39+ '';
40+ };
41+ systemd.sockets.socket-activated = {
42+ wantedBy = [ "sockets.target" ];
43+ listenStreams = [ "/run/test.sock" ];
44+ socketConfig.SocketMode = lib.mkDefault "0777";
45+ };
46+ };
47+48+ # The same system but the socket is modified
49+ modified-socket.configuration = {
50+ imports = [ config.specialisation.simple-socket.configuration ];
51+ systemd.sockets.socket-activated.socketConfig.SocketMode = "0666";
52+ };
53+54+ # The same system but the service is modified
55+ modified-service.configuration = {
56+ imports = [ config.specialisation.simple-socket.configuration ];
57+ systemd.services.socket-activated.serviceConfig.X-Test = "test";
58+ };
59+60+ # The same system but both service and socket are modified
61+ modified-service-and-socket.configuration = {
62+ imports = [ config.specialisation.simple-socket.configuration ];
63+ systemd.services.socket-activated.serviceConfig.X-Test = "some_value";
64+ systemd.sockets.socket-activated.socketConfig.SocketMode = "0444";
65+ };
66+67+ # A system with a socket-activated service and some simple services
68+ service-and-socket.configuration = {
69+ imports = [ config.specialisation.simple-socket.configuration ];
70+ systemd.services.simple-service = {
71+ wantedBy = [ "multi-user.target" ];
72+ serviceConfig = {
73+ Type = "oneshot";
74+ RemainAfterExit = true;
75+ ExecStart = "${pkgs.coreutils}/bin/true";
76+ };
77+ };
78+79+ systemd.services.simple-restart-service = {
80+ stopIfChanged = false;
81+ wantedBy = [ "multi-user.target" ];
82+ serviceConfig = {
83+ Type = "oneshot";
84+ RemainAfterExit = true;
85+ ExecStart = "${pkgs.coreutils}/bin/true";
86+ };
87+ };
88+89+ systemd.services.simple-reload-service = {
90+ reloadIfChanged = true;
91+ wantedBy = [ "multi-user.target" ];
92+ serviceConfig = {
93+ Type = "oneshot";
94+ RemainAfterExit = true;
95+ ExecStart = "${pkgs.coreutils}/bin/true";
96+ ExecReload = "${pkgs.coreutils}/bin/true";
97+ };
98+ };
99+100+ systemd.services.no-restart-service = {
101+ restartIfChanged = false;
102+ wantedBy = [ "multi-user.target" ];
103+ serviceConfig = {
104+ Type = "oneshot";
105+ RemainAfterExit = true;
106+ ExecStart = "${pkgs.coreutils}/bin/true";
107+ };
108+ };
109+ };
110+111+ # The same system but with an activation script that restarts all services
112+ restart-and-reload-by-activation-script.configuration = {
113+ imports = [ config.specialisation.service-and-socket.configuration ];
114+ system.activationScripts.restart-and-reload-test = {
115+ supportsDryActivation = true;
116+ deps = [];
117+ text = ''
118+ if [ "$NIXOS_ACTION" = dry-activate ]; then
119+ f=/run/nixos/dry-activation-restart-list
120+ else
121+ f=/run/nixos/activation-restart-list
122+ fi
123+ cat <<EOF >> "$f"
124+ simple-service.service
125+ simple-restart-service.service
126+ simple-reload-service.service
127+ no-restart-service.service
128+ socket-activated.service
129+ EOF
130+ '';
131+ };
132+ };
133+134+ # A system with a timer
135+ with-timer.configuration = {
136+ systemd.timers.test-timer = {
137+ wantedBy = [ "timers.target" ];
138+ timerConfig.OnCalendar = "@1395716396"; # chosen by fair dice roll
139+ };
140+ systemd.services.test-timer = {
141+ serviceConfig = {
142+ Type = "oneshot";
143+ ExecStart = "${pkgs.coreutils}/bin/true";
144+ };
145+ };
146+ };
147+148+ # The same system but with another time
149+ with-timer-modified.configuration = {
150+ imports = [ config.specialisation.with-timer.configuration ];
151+ systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00";
152+ };
153+154+ # A system with a systemd mount
155+ with-mount.configuration = {
156+ systemd.mounts = [
157+ {
158+ description = "Testmount";
159+ what = "tmpfs";
160+ type = "tmpfs";
161+ where = "/testmount";
162+ options = "size=1M";
163+ wantedBy = [ "local-fs.target" ];
164+ }
165+ ];
166+ };
167+168+ # The same system but with another time
169+ with-mount-modified.configuration = {
170+ systemd.mounts = [
171+ {
172+ description = "Testmount";
173+ what = "tmpfs";
174+ type = "tmpfs";
175+ where = "/testmount";
176+ options = "size=10M";
177+ wantedBy = [ "local-fs.target" ];
178+ }
179+ ];
180+ };
181+182+ # A system with a path unit
183+ with-path.configuration = {
184+ systemd.paths.test-watch = {
185+ wantedBy = [ "paths.target" ];
186+ pathConfig.PathExists = "/testpath";
187+ };
188+ systemd.services.test-watch = {
189+ serviceConfig = {
190+ Type = "oneshot";
191+ ExecStart = "${pkgs.coreutils}/bin/touch /testpath-modified";
192+ };
193+ };
194+ };
195+196+ # The same system but watching another file
197+ with-path-modified.configuration = {
198+ imports = [ config.specialisation.with-path.configuration ];
199+ systemd.paths.test-watch.pathConfig.PathExists = lib.mkForce "/testpath2";
200+ };
201+202+ # A system with a slice
203+ with-slice.configuration = {
204+ systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation
205+ systemd.services.testservice = {
206+ serviceConfig = {
207+ Type = "oneshot";
208+ RemainAfterExit = true;
209+ ExecStart = "${pkgs.coreutils}/bin/true";
210+ Slice = "testslice.slice";
211+ };
212+ };
213+ };
214+215+ # The same system but the slice allows to allocate memory
216+ with-slice-non-crashing.configuration = {
217+ imports = [ config.specialisation.with-slice.configuration ];
218+ systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null;
219+ };
220+ };
221 };
222 other = { ... }: {
223 users.mutableUsers = true;
224 };
225 };
226227+ testScript = { nodes, ... }: let
228 originalSystem = nodes.machine.config.system.build.toplevel;
229 otherSystem = nodes.other.config.system.build.toplevel;
230···236 set -o pipefail
237 exec env -i "$@" | tee /dev/stderr
238 '';
239+ in /* python */ ''
240+ def switch_to_specialisation(name, action="test"):
241+ out = machine.succeed(f"${originalSystem}/specialisation/{name}/bin/switch-to-configuration {action} 2>&1")
242+ assert_lacks(out, "switch-to-configuration line") # Perl warnings
243+ return out
244+245+ def assert_contains(haystack, needle):
246+ if needle not in haystack:
247+ print("The haystack that will cause the following exception is:")
248+ print("---")
249+ print(haystack)
250+ print("---")
251+ raise Exception(f"Expected string '{needle}' was not found")
252+253+ def assert_lacks(haystack, needle):
254+ if needle in haystack:
255+ print("The haystack that will cause the following exception is:")
256+ print("---")
257+ print(haystack, end="")
258+ print("---")
259+ raise Exception(f"Unexpected string '{needle}' was found")
260+261+262 machine.succeed(
263 "${stderrRunner} ${originalSystem}/bin/switch-to-configuration test"
264 )
265 machine.succeed(
266 "${stderrRunner} ${otherSystem}/bin/switch-to-configuration test"
267 )
268+269+ with subtest("systemd sockets"):
270+ machine.succeed("${originalSystem}/bin/switch-to-configuration test")
271+272+ # Simple socket is created
273+ out = switch_to_specialisation("simple-socket")
274+ assert_lacks(out, "stopping the following units:")
275+ # not checking for reload because dbus gets reloaded
276+ assert_lacks(out, "restarting the following units:")
277+ assert_lacks(out, "\nstarting the following units:")
278+ assert_contains(out, "the following new units were started: socket-activated.socket\n")
279+ assert_lacks(out, "as well:")
280+ machine.succeed("[ $(stat -c%a /run/test.sock) = 777 ]")
281+282+ # Changing the socket restarts it
283+ out = switch_to_specialisation("modified-socket")
284+ assert_lacks(out, "stopping the following units:")
285+ #assert_lacks(out, "reloading the following units:")
286+ assert_contains(out, "restarting the following units: socket-activated.socket\n")
287+ assert_lacks(out, "\nstarting the following units:")
288+ assert_lacks(out, "the following new units were started:")
289+ assert_lacks(out, "as well:")
290+ machine.succeed("[ $(stat -c%a /run/test.sock) = 666 ]") # change was applied
291+292+ # The unit is properly activated when the socket is accessed
293+ if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello":
294+ raise Exception("Socket was not properly activated")
295+296+ # Changing the socket restarts it and ignores the active service
297+ out = switch_to_specialisation("simple-socket")
298+ assert_contains(out, "stopping the following units: socket-activated.service\n")
299+ assert_lacks(out, "reloading the following units:")
300+ assert_contains(out, "restarting the following units: socket-activated.socket\n")
301+ assert_lacks(out, "\nstarting the following units:")
302+ assert_lacks(out, "the following new units were started:")
303+ assert_lacks(out, "as well:")
304+ machine.succeed("[ $(stat -c%a /run/test.sock) = 777 ]") # change was applied
305+306+ # Changing the service does nothing when the service is not active
307+ out = switch_to_specialisation("modified-service")
308+ assert_lacks(out, "stopping the following units:")
309+ assert_lacks(out, "reloading the following units:")
310+ assert_lacks(out, "restarting the following units:")
311+ assert_lacks(out, "\nstarting the following units:")
312+ assert_lacks(out, "the following new units were started:")
313+ assert_lacks(out, "as well:")
314+315+ # Activating the service and modifying it stops it but leaves the socket untouched
316+ machine.succeed("socat - UNIX-CONNECT:/run/test.sock")
317+ out = switch_to_specialisation("simple-socket")
318+ assert_contains(out, "stopping the following units: socket-activated.service\n")
319+ assert_lacks(out, "reloading the following units:")
320+ assert_lacks(out, "restarting the following units:")
321+ assert_lacks(out, "\nstarting the following units:")
322+ assert_lacks(out, "the following new units were started:")
323+ assert_lacks(out, "as well:")
324+325+ # Activating the service and both the service and the socket stops the service and restarts the socket
326+ machine.succeed("socat - UNIX-CONNECT:/run/test.sock")
327+ out = switch_to_specialisation("modified-service-and-socket")
328+ assert_contains(out, "stopping the following units: socket-activated.service\n")
329+ assert_lacks(out, "reloading the following units:")
330+ assert_contains(out, "restarting the following units: socket-activated.socket\n")
331+ assert_lacks(out, "\nstarting the following units:")
332+ assert_lacks(out, "the following new units were started:")
333+ assert_lacks(out, "as well:")
334+335+ with subtest("restart and reload by activation file"):
336+ out = switch_to_specialisation("service-and-socket")
337+ # Switch to a system where the example services get restarted
338+ # by the activation script
339+ out = switch_to_specialisation("restart-and-reload-by-activation-script")
340+ assert_lacks(out, "stopping the following units:")
341+ assert_contains(out, "stopping the following units as well: simple-service.service, socket-activated.service\n")
342+ assert_contains(out, "reloading the following units: simple-reload-service.service\n")
343+ assert_contains(out, "restarting the following units: simple-restart-service.service\n")
344+ assert_contains(out, "\nstarting the following units: simple-service.service")
345+346+ # The same, but in dry mode
347+ switch_to_specialisation("service-and-socket")
348+ out = switch_to_specialisation("restart-and-reload-by-activation-script", action="dry-activate")
349+ assert_lacks(out, "would stop the following units:")
350+ assert_contains(out, "would stop the following units as well: simple-service.service, socket-activated.service\n")
351+ assert_contains(out, "would reload the following units: simple-reload-service.service\n")
352+ assert_contains(out, "would restart the following units: simple-restart-service.service\n")
353+ assert_contains(out, "\nwould start the following units: simple-service.service")
354+355+ with subtest("mounts"):
356+ switch_to_specialisation("with-mount")
357+ out = machine.succeed("mount | grep 'on /testmount'")
358+ assert_contains(out, "size=1024k")
359+360+ out = switch_to_specialisation("with-mount-modified")
361+ assert_lacks(out, "stopping the following units:")
362+ assert_contains(out, "reloading the following units: testmount.mount\n")
363+ assert_lacks(out, "restarting the following units:")
364+ assert_lacks(out, "\nstarting the following units:")
365+ assert_lacks(out, "the following new units were started:")
366+ assert_lacks(out, "as well:")
367+ # It changed
368+ out = machine.succeed("mount | grep 'on /testmount'")
369+ assert_contains(out, "size=10240k")
370+371+ with subtest("timers"):
372+ switch_to_specialisation("with-timer")
373+ out = machine.succeed("systemctl show test-timer.timer")
374+ assert_contains(out, "OnCalendar=2014-03-25 02:59:56 UTC")
375+376+ out = switch_to_specialisation("with-timer-modified")
377+ assert_lacks(out, "stopping the following units:")
378+ assert_lacks(out, "reloading the following units:")
379+ assert_contains(out, "restarting the following units: test-timer.timer\n")
380+ assert_lacks(out, "\nstarting the following units:")
381+ assert_lacks(out, "the following new units were started:")
382+ assert_lacks(out, "as well:")
383+ # It changed
384+ out = machine.succeed("systemctl show test-timer.timer")
385+ assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00")
386+387+ with subtest("paths"):
388+ switch_to_specialisation("with-path")
389+ machine.fail("test -f /testpath-modified")
390+391+ # touch the file, unit should be triggered
392+ machine.succeed("touch /testpath")
393+ machine.wait_until_succeeds("test -f /testpath-modified")
394+395+ machine.succeed("rm /testpath /testpath-modified")
396+ switch_to_specialisation("with-path-modified")
397+398+ machine.succeed("touch /testpath")
399+ machine.fail("test -f /testpath-modified")
400+ machine.succeed("touch /testpath2")
401+ machine.wait_until_succeeds("test -f /testpath-modified")
402+403+ # This test ensures that changes to slice configuration get applied.
404+ # We test this by having a slice that allows no memory allocation at
405+ # all and starting a service within it. If the service crashes, the slice
406+ # is applied and if we modify the slice to allow memory allocation, the
407+ # service should successfully start.
408+ with subtest("slices"):
409+ machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing
410+ out = switch_to_specialisation("with-slice")
411+ machine.fail("systemctl start testservice.service")
412+ out = switch_to_specialisation("with-slice-non-crashing")
413+ machine.succeed("systemctl start testservice.service")
414+ machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing
415+416 '';
417})
···1-diff --git a/tool/jt.rb b/tool/jt.rb
2-index 870d88edcb..0a6e4c367b 100755
3---- a/tool/jt.rb
4-+++ b/tool/jt.rb
5-@@ -152,13 +152,16 @@ module Utilities
6- end
7-8- def find_mx
9-- if which('mx')
10-- 'mx'
11-+ if ENV.key?("MX_GIT_CACHE_DIR")
12-+ "mx-internal"
13- else
14-- mx_repo = find_or_clone_repo("https://github.com/graalvm/mx.git")
15-- "#{mx_repo}/mx"
16-+ if which('mx')
17-+ 'mx'
18-+ else
19-+ mx_repo = find_or_clone_repo("https://github.com/graalvm/mx.git")
20-+ "#{mx_repo}/mx"
21-+ end
22- end
23-- end
24-25- def find_launcher(use_native)
26- if use_native
27-@@ -444,8 +447,8 @@ module Commands
28- --no-sforceimports do not run sforceimports before building
29- parser build the parser
30- options build the options
31-- graalvm build a minimal JVM-only GraalVM containing only TruffleRuby,
32-- available by default in mxbuild/truffleruby-jvm,
33-+ graalvm build a minimal JVM-only GraalVM containing only TruffleRuby,
34-+ available by default in mxbuild/truffleruby-jvm,
35- the Ruby is symlinked into rbenv or chruby if available
36- --graal include the GraalVM Compiler in the build
37- --native build native ruby image as well, available in mxbuild/truffleruby-native
38-@@ -491,7 +494,7 @@ module Commands
39- jt test compiler run compiler tests
40- jt test integration [TESTS] run integration tests
41- jt test bundle [--jdebug] tests using bundler
42-- jt test gems [TESTS] tests using gems
43-+ jt test gems [TESTS] tests using gems
44- jt test ecosystem [TESTS] tests using the wider ecosystem such as bundler, Rails, etc
45- jt test cexts [--no-openssl] [--no-gems] [test_names...]
46- run C extension tests (set GEM_HOME)
···1-diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/query/SizeAndSignednessVerifier.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/query/SizeAndSignednessVerifier.java
2-index 23a76357fd2..f13694b6ed7 100644
3---- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/query/SizeAndSignednessVerifier.java
4-+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/query/SizeAndSignednessVerifier.java
5-@@ -249,15 +249,6 @@ public final class SizeAndSignednessVerifier extends NativeInfoTreeVisitor {
6- }
7-8- private void checkSignedness(boolean isUnsigned, ResolvedJavaType type, ResolvedJavaMethod method) {
9-- if (isSigned(type)) {
10-- if (isUnsigned) {
11-- addError("Type " + type.toJavaName(false) + " is signed, but accessed C value is unsigned", method);
12-- }
13-- } else if (nativeLibs.isWordBase(type)) {
14-- /* every Word type other than Signed is assumed to be unsigned. */
15-- if (!isUnsigned) {
16-- addError("Type " + type.toJavaName(false) + " is unsigned, but accessed C value is signed", method);
17-- }
18-- }
19-+
20- }
21- }
···1-# This Makefile is used by mx to bootstrap libffi build.
2-3-# `make MX_VERBOSE=y` will report all lines executed. The actual value doesn't
4-# matter as long as it's not empty.
5-6-QUIETLY$(MX_VERBOSE) = @
7-8-.PHONY: default
9-10-default:
11- sed -i "s|-print-multi-os-directory||g" ../$(SOURCES)/configure
12- $(QUIETLY) echo CONFIGURE libffi
13- $(QUIETLY) mkdir ../$(OUTPUT)
14- $(QUIETLY) cd ../$(OUTPUT) && ../$(SOURCES)/configure $(CONFIGURE_ARGS)
15- $(QUIETLY) echo MAKE libffi
16- $(QUIETLY) $(MAKE) -C ../$(OUTPUT)
···0000000000000000
+7-5
pkgs/development/compilers/nim/default.nix
···72 nimHost = parsePlatform stdenv.hostPlatform;
73 nimTarget = parsePlatform stdenv.targetPlatform;
7475- bootstrapCompiler = stdenv.mkDerivation rec {
0076 pname = "nim-bootstrap";
77- version = "0.20.0";
7879 src = fetchgit {
80 # A Git checkout is much smaller than a GitHub tarball.
81- url = "https://github.com/nim-lang/csources.git";
82- rev = "v${version}";
83- sha256 = "0i6vsfy1sgapx43n226q8m0pvn159sw2mhp50zm3hhb9zfijanis";
84 };
8586 enableParallelBuilding = true;
···72 nimHost = parsePlatform stdenv.hostPlatform;
73 nimTarget = parsePlatform stdenv.targetPlatform;
7475+ bootstrapCompiler = let
76+ revision = "561b417c65791cd8356b5f73620914ceff845d10";
77+ in stdenv.mkDerivation {
78 pname = "nim-bootstrap";
79+ version = "g${lib.substring 0 7 revision}";
8081 src = fetchgit {
82 # A Git checkout is much smaller than a GitHub tarball.
83+ url = "https://github.com/nim-lang/csources_v1.git";
84+ rev = revision;
85+ sha256 = "1c2k681knrha1zmf4abhb32i2wwd3nwflzylnqryxk753swla043";
86 };
8788 enableParallelBuilding = true;
···25# propagate build dependencies so in case we have A -> B -> C,
26# C can import package A propagated by B
27, propagatedBuildInputs ? []
28-, propagatedNativeBuildInputs ? []
2930# used to disable derivation, useful for specific lua versions
31# TODO move from this setting meta.broken to a 'disabled' attribute on the
···50# The latter is used to work-around luarocks having a problem with
51# multiple-output derivations as external deps:
52# https://github.com/luarocks/luarocks/issues/766<Paste>
53-, externalDeps ? lib.unique (lib.filter (drv: !drv ? luaModule) (propagatedBuildInputs ++ buildInputs))
5455# Appended to the generated luarocks config
56, extraConfig ? ""
···74let
75 generatedRockspecFilename = "${rockspecDir}/${pname}-${version}.rockspec";
7677-78 # TODO fix warnings "Couldn't load rockspec for ..." during manifest
79 # construction -- from initial investigation, appears it will require
80 # upstream luarocks changes to fix cleanly (during manifest construction,
···83 luarocks_config = "luarocks-config.lua";
84 luarocks_content = let
85 generatedConfig = lua.pkgs.lib.generateLuarocksConfig {
86- inherit externalDeps;
87 inherit extraVariables;
88 inherit rocksSubdir;
89 inherit requiredLuaRocks;
···99 # Filter out the lua derivation itself from the Lua module dependency
100 # closure, as it doesn't have a rock tree :)
101 requiredLuaRocks = lib.filter (d: d ? luaModule)
102- (lua.pkgs.requiredLuaModules propagatedBuildInputs);
103104 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
0105 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
106-in
107-toLuaModule ( lua.stdenv.mkDerivation (
108builtins.removeAttrs attrs ["disabled" "checkInputs" "externalDeps" "extraVariables"] // {
109110 name = namePrefix + pname + "-" + version;
···146 runHook postConfigure
147 '';
148149- # TODO could be moved to configurePhase
150 buildPhase = ''
151 runHook preBuild
152153 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
154155- LUAROCKS=luarocks
156 if (( ''${NIX_DEBUG:-0} >= 1 )); then
157 LUAROCKS="$LUAROCKS --verbose"
158 fi
···195 passthru = {
196 inherit lua; # The lua interpreter
197 inherit externalDeps;
0198 } // passthru;
199200 meta = {
···203 maintainers = (meta.maintainers or []) ++ [ ];
204 broken = disabled;
205 } // meta;
206-}))
00
···25# propagate build dependencies so in case we have A -> B -> C,
26# C can import package A propagated by B
27, propagatedBuildInputs ? []
02829# used to disable derivation, useful for specific lua versions
30# TODO move from this setting meta.broken to a 'disabled' attribute on the
···49# The latter is used to work-around luarocks having a problem with
50# multiple-output derivations as external deps:
51# https://github.com/luarocks/luarocks/issues/766<Paste>
52+, externalDeps ? []
5354# Appended to the generated luarocks config
55, extraConfig ? ""
···73let
74 generatedRockspecFilename = "${rockspecDir}/${pname}-${version}.rockspec";
75076 # TODO fix warnings "Couldn't load rockspec for ..." during manifest
77 # construction -- from initial investigation, appears it will require
78 # upstream luarocks changes to fix cleanly (during manifest construction,
···81 luarocks_config = "luarocks-config.lua";
82 luarocks_content = let
83 generatedConfig = lua.pkgs.lib.generateLuarocksConfig {
84+ externalDeps = externalDeps ++ externalDepsGenerated;
85 inherit extraVariables;
86 inherit rocksSubdir;
87 inherit requiredLuaRocks;
···97 # Filter out the lua derivation itself from the Lua module dependency
98 # closure, as it doesn't have a rock tree :)
99 requiredLuaRocks = lib.filter (d: d ? luaModule)
100+ (lua.pkgs.requiredLuaModules luarocksDrv.propagatedBuildInputs);
101102 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
103+ externalDepsGenerated = lib.unique (lib.filter (drv: !drv ? luaModule) (luarocksDrv.propagatedBuildInputs ++ luarocksDrv.buildInputs));
104 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
105+106+ luarocksDrv = toLuaModule ( lua.stdenv.mkDerivation (
107builtins.removeAttrs attrs ["disabled" "checkInputs" "externalDeps" "extraVariables"] // {
108109 name = namePrefix + pname + "-" + version;
···145 runHook postConfigure
146 '';
1470148 buildPhase = ''
149 runHook preBuild
150151 nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
152153+ LUAROCKS=${lua.pkgs.luarocks}/bin/luarocks
154 if (( ''${NIX_DEBUG:-0} >= 1 )); then
155 LUAROCKS="$LUAROCKS --verbose"
156 fi
···193 passthru = {
194 inherit lua; # The lua interpreter
195 inherit externalDeps;
196+ inherit luarocks_content;
197 } // passthru;
198199 meta = {
···202 maintainers = (meta.maintainers or []) ++ [ ];
203 broken = disabled;
204 } // meta;
205+}));
206+in
207+ luarocksDrv
···1-# This file was originally generated by https://github.com/kamilchm/go2nix v1.2.1
2-{ lib, buildGoPackage, fetchgit }:
3-4-buildGoPackage rec {
5- pname = "pprof-unstable";
6- version = "2018-08-15";
7- rev = "781f11b1fcf71fae9d185e7189b5e686f575075a";
89- goPackagePath = "github.com/google/pprof";
001011- src = fetchgit {
12- inherit rev;
13- url = "git://github.com/google/pprof";
14- sha256 = "1nvzwcj6h4q0lsjlri3bym4axgv848w3xz57iz5p0wz9lcd5jsmf";
015 };
1617- goDeps = ./deps.nix;
1819 meta = with lib; {
20 description = "A tool for visualization and analysis of profiling data";
21 homepage = "https://github.com/google/pprof";
22 license = licenses.asl20;
23 longDescription = ''
24- pprof reads a collection of profiling samples in profile.proto format and generates reports to visualize and help analyze the data. It can generate both text and graphical reports (through the use of the dot visualization package).
0002526- profile.proto is a protocol buffer that describes a set of callstacks and symbolization information. A common usage is to represent a set of sampled callstacks from statistical profiling. The format is described on the proto/profile.proto file. For details on protocol buffers, see https://developers.google.com/protocol-buffers
00002728- Profiles can be read from a local file, or over http. Multiple profiles of the same type can be aggregated or compared.
02930- If the profile samples contain machine addresses, pprof can symbolize them through the use of the native binutils tools (addr2line and nm).
03132 This is not an official Google product.
33 '';
···1+{ lib
2+, buildGoModule
3+, fetchFromGitHub
4+}:
00056+buildGoModule rec {
7+ pname = "pprof";
8+ version = "unstable-2021-09-30";
910+ src = fetchFromGitHub {
11+ owner = "google";
12+ repo = "pprof";
13+ rev = "7fe48b4c820be13151ae35ce5a5e3f54f1b53eef";
14+ sha256 = "05nr3igdigs1586qplwfm17hfw0v81jy745g6vayq7cbplljfjb1";
15 };
1617+ vendorSha256 = "0yl8y3m2ia3cwxhmg1km8358a0225khimv6hcvras8r2glm69h3f";
1819 meta = with lib; {
20 description = "A tool for visualization and analysis of profiling data";
21 homepage = "https://github.com/google/pprof";
22 license = licenses.asl20;
23 longDescription = ''
24+ pprof reads a collection of profiling samples in profile.proto format and
25+ generates reports to visualize and help analyze the data. It can generate
26+ both text and graphical reports (through the use of the dot visualization
27+ package).
2829+ profile.proto is a protocol buffer that describes a set of callstacks and
30+ symbolization information. A common usage is to represent a set of sampled
31+ callstacks from statistical profiling. The format is described on the
32+ proto/profile.proto file. For details on protocol buffers, see
33+ https://developers.google.com/protocol-buffers
3435+ Profiles can be read from a local file, or over http. Multiple profiles of
36+ the same type can be aggregated or compared.
3738+ If the profile samples contain machine addresses, pprof can symbolize them
39+ through the use of the native binutils tools (addr2line and nm).
4041 This is not an official Google product.
42 '';
···333 google-musicmanager = throw "google-musicmanager has been removed because Google Play Music was discontinued"; # added 2021-03-07
334 googleAuthenticator = google-authenticator; # added 2016-10-16
335 grantlee5 = libsForQt5.grantlee; # added 2015-12-19
00336 gsettings_desktop_schemas = gsettings-desktop-schemas; # added 2018-02-25
337 gtk_doc = gtk-doc; # added 2018-02-25
338 guileCairo = guile-cairo; # added 2017-09-24
···374 jbuilder = dune_1; # added 2018-09-09
375 jikes = throw "jikes was deprecated on 2019-10-07: abandoned by upstream";
376 joseki = apache-jena-fuseki; # added 2016-02-28
0377 json_glib = json-glib; # added 2018-02-25
378 kdecoration-viewer = throw "kdecoration-viewer has been removed from nixpkgs, as there is no upstream activity"; # 2020-06-16
379 k9copy = throw "k9copy has been removed from nixpkgs, as there is no upstream activity"; # 2020-11-06
···569 mpv-with-scripts = self.wrapMpv self.mpv-unwrapped { }; # added 2020-05-22
570 multipath_tools = multipath-tools; # added 2016-01-21
571 mupen64plus1_5 = mupen64plus; # added 2016-02-12
0572 mxisd = throw "mxisd has been removed from nixpkgs as it has reached end of life, see https://github.com/kamax-matrix/mxisd/blob/535e0a5b96ab63cb0ddef90f6f42c5866407df95/EOL.md#end-of-life-notice . ma1sd may be a suitable alternative."; # added 2021-04-15
573 mysqlWorkbench = mysql-workbench; # added 2017-01-19
574 nagiosPluginsOfficial = monitoring-plugins;
···333 google-musicmanager = throw "google-musicmanager has been removed because Google Play Music was discontinued"; # added 2021-03-07
334 googleAuthenticator = google-authenticator; # added 2016-10-16
335 grantlee5 = libsForQt5.grantlee; # added 2015-12-19
336+ graalvm8 = graalvm8-ce;
337+ graalvm11 = graalvm11-ce;
338 gsettings_desktop_schemas = gsettings-desktop-schemas; # added 2018-02-25
339 gtk_doc = gtk-doc; # added 2018-02-25
340 guileCairo = guile-cairo; # added 2017-09-24
···376 jbuilder = dune_1; # added 2018-09-09
377 jikes = throw "jikes was deprecated on 2019-10-07: abandoned by upstream";
378 joseki = apache-jena-fuseki; # added 2016-02-28
379+ jvmci8 = throw "graalvm8 and its tools were deprecated in favor of graalvm8-ce"; # added 2021-10-15
380 json_glib = json-glib; # added 2018-02-25
381 kdecoration-viewer = throw "kdecoration-viewer has been removed from nixpkgs, as there is no upstream activity"; # 2020-06-16
382 k9copy = throw "k9copy has been removed from nixpkgs, as there is no upstream activity"; # 2020-11-06
···572 mpv-with-scripts = self.wrapMpv self.mpv-unwrapped { }; # added 2020-05-22
573 multipath_tools = multipath-tools; # added 2016-01-21
574 mupen64plus1_5 = mupen64plus; # added 2016-02-12
575+ mx = throw "graalvm8 and its tools were deprecated in favor of graalvm8-ce"; # added 2021-10-15
576 mxisd = throw "mxisd has been removed from nixpkgs as it has reached end of life, see https://github.com/kamax-matrix/mxisd/blob/535e0a5b96ab63cb0ddef90f6f42c5866407df95/EOL.md#end-of-life-notice . ma1sd may be a suitable alternative."; # added 2021-04-15
577 mysqlWorkbench = mysql-workbench; # added 2017-01-19
578 nagiosPluginsOfficial = monitoring-plugins;