Skip to content

Instantly share code, notes, and snippets.

@meeech
Last active August 25, 2025 08:34
Show Gist options
  • Save meeech/0b97a86f235d10bc4e2a1116eec38e7e to your computer and use it in GitHub Desktop.
Save meeech/0b97a86f235d10bc4e2a1116eec38e7e to your computer and use it in GitHub Desktop.

Revisions

  1. meeech revised this gist May 26, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion a_help-osx-borked-my-nix.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ Ok, so you've had nix (home-manager) working fine. Then Apple tells you it's tim

    Ok. Reboot. Oops. It has now broken your Nix setup. Here's some stuff to work through. YMMV.

    Note: This is what worked for me, who was just using nix + home-manager.
    Note: This is what worked for me, who was just using nix + home-manager. The upgrade that I last did that caused all these issues was 12.3.X > 12.4

    ## Useful Links

  2. meeech renamed this gist May 25, 2022. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. meeech created this gist May 25, 2022.
    140 changes: 140 additions & 0 deletions generate-volume-mount-plist.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    #!/usr/bin/env bash
    set -eu
    set -o pipefail

    # Script to regenerate the automount for Nix Store to /nix
    # Cobbled together looking at https://raw.githubusercontent.com/NixOS/nix/master/scripts/create-darwin-volume.sh
    readonly NIX_ROOT="${NIX_ROOT:-/nix}"
    readonly NIX_VOLUME_LABEL="${NIX_VOLUME_LABEL:-Nix Store}"
    readonly NIX_VOLUME_MOUNTD_DEST="${NIX_VOLUME_MOUNTD_DEST:-/Library/LaunchDaemons/org.nixos.darwin-store.plist}"
    readonly NIX_VOLUME_STATE=${NIX_VOLUME_STATE:-encrypted} # encrypted|unencrypted
    readonly NIX_VOLUME_UUID="${NIX_VOLUME_UUID:-}"

    ui_confirm() {

    local prompt="[y/n] "
    echo -n "$prompt"
    while read -r y; do
    if [ "$y" = "y" ]; then
    echo ""
    return 0
    elif [ "$y" = "n" ]; then
    echo "You said no. Exiting."
    return 1
    else
    echo "Sorry, I didn't understand. I can only understand answers of y or n"
    echo -n "$prompt"
    fi
    done
    echo ""
    return 1
    }

    uuid_set() {
    if [[ -z "$NIX_VOLUME_UUID" ]]; then
    echo "You need to set the value of NIX_VOLUME_UUID. You can find this info with 'diskutil info -all' or using Disk Utility app."
    return 1
    fi
    return 0
    }


    volume_state_set() {
    if [[ "$NIX_VOLUME_STATE" != "encrypted" && "$NIX_VOLUME_STATE" != "unencrypted" ]]; then
    echo "Invalid value for NIX_VOLUME_STATE - must be encrypted or unencrypted"
    return 1
    fi
    return 0
    }


    check() {
    uuid_set
    volume_state_set
    echo "All checks passed."
    }

    generate_mount_command() {
    local cmd_type="$1" # encrypted|unencrypted
    local volume_uuid mountpoint cmd=()
    printf -v volume_uuid "%q" "$2"
    printf -v mountpoint "%q" "$NIX_ROOT"

    case "$cmd_type" in
    encrypted)
    cmd=(/bin/sh -c "/usr/bin/security find-generic-password -s '$volume_uuid' -w | /usr/sbin/diskutil apfs unlockVolume '$volume_uuid' -mountpoint '$mountpoint' -stdinpassphrase");;
    unencrypted)
    cmd=(/usr/sbin/diskutil mount -mountPoint "$mountpoint" "$volume_uuid");;
    *)
    failure "Invalid first arg $cmd_type to generate_mount_command";;
    esac

    printf " <string>%s</string>\n" "${cmd[@]}"
    }

    generate_mount_daemon() {
    local cmd_type="$1" # encrypted|unencrypted
    local volume_uuid="$2"
    cat <<EOF
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>org.nixos.darwin-store</string>
    <key>ProgramArguments</key>
    <array>
    $(generate_mount_command "$cmd_type" "$volume_uuid")
    </array>
    </dict>
    </plist>
    EOF
    }

    test_voldaemon() {
    test -f "$NIX_VOLUME_MOUNTD_DEST"
    }

    task() {
    echo "$@"
    }

    _sudo() {
    shift # throw away the 'explanation'
    /usr/bin/sudo "$@"
    }

    setup_volume_daemon() {
    local cmd_type="$1" # encrypted|unencrypted
    local volume_uuid="$2"
    if ! test_voldaemon; then
    task "Configuring LaunchDaemon to mount '$NIX_VOLUME_LABEL'" >&2
    # Note: `-u NONE` disables vim plugins/rc; see note on --clean earlier
    _sudo "to install the Nix volume mounter" /usr/bin/ex -u NONE "$NIX_VOLUME_MOUNTD_DEST" <<EOF
    :a
    $(generate_mount_daemon "$cmd_type" "$volume_uuid")
    .
    :x
    EOF

    # TODO: should probably alert the user if this is disabled?
    _sudo "to launch the Nix volume mounter" \
    launchctl bootstrap system "$NIX_VOLUME_MOUNTD_DEST" || true
    # TODO: confirm whether kickstart is necessesary?
    # I feel a little superstitous, but it can guard
    # against multiple problems (doesn't start, old
    # version still running for some reason...)
    _sudo "to launch the Nix volume mounter" \
    launchctl kickstart -k system/org.nixos.darwin-store
    fi
    }


    main() {
    check
    setup_volume_daemon $NIX_VOLUME_STATE $NIX_VOLUME_UUID
    }

    main
    80 changes: 80 additions & 0 deletions help-osx-borked-my-nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    # Apple Borked my Nix!

    Ok, so you've had nix (home-manager) working fine. Then Apple tells you it's time to update.

    Ok. Reboot. Oops. It has now broken your Nix setup. Here's some stuff to work through. YMMV.

    Note: This is what worked for me, who was just using nix + home-manager.

    ## Useful Links

    * Install instructions for OS X - it has a good summary of what is being done during install. https://nixos.org/manual/nix/stable/installation/installing-binary.html#macos-installation-a-namesect-macos-installation-change-store-prefixaa-namesect-macos-installation-encrypted-volumeaa-namesect-macos-installation-symlinkaa-namesect-macos-installation-recommended-notesa
    * Actual install script https://github.com/NixOS/nix/blob/master/scripts/install-darwin-multi-user.sh
    * Actual install script that works with setting up the Nix volume. https://raw.githubusercontent.com/NixOS/nix/master/scripts/create-darwin-volume.sh

    ## Nix setup will modify your `/etc/zshrc`. When OS X updates, it will sometimes restore the original `/etc/zshrc`.

    Check the bottom of your `etc/zshrc`, you should see the following:

    ```sh
    # Nix
    if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
    . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
    fi
    # End Nix
    ```

    If it is NOT there, you want to add this back to the bottom of your `/etc/zshrc`. Or you can try to future proof things a little, and add it to the top of your own `~/.zshrc`.

    ## Nix Store volume check

    From terminal try `diskutil list | grep Nix`. You should see something like
    ```
    7: APFS Volume Nix Store 10.1 GB disk3s7
    ```

    So that means we have the volume. That last bit - `disk3s7` is the disk identifier. So then try `diskutil info disk3s7`

    ```
    Device Identifier: disk3s7
    ... snip ...
    Volume Name: Nix Store
    Mounted: Yes
    Mount Point: /nix
    ... snip ...
    Volume UUID: 53E764A4-140E-4980-9EE2-39CB2404DAFF
    ... snip ...
    FileVault: Yes
    ... snip ...
    ```

    So if `Mounted` is `No` then you need to mount this. Probably means the auto-mount script is broken. Check if `/Library/LaunchDaemons/org.nixos.darwin-store.plist` exists. If not, you can recreate it with the provided script - generate-volume-mount-plist.sh. This script is based off the nix install script `create-darwin-volume.sh`.

    USE THE VOLUME UUID you found above. And use `unencrypted` if your volume is FileVault: No.

    `NIX_VOLUME_UUID=53E764A4-140E-4980-9EE2-39CB2404DAFF NIX_VOLUME_STATE=encrypted ./generate-volume-mount-plist.sh`

    ## Check you have `/nix`

    If your `/nix` root level is missing, that means the mount point of your Nix Store got hosed. Let's rebuild it.

    * Check for `/etc/synthetic.conf`. If it exists, make sure you have an entry for `nix`. If you don't have one, then you will need to set it up. It should be as simple as a file that just says:

    ```
    nix
    ```

    * Check your `/etc/fstab` file. If it exists, check you have an entry for `/nix`. If it doesn't, you will need to create it. WITH YOUR UUID you found earlier.

    ```
    #
    # Warning - this file should only be modified with vifs(8)
    #
    # Failure to do so is unsupported and may be destructive.
    #
    UUID=53E764A4-140E-4980-9EE2-39CB2404DAFF /nix apfs rw,noauto,nobrowse,suid,owners
    ```

    ## Done

    Reboot.