docs: prepare repeatable V1 presentation
This commit is contained in:
Executable
+164
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
demo_repository_root() {
|
||||
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P
|
||||
}
|
||||
|
||||
demo_is_uint() {
|
||||
[[ ${1:-} =~ ^[0-9]+$ ]]
|
||||
}
|
||||
|
||||
demo_read_one_line() {
|
||||
local path=$1 destination=$2 value extra
|
||||
IFS= read -r value <"$path" || return 1
|
||||
if IFS= read -r extra < <(sed -n '2p' "$path") && [[ -n "$extra" ]]; then return 1; fi
|
||||
printf -v "$destination" '%s' "$value"
|
||||
}
|
||||
|
||||
demo_start_tick() {
|
||||
local pid=$1 stat rest
|
||||
local -a fields
|
||||
demo_is_uint "$pid" || return 1
|
||||
[[ -r "/proc/$pid/stat" ]] || return 1
|
||||
stat=$(<"/proc/$pid/stat")
|
||||
rest=${stat##*) }
|
||||
read -r -a fields <<<"$rest"
|
||||
demo_is_uint "${fields[19]:-}" || return 1
|
||||
printf '%s\n' "${fields[19]}"
|
||||
}
|
||||
|
||||
demo_process_group() {
|
||||
local pid=$1 pgid
|
||||
pgid=$(ps -o pgid= -p "$pid" 2>/dev/null) || return 1
|
||||
pgid=${pgid//[[:space:]]/}
|
||||
demo_is_uint "$pgid" || return 1
|
||||
printf '%s\n' "$pgid"
|
||||
}
|
||||
|
||||
demo_has_sequence() {
|
||||
local array_name=$1
|
||||
local -n argv_ref=$array_name
|
||||
shift
|
||||
local -a wanted=("$@")
|
||||
local i j
|
||||
for ((i = 0; i + ${#wanted[@]} <= ${#argv_ref[@]}; i++)); do
|
||||
for ((j = 0; j < ${#wanted[@]}; j++)); do
|
||||
[[ ${argv_ref[i+j]} == "${wanted[j]}" ]] || break
|
||||
done
|
||||
((j == ${#wanted[@]})) && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
demo_command_matches() {
|
||||
local pid=$1 kind=$2 argument base found=0
|
||||
local -a arguments=()
|
||||
[[ -r "/proc/$pid/cmdline" ]] || return 1
|
||||
mapfile -d '' -t arguments <"/proc/$pid/cmdline"
|
||||
((${#arguments[@]} > 0)) || return 1
|
||||
for argument in "${arguments[@]}"; do
|
||||
base=${argument##*/}
|
||||
if [[ "$kind" == anvil && "$base" == anvil ]]; then found=1; fi
|
||||
if [[ "$kind" == vite && ( "$base" == vite || "$base" == vite.js ) ]]; then found=1; fi
|
||||
done
|
||||
((found == 1)) || return 1
|
||||
if [[ "$kind" == anvil ]]; then
|
||||
demo_has_sequence arguments --host 127.0.0.1 || return 1
|
||||
demo_has_sequence arguments --port 8545 || return 1
|
||||
demo_has_sequence arguments --chain-id 31337 || return 1
|
||||
elif [[ "$kind" == vite ]]; then
|
||||
demo_has_sequence arguments web --host 127.0.0.1 --port 5173 || return 1
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
demo_remove_record() {
|
||||
local root=$1 kind=$2 path
|
||||
for path in "$root/.demo/$kind.pid" "$root/.demo/$kind.start" "$root/.demo/$kind.pgid"; do
|
||||
if [[ -e "$path" ]]; then
|
||||
rm -f -- "$path"
|
||||
printf 'Removed %s\n' "${path#"$root/"}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
demo_record_process() {
|
||||
local root=$1 kind=$2 pid=$3 start pgid
|
||||
[[ "$kind" == anvil || "$kind" == vite ]] || return 1
|
||||
demo_is_uint "$pid" || return 1
|
||||
start=$(demo_start_tick "$pid") || return 1
|
||||
pgid=$(demo_process_group "$pid") || return 1
|
||||
[[ "$pid" == "$pgid" ]] || return 1
|
||||
demo_command_matches "$pid" "$kind" || return 1
|
||||
mkdir -p "$root/.demo"
|
||||
chmod 0700 "$root/.demo"
|
||||
printf '%s\n' "$pid" >"$root/.demo/$kind.pid"
|
||||
printf '%s\n' "$start" >"$root/.demo/$kind.start"
|
||||
printf '%s\n' "$pgid" >"$root/.demo/$kind.pgid"
|
||||
chmod 0600 "$root/.demo/$kind.pid" "$root/.demo/$kind.start" "$root/.demo/$kind.pgid"
|
||||
}
|
||||
|
||||
demo_pid_is_running() {
|
||||
local pid=$1 stat rest state
|
||||
{ IFS= read -r stat <"/proc/$pid/stat"; } 2>/dev/null || return 1
|
||||
rest=${stat##*) }
|
||||
state=${rest%% *}
|
||||
[[ "$state" != Z ]]
|
||||
}
|
||||
|
||||
demo_stop_recorded() {
|
||||
local root=$1 kind=$2 pid start pgid actual_start actual_pgid
|
||||
local pid_path="$root/.demo/$kind.pid"
|
||||
local start_path="$root/.demo/$kind.start"
|
||||
local pgid_path="$root/.demo/$kind.pgid"
|
||||
[[ "$kind" == anvil || "$kind" == vite ]] || return 1
|
||||
[[ -e "$pid_path" ]] || return 0
|
||||
if ! demo_read_one_line "$pid_path" pid || [[ ! "$pid" =~ ^[1-9][0-9]*$ ]] || ((10#$pid <= 1)); then
|
||||
printf 'Refusing invalid %s PID record\n' "$kind" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! demo_pid_is_running "$pid"; then
|
||||
printf 'Discarding stale %s process record for PID %s\n' "$kind" "$pid"
|
||||
demo_remove_record "$root" "$kind"
|
||||
return 0
|
||||
fi
|
||||
if ! demo_read_one_line "$start_path" start || ! demo_is_uint "$start"; then
|
||||
printf 'Refusing incomplete %s start-tick record\n' "$kind" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! demo_read_one_line "$pgid_path" pgid || [[ ! "$pgid" =~ ^[1-9][0-9]*$ ]] || ((10#$pgid <= 1)); then
|
||||
printf 'Refusing incomplete %s process-group record\n' "$kind" >&2
|
||||
return 1
|
||||
fi
|
||||
actual_start=$(demo_start_tick "$pid") || return 1
|
||||
actual_pgid=$(demo_process_group "$pid") || return 1
|
||||
if [[ "$actual_start" != "$start" || "$actual_pgid" != "$pgid" || "$pid" != "$pgid" ]]; then
|
||||
printf 'Refusing %s PID %s: recorded identity does not match\n' "$kind" "$pid" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! demo_command_matches "$pid" "$kind"; then
|
||||
printf 'Refusing %s PID %s: command signature does not match\n' "$kind" "$pid" >&2
|
||||
return 1
|
||||
fi
|
||||
printf 'Stopping validated %s process group %s\n' "$kind" "$pgid"
|
||||
kill -TERM -- "-$pgid"
|
||||
for _ in {1..50}; do
|
||||
demo_pid_is_running "$pid" || break
|
||||
sleep 0.1
|
||||
done
|
||||
if demo_pid_is_running "$pid"; then
|
||||
printf 'Escalating validated %s process group %s to KILL\n' "$kind" "$pgid"
|
||||
kill -KILL -- "-$pgid"
|
||||
for _ in {1..20}; do
|
||||
demo_pid_is_running "$pid" || break
|
||||
sleep 0.1
|
||||
done
|
||||
fi
|
||||
wait "$pid" 2>/dev/null || true
|
||||
demo_pid_is_running "$pid" && {
|
||||
printf 'Validated %s process group %s did not stop\n' "$kind" "$pgid" >&2
|
||||
return 1
|
||||
}
|
||||
demo_remove_record "$root" "$kind"
|
||||
}
|
||||
Reference in New Issue
Block a user