Skip to main content
Topic: First Impressions (Read 2665 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

First Impressions

Thanks to Dudemanguy for packaging S6 for Artix. I hope the following comments will be of use, both to him and anybody else who might be interested.

Installation.

I decided to try converting my OpenRC Artix install to S6 (using a copy in a separate partition, of course).

All went fairly smoothly to start with - removed OpenRC, installed S6 and added a number of service packages: lightdm-s6, dbus-s6, cups-d6 and so forth.

However, things started to get decidedly odd when I added a number of self-written service files, and so had to run 's6-rc-compile' and 's6-rc-update'. And even worse when I subsequently added a futher S6 package or two from the repos.

After a lot of trial and error, investigation, and reading skarnet.org's documentation, I realised that the following conditions must be met -

1. /etc/s6/rc/ contains a link 'compiled' pointing to the current database, but 's6-rc-update' doesn't update this link to point to the latest version produced by the previous 's6-rc-compiled'. You have to do this yourself.

2. 's6-rc-update' deletes your 'default' bundle completely. So you MUST rerun 's6-rc-bundle add default .....' before any reboot.

3. If you run pacman to add/delete an S6 package, the post-transaction hook (in /usr/share/libalpm/hooks/s6-rc-db-update.hook and /usr/share/libalpm/scripts/s6-rc-db-update-hook) does the following -

    a. Runs 's6-rc-compile', 's6-rc-update', an edits the 'compiled' link to point to the latest database. All good so far.

    b. Deletes any old databases in /etc/s6/rc/. Not so good, as it deletes based purely on the filename ('compiled-nnnnnnnnnn' where 'nnnnnnnnnn' is the output of 'date +%s' at the time of running the hook), rather than the actual timestamp of the file.

    c. Outputs a message asking that you redo your bundle.

    So you MUST use 'date +%s' when naming your self-compiled databases. If not, you could end up (as I did) with the 'compiled' link pointing to a non-existant database, with the one just created by the hook having been deleted.

Suggestions.

1. For users: read all the relevant documentation on the skarnet.org website BEFORE starting. Perhaps print it out, and highlight any important bits?  Also keep a note of your 'default' bundle's services.
Note: some of the skarnet documentation differs from the Artix package.

2. For Dudemanguy: amend the post-transaction hook to do the database deletions based on the timestamps, not filenames. Perhaps keep 2 or 3 old copies as well as the latest? Also amend the final message to to make it clear that one MUST redo the bundle.

Further notes.

1. The 'hostname' service doesn't seem to work - the hostname is set to 'artixlinux' rather than that specified in /etc/hostname.

2. If running 'dnsmasq', you'll find hundreds of Dbus error messages in the console log. These can be eliminated by editing /usr/share/dbus-1/system.d/dnsmasq.conf to have an extra 'allow' policy for user 'dnsmasq' (don't delete the 'root' one).

Package requests.

The following would be useful, if possible to do -
fuse-s6
netmount-s6
nftables-s6 (ideally with a 'down' as well as 'up')

Apologies for this rather long post, and for any mistakes/inconsistencies you might find.

Re: First Impressions

Reply #1
First of all, thanks for all your feedback!

2. For Dudemanguy: amend the post-transaction hook to do the database deletions based on the timestamps, not filenames. Perhaps keep 2 or 3 old copies as well as the latest? Also amend the final message to to make it clear that one MUST redo the bundle.

Good idea. I'll do this. The reason I used date was so I could generate a unique filename. When it came to deleting databases, I just wrote the script to consider the filename based on the time. But you're right, this is bad if a user goes around creating their own databases with their own names. Any suggestions on amending that message? The intention there was to make it clear that you had to redo all your service bundles, but apparently that's not clear enough. Another possibility is that I could attempt to write logic into the hook that automatically redos any bundles. It's probably not too difficult.

I could modify the database deleting behavior. Strictly speaking, I don't even have to delete them at all. The only reason was to not bloat the HDD with a ton of databases, but it's not unreasonable to leave database removal completely to the user.

And yeah, s6 is kind of complicated and a bit different. Ideally, if users just stick to what's packaged, they shouldn't have to read too much documentation, but if you're going to go around and write your own scripts, then you definitely need to be aware of what you're doing. The defaults are a little different on Artix for mostly convenience reasons (having everything lumped in /etc/s6 makes more sense).

And yes, I can look into doing those s6 packages plus fixing the hostname thing too.

Re: First Impressions

Reply #2
Thanks for the reply.

Any suggestions on amending that message?

Perhaps something like 'Don't forget that you must redo yours bundles before rebooting' ?

Another possibility is that I could attempt to write logic into the hook that automatically redos any bundles. It's probably not too difficult.

One other possibility that you've probably considered and rejected: ask the user to create a bundle-type service in /etc/s6/sv, with the 'contents' file having a list of the services in the bundle. This would remove the necessity of having to redo the bundles after the pacman update, but would require the user to update the 'contents' prior to running the pacman. Probably more trouble than its worth, as the user would have to know the name of the service in advance (it's not always the same as the package name).

but it's not unreasonable to leave database removal completely to the user.

