/
tutorial-user-systemd-unit-on-boot.adoc
249 lines (219 loc) · 7.36 KB
/
tutorial-user-systemd-unit-on-boot.adoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
= Launching a user-level systemd unit on boot
NOTE: Complete all the steps described in the xref:tutorial-setup.adoc[initial setup page] before starting this tutorial. Make sure you have create file `ssh-key.pub` following the instructions provided in the https://docs.fedoraproject.org/en-US/fedora-coreos/tutorial-setup/#_ssh_public_key[prerequisites] for the tutorial. We will use this key in the Butane configuration file that we are about to write.
In this tutorial, we will set up a user level systemd unit for an unprivileged user. There are times when it's helpful to launch a user-level https://www.freedesktop.org/software/systemd/man/systemd.unit.html[systemd unit] without having to log in. For example, you may wish to launch a container that provides a network service or run an HPC job. For this setup, we will add the following to a Butane config:
* A user level systemd unit: `/home/sleeper/.config/systemd/user/linger-example.service`.
* Enable it as a user level systemd service.
== Setting up the systemd unit
In this example, we will launch a systemd service for the user `sleeper`. First, let's create a user:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
passwd:
users:
- name: sleeper
----
This will also create the home directory for the `sleeper` user. Then we can add the systemd unit:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
storage:
files:
- path: /home/sleeper/.config/systemd/user/linger-example.service
mode: 0644
contents:
inline: |
[Unit]
Description=A systemd user unit demo
[Service]
ExecStart=/usr/bin/sleep infinity
user:
name: sleeper
group:
name: sleeper
----
System services can be directly enabled in Butane configs but user level services have to be manually enabled for now:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
storage:
directories:
- path: /home/sleeper/.config/systemd/user/default.target.wants
mode: 0755
user:
name: sleeper
group:
name: sleeper
links:
- path: /home/sleeper/.config/systemd/user/default.target.wants/linger-example.service
user:
name: sleeper
group:
name: sleeper
target: /home/sleeper/.config/systemd/user/linger-example.service
hard: false
----
We set up lingering for the systemd user level instance so that it gets started directly on boot and stays running:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
storage:
files:
- path: /var/lib/systemd/linger/sleeper
mode: 0644
----
As the following directories do not exist yet, we will have to create them to tell Ignition to set the right ownership and permissions:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
storage:
directories:
- path: /home/sleeper/.config
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd/user
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd/user/default.target.wants
mode: 0755
user:
name: sleeper
group:
name: sleeper
----
== Writing the Butane config and converting to Ignition
The final Butane config, stored in `user.bu`, will be:
[source,yaml,subs="attributes"]
----
variant: fcos
version: {butane-latest-stable-spec}
passwd:
users:
- name: core
ssh_authorized_keys_local:
- ssh-key.pub
- name: sleeper
storage:
directories:
- path: /home/sleeper/.config
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd/user
mode: 0755
user:
name: sleeper
group:
name: sleeper
- path: /home/sleeper/.config/systemd/user/default.target.wants
mode: 0755
user:
name: sleeper
group:
name: sleeper
files:
- path: /var/lib/systemd/linger/sleeper
mode: 0644
- path: /home/sleeper/.config/systemd/user/linger-example.service
mode: 0644
contents:
inline: |
[Unit]
Description=A systemd user unit demo
[Service]
ExecStart=/usr/bin/sleep infinity
user:
name: sleeper
group:
name: sleeper
links:
- path: /home/sleeper/.config/systemd/user/default.target.wants/linger-example.service
user:
name: sleeper
group:
name: sleeper
target: /home/sleeper/.config/systemd/user/linger-example.service
hard: false
----
This config can be converted to Ignition:
[source,bash]
----
butane --pretty --strict --files-dir=./ user.bu --output user.ign
----
== Testing
Just as before we will use the following to boot the instance:
[source,bash]
----
# Setup the correct SELinux label to allow access to the config
chcon --verbose --type svirt_home_t user.ign
# Start a Fedora CoreOS virtual machine
virt-install --name=fcos --vcpus=2 --ram=2048 --os-variant=fedora-coreos-stable \
--import --network=bridge=virbr0 --graphics=none \
--qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=${PWD}/user.ign" \
--disk=size=20,backing_store=${PWD}/fedora-coreos.qcow2
----
We can then verify that the unit has been started under the sleeper systemd user instance:
[source,bash]
----
[core@localhost ~]$ sudo machinectl shell sleeper@
Connected to the local host. Press ^] three times within 1s to exit session.
[sleeper@localhost ~]$ systemctl --user status
● localhost.localdomain
State: running
Units: 157 loaded (incl. loaded aliases)
Jobs: 0 queued
Failed: 0 units
Since: Thu 2023-08-03 18:31:27 UTC; 23s ago
systemd: 253.4-1.fc38
CGroup: /user.slice/user-1001.slice/user@1001.service
├─app.slice
│ └─linger-example.service
│ └─1589 /usr/bin/sleep infinity
└─init.scope
├─1489 /usr/lib/systemd/systemd --user
└─1496 "(sd-pam)"
[sleeper@localhost ~]$ systemctl --user status linger-example.service
● linger-example.service - A systemd user unit demo
Loaded: loaded (/var/home/sleeper/.config/systemd/user/linger-example.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/user/service.d
└─10-timeout-abort.conf
Active: active (running) since Thu 2023-08-03 18:31:27 UTC; 38s ago
Main PID: 1589 (sleep)
Tasks: 1 (limit: 2238)
Memory: 224.0K
CPU: 1ms
CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/linger-example.service
└─1589 /usr/bin/sleep infinity
Aug 03 18:31:27 localhost.localdomain systemd[1489]: Started linger-example.service - A systemd user unit demo.
----
== Cleanup
You can then take down the instance. First, disconnect from the serial console by pressing `CTRL` + `]` and then destroy the machine:
----
virsh destroy fcos
virsh undefine --remove-all-storage fcos
----
You may now proceed with the xref:tutorial-updates.adoc[next tutorial].