Dear Guix'ers,I'd like to share my "update everything" script, because it could be useful to you, and maybe you have suggestions to improve it.
First the body of the script, then the context, line-by-line explanation, and finally some possible improvements. The script:
guix time-machine -- describe --format=channels > chans.scm guix time-machine --channels=chans.scm -- build -m manifest-all.scm guix time-machine --channels=chans.scm -- system build config.scm sudo guix time-machine -C chans.scm -- system reconfigure config.scm guix time-machine --channels=chans.scm -- package -m manifest.scm guix pull --channels=chans.scmContext: The problem I was trying to solve is that there are three things that have generations in Guix, and I would like to be able to update them together. That is:
- guix itself, updated with `guix pull`, - The system, updated with `guix system reconfigure`, and - My profile, updated with `guix package -m`.My previous workflow was just doing `guix pull` and then `guix system reconfigure`. The problem with that was that the reconfigure could take very long, and during that time I could basically not do much else with guix. E.g. I couldn't install packages in my profile, because they would conflict with existing packages, or would require the same long builds to finish first.
Of course substitutes help solve this problem. But I consider it a selling point of Guix that we don't have to rely on binaries provided by machines we don't control. This script makes me see the availability of substitutes as a 'happy surprise', instead of the their non-existence as a frustrating experience. Because the update is atomic: either all three (guix, system, profile) update, or none of them.
Line by line explanation: 1. guix time-machine -- describe --format=channels > chans.scmUse guix time-machine to get a most up-to-date channels file. time-machine can be used to 'travel' back in time as well as forward, and the default is to take the latest commit. If this step fails, something is wrong with Guix itself, which happens very rarely.
2. guix time-machine --channels=chans.scm -- build -m manifest-all.scmBuild all packages I'm interested in, even ones I don't use regularly, so there are no surprises. If this fails, I can decide to fix those packages, or just comment them out. This stage can take hours if there are no substitutes, but that is fine, because it is running in the background. And I can just interrupt it.
3. guix time-machine --channels=chans.scm -- system build config.scmBuild my system configuration. This should be fast and should not fail, with all the packages already build. But who knows! I recently added a hurd-vm and one of those package broke, which I had not in my large manifest file.
Everything should be build at this point. Now it is time to actually 'activate' everything. Let's do that in the reverse order (doesn't really matter).
4. sudo guix time-machine -C chans.scm -- system reconfigure config.scm Actually update the system. 5. guix time-machine --channels=chans.scm -- package -m manifest.scmInstall all my personal packages for my main profile; they should already be built.
6. guix pull --channels=chans.scmUpdate the local guix installation to the version that was used to build all the packages and reconfigure the system.
That's it! I even started running the script back to back just for funsies. Two extra details about the actual bash script I use:1) at the start I set `set -x` so the script stops when one of the steps fail. That's the whole point! Technically things are still inconsistent if one of the last three steps fail, but that has not happened yet. And it would be easy to resolve by rolling back.
2) The 'sudo' command above is not actually in the script. Instead I run the whole script with 'sudo', and have every other line prefixed with the opposite:
sudo -u "${SUDO_USER}"
which runs those lines as my normal user.
Some possible improvements I thought off:
1) Add a step in between 1 and 2 to check for substitutes of certain
packages (linux-libre, qtbase, qtwebengine, icecat), so the script bails
if those are not available, e.g.
guix time-machine -C chans.scm weather manifest-must-substitute.scm2) Put all of the above in a loop that iterates backwards through the Guix commits until it finds one where it succeeds. But actually I don't mind anymore. I can just wait or fix things and run the script again.
Cheers, and major thanks to everyone who makes Guix possible! It is just amazing to me that we can do things like this now. By design.
Hugo
