Software. Dotfiles. System configuration files. Secrets like private keys.
All of these are required when setting up a computer.
What’s the problem with doing it manually every time?
- It is easy to forget an essential piece of setup.
- Its hard to remember how exactly you set up some tool years ago.
- Personal scripts always seem to break when you need them most, often because of setup issues/changes.
Having a declarative, automated setup gives you confidence to automate more of your work. It gives you a firm foundation to build upon.
Currently, this tool is heavily work-in-progress, but the eventual goal is:
- a static(ish) executable precompiled for relevant
systems, that is downloadable to a new workstation for initial setup
- Linux executables will be fully static.
- MacOS will have everything static besides the required system libraries.
- Tool is written in haskell, though that should not matter to a potential user.
- has various “properties”, expects a yaml file that declares the expected workstation configuration.
Here is an example of a simple config file. It shows roughly how I have my system set up currently
workstations:
- name: "aeglos"
properties:
- type: GitHomeDir
params:
gitDir: .git-dir
remoteUrl: "git@github.com:joelmccracken/dotfiles.git"
branch: master
- type: NixDaemon
params:
interactive: False
nixConf: |
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=
substituters = https://cache.nixos.org https://cache.iog.io
experimental-features = nix-command flakes
trusted-users = root joelmccracken runner
build-users-group = nixbld
- type: HomeManager
params:
dir: "~/.config/funstation/nix"
- type: HomebrewBundle
params:
brewfile: "~/.config/funstation/Brewfile"
- type: BitwardenSecrets
params:
syncIntervalDays: 7This property logs in with a Bitwarden personal API key, and expects three files to exist before it runs:
| file | where it comes from |
|---|---|
~/secrets/bw_client_id | web vault, Account Settings -> Security -> Keys -> View API Key |
~/secrets/bw_client_secret | same place |
~/secrets/bw_master_pass | your master password |
All three should be mode 0600.
The master password is still required: bw login --apikey authenticates the
client, but it does not unlock the vault, so bw unlock still needs the
password to produce a session token.
The client id and secret are passed to bw through the environment rather than
on the command line, so they do not show up in ps.
~/secrets/bw_email is no longer read and can be deleted.
Each secret written from the vault is set to mode 700. To use a different
mode, set mode (quoted, so YAML keeps it a string):
- type: BitwardenSecrets
params:
syncIntervalDays: 7
mode: "600"Each sync records the files it wrote. On later runs, if any of them is missing
or has a different mode, the property runs again, even if the last sync is
still within syncIntervalDays.
- download the appropriate executable from releases for your system.
- create your `config.yaml`, or download your preexisting file.
on your system, run the bootstrap:
fun --config config.yaml --workstation $YOUR_SYSTEM_NAME bootstrapTo rebuild and activate just the home-manager configuration, without running a full bootstrap:
fun home-manager rebuildThis builds and runs the activation script for the HomeManager property
for the current workstation.
For reference, the output executed by this property:
cd the/nix/dir; nix run ".#homeConfigurations.\"${USER}@${WORKSTATION_NAME}\".activationPackage"Bootstrap only re-syncs Bitwarden secrets once syncIntervalDays have passed.
To sync them now, regardless of when they were last synced:
fun bitwarden-secrets syncThis runs the BitwardenSecrets property for the current workstation, and
resets its last-sync timestamp.
To run brew bundle install for the configured Brewfile, without running a
full bootstrap:
fun brew-bundle installThis runs the brew-bundle property for the current workstation, even when
brew bundle check reports the Brewfile is already satisfied.
To start a shell with GIT_DIR set to the GitHomeDir property’s git dir, so
plain git commands operate on your home dir repo:
fun git-home-dir shThis runs $SHELL (or /bin/sh if unset); exit the shell to return.
run with
cabal build && cabal run -- fun --config ./config.yaml --workstation glamdring bootstraprun main test suite with
cabal testto run the “scratch” suite:
cabal test -f scratch funstation-scratchbuild the nix package (e.g. build the version thats statically linked)
nix build # output will be at `result/bin/fun`
test the build in a VM (assumes setup handled, TODO transfer setup process from notes.org)
bash test/vm/run-in-vm.shcan build possibly with other cabal tooling, not how I normally do it:
cabal build funstation-test --allow-newer