Skip to main content
Topic: shed init independient user services (Read 1852 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

shed init independient user services

user services are something that both systemd (user units) and runit users are familiar with i imagine, however i don't think many other inits got them (at least i'm sure neither sysvinit nor openrc have them) and altho the classic xinitrc exits to start processes needed for an xsession it really doesn't compare to the flexibility of proper user services, so i decided to cobble together something that can provide a decent solution

enter shed:  https://codeberg.org/eylles/shed

inspired by the architecture of sysvinit, shed is made to function in a similar manner that the combo of init and the service command, right now shed is more of a proof of concept but in the concept level is a more robust solution than others that i have found for the same problems shed solves, specially the problems and solutions i mention in the readme.

i have started to spread some word about shed since i really want some feedback on the idea from the target audience, that is users of no-systemd distros, altho i doubt that the void linux community would care much thanks to runit and i have barely interacted with the bsd side of things.

Re: shed init independient user services

Reply #1
ah well, a little status update for those interested in shed, i will put out a release tag once i'm done with another 3 points of the todo list on the repo.

as for showing the status i went for something that those acquainted with sysvinit will find familiar.

Re: shed init independient user services

Reply #2
the first version of shed, v.0.0.0 is finally out

https://codeberg.org/eylles/shed

after this i plan to work on the rest of intended features, bash completion and a man page.

Re: shed init independient user services

Reply #3
A small suggestion: since you liked using awk in your script, how about removing that line who uses bc and replacing it with awk, this way you don't carry extra dependencies for no reason
Code: [Select]
steptime=$(printf '%s\n' "scale=2; $totaltime / 20" | bc)
Code: [Select]
steptime=$(awk -v CONVFMT='%.2f' BEGIN'{print sprintf('$totaltime'/20)}')
This should work as a drop in replacement.

Also, to have this script really cut above simple service managers in e.g. LXQt, you should implement an auto-restart system with safetys against creating multiple PID's, should be simple to implement. And regarding PID's, why don't you store the pidfiles in /run/user/$UID instead of /tmp? It will be way more resilient against being overwritten.

Anyways, good job! for simpler desktops this is really useful.

Re: shed init independient user services

Reply #4
A small suggestion: since you liked using awk in your script, how about removing that line who uses bc and replacing it with awk, this way you don't carry extra dependencies for no reason
Code: [Select]
steptime=$(printf '%s\n' "scale=2; $totaltime / 20" | bc)
Code: [Select]
steptime=$(awk -v CONVFMT='%.2f' BEGIN'{print sprintf('$totaltime'/20)}')
This should work as a drop in replacement.
I'd write it as

Code: [Select]
steptime=$(awk -v tt="$totaltime" 'BEGIN {printf "%.2f", tt/20}')

This way, it works as intended even if $totaltime is empty or somehow contains awk code.

Quote
And regarding PID's, why don't you store the pidfiles in /run/user/$UID instead of /tmp? It will be way more resilient against being overwritten.

Seconding /run/user/$UID, it'd automatically clean the PID files on logout. (also, how it'd be more resilent?)

Quote
Also, to have this script really cut above simple service managers in e.g. LXQt, you should implement an auto-restart system with safetys against creating multiple PID's, should be simple to implement.

The simple way to implement auto-restart in sysv-rc style inits is polling the PID, which eats far more CPU than runit/s6/dinit's approach of just not letting daemons go into the background, as well as being less reliable as PIDs could be reused between the monitored program dying and the script doing another round of polling.

Implementing the latter in shell script and still being responsive to user commands gets quite tricky, though, speaking from experience.

Re: shed init independient user services

Reply #5
This way, it works as intended even if $totaltime is empty or somehow contains awk code.

True, i've overlooked how the variable was set. This way it's pretty much bulletproof. :)

Seconding /run/user/$UID, it'd automatically clean the PID files on logout. (also, how it'd be more resilent?)

To my knowledge files in /tmp get deleted quite easily by routines, i know it happens more with systemd but i've had this happen on different distros too like this too. And anyway to avoid mixups i'd suggest using ps (maybe also pgrep to ensure same process name), even with the strange glibc bug that causes them to freeze, something that i'm still figuring out how to report but it's apparently on high uptimes.

The simple way to implement auto-restart in sysv-rc style inits is polling the PID, which eats far more CPU than runit/s6/dinit's approach of just not letting daemons go into the background, as well as being less reliable as PIDs could be reused between the monitored program dying and the script doing another round of polling.

Implementing the latter in shell script and still being responsive to user commands gets quite tricky, though, speaking from experience.

Yeah, only if he wants to ditch posix sh for bash/zsh to use some shortcuts. His double script solution can act nicely, shed to be the manager and shedc to be the daemon instead of just launching. As such not even polling woule be needed, just a protection mechanism to avoid relaunching a process that gets killed instantly over and over again. Kind of what you meant by runit/s6/dinit's approach i've meant aswell.

Re: shed init independient user services

Reply #6
ah i didn't know that one thing about awk, and i figured that since bc is part of the coreutils it was fine to use.

as for the thing about /tmp i had no idea, after all i went into this knowing barely anything on the matter completely ignorant of what the best practices were barely getting any feedback from someone other than myself, which is why i put out v0.0.0 back in october and posted about it not just here in the artix forum but on the forums for devuan, mx linux and even a couple posts on 4chan with the intention of getting feedback on shed, which parts were nonsense, what was missing or if i was just another schizo reinventing the wheel in a more crude way, because you know there is a large amount of useful *nix programs that only get mentioned in some obscure readme once in a full moon.

you guys are the first real feedback i got since releasing this thing, honestly have not looked into shed since october the 8th as i began working on some scripts to use a terminal + fzf to pick copypastas , a low deps minimal "replacement" for auto-cpufreq and a permanent fork of pywal, intended to use these weeks of november to figure out github ci/cd to package pywal16 but found myself on the necessity of getting a job ASAP so i won't be doing much work if any on shed or any other repo until next week once i'm used to my work shift.

Re: shed init independient user services

Reply #7
And anyway to avoid mixups i'd suggest using ps (maybe also pgrep to ensure same process name), even with the strange glibc bug that causes them to freeze, something that i'm still figuring out how to report but it's apparently on high uptimes.

A good idea. That's also what FreeBSD's init does when checking if a PID still belongs to a certain process.

Yeah, only if he wants to ditch posix sh for bash/zsh to use some shortcuts. His double script solution can act nicely, shed to be the manager and shedc to be the daemon instead of just launching. As such not even polling woule be needed, just a protection mechanism to avoid relaunching a process that gets killed instantly over and over again. Kind of what you meant by runit/s6/dinit's approach i've meant aswell.

This new shedc structure sounds too much like a less efficient daemontools/runit/s6 clone to me. They can already be made to work independent of any init, and I don't know of shells that expose the poll(3) syscall, which would allow for this new shed to efficiently listen at the same time for both the daemon starting/stopping and user issuing commands.

I'd instead try to make shedc more like openrc-run (i.e. does some preparations, sources the definition and executes the contents) so no shed-related daemon would be running at all during the user session. A shed-shutdown would then be called during logout. A sysv-rc of user services like this would be something actually unique.

ah i didn't know that one thing about awk, and i figured that since bc is part of the coreutils it was fine to use.

It's a really common program, but it's a separate package from coreutils. It's not even a part of base-devel, iirc, and nothing on my system seems to depend on it. There's a chance people will have awk, but not bc.

To be honest, I didn't know about awk 'BEGIN {}' either, but it's specified by the POSIX manual.

scripts to use a terminal + fzf to pick copypastas

I'll take Software I Didn't Know I Needed for $500, Alex.

Re: shed init independient user services

Reply #8
I'll take Software I Didn't Know I Needed for $500, Alex.

here it is, https://github.com/eylles/fzf-copypasta
i only include 1 copy pasta and the example config, i'm thinking of maybe adding another copy pasta that is safe there, rn i got 25 copypastas on my collection (including the gnu+linux one) but most of them are 4chan culture or adjacent so it is impossible to have them in any corporate backed git host or gitea/gitlab instance or with my regular git credentials without getting cancelled to hell and back, so you are expected to provide and format your own copypastas using the included one as example.

To be honest, I didn't know about awk 'BEGIN {}' either, but it's specified by the POSIX manual.
i did know about the BEGIN and END statements in awk, but i ain't so versed on actually doing math and real work in awk, only know how to do meme tier stuff and text search, formatting replacement. speaking of meme tier stuff in awk take a look https://github.com/eylles/awkat

Re: shed init independient user services

Reply #9
welp, took a while but i think i got shed to at least the suggestions i got from this thread, currently i'm working on having shed work with a named pipe for the "reply" to shedc, also i'm looking into one-shot services and session components to be started by shed.

https://codeberg.org/eylles/shed/releases/tag/v0.2.0

 

Re: shed init independient user services

Reply #10
I've been coming across this project and found it interesting, but I want to address a few things from looking at, running it without any services, and somewhat tinkering with the code (I wanted to try it with some test services, but it seems to hang on start_services for both master and version 0.2.0):
  • While I do understand that shed's primary use case is for GUI sessions (thus, usually summoned by .xinitrc), I think this has the potential to be a full-blown user service manager (for something written in shell, it can be even integrated with turnstile).
    Currently, we export GUI_SESSION_PID in .xinitrc so that shedc can read it later. Why not save $GUI_SESSION_PID to a file to be read by shedc to detect if a shed session is running? Since it already uses XDG_RUNTIME_DIR, I think it can be something like /run/user/$USER_ID/shed/session (I also believe shed should get its own directory inside $XDG_RUNTIME_DIR). This way if I log into my system on another tty, I can still control my shed-controlled daemon.
  • When shed exits without shedc (by Ctrl+C or any unexpected exits, for instance), it should also do things like shedc logout so that it can cleanly exit without leaving anything behind, I think a trap would do nicely.
Overall, I actually like it, but unfortunately I can't run any services since it seems it's stuck on start_services. I can post logs if needed.
now only the dinit guy in artix