I suck at backing up. For once, I'd like to be able to download all my important stuff, run a single command, and have everything up and running. I've seen many dotfile management schemes, including dotfiles.sh and Mackup, but they all seem just a little bit over-engineered for my tastes. In general, I prefer the Stow method.
The only problem with using GNU Stow for this is that I can't really keep private files separate, and I certainly can't keep passwords out of files that demand to keep them alongside all the intersting settings that are worth sharing. To solve this, I will keep a single Stow package for all private files, and a CSV file containing key-vlaue pairs for all private strings, which be applied and reverted with a simple search-and-replace mechanism before each deployment and publication.
This text should describe what's important to me, and how it will be structured in a backup.
There are two categories of important things: public, and private.
I scribbled a mockup of the layout of my dotfiles on paper last night. It now looks something like this:
dotfiles/ emacs/ .emacs git/ .gitconfig ssh/ .ssh/ id_rsa.pub known_hosts private.tar.gz.gpg .gnupg/ ... .password-store/ calher/ matrix/ pass.gpg ... csh/ bluehome/ pass.gpg roaming-initiative/ pass.gpg sdf/ pass.gpg notabug/ pass.gpg calRedditFLOSSyourJS/ reddit/ pass.gpg CharlieBrown/ freenode/ pass.gpg freepost/ pass.gpg .ssh/ id_rsa substitutions.csv sha256sum password hash,base64 password cleartext 0693a3a41b7bda5568f205cc000bff5f3bf917f65535b721ae273b3a956ea0b5,UGFzc3dvcmQxCg==
Perhaps the most peculiar item in this listing is the file substitutions.csv. This is a list of corresponding strings for a search-and-replace program to use when adding or removing private information to otherwise public files. For example, if I wanted to put the passphrase Password1 in my .gitconfig, I would add the following line after the [sendemail] section.
smtppass = 0693a3a41b7bda5568f205cc000bff5f3bf917f65535b721ae273b3a956ea0b5
This would be put in the public copy of .gitconfig. After replacing all the strings and applying it to the running system, however, the same line would show the more legible passphrase, Password1.
smtppass = Password1
This should work with any file. I doubt many programs would need me to escape characters in passphrases.
The #deployment of the files should be as simple as cloning the repo, stowing the packages into the home directory where they belong, and replacing all the private strings mentioned in substitutions.csv.
git clone https://notabug.org/csh/dotfiles cd dotfiles stow tmux bash emacs git ssh gpg -d private.tar.gz.gpg tar -xvf private.tar.gz stow private private/expose-strings
expose-strings searches every file in the dotfiles/ directory for the first cell of a line in substitutions.csv, base64-decodes the second cell of a line in the file, and puts the result in place of every found instance of the contents of the first cell of a line.
hide-strings will undo all of this, returning the hashes to their original places. It will be run before every commit and upload. Hopefully, version control will not notice.
In order to do the #publishing of any new changes made in version control, and put them in public view on the Internet, we must ensure that private/ and private.tar.gz are erased so they do not get tracked or committed. In addition, hide-strings must be run so that passwords don't show up in public files either. Only then can changes be committed and pushed to version control.
An example shell script might look like the following.
#!/bin/sh cd ~/dotfiles/ # Disconnect private/ rm private.tar.gz private.tar.gz.gpg stow -d private # Update private/ tar -cvzf private.tar.gz private gpg -c private.tar.gz # Purge everything ./private/hide-strings rm -r private/ private.tar.gz # Push # No git commit; do manually in Emacs VC/Bash beforehand git push