mirror of
https://github.com/webmin/webmin.git
synced 2026-10-01 01:40:39 +01:00
Add get_unit_state to read fresh systemd unit properties
This commit is contained in:
@@ -662,6 +662,33 @@ my $out = backquote_logged(
|
||||
return (!$?, $out);
|
||||
}
|
||||
|
||||
=head2 get_unit_state(name)
|
||||
|
||||
Returns a fresh hash of LoadState, UnitFileState, ActiveState, SubState and
|
||||
MainPID, followed by an error string. Missing units have LoadState not-found;
|
||||
command or validation failures return undef and an error. No inventory cache
|
||||
is used, so callers can verify a change immediately.
|
||||
|
||||
=cut
|
||||
sub get_unit_state
|
||||
{
|
||||
my ($name) = @_;
|
||||
return (undef, $text{'systemd_ename'}) if (!valid_unit_name($name));
|
||||
my $out = backquote_logged("systemctl show --no-pager ".
|
||||
"--property=LoadState,UnitFileState,ActiveState,SubState,MainPID ".
|
||||
quotemeta($name)." 2>&1 </dev/null");
|
||||
my $rv = $?;
|
||||
my %state;
|
||||
foreach my $line (split(/\r?\n/, $out)) {
|
||||
$state{$1} = $2
|
||||
if ($line =~ /^(LoadState|UnitFileState|ActiveState|SubState|MainPID)=(.*)$/);
|
||||
}
|
||||
# systemctl may return a nonzero status for an explicitly missing unit.
|
||||
return (undef, $out || "Failed to read systemd unit $name")
|
||||
if (!$state{'LoadState'} || ($rv && $state{'LoadState'} ne 'not-found'));
|
||||
return (\%state, undef);
|
||||
}
|
||||
|
||||
=head2 dependencies_unit(name)
|
||||
|
||||
Gets dependency tree output for a systemd unit.
|
||||
|
||||
@@ -855,6 +855,30 @@ like(get_unit_root(), qr{^/(etc|usr/lib|lib)/systemd/system$},
|
||||
like($out, qr/Start failed/, 'failed start includes diagnostics');
|
||||
}
|
||||
|
||||
# Readiness needs fresh properties, including idle sockets and missing units.
|
||||
{
|
||||
my $reply = "LoadState=loaded\nUnitFileState=enabled\nActiveState=active\nSubState=listening\nMainPID=0\n";
|
||||
my $status = 0;
|
||||
my @commands;
|
||||
local *main::backquote_logged = sub { push @commands, $_[0]; $? = $status; return $reply; };
|
||||
my ($state, $error) = get_unit_state('demo.socket');
|
||||
is($error, undef, 'valid unit state has no error');
|
||||
is($state->{SubState}, 'listening', 'socket readiness is exposed');
|
||||
like($commands[-1], qr/--property=LoadState,UnitFileState,ActiveState,SubState,MainPID/, 'only requested properties are read');
|
||||
$reply = "LoadState=loaded\nUnitFileState=enabled\nActiveState=inactive\n";
|
||||
($state, $error) = get_unit_state('demo.socket');
|
||||
is($state->{ActiveState}, 'inactive', 'state is not cached');
|
||||
$reply = "LoadState=not-found\nActiveState=inactive\n"; $status = 1024;
|
||||
($state, $error) = get_unit_state('missing.service');
|
||||
is($state->{LoadState}, 'not-found', 'missing unit is a valid discovery result');
|
||||
$reply = 'Failed to connect to bus';
|
||||
($state, $error) = get_unit_state('demo.socket');
|
||||
ok(!defined($state), 'bus failure returns no state');
|
||||
like($error, qr/connect to bus/, 'bus error is preserved');
|
||||
($state, $error) = get_unit_state('bad;unit.service');
|
||||
is($error, 'bad unit name', 'invalid state lookup is rejected');
|
||||
}
|
||||
|
||||
{
|
||||
my @cmds;
|
||||
my $reloaded = 0;
|
||||
|
||||
Reference in New Issue
Block a user