The back-up obsession
Since a few years, I grew this rampant idea that I need to be independent from my laptop. My software, my work-environement, should be completly independent from my current hardware. Concretely, the scenario I envision is the following. I set my laptop on fire, violently smash it with a hammer and throw it out the window — voluntarily, or involuntarily. Then I buy a new one, type some command, a password, and 30 minutes later I am in front of my usual environment.
Basically, I want a backup solution. For all of my data, this is plain simple. I use gitlab for my development projects, and some cloud provider for the rest of my documents. But in the previous scenario, I specifically said “environment”. I want to be able restore the state my machine was. That includes the program I installed, the configurations I did, the themes I choose, and so on … OSX provides an elegant tool for this purpose : Time Machine. And there is a bunch of alternatives based on rsync, or equivalent.
And there enters my paranoia, along with my perfectionism.
I don’t want to store the state my machine is in as a blob. Rather, I would like to meticulously describe this state manually, and then generate this blob automatically. There are several reason for this.
I like to keep my machine dry clean ; sterile clean even. Knowing that some file — malware or not — could somehow persist in the backups and stay undetected, is simply unbearable. But paradoxically, I am always making a mess by testing new packages, starting new projects, dropping files at random places. I can’t help it.
I have several machines. Installing and configuring each one individually is a waste of time, and undesirable redundancy. I use the same tools most of the time, so I should just install them once, and be done with it. When I change my configuration, I would like to do it only once, and not replicate it on hundreds of machines.
I have a very selective memory. I never remember how I installed stuff. So I need to write it down, but never actually do it, because “Meh, I will remember it this time”. So, it would be amazing if the description of the installation process itself could be used to actually run the installation. Oh wait … isn’t that precisely the point of automation ?
With these requirements in mind, I organized my systems to be as close as possible of my dream scenario. I came up with a backup system which I currently use on my machines. I called it cellar. I describe below the how-tos.
Cellar is roughly composed of 2 parts. The first part contains the description of the states my machines should be. And the second contains the deployement scripts to put an empty machine in the desired state. The following describes briefly the first of these two parts. The second will be described in a following article.
At some point, I followed the trend, and put my dotfiles on github. I even wrote some scripts to be able to precisely deploy specific dotfiles on different machines, depending on their needs.
And then, I wanted to backup not only my dotfiles, but some of my
/etc, and the program I installed, and everything.
I switch to Salt.
Salt is described as a way to maintain consistency across multiple machines. But what was interesting at the time, was the ability to describe the states machine needs to be in, and not only the commands or recipes to execute. It is about idempotence.
If your commands are idempotent, they can be executed many times, and alaways result in the same outcome. For example, installing a package is somehow idempotent — somehow, because we all now that reinstalling a package can sometime fix some bugs. You can reinstall a package many times, and it should always result in the same outcome : the package being installed. But installing a package might take time. For some commands, idempotency is just a by-product. They are not built to take advantage of this idempotence, and save time if the outcome is already here. Salt brings this idempotency outside of the commands, and its nice.
One thing leading to another, I now have a quite complex hierarchies of state descriptions. To allow others to reuse cellar, I organized the states in three different sections :
The high-school chemists among you might remember that salt, is actually NaCl : Sodium and Chloride.
Credentials contains, well, my credentials. Everything I don't want everybody to read. They are stored in an encrypted git repo.
Chloride contains very general salt helpers.
Mostly formulas and macros that everyone could use and contribute to when using cellar.
The macros help to ease the description of states.
For exemple, there is a
dotfile macro to help put in my
/home a symbolic link to its corresponding file in Sodium.
And the formulas help to describe common setups, like Gnome.
A more comprehensive and technical description of Chloride is in the readme).
Sodium contains my specific salt sates, and machine descriptions.
Each machine is described as a list of roles in a YAML file, to condition the application of states.
For example, the
desktop role precises that
gnome and all the graphical interface stuff should apply to this machine.
States are grouped themes, each one in a folder, with an
init.sls file to describe the state, along with all the necessary files.
For example, in my
git-themed state, there are the
.gitconfig and the
.gitignore along with the
init.sls to specify that these files are dotfiles to symlink in my
Machine descriptions also allow to filter states for specific hardware description.
For example, the
macbook-pro-themed state specifies that a specific wireless drivers should be installed, and that the cmd and ctrl keys should be switched in my keyboard layout.
A little trick
When using salt, it is necessary to describe precisely the hierarchy of the states.
You have a
top.sls file, which points to all the states somehow.
I found it cumbersome to modify this file each time I added a new state.
To simplify the process of adding or removing states, I kind of tricked salt to include all the folders in the sodium states.
top.sls file is in Chloride, but point to the states in Sodium)
End-result, instead of a top file, the file hierarchy in the Sodium states describes my states.
Safe in the cloud
With all the states described in Sodium, and pushed to the cloud, I can now safely put my laptop on fire, as long as I keep access to my credentials.