Newer
Older
#!/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.
# 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.
;;
"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.
# 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
# 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)" ":"
Jean-Paul Calderone
committed
# Set nixpkgs to our preferred version for the morph build. Annoyingly, we
# can't just use nixpkgs.nix as our nixpkgs because some code (in morph,
Jean-Paul Calderone
committed
# 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.nix/lib` which is nonsense.
Jean-Paul Calderone
committed
#
# 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.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
else
# Oops. Not so fortunate. Record failure.
echo "${LOG_MESSAGE} FAIL" >> ${HOME}/updates.txt