]> git.scottworley.com Git - auto-upgrade-with-pinch/blobdiff - modules/auto-upgrade.nix
When becoming other users, cd to / with pushd, not sudo -D
[auto-upgrade-with-pinch] / modules / auto-upgrade.nix
index 56d15d9202bfa8c783c5bec5a0ef03e02c0a3b30..0977176a8176855b4521ef60dc7b875062fda921 100644 (file)
@@ -1,65 +1,73 @@
+# auto-upgrade-with-pinch: Secure managed NixOS updates
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, version 3.
+
 { config, lib, pkgs, ... }:
 with lib;
 let
+  local-pkgs = import ../. { inherit pkgs; };
   cfg = config.system.autoUpgradeWithPinch;
-  pull-repo-script =
-    pkgs.writeShellScript "pull-repo" ''
-      set -eo pipefail
-
-      path=$1
-      config=$2
-
-      prop() {
-        ${pkgs.jq}/bin/jq -r ".$1" <<< "$config"
-      }
-
-      echo Pulling in "$path" >&2
-
-      if [[ ! -e "$path" ]];then
-        d=$(mktemp -d)
-        ${pkgs.git}/bin/git init "$d"
-        ${pkgs.git}/bin/git -C "$d" checkout -b "$(prop localBranch)"
-        ${pkgs.git}/bin/git -C "$d" remote add "$(prop remoteName)" "$(prop url)"
-        ${pkgs.git}/bin/git -C "$d" branch -u "$(prop remoteBranch)"
-        mkdir -p "$(${pkgs.coreutils}/bin/dirname "$path")"
-        mv "$d" "$path"
-      fi
-
-      cd "$path"
-
-      if [[ "$(${pkgs.git}/bin/git remote get-url "$(prop remoteName)")" != "$(prop url)" ]]; then
-        echo Expected git remote "$(prop remoteName)" to point at "$(prop url)" \
-          but it points at "$(${pkgs.git}/bin/git remote get-url "$(prop remoteName)")" >&2
-        case "$(prop onRemoteURLMismatch)" in
-          abort)  exit 1;;
-          update) echo Updating it >&2
-                  ${pkgs.git}/bin/git -C "$d" remote set-url "$(prop remoteName)" "$(prop url)";;
-        esac
-      fi
-
-      ${pkgs.git}/bin/git fetch "$(prop remoteName)" "$(prop remoteBranch)"
-
-      if [[ "$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)" != "$(prop localBranch)" ]];then
-        echo Could not merge because currently-checked-out \
-             \""$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)"\" is not \
-             \""$(prop localBranch)"\"
-        case "$(prop onBranchMismatch)" in
-          abort) exit 1;;
-          continue) exit 0;;
-        esac
-      fi
-
-      if [[ "$(prop requireSignature)" == true ]]; then
-        ${pkgs.polite-merge}/bin/polite-merge \
-          -c gpg.program=${escapeShellArg (pkgs.keyedgpg cfg.signingKeys)} \
-          merge --ff-only --verify-signatures
-      else
-        ${pkgs.polite-merge}/bin/polite-merge merge --ff-only
-      fi
-    '';
+  pull-repo-script = pkgs.writeShellScript "pull-repo" ''
+    set -eo pipefail
+
+    path=$1
+    config=$2
+
+    prop() {
+      ${pkgs.jq}/bin/jq -r ".$1" <<< "$config"
+    }
+
+    echo Pulling in "$path" >&2
+
+    if [[ ! -e "$path" ]];then
+      d=$(mktemp -d)
+      ${pkgs.git}/bin/git init "$d"
+      ${pkgs.git}/bin/git -C "$d" checkout -b "$(prop localBranch)"
+      ${pkgs.git}/bin/git -C "$d" remote add "$(prop remoteName)" "$(prop url)"
+      ${pkgs.git}/bin/git -C "$d" branch -u "$(prop remoteBranch)"
+      mkdir -p "$(${pkgs.coreutils}/bin/dirname "$path")"
+      mv "$d" "$path"
+    fi
+
+    cd "$path"
+
+    if [[ "$(${pkgs.git}/bin/git remote get-url "$(prop remoteName)")" != "$(prop url)" ]]; then
+      echo Expected git remote "$(prop remoteName)" to point at "$(prop url)" \
+        but it points at "$(${pkgs.git}/bin/git remote get-url "$(prop remoteName)")" >&2
+      case "$(prop onRemoteURLMismatch)" in
+        abort)  exit 1;;
+        update) echo Updating it >&2
+                ${pkgs.git}/bin/git -C "$d" remote set-url "$(prop remoteName)" "$(prop url)";;
+      esac
+    fi
+
+    ${pkgs.git}/bin/git fetch "$(prop remoteName)" "$(prop remoteBranch)"
+
+    if [[ "$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)" != "$(prop localBranch)" ]];then
+      echo Could not merge because currently-checked-out \
+           \""$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)"\" is not \
+           \""$(prop localBranch)"\"
+      case "$(prop onBranchMismatch)" in
+        abort) exit 1;;
+        continue) exit 0;;
+      esac
+    fi
+
+    if [[ "$(prop requireSignature)" == true ]]; then
+      ${pkgs.polite-merge}/bin/polite-merge \
+        -c gpg.program=${escapeShellArg (local-pkgs.keyed-gpg cfg.signingKeys)} \
+        merge --ff-only --verify-signatures
+    else
+      ${pkgs.polite-merge}/bin/polite-merge merge --ff-only
+    fi
+  '';
 
   auto-upgrade-script = pkgs.writeShellScript "auto-upgrade" ''
-    ${pkgs.utillinux}/bin/flock /run/auto-upgrade-with-pinch ${
+    ${pkgs.coreutils}/bin/nice -n 17 \
+    ${pkgs.util-linux}/bin/ionice -c 3 \
+    ${pkgs.util-linux}/bin/flock /run/auto-upgrade-with-pinch ${
       pkgs.writeShellScript "auto-upgrade-with-lock-held" ''
         set -eo pipefail
 
@@ -144,12 +152,12 @@ let
           + concatMapStringsSep "\n" (f: "verify_ownership ${escapeShellArg f}")
           cfg.upgradeConfig)}
 
-        config=$(${pkgs.nix}/bin/nix eval --json -f ${../upgrade-config.nix} \
+        config=$(${pkgs.nix}/bin/nix-instantiate --eval --strict --json -A config \
           --arg upgradeConfig ${
             escapeShellArg ("["
               + lib.concatMapStringsSep " " lib.strings.escapeNixString
               cfg.upgradeConfig + "]")
-          } config)
+          } ${../upgrade-config.nix})
 
         config_query() {
           ${pkgs.jq}/bin/jq -r "$@" <<< "$config"
@@ -175,8 +183,10 @@ let
         # Build
         in_tmpdir hydrate ${config.system.build.nixos-rebuild}/bin/nixos-rebuild build
         while read user;do
+          pushd /
           hydrate /run/wrappers/bin/sudo -u "$user" \
             ${pkgs.nix}/bin/nix-build --no-out-link '<nixpkgs>' -A "$(userenv_query "$user" .package)"
+          popd
         done < <( config_query '.userEnvironments | keys []' )
 
         # Install
@@ -270,7 +280,6 @@ in {
     '';
 
     nixpkgs.overlays = [
-      (import ../overlays/keyedgpg.nix)
       (import ../overlays/pinch.nix)
       (import ../overlays/polite-merge.nix)
       (self: super: {