Re: First time user experiences
Alexis <[email protected]> Mon, 02 Mar 2026 10:59:26 +1100
| Newsgroups | gmane.comp.sysutils.supervision.general |
|---|---|
| Message-ID | <[email protected]> |
Guillermo <[email protected]> writes: > What Gentoo with OpenRC has traditionally done for dealing with > PipeWire and WirePlumber, is installing a script that tries to > emulate > the behaviour, and that is called by desktop environments that > implement Freedesktop's desktop application autostart > specification. > > * > https://gitweb.gentoo.org/repo/gentoo.git/tree/media-video/pipewire/files/gentoo-pipewire-launcher.in-r4?id=20c3561947c263ea300c9e04a134910539f9c191 > * https://specifications.freedesktop.org/autostart/0.5 > > But, with navi-desu's contributions, OpenRC added user services > in > version 0.60, so Gentoo now also ships corresponding OpenRC user > service scripts. Indeed, although at this point, it should be noted that those specific user services are still regarded as 'experimental', and there are some things to be aware of when using them, as i've described in this issue i've opened: https://bugs.gentoo.org/970611 (i've actually contributed various fixes/improvements to the `gentoo-pipewire-launcher` script over time, e.g. https://bugs.gentoo.org/907891, amongst others.) > What is missing is the tie with login sessions, which would > probably > require dealing with those "unsavory interfaces". That's why I > was > interested in what Alexis was doing. Well, the first thing to note is that i'm using elogind, which probably avoids certain issues. (On the Gentoo wiki, we have a page to try to support those who don't want to use elogind, https://wiki.gentoo.org/wiki/Configuring_a_system_without_elogind ) Also, my user setup is - to say the least - 'unusual', in that it has a focus on decoupling, designed to: * help isolate issues, and; * facilitate switching between different sorts of setups, in order to be better able to understand and document things for others. i thus make no claim that how i've done things is The Way To Do Things. :-) With all that said: i use Zsh as my 'daily driver' shell. In my ~/.zprofile, i have this: ``` # Used by ~/.local/bin/start-services.sh, called by ~/.zlogin: # # 'manual' to manually start services. # * 's6sup' to manually start s6-supervise processes for services. # * 's6svscan' to use s6-svscan on a scandir. # * 's6rc' to use s6-rc services. export USER_S6=s6rc ``` In ~/.zlogin, i have: ``` if [ $(who | wc -l) -lt 2 ]; then ${HOME}/.local/bin/start-services.sh fi ``` This is to (try to) ensure i'm only running services under one login session, so that i can log in on other VTs to do things like test how a specific Wayland compositor works, whilst still running my usual GUI session. (Side note: i often try to write shell that's as close to POSIX as possible, so that it's easier to generalise to being portable should i decide to make it public; i've created a page on the Gentoo wiki to help me - and hopefully others! - remember the scripting-related differences between shells, https://wiki.gentoo.org/wiki/Shell/Scripting ) In ~/.local/bin/start-services.sh (yes, i know i don't _need_ the `.sh` extension; it's purely a personal reminder to me that i find helpful): ``` #!/usr/bin/sh # # Script assumes XDG_* env vars and LOGS env var are set appropriately. # # Which services to start are specified as files in # $XDG_STATE_HOME/services, each file containing a single # line, separated by ':', consisting of three fields: # # * Command line to start the service manually. # * `pgrep` option to check if service is already running. # * Description of service. # SERVICES="${XDG_STATE_HOME}/services" ### # Helper functions. ## ... [logging functions] ... # Start services. case ${USER_S6} in 's6rc') S6RC_SERVICES="${HOME}/src/srht/s6-rc-services/sh/user" S6RC_WANTED="${XDG_STATE_HOME}/s6-rc/wanted" S6RC_COMPILED="${XDG_STATE_HOME}/s6-rc/compiled" S6RC_SCANDIR="${XDG_STATE_HOME}/s6-rc/scandir" S6RC_LIVE="${XDG_RUNTIME_DIR}/s6-rc" rm -f "${S6RC_WANTED}"/* rm -rf "${S6RC_COMPILED}" rm -f "${S6RC_SCANDIR}"/* rm -rf "${S6RC_LIVE}"* for s in $SERVICES/*; do ln -s "${S6RC_SERVICES}/$(basename $s)" "${S6RC_WANTED}" if [ -d "${S6RC_SERVICES}/$(basename $s)-log" ] then ln -s "${S6RC_SERVICES}/$(basename $s)-log" "${S6RC_WANTED}" fi done echo -n "Compiling s6-rc database in ${S6RC_COMPILED} .... " s6-rc-compile "${S6RC_COMPILED}" "${S6RC_WANTED}" if [ ! $? = '0' ]; then echo 'failed.' else echo 'ok.' fi echo -n "Starting s6-svscan on ${S6RC_SCANDIR} .... " s6-svscan -- "${S6RC_SCANDIR}" 1>>"${LOGS}/s6-svscan.log" 2>&1 & if [ ! $? = '0' ]; then echo 'failed.' else echo 'ok.' fi echo -n "Initialising s6-rc with live at ${S6RC_LIVE} .... " s6-rc-init -c "${S6RC_COMPILED}" -l "${S6RC_LIVE}" "${S6RC_SCANDIR}" if [ ! $? = '0' ]; then echo 'failed.' else echo 'ok.' fi for s in $S6RC_SCANDIR/*; do echo -n "Starting $(basename $s) .... " s6-rc -l "${S6RC_LIVE}" start "$(basename $s)" if [ ! $? = '0' ]; then echo 'failed.' else echo 'ok.' fi done ;; 's6svscan') ... *) echo "Unknown value for USER_S6, '${USER_S6}' - no services started!" exit 1 ;; esac ``` "${HOME}/src/srht/s6-rc-services/sh/user" is part of a Git repo whose upstream is a private repo on Sourcehut, which i've not yet set up properly due to All The Stuff Happening. :-) The `sh` in the path is intended to be able to separate services based on POSIX sh from services based on e.g. execline, and the `user` is intended to separate 'user' services from 'system' services. This was part of my idea for a public repo of s6-rc services; i'll come back to this. My ${XDG_STATE_HOME}/services/ directory looks like: ``` -rw-r--r-- 1 alexis alexis 0 Dec 16 2024 dbus-session-bus -rw-r--r-- 1 alexis alexis 0 Dec 16 2024 emacs -rw-r--r-- 1 alexis alexis 0 Dec 22 2024 mpd -rw-r--r-- 1 alexis alexis 0 Dec 22 2024 pipewire -rw-r--r-- 1 alexis alexis 0 Dec 22 2024 pipewire-pulse -rw-r--r-- 1 alexis alexis 0 Dec 22 2024 wireplumber ``` where each entry has been created via touch(1), to 'activate' the service. We're finally at the actual services. :-P The `dbus-session-bus` service is basically as i've described in my "OpenRC user services via s6 and s6-rc" guide: https://wiki.gentoo.org/wiki/User:Flexibeast/guides/OpenRC_user_services_via_s6_and_s6-rc#An_s6-rc_D-Bus_session_bus_service In a previous post to the list, i wrote "by default, PipeWire runs per-user, and requires a D-Bus session bus"; what i _should_ have written was "requires a D-Bus session bus _for my use-cases_". In particular, i want RTKit support, which is one of the cases where D-Bus support is required, as described in the PipeWire FAQ: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#does-pipewire-require-dbussystemdflatpak (i'm wanting to do more music production, so Linux audio is effectively now on my 'critical path', hence my increased focus on it, and wanting to spend less time on other stuff.) The run files for the `pipewire`, `pipewire-pulse` and `wireplumber` user services reflect the fact that i'd been intending to make their behaviour configurable: ``` #!/bin/sh if [ -f "${XDG_CONFIG_HOME}/s6-rc/pipewire" ] then . "${XDG_CONFIG_HOME}/s6-rc/pipewire" fi exec /usr/bin/s6-notifyoncheck /usr/bin/pipewire ``` ``` !/bin/sh if [ -f "${XDG_CONFIG_HOME}/s6-rc/pipewire-pulse" ] then . "${XDG_CONFIG_HOME}/s6-rc/pipewire-pulse" fi exec /usr/bin/s6-notifyoncheck /usr/bin/pipewire -c pipewire-pulse.conf ``` ``` #!/bin/sh exec /usr/bin/s6-notifyoncheck /usr/bin/wireplumber ``` With all that in place, i have the following convenience functions in my ~/.zshrc: ``` function s6rc-reset { setopt local_options rm_star_silent no_rm_star_wait null_glob S6RC_WANTED="${XDG_STATE_HOME}/s6-rc/wanted" S6RC_COMPILED="${XDG_STATE_HOME}/s6-rc/compiled" S6RC_SCANDIR="${XDG_STATE_HOME}/s6-rc/scandir" S6RC_LIVE="${XDG_RUNTIME_DIR}/s6-rc" rm -f "${S6RC_WANTED}"/* rm -rf "${S6RC_COMPILED}" rm -f "${S6RC_SCANDIR}"/* rm -rf "${S6RC_LIVE}"* } function s6rc-live { # "${@}" expands each positional parameter as a separate argument. # Double quotes are required for this to happen. s6-rc -l "${XDG_RUNTIME_DIR}/s6-rc" "${@}" } function s6rc-svc { service=${argv[-1]} opts=${argv[1,-2]} s6-svc ${opts} "${XDG_RUNTIME_DIR}/s6-rc/servicedirs/${service}" } ``` where `s6rc-svc` is the function i use to restart a service, bring it down, etc. Whew! That's obviously a lot; hope it's of some use. :-) i'm sure there are various things that should be done differently, or that could be improved, but i don't really want to get into the weeds on this, given my limited personal resources. Finally, earlier i wrote: > This was part of my plan for a public repo of s6-rc services; > i'll come back to this. Something i've noticed is that many of us are constantly re-inventing the wheel in terms of services. Yes, many of us publicly share the services we've created, which might themselves be based on similar services publicly shared by others. And yes, it's true that a given service might require OS-specific stuff. But my thought was that it might be nice to have something like the package repos associated with various programming languages, containing services that are designed to be configurable as possible, so that they can be used 'out of the box' by e.g. packagers, end-users, etc., without having to futz with the details. Hence the `sh` / `user` directory structure i described; i was thinking that such a 'service repo' could have a directory structure something like: /s6-services/execline/system /s6-services/execline/user /s6-services/sh/system /s6-services/sh/user /s6-rc-services/execline/system /s6-rc-services/execline/user /s6-rc-services/sh/system /s6-rc-services/sh/user and then possibly things like: /s6-rc-services/python/system /s6-rc-services/python/user etc. This would allow packages, end-users, etc. to make use of whichever language is best-suited to their particular use-case, without having to create bespoke services (even if they're based on other bespoke services). Of course, the release of s6-frontend changes the landscape. :-) But i still feel the overall idea - of making it much easier for packagers and users to get a working s6-based setup of some type - is probably one that might be useful for people to consider. Alexis.