Yes, possibly the best option: your documentation would have to remind the user to be careful and not delete the latest DB, though.

And yes, I can look into doing those s6 packages plus fixing the hostname thing too.

Thanks.

Re: First Impressions

Reply #3
Okay, I went ahead changed some things here. The biggest change is that s6-rc-db-update-hook has been rewritten  (currently, the new version of s6-rc is in testing; will be moved to system sometime later). The behavior is different now when adding/removing s6 services and (I think) it's better now. First of all, it does not delete any database directories anymore. That is left entirely up to the user. Of course this means that a new database directory is created everytime you install/uninstall a script from the repos, but in practice there's no reason anyone would do this constantly. There's a gentle reminder in the hook (which I think is worded OK; can change it if it's not clear enough though)  telling the user that he/she can remove unneeded/unwanted databases.

Additionally, the hook does its best to preserve old bundles from the old database so you don't have to remake bundles when you install a script from the repo. This basically done in two steps. First: see if there are any bundles that existed in the old database that don't exist in the new one (i.e. bundles added with the s6-rc-bundle command). And then secondly, find the services in the old bundle that still exist in the new database and recreate the old bundle. This way, if you uninstall a service that's part of a bundle, the hook will recognize this and remake the bundle without trying to add the service you removed (which would result in an error of course).

On the init script front. I did add nftables-s6 to world which was simple enough. However, there's no "down" script right now. I'm not really familiar with it and I didn't see a good reference init script anywhere that told me what command I should run when shutting it down. Any suggestions? Fuse and netmount are more complicated (i.e. I haven't done them yet) and for those I should probably put them in s6-scripts (initial set of bootup scripts that comes with s6-rc). For the hostname fix, I'm leaning towards putting it with a global "s6.conf" file that's still on the TODO list.

Sidenote: I checked Arch's systemd file and it runs dnsmasq with the dnsmasq user as well which makes me think that's probably right. Perhaps this calls for changing the default configuration file that comes with dnsmasq?

Re: First Impressions

Reply #4
Many thanks for doing these changes - they should make things a lot easier for the user.

Quote
Okay, I went ahead changed some things here. The biggest change is that s6-rc-db-update-hook has been rewritten  (currently, the new version of s6-rc is in testing; will be moved to system sometime later). The behavior is different now when adding/removing s6 services and (I think) it's better now. First of all, it does not delete any database directories anymore. That is left entirely up to the user. Of course this means that a new database directory is created every time you install/uninstall a script from the repos, but in practice there's no reason anyone would do this constantly. There's a gentle reminder in the hook (which I think is worded OK; can change it if it's not clear enough though)  telling the user that he/she can remove unneeded/unwanted databases.

This appears to work flawlessly.

Quote
Additionally, the hook does its best to preserve old bundles from the old database so you don't have to remake bundles when you install a script from the repo. This basically done in two steps. First: see if there are any bundles that existed in the old database that don't exist in the new one (i.e. bundles added with the s6-rc-bundle command). And then secondly, find the services in the old bundle that still exist in the new database and recreate the old bundle. This way, if you uninstall a service that's part of a bundle, the hook will recognize this and remake the bundle without trying to add the service you removed (which would result in an error of course).

1. Deleting a service package works as intended - the service is removed from the bundle.
2. Adding a service package doesn't seem to work - the service just isn't added to the bundle. Perhaps I'm doing something wrong (wouldn't be the first time!).

Quote
On the init script front. I did add nftables-s6 to world which was simple enough. However, there's no "down" script right now. I'm not really familiar with it and I didn't see a good reference init script anywhere that told me what command I should run when shutting it down. Any suggestions?

I've been looking at the OpenRC init script for nftables (Artix doesn't yet provide one, so I obtained a copy from the Gentoo website - https://gitweb.gentoo.org/repo/gentoo.git/tree/net-firewall/nftables/files/nftables.init , and ....../confd).

This has a 'stop' function which optionally runs a 'save' function to copy the current firewall settings to /var/lib/nftables/rules-save. This file is loaded in the 'start' function, rather than /etc/nftables.conf.

It looks like the OpenRC init for iptables does something similar.


As for dnsmasq, I suspect that the spurious messages might also happen with OpenRC, but they simply don't appear in the console log for some reason. Just a guess though, could well be wrong.

Hope the above comments are of use.

Re: First Impressions

Reply #5
2. Adding a service package doesn't seem to work - the service just isn't added to the bundle. Perhaps I'm doing something wrong (wouldn't be the first time!).

When you remove a service, you need to be sure to remove it from any existing bundles so the hook has to take that into account. But simply installing a service shouldn't add it to any bundle by default so the hook does nothing in that case. Adding services to a bundle is left to the user. Unless I misunderstand what you mean here.

Quote
I've been looking at the OpenRC init script for nftables (Artix doesn't yet provide one, so I obtained a copy from the Gentoo website - https://gitweb.gentoo.org/repo/gentoo.git/tree/net-firewall/nftables/files/nftables.init , and ....../confd).

