worklyn / zukapublic
Agent-first git hosting. One Rust binary: git over HTTP and SSH, a REST API, MCP, CI, and multi-tenant isolation.
Get a copy:
git clone https://zuka.worklyn.com/worklyn/zuka.git
| 1 | #!/bin/bash |
| 2 | # Restart the build instance onto a newer binary, but never mid-build. |
| 3 | # |
| 4 | # Both instances run /usr/local/bin/zuka, so a deploy has already replaced the file |
| 5 | # the build instance started from — it just carries on running the old inode until |
| 6 | # something restarts it. The deploy cannot do that itself: the CI run that asked for |
| 7 | # the deploy is executing inside the build instance, and restarting it would kill the |
| 8 | # run half way through reading the deploy's own result. |
| 9 | # |
| 10 | # So this waits for idle instead. The wait is bounded without needing a ceiling, |
| 11 | # because a run cannot outlive the CI timeout — unlike a tenant, which can be busy |
| 12 | # indefinitely and therefore does need one. |
| 13 | # |
| 14 | # Install: |
| 15 | # sudo install -o root -g root -m 0755 zuka-build-refresh /usr/local/bin/ |
| 16 | # sudo install -o root -g root -m 0644 zuka-build-refresh.{service,timer} \ |
| 17 | # /etc/systemd/system/ |
| 18 | # sudo systemctl enable --now zuka-build-refresh.timer |
| 19 | |
| 20 | set -euo pipefail |
| 21 | |
| 22 | readonly SERVICE="zuka-build" |
| 23 | readonly JOBS="zuka-build-jobs" |
| 24 | readonly INSTALLED="/usr/local/bin/zuka" |
| 25 | readonly HEALTH="http://127.0.0.1:8791/healthz" |
| 26 | |
| 27 | log() { printf '[refresh] %s\n' "$*" >&2; } |
| 28 | |
| 29 | health="$(curl -fsS --max-time 5 "$HEALTH" 2>/dev/null)" || { |
| 30 | # Down or still starting. Not this script's problem: systemd restarts the unit, |
| 31 | # and restarting it again here would only add noise to a service already |
| 32 | # flapping. |
| 33 | log "$SERVICE is not answering; leaving it alone" |
| 34 | exit 0 |
| 35 | } |
| 36 | |
| 37 | running="$("$INSTALLED" version 2>/dev/null | awk '{print $NF}')" || { |
| 38 | log "the installed binary does not run; refusing to restart onto it" |
| 39 | exit 1 |
| 40 | } |
| 41 | |
| 42 | # What the live process reports, which is the binary it actually started from. |
| 43 | if [[ $health == *"$running"* ]]; then |
| 44 | exit 0 |
| 45 | fi |
| 46 | |
| 47 | # A build is in flight. Try again on the next tick rather than killing it. |
| 48 | if [[ $health != *'"ci_running":0'* ]]; then |
| 49 | log "a run is in flight; deferring the restart to $running" |
| 50 | exit 0 |
| 51 | fi |
| 52 | |
| 53 | log "restarting onto $running" |
| 54 | systemctl restart "$SERVICE" "$JOBS" |