# Top-level wrapper script for calling per-machine provisioners. # # Given ops.machines."edge01.waw.bgp.wtf".config.passthru.hscloud.provision, # this script allows to run it by doing: # $ $(nix-build -A ops.provision) edge01.waw.bgp.wtf # Or, to first list all available machines by doing: # $ $(nix-build -A ops.provision) # # The main logic of the provisioner script is in machines.nix. { hscloud, pkgs, lib, ... }: with lib; with builtins; let # All machines from ops.machines, keyed by FQDN. machines = filterAttrs (n: _: n != "__readTree") hscloud.ops.machines; # Machines' provisioner scripts, keyed by machine FQDN. machineProvisioners = mapAttrs (_: v: v.config.passthru.hscloud.provision) machines; # List of machine FQDNs. machineNames = attrNames machines; # User-friendly list of machines by FQDN. machineList = concatStringsSep "\n" (map (name: " - ${name}") machineNames); # Derivation containing bin/provision-FQDN symlinks to machines' provisioners. forest = pkgs.linkFarm "provision-forest" (mapAttrsToList (fqdn: p: { name = "bin/provision-${fqdn}"; path = p; }) machineProvisioners); in pkgs.writeScript "provision" '' #!/bin/sh name="$1" usage() { echo >&2 "Usage: $0 machine|machine.hswaw.net" echo >&2 "Available machines:" echo >&2 "${machineList}" } if [ -z "$name" ]; then usage exit 1 fi provisioner="${forest}/bin/provision-$name" if [ ! -e "$provisioner" ]; then name="$name.hswaw.net" provisioner="${forest}/bin/provision-$name" fi if [ ! -e "$provisioner" ]; then usage exit 1 fi # :^) echo -ne "\e[34mh \e[31ms \e[33mc l \e[34mo \e[32mu \e[31md \e[0m" echo "" echo "Starting provisioner for $name..." echo "" echo "Too slow to evaluate? Equivalent faster command line that rebuilds just one node:" echo " \$(nix-build -A 'ops.machines.\"$name\".config.passthru.hscloud.provision')" echo "" echo "Or, if you want to deploy the same configuration on different machines, just run" echo "this script again without re-evaluating nix:" echo " $0 $name" echo "" exec "$provisioner" ''