Migrating to an SSD — GNUcode.me

Migrating to an SSD

by Joshua Branson — June 29, 2021

Table of Contents

  1. Time to upgrade your computer

    1. Introduction

    2. Installing packages for the user profile: joshua

    3. Setting up Sway's config files

    4. Refreshing my fonts

    5. Reconfiguring my system to use my services

    6. Setting up jmacs

    7. Setting up my hosts file

    8. re-installing firefox via flatpak

    9. Setting up application specific settings

      1. Setting up isync.
      2. Setting up termite settings
      3. re-setting up tootle
      4. re-setting up linphone
      5. re-setting up my wifi connections
      6. setting up my git username
    10. copying ~./authinfo

    11. Conclusion

<a id="orgf6d0c49"></a>

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 \
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.

<a id="org0396ea4"></a>


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)

  (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")
                    '("wheel" "netdev" "audio" "video")))
      (list (specification->package "nss-certs"))
      (list (service network-manager-service-type)
            (service wpa-supplicant-service-type))
      (bootloader grub-bootloader)
      (target "/dev/sda")
      (keyboard-layout keyboard-layout)))
    (list (uuid "d021373e-2399-49ea-bc92-6134f2b2c94f")))
    (cons* (file-system
            (mount-point "/")
               (uuid "4bf80701-e54e-44eb-817f-b2f52f5af80e"
             (type "ext4"))

<a id="org3c88524"></a>

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 ~/.config/guix/channels.scm. 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:

ls manifest.scm

Anyway, take 3:

guix package -m manifest.scm

This time it worked! Sweetness! I now have the previous file in my profile.

<a id="org227238d"></a>

Setting up Sway's config files

Now I need to copy my sway configuration into ~/.config/sway.

mkdir ~/.config/sway
cp ./config ~/.config/sway/
cp ./status.sh ~/.config/sway/

<a id="org1bb21a0"></a>

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.

fc-cache -fv

<a id="org135c8b8"></a>

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
# 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.
# write to the disk save and exit
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.

   (mount-point "/boot/efi")
   (type "vfat")
   (device (file-system-label "my-EFI")))
   (mount-point "/")
   (type "ext4")
   (device (file-system-label "my-root")))))

A quick copy from my local /etc/config.scm later:

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.

<a id="org66d6e9e"></a>

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.

While it is nice to set up jmacs via my custom channel. For development purposes, it's actually easier to set up GUIX_PACKAGE_PATH.

So I copied my .bash<sub>profile</sub> from the old machine.

cat ~/.bash_profile

The important bit is where I set GUIX_PACKAGE_PATH 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.

Take 2!

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 ~/gnu/guix/guix-packages/gnu/packages/jmacs.scm later…

Take 3!

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. My 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:

mkdir ~/.config/emacs/emacs-auto-saves

<a id="orgeb8ae8c"></a>

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".

<a id="orgd6b36d5"></a>

re-installing firefox via flatpak

And re-settung up firefox sync only took about 5 minutes.

flatpak install flathub org.mozilla.firefox

<a id="org6c5528f"></a>

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.

<a id="orgf4086d5"></a>

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 like:

password SomeReallyAwesomePassword

And then I would put .mbsyncrc into my .gitignore file. Any changes that I make to that file would not go in the repo.

It would probably be better to create a user service guix home or just a regular Guix System Service.

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. My ~/.mbsyncrc now works for me.

mkdir -p ~/.mail/dismail
mbsync -a

<a id="org9fa06cd"></a>

Setting up termite settings

My default terminal is termite, and I need to recreate the terminal configuration file: ~/.config/termite/config:

mkdir -p ~/.config/termite;
nano -p ~/.config/termite/config
# some edits later
cat ~/.config/termite/config


<a id="orgb693454"></a>

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.

<a id="orgea6efa5"></a>

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 ~/.config/ directory from my hard drive to a usb, and copy the linphone directory over.

<a id="orga2a283e"></a>

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

  • work wifi

  • home wifi

-public library wifi

<a id="org94e1897"></a>

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 ~/.config/git directory.

<a id="orga2d1f7d"></a>

copying ~./authinfo

So Emacs uses ~/.authinfo to save my passwords for various machines. For example to use my dismail email account the lines look like:

machine imap.dismail.de login jbranso@dismail.de port imaps password someCoolPassword
machine smtp.dismail.de login jbranso@dismail.de 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 ~/.authinfo.gpg 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 decrypt my .authinfo.gpg file. I also have a hard time setting up emacs to use ~/.authinfo.gpg.

Perhaps I should invest in a physical trusted platform module like the yubikey or librem-key. I've heard that makes gpg key management a little easier. But then I just cannot lose that physical key.

<a id="org94b5f0b"></a>


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 / partition 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

And /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 package generations?

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!