summaryrefslogtreecommitdiff
path: root/scripts/guix-retry
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xscripts/guix-retry76
1 files changed, 64 insertions, 12 deletions
diff --git a/scripts/guix-retry b/scripts/guix-retry
index c504048..6fe4da4 100755
--- a/scripts/guix-retry
+++ b/scripts/guix-retry
@@ -1,21 +1,73 @@
#!/bin/sh
-error="write_to_session_record_port"
+# fail on errors
+set -e
-# create redirection
-# file descripters
-exec 11>&1 # stdout
-exec 22>&2 # stderr
+# if the error output matches this regex, auto retry
+# and dont prompt user.
+auto_retry_regex="write_to_session_record_port" # Guix does not know how to
+ # gracefully reconnect TLS...
+# run dir
+run="${XDG_RUNTIME_DIR:-/tmp}/guix-retry/$$"
+mkdir -p "$run"
+# delete run dir on exit
+function cleanup {
+ real="$(realpath "$run")"
+ if [[ ! "$real" = "/" ]]; then
+ rm -fr "$real"
+ fi
+}
+
+trap cleanup EXIT
+
+# get error stream
+stderr="$run/stderr"
+mkfifo -m 600 "$stderr"
+
+log="$run/log"
+
+# unset fail on errors
+set +e
+
+# retry command forever
+# until success or abort
while true; do
- # send stdout to stdout
- # send stderr though pipe
- output=$("$@" 2>&1 1>&11 | tee >(cat - >&22)) # return stderr to
- # normal stderr as well
- # check if error is in stderr
- if echo "$output" | grep -q "$error"; then
+ # execute command
+ if [[ ! -z "$GUIX_RETRY_NO_TTY" ]]; then
+ "$@" 2>"$stderr" &
+ else
+ command="$@"
+ script -q -c "$command" 2>"$stderr" "$log" &
+ fi
+ pid="$!"
+ output="$(cat "$stderr" | tee /dev/stderr)"
+ wait "$pid"
+ err="$?"
+ if [[ -z "$GUIX_RETRY_NO_TTY" ]]; then
+ err="$(tail -n1 "$log" | awk -F '"' '{ print $2 }')"
+ fi
+
+ if [[ "$err" -eq 0 ]]; then
+ # command succeeded, break loop
+ break
+ fi
+
+ if [[ "$output" =~ "$auto_retry_regex" ]]; then
+ # command errored and is set to auto retry
continue
fi
- break
+
+ if [[ ! -z "$GUIX_RETRY_NO_PROMPT" ]]; then
+ # do not prompt, just fail
+ exit 1
+ fi
+
+ # check if user wants to retry
+ read -p "Command failed. Retry? (y/N): " response
+ if [[ ! "$response" = "y" ]]; then
+ # command failed and told to abort, break loop
+ exit 1
+ fi
done