by Joshua Branson — June 29, 2021
Table of Contents
TODO Time to upgrade your computer
tl;dr Re-installing my OS to my liking sure takes a while. It took me 9 hours (and counting). Can you beat that time? Let's be real. Of course you can! :)
The strategy described below is perhaps a bit silly. This strategy is how you would recreate your OS settings from your config files. It may be easier to occasionally re-create your entire disk image and save to a file or usb stick. The below example taken from the guix manual, shows you how to boot your GNU Guix system image from a virtual machine.
image=$(guix system image --image-type=qcow2 \ gnu/system/examples/lightweight-desktop.tmpl) cp $image /tmp/my-image.qcow2 chmod +w /tmp/my-image.qcow2 qemu-system-x86_64 -enable-kvm -hda /tmp/my-image.qcow2 -m 1000 \ -bios $(guix build ovmf)/share/firmware/ovmf_x64.bin
It is probably possible to modify the commands below to create a boot-able usb stick that has your exact OS with all your settings, users, and packages. With that usb stick, you should somehow be able to boot it and copy it onto your new computer.
I read a blog post entitled what if you lost your computer right now? from a guix developer some time ago. It describes a fun thought experiment, namely how difficult would it be to copy your settings from your previous computer to your new one? How long would this process take you? Well today I updated my os-boot-ed Thinkpad T400 laptop from an HDD to an SSD. Here are the settings that I had to manually copy over to the SSD.
I first tried to set up disc encryption via guix's installer. The install went ok, but booting it up did not work. Grub would not decrypt the drive. That's when I realized that the keyboard layout that I typed in the original password was dvorak, but osboot was using a qwerty layout. So then I re-installed GNU Guix and specified an encrypted password for /dev/sda3 to be only numbers. Grub still did not decrypt the partition…Please note that I am using os-boot, which means that I am using not using the grub that is installed via Guix. Instead osboot already includes a grub that is flashed to my rom image. So perhaps that image is a bit dated.
Anyway, then I installed Guix System without any encryption. Now I could boot into the system. Oh, and I installed Guix System using this mostly barebones config. In my experience, if you try to install Guix System with a desktop environment, at some point your internet will flake out, fail to download some dependency, and you will have to start over. So install bare bones first. :)
;; This is an operating system configuration generated ;; by the graphical installer. (use-modules (gnu)) (use-service-modules desktop networking ssh xorg) (operating-system (locale "en_US.utf8") (timezone "America/Indiana/Indianapolis") (keyboard-layout (keyboard-layout "us" "dvorak")) (host-name "dobby") (users (cons* (user-account (name "joshua") (comment "Joshua Branson") (group "users") (home-directory "/home/joshua") (supplementary-groups '("wheel" "netdev" "audio" "video"))) %base-user-accounts)) (packages (append (list (specification->package "nss-certs")) %base-packages)) (services (append (list (service network-manager-service-type) (service wpa-supplicant-service-type)) %base-services)) (bootloader (bootloader-configuration (bootloader grub-bootloader) (target "/dev/sda") (keyboard-layout keyboard-layout))) (swap-devices (list (uuid "d021373e-2399-49ea-bc92-6134f2b2c94f"))) (file-systems (cons* (file-system (mount-point "/") (device (uuid "4bf80701-e54e-44eb-817f-b2f52f5af80e" 'ext4)) (type "ext4")) %base-file-systems)))
Installing packages for the user profile: joshua
Now that I could boot my configuration (into a tty console), I started to go about installing my previous packages for the user "joshua", which is me! Obviously. :D
joshua@dobby $ git clone https://notabug.org/jbranso/prog $ boring output blah blah blah $ done joshua@dobby $ joshua@dobby $ cd prog; joshua@dobby $ mkdir -p gnu/guix; joshua@dobby $ cd gnu/guix; joshua@dobby $ git clone https://notabug.org/jbranso/guix-config $ boring output blah blah blah $ done joshua@dobby $ joshua@dobby $ guix package -m manifest.scm joshua@dobby $ error: jmacs package not found
Error: package jmacs cannot be found
Whoops…I forgot. jmacs is my custom emacs package. Don't get too excited. It pretty much only works for me, and if you try to use it, you will curse my name. Create specific files for reasons that only make sense to me. Trust me, you'd have to add in my custom channel, fail to install my jmacs, etc. You have been warned.
So this is a minor annoyance. As far as I know, GNU Guix does
not let you specify your channel in
config.scm. Instead you
specify your custom channels in
Perhaps this is a strategic choice. As in, please push your code
upstream that way you do NOT need to have a private repo of code.
Anyway, for now, I will delete my jmacs package in the manifest file. Take 2:
nano manifest.scm # delete my jmacs line guix package -m manifest.scm
For some reason the above command
guix package -m manifest.scm,
failed the first time I tried it. I guess my manifest file is
sort of big:
Anyway, take 3:
guix package -m manifest.scm
This time it worked! Sweetness! I now have the previous file in my profile.
Setting up Sway's config files
Now I need to copy my sway configuration into
mkdir ~/.config/sway cp ./config ~/.config/sway/ cp ./status.sh ~/.config/sway/
Refreshing my fonts
Due to a long standing bug in GNU Guix, fontconfig's cache is not refreshed automatically. The below command makes my newly installed fonts available, which are needed for my sway status bar.
Reconfiguring my system to use my services
Originally I installed GNU Guix from a bare-bones.scm file. Now, I can reconfigure my system to set up my services, including a locally running dovecot server, nginx, and mcron, etc. Here is my current sway.scm config file.
sudo guix system reconfigure sway.scm
Error: no code for module secret
Whoops. That's right. I've got some bit of code in my config that I did not share with the world…That means that my current config will not work…A few deletions to my config later…
sudo guix system reconfigure sway.scm
Error filesystem uuid "0542cf20-9f62-49cf-992f-54a75186f2b2" not found.
Whoops. I can't use the uuid from the HHD. I need to get the UUID from the SSD.
In order to avoid having this minor annoyance in the future, I could label my partitions. When doing the manual install I could do something like:
sudo fdisk /dev/sda; # create a new partition table either msdos or gpt # gpt is probably what you want for newer hardware g # add a new partition # it's just much easier to set it up to use two partitions # 1 for the EFI partition and 2 for the / (root) filesystem. n n # write to the disk save and exit w parted /dev/sda set 1 esp on mkfs.fat -F32 -L my-EFI /dev/sda1 mkfs.ext4 -L my-root /dev/sda2 mount LABEL=my-root /mnt mkdir -p /mnt/boot/efi mount LABEL=my-EFI /mnt/boot/efi
Then I could use this bit to configure my partitions.
(filesystems (list (file-system (mount-point "/boot/efi") (type "vfat") (device (file-system-label "my-EFI"))) (file-system (mount-point "/") (type "ext4") (device (file-system-label "my-root")))))
A quick copy from my local
sudo guix system reconfigure sway.scm
This surprisingly was really uneventful. Most of the services
did not run immediately. For instance dovecot did not run,
because I do not have the
~/.mbsyncrc file, which means that I
don't have any mail to serve. Surprisingly nginx did run! Even
though some of the spots where I told it to serve html files do
not exist yet on the filesystem. But I can actually view my
locally running website (local.gnucode.me) via opening up icecat
and viewing http://local.propernaming.org. Which is really
weird. Because it should be showing my local propernaming.org
site, but instead it is showing my gnucode.me site. Weird.
Apparently I need to tweak my nginx service.
Setting up jmacs
I first need to download my emacs config.
git clone https://notabug.org/jbranso/emacs.d ~/.config/emacs rm -r ~/.emacs.d
Now I can guix pull and install jmacs.
guix pull guix package -i jmacs -sha256 hash mismatch for /gnu/store/8i2n33a06lfbpxr3jmxj6mhdvsp5fnvl-aggressive-fill-paragraph-20180910.816.el: expected hash: 12fi9r1wfzv8iqyzrnh82lq6793i9gxq52hk54acxskax29kmn30 actual hash: 1q1xpz3rfsm7402d5k32lkr2vfvimwxf19p1xf3jslqdw8c0k06a
Hmmm, emacs-aggressive-fill-paragraph is not building…I don't think that I actually use aggressive fill paragraph much…So I think that I will NOT use that.
So I copied my .bash<sub>profile</sub> from the old machine.
The important bit is where I set
environmental variable. It might actually be a better idea to
set that variable in ~/.profile, because that then those
settings would be saved for any shell.
guix pull guix package -i jmacs
build of /gnu/store/9m73xmni7ixvmlyksj74fid73ij9sn0b-ledger-mode-20200530.1710.tar.drv failed View build log at '/var/log/guix/drvs/9m/73xmni7ixvmlyksj74fid73ij9sn0b-ledger-mode-20200530.1710.tar.drv.bz2'.
Oh, I guess I haven't actually used ledger mode in emacs in a
while…let's disable that as well. A few more local edits in
guix package -i jmacs
I do find it a little interesting that it is compiling Emacs
from source. I'm not entirely certain why this is necessary.
jmacs.scm is not entirely complicated. Here is an excerpt:
grep -A 15 '(define-public jmacs' /home/joshua/prog/gnu/guix/guix-packages/gnu/packages/jmacs.scm
I'm essentially just setting up Emacs to use guix as the package manager for emacs packages.
Surprisingly, jmacs worked for me after I got it to install. I did not expect that to work out so well. I did have one tiny issue with autosaves. I just needed to create this directory:
Setting up my hosts file
I have a 10 or lines in my /etc/hosts file, so that I can run my static websites locally. That way I can make local changes, before I upload them to the actual server. I've got most of these settings in my guix-config.scm, but some of them are "secret".
re-installing firefox via flatpak
And re-settung up firefox sync only took about 5 minutes.
flatpak install flathub org.mozilla.firefox
Setting up application specific settings
This following would not be all that necessary if I set up guix home or the slightly more "perfect" guix home manager. Those two tools let you set up a user profile that declares all of your system state. The command for it might look like:
guix home reconfigure home.scm
At the moment, I am not using these tools. It also appears that guix home will be merged into GNU Guix soon-ish. I would recommend you use guix home, if you want to try it.
Setting up isync.
Isync is what the cool kids are doing to set up local maildirs, which is how you can search for your email REALLY fast. Like the speed of thought fast. :)
isync's configuration file is found in
~/.mbsyncrc. Now this
file currently has the password for my email account. So I
cannot simply put this file in my
guix-config git repository.
Or perhaps I could I would just modify the password line to look
And then I would put .mbsyncrc into my .gitignore file. Any changes that I make to that file would not go in the repo.
But then I still have to figure out how to give isync my password for my email account. One possibility comes from the archlinux wiki (seriously, if you are ever configuring software, read the archlinux wiki first. It is hands down the best wiki out there to help you configure software! Beware though. Some webpages will tell you how to set up proprietary software).
# PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d ~/.mailpass.gpg"
Another option is to set up Gnome keyring, and to use the secret tool. The Archlinux wiki page about the gnome keyring would probably be helpful in setting this up. But again, I would have to continually re-store my secrets on every upgrade. I do not know if Gnome keyring has a way of securely storing my secrets in a git repository.
For now, I will just chose the lazy option. Just copying the
config from the archlinux wiki page and tweaking it for my needs.
~/.mbsyncrc now works for me.
mkdir -p ~/.mail/dismail mbsync -a
Setting up termite settings
My default terminal is termite, and I need to recreate the
terminal configuration file:
mkdir -p ~/.config/termite; nano -p ~/.config/termite/config # some edits later cat ~/.config/termite/config
re-setting up tootle
Tootle is a gtk application to access your mastodon account.
It's actually pretty awesome! It only took me 5 minutes to get
this re-setup. The file in
~/.config/com.github.bleakgrey.tootle/accounts.json includes a
secret API token. Again, I cannot put that in my guix-config.
Though I think that guix-home has a way to get around this…I hope.
re-setting up linphone
This first bit is authentication. That takes 5 minutes.
The trick bit is merging my contacts. I use jmp.chat, which is an awesome cellular service. For texting, jmp.chat uses XMPP. Which is awesome, because my contacts are saved on the server.
BUT linphone, stores all the contacts locally…So I need to
find a way to automate all of my contacts when I upgrade. For
now, it was pretty easy to just save my
from my hard drive to a usb, and copy the linphone directory over.
re-setting up my wifi connections
Right now I use sway, and I can't quite get nm-applet to work. So I set up wifi connections via
sudo nmcli dev wifi connect "<WIFI Name>" password <password> [name "<name>"]
I've got three or so wifi networks that I use:
My parents wifi
-public library wifi
setting up my git username
git config --global user.name "Joshua Branson" git config --global user.email "jbranso AT gnucode.me"
I actually don't know where git stores these settings, because
I do not see a
So Emacs uses
~/.authinfo to save my passwords for various
machines. For example to use my dismail email account the lines
machine imap.dismail.de login firstname.lastname@example.org port imaps password someCoolPassword machine smtp.dismail.de login email@example.com port 587 password someCoolPassword
Of course this password cannot be stored in a git repository, or anyone could read my email. So I have to copy this file directly from the old machine.
Please note that Emacs recommends that you use
to securely encrypt your passwords. For the life of me, I cannot
figure out how to reliably get this to work. gpg is hard to
use. I also lose my gpg key all the time, and then I cannot
.authinfo.gpg file. I also have a hard time setting
up emacs to use
Whew! If you've read this far, then you are an awesome human being! As you can see, many of up carry a lot of system state in your operating systems. I hope this convinces you that we should store this state, so that it can be reliable reproduced without too much hassle!
Also, as a fun aside, Guix System sure takes up a lot of disk
space. My SSD is either 220 or 240 GB. My
originally had 219 GB of free space on it.
sudo fdisk --list /dev/sda | grep -e '240|sda3'
BUT after installing GNU Guix System, and setting up sway and a
good amount of applications, 10% of
/ is already being used!
df -h | grep -B 1 sda
/gnu/ takes up 17GB!
sudo du -hc --max-depth=1 /gnu/
Now I've reconfigured a few times. How much of that
/gnu/store/ can be
deleted once I have deleted some system generations and perhaps some
The below suggests that I have three system generations. Let's reboot (to make sure that the current generation works), and then delete those old generations.
guix system list-generations | grep Generation Generation 3 Jun 22 2021 21:41:14 Generation 4 Jun 27 2021 01:36:47 (current)
Rebooting worked, now let's try deleting some old generations.
sudo guix system delete-generations
deleting /var/guix/profiles/system-1-link deleting /var/guix/profiles/system-2-link building /gnu/store/gdbm5lvi901ys1dplgjpw144fymr9di5-grub.cfg.drv... building /gnu/store/zx89ajlx901m46jk48pql3zlb25zsdsa-install-bootloader.scm.drv...
The same is true for my package generations:
guix package --list-generations | grep Generation Generation 5 Jun 23 2021 02:31:59 (current) guix package --delete-generations
New let's go and delete some garbage!
guix gc deleting `/gnu/store/trash' deleting unused links... note: currently hard linking saves 1386.33 MiB guix gc: freed 13,245.99083 MiBs
Now how much does space does
/gnu/ take up now?
sudo du -hc --max-depth=1 /gnu/
11G /gnu/store 11G /gnu/ 11G total
So it looks like we deleted 6 GB of cruft! That's not too bad!