diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75a903ad3f8637ac5952c0fcb81bbddb72ca3314..ba6c8ad1e99f0ed9dc44ee59a74d4ad8bf102208 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,10 +20,42 @@ unit-tests: script: - "nix-shell --run 'nix-build nixos/unit-tests.nix' && cat result" +.morph-build: &MORPH_BUILD + stage: "test" + timeout: "3 hours" + + script: + - | + # GRID is set in one of the "instantiations" of this job template. + nix-shell --run "morph build --show-trace morph/grid/${GRID}/grid.nix" + + +morph-build-localdev: + <<: *MORPH_BUILD + variables: + GRID: "local" + + before_script: + - | + # The local grid configuration is *almost* complete enough to build. It + # just needs this tweak. + sed -i 's/undefined/\"unundefined\"/' morph/grid/${GRID}/public-keys/users.nix + +morph-build-testing: + <<: *MORPH_BUILD + variables: + GRID: "testing" + + +morph-build-production: + <<: *MORPH_BUILD + variables: + GRID: "production" + + vulnerability-scan: stage: "test" script: - - "sed -i 's/undefined/\"unundefined\"/' morph/grid/local/public-keys/users.nix" - "ci-tools/vulnerability-scan security-report.json" - "ci-tools/count-vulnerabilities <security-report.json" artifacts: @@ -38,24 +70,49 @@ system-tests: script: - "nix-shell --run 'nix-build nixos/system-tests.nix'" -deploy-to-staging: +# A template for a job that can update one of the grids. +.update-grid: &UPDATE_GRID stage: "deploy" + script: + # Announce our intentions. + - | + echo "Hello $GITLAB_USER_LOGIN from $CI_JOB_NAME. I was triggered by $CI_PIPELINE_SOURCE" + echo "and I am deploying the $CI_COMMIT_BRANCH branch to the $CI_ENVIRONMENT_NAME environment." + + # Copy the deploy key from the environment to a file so we can actually + # tell ssh to use it. + - | + # The environment variable is configured with GitLab using Terraform so + # we can retain some bare minimum level of confidentiality. + KEY_DIR="$(mktemp -d -p "${XDG_RUNTIME_DIR}-deploy_key")" + KEY_PATH="${KEY_DIR}/deploy_key" + base64 --decode "${PRIVATESTORAGEIO_STAGING_SSH_DEPLOY_KEY}" > "${KEY_PATH}" + + # Update the deployment + - | + ./ci-tools/update-grid-servers "${KEY_PATH}" ${name} + + # Remove the key from the filesystem to reduce the chance of unintentional + # disclosure. Overall our handling of this key is still not *particulary* + # safe or secure but that's why the key is only authorized to perform a + # single very specific operation. + - | + rm -v "${KEY_PATH}" + +# Update the staging deployment - only on a merge to the staging branch. +update-staging: + <<: *UPDATE_GRID only: - "staging" environment: name: "staging" url: "https://privatestorage-staging.com/" - script: - - echo "Hello $GITLAB_USER_LOGIN from $CI_JOB_NAME. I was triggered by $CI_PIPELINE_SOURCE " - - echo "and would like to deploy the $CI_COMMIT_BRANCH branch to the $CI_ENVIRONMENT_NAME environment." +# Update the production deployment - only on a merge to the production branch. deploy-to-production: - stage: "deploy" + <<: *UPDATE_GRID only: - "production" environment: name: "production" url: "https://privatestorage.io/" - script: - - echo "Hello $GITLAB_USER_LOGIN from $CI_JOB_NAME. I was triggered by $CI_PIPELINE_SOURCE " - - echo "and would like to deploy the $CI_COMMIT_BRANCH branch to the $CI_ENVIRONMENT_NAME environment." diff --git a/ci-tools/update-grid-servers b/ci-tools/update-grid-servers new file mode 100755 index 0000000000000000000000000000000000000000..61b4cf477ca963d8177ab7d990a9ea88e7f67013 --- /dev/null +++ b/ci-tools/update-grid-servers @@ -0,0 +1,56 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p jp + +# +# Tell all servers belonging to a certain grid that they should update +# themselves to the latest configuration associated with that grid. +# + +set -euxo pipefail + +# Get the path to the ssh key which authorizes us to deliver this +# notification. +DEPLOY_KEY=$1 +shift + +# Get the name of the grid to which we're going to deliver notification. This +# corresponds to the name of one of the directories in the top-level `morph` +# directory. +GRIDNAME=$1 +shift + +# Tell one server to update itself. +update_one_node() { + deploy_key=$1 + shift + + node=$1 + shift + + ssh -i "${deploy_key}" "deployment@${node}" +} + +# Tell all servers belonging to one grid to update themselves. +update_grid_nodes() { + deploy_key=$1 + shift + + gridname=$1 + shift + + # Find the names of all hosts that belong to this grid. This list includes + # one extra string, "network", which is morph configuration stuff and we need + # to filter out later. + nodes=$(nix eval --json '(builtins.attrNames (import ./morph/${gridname}/grid.nix))') + + # Tell every server in the network to update itself. + for node in ${nodes}; do + if [ "${node}" = "network" ]; then + # This isn't a server, it's part of the morph configuration. + continue + fi + update_one_node "${deploy_key}" "${node}" + fi +} + +update_grid_nodes "${DEPLOY_KEY}" "${GRIDNAME}" diff --git a/ci-tools/vulnerability-scan b/ci-tools/vulnerability-scan index 3162e49511697ed0ea13e0121a67336405ce5225..48bf51e071a398f37565717a22b2066d3f905fbe 100755 --- a/ci-tools/vulnerability-scan +++ b/ci-tools/vulnerability-scan @@ -21,7 +21,7 @@ OUTPUT=$1 [ -e scan-target ] && rm -v scan-target nix-shell --run ' set -x -if morph_result=$(morph build morph/grid/local/grid.nix 2>&1); then +if morph_result=$(morph build morph/grid/testing/grid.nix 2>&1); then object=$(echo "$morph_result" | tail -n 1) ln -s "$object" scan-target else diff --git a/morph/grid/local/Vagrantfile b/morph/grid/local/Vagrantfile index a2890b8a63304d37002076b5804f2b322207160e..a871cbbe72e410de88a19596ff528391e32ff811 100644 --- a/morph/grid/local/Vagrantfile +++ b/morph/grid/local/Vagrantfile @@ -13,6 +13,16 @@ Vagrant.configure("2") do |config| config.vm.box = "esselius/nixos" config.vm.box_version = "20.09" config.vm.box_check_update = false + + # To use the self-updating deployment system you need more memory. Giving + # all of the VMs enough memory for this is rather taxing, though, and the + # self-updating deployment system is not particularly useful for local + # dev. But should you want to: + # + # config.vm.provider "virtualbox" do |v| + # v.memory = 4096 + # end + config.vm.network "private_network", ip: "192.168.67.21" # Add self signed SSL key for zkap-issuer: config.vm.provision "file", source: "private-keys/payments-localdev-ssl", destination: "/tmp/payments-localdev-ssl" diff --git a/morph/grid/local/grid.nix b/morph/grid/local/grid.nix index bca902f20440e60e7d71162f273dd65d67317545..4e82fa29db5df7da2c9e977f978e67228e527be5 100644 --- a/morph/grid/local/grid.nix +++ b/morph/grid/local/grid.nix @@ -12,6 +12,14 @@ let privateKeyPath = toString ./. + "/${rawConfig.privateKeyPath}"; }; + # Configure deployment management authorization for all systems in the grid. + deployment = { + services.private-storage.deployment = { + authorizedKey = builtins.readFile "${config.publicKeyPath}/deploy_key.pub"; + gridName = "local"; + }; + }; + payments = { imports = [ gridlib.issuer @@ -19,6 +27,7 @@ let (gridlib.customize-issuer (config // { monitoringvpnIPv4 = "172.23.23.11"; })) + deployment ]; }; @@ -30,6 +39,7 @@ let monitoringvpnIPv4 = "172.23.23.12"; stateVersion = "19.09"; })) + deployment ]; }; @@ -41,6 +51,7 @@ let monitoringvpnIPv4 = "172.23.23.13"; stateVersion = "19.09"; })) + deployment ]; }; @@ -54,6 +65,7 @@ let monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) + deployment ]; }; diff --git a/morph/grid/local/private-keys/deploy_key b/morph/grid/local/private-keys/deploy_key new file mode 100644 index 0000000000000000000000000000000000000000..5c8807906eca2a818d2807e2512d03642d038edb --- /dev/null +++ b/morph/grid/local/private-keys/deploy_key @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACADU1IBThyH0blWBG8afIA/h/bmVdUQkFAuAIQgAWE+ewAAAJjsA+8c7APv +HAAAAAtzc2gtZWQyNTUxOQAAACADU1IBThyH0blWBG8afIA/h/bmVdUQkFAuAIQgAWE+ew +AAAED6aLiQi/K2qG8sLsvV8Xar9PjJeFxKfb+GUvmseu8TqQNTUgFOHIfRuVYEbxp8gD+H +9uZV1RCQUC4AhCABYT57AAAADmV4YXJrdW5AYmFyeW9uAQIDBAUGBw== +-----END OPENSSH PRIVATE KEY----- diff --git a/morph/grid/local/public-keys/deploy_key.pub b/morph/grid/local/public-keys/deploy_key.pub new file mode 100644 index 0000000000000000000000000000000000000000..15d38cefef61e5f2008efa949ff36245677f8426 --- /dev/null +++ b/morph/grid/local/public-keys/deploy_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIANTUgFOHIfRuVYEbxp8gD+H9uZV1RCQUC4AhCABYT57 exarkun@baryon diff --git a/morph/grid/production/grid.nix b/morph/grid/production/grid.nix index ec21972cfd92bbf191312df3631d403c47bf9068..52a96040b54cbf89d757628f3ca4db8477395351 100644 --- a/morph/grid/production/grid.nix +++ b/morph/grid/production/grid.nix @@ -13,6 +13,14 @@ let privateKeyPath = toString ./. + "/${rawConfig.privateKeyPath}"; }; + # Configure deployment management authorization for all systems in the grid. + deployment = { + services.private-storage.deployment = { + authorizedKey = builtins.readFile "${config.publicKeyPath}/deploy_key.pub"; + gridName = "production"; + }; + }; + payments = {name, ...}: { networking.hostName = name; imports = [ @@ -21,6 +29,7 @@ let (gridlib.customize-issuer (config // { monitoringvpnIPv4 = "172.23.23.11"; })) + deployment ]; }; @@ -35,6 +44,7 @@ let monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) + deployment ]; }; @@ -60,6 +70,9 @@ let monitoringvpnIPv4 = vpnIP; inherit stateVersion; })) + + # Also configure deployment management authorization + deployment ]; # And supply configuration for those hardware / network / bootloader diff --git a/morph/grid/production/public-keys/deploy_key.pub b/morph/grid/production/public-keys/deploy_key.pub new file mode 100644 index 0000000000000000000000000000000000000000..3d9ea022d26654ba7b18bd3426a464049b58c9ea --- /dev/null +++ b/morph/grid/production/public-keys/deploy_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK50RwXncelNB4JAazoXEhCxXbJZ79qWcQMAWeX14H+W exarkun@baryon diff --git a/morph/grid/testing/grid.nix b/morph/grid/testing/grid.nix index bc4252fcae49f05e533562bb7c891984d904f095..1534f08c765513da04a263c916f48ef4e859cb76 100644 --- a/morph/grid/testing/grid.nix +++ b/morph/grid/testing/grid.nix @@ -13,6 +13,14 @@ let privateKeyPath = toString ./. + "/${rawConfig.privateKeyPath}"; }; + # Configure deployment management authorization for all systems in the grid. + deployment = { + services.private-storage.deployment = { + authorizedKey = builtins.readFile "${config.publicKeyPath}/deploy_key.pub"; + gridName = "testing"; + }; + }; + payments = {name, ...}: { networking.hostName = name; imports = [ @@ -21,6 +29,7 @@ let (gridlib.customize-issuer (config // { monitoringvpnIPv4 = "172.23.23.11"; })) + deployment ]; }; @@ -33,6 +42,7 @@ let monitoringvpnIPv4 = "172.23.23.12"; stateVersion = "19.03"; })) + deployment ]; }; @@ -47,6 +57,7 @@ let monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) + deployment ]; }; diff --git a/morph/grid/testing/public-keys/deploy_key.pub b/morph/grid/testing/public-keys/deploy_key.pub new file mode 100644 index 0000000000000000000000000000000000000000..2dafd3cce2c83b8e4a32815c37c51ee890ba846c --- /dev/null +++ b/morph/grid/testing/public-keys/deploy_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB88qfLdoR5Pq9Us7vOVc6wBWmIDxme9MXYQSxxO+8/X exarkun@baryon diff --git a/morph/grid/testing/testing001-hardware.nix b/morph/grid/testing/testing001-hardware.nix index dd2f9733796875bb9d8a549538cba5743a8727a3..b57f193a6155a88be0af804fd6edd9a98043368a 100644 --- a/morph/grid/testing/testing001-hardware.nix +++ b/morph/grid/testing/testing001-hardware.nix @@ -13,7 +13,7 @@ networking.hostId = "10000000"; # Manually created using: - # zpool create -m legacy -o ashift=12 root raidz /dev/disk/by-id/{nvme-nvme.1d0f-766f6c3038623133353836383465643436363430-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001,nvme-nvme.1d0f-766f6c3034653531383066303134633436653034-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001,nvme-nvme.1d0f-766f6c3062333164633831386366623231373730-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001,nvme-nvme.1d0f-766f6c3061353939623438336661353933636664-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001} + # zpool create -m legacy -o ashift=12 root /dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol047fc3ea6bafdcc58 fileSystems."/storage" = { device = "root"; fsType = "zfs"; diff --git a/morph/lib/issuer.nix b/morph/lib/issuer.nix index 417ef7965ea0120322995059fcca7a5a9afe2543..51046b436e297cdc5034134e3503556e8030588c 100644 --- a/morph/lib/issuer.nix +++ b/morph/lib/issuer.nix @@ -40,6 +40,9 @@ rec { }; imports = [ + # Allow us to remotely trigger updates to this system. + ../../nixos/modules/deployment.nix + ../../nixos/modules/issuer.nix ../../nixos/modules/monitoring/vpn/client.nix ../../nixos/modules/monitoring/exporters/node.nix diff --git a/morph/lib/monitoring.nix b/morph/lib/monitoring.nix index b48820f0941694869fdda06e724ba1ae714b5993..fa769d5ebcb32d893310136291064a85c09beee2 100644 --- a/morph/lib/monitoring.nix +++ b/morph/lib/monitoring.nix @@ -21,6 +21,9 @@ rec { }; imports = [ + # Allow us to remotely trigger updates to this system. + ../../nixos/modules/deployment.nix + ../../nixos/modules/monitoring/vpn/server.nix ../../nixos/modules/monitoring/server/grafana.nix ../../nixos/modules/monitoring/server/prometheus.nix diff --git a/morph/lib/storage.nix b/morph/lib/storage.nix index 1cac51b43aa38fb90a535fd34ba53363fc0cdbaa..ebad3d17e17e0098f6e098d61d7c614fde91b31e 100644 --- a/morph/lib/storage.nix +++ b/morph/lib/storage.nix @@ -32,6 +32,8 @@ rec { # Any extra NixOS modules to load on this server. imports = [ + # Allow us to remotely trigger updates to this system. + ../../nixos/modules/deployment.nix # Bring in our module for configuring the Tahoe-LAFS service and other # Private Storage-specific things. ../../nixos/modules/private-storage.nix diff --git a/nixos/modules/deployment.nix b/nixos/modules/deployment.nix new file mode 100755 index 0000000000000000000000000000000000000000..2615659519469c9c1c2712382b178bc4fd1c323b --- /dev/null +++ b/nixos/modules/deployment.nix @@ -0,0 +1,130 @@ +# A NixOS module which enables remotely-triggered deployment updates. +{ config, lib, pkgs, ... }: +let + # A handy alias for our part of the configuration. + cfg = config.services.private-storage.deployment; + + # Compute an authorized_keys line that allows the holder of a certain key to + # execute a certain command *only*. + restrictedKey = + { authorizedKey, command, gridName }: + # `restrict` means "disable all the things" then `command` means "but + # enable running this one command" (the client does not have to supply the + # command; if they authenticate, this is the command that will run). + # environment lets us pass an environment variable into the process + # started by the given command. It only works because we configured our + # sshd to allow this particular variable through. By passing this value, + # we can pin nixpkgs in the executed command to the same version + # configured for use here. It might be better if we just had a channel + # the system could be configured with ... but we don't at the moment. + "restrict,environment=\"NIXPKGS_FOR_MORPH=${pkgs.path}\",command=\"${command} ${gridName}\" ${authorizedKey}"; +in { + options = { + services.private-storage.deployment.authorizedKey = lib.mkOption { + type = lib.types.str; + example = lib.literalExample '' + ssh-ed25519 AAAAC3N... + ''; + description = '' + The SSH public key to authorize to trigger a deployment update. + ''; + }; + services.private-storage.deployment.gridName = lib.mkOption { + type = lib.types.str; + example = lib.literalExample "staging"; + description = '' + The name of the grid configuration to use to update this deployment. + ''; + }; + }; + + config = { + # Configure the system to use our binary cache so that deployment updates + # only require downloading pre-built software, not building it ourselves. + nix = { + binaryCachePublicKeys = [ + "saxtons.private.storage:MplOcEH8G/6mRlhlKkbA8GdeFR3dhCFsSszrspE/ZwY=" + ]; + binaryCaches = [ + "http://saxtons.private.storage" + ]; + }; + + services.openssh.extraConfig = '' + PermitUserEnvironment=NIXPKGS_FOR_MORPH + ''; + + # Create a one-time service that will set up an ssh key that allows the + # deployment user to authorize as root to perform the system update with + # `morph deploy`. + systemd.services.authorize-morph-as-root = { + enable = true; + serviceConfig = { + # Tell systemd that the service is a process that runs and then exits. + # By being "oneshot" instead of "simple" any dependencies are not + # started until after the process exits. We have no dependencies yet + # but if we did it would be more correct for them to wait until we are + # done. + # + # It is not clear that "oneshot" means "run once" though (maybe it + # does, I can't tell) so the script is robust in the face of repeated + # runs even though it should only ever need to be run once. + Type = "oneshot"; + }; + wantedBy = [ + # Run this to reach the multi-user target, a good target that is + # reached in the typical course of system startup. + "multi-user.target" + ]; + # Here's the program to run for this unit. It's a shell script that + # creates an ssh key that authorized root access via ssh and give it to + # the deployment user. If such a key appears to exist already, do + # nothing. + script = '' + KEY=~deployment/.ssh/morph_key + TMP="$KEY"_tmp + if [ ! -e "$KEY" ]; then + mkdir -p ~deployment/.ssh ~root/.ssh + chown deployment ~deployment/.ssh + ${pkgs.openssh}/bin/ssh-keygen -f "$TMP" + cat "$TMP".pub >> ~root/.ssh/authorized_keys + mv "$TMP".pub "$KEY".pub + mv "$TMP" "$KEY" + chown deployment "$KEY" + fi + ''; + }; + + # Raise the hard-limit on the size of $XDG_RUNTIME_DIR (ie + # /run/user/<uid>). The default of 10% is too small on some systems for + # the temporary state morph creates to do the self-update. + services.logind.extraConfig = '' + RuntimeDirectorySize=50% + ''; + + # Configure the deployment user. + users.users.deployment = { + # Without some shell no login is possible at all, even to execute our + # single non-restricted command. + useDefaultShell = true; + + # Without a home directory, lots of tools break. + createHome = true; + home = "/home/deployment"; + + packages = [ + # update-deployment dependencies + pkgs.morph + pkgs.git + ]; + + # Authorize the supplied key to run the deployment update command. + openssh.authorizedKeys.keys = [ + (restrictedKey { + inherit (cfg) authorizedKey gridName; + command = ./update-deployment; + }) + ]; + }; + }; +} diff --git a/nixos/modules/ssh.nix b/nixos/modules/ssh.nix index 667bdd26215b4e0978781244741dd4c5313cefbd..3e90528322c153d6b96679af5d914c4e753b49bf 100644 --- a/nixos/modules/ssh.nix +++ b/nixos/modules/ssh.nix @@ -40,12 +40,6 @@ # Agent forwarding is fraught. It can be used by an attacker to # leverage one compromised system into more. Discourage its use. AllowAgentForwarding no - - # Only allow authentication as one of the configured users, not random - # other (often system-managed) users. Possibly this is also - # superfluous! NixOS system users have nologin as their shell ... so they - # cannot log in anyway. - AllowUsers ${builtins.concatStringsSep " " (builtins.attrNames cfg.sshUsers)} ''; }; diff --git a/nixos/modules/update-deployment b/nixos/modules/update-deployment new file mode 100755 index 0000000000000000000000000000000000000000..19599a4aa7ac2ec7bbb7e160ec1b37a8493b4a62 --- /dev/null +++ b/nixos/modules/update-deployment @@ -0,0 +1,95 @@ +#!/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") + BRANCH="develop" + ;; + + "testing") + BRANCH="staging" + ;; + + "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 fix the undefined key. +if [ "${GRIDNAME}" = "local" ]; then + KEY="$(cat /etc/ssh/authorized_keys.d/vagrant)" + sed -i "s_undefined_\"${KEY}\"_" "${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. The NIX_PATH +# environment variable itself receives special treatment by some parts of the +# system (especially those parts leading up to the execution of this script) +# so we pass the desired information through a different variable and then +# shuffle it into the right place here, just before it is needed. +export NIX_PATH="nixpkgs=$NIXPKGS_FOR_MORPH" + +# 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 +fi diff --git a/nixpkgs-ps.json b/nixpkgs-ps.json index c5b01313cacdfc86f06e3baa82fb1d605c35da56..97449535de722fdaf89d8551c6bd6d124e3818c7 100644 --- a/nixpkgs-ps.json +++ b/nixpkgs-ps.json @@ -1,4 +1,4 @@ -{ "name": "nixpkgs-ps" -, "url": "https://github.com/PrivateStorageio/nixpkgs/archive/788cc5806d46b89013ddd59db589b748bc20435e.tar.gz" -, "sha256": "1mjznn4i4524gl5aiapjpy2jzpac1fzp7jvnkamrh9090ndalhar" +{ "name": "nixpkgs" +, "url": "https://github.com/PrivateStorageio/nixpkgs/archive/a5cbaadd9676e8c568061e92bbf5ad6a5d884ded.tar.gz" +, "sha256": "0q5zknsp0qb25ag9zr9bw1ap7pb3f76bxsw81ahxkzj4z5dw6k2f" }