run_host.sh (3274B)
1 #!/usr/bin/env bash 2 set -euo pipefail 3 4 script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" 5 date_utc="$(date -u +%F)" 6 7 require_command() { 8 if command -v "$1" >/dev/null 2>&1; then 9 return 10 fi 11 echo "missing required command: $1" >&2 12 exit 1 13 } 14 15 require_env() { 16 local name="$1" 17 18 if [[ -z "${!name:-}" ]]; then 19 echo "missing required environment variable: ${name}" >&2 20 exit 1 21 fi 22 } 23 24 forward_signal() { 25 local signal="$1" 26 27 if [[ -n "${app_pid:-}" ]] && kill -0 "${app_pid}" 2>/dev/null; then 28 kill "-${signal}" "${app_pid}" 2>/dev/null || kill "${app_pid}" 2>/dev/null || true 29 fi 30 } 31 32 require_command grep 33 require_command /usr/libexec/PlistBuddy 34 require_env RADROOTS_APP_LOCAL_LOG_ROOT 35 require_env RADROOTS_APP_NOSTR_RELAY_URLS 36 37 if [[ -n "${RADROOTS_APP_HOST_BUNDLE_PATH:-}" ]]; then 38 app_path="${RADROOTS_APP_HOST_BUNDLE_PATH}" 39 else 40 app_path="$("${script_dir}/build_host.sh")" 41 fi 42 plist_path="${app_path}/Contents/Info.plist" 43 executable_name="$( 44 /usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "${plist_path}" 45 )" 46 executable_path="${app_path}/Contents/MacOS/${executable_name}" 47 app_log_root="${RADROOTS_APP_LOCAL_LOG_ROOT}/apps/local/app/app-macos-native" 48 structured_log_file="${app_log_root}/${date_utc}.jsonl" 49 latest_log_path="${app_log_root}/latest.jsonl" 50 stdout_file="${app_log_root}/raw/stdout.${date_utc}.log" 51 stderr_file="${app_log_root}/raw/stderr.${date_utc}.log" 52 startup_attempts="${RADROOTS_APP_HOST_STARTUP_ATTEMPTS:-300}" 53 54 mkdir -p "${app_log_root}/raw" 55 export RUST_LOG="${RADROOTS_APP_RUST_LOG:-info}" 56 57 trap 'forward_signal TERM' TERM 58 trap 'forward_signal INT' INT 59 trap 'forward_signal HUP' HUP 60 61 stop_app_with_error() { 62 local message="$1" 63 64 if [[ -n "${app_pid:-}" ]] && kill -0 "${app_pid}" 2>/dev/null; then 65 kill "${app_pid}" 2>/dev/null || true 66 wait "${app_pid}" || true 67 fi 68 69 echo "${message}" >&2 70 exit 1 71 } 72 73 "${executable_path}" "$@" >>"${stdout_file}" 2>>"${stderr_file}" & 74 app_pid="$!" 75 76 launch_confirmed=false 77 for _ in $(seq 1 "${startup_attempts}"); do 78 if [[ -f "${structured_log_file}" ]] && grep -q '"event":"runtime.launch"' "${structured_log_file}" 2>/dev/null; then 79 launch_confirmed=true 80 break 81 fi 82 83 if ! kill -0 "${app_pid}" 2>/dev/null; then 84 wait "${app_pid}" 85 exit $? 86 fi 87 88 sleep 0.1 89 done 90 91 if [[ "${launch_confirmed}" != "true" ]]; then 92 stop_app_with_error "app launch did not emit runtime.launch within startup timeout" 93 fi 94 95 grep -q '"event":"logging.initialized"' "${structured_log_file}" 2>/dev/null || { 96 stop_app_with_error "app launch did not emit logging.initialized in ${structured_log_file}" 97 } 98 99 [[ -e "${latest_log_path}" ]] || { 100 stop_app_with_error "app launch did not create latest structured log alias: ${latest_log_path}" 101 } 102 103 [[ -f "${stdout_file}" ]] || { 104 stop_app_with_error "app launch did not create raw stdout log: ${stdout_file}" 105 } 106 107 [[ -f "${stderr_file}" ]] || { 108 stop_app_with_error "app launch did not create raw stderr log: ${stderr_file}" 109 } 110 111 printf 'radroots_app run: ready\n' 112 printf 'relays=%s\n' "${RADROOTS_APP_NOSTR_RELAY_URLS}" 113 printf 'structured_log=%s\n' "${structured_log_file}" 114 printf 'latest_log=%s\n' "${latest_log_path}" 115 printf 'stdout_log=%s\n' "${stdout_file}" 116 printf 'stderr_log=%s\n' "${stderr_file}" 117 118 wait "${app_pid}"