## Summary Adds `tools/hangar` — a macOS desktop control panel for working on Fleet locally: branch management, `fleet serve` orchestration, log tail, dev MySQL backup/restore, `fleetctl`, GitOps, and `osquery-perf`, all in one window. Built with **Go + [Wails 3](https://v3alpha.wails.io)** — the backend is plain Go (`os/exec`, `syscall`, goroutines) so Fleet engineers can contribute to it; only the desktop shell is Wails. The `internal/` packages are pure and unit-tested. ### History note Hangar started as a Rust/Tauri app. It was ported to Go, and **the Go port is now the canonical `tools/hangar`**. The original Rust/Tauri implementation has been removed from the monorepo (preserved in a standalone repo) — so although this branch's earlier commits add and then replace the Rust app, the net diff is just the Go app at `tools/hangar`. The bundle identifier is `com.fleetdm.fleet-hangar`, matching the original app so existing settings carry over. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops > No `changes/` file: `tools/` is contributor tooling, not a user-visible Fleet change. No DB migrations, no Fleet config settings, no fleetd/orbit changes. ## Testing - [x] Added/updated automated tests (Go unit tests across `internal/`, including a path-traversal regression for backup deletion) - [x] QA'd all new/changed functionality manually ## Test plan - [x] `cd tools/hangar && task dev` launches the app (live-reload) - [x] `task build` produces `bin/fleet-hangar`; `go test ./...` is green - [x] First-run gate discovers a local Fleet clone and runs dep checks - [x] Server tab can run the build chain and start `fleet serve` - [x] Git tab branch search finds an older branch (e.g. a stale `qa-*`) by name <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced Fleet Hangar, a comprehensive desktop application for Fleet development workflows, providing unified controls for server/database management, git operations, configuration, logging, and troubleshooting. * Added database backup management with metadata tracking. * Integrated process orchestration for development services (Docker, ngrok, Python). <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: George Karr <georgekarrv@users.noreply.github.com>
43 lines
1.7 KiB
Bash
Executable File
43 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Dev wrapper for `wails3 dev` with reliable Ctrl+C teardown.
|
|
#
|
|
# wails3 dev launches the Vite dev server as a *detached* child (its own
|
|
# process group), so a plain Ctrl+C — delivered only to the foreground group —
|
|
# leaves Vite orphaned on the port ("address already in use" next run).
|
|
#
|
|
# We run wails3 as a *background job under job control* (`set -m`, so it gets
|
|
# its own process group) and `wait` on it. That keeps this shell free to run
|
|
# its trap the instant a signal arrives (running wails3 in the foreground
|
|
# would block the trap until wails3 exits — which it doesn't, hence the hang).
|
|
# On signal we tear down explicitly: wails3 + the app (its process group),
|
|
# then Vite (by port, since it's in a separate group).
|
|
set -uo pipefail
|
|
set -m
|
|
|
|
PORT="${1:-9245}"
|
|
|
|
cleanup() {
|
|
trap '' INT TERM # ignore repeat signals while we tear down
|
|
# Stop wails3 dev + the app (its process group). wails3 dev ignores SIGINT,
|
|
# so TERM it, then escalate to KILL if it lingers.
|
|
if [ -n "${WAILS:-}" ]; then
|
|
kill -TERM -"${WAILS}" 2>/dev/null || kill -TERM "${WAILS}" 2>/dev/null || true
|
|
sleep 0.3
|
|
if kill -0 -"${WAILS}" 2>/dev/null || kill -0 "${WAILS}" 2>/dev/null; then
|
|
kill -KILL -"${WAILS}" 2>/dev/null || kill -KILL "${WAILS}" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
# Vite is detached into its own group by wails3 — free it by port.
|
|
local pids
|
|
pids="$(lsof -ti "tcp:${PORT}" 2>/dev/null || true)"
|
|
if [ -n "${pids}" ]; then
|
|
# shellcheck disable=SC2086 # intentional word-split: kill may take several PIDs
|
|
kill -KILL ${pids} 2>/dev/null || true
|
|
fi
|
|
}
|
|
trap cleanup INT TERM EXIT
|
|
|
|
wails3 dev -config ./build/config.yml -port "${PORT}" &
|
|
WAILS=$!
|
|
wait "${WAILS}"
|