#!/usr/bin/env bash set -euxo pipefail # Accept the name of the grid this system is part of as a parameter. This # lets us pick the correct morph grid source file later on. GRIDNAME=$1 shift # Determine the right branch name to use for the particular grid we've been # told we belong to. The grid name is a parameter to this script we can # re-use it across all of our grids. See deployment.nix for the ssh # configuration that controls what value is actually passed when an update is # triggered. case "${GRIDNAME}" in "local"|"testing") BRANCH="develop" ;; "production") BRANCH="production" ;; *) echo "Unknown grid: ${GRIDNAME}" exit 1 esac # This is where we will maintain a checkout of PrivateStorageio for morph to # use to compute the desired state. CHECKOUT="${HOME}/PrivateStorageio" # This is the address of the git remote where we can get the latest # PrivateStorageio. REPO="https://whetstone.privatestorage.io/privatestorage/PrivateStorageio.git" if [ -e "${CHECKOUT}" ]; then # It exists already so just make sure it contains the latest changes from # the canonical repository. git -C "${CHECKOUT}" fetch else # It doesn't exist so clone it. git clone "${REPO}" "${CHECKOUT}" fi # Get us to a pristine checkout of the right branch. git -C "${CHECKOUT}" reset --hard "origin/${BRANCH}" # If we happen to be on the local grid then add the required user.nix file # containing ssh-keys. if [ "${GRIDNAME}" = "local" ]; then echo "import /etc/nixos/ssh-users.nix" > "${CHECKOUT}"/morph/grid/"${GRIDNAME}"/public-keys/users.nix fi # Compute a log message explaining what we're doing. LOG_MESSAGE="$(date --iso-8601=seconds) $(git -C "${CHECKOUT}" rev-parse HEAD)" # Make sure we use the right credentials and ask for the right account when # morph makes the connection. morph's deployment target for each host is the # full domain name (even though the host is only named with the unqualified # hostname in the morph grid definition) so compute an ssh config section that # matches that. Regardless, point this effort at localhost because we *know* # it's just us we want to update. cat > ~/.ssh/config <<EOF Host $(hostname).$(domainname) HostName 127.0.0.1 IdentityFile ~/.ssh/morph_key User root EOF # Make sure known_hosts has the host key in it. ssh -o StrictHostKeyChecking=no "$(hostname).$(domainname)" ":" # Set nixpkgs to our preferred version for the morph build. Annoyingly, we # can't just use nixpkgs-2105.nix as our nixpkgs because some code (in morph, # at least) wants <nixpkgs> to be a fully-resolved path to a nixpkgs tree. # For example, morph evaluated `import <nixpkgs/lib>` which would turn into # something like `import nixpkgs-2105.nix/lib` which is nonsense. # # So instead, import our nixpkgs which forces it to be instantiated in the # store, then ask for its path, then set NIX_PATH to that. export NIX_PATH="nixpkgs=$(nix eval "(import ${CHECKOUT}/nixpkgs-2105.nix { }).path")" # Attempt to update just this host. Choose the morph grid definition matching # the grid we belong to and limit the morph deployment update to the host # matching our name. morph uses just the bare hostname without the domain # part. if morph deploy "${CHECKOUT}"/morph/grid/"${GRIDNAME}"/grid.nix switch --on "$(hostname)"; then # The deployment succeeded. Record success along with context we pre-computed. echo "${LOG_MESSAGE} OK" >> ${HOME}/updates.txt exit 0 else # Oops. Not so fortunate. Record failure. echo "${LOG_MESSAGE} FAIL" >> ${HOME}/updates.txt exit 1 fi