From 1a1cda2a3ddc70c2c6625a500246e59207c3a43b Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Aug 2023 12:36:28 +1000 Subject: [PATCH 01/11] etc: allow overwriting files with unknown hashes --- modules/lib/write-text.nix | 9 +++++++++ modules/system/etc.nix | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/modules/lib/write-text.nix b/modules/lib/write-text.nix index 2fe02aff7..17e861aea 100644 --- a/modules/lib/write-text.nix +++ b/modules/lib/write-text.nix @@ -58,6 +58,15 @@ in type = types.listOf types.str; default = []; }; + + force = mkOption { + type = types.bool; + default = false; + internal = true; + description = '' + Whether this file should be placed even if an unknown version of the file already exists. + ''; + }; }; config = { diff --git a/modules/system/etc.nix b/modules/system/etc.nix index 008fb1c1f..dc89bbb84 100644 --- a/modules/system/etc.nix +++ b/modules/system/etc.nix @@ -48,6 +48,12 @@ in etc} ) + declare -A etcForced=( + ${concatMapStringsSep "\n " + (attr: "[${escapeShellArg attr.target}]=" + (builtins.toJSON attr.force)) + etc} + ) + declare -a etcProblems=() while IFS= read -r -d "" configFile; do @@ -69,6 +75,11 @@ in # everything else (e.g. directories) we complain about # unconditionally. if [[ -f $(readlink -f "$etcFile") ]]; then + # Skip checking hashes for files marked force. + if [[ ''${etcForced[$subPath]} == "true" ]]; then + continue + fi + etcFileSha256Output=$(shasum -a 256 "$etcFile") etcFileSha256Hash=''${etcFileSha256Output%% *} for knownSha256Hash in ''${etcSha256Hashes[$subPath]}; do From 7e4c4e9f6f798a5d8757523785735abfce8a7a92 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Aug 2023 12:38:11 +1000 Subject: [PATCH 02/11] DONOTMERGE! add debugging environment --- tart/.envrc | 1 + tart/.gitignore | 2 ++ tart/shell.nix | 15 +++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 tart/.envrc create mode 100644 tart/.gitignore create mode 100644 tart/shell.nix diff --git a/tart/.envrc b/tart/.envrc new file mode 100644 index 000000000..1d953f4bd --- /dev/null +++ b/tart/.envrc @@ -0,0 +1 @@ +use nix diff --git a/tart/.gitignore b/tart/.gitignore new file mode 100644 index 000000000..90acb213d --- /dev/null +++ b/tart/.gitignore @@ -0,0 +1,2 @@ +.direnv +*/** diff --git a/tart/shell.nix b/tart/shell.nix new file mode 100644 index 000000000..7db23b7ba --- /dev/null +++ b/tart/shell.nix @@ -0,0 +1,15 @@ +{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/6cee3b5893090b0f5f0a06b4cf42ca4e60e5d222.tar.gz") { + config.allowUnfree = true; +} }: + +pkgs.mkShell { + nativeBuildInputs = [ + pkgs.tart + pkgs.vncdo + pkgs.bashInteractive + ]; + + shellHook = '' + export TART_HOME=/Users/enzime/Code/nix-darwin/tart/darwin-vm + ''; +} From 2c5a189c27518bbbc1c148804c5b4b0aad2fdd9b Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Aug 2023 12:40:45 +1000 Subject: [PATCH 03/11] DONOTMERGE! no pipelines on this branch --- .github/workflows/build.yml | 18 -- .github/workflows/debug.yml | 23 --- .github/workflows/test.yml | 292 ---------------------------- .github/workflows/update-manual.yml | 37 ---- 4 files changed, 370 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/debug.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/update-manual.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 1cb24265b..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: "Build" -on: - # curl -fsSL -XPOST \ - # -H "Accept: application/vnd.github.everest-preview+json" \ - # -H "Authorization: token $GITHUB_TOKEN" \ - # --data '{"event_type": "build", "client_payload": {"args": "-f channel:nixpkgs-unstable hello"}}' \ - # https://api.github.com/repos/LnL7/nix-darwin/dispatches - repository_dispatch: - types: - - build -jobs: - build: - runs-on: macos-12 - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v22 - - run: | - nix build ${{ github.event.client_payload.args }} -vL diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml deleted file mode 100644 index 7535f7134..000000000 --- a/.github/workflows/debug.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: "Debug" -on: - # curl -fsSL -XPOST \ - # -H "Accept: application/vnd.github.everest-preview+json" \ - # -H "Authorization: token $GITHUB_TOKEN" \ - # --data '{"event_type": "debug"}' \ - # https://api.github.com/repos/LnL7/nix-darwin/dispatches - repository_dispatch: - types: - - debug -jobs: - debug: - runs-on: macos-12 - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v22 - - run: | - nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs - nix-channel --update - - run: | - nix-shell -A installer - nix-shell -A installer.check - - uses: mxschmitt/action-tmate@v3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index a494fd651..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,292 +0,0 @@ -name: "Test" -on: - pull_request: - push: - -env: - CURRENT_STABLE_CHANNEL: nixpkgs-23.11-darwin - -jobs: - test-stable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix corresponding to latest stable channel - uses: cachix/install-nix-action@v23 - with: - install_url: https://releases.nixos.org/nix/nix-2.13.6/install - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A manpages - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple - - test-unstable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v23 - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A manpages - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple - - install-against-stable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix corresponding to latest stable channel - uses: cachix/install-nix-action@v23 - with: - install_url: https://releases.nixos.org/nix/nix-2.13.6/install - nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} - - name: Install ${{ env.CURRENT_STABLE_CHANNEL }} channel - run: | - nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs - nix-channel --update - - name: Install nix-darwin and test - run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - - # We run nix-darwin twice to test that it can create darwin-configuration correctly for us - # but we expect it to fail setting up /etc/nix/nix.conf - nix-shell -A installer || true - - nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) - /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - ~/.nixpkgs/darwin-configuration.nix - - nix-shell -A installer - nix-shell -A installer.check - - name: Build and activate default derivation - run: | - . /etc/static/bashrc - darwin-rebuild switch -I darwin=. - - name: Test uninstallation of nix-darwin - run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - nix-shell -A uninstaller - nix-shell -A uninstaller.check - - name: Debugging tmate session - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 15 - with: - limit-access-to-actor: true - - install-against-unstable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixpkgs-unstable - - name: Install nixpkgs-unstable channel - run: | - nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs - nix-channel --update - - name: Install nix-darwin and test - run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - - # We run nix-darwin twice to test that it can create darwin-configuration correctly for us - # but we expect it to fail setting up /etc/nix/nix.conf - nix-shell -A installer || true - - nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) - /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - ~/.nixpkgs/darwin-configuration.nix - - nix-shell -A installer - nix-shell -A installer.check - - name: Build and activate default derivation - run: | - . /etc/static/bashrc - darwin-rebuild switch -I darwin=. - - name: Test uninstallation of nix-darwin - run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - nix-shell -A uninstaller - nix-shell -A uninstaller.check - - name: Debugging tmate session - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 15 - with: - limit-access-to-actor: true - - install-flake-against-stable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix version corresponding to latest stable channel - uses: cachix/install-nix-action@v23 - with: - install_url: https://releases.nixos.org/nix/nix-2.13.6/install - - name: Install nix-darwin - run: | - mkdir -p ~/.config/nix-darwin - darwin=$(pwd) - pushd ~/.config/nix-darwin - nix flake init -t $darwin - nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) - /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - flake.nix - popd - nix run .#darwin-rebuild -- \ - switch --flake ~/.config/nix-darwin#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface - run: | - . /etc/static/bashrc - darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - - name: Test git submodules - run: | - . /etc/static/bashrc - - mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule} - - pushd /tmp/example-submodule - echo '"hello"' > hello.nix - git init - git add . - git commit -m "add a submodule we will import" - popd - - cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules - cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules - - pushd /tmp/test-nix-darwin-submodules - /usr/bin/sed -i.bak \ - '\#modules = \[#s#configuration#configuration ./simple.nix#' \ - ./flake.nix - /usr/bin/sed -i.bak \ - 's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \ - ./simple.nix - git init - git add flake.nix simple.nix - git \ - -c protocol.file.allow=always \ - submodule add /tmp/example-submodule submodule-test - popd - - # Should fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - # Should also fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=0#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should succeed - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - - install-flake-against-unstable: - runs-on: macos-12 - timeout-minutes: 30 - steps: - - uses: actions/checkout@v3 - - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v23 - - name: Install nix-darwin - run: | - mkdir -p ~/.config/nix-darwin - darwin=$(pwd) - pushd ~/.config/nix-darwin - nix flake init -t $darwin - nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) - /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - flake.nix - popd - nix run .#darwin-rebuild -- \ - switch --flake ~/.config/nix-darwin#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable - - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface - run: | - . /etc/static/bashrc - darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/nixpkgs-unstable - - name: Test git submodules - run: | - . /etc/static/bashrc - - mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule} - - pushd /tmp/example-submodule - echo '"hello"' > hello.nix - git init - git add . - git commit -m "add a submodule we will import" - popd - - cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules - cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules - - pushd /tmp/test-nix-darwin-submodules - /usr/bin/sed -i.bak \ - '\#modules = \[#s#configuration#configuration ./simple.nix#' \ - ./flake.nix - /usr/bin/sed -i.bak \ - 's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \ - ./simple.nix - git init - git add flake.nix simple.nix - git \ - -c protocol.file.allow=always \ - submodule add /tmp/example-submodule submodule-test - popd - - # Should fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should also fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=0#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should succeed - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable - - # Should also succeed - darwin-rebuild build \ - --flake git+file:///tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml deleted file mode 100644 index ef9d52f45..000000000 --- a/.github/workflows/update-manual.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Update manual -on: - push: - branches: - - master - paths: - - '**.nix' - -jobs: - update-manual: - runs-on: macos-12 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - # So that we fetch all branches, since we need to checkout the `gh-pages` branch later. - fetch-depth: 0 - - - name: Install Nix - uses: cachix/install-nix-action@v22 - - - name: Build manual - run: | - nix-build ./release.nix -I nixpkgs=channel:nixpkgs-23.11-darwin -I darwin=. -A manualHTML - - - name: Push update to manual - run: | - git checkout gh-pages - rm -rf manual - cp -R result/share/doc/darwin manual - rm result - git checkout master -- README.md - git config user.name github-actions - git config user.email github-actions@github.com - git add --all - git commit -m "Update manual" - git push From bff4f27bd60f3e4dfdce8fe9f4178e1725f6bd46 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 27 Aug 2023 16:30:25 +1000 Subject: [PATCH 04/11] darwin-rebuild: fix `activate` not setting profile --- pkgs/nix-tools/darwin-rebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index 2dec477b8..a1efabc48 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -221,7 +221,7 @@ fi if [ -z "$systemConfig" ]; then exit 0; fi -if [ "$action" = switch ]; then +if [ "$action" = switch ] || [ "$action" = activate ]; then if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then sudo nix-env -p "$profile" --set "$systemConfig" else From e0be550a2032c565c3b7d90a91e99b77801a8a83 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 9 Jan 2024 21:39:10 +1100 Subject: [PATCH 05/11] nix-installer: init at 0.15.1 --- pkgs/nix-installer/default.nix | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 pkgs/nix-installer/default.nix diff --git a/pkgs/nix-installer/default.nix b/pkgs/nix-installer/default.nix new file mode 100644 index 000000000..1457d3cc4 --- /dev/null +++ b/pkgs/nix-installer/default.nix @@ -0,0 +1,17 @@ +{ stdenv, fetchurl }: + +stdenv.mkDerivation (finalAttrs: { + pname = "nix-installer"; + version = "0.15.1"; + + src = fetchurl { + url = "https://github.com/DeterminateSystems/${finalAttrs.pname}/releases/download/v${finalAttrs.version}/${finalAttrs.pname}-aarch64-darwin"; + hash = "sha256-mcYiRv1KD7F83MJTaV4++dXroPBjelvbGYeSM0Lzdc8="; + }; + + dontUnpack = true; + + installPhase = "install -Dm555 $src $out/bin/${finalAttrs.pname}"; + + meta.mainProgram = finalAttrs.pname; +}) From 0a57885b7ad6dbc342a1d9d28a68c23a9ced3f81 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 9 Jan 2024 21:40:54 +1100 Subject: [PATCH 06/11] ipsw: init with all macOS versions --- flake.nix | 4 +- pkgs/ipsw/default.nix | 563 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 pkgs/ipsw/default.nix diff --git a/flake.nix b/flake.nix index e25fe6a6f..dfcf53925 100644 --- a/flake.nix +++ b/flake.nix @@ -43,6 +43,8 @@ inherit (prev.callPackage ./pkgs/nix-tools { }) darwin-rebuild darwin-option darwin-version; darwin-uninstaller = prev.callPackage ./pkgs/darwin-uninstaller { }; + + ipsw = prev.callPackage ./pkgs/ipsw { }; }; darwinModules.hydra = ./modules/examples/hydra.nix; @@ -79,7 +81,7 @@ in { default = self.packages.${system}.darwin-rebuild; - inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller; + inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller ipsw; }); }; } diff --git a/pkgs/ipsw/default.nix b/pkgs/ipsw/default.nix new file mode 100644 index 000000000..c1d1c223d --- /dev/null +++ b/pkgs/ipsw/default.nix @@ -0,0 +1,563 @@ +{ lib, fetchurl, writeShellApplication, aria2 }: + +# These URLs are from https://github.com/insidegui/VirtualBuddy/blob/main/data/ipsws_v1.json +let + addFetchScript = fetcher: let + inherit (fetcher) name url outputHash; + in fetcher // { + fetchScript = writeShellApplication { + name = "fetch-${name}"; + runtimeInputs = [ aria2 ]; + text = '' + aria2c -x4 "${url}" -o "${name}" + hash=$(nix-hash --type sha256 --to-sri "$(nix-hash --flat --type sha256 "${name}")") + if [[ "$hash" != "${outputHash}" ]]; then + echo "error: hashes don't match" + echo "expected = ${outputHash}" + echo " got = $hash" + echo "remove ${name} and try again" + exit 1 + fi + nix-store --add-fixed sha256 "${name}" + rm "${name}" + ''; + }; + }; +in lib.mapAttrs (key: fetcher: addFetchScript fetcher) { + "12.3.1" = fetchurl { + name = "UniversalMac_12.3.1_21E258_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringFCS/fullrestores/002-79219/851BEDF0-19DB-4040-B765-0F4089D1530D/UniversalMac_12.3.1_21E258_Restore.ipsw"; + hash = "sha256-ywRDUlVx6l5UqlqP2cUndFkYkjEUBRg3QfSgL5k+GNU="; + }; + + "12.4" = fetchurl { + name = "UniversalMac_12.4_21F79_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringFCS/fullrestores/012-06874/9CECE956-D945-45E2-93E9-4FFDC81BB49A/UniversalMac_12.4_21F79_Restore.ipsw"; + hash = "sha256-H56SH3e7y1z3gCY4nW9zMc3WdbwIH/rHf8AEBafoIrM="; + }; + + "12.5" = fetchurl { + name = "UniversalMac_12.5_21G72_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerFCS/fullrestores/012-42731/BD9917E0-262C-41C5-A69F-AC316A534A39/UniversalMac_12.5_21G72_Restore.ipsw"; + hash = "sha256-Set08zE7Cwwi1MBV9WciFD/a4eXMsdy/d5oaTE3LxCs="; + }; + + "12.5.1" = fetchurl { + name = "UniversalMac_12.5.1_21G83_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerFCS/fullrestores/012-51674/A7019DDB-3355-470F-A355-4162A187AB6C/UniversalMac_12.5.1_21G83_Restore.ipsw"; + hash = "sha256-l6XGHiHp3fJRWOydyme0giBfndMR0nShpZkVtLsELIM="; + }; + + "12.6" = fetchurl { + name = "UniversalMac_12.6_21G115_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-40537/0EC7C669-13E9-49FB-BD64-9EECC1D174B2/UniversalMac_12.6_21G115_Restore.ipsw"; + hash = "sha256-URP408d/1yXqY1fO1XZLxXGD0tOISSxYxG/ycp0GWOU="; + }; + + "12.6.1" = fetchurl { + name = "UniversalMac_12.6.1_21G217_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-66032/8D8D90C6-A876-4FFF-BBF4-D158939B3841/UniversalMac_12.6.1_21G217_Restore.ipsw"; + hash = "sha256-ZZdnJlNkRttOgr3bqrAwaArfBMN+sze7aMOIiGA1w7s="; + }; + + "13.0" = fetchurl { + name = "UniversalMac_13.0_22A380_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-92188/2C38BCD1-2BFF-4A10-B358-94E8E28BE805/UniversalMac_13.0_22A380_Restore.ipsw"; + hash = "sha256-U3AIkA/jTutwPZKM5hNwi/vWv0RSiZSAWPxhe+Ty0JA="; + }; + + "13.0.1" = fetchurl { + name = "UniversalMac_13.0.1_22A400_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-93802/A7270B0F-05F8-43D1-A9AD-40EF5699E82C/UniversalMac_13.0.1_22A400_Restore.ipsw"; + hash = "sha256-WNxmFJR83MlxzH0a6IKz2u5cNLjHIdUROaDP9G07VD8="; + }; + + "13.1" = fetchurl { + name = "UniversalMac_13.1_22C65_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-60270/0A7F49BA-FC31-4AD9-8E45-49B1FB9128A6/UniversalMac_13.1_22C65_Restore.ipsw"; + hash = "sha256-mN0Wf7QrNF77rcYsi/dPqpjsPX5geQhdyS75jHeXsUs="; + }; + + "13.2" = fetchurl { + name = "UniversalMac_13.2_22D49_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterFCS/fullrestores/032-35688/0350BB21-2B4B-4850-BF77-70B830283B28/UniversalMac_13.2_22D49_Restore.ipsw"; + hash = "sha256-uoBzLvzA/JrITFf1BM7QnbxDHEnitjO5q9RzDlWsZqU="; + }; + + "13.2.1" = fetchurl { + name = "UniversalMac_13.2.1_22D68_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterFCS/fullrestores/032-48346/EFF99C1E-C408-4E7A-A448-12E1468AF06C/UniversalMac_13.2.1_22D68_Restore.ipsw"; + hash = "sha256-AxAiDIpUDcU6kuyfngiU22J9j5f9GMMnXrloZabl/gQ="; + }; + + "13.3" = fetchurl { + name = "UniversalMac_13.3_22E252_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/002-75537/8250FA0E-0962-46D6-8A90-57A390B9FFD7/UniversalMac_13.3_22E252_Restore.ipsw"; + hash = "sha256-kf4dVYQ5JfJCtKlM4QaQc/miLyKkDrd6Vhi4d+DsnyQ="; + }; + + "13.3.1" = fetchurl { + name = "UniversalMac_13.3.1_22E261_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterFCS/fullrestores/032-66602/418BC37A-FCD9-400A-B4FA-022A19576CD4/UniversalMac_13.3.1_22E261_Restore.ipsw"; + hash = "sha256-bp2bMFKOyVHYo3cXOzVZMmRxlMMmNH78XlSt4f5xy8g="; + }; + + "13.4" = fetchurl { + name = "UniversalMac_13.4_22F66_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw"; + hash = "sha256-RyGSky5BUtINBQRkHfTIV0kpkD8vMkT0W0avfVsuRgY="; + }; + + "13.4.1" = fetchurl { + name = "UniversalMac_13.4.1_22F82_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/042-01877/2F49A9FE-7033-41D0-9D0C-64EFCE6B4C22/UniversalMac_13.4.1_22F82_Restore.ipsw"; + hash = "sha256-67s3efxolHWJRYlXLCKHr7ZA0FO+gneKUPTOwljXhBs="; + }; + + "13.5" = fetchurl { + name = "UniversalMac_13.5_22G74_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerFCS/fullrestores/032-69606/D3E05CDF-E105-434C-A4A1-4E3DC7668DD0/UniversalMac_13.5_22G74_Restore.ipsw"; + hash = "sha256-pCpboSako1uunz3NZFZavCIy6fOVTGWM9cq1vZL50ZE="; + }; + + "13.5.1" = fetchurl { + name = "UniversalMac_13.5.1_22G90_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerFCS/fullrestores/042-25658/2D6BE8DB-5549-4F85-8C54-39FC23BABC68/UniversalMac_13.5.1_22G90_Restore.ipsw"; + hash = "sha256-sWlmMRtUqlJJzS7pCemFTgkjw/hQ4psFBhRTfXq+ZX4="; + }; + + "13.5.2" = fetchurl { + name = "UniversalMac_13.5.2_22G91_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerFCS/fullrestores/042-43686/945D434B-DA5D-48DB-A558-F6D18D11AD69/UniversalMac_13.5.2_22G91_Restore.ipsw"; + hash = "sha256-aJGu4KsLlmle8W+lPwa97aQQb2jeUWZxmE60atLg47g="; + }; + + "13.6" = fetchurl { + name = "UniversalMac_13.6_22G120_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-55833/C0830847-A2F8-458F-B680-967991820931/UniversalMac_13.6_22G120_Restore.ipsw"; + hash = "sha256-m/CVc5uLLV69IPfo3pOPELxEn5hD3iHEpBrlTXNSZyg="; + }; + + "14.0" = fetchurl { + name = "UniversalMac_14.0_23A344_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-54934/0E101AD6-3117-4B63-9BF1-143B6DB9270A/UniversalMac_14.0_23A344_Restore.ipsw"; + hash = "sha256-xaE3uQWj+fxPt7uhar+mJckRkVT5N1n1caockV09lmQ="; + }; + + "14.1" = fetchurl { + name = "UniversalMac_14.1_23B74_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-86430/DBE44960-58A6-4715-948B-D64F33F769BD/UniversalMac_14.1_23B74_Restore.ipsw"; + hash = "sha256-GrcFAMwwbGnm476WawKXcKG0wycejuxXpW5Zl9+qDl4="; + }; + + "14.1.1" = fetchurl { + name = "UniversalMac_14.1.1_23B81_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-89681/55BD14DB-5535-4203-9359-E2C070E43FBE/UniversalMac_14.1.1_23B81_Restore.ipsw"; + hash = "sha256-9/1QInuv4Q0XHe60kZv1UFhbyufvKSQjXA1ihGuD2Zo="; + }; + + "14.2" = fetchurl { + name = "UniversalMac_14.2_23C64_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/052-15117/DC2EE605-ABF3-41AE-9652-D137A8AA5907/UniversalMac_14.2_23C64_Restore.ipsw"; + hash = "sha256-vfxHhMP99iJjVwf76hcqoRj93C1RmKOYJUkrEpfHWsY="; + }; + + "14.2.1" = fetchurl { + name = "UniversalMac_14.2.1_23C71_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/052-22662/ECE59A41-DACC-4CA5-AB23-FDED1A4567DE/UniversalMac_14.2.1_23C71_Restore.ipsw"; + hash = "sha256-fkROGjG4m0lycQGVN/nIuAgdUofssIVio6asXz2exm8="; + }; + + ## Developer Betas or Release Candidates + + "12.4b1" = fetchurl { + name = "UniversalMac_12.4_21F5048e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringSeed/fullrestores/002-85721/A21FF659-8493-4A16-A989-2C3141F48D8C/UniversalMac_12.4_21F5048e_Restore.ipsw"; + hash = "sha256-RHrFu2XKic2pGD63rKqAir9xtUCYYtiS6kyZgJ5shNA="; + }; + + "12.4b2" = fetchurl { + name = "UniversalMac_12.4_21F5058e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringSeed/fullrestores/002-87587/BC2EBE80-F0F4-4B56-BCDC-340E0AD8E985/UniversalMac_12.4_21F5058e_Restore.ipsw"; + hash = "sha256-4z+v7yGJxkQ2YJBZOdwyLSiSxNUBDtLnIH6+/h9OaK4="; + }; + + "12.4b3" = fetchurl { + name = "UniversalMac_12.4_21F5063e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringSeed/fullrestores/002-90009/DA6BD192-1698-48B3-AB6D-9D3A045ED1B1/UniversalMac_12.4_21F5063e_Restore.ipsw"; + hash = "sha256-SH3vPanvtKH1JXN3kJx9Eo9ZbDIn0gKZw3S7w8l1iO4="; + }; + + "12.4b4" = fetchurl { + name = "UniversalMac_12.4_21F5071b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SpringSeed/fullrestores/002-95106/0F7A6388-C4B5-4B8E-B8B2-F62C030699D0/UniversalMac_12.4_21F5071b_Restore.ipsw"; + hash = "sha256-PdoqOKXXpqUNoFtwcz49eG+3k3QXWl4vHlhsZJ94ctU="; + }; + + "12.5b1" = fetchurl { + name = "UniversalMac_12.5_21G5027d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/002-93712/5F234425-6096-43FC-B518-1E9D7B4D0254/UniversalMac_12.5_21G5027d_Restore.ipsw"; + hash = "sha256-5MpM7TvPZ/zquVJuR/Gu8Egi6g3Y4WQsKNi/VJZifCg="; + }; + + "12.5b2" = fetchurl { + name = "UniversalMac_12.5_21G5037d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/012-10648/1CC63FC5-5A22-4A5A-9A7B-C19C8C4A6731/UniversalMac_12.5_21G5037d_Restore.ipsw"; + hash = "sha256-EytzaJmDC8ewbly5d6b2xyZ69Zr99vW6KMNF0uVcIZE="; + }; + + "12.5b3" = fetchurl { + name = "UniversalMac_12.5_21G5046c_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/012-18271/FFF202B2-E4B6-4A3E-9681-42A0F3F81B11/UniversalMac_12.5_21G5046c_Restore.ipsw"; + hash = "sha256-NCxRy9IBJIJ/rEP4bFmJ7CdAyvOgEydWq5L2byvhLgs="; + }; + + "12.5b4" = fetchurl { + name = "UniversalMac_12.5_21G5056b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/012-26441/AE0AC638-2773-49D3-BF84-950B10BF39E9/UniversalMac_12.5_21G5056b_Restore.ipsw"; + hash = "sha256-psj41hDtWvi9gAsKPjcofImvw4WQFKE9GMeVnzu9VEs="; + }; + + "12.5b5" = fetchurl { + name = "UniversalMac_12.5_21G5063a_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/012-36748/52342C55-6598-4A86-AAB8-8901145792C8/UniversalMac_12.5_21G5063a_Restore.ipsw"; + hash = "sha256-AfoRC0VP92mn/96FrgNmIqESCWkpB+xgFJdAXOrPlWE="; + }; + + "12.5rc1" = fetchurl { + name = "UniversalMac_12.5_21G69_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerFCS/fullrestores/012-40368/5DD0A524-140A-46AF-91ED-5F28EA9DEC01/UniversalMac_12.5_21G69_Restore.ipsw"; + hash = "sha256-Cc17jNj74VfRZGForale9wz8xLTvXFUQigsvKNRV6wY="; + }; + + "13.0b1" = fetchurl { + name = "UniversalMac_13.0_22A5266r_Restore.ipsw"; + url = "https://archive.org/download/UniversalMac_13.0_22A5266r_Restore.ipsw/UniversalMac_13.0_22A5266r_Restore.ipsw"; + hash = "sha256-0ZGG/SflRSVYnkpT+a1jGn0TYIl+ADAz34hhKZnP4kk="; + }; + + "13.0b2" = fetchurl { + name = "UniversalMac_13.0_22A5286j_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-30346/9DD787A7-044B-4650-86D4-84E80B6B9C36/UniversalMac_13.0_22A5286j_Restore.ipsw"; + hash = "sha256-M4xkDOnnJVP9JSn+DgNJKpuNHS1MvyZ5bYSIdQ7y8p4="; + }; + + "13.0b3" = fetchurl { + name = "UniversalMac_13.0_22A5295h_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-34274/130176F5-C4CB-4664-A2F0-F29CA1281694/UniversalMac_13.0_22A5295h_Restore.ipsw"; + hash = "sha256-LbNHYPVKVKpwXUmqZInQ1Nr9gaYni4IKjelvzpl72LI="; + }; + + "13.0b3 (22A5295i)" = fetchurl { + name = "UniversalMac_13.0_22A5295i_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-38309/6EDC76A0-4432-4C64-83C5-F43C885A75D6/UniversalMac_13.0_22A5295i_Restore.ipsw"; + hash = "sha256-0V/qRmbpKS9895jX4gykwnE3gYbuJMp/FCdoYP734wg="; + }; + + "13.0b4" = fetchurl { + name = "UniversalMac_13.0_22A5311f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-43316/6CE4D83A-E44C-4DD1-B47F-DE168355662E/UniversalMac_13.0_22A5311f_Restore.ipsw"; + hash = "sha256-KcER556MLoEm9rw0ZuC3UKajSWjMFyyu+cRGEa2gI8g="; + }; + + "13.0b5" = fetchurl { + name = "UniversalMac_13.0_22A5321d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-51397/8EF0874D-388A-4F62-B58A-89F968DD3082/UniversalMac_13.0_22A5321d_Restore.ipsw"; + hash = "sha256-Qm0nDpcyhRgYMC4ubBXKMPH92Ba+/JEAMYySRj6YxMg="; + }; + + "13.0b6" = fetchurl { + name = "UniversalMac_13.0_22A5331f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-61458/80300AD0-69E5-4429-AE3E-A936CA83B5FC/UniversalMac_13.0_22A5331f_Restore.ipsw"; + hash = "sha256-etUkffhqcsud2hhR2d2Ode3HToUMrNHD6RvBvIsN5mg="; + }; + + "13.0b7" = fetchurl { + name = "UniversalMac_13.0_22A5342f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-66750/108EF06D-FBEE-4910-BA83-56A5C9B54110/UniversalMac_13.0_22A5342f_Restore.ipsw"; + hash = "sha256-c88dvRAtVvcw8cwxDy3VqiXnPHPAlMIQVoRASL3YYKk="; + }; + + "13.0b8" = fetchurl { + name = "UniversalMac_13.0_22A5352e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-70113/6F1F08B7-9A1B-48A9-93DB-55EE21121C87/UniversalMac_13.0_22A5352e_Restore.ipsw"; + hash = "sha256-stKXohQRAojbpLQQcvesmipivpLvG0luURGNXc4uncU="; + }; + + "13.0b9" = fetchurl { + name = "UniversalMac_13.0_22A5358e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-71790/AF5A04A6-FF20-44C1-9BFF-43081BDB4D8C/UniversalMac_13.0_22A5358e_Restore.ipsw"; + hash = "sha256-DV/E3WyawFJTJ6jbIiNdusZqrI8J8q7v0QyTL97m1Sg="; + }; + + "13.0b10" = fetchurl { + name = "UniversalMac_13.0_22A5365d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-83054/16ECAA12-3A1B-4663-B49B-B1563ECD4314/UniversalMac_13.0_22A5365d_Restore.ipsw"; + hash = "sha256-nfWXOgiFgEAfXIgouLFTsNeGAtGfOrn/5geG3Qpxjt0="; + }; + + "13.0b11" = fetchurl { + name = "UniversalMac_13.0_22A5373b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022SummerSeed/fullrestores/012-84563/2FC38C63-3213-4BB6-8E41-2B066332CBE6/UniversalMac_13.0_22A5373b_Restore.ipsw"; + hash = "sha256-VRE4ZVgk1sFmH4xqBgQPLZ1V+uBqyrhENUHbf526PgY="; + }; + + "13.0rc1" = fetchurl { + name = "UniversalMac_13.0_22A379_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/071-08994/1118ADF4-1CC9-4554-9333-B1F64CF0C820/UniversalMac_13.0_22A379_Restore.ipsw"; + hash = "sha256-1mWHFt/bzk0/yyE5aO79abkjhHEnkWL6hC4J03QRxkc="; + }; + + "13.1b1" = fetchurl { + name = "UniversalMac_13.1_22C5033e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/012-82062/10E6B723-51B8-4B2C-BA3B-12A18ED4E719/UniversalMac_13.1_22C5033e_Restore.ipsw"; + hash = "sha256-wpVJLiDvvYWxi/eUoV0fcQBJ/AFnq9gh8xex4X8mHI0="; + }; + + "13.1b2" = fetchurl { + name = "UniversalMac_13.1_22C5044e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/032-02019/670C9BA6-67EB-4AE6-A02E-88976F6F3118/UniversalMac_13.1_22C5044e_Restore.ipsw"; + hash = "sha256-QlMUsWk5mHtz8VnwHlnGy/vnLAaIJOKF9HF4nBs9i8I="; + }; + + "13.1b3" = fetchurl { + name = "UniversalMac_13.1_22C5050e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/032-06252/946CBF92-8F27-49B1-A692-81F54C73D2F0/UniversalMac_13.1_22C5050e_Restore.ipsw"; + hash = "sha256-y9ZIejk2Zst/1KwYTRZ68jKS0iTGZ2Zu+U1PFZhqftk="; + }; + + "13.1b4" = fetchurl { + name = "UniversalMac_13.1_22C5059b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2022FallSeed/fullrestores/032-08112/957EA73A-7C95-4B3C-B99C-2C2C47555832/UniversalMac_13.1_22C5059b_Restore.ipsw"; + hash = "sha256-6wQVedVUfWjj60eJJgZFgP3lOILsAiIC2swhKcJxKn4="; + }; + + "13.2b1" = fetchurl { + name = "UniversalMac_13.2_22D5027d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-12640/6B472BA3-E678-4251-92D1-7AA23B66F53E/UniversalMac_13.2_22D5027d_Restore.ipsw"; + hash = "sha256-qZMg/+rlTWeKkmIeW5kP2vYfNU15t6GElXkpvxgPWVQ="; + }; + + "13.2b2" = fetchurl { + name = "UniversalMac_13.2_22D5038i_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-33181/62ECE236-5806-4136-AD08-EDC026FD80A5/UniversalMac_13.2_22D5038i_Restore.ipsw"; + hash = "sha256-hW8M6uBCh6mTD+2Q7+OiB/UuKFK8FbEKj/0XeH0MbfE="; + }; + + "13.3b1" = fetchurl { + name = "UniversalMac_13.3_22E5219e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-01932/676E0981-4535-4942-A4AE-E14C604CE719/UniversalMac_13.3_22E5219e_Restore.ipsw"; + hash = "sha256-Oagbaroj5FSDc+0oP/+UlZIXPcj4wa+zyr8KDy13vU0="; + }; + + "13.3b2" = fetchurl { + name = "UniversalMac_13.3_22E5230e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-54760/AE02E378-FD59-474D-93AB-C52617103C72/UniversalMac_13.3_22E5230e_Restore.ipsw"; + hash = "sha256-08iLueGAXbjbKu07JqYKXagyKMZoTjlcfdjWCS8eysk="; + }; + + "13.3b3" = fetchurl { + name = "UniversalMac_13.3_22E5236f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-60411/1DDA996F-B620-4770-8FFE-87AB2043784D/UniversalMac_13.3_22E5236f_Restore.ipsw"; + hash = "sha256-PVsd6mXMPDXAr7kj67qzGnp426AgCm5JqrsxfHMO+hM="; + }; + + "13.3b4" = fetchurl { + name = "UniversalMac_13.3_22E5246b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/032-63669/7C0F9BA8-35C0-457F-AF56-6943D58A2CDB/UniversalMac_13.3_22E5246b_Restore.ipsw"; + hash = "sha256-7rPfsg6CxIsZl7B012EwrV5fq6QY2PZPIsyWbT3sy40="; + }; + + "13.4b1" = fetchurl { + name = "UniversalMac_13.4_22F5027f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-69187/B11709E0-1CF5-4460-A069-D12E1243E2AD/UniversalMac_13.4_22F5027f_Restore.ipsw"; + hash = "sha256-ZI7tCIbLXKfDLPtniSrb0dkurzZqhbLM5Ccf869vJbs="; + }; + + "13.4b2" = fetchurl { + name = "UniversalMac_13.4_22F5037d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-69885/ECFA1532-C633-4ACE-9D2C-3B5FD19510D4/UniversalMac_13.4_22F5037d_Restore.ipsw"; + hash = "sha256-NsP4lzPu89CTBiIUDa7MaZap4pObbCb7Bky+qORYpmM="; + }; + + "13.4b3" = fetchurl { + name = "UniversalMac_13.4_22F5049e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-76661/573284E7-4A4A-440C-AC01-6065C7A8E667/UniversalMac_13.4_22F5049e_Restore.ipsw"; + hash = "sha256-1V9d90PgVU80HzF7aXXhVSJnX4zjOOl7yDHquvlEqno="; + }; + + "13.4b4" = fetchurl { + name = "UniversalMac_13.4_22F5059b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-79565/BA9CBFB7-152C-4FB6-B0B3-47769997BFA1/UniversalMac_13.4_22F5059b_Restore.ipsw"; + hash = "sha256-W7c3BIQcFQD+RdgEnjAn/tvSK2LylyqZRpYD2ZlT5b8="; + }; + + "13.4rc1" = fetchurl { + name = "UniversalMac_13.4_22F62_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-44024/731F1533-53BE-4CEB-AA05-74F333CA904A/UniversalMac_13.4_22F62_Restore.ipsw"; + hash = "sha256-5oeroNSN6DX8ViVZGTUzGh9rPE8GdF7/7AMLx1FOQbM="; + }; + + "13.4rc2" = fetchurl { + name = "UniversalMac_13.4_22F63_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-83954/6E06237C-1B56-4932-A8E1-3A07A3EE03A8/UniversalMac_13.4_22F63_Restore.ipsw"; + hash = "sha256-z9XMRmiAtfgFnw1sDOZ+gjFqySMzij9vlCQFLyZl1Hk="; + }; + + # Was actually in the release channel but I think it fits here better + "13.4.1 (WWDC23 M2 Macs)" = fetchurl { + name = "UniversalMac_13.4.1_22F2083_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/042-01864/A8378F91-BA71-40DF-8F0D-606A16F1836B/UniversalMac_13.4.1_22F2083_Restore.ipsw"; + hash = "sha256-67s3efxolHWJRYlXLCKHr7ZA0FO+gneKUPTOwljXhBs="; + }; + + "13.5b1" = fetchurl { + name = "UniversalMac_13.5_22G5027e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-86178/CE6C5645-C5C3-41A9-B986-D5F0BD7BB10B/UniversalMac_13.5_22G5027e_Restore.ipsw"; + hash = "sha256-XmJ+j6pvTZodqO/Cvx2QLcl43O6+FJBKz5atOaK459Y="; + }; + + "13.5b2" = fetchurl { + name = "UniversalMac_13.5_22G5038d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-92523/E476F5EC-D046-4A76-889B-F19DA354459E/UniversalMac_13.5_22G5038d_Restore.ipsw"; + hash = "sha256-3PohpMoQX46m10C/H+UPt2HzQRTTiZQ8T39oLPW38vs="; + }; + + "13.5b3" = fetchurl { + name = "UniversalMac_13.5_22G5048d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/032-93679/1D39F2AC-8FD4-46A3-A159-478C76472B16/UniversalMac_13.5_22G5048d_Restore.ipsw"; + hash = "sha256-9v0sJNI9WyRXbLooLc/swjgssBaNHVLz+TLr6LSrhUk="; + }; + + "13.5b4" = fetchurl { + name = "UniversalMac_13.5_22G5059d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/042-03209/55CBE04D-FD90-483B-A6D7-45E0FBC1C94F/UniversalMac_13.5_22G5059d_Restore.ipsw"; + hash = "sha256-b0KWmAvWoHuIjNt9R9hrSj4bWbhTtCN2aMPIN/eGVQ4="; + }; + + "13.5b5" = fetchurl { + name = "UniversalMac_13.5_22G5072a_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringSeed/fullrestores/042-09570/8DA0B0AA-6FD4-42C4-A54E-BC0D53B92AC0/UniversalMac_13.5_22G5072a_Restore.ipsw"; + hash = "sha256-YQjEilnurIVhSwHSeMGHcDtWDMQfB2MPprwfyQZHLZM="; + }; + + "14.0b1" = fetchurl { + name = "UniversalMac_14.0_23A5257q_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/032-94355/CBE8CBE1-750D-487E-A393-B90FEF60CEBA/UniversalMac_14.0_23A5257q_Restore.ipsw"; + hash = "sha256-+81gI6uvp/Ru2XMRlYZh9QNYpPKSApHQFPcoScd2Pqs="; + }; + + "14.0b2" = fetchurl { + name = "UniversalMac_14.0_23A5276g_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/032-95861/67600C59-8516-4A46-B9D7-4007D395CEF5/UniversalMac_14.0_23A5276g_Restore.ipsw"; + hash = "sha256-q9WWcgfNkgKNrIPMExmzwZNZIFXdlqrg3WT1inxLLBA="; + }; + + "14.0b3" = fetchurl { + name = "UniversalMac_14.0_23A5286g_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-06324/379026FA-C14F-4095-99FD-19F607D10EBF/UniversalMac_14.0_23A5286g_Restore.ipsw"; + hash = "sha256-vVHCrkrvNgehNWGnnXUwF1n9tJcb1wuifQi4i8BsD5A="; + }; + + "14.0b3 (23A5286i)" = fetchurl { + name = "UniversalMac_14.0_23A5286i_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-13887/3B4075C1-B695-49EA-82D9-4B720699D341/UniversalMac_14.0_23A5286i_Restore.ipsw"; + hash = "sha256-O97KjU8hkPVoY9VeEPhsWs5dWTh3OaFNrrDrlNcTGCs="; + }; + + "14.0b4" = fetchurl { + name = "UniversalMac_14.0_23A5301h_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-25548/9EA6EC3D-5A7D-4D53-A17C-70EE71393921/UniversalMac_14.0_23A5301h_Restore.ipsw"; + hash = "sha256-B6smMQU50hv7V7/cSvT6RmOPquSXdwX9BxQqKdirLHo="; + }; + + "14.0b5" = fetchurl { + name = "UniversalMac_14.0_23A5312d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-27168/7E046825-8EBA-4AAE-8ECC-DDD51B9306D2/UniversalMac_14.0_23A5312d_Restore.ipsw"; + hash = "sha256-hx1/xFpCwo1+KC52OtMtDFxlLHIWHetrk4NDw0kUP9s="; + }; + + "14.0b6" = fetchurl { + name = "UniversalMac_14.0_23A5328b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-37824/AA6B32A0-3C2C-4BEB-95A1-64E601934330/UniversalMac_14.0_23A5328b_Restore.ipsw"; + hash = "sha256-MDOpUQewfU25Ns50RvZNUWwd9FaNjl3uBkbbOMqCn8A="; + }; + + "14.0b7" = fetchurl { + name = "UniversalMac_14.0_23A5337a_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SummerSeed/fullrestores/042-41500/D1789AEF-013B-4112-8A1E-401589023267/UniversalMac_14.0_23A5337a_Restore.ipsw"; + hash = "sha256-UVBDbNQ0rtkjwUkgktcTm8jkweGNfzrOYTSvQ9yMNoc="; + }; + + "14.0rc1" = fetchurl { + name = "UniversalMac_14.0_23A339_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/002-81996/596571C1-9856-4BB3-B5BF-B5A48F4B406E/UniversalMac_14.0_23A339_Restore.ipsw"; + hash = "sha256-JjUOHbqJOI3TkEbVc8pqikNjr+gkoQhG2fbaKZ4dLf4="; + }; + + "14.1b1" = fetchurl { + name = "UniversalMac_14.1_23B5046f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-60177/C4B6F5B3-8B66-461A-A048-4A9925F36FCD/UniversalMac_14.1_23B5046f_Restore.ipsw"; + hash = "sha256-nGU5Jfpa0VVv3aYk97M3bhmRRNa8rS07EQxBMoiQh3U="; + }; + + "14.1b2" = fetchurl { + name = "UniversalMac_14.1_23B5056e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-65885/0FA6C4A7-C21A-4A5F-84C8-8FEE0D98A153/UniversalMac_14.1_23B5056e_Restore.ipsw"; + hash = "sha256-Xs55AzexOAs/201gFGOeidXN7Xlju0bAF0oiiv4G/Jc="; + }; + + "14.1b3" = fetchurl { + name = "UniversalMac_14.1_23B5067a_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-73325/B24FC9CF-34D1-44A6-B977-FA718FE83DEB/UniversalMac_14.1_23B5067a_Restore.ipsw"; + hash = "sha256-V+ZrkrBKCH0gqji5Usw/xN8T+RpZdNvkDFCnWTauAaU="; + }; + + "14.1rc1" = fetchurl { + name = "UniversalMac_14.1_23B73_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-10900/347B734E-BC0B-41FA-9671-8000FCB5B0BB/UniversalMac_14.1_23B73_Restore.ipsw"; + hash = "sha256-nZGVpR+0VzPHeHZLoU4dZ8Q5gSUbpqeVt5pgJvzuMco="; + }; + + "14.2b1" = fetchurl { + name = "UniversalMac_14.2_23C5030f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-71093/ECEFE157-E28B-40B4-9F21-CFD075129029/UniversalMac_14.2_23C5030f_Restore.ipsw"; + hash = "sha256-AOU19qgCjWJi5Zi2N0xVNYHzdhS/z+i4pndqubQWEME="; + }; + + "14.2b2" = fetchurl { + name = "UniversalMac_14.2_23C5041e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-92143/F642F928-DEE0-4C3F-A416-85745C778855/UniversalMac_14.2_23C5041e_Restore.ipsw"; + hash = "sha256-mMhPpETzF1AQRm0tfMNwyn6czs22DxNYYftxDPZYlnA="; + }; + + "14.2b3" = fetchurl { + name = "UniversalMac_14.2_23C5047e_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallSeed/fullrestores/042-99526/0A9085CC-B36A-400A-86D8-B9FE23B1DA29/UniversalMac_14.2_23C5047e_Restore.ipsw"; + hash = "sha256-bhQzFlM2DejjkeFs9nlTsdPIn4ntVmx1GcWw7Cjg3m0="; + }; + + "14.2b4" = fetchurl { + name = "UniversalMac_14.2_23C5055b_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterFCS/fullrestores/052-05962/A8344C85-06CE-43C7-9FF6-7B477A4DB8BA/UniversalMac_14.2_23C5055b_Restore.ipsw"; + hash = "sha256-TLdLTiIkVeiogxGD4+/jxhiQFsjpufNsEnXlX+Blhkc="; + }; + + "14.2rc1" = fetchurl { + name = "UniversalMac_14.2_23C63_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/052-14744/7215DBB4-BEAD-4A9C-9202-276ABA6832D5/UniversalMac_14.2_23C63_Restore.ipsw"; + hash = "sha256-knjCuw4ib94IgvQxbAh3mShq3PHceaDV7hUoVlmn4B0="; + }; + + "14.3b1" = fetchurl { + name = "UniversalMac_14.3_23D5033f_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/052-04657/4126C431-B3EA-42C2-BC36-ED83715B8700/UniversalMac_14.3_23D5033f_Restore.ipsw"; + hash = "sha256-IYMDLuuYMSkXvPigERasaWdBCz/Sw4CPBurrFLMMuyo="; + }; + + "14.3b2" = fetchurl { + name = "UniversalMac_14.3_23D5043d_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023WinterSeed/fullrestores/052-23267/60655998-DD9A-40BF-BFAB-6D2A4442DE83/UniversalMac_14.3_23D5043d_Restore.ipsw"; + hash = "sha256-fxrABSY7yqGu64zoS+YIn1XbCH7jBKUfs62Fh3dI3RY="; + }; +} From 552b4d8492766bee99433a8ff7d6fcdf86d0439e Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Aug 2023 12:44:59 +1000 Subject: [PATCH 07/11] system: add nix-darwin VMs using `tart` --- ...2aaee5634a4a38084d7b498490fccfe442ad8c46ee | 1 + eval-config.nix | 1 + modules/module-list.nix | 1 + modules/programs/zsh/default.nix | 1 + modules/virtualisation/build-vm.nix | 32 +++ modules/virtualisation/tart-vm.nix | 264 ++++++++++++++++++ 6 files changed, 300 insertions(+) create mode 100644 doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee create mode 100644 modules/virtualisation/build-vm.nix create mode 100644 modules/virtualisation/tart-vm.nix diff --git a/doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee b/doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee new file mode 100644 index 000000000..4f4dd441b --- /dev/null +++ b/doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee @@ -0,0 +1 @@ +. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh diff --git a/eval-config.nix b/eval-config.nix index cd14493d0..84afa703e 100644 --- a/eval-config.nix +++ b/eval-config.nix @@ -28,4 +28,5 @@ in inherit (eval) _module; system = eval.config.system.build.toplevel; + inherit (eval.config.system.build) vm; } diff --git a/modules/module-list.nix b/modules/module-list.nix index e87f696ca..6350ed6fe 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -100,4 +100,5 @@ ./programs/zsh ./homebrew.nix ./users + ./virtualisation/build-vm.nix ] diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index bbf8ad9e0..565e2c81c 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -220,6 +220,7 @@ in ]; environment.etc."zshenv".knownSha256Hashes = [ + "149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee" # nix-darwin VM "d07015be6875f134976fce84c6c7a77b512079c1c5f9594dfa65c70b7968b65f" # DeterminateSystems installer ]; diff --git a/modules/virtualisation/build-vm.nix b/modules/virtualisation/build-vm.nix new file mode 100644 index 000000000..7d2c09ef6 --- /dev/null +++ b/modules/virtualisation/build-vm.nix @@ -0,0 +1,32 @@ +{ config, extendModules, lib, ... }: +let + + inherit (lib) mkOption; + + vmVariant = extendModules { + modules = [ ./tart-vm.nix ]; + }; +in +{ + options = { + + virtualisation.vmVariant = mkOption { + description = '' + Machine configuration to be added for the vm script produced by `darwin-rebuild build-vm`. + ''; + inherit (vmVariant) type; + default = {}; + visible = "shallow"; + }; + + }; + + config = { + + system.build = { + vm = lib.mkDefault config.virtualisation.vmVariant.system.build.vm; + }; + + }; +} + diff --git a/modules/virtualisation/tart-vm.nix b/modules/virtualisation/tart-vm.nix new file mode 100644 index 000000000..b4a545f5e --- /dev/null +++ b/modules/virtualisation/tart-vm.nix @@ -0,0 +1,264 @@ +{ config, pkgs, lib, ... }: + +{ + config = let + # This file is 12GB, you'll want to download it yourself and then add it to the Nix Store before running the VM script + # $ aria2c -x4 https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw + # $ nix-store --add UniversalMac_13.4_22F66_Restore.ipsw + ipsw = pkgs.fetchurl { + name = "UniversalMac_13.4_22F66_Restore.ipsw"; + url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw"; + hash = "sha256-RyGSky5BUtINBQRkHfTIV0kpkD8vMkT0W0avfVsuRgY="; + }; + + nix-installer = pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "nix-installer"; + version = "0.15.1"; + + src = pkgs.fetchurl { + url = "https://github.com/DeterminateSystems/${finalAttrs.pname}/releases/download/v${finalAttrs.version}/${finalAttrs.pname}-aarch64-darwin"; + hash = "sha256-mcYiRv1KD7F83MJTaV4++dXroPBjelvbGYeSM0Lzdc8="; + }; + + dontUnpack = true; + + installPhase = "install -Dm555 $src $out/bin/${finalAttrs.pname}"; + + meta.mainProgram = finalAttrs.pname; + }); + + tart = "${lib.getBin pkgs.tart}/bin/tart"; + jq = lib.getExe pkgs.jq; + vncdo = "${lib.getBin pkgs.vncdo}/bin/vncdo"; + passh = "${lib.getBin pkgs.passh}/bin/passh"; + retry = "${lib.getBin pkgs.retry}/bin/retry"; + timeout = "${lib.getBin pkgs.coreutils}/bin/timeout"; + sshOptions = "-o UserKnownHostsFile=$TART_HOME/known_hosts -F /dev/null -i $TART_HOME/id_ed25519"; + + # NOTE: only 15GiB necessary for macOS install + startVM = '' + set -euxo pipefail + + # Allows trap ERR to work with `set -e` + set -E + + # For job control + set -m + + # If we fail during installation, pass control back to `tart run` so users can kill the VM with Ctrl-C + trap fg ERR + + unset SSH_AUTH_SOCK + + export TART_HOME=$PWD/darwin-vm + STATE_FILE=$TART_HOME/darwin-vm.state + + # states: null, uninstalled, macos-possibly-finished, macos-installed, installation-complete + VM_STATE=$(cat $STATE_FILE || echo "null") + VM_RUNNING=$(${tart} list --format json | ${jq} '.[] | select(.Name == "darwin-vm") | .Running') + + if [[ "$VM_STATE" != "installation-complete" ]]; then + if [[ "$VM_RUNNING" == "true" ]]; then + ${tart} stop darwin-vm + fi + + if [[ "$VM_STATE" != "uninstalled" && "$VM_STATE" != "null" ]]; then + ${tart} delete darwin-vm + fi + + if ! ${tart} list | grep darwin-vm >/dev/null 2>&1; then + ${tart} create darwin-vm --from-ipsw ${ipsw} --disk-size 35 + echo uninstalled > $STATE_FILE + + # To avoid running into "Failed to lock auxiliary storage." we need to wait a bit after creating a VM + sleep 5 + fi + + (${tart} run --vnc-experimental --no-graphics darwin-vm | tee $TART_HOME/tart.out) & + + # Give it time to start VM and VNC server + sleep 5 + VNC_URL=$(grep --only 'vnc://.*\d' $TART_HOME/tart.out) + VNC_URL=''${VNC_URL//@/:} + declare -a array=(''${VNC_URL//:/ }) + VNC_PASSWORD=''${array[2]} + VNC_ADDRESS=''${array[3]} + VNC_PORT=''${array[4]} + + function vncdo { + echo Sending VNC inputs for $1 + ${timeout} 15s ${vncdo} -p $VNC_PASSWORD -s $VNC_ADDRESS::$VNC_PORT capture $TART_HOME/vms/darwin-vm/$(date +%F_%H-%M-%S).png "''${@:2}" + } + + sleep 60 + vncdo "Getting Started" key space + + sleep 30 + vncdo "Language" key enter + + sleep 30 + vncdo "Select Your Country or Region" type australia pause 0.3 key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Written and Spoken Languages" key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Accessibility" key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Data & Privacy" key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Migration Assistant" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + + sleep 10 + vncdo "Sign in with Your Apple ID" key shift-tab pause 0.3 key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Are you sure you want to skip signing in with an Apple ID?" key tab pause 0.3 key space + + sleep 10 + vncdo "Terms and Conditions" key shift-tab pause 0.3 key space + + sleep 10 + vncdo "I have read and agree to the macOS Software License Agreement." key tab pause 0.3 key space + + sleep 10 + ${vncdo} type admin pause 0.3 key tab pause 0.3 key tab pause 0.3 type admin pause 0.3 key tab pause 0.3 type admin pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + + sleep 10 + vncdo "Enable Location Services" key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Are you sure you don't want to use Location Services?" key tab pause 0.3 key space + + sleep 10 + vncdo "Select Your Time Zone" key tab pause 0.3 type UTC pause 0.3 key enter pause 0.3 key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Analytics" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Screen Time" key tab pause 0.3 key space + + sleep 10 + vncdo "Siri" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space + + sleep 10 + vncdo "Choose Your Look" key shift-tab pause 0.3 key space + + sleep 10 + + # macOS installation possibly complete + echo macos-possibly-finished > $STATE_FILE + + vncdo "enabling Voice Over" key alt-f5 pause 5 key v + + vncdo "opening System Settings" move 0 0 click 1 pause 0.3 key down key down key enter + + sleep 10 + vncdo "navigating to Sharing" key up pause 3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + + sleep 10 + vncdo "enabling Screen Sharing" key tab pause 0.3 key tab pause 0.3 key space + + sleep 10 + vncdo "enabling Remote Login" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + + vncdo "enabling Full Disk Access" key tab key space pause 10 key tab key space pause 1 key shift-tab key shift-tab key space + + vncdo "disabling Voice Over" key alt-f5 + + # Installation complete, tart/AV private VNC server no longer necessary + rm $TART_HOME/tart.out + + export VM_IP=$(${tart} ip darwin-vm) + + if [[ -f $TART_HOME/id_ed25519 ]]; then + rm $TART_HOME/id_ed25519 $TART_HOME/id_ed25519.pub + fi + + ssh-keygen -t ed25519 -f $TART_HOME/id_ed25519 -N "" + + # Sometimes it takes time for this to succeed after enabling SSH + ${retry} -d 5 -t 10 ${pkgs.writeShellScript "ssh-keyscan-vm" '' + set -eux + ssh-keyscan -t ed25519 $VM_IP | tee $TART_HOME/known_hosts + if [[ ! -s $TART_HOME/known_hosts ]]; then + exit 1 + fi + ''} + + # Use SSH keys + ${passh} -p admin ssh-copy-id ${sshOptions} admin@$VM_IP + + if [[ $(ssh ${sshOptions} admin@$VM_IP "echo yo") == "yo" ]]; then + echo macos-installed > $STATE_FILE + else + echo "error: couldn't SSH into VM" + echo "press Ctrl-C to close the VM, then rerun the script" + exit 1 + fi + + # Enable passwordless sudo + ${passh} -p admin ssh ${sshOptions} admin@$VM_IP "sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo 'admin ALL=(ALL) NOPASSWD: ALL' | EDITOR=tee visudo /etc/sudoers.d/admin-nopasswd\"" + + # Install Nix + scp ${sshOptions} ${lib.getExe nix-installer} admin@$VM_IP:/tmp/nix-installer + + ssh ${sshOptions} admin@$VM_IP /tmp/nix-installer install --no-confirm + + # Fixes `command not found: nix` for nix-copy-closure + cat ${../../doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee} | ssh ${sshOptions} admin@$VM_IP "sudo tee /etc/zshenv" + + ssh ${sshOptions} admin@$VM_IP "sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak" + + # Necessary for nix-copy-closure + echo "trusted-users = admin" | ssh ${sshOptions} admin@$VM_IP "sudo tee -a /etc/nix/nix.conf" + + ssh ${sshOptions} admin@$VM_IP "sudo launchctl kickstart -k system/org.nixos.nix-daemon" + + VM_PUBLIC_KEY=$(ssh ${sshOptions} admin@$VM_IP "base64 -i /etc/ssh/ssh_host_ed25519_key.pub") + + NIX_SSHOPTS="${sshOptions}" nix-copy-closure --to admin@$VM_IP ${config.system.build.toplevel} + + # Restore the version without `trusted-users` to match known SHA256 hashes + ssh ${sshOptions} admin@$VM_IP "sudo mv /etc/nix/nix.conf.bak /etc/nix/nix.conf" + + ssh ${sshOptions} admin@$VM_IP "${config.system.build.toplevel}/sw/bin/darwin-rebuild activate" + + if [[ $(ssh ${sshOptions} admin@$VM_IP "realpath /run/current-system") == ${config.system.build.toplevel} ]]; then + echo installation-complete > $STATE_FILE + else + echo "error: nix-darwin installation did not complete successfully" + echo "press Ctrl-C to close the VM, then rerun the script" + exit 1 + fi + + ${timeout} 30s ssh ${sshOptions} $VM_USER@$VM_IP "sudo bash -c 'rm /etc/sudoers.d/admin-nopasswd ~/.ssh/authorized_keys; shutdown -h now'" || true + + sleep 30 + + VM_RUNNING=$(${tart} list --format json | ${jq} '.[] | select(.Name == "darwin-vm") | .Running') + + if [[ "$VM_RUNNING" == "true" ]]; then + echo shutdown-failed > $STATE_FILE + echo "error: failed to shut down VM" + echo "forcibly stopping VM, please rerun the script" + ${tart} stop --timeout 5 darwin-vm + exit 1 + fi + fi + + ${tart} run darwin-vm + ''; + in { + environment.etc."nix/nix.conf".force = true; + + system.build.vm = pkgs.runCommand "run-darwin-vm" { } '' + mkdir -p $out/bin + ln -s ${config.system.build.toplevel} $out/system + ln -s ${pkgs.writeShellScript "run-darwin-vm" startVM} $out/bin/run-darwin-vm + ''; + }; +} From 735b3dbfde21a2b2472bd17aee31e03849ef4933 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Aug 2023 12:45:50 +1000 Subject: [PATCH 08/11] DONOTMERGE! for testing the VM $ cd tart $ nix run ~/Code/nix-darwin/modules/examples/flake#darwinConfigurations.simple.vm --override-input nix-darwin lnd --- modules/examples/flake/flake.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index 865056295..d2cc61313 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -2,7 +2,7 @@ description = "Example Darwin system flake"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/6cee3b5893090b0f5f0a06b4cf42ca4e60e5d222"; nix-darwin.url = "github:LnL7/nix-darwin"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; }; @@ -35,7 +35,9 @@ system.stateVersion = 4; # The platform the configuration will be used on. - nixpkgs.hostPlatform = "x86_64-darwin"; + nixpkgs.hostPlatform = "aarch64-darwin"; # TODO: debug + + nixpkgs.config.allowUnfree = true; # TODO: debug }; in { From 724afd29aae9fdc9d1cbd02eb675623234e86cce Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Wed, 30 Aug 2023 04:49:11 +1000 Subject: [PATCH 09/11] tart-vm: support specifying username --- modules/virtualisation/tart-vm.nix | 56 +++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/modules/virtualisation/tart-vm.nix b/modules/virtualisation/tart-vm.nix index b4a545f5e..31f9e84f7 100644 --- a/modules/virtualisation/tart-vm.nix +++ b/modules/virtualisation/tart-vm.nix @@ -1,6 +1,21 @@ { config, pkgs, lib, ... }: { + options = with lib; { + virtualisation.initialUser = mkOption { + type = types.str; + default = if builtins.length (builtins.attrNames config.users.users) > 0 then builtins.elemAt (naturalSort (builtins.attrNames config.users.users)) 0 else "admin"; + defaultText = literalExpression '' + if builtins.length (builtins.attrNames config.users.users) > 0 then builtins.elemAt (lib.naturalSort (builtins.attrNames config.users.users)) 0 else "admin"; + ''; + description = mdDoc '' + The user to create the VM with. + + This defaults to the first user defined in `users.users`, otherwise it will default to `admin`. + ''; + }; + }; + config = let # This file is 12GB, you'll want to download it yourself and then add it to the Nix Store before running the VM script # $ aria2c -x4 https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw @@ -33,7 +48,12 @@ passh = "${lib.getBin pkgs.passh}/bin/passh"; retry = "${lib.getBin pkgs.retry}/bin/retry"; timeout = "${lib.getBin pkgs.coreutils}/bin/timeout"; + + username = config.virtualisation.initialUser; + user = config.users.users.${username}; + sshOptions = "-o UserKnownHostsFile=$TART_HOME/known_hosts -F /dev/null -i $TART_HOME/id_ed25519"; + sshDestination = "${sshOptions} ${username}@$VM_IP"; # NOTE: only 15GiB necessary for macOS install startVM = '' @@ -57,6 +77,8 @@ VM_STATE=$(cat $STATE_FILE || echo "null") VM_RUNNING=$(${tart} list --format json | ${jq} '.[] | select(.Name == "darwin-vm") | .Running') + VM_PASS=admin + if [[ "$VM_STATE" != "installation-complete" ]]; then if [[ "$VM_RUNNING" == "true" ]]; then ${tart} stop darwin-vm @@ -124,7 +146,7 @@ vncdo "I have read and agree to the macOS Software License Agreement." key tab pause 0.3 key space sleep 10 - ${vncdo} type admin pause 0.3 key tab pause 0.3 key tab pause 0.3 type admin pause 0.3 key tab pause 0.3 type admin pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + vncdo "Create a Computer Account" type "${user.name}" pause 0.3 key tab pause 0.3 type "${username}" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space sleep 10 vncdo "Enable Location Services" key shift-tab pause 0.3 key space @@ -190,9 +212,9 @@ ''} # Use SSH keys - ${passh} -p admin ssh-copy-id ${sshOptions} admin@$VM_IP + ${passh} -p "$VM_PASS" ssh-copy-id ${sshDestination} - if [[ $(ssh ${sshOptions} admin@$VM_IP "echo yo") == "yo" ]]; then + if [[ $(ssh ${sshDestination} "echo yo") == "yo" ]]; then echo macos-installed > $STATE_FILE else echo "error: couldn't SSH into VM" @@ -201,33 +223,33 @@ fi # Enable passwordless sudo - ${passh} -p admin ssh ${sshOptions} admin@$VM_IP "sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo 'admin ALL=(ALL) NOPASSWD: ALL' | EDITOR=tee visudo /etc/sudoers.d/admin-nopasswd\"" + ${passh} -p "$VM_PASS" ssh ${sshDestination} "sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo '%admin ALL=(ALL) NOPASSWD: ALL' | VISUAL=tee visudo /etc/sudoers.d/admin-nopasswd\"" # Install Nix - scp ${sshOptions} ${lib.getExe nix-installer} admin@$VM_IP:/tmp/nix-installer + scp ${sshOptions} ${lib.getExe nix-installer} ${username}@$VM_IP:/tmp/nix-installer - ssh ${sshOptions} admin@$VM_IP /tmp/nix-installer install --no-confirm + ssh ${sshDestination} /tmp/nix-installer install --no-confirm # Fixes `command not found: nix` for nix-copy-closure - cat ${../../doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee} | ssh ${sshOptions} admin@$VM_IP "sudo tee /etc/zshenv" + cat ${../../doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee} | ssh ${sshDestination} "sudo tee /etc/zshenv" - ssh ${sshOptions} admin@$VM_IP "sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak" + ssh ${sshDestination} "sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak" # Necessary for nix-copy-closure - echo "trusted-users = admin" | ssh ${sshOptions} admin@$VM_IP "sudo tee -a /etc/nix/nix.conf" + echo "trusted-users = ${username}" | ssh ${sshDestination} "sudo tee -a /etc/nix/nix.conf" - ssh ${sshOptions} admin@$VM_IP "sudo launchctl kickstart -k system/org.nixos.nix-daemon" + ssh ${sshDestination} "sudo launchctl kickstart -k system/org.nixos.nix-daemon" - VM_PUBLIC_KEY=$(ssh ${sshOptions} admin@$VM_IP "base64 -i /etc/ssh/ssh_host_ed25519_key.pub") + VM_PUBLIC_KEY=$(ssh ${sshDestination} "base64 -i /etc/ssh/ssh_host_ed25519_key.pub") - NIX_SSHOPTS="${sshOptions}" nix-copy-closure --to admin@$VM_IP ${config.system.build.toplevel} + NIX_SSHOPTS="${sshOptions}" nix-copy-closure --to ${username}@$VM_IP ${config.system.build.toplevel} # Restore the version without `trusted-users` to match known SHA256 hashes - ssh ${sshOptions} admin@$VM_IP "sudo mv /etc/nix/nix.conf.bak /etc/nix/nix.conf" + ssh ${sshDestination} "sudo mv /etc/nix/nix.conf.bak /etc/nix/nix.conf" - ssh ${sshOptions} admin@$VM_IP "${config.system.build.toplevel}/sw/bin/darwin-rebuild activate" + ssh ${sshDestination} "${config.system.build.toplevel}/sw/bin/darwin-rebuild activate" - if [[ $(ssh ${sshOptions} admin@$VM_IP "realpath /run/current-system") == ${config.system.build.toplevel} ]]; then + if [[ $(ssh ${sshDestination} "realpath /run/current-system") == ${config.system.build.toplevel} ]]; then echo installation-complete > $STATE_FILE else echo "error: nix-darwin installation did not complete successfully" @@ -235,7 +257,7 @@ exit 1 fi - ${timeout} 30s ssh ${sshOptions} $VM_USER@$VM_IP "sudo bash -c 'rm /etc/sudoers.d/admin-nopasswd ~/.ssh/authorized_keys; shutdown -h now'" || true + ${timeout} 30s ssh ${sshDestination} "sudo bash -c 'rm /etc/sudoers.d/admin-nopasswd ~/.ssh/authorized_keys; shutdown -h now'" || true sleep 30 @@ -255,6 +277,8 @@ in { environment.etc."nix/nix.conf".force = true; + users.users.admin.name = lib.mkDefault "admin"; + system.build.vm = pkgs.runCommand "run-darwin-vm" { } '' mkdir -p $out/bin ln -s ${config.system.build.toplevel} $out/system From 393d0f180875fe124c99fb84d8b5a640e00910ec Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 9 Jan 2024 21:42:14 +1100 Subject: [PATCH 10/11] =?UTF-8?q?refactor=20=F0=9F=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/virtualisation/tart-vm.nix | 383 ++++++++++++++--------------- 1 file changed, 190 insertions(+), 193 deletions(-) diff --git a/modules/virtualisation/tart-vm.nix b/modules/virtualisation/tart-vm.nix index 31f9e84f7..2c1880cc7 100644 --- a/modules/virtualisation/tart-vm.nix +++ b/modules/virtualisation/tart-vm.nix @@ -1,6 +1,8 @@ { config, pkgs, lib, ... }: -{ +let + ipsw = pkgs.callPackage ../../pkgs/ipsw { }; +in { options = with lib; { virtualisation.initialUser = mkOption { type = types.str; @@ -14,275 +16,270 @@ This defaults to the first user defined in `users.users`, otherwise it will default to `admin`. ''; }; - }; - config = let - # This file is 12GB, you'll want to download it yourself and then add it to the Nix Store before running the VM script - # $ aria2c -x4 https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw - # $ nix-store --add UniversalMac_13.4_22F66_Restore.ipsw - ipsw = pkgs.fetchurl { - name = "UniversalMac_13.4_22F66_Restore.ipsw"; - url = "https://updates.cdn-apple.com/2023SpringFCS/fullrestores/032-84884/F97A22EE-9B5E-4FD5-94C1-B39DCEE8D80F/UniversalMac_13.4_22F66_Restore.ipsw"; - hash = "sha256-RyGSky5BUtINBQRkHfTIV0kpkD8vMkT0W0avfVsuRgY="; + virtualisation.diskSize = mkOption { + type = types.ints.positive; + default = 30; + description = mdDoc '' + The disk size in gigabytes of the virtual machine. + + 15GiB is the minimum for a macOS install + ''; }; - nix-installer = pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "nix-installer"; - version = "0.15.1"; + virtualisation.macOSVersion = mkOption { + type = types.enum (builtins.attrNames ipsw); + default = "13.4"; + description = mdDoc '' + The version of macOS that should be installed inside the virtual machine. - src = pkgs.fetchurl { - url = "https://github.com/DeterminateSystems/${finalAttrs.pname}/releases/download/v${finalAttrs.version}/${finalAttrs.pname}-aarch64-darwin"; - hash = "sha256-mcYiRv1KD7F83MJTaV4++dXroPBjelvbGYeSM0Lzdc8="; - }; + You can download the IPSW file using the fetch script: - dontUnpack = true; + nix run nix-darwin#ipsw.\"13.4\".fetchScript + ''; + }; + }; - installPhase = "install -Dm555 $src $out/bin/${finalAttrs.pname}"; + config = let + cfg = config.virtualisation; - meta.mainProgram = finalAttrs.pname; - }); + nix-installer = pkgs.callPackage ../../pkgs/nix-installer { }; - tart = "${lib.getBin pkgs.tart}/bin/tart"; - jq = lib.getExe pkgs.jq; - vncdo = "${lib.getBin pkgs.vncdo}/bin/vncdo"; - passh = "${lib.getBin pkgs.passh}/bin/passh"; - retry = "${lib.getBin pkgs.retry}/bin/retry"; timeout = "${lib.getBin pkgs.coreutils}/bin/timeout"; - username = config.virtualisation.initialUser; + username = cfg.initialUser; user = config.users.users.${username}; - sshOptions = "-o UserKnownHostsFile=$TART_HOME/known_hosts -F /dev/null -i $TART_HOME/id_ed25519"; - sshDestination = "${sshOptions} ${username}@$VM_IP"; - - # NOTE: only 15GiB necessary for macOS install - startVM = '' - set -euxo pipefail + sshOptions = ''-o "UserKnownHostsFile=$TART_HOME/known_hosts" -F /dev/null -i "$TART_HOME/id_ed25519"''; + sshDestination = ''${sshOptions} "${username}@$VM_IP"''; - # Allows trap ERR to work with `set -e` - set -E + in { + environment.etc."nix/nix.conf".force = true; - # For job control - set -m + users.users.admin.name = lib.mkDefault "admin"; - # If we fail during installation, pass control back to `tart run` so users can kill the VM with Ctrl-C - trap fg ERR + system.build.ipsw = ipsw.${cfg.macOSVersion}; - unset SSH_AUTH_SOCK + system.build.vm = (pkgs.writeShellApplication { + name = "run-darwin-vm"; + runtimeInputs = [ pkgs.tart pkgs.jq pkgs.vncdo pkgs.passh pkgs.retry ]; + text = '' + set -euxo pipefail - export TART_HOME=$PWD/darwin-vm - STATE_FILE=$TART_HOME/darwin-vm.state + # Allows trap ERR to work with `set -e` + set -E - # states: null, uninstalled, macos-possibly-finished, macos-installed, installation-complete - VM_STATE=$(cat $STATE_FILE || echo "null") - VM_RUNNING=$(${tart} list --format json | ${jq} '.[] | select(.Name == "darwin-vm") | .Running') + # For job control + set -m - VM_PASS=admin + # If we fail during installation, pass control back to `tart run` so users can kill the VM with Ctrl-C + trap fg ERR - if [[ "$VM_STATE" != "installation-complete" ]]; then - if [[ "$VM_RUNNING" == "true" ]]; then - ${tart} stop darwin-vm - fi + unset SSH_AUTH_SOCK - if [[ "$VM_STATE" != "uninstalled" && "$VM_STATE" != "null" ]]; then - ${tart} delete darwin-vm - fi + export TART_HOME=$PWD/darwin-vm + STATE_FILE=$TART_HOME/darwin-vm.state - if ! ${tart} list | grep darwin-vm >/dev/null 2>&1; then - ${tart} create darwin-vm --from-ipsw ${ipsw} --disk-size 35 - echo uninstalled > $STATE_FILE + # states: null, uninstalled, macos-possibly-finished, macos-installed, installation-complete + VM_STATE=$(cat "$STATE_FILE" || echo "null") + VM_RUNNING=$(tart list --format json | jq '.[] | select(.Name == "darwin-vm") | .Running') - # To avoid running into "Failed to lock auxiliary storage." we need to wait a bit after creating a VM - sleep 5 - fi - - (${tart} run --vnc-experimental --no-graphics darwin-vm | tee $TART_HOME/tart.out) & + VM_PASS="admin" - # Give it time to start VM and VNC server - sleep 5 - VNC_URL=$(grep --only 'vnc://.*\d' $TART_HOME/tart.out) - VNC_URL=''${VNC_URL//@/:} - declare -a array=(''${VNC_URL//:/ }) - VNC_PASSWORD=''${array[2]} - VNC_ADDRESS=''${array[3]} - VNC_PORT=''${array[4]} + if [[ "$VM_STATE" != "installation-complete" ]]; then + if [[ "$VM_RUNNING" == "true" ]]; then + tart stop darwin-vm + fi - function vncdo { - echo Sending VNC inputs for $1 - ${timeout} 15s ${vncdo} -p $VNC_PASSWORD -s $VNC_ADDRESS::$VNC_PORT capture $TART_HOME/vms/darwin-vm/$(date +%F_%H-%M-%S).png "''${@:2}" - } + if [[ "$VM_STATE" != "uninstalled" && "$VM_STATE" != "null" ]]; then + tart delete darwin-vm + fi - sleep 60 - vncdo "Getting Started" key space + if ! tart list | grep darwin-vm >/dev/null 2>&1; then + tart create darwin-vm --from-ipsw ${ipsw.${cfg.macOSVersion}} --disk-size ${toString cfg.diskSize} + echo uninstalled > "$STATE_FILE" - sleep 30 - vncdo "Language" key enter + # To avoid running into "Failed to lock auxiliary storage." we need to wait a bit after creating a VM + sleep 5 + fi - sleep 30 - vncdo "Select Your Country or Region" type australia pause 0.3 key shift-tab pause 0.3 key space + (tart run --vnc-experimental --no-graphics darwin-vm | tee "$TART_HOME/tart.out") & - sleep 10 - vncdo "Written and Spoken Languages" key shift-tab pause 0.3 key space + # Give it time to start VM and VNC server + sleep 5 + VNC_URL=$(grep --only 'vnc://.*\d' "$TART_HOME/tart.out") + VNC_URL=''${VNC_URL//@/:} + declare -a array=("''${VNC_URL//:/ }") + VNC_PASSWORD=''${array[2]} + VNC_ADDRESS=''${array[3]} + VNC_PORT=''${array[4]} - sleep 10 - vncdo "Accessibility" key shift-tab pause 0.3 key space + function vncdo { + echo Sending VNC inputs for "$1" + ${timeout} 15s vncdo -p "$VNC_PASSWORD" -s "$VNC_ADDRESS::$VNC_PORT" capture "$TART_HOME/vms/darwin-vm/$(date +%F_%H-%M-%S).png" "''${@:2}" + } - sleep 10 - vncdo "Data & Privacy" key shift-tab pause 0.3 key space + sleep 60 + vncdo "Getting Started" key space - sleep 10 - vncdo "Migration Assistant" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + sleep 30 + vncdo "Language" key enter - sleep 10 - vncdo "Sign in with Your Apple ID" key shift-tab pause 0.3 key shift-tab pause 0.3 key space + sleep 30 + vncdo "Select Your Country or Region" type australia pause 0.3 key shift-tab pause 0.3 key space - sleep 10 - vncdo "Are you sure you want to skip signing in with an Apple ID?" key tab pause 0.3 key space + sleep 10 + vncdo "Written and Spoken Languages" key shift-tab pause 0.3 key space - sleep 10 - vncdo "Terms and Conditions" key shift-tab pause 0.3 key space + sleep 10 + vncdo "Accessibility" key shift-tab pause 0.3 key space - sleep 10 - vncdo "I have read and agree to the macOS Software License Agreement." key tab pause 0.3 key space + sleep 10 + vncdo "Data & Privacy" key shift-tab pause 0.3 key space - sleep 10 - vncdo "Create a Computer Account" type "${user.name}" pause 0.3 key tab pause 0.3 type "${username}" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + sleep 10 + vncdo "Migration Assistant" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space - sleep 10 - vncdo "Enable Location Services" key shift-tab pause 0.3 key space + sleep 10 + vncdo "Sign in with Your Apple ID" key shift-tab pause 0.3 key shift-tab pause 0.3 key space - sleep 10 - vncdo "Are you sure you don't want to use Location Services?" key tab pause 0.3 key space + sleep 10 + vncdo "Are you sure you want to skip signing in with an Apple ID?" key tab pause 0.3 key space - sleep 10 - vncdo "Select Your Time Zone" key tab pause 0.3 type UTC pause 0.3 key enter pause 0.3 key shift-tab pause 0.3 key space + sleep 10 + vncdo "Terms and Conditions" key shift-tab pause 0.3 key space - sleep 10 - vncdo "Analytics" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space + sleep 10 + vncdo "I have read and agree to the macOS Software License Agreement." key tab pause 0.3 key space - sleep 10 - vncdo "Screen Time" key tab pause 0.3 key space + sleep 10 + vncdo "Create a Computer Account" type "${user.name}" pause 0.3 key tab pause 0.3 type "${username}" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 type "$VM_PASS" pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space - sleep 10 - vncdo "Siri" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space + sleep 10 + vncdo "Enable Location Services" key shift-tab pause 0.3 key space - sleep 10 - vncdo "Choose Your Look" key shift-tab pause 0.3 key space + sleep 10 + vncdo "Are you sure you don't want to use Location Services?" key tab pause 0.3 key space - sleep 10 + sleep 10 + vncdo "Select Your Time Zone" key tab pause 0.3 type UTC pause 0.3 key enter pause 0.3 key shift-tab pause 0.3 key space - # macOS installation possibly complete - echo macos-possibly-finished > $STATE_FILE + sleep 10 + vncdo "Analytics" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space - vncdo "enabling Voice Over" key alt-f5 pause 5 key v + sleep 10 + vncdo "Screen Time" key tab pause 0.3 key space - vncdo "opening System Settings" move 0 0 click 1 pause 0.3 key down key down key enter + sleep 10 + vncdo "Siri" key tab pause 0.3 key space pause 0.3 key shift-tab pause 0.3 key space - sleep 10 - vncdo "navigating to Sharing" key up pause 3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + sleep 10 + vncdo "Choose Your Look" key shift-tab pause 0.3 key space - sleep 10 - vncdo "enabling Screen Sharing" key tab pause 0.3 key tab pause 0.3 key space + sleep 10 - sleep 10 - vncdo "enabling Remote Login" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space + # macOS installation possibly complete + echo macos-possibly-finished > "$STATE_FILE" - vncdo "enabling Full Disk Access" key tab key space pause 10 key tab key space pause 1 key shift-tab key shift-tab key space + vncdo "enabling Voice Over" key alt-f5 pause 5 key v - vncdo "disabling Voice Over" key alt-f5 + vncdo "opening System Settings" move 0 0 click 1 pause 0.3 key down key down key enter - # Installation complete, tart/AV private VNC server no longer necessary - rm $TART_HOME/tart.out + sleep 10 + vncdo "navigating to Sharing" key up pause 3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space - export VM_IP=$(${tart} ip darwin-vm) + sleep 10 + vncdo "enabling Screen Sharing" key tab pause 0.3 key tab pause 0.3 key space - if [[ -f $TART_HOME/id_ed25519 ]]; then - rm $TART_HOME/id_ed25519 $TART_HOME/id_ed25519.pub - fi + sleep 10 + vncdo "enabling Remote Login" key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key tab pause 0.3 key space - ssh-keygen -t ed25519 -f $TART_HOME/id_ed25519 -N "" + vncdo "enabling Full Disk Access" key tab key space pause 10 key tab key space pause 1 key shift-tab key shift-tab key space - # Sometimes it takes time for this to succeed after enabling SSH - ${retry} -d 5 -t 10 ${pkgs.writeShellScript "ssh-keyscan-vm" '' - set -eux - ssh-keyscan -t ed25519 $VM_IP | tee $TART_HOME/known_hosts - if [[ ! -s $TART_HOME/known_hosts ]]; then - exit 1 - fi - ''} + vncdo "disabling Voice Over" key alt-f5 - # Use SSH keys - ${passh} -p "$VM_PASS" ssh-copy-id ${sshDestination} + # Installation complete, tart/AV private VNC server no longer necessary + rm "$TART_HOME/tart.out" - if [[ $(ssh ${sshDestination} "echo yo") == "yo" ]]; then - echo macos-installed > $STATE_FILE - else - echo "error: couldn't SSH into VM" - echo "press Ctrl-C to close the VM, then rerun the script" - exit 1 - fi + VM_IP=$(tart ip darwin-vm) - # Enable passwordless sudo - ${passh} -p "$VM_PASS" ssh ${sshDestination} "sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo '%admin ALL=(ALL) NOPASSWD: ALL' | VISUAL=tee visudo /etc/sudoers.d/admin-nopasswd\"" + if [[ -f $TART_HOME/id_ed25519 ]]; then + rm "$TART_HOME/id_ed25519" "$TART_HOME/id_ed25519.pub" + fi - # Install Nix - scp ${sshOptions} ${lib.getExe nix-installer} ${username}@$VM_IP:/tmp/nix-installer + ssh-keygen -t ed25519 -f "$TART_HOME/id_ed25519" -N "" + + # Sometimes it takes time for this to succeed after enabling SSH + retry -d 5 -t 10 ${pkgs.writeShellScript "ssh-keyscan-vm" '' + set -eux + ssh-keyscan -t ed25519 $VM_IP | tee $TART_HOME/known_hosts + if [[ ! -s $TART_HOME/known_hosts ]]; then + exit 1 + fi + ''} + + # Use SSH keys + passh -p "$VM_PASS" ssh-copy-id ${sshDestination} + + if [[ $(ssh ${sshDestination} "echo yo") == "yo" ]]; then + echo macos-installed > "$STATE_FILE" + else + echo "error: couldn't SSH into VM" + echo "press Ctrl-C to close the VM, then rerun the script" + exit 1 + fi - ssh ${sshDestination} /tmp/nix-installer install --no-confirm + # Enable passwordless sudo + passh -p "$VM_PASS" ssh ${sshDestination} "sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo '%admin ALL=(ALL) NOPASSWD: ALL' | VISUAL=tee visudo /etc/sudoers.d/admin-nopasswd\"" - # Fixes `command not found: nix` for nix-copy-closure - cat ${../../doc/known-files/149e2e58b956511fb409732aaee5634a4a38084d7b498490fccfe442ad8c46ee} | ssh ${sshDestination} "sudo tee /etc/zshenv" + # Install Nix + scp ${sshOptions} ${lib.getExe nix-installer} "${username}@$VM_IP:/tmp/nix-installer" - ssh ${sshDestination} "sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak" + ssh ${sshDestination} /tmp/nix-installer install --no-confirm - # Necessary for nix-copy-closure - echo "trusted-users = ${username}" | ssh ${sshDestination} "sudo tee -a /etc/nix/nix.conf" + ssh ${sshDestination} "sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak" - ssh ${sshDestination} "sudo launchctl kickstart -k system/org.nixos.nix-daemon" + # Necessary for nix-copy-closure + echo "trusted-users = ${username}" | ssh ${sshDestination} "sudo tee -a /etc/nix/nix.conf" - VM_PUBLIC_KEY=$(ssh ${sshDestination} "base64 -i /etc/ssh/ssh_host_ed25519_key.pub") + ssh ${sshDestination} "sudo launchctl kickstart -k system/org.nixos.nix-daemon" - NIX_SSHOPTS="${sshOptions}" nix-copy-closure --to ${username}@$VM_IP ${config.system.build.toplevel} + NIX_SSHOPTS="${sshOptions}" nix-copy-closure --to "${username}@$VM_IP" ${config.system.build.toplevel} - # Restore the version without `trusted-users` to match known SHA256 hashes - ssh ${sshDestination} "sudo mv /etc/nix/nix.conf.bak /etc/nix/nix.conf" + # Restore the version without `trusted-users` to match known SHA256 hashes + ssh ${sshDestination} "sudo mv /etc/nix/nix.conf.bak /etc/nix/nix.conf" - ssh ${sshDestination} "${config.system.build.toplevel}/sw/bin/darwin-rebuild activate" + ssh ${sshDestination} "${config.system.build.toplevel}/sw/bin/darwin-rebuild activate" - if [[ $(ssh ${sshDestination} "realpath /run/current-system") == ${config.system.build.toplevel} ]]; then - echo installation-complete > $STATE_FILE - else - echo "error: nix-darwin installation did not complete successfully" - echo "press Ctrl-C to close the VM, then rerun the script" - exit 1 - fi + if [[ $(ssh ${sshDestination} "realpath /run/current-system") == ${config.system.build.toplevel} ]]; then + echo installation-complete > "$STATE_FILE" + else + echo "error: nix-darwin installation did not complete successfully" + echo "press Ctrl-C to close the VM, then rerun the script" + exit 1 + fi - ${timeout} 30s ssh ${sshDestination} "sudo bash -c 'rm /etc/sudoers.d/admin-nopasswd ~/.ssh/authorized_keys; shutdown -h now'" || true + ${timeout} 30s ssh ${sshDestination} "sudo bash -c 'rm /etc/sudoers.d/admin-nopasswd ~/.ssh/authorized_keys; shutdown -h now'" || true - sleep 30 + sleep 30 - VM_RUNNING=$(${tart} list --format json | ${jq} '.[] | select(.Name == "darwin-vm") | .Running') + VM_RUNNING=$(tart list --format json | jq '.[] | select(.Name == "darwin-vm") | .Running') - if [[ "$VM_RUNNING" == "true" ]]; then - echo shutdown-failed > $STATE_FILE - echo "error: failed to shut down VM" - echo "forcibly stopping VM, please rerun the script" - ${tart} stop --timeout 5 darwin-vm - exit 1 + if [[ "$VM_RUNNING" == "true" ]]; then + echo shutdown-failed > "$STATE_FILE" + echo "error: failed to shut down VM" + echo "forcibly stopping VM, please rerun the script" + tart stop --timeout 5 darwin-vm + exit 1 + fi fi - fi - - ${tart} run darwin-vm - ''; - in { - environment.etc."nix/nix.conf".force = true; - users.users.admin.name = lib.mkDefault "admin"; - - system.build.vm = pkgs.runCommand "run-darwin-vm" { } '' - mkdir -p $out/bin - ln -s ${config.system.build.toplevel} $out/system - ln -s ${pkgs.writeShellScript "run-darwin-vm" startVM} $out/bin/run-darwin-vm - ''; + tart run darwin-vm + ''; + }) // { + postBuild = '' + ln -s ${config.system.build.toplevel} $out/system + ''; + }; }; } From dc52b8031b8c1e073416bd81fa9be44a54235a16 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 6 Jul 2024 18:09:34 +1000 Subject: [PATCH 11/11] further refactoring NOTE: untested --- modules/virtualisation/tart-vm.nix | 45 +++++++++++++++++++----------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/modules/virtualisation/tart-vm.nix b/modules/virtualisation/tart-vm.nix index 2c1880cc7..3e1bf891c 100644 --- a/modules/virtualisation/tart-vm.nix +++ b/modules/virtualisation/tart-vm.nix @@ -64,7 +64,7 @@ in { name = "run-darwin-vm"; runtimeInputs = [ pkgs.tart pkgs.jq pkgs.vncdo pkgs.passh pkgs.retry ]; text = '' - set -euxo pipefail + set -x # Allows trap ERR to work with `set -e` set -E @@ -72,9 +72,6 @@ in { # For job control set -m - # If we fail during installation, pass control back to `tart run` so users can kill the VM with Ctrl-C - trap fg ERR - unset SSH_AUTH_SOCK export TART_HOME=$PWD/darwin-vm @@ -108,11 +105,18 @@ in { # Give it time to start VM and VNC server sleep 5 VNC_URL=$(grep --only 'vnc://.*\d' "$TART_HOME/tart.out") - VNC_URL=''${VNC_URL//@/:} - declare -a array=("''${VNC_URL//:/ }") - VNC_PASSWORD=''${array[2]} - VNC_ADDRESS=''${array[3]} - VNC_PORT=''${array[4]} + IFS=":" read -r -a VNC_DETAILS <<< "''${VNC_URL//@/:}" + VNC_PASSWORD=''${VNC_DETAILS[2]} + VNC_ADDRESS=''${VNC_DETAILS[3]} + VNC_PORT=''${VNC_DETAILS[4]} + + # If we fail during installation, pass control back to `tart run` so users can kill the VM with Ctrl-C + trap onInstallFail ERR + + onInstallFail() { + open "$VNC_URL" + fg + } function vncdo { echo Sending VNC inputs for "$1" @@ -202,6 +206,7 @@ in { rm "$TART_HOME/tart.out" VM_IP=$(tart ip darwin-vm) + export VM_IP if [[ -f $TART_HOME/id_ed25519 ]]; then rm "$TART_HOME/id_ed25519" "$TART_HOME/id_ed25519.pub" @@ -210,13 +215,18 @@ in { ssh-keygen -t ed25519 -f "$TART_HOME/id_ed25519" -N "" # Sometimes it takes time for this to succeed after enabling SSH - retry -d 5 -t 10 ${pkgs.writeShellScript "ssh-keyscan-vm" '' - set -eux - ssh-keyscan -t ed25519 $VM_IP | tee $TART_HOME/known_hosts - if [[ ! -s $TART_HOME/known_hosts ]]; then - exit 1 - fi - ''} + retry -d 5 -t 10 ${lib.getExe (pkgs.writeShellApplication { + name = "ssh-keyscan-vm"; + text = '' + set -x + + ssh-keyscan -t ed25519 "$VM_IP" | tee "$TART_HOME/known_hosts" + + if [[ ! -s $TART_HOME/known_hosts ]]; then + exit 1 + fi + ''; + })} # Use SSH keys passh -p "$VM_PASS" ssh-copy-id ${sshDestination} @@ -274,6 +284,9 @@ in { fi fi + # Remove trap now that installation has finished + trap - ERR + tart run darwin-vm ''; }) // {