nix-installer icon indicating copy to clipboard operation
nix-installer copied to clipboard

nix run commands stuck on post-build step

Open momrak opened this issue 9 months ago • 2 comments

I am using MacOS Sequoia 15.3.1 (24D70) Nix 2.25.3 installed with determinate systems nix-darwin

When trying to run a nix run command it will get stuck in the post-build step.

I first encountered it in the following command nix --extra-experimental-features nix-command --extra-experimental-features flakes run nix-darwin/master#darwin-rebuild -- switch --flake ~/.config/nix-darwin/#<flake>

Resulting in

❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
warning: 'https://cache.flakehub.com' does not appear to be a binary cache
[1/0/1 built, 0.0 MiB DL] post-build darwin-system-25.05.a674621

Then I thought something was wrong with my nix-darwin install so I tried uninstalling that with ❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller And that resulted in

❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
warning: 'https://cache.flakehub.com' does not appear to be a binary cache
[5/0/13 built, 0.0 MiB DL] post-build fonts

I first added an issue to the nix-darwin repo https://github.com/LnL7/nix-darwin/issues/1370#issue-2898488787

I have seen this before as well and done the local darwin-uninstaller then uninstalled nix, and then reinstalled both, and it has usually worked for some time. It was now quite some time since I had run and update on my nix-darwin config, and then I suddenly started hanging again.

Do you have any idea of what could cause me ending up in this state?

momrak avatar Mar 06 '25 05:03 momrak

Image

This identified and resolved the problem for me. I am guessing this is because systems.determinate.nix-daemon is expected to read from that (presumably) FIFO at /nix/var/determinate/intake.pipe mentioned at the bottom of /nix/var/determinate/post-build-hook.sh.

Probably the post-build hook should have some handling here that detects if the FIFO is unwritable or times out and prints some other message.

burke avatar Mar 26 '25 14:03 burke

I haven't tried it but, for inspiration, chatgpt suggests something like this may work:

#!/bin/sh
set -f
export IFS=' '
i=0

# Create a temporary file for the output
temp_file=$(mktemp)

# Prepare the output
{
    for p in $OUT_PATHS
    do
        printf '{"s": %d, "v":"1","c":"add-output","drv":"%s","idx":%d,"output":"%s"}\n' "$$" "$DRV_PATH" $i "$p"
        i=$((i + 1))
    done
    printf '{"s": %d, "v":"1","c":"finish","drv":"%s","count":%d}\n' "$$" "$DRV_PATH" $i
} > "$temp_file"

# Try to write to the FIFO with a timeout using background process
(cat "$temp_file" >> /nix/var/determinate/intake.pipe) &
pid=$!

# Wait for up to 10 seconds
wait_time=0
while [ $wait_time -lt 10 ] && kill -0 $pid 2>/dev/null; do
    sleep 1
    wait_time=$((wait_time + 1))
done

# Check if the process is still running (blocked)
if kill -0 $pid 2>/dev/null; then
    kill $pid
    echo "ERROR: Failed to write to FIFO /nix/var/determinate/intake.pipe (timeout)" >&2
    rm -f "$temp_file"
    exit 1
fi

# Check if the process exited successfully
wait $pid
exit_code=$?
rm -f "$temp_file"

if [ $exit_code -ne 0 ]; then
    echo "ERROR: Failed to write to FIFO /nix/var/determinate/intake.pipe (exit code $exit_code)" >&2
    exit 1
fi

exit 0

burke avatar Mar 26 '25 14:03 burke