Merge pull request #160458 from helsinki-systems/fix/stc-backslashes
nixos/switch-to-configuration: Fix backslashes in unit names
This commit is contained in:
commit
dcbacb0f62
2 changed files with 51 additions and 10 deletions
|
@ -173,13 +173,18 @@ sub parseSystemdIni {
|
|||
#
|
||||
# If a directory with the same basename ending in .d exists next to the unit file, it will be
|
||||
# assumed to contain override files which will be parsed as well and handled properly.
|
||||
sub parseUnit {
|
||||
my ($unitPath) = @_;
|
||||
sub parse_unit {
|
||||
my ($unit_path) = @_;
|
||||
|
||||
# Parse the main unit and all overrides
|
||||
my %unitData;
|
||||
parseSystemdIni(\%unitData, $_) for glob("${unitPath}{,.d/*.conf}");
|
||||
return %unitData;
|
||||
my %unit_data;
|
||||
# Replace \ with \\ so glob() still works with units that have a \ in them
|
||||
# Valid characters in unit names are ASCII letters, digits, ":", "-", "_", ".", and "\"
|
||||
$unit_path =~ s/\\/\\\\/gmsx;
|
||||
foreach (glob "${unit_path}{,.d/*.conf}") {
|
||||
parseSystemdIni(\%unit_data, "$_")
|
||||
}
|
||||
return %unit_data;
|
||||
}
|
||||
|
||||
# Checks whether a specified boolean in a systemd unit is true
|
||||
|
@ -310,7 +315,7 @@ sub handleModifiedUnit {
|
|||
# Revert of the attempt: https://github.com/NixOS/nixpkgs/pull/147609
|
||||
# More details: https://github.com/NixOS/nixpkgs/issues/74899#issuecomment-981142430
|
||||
} else {
|
||||
my %unitInfo = $newUnitInfo ? %{$newUnitInfo} : parseUnit($newUnitFile);
|
||||
my %unitInfo = $newUnitInfo ? %{$newUnitInfo} : parse_unit($newUnitFile);
|
||||
if (parseSystemdBool(\%unitInfo, "Service", "X-ReloadIfChanged", 0) and not $unitsToRestart->{$unit} and not $unitsToStop->{$unit}) {
|
||||
$unitsToReload->{$unit} = 1;
|
||||
recordUnit($reloadListFile, $unit);
|
||||
|
@ -412,12 +417,12 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
|
||||
if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
|
||||
if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
|
||||
my %unitInfo = parseUnit($prevUnitFile);
|
||||
my %unitInfo = parse_unit($prevUnitFile);
|
||||
$unitsToStop{$unit} = 1 if parseSystemdBool(\%unitInfo, "Unit", "X-StopOnRemoval", 1);
|
||||
}
|
||||
|
||||
elsif ($unit =~ /\.target$/) {
|
||||
my %unitInfo = parseUnit($newUnitFile);
|
||||
my %unitInfo = parse_unit($newUnitFile);
|
||||
|
||||
# Cause all active target units to be restarted below.
|
||||
# This should start most changed units we stop here as
|
||||
|
@ -451,8 +456,8 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
}
|
||||
|
||||
else {
|
||||
my %old_unit_info = parseUnit($prevUnitFile);
|
||||
my %new_unit_info = parseUnit($newUnitFile);
|
||||
my %old_unit_info = parse_unit($prevUnitFile);
|
||||
my %new_unit_info = parse_unit($newUnitFile);
|
||||
my $diff = compare_units(\%old_unit_info, \%new_unit_info);
|
||||
if ($diff eq 1) {
|
||||
handleModifiedUnit($unit, $baseName, $newUnitFile, \%new_unit_info, $activePrev, \%unitsToStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, \%unitsToSkip);
|
||||
|
|
|
@ -145,6 +145,23 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
|||
systemd.services.test.serviceConfig."X-Test" = "test";
|
||||
};
|
||||
|
||||
unitWithBackslash.configuration = {
|
||||
systemd.services."escaped\\x2ddash" = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||
ExecReload = "${pkgs.coreutils}/bin/true";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
unitWithBackslashModified.configuration = {
|
||||
imports = [ unitWithBackslash.configuration ];
|
||||
systemd.services."escaped\\x2ddash".serviceConfig.X-Test = "test";
|
||||
};
|
||||
|
||||
restart-and-reload-by-activation-script.configuration = {
|
||||
systemd.services = rec {
|
||||
simple-service = {
|
||||
|
@ -433,6 +450,25 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
|||
assert_lacks(out, "as well:")
|
||||
assert_contains(out, "would start the following units: test.service\n")
|
||||
|
||||
# Ensure \ works in unit names
|
||||
out = switch_to_specialisation("${machine}", "unitWithBackslash")
|
||||
assert_contains(out, "stopping the following units: test.service\n")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_contains(out, "the following new units were started: escaped\\x2ddash.service\n")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
out = switch_to_specialisation("${machine}", "unitWithBackslashModified")
|
||||
assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_contains(out, "\nstarting the following units: escaped\\x2ddash.service\n")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
with subtest("failing units"):
|
||||
# Let the simple service fail
|
||||
switch_to_specialisation("${machine}", "simpleServiceModified")
|
||||
|
|
Loading…
Reference in a new issue