tvrzna / emptty

Dead simple CLI Display Manager on TTY
MIT License
696 stars 26 forks source link

How am I supposed to run login session services that die with login session? #73

Closed amano-kenji closed 2 years ago

amano-kenji commented 2 years ago

dbus-launch gave me its process ID, so I could kill it manually in a custom emptty session.

I can also do

#!/bin/sh

some-service &
service_pid=$!

sway

kill $service_pid

This has the advantage of making services inherit environmental variables including DBUS_SESSION_BUS_ADDRESS. For dbus session services, having access to DBUS_SESSION_BUS_ADDRESS is crucial.

But, this is ugly and fragile. If the service dies, there is no process supervisor to revive it and kill it during logout.

Is there a program that handles process life cycle for me for login sessions?

amano-kenji commented 2 years ago

One way I thought of is this.

#!/bin/sh

supervisor -l /dev/null -p ${XDG_RUNTIME_DIR}/supervisor.pid -c ./supervisor-sway.conf

sway

kill $(cat ${XDG_RUNTIME_DIR}/supervisor.pid)

supervisor is https://github.com/Supervisor/supervisor Another implementation is https://github.com/ochinchina/supervisord

Do you know any cleaner way?

tvrzna commented 2 years ago

It's a question, what could be clean in this case. If dbus-daemon or any other part is considered as fragile, there is something wrong with an environment. From emptty side there could be provided the PID as environmental variable, but there still needs to be some kind of supervisor (or user service in your init). The simplest solution is to use known tools, the hardest is to develop one.

amano-kenji commented 2 years ago

https://github.com/mdellweg/pass_secret_service depends on a user systemd service to shut itself down. Thus, it doesn't die when its session dbus dies. gnome-keyring-daemon dies when its session dbus dies.

I tried https://github.com/Supervisor/supervisor, but I was put off by its complexity and its lack of support for service dependencies.

I found https://github.com/davmac314/dinit which can serve as a user process supervisor or a system init. It is simple and supports dependencies properly. It is better than OpenRC, runit, s6, systemd, supervisor, and so on for customized user process supervision.

But, dinit also needs to sandwich a window manager like sway with two commands.

Can you think of a better way to introduce a user process supervisor than sandwiching a window manager with two commands?

tvrzna commented 2 years ago

Commit for #72 does that, but it is still a sandwich. It could be expanded to always run this dbus-launch, even ~/.config/emptty is used, however this wouldn't watch for unexpected crashes. But it would handle the kill of daemon on and of a session.

amano-kenji commented 2 years ago

emptty could implement session services that are executed betwen dbus-launch and emptty session and die with emptty session.

You decide whether you want to implement emptty session services.

I think this can be done by me with custom sessions.

tvrzna commented 2 years ago

There's already DISPLAY_START_SCRIPT and DISPLAY_STOP_SCRIPT config params, it's not optimal, but could do the thing. Or new param ALWAYS_DBUS_LAUNCH or something like that can be introduced and it would always start and stop dbus-daemon.

amano-kenji commented 2 years ago

Why was ALWAYS_DBUS_LAUNCH added?

DISPLAY_START_SCRIPT and DISPLAY_STOP_SCRIPT are started as root because I run emptty in daemon mode. I want to start them as login user. Another problem is that the scripts don't have access to session dbus.

If I start dinit before sway and dinitctl shutdown after sway in my custom session, I get what I want.

This is how I launch dinit and scrap it in a custom session.

#!/bin/sh

. ~/.env

dinit &

sway

# This sends TERM signal to dinit through dinitctl unix socket.
dinitctl shutdown

If I wanted to execute dinit for a specific window manager, I would use a custom session. If I wanted to execute dinit and source ~/.env for every session, I would need something else.

tvrzna commented 2 years ago

The reason for ALWAYS_DBUS_LAUNCH is to provide interruption of dbus-daemon to anyone, who doesn't want to polish own script. Scripts are always better, but often it's not universal solution.

You are right; I forgot that fact, that it's started as root.

Are you aware of ~/.config/emptty? This would work for each session.

amano-kenji commented 2 years ago

It seems ~/.config/emptty will work for source ~/.env. But, what about dinitctl shutdown or running dinit as a session service?

What is the relationship between ALWAYS_DBUS_LAUNCH and DBUS_LAUNCH?

tvrzna commented 2 years ago

You can look at ~/.config/emptty as a common custom session, it should work as it works for you now.

These options uses same code, DBUS_LAUNCH runs only in specific cases, but ALWAYS_DBUS_LAUNCH ignores these conditions and launches it always. So you can have DBUS_LAUNCH=false, ALWAYS_DBUS_LAUNCH=true will start dbus-daemon.

amano-kenji commented 2 years ago

I just got back from testing. It seems user config can actually execute commands before and after session. But, the documentation is confusing.

In man emptty

Further questions

ALWAYS_DBUS_LAUNCH seems both useful but a bit questionable in value after getting to know Selection=true of user config and XINITRC_LAUNCH. It is useful because people don't have to tinker with dbus-launch in ~/.xinitrc or user config.

tvrzna commented 2 years ago

Sorry for late reaction to this issue. I've updated some points in man and readme.

Configuration of system is an alchemy. I'm thinking about switch to DBUS_LAUNCH to false as default in favor of ALWAYS_DBUS_LAUNCH. But that is just future, it needs to be accepted by users in common since it changes behaviour defined in first release.

amano-kenji commented 2 years ago

The documentation still mentions .emptty instead of user config. I really thought the documentation didn't apply to ~/.config/emptty because it specifically mentioned .emptty instead of user config which is both ~/.emptty and ~/.config/emptty.

amano-kenji commented 2 years ago

Good.