This has a 'stop' function which optionally runs a 'save' function to copy the current firewall settings to /var/lib/nftables/rules-save. This file is loaded in the 'start' function, rather than /etc/nftables.conf.

It looks like the OpenRC init for iptables does something similar.

Hmm, the gentoo script calls some nftables.sh script multiple times. No idea what that is (doesn't come with arch at any rate) which makes it hard to use as a reference. Just glancing at the Arch Wiki entry, does nftables even need a down script? You have your ruleset saved in /etc/nftables.conf which is loaded on startup. I don't think there's anything that needs to be done on shutdown is there?


Quote
As for dnsmasq, I suspect that the spurious messages might also happen with OpenRC, but they simply don't appear in the console log for some reason. Just a guess though, could well be wrong.

Hmm at least for runit I have not been able to reproduce the error message, but then again I don't really know what exactly dbus does with dnsmasq. So I don't know if it actually works like it's supposed to in the first place.

Re: First Impressions

Reply #6
When you remove a service, you need to be sure to remove it from any existing bundles so the hook has to take that into account. But simply installing a service shouldn't add it to any bundle by default so the hook does nothing in that case. Adding services to a bundle is left to the user. Unless I misunderstand what you mean here.

Guess I misinterpreted the following from your earlier post, sorry -
....... so you don't have to remake bundles when you install a script from the repo.


Hmm, the gentoo script calls some nftables.sh script multiple times. No idea what that is (doesn't come with arch at any rate) which makes it hard to use as a reference. Just glancing at the Arch Wiki entry, does nftables even need a down script? You have your ruleset saved in /etc/nftables.conf which is loaded on startup. I don't think there's anything that needs to be done on shutdown is there?

The 'nftables.sh' script is in the same place on the Gentoo website I mentioned earlier, but in sub-directory 'libexec'.

I imagine that whoever wrote the 'nftables-openrc' service made it as similar as possible to the 'iptables-openrc' one. Perhaps the optional 'save' function in both is to cater for the user making dynamic changes to the firewall and wishing to save these automatically over a reboot. I doubt that many people would want to use this facility, however, so perhaps including it in nftables-s6 (and iptables-s6) would be overkill.

Re: First Impressions

Reply #7
iptables-s6 was made based off of the iptables-runit script which doesn't any special down scripts either. Honestly, openrc scripts kind of confuse me since they have to do this weird start/stop stuff (well actually they don't have to, but most of the gentoo scripts are all like that).

Re: First Impressions

Reply #8
Regarding hostname. I believe the problem is that importas is run in a foreground block. The foreground block is executed in a separate fork, which means the variable wont be available after the foreground block.

I.e. $HOSTNAME is always undefined on the last line:
Code: [Select]
foreground {
    if { test -s /etc/hostname } backtick -n HOSTNAME { cat /etc/hostname }
    importas -iu HOSTNAME HOSTNAME
}
if -n { test -z $HOSTNAME } sh -c "echo $HOSTNAME >| /proc/sys/kernel/hostname"
I'm new to execline, but played around a bit and this seems to work:
Code: [Select]
#!/usr/bin/execlineb -P

fdmove -c 2 1
if { echo -- Setting hostname }
ifelse { test -s /etc/hostname } {
  backtick -n HOSTNAME { head -n1 /etc/hostname }
  importas -iu HOSTNAME HOSTNAME
  ifelse -n { test -z $HOSTNAME } { sh -c "echo $HOSTNAME >| /proc/sys/kernel/hostname" }
}
I'm using ifelse to avoid having the script exit with a non-zero value. The "else" clauses are empty here, but one could for example print something:
Code: [Select]
if { echo -- Setting hostname }
ifelse { test -s /etc/hostname } {
...
}
if { echo -- No (or empty) /etc/hostname file }

Re: First Impressions

Reply #9
Yup, that would explain the error indeed. Thanks for looking at this. Hopefully I can find some time to cleanup the s6-scripts stuff soon.

Re: First Impressions

Reply #10
@Old Greybeard: I added fuse-s6 to the gremlins. I don't really use any fuse stuff, so I'm not sure if it works so if you test it on your setup that would be great.

I still haven't decided on how to handle netmount yet. It would be a good feature for sure, but I would need to come up with a good, clean way to check if any network daemon has started in a generic way (preferably with s6's dependencies file of course).

Re: First Impressions

Reply #11
@Old Greybeard: I added fuse-s6 to the gremlins. I don't really use any fuse stuff, so I'm not sure if it works so if you test it on your setup that would be great.
Many thanks for producing 'fuse-s6' - it appears to be working as expected.

I still haven't decided on how to handle netmount yet. It would be a good feature for sure, but I would need to come up with a good, clean way to check if any network daemon has started in a generic way (preferably with s6's dependencies file of course).
As for netmount, don't worry to much about doing this (unless someone else requests it, of course).

Re: First Impressions

Reply #12
Many thanks for producing 'fuse-s6' - it appears to be working as expected.


Awesome, I just moved it to the world repo.

Quote
As for netmount, don't worry to much about doing this (unless someone else requests it, of course).

I kind of want this feature myself (it could be useful in a few ways). We'll see.