Add global systemd user unit controls
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled

This commit is contained in:
Ilia Ross
2026-08-05 21:00:36 +02:00
parent 137fbd5768
commit 555ff28a4d
2 changed files with 93 additions and 0 deletions

View File

@@ -2552,6 +2552,32 @@ my $out = backquote_logged($cmd." 2>&1 </dev/null");
return (!$?, $out);
}
=head2 global_user_systemctl_command(arg, ...)
Returns a quoted systemctl command line for changing global user-unit policy.
=cut
sub global_user_systemctl_command
{
my (@args) = @_;
my $systemctl = has_command("systemctl") || "systemctl";
return join(" ", quotemeta($systemctl), "--global",
map { quotemeta($_) } @args);
}
=head2 run_global_user_systemctl(arg, ...)
Runs systemctl --global, returning an OK flag and command output.
=cut
sub run_global_user_systemctl
{
my (@args) = @_;
my $cmd = global_user_systemctl_command(@args);
my $out = backquote_logged($cmd." 2>&1 </dev/null");
return (!$?, $out);
}
=head2 reload_user_manager(user)
Tells a user's systemd manager to re-read its unit files.
@@ -3350,6 +3376,32 @@ my $out = backquote_logged(
return (!$?, $out);
}
=head2 enable_global_user_unit(name)
Enables a systemd user unit globally for all user managers.
=cut
sub enable_global_user_unit
{
my ($name) = @_;
return (0, $text{'systemd_ename'}) if (!valid_unit_name($name));
my ($ok, $out) = run_global_user_systemctl("enable", $name);
return ($ok && !startup_change_skipped($out), $out);
}
=head2 disable_global_user_unit(name)
Disables a globally-enabled systemd user unit for all user managers.
=cut
sub disable_global_user_unit
{
my ($name) = @_;
return (0, $text{'systemd_ename'}) if (!valid_unit_name($name));
my ($ok, $out) = run_global_user_systemctl("disable", $name);
return ($ok && !startup_change_skipped($out), $out);
}
=head2 enable_user_unit(user, name)
Enable a systemd user unit.

View File

@@ -1716,6 +1716,47 @@ like(get_unit_root(), qr{^/(etc|usr/lib|lib)/systemd/system$},
'reload_user_manager reloads the user manager');
}
{
my @cmds;
local *main::has_command = sub {
return $_[0] eq 'systemctl' ? '/bin/systemctl' : undef;
};
local *main::backquote_logged = sub {
push(@cmds, $_[0]);
$? = 0;
return 'ran';
};
my ($ok, $out) = run_global_user_systemctl(
'is-enabled', 'demo.service');
ok($ok, 'run_global_user_systemctl reports command success');
is($out, 'ran', 'run_global_user_systemctl returns command output');
is($cmds[-1],
quotemeta('/bin/systemctl').' --global '.quotemeta('is-enabled').' '.
quotemeta('demo.service').' 2>&1 </dev/null',
'global user systemctl command uses global scope and quotes arguments');
}
{
my @run;
local *main::run_global_user_systemctl = sub {
push(@run, [ @_ ]);
return (1, 'ok');
};
my ($ok) = enable_global_user_unit('demo.service');
ok($ok, 'enable_global_user_unit reports success');
is_deeply($run[-1], [ 'enable', 'demo.service' ],
'enable_global_user_unit arguments');
($ok) = disable_global_user_unit('demo.service');
ok($ok, 'disable_global_user_unit reports success');
is_deeply($run[-1], [ 'disable', 'demo.service' ],
'disable_global_user_unit arguments');
my $before_invalid = scalar(@run);
($ok) = enable_global_user_unit('bad;touch.service');
ok(!$ok, 'global user enable rejects invalid unit names');
is(scalar(@run), $before_invalid,
'invalid global user unit name builds no systemctl command');
}
{
my @run;
local *main::run_user_systemctl = sub {