4

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
1
  • 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. Commented Nov 27, 2021 at 1:00

1 Answer 1

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.