Skip to main content

max / alloy

2.7 KB · 78 lines History Blame Raw
1 #!/usr/bin/env bash
2 #
3 # serve.sh — bring the RPM repo and the OCI registry up, or take them down.
4 #
5 # Both have to be reachable from inside the guest, which means bound on the
6 # host rather than on loopback only: qemu user networking reaches the host as
7 # 10.0.2.2, and a server bound to 127.0.0.1 is not there.
8 #
9 # serve.sh up start both, idempotent
10 # serve.sh down stop both
11 # serve.sh status say what is listening
12 set -euo pipefail
13
14 # shellcheck source=build/layertest/common.sh
15 . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
16
17 # shellcheck source=build/privilege.sh
18 . "$HERE/../privilege.sh"
19
20 PIDFILE="$STATE/repo-server.pid"
21
22 repo_up() {
23 [ -d "$STATE/repo" ] || die "no state/repo; run build.sh first"
24 if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
25 say "repo already serving on $REPO_PORT"; return
26 fi
27 # `setsid --fork`, and no `&` anywhere. The server has to stop being this
28 # script's descendant, and it has to stop holding this script's stdout.
29 #
30 # Both of those bite. A plain `cmd &` leaves the server a child that bash
31 # waits for at exit, and wrapping it in `( ... & )` only moves the problem to
32 # the subshell, which then holds the write end of any pipe `serve.sh up` was
33 # called through. Either way `./serve.sh up | tail` never returns and an &&
34 # chain after it never runs. nohup does not help: it redirects, it does not
35 # detach.
36 setsid --fork python3 -m http.server "$REPO_PORT" \
37 --bind 0.0.0.0 --directory "$STATE/repo" \
38 < /dev/null > "$STATE/repo-server.log" 2>&1
39 pgrep -f "http.server $REPO_PORT" > "$PIDFILE" || true
40 say "repo serving on $REPO_PORT"
41 }
42
43 repo_down() {
44 if [ -f "$PIDFILE" ]; then
45 kill "$(cat "$PIDFILE")" 2>/dev/null || true
46 rm -f "$PIDFILE"
47 fi
48 # The pidfile is not the whole story: a run killed part-way leaves a server
49 # with no pidfile, and the next `up` would then bind-fail for a reason that
50 # reads as unrelated.
51 pkill -f "http.server $REPO_PORT" 2>/dev/null || true
52 say "repo stopped"
53 }
54
55 registry_up() {
56 if privc podman container exists alloy-layertest-registry 2>/dev/null; then
57 privc podman start alloy-layertest-registry >/dev/null 2>&1 || true
58 else
59 privc podman run -d --name alloy-layertest-registry \
60 -p "$REGISTRY_PORT:5000" docker.io/library/registry:2 >/dev/null
61 fi
62 say "registry serving on $REGISTRY_PORT"
63 }
64
65 registry_down() {
66 privc podman rm -f alloy-layertest-registry >/dev/null 2>&1 || true
67 say "registry stopped"
68 }
69
70 case "${1:-up}" in
71 up) repo_up; registry_up ;;
72 down) repo_down; registry_down ;;
73 status)
74 ss -ltn 2>/dev/null | grep -E ":$REPO_PORT|:$REGISTRY_PORT" || say "neither port is listening"
75 ;;
76 *) die "usage: serve.sh [up|down|status]" ;;
77 esac
78