3

I would like to replace my Xsession with my custom program (kiosk-like setup), previously I was just setting STARTUP variable in my .xsessionrc file like:

STARTUP='/path/to/my/program'

Now I want to wrap my program as a systemd service to utilize some systemd features like journal logging, configurable automatic restarts, etc. As with previous setup I would prefer to avoid to run 3rd-party session and window managers, but I still have to run something to keep session active, so I've used:

STARTUP='systemd-run --user --scope /path/to/my/program'

However it's still not a convenient systemd unit and finally I've ended up with:

STARTUP='systemd-run --user --scope --unit my-session sleep inf'

and defined a service unit for my program to run:

[Unit]
Description=My service
BindsTo=my-session.scope
Requisite=my-session.scope
After=my-session.scope

[Service]
Type=exec
ExecStart=/path/to/my/program
Restart=always

[Install]
WantedBy=my-session.scope

In general this setup works like a charm however relying on scope name that is generated on the fly seems clunky for me and moreover sometimes it's required to do implicit cleanup on session restart like:

systemctl reset-failed my.service my-session.scope

because systemd complains that my-session.scope already exists.

So, I'm looking for a way to run systemd service synchronously as systemd-run --scope does but same time re-using existing unit file and not generating one on the fly.

P.S.: I've tried following approach but it doesnt work correctly (interrupting systemctl doesnt interrupt the service managed):

systemctl start --wait my-session.target
reddot
  • 266
  • 3
  • 10
  • ```systemctl start --wait my-session.target``` actually worked for me. The only thing I altered, was to remove the ```Restart=always``` line from the service file, since I do not want this behavior. – dirdi Nov 27 '21 at 01:00

1 Answers1

1

Finally found several suitable configurations:

a) Mark running service as StopWhenUnneeded and use Wants property with systemd-run --scope:

.xsessionrc:

STARTUP='systemd-run --user --scope --property Wants=my.service sleep inf'

my.service:

[Unit]
Description=My service
StopWhenUnneeded=yes

[Service]
Type=exec
ExecStart=/path/to/my/program
Restart=always

It's really minimal solution and does all the things required, however it's not possible to start my.service manually. In case it's desired:

b) Introduce intermediate my-session.target and declare my.service as PartOf=my-session.target:

.xsessionrc:

STARTUP='systemd-run --user --scope --property Wants=my-session.target sleep inf'

my.service:

[Unit]
Description=My service
PartOf=my-session.target

[Service]
Type=exec
ExecStart=/path/to/my/program
Restart=always

[Install]
WantedBy=my-session.target

my-session.target:

[Unit]
Description=My session
StopWhenUnneeded=yes
RefuseManualStart=yes
RefuseManualStop=yes

c) Finally it worth noting that systemd-run doesn't prohibit using of "automatic-only" properties such as BoundBy/ConsistsOf, as a result it's possible to do:

.xsessionrc

STARTUP='systemd-run --user --scope --property BoundBy=my.service --property Wants=my.service sleep inf'

my.service:

[Unit]
Description=My service

[Service]
Type=exec
ExecStart=/path/to/my/program
Restart=always

I would consider using those properties as hackish and probably being a bug. But maybe somebody could find it useful.

reddot
  • 266
  • 3
  • 10