Skip to main content
Topic: How does s6 switch databases while keeping bundles (Read 920 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How does s6 switch databases while keeping bundles

Alright so when making my own local user s6 live, what if i needed to make a new service? Put it in my database-source directory, compile the database with s6-rc-compile ~/s6/newdb ~/s6/database-source and s6-rc-update ~/s6/newdb, right? Exept that now my default bundle is gone.
How could i make my bundles permanent? Is there a way to remember the bundles from a database and pass them to the new one? How do the artix system-wide s6 databases do it?

Re: How does s6 switch databases while keeping bundles

Reply #1
Ah yes you just discovered a not-so-fun part of s6-rc's behavior. There's no way to preserve live bundles from the previous database. When you make a new database, there won't be any live bundles in it. Artix preserves bundles by using a bash script (/usr/share/libalpm/scripts/s6-rc-db-hook) to get the contents of any bundles in the previous database and adding it to the new one. I could potentially look into making the script more generic/flexible so you could use it for your use case (ex. s6-rc-bundle-update is actually a script but you can use it for anything). At the moment it's hardcoded to look at /etc/s6/rc/compiled and compile based on the /etc/s6/sv path.

Re: How does s6 switch databases while keeping bundles

Reply #2
Alright so i modified the script a bit for my use
Code: [Select]
#!/bin/bash
if [ -e "$HOME/s6/compiled" ]; then
    old_bundles=$(s6-rc-db -l $HOME/s6/live -c $HOME/s6/compiled list bundles)
    len=0
    for i in $old_bundles; do
        contents[$len]=$(s6-rc-db -l $HOME/s6/live -c $HOME/s6/compiled contents $i)
        len=$(($len + 1))
    done
fi

timestamp=$(date +%s)
ret=$(s6-rc-compile $HOME/s6/compiled-$timestamp $HOME/s6/sv)
if [[ "$?" != 0 ]]; then
    echo "Error compiling database. Please double check the $HOME/s6/sv directories. Exiting."
    exit 1
fi
if [ -e "$HOME/s6/live" ]; then
    s6-rc-update -l $HOME/s6/live $HOME/s6/compiled-$timestamp
fi
if [ -d "$HOME/s6/compiled" ]; then
    ln -sf $HOME/s6/compiled-$timestamp $HOME/s6/compiled/compiled && mv -f $HOME/s6/compiled/compiled $HOME/s6
else
    ln -sf $HOME/s6/compiled-$timestamp $HOME/s6/compiled
fi

new_bundles=$(s6-rc-db -l $HOME/s6/live -c $HOME/s6/compiled list bundles)
all_services=$(s6-rc-db -l $HOME/s6/live -c $HOME/s6/compiled list all)

a_newbundle() {
    for j in $new_bundles; do
        if [ $j == $1 ]; then
            return 0
        fi
    done
    return 1
}

service_exists() {
    for k in $all_services; do
        if [ $k == $1 ]; then
            return 0
        fi
    done
    return 1
}

in_newbundle() {
    bundle_contents=$(s6-rc-db l $HOME/s6/live -c $HOME/s6/compiled contents $1)
    for l in $bundle_contents; do
        if [ $l == $2 ]; then
            return 0
        fi
    done
    return 1
}

if test -n "$old_bundles"; then
    len=0
    for m in $old_bundles; do
        old_contents=${contents[$len]}
        a_newbundle $m
        ret=$?
        for n in $old_contents; do
            service_exists $n
            ret2=$?
            if test $ret -eq 1; then
                if test $ret2 -eq 0; then
                    new_contents=$new_contents" "$n
                fi
            else
                if test $ret2 -eq 0; then
                    in_newbundle $m $n
                    ret3=$?
                    if test $ret3 -eq 1; then
                        s6-rc-bundle-update -c $HOME/s6/compiled add $m $n
                    fi
                fi
            fi
        done
        if test -n "$new_contents"; then
            s6-rc-bundle -l $HOME/s6/live -c $HOME/s6/compiled add $m $new_contents
        fi
        new_contents=""
        len=$(($len + 1))
    done
fi
echo "Switched to a new database. Feel free to remove any old unwanted/unneeded database directories in $HOME/s6."
Works very fine. Thanks.

Re: How does s6 switch databases while keeping bundles

Reply #3
It would be cool to actually make that POSIX, but it uses arrays (aren't POSIX) which makes it trickier unfortunately.

Re: How does s6 switch databases while keeping bundles

Reply #4
Sorry if this is an necro.

Today i installed Artix-xfce-s6 on my notebook, cause i want to use s6 on my homeserver, to get it to know.
But trying to update, post-installation-hooks gets stuck on s6-rc-db-update-hook while trying to update s6-scripts. If ctrl+c-ing, the next reboot fails to boot, complaining about missing service files.
Investigating that further, the part with s6-rc-update /etc/s6/rc/compiled-$timestamp hangs, providing no output even with options -n (dry run) or -v 3 (debug-level). Strangely, the tool fails immediately with option -t (timeout if it fails), even if set to high values. Error message is
Quote
s6-rc-update: fatal: unable to take lock on /run/s6-rc and /run/s6-rc/compiled: No such file or directory
with errorlevel 111: system call failed from the docs.

But i don't understand s6 enough yet to fix that. Can anyone help?

Re: How does s6 switch databases while keeping bundles

Reply #5
Why didn't you make a new topic? This has nothing to do with the thread.

s6-rc-update: fatal: unable to take lock on /run/s6-rc and /run/s6-rc/compiled: No such file or directory

Well this error message means exactly what it says. For whatever reason, there is no /run/s6-rc or /run/s6-rc/compiled on your machine. That is, of course, bad as both things are created on boot with s6-rc launches. If you are in a live iso environment chrooted into a root partition, those run directories will, of course, not exist but the hook deliberately skips doing the live update in that case. Without the run directories, you will not be able to properly do anything with the current live database. Not sure how you got into this state. It's something that shouldn't happen.

Not sure what you mean by "reboot fails" but it sounds like you'll have to fix your s6-rc database manually. Artix reads s6-rc databases from the /etc/s6/rc directory so it would be something like this.

Code: [Select]
# timestamp=$(date +%s)
# s6-rc-compile /etc/s6/rc/compiled-$timestamp /etc/s6/sv  #if this step fails, you need to fix your service definitions
# ln -sf /etc/s6/rc/compiled-$timestamp /etc/s6/rc/compiled/compiled && mv -f /etc/s6/rc/compiled/compiled /etc/s6/rc

Give it a reboot after that and it should be OK. You'll have to readd any bundles to default again afterwards.

Re: How does s6 switch databases while keeping bundles

Reply #6
Quote
Why didn't you make a new topic? This has nothing to do with the thread.
Ah, sorry, thought cause its about s6-rc-db-update-hook too.

No, that system was installed via calamares from the newest artix-xfce-s6 iso.
So trying to update s6-scripts package, post-installation-hook 's6-rc-db-update-hook' gets stuck.
That's why i looked closer, with the result that the line 's6-rc-update /etc/s6/rc/compiled-$timestamp' hangs, with no output.
Though adding the opton '-t 10000' executes immediately (it should wait 10000 milliseconds), with aforementioned error message. Folder /run/s6-rc is present, but not /run/s6-rc/compiled. The folder /etc/s6/rc/compiled-$timestamp gets created with the script.

Thanks for the tip, will try it.