bedrocklinux / bedrocklinux-userland

This tracks development for the things such as scripts and (defaults for) config files for Bedrock Linux
https://bedrocklinux.org
GNU General Public License v2.0
602 stars 65 forks source link

R&D effort: service manager config file format translation #208

Open paradigm opened 3 years ago

paradigm commented 3 years ago

Bedrock has a virtual filesystem which translates resources on-the-fly from some underlying format into one which is portable across strata. In 0.7 Poki, this is called "crossfs" and is mounted at /bedrock/cross. Eventually, this should not only be able to translate service manager config files to be cross stratum (e.g. make it so one stratum's systemd unit files work with another stratum's sytemd) but also convert across service manager formats (e.g. make it so one stratum's systemd unit files work with another stratum's runit).

This effort will start with easy subsets of this problem then add roll out more support as we figure out how to translate more things. When sufficient confidence is built in this effort, another Bedrock subsystem (in 0.7 Poki, "etcfs") will offer the ability to automatically generate symlinks to effectively enable services across all installed service managers when they are enabled in any. This way, (a subset of) cross-stratum service management should "just work".

Rather than translating between service manager formats directly, this will likely translate from each format into a Bedrock-specific internal, general format, and then from that internal format back out to whatever the desired service manager format. This will ensure the effort scales linearly with service managers as add, rather than quadratically.

The goal here is to collect and organize concepts we'll want to translate between formats, as well as add notes on how to do this translation to and from various service manager formats. Feel free to comment below with:

in which case I'll update the table here accordingly.

concept systemd runit openrc BSD-style SysV
example distro arch, debian void alpine, gentoo slackware, crux
documentation http://smarden.org/runit/ https://docs.voidlinux.org/config/services/index.html
enabled service location /var/service when running, /etc/runit/runsvdir/default when offline
disabled service location /etc/sv or /var/service with down file
service name file name? directory name file name
service description [Unit]/Description= description=
start service by running executable, blocking run script
bobbbay commented 3 years ago

I'm writing down some ideas right now - maybe you want another table for commands that can be run? Here, let me put one up:

command systemd runit OpenRC BSD-style SysV
start service systemctl start rc-service start (*)
stop service systemctl stop rc-service stop (*)
restart service systemctl restart rc-service restart (*)
service status systemctl status rc-service status (*)
run on boot systemctl enable rc-update add default
stop run on boot systemctl disable rc-update del default
show all services systemctl list-unit-files --type=service rc-update show -v
show startup services systemctl list-units rc-update show (**)

(*) Can also be run by /etc/init.d/<servicce> (**) Can also be run by rc-status

It's funny, I was working on this for a bit and then came across this legendary wiki page.

Please don't quote me on some of these, specifically he last few in systemd I've never needed to use.

Also, here's the documentation for OpenRC: https://wiki.gentoo.org/wiki/OpenRC

paradigm commented 3 years ago

I'm writing down some ideas right now - maybe you want another table for commands that can be run?

Commands like this could be useful for developers testing this subsystem, but not necessarily for the main aim. Our ultimate goal here is to write software that has read access to service manager configuration files (e.g. systemd .service files, runit directories, OpenRC scripts, etc), and from those generates stratum-portable equivalents (both for the same service manager, e.g. adding strat where necessary, and across service managers, translating things like systemd .service files into OpenRC scripts). The software we're making here won't need to actually know these commands.

Please don't quote me on some of these, specifically he last few in systemd I've never needed to use.

Blindly copy/pasting from documentation could result in headaches later, as it could result in us generating configuration that doesn't do what we expect it to do. Part of the effort here is for people to take the time to really understand these service managers. The end-goal isn't to populate a table; that's just an intermediate step toward actually doing this translation, which requires enough confidence that we'd feel comfortable being quoted.


A good way to think about what we need here could be to try this:

Pick two service managers. Presumably OpenRC would be one of them in your case. Install corresponding strata and packages so you have service configs available you can reference. Learn their configuration formats. Then try to make service configuration for one service-manager/stratum that will let it manage a service from the other service-manager/stratum. For example, you might make a #!/sbin/openrc-run script that references/wraps a runit run script, or a runit run script that calls out to strat <stratum> openrc-run. Think about what concepts you needed to gather from one of them to translate them to another - blocking vs non-blocking, pid file location tracking, dependencies (if that translates), etc. That kind of thing is what we need here.

Once we have a good list of these concepts, we can write an intermediate representation (probably a C data structure) that covers all of the concept we know of across service managers, then write code to translate to/from this intermediate representation.

bobbbay commented 3 years ago

Sounds good to me. I'll start work on such R&D tomorrow! Admittedly, I bricked my Gentoo install today at lunch, but I'll be ready by tomorrow to work on this. Will provide updates, cheers!

unrooted commented 3 years ago
concept Systemd s6 OpenRC
example distro Arch, Debian Artix Gentoo, Alpine
documentation https://www.freedesktop.org/wiki/Software/systemd/ https://skarnet.org/software/ (linking the whole website, because of how modular s6 is) https://wiki.gentoo.org/wiki/OpenRC
enabled service location /etc/systemd /etc/init.d/ (correct me if I'm wrong, but afaik, this)
disabled service location same as above same as above
service name file name file name
service description [Unit]/Description= description=
start service by running executable, blocking Exec= /etc/init.d/{service-name} start (correct me if I'm wrong in here as well)

Also, a little note when it comes to runit: Available services on Artix with runit are in /etc/runit/sv directory, while enabled ones are in /run/runit/service directory

I also think, that runit case needs mentioning how the service directory looks like:

-- service_name
    -- run
    -- supervise (created by runsv)
    -- finish (optional)
    -- config (optional)
    -- log (optional directory)
        -- run 
        -- current

Edit: from what I got when it comes to service description in runit, there's no description as an option, since runit tries to be as small as possible, but you can use comments there.