Skip to content

Commit

Permalink
Support reload systemd --user for non-zero UIDs
Browse files Browse the repository at this point in the history
Support calling the `systemd --user` for a particular uid.

A `uid` must be used rather than the probably more convenient username
since the `$XDG_RUNTIME_DIR` for the user must be known.

This change assumes that XDG_RUNTIME_DIR is `/run/user/<uid>` for all
uids.

Example run:
```puppet
notify{'junk':
 notify => Systemd::Daemon_reload['foobar'],
}

systemd::daemon_reload{'foobar':
  uid => 1000,
}
```

results in

```
Notice: Compiled catalog for fedora. in environment production in 0.05 seconds
Notice: junk
Notice: /Stage[main]/Main/Notify[junk]/message: defined 'message' as 'junk'
Notice: /Stage[main]/Main/Systemd::Daemon_reload[foobar]/Exec[systemd-foobar-systemctl-user-1000-daemon-reload]: Triggered 'refresh' from 1 event
Notice: Applied catalog in 0.17 seconds
```
and a journal (debug on) of

```
Feb 28 11:44:34 fedora systemd[1]: [email protected]: Got notification message from PID 1877 (RELOADING=1, MONOTONIC_USEC=5874581103)
Feb 28 11:44:34 fedora systemd[1]: [email protected]: Changed running -> reload-notify
Feb 28 11:44:34 fedora systemd[1]: [email protected]: Installed new job [email protected]/nop as 6151
...
  • Loading branch information
traylenator committed Feb 29, 2024
1 parent bcec820 commit 4e3d0a1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
34 changes: 33 additions & 1 deletion REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,12 +622,35 @@ Default value: `['create']`

Run systemctl daemon-reload

#### Examples

##### Force reload the system systemd

```puppet
notify{ 'fake event to notify from':
notify => Systemd::Daemon_reload['special']
}
systemd::daemon_reload{ 'special': }
```

##### Force reload a systemd --user

```puppet
notify{ 'fake event to notify from':
notify => Systemd::Daemon_reload['user']
}
systemd::daemon_reload{ 'user':
uid => 1234,
}
```

#### Parameters

The following parameters are available in the `systemd::daemon_reload` defined type:

* [`name`](#-systemd--daemon_reload--name)
* [`enable`](#-systemd--daemon_reload--enable)
* [`uid`](#-systemd--daemon_reload--uid)

##### <a name="-systemd--daemon_reload--name"></a>`name`

Expand All @@ -638,11 +661,20 @@ A globally unique name for the resource
Data type: `Boolean`

Enable the reload exec

* Added in case users want to disable the reload globally using a resource collector

Default value: `true`

##### <a name="-systemd--daemon_reload--uid"></a>`uid`

Data type: `Optional[Integer[1]]`

Specify uid of `systemd --user` to reload. When `uid` is left `undef` the system
systemd instance will be reloaded. It is assumed that the `XDG_RUNTIME_DIR` for
the user is `/run/user/<uid>`.

Default value: `undef`

### <a name="systemd--dropin_file"></a>`systemd::dropin_file`

Creates a drop-in file for a systemd unit
Expand Down
42 changes: 39 additions & 3 deletions manifests/daemon_reload.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,51 @@
#
# @param enable
# Enable the reload exec
#
# * Added in case users want to disable the reload globally using a resource collector
#
# @param uid
# Specify uid of `systemd --user` to reload. When `uid` is left `undef` the system
# systemd instance will be reloaded. It is assumed that the `XDG_RUNTIME_DIR` for
# the user is `/run/user/<uid>`.
#
# @example Force reload the system systemd
# notify{ 'fake event to notify from':
# notify => Systemd::Daemon_reload['special']
# }
# systemd::daemon_reload{ 'special': }
#
# @example Force reload a systemd --user
# notify{ 'fake event to notify from':
# notify => Systemd::Daemon_reload['user']
# }
# systemd::daemon_reload{ 'user':
# uid => 1234,
# }
#
define systemd::daemon_reload (
Boolean $enable = true,
Optional[Integer[1]] $uid = undef,
) {
if $enable {
exec { "${module_name}-${name}-systemctl-daemon-reload":
command => 'systemctl daemon-reload',
# For a `systemd --user` instance XDG_RUNTIME_DIR must be set so dbus
# can be found.

if $uid {
$_title = "${module_name}-${name}-systemctl-user-${uid}-daemon-reload"
$_user = String($uid) # exec seems unhappy with integers.
$_env = "XDG_RUNTIME_DIR=/run/user/${uid}"
$_command = ['systemctl', '--user', 'daemon-reload']
} else {
$_title = "${module_name}-${name}-systemctl-daemon-reload"
$_user = undef
$_env = undef
$_command = ['systemctl', 'daemon-reload']
}

exec { $_title:
command => $_command,
environment => $_env,
user => $_user,
refreshonly => true,
path => $facts['path'],
}
Expand Down
28 changes: 26 additions & 2 deletions spec/defines/daemon_reload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
context 'with defaults' do
it do
expect(subject).to contain_exec("systemd-#{title}-systemctl-daemon-reload").
with_command('systemctl daemon-reload').
with_refreshonly(true)
with_command(%w[systemctl daemon-reload]).
with_refreshonly(true).
without_environment.
without_user
end
end

Expand All @@ -28,6 +30,28 @@
expect(subject).not_to contain_exec("systemd-#{title}-systemctl-daemon-reload")
end
end

context 'when a non-zero uid is specified' do
let(:params) do
{ 'uid' => 1234 }
end

it do
expect(subject).to contain_exec("systemd-#{title}-systemctl-user-1234-daemon-reload").
with_command(%w[systemctl --user daemon-reload]).
with_environment('XDG_RUNTIME_DIR=/run/user/1234').
with_user(1234).
with_refreshonly(true)
end
end

context 'when the uid is 0 (root)' do
let(:params) do
{ 'uid' => 0 }
end

it { is_expected.to compile.and_raise_error(%r{Undef or Integer\[1\]}) }
end
end
end
end
Expand Down

0 comments on commit 4e3d0a1

Please sign in to comment.