Unverified Commit 49c05db1 authored by r-vdp's avatar r-vdp
Browse files

nixos/switchable-system: improve switch-inhibitor pre-check

The check ran `realpath /run/current-system` under errexit, so a
missing current-system symlink aborted the script.
Drop the realpath calls (the -f test and jq already follow symlinks)
and use a static store path for the empty fallback instead of mktemp/trap.

Also exempt dry-activate, which makes no state changes and was being
blocked from showing its diff, and let jq fail loudly on malformed
inhibitor JSON instead of silently treating it as empty.
parent 3ded3dec
Loading
Loading
Loading
Loading
+14 −24
Original line number Diff line number Diff line
@@ -71,41 +71,31 @@

      preSwitchChecks.switchInhibitors =
        let
          realpath = lib.getExe' pkgs.coreutils "realpath";
          mktemp = lib.getExe' pkgs.coreutils "mktemp";
          rm = lib.getExe' pkgs.coreutils "rm";
          jq = lib.getExe' pkgs.jq "jq";
          jq = lib.getExe pkgs.jq;
          empty = pkgs.writeText "empty-inhibitors" "{}";
        in
        # bash
        ''
          incoming="''${1-}"
          action="''${2-}"

          if [ "$action" == "boot" ]; then
          case "$action" in
            boot|dry-activate)
              echo "Not checking switch inhibitors (action = $action)"
              exit
          fi
              ;;
          esac

          echo -n "Checking switch inhibitors..."

          # Create a temporary file that we use in case a generation does not have
          # the switch-inhibitors file.
          empty="$(${mktemp} -t switch_inhibit.XXXX)"
          # shellcheck disable=SC2329
          clean_up() {
            ${rm} -f "$empty"
          }
          trap clean_up EXIT
          echo "{}" > "$empty"

          current_inhibitors="$(${realpath} /run/current-system)/switch-inhibitors"
          current_inhibitors="/run/current-system/switch-inhibitors"
          if [ ! -f "$current_inhibitors" ]; then
            current_inhibitors="$empty"
            current_inhibitors="${empty}"
          fi

          new_inhibitors="$(${realpath} "$incoming")/switch-inhibitors"
          new_inhibitors="$incoming/switch-inhibitors"
          if [ ! -f "$new_inhibitors" ]; then
            new_inhibitors="$empty"
            new_inhibitors="${empty}"
          fi

          diff="$(
@@ -115,8 +105,8 @@
              --rawfile current "$current_inhibitors" \
              --rawfile newgen "$new_inhibitors" \
            '
              $current | try fromjson catch {} as $old |
              $newgen | try fromjson catch {} as $new |
              ($current | fromjson) as $old |
              ($newgen | fromjson) as $new |
              $old |
              to_entries |
              map(
+3 −0
Original line number Diff line number Diff line
@@ -776,6 +776,9 @@ in
          assert_contains(out, "baz")
          # Confirm that we can set that same generation as the new boot default
          switch_to_specialisation("${machine}", "inhibitors_changed", action="boot")
          # Confirm that dry-activate is not blocked by inhibitors
          out = switch_to_specialisation("${machine}", "inhibitors_changed", action="dry-activate")
          assert_contains(out, "Not checking switch inhibitors")
          # Check that we can switch into a new generation with new inhibitors, but same values for existing ones
          switch_to_specialisation("${machine}", "inhibitors_new", action="switch")
          # Check that we can switch back into a generation without inhibitors