mirror of
https://github.com/sol1/rustguac.git
synced 2026-10-25 21:19:45 +00:00
994f138685
guacenc, from guacamole-server, converts .guac recordings to video and is what MP4 downloads (#241) run. Stop passing --disable-guacenc in build-deb.sh, the release workflow, install.sh, the Dockerfile and dev.sh, and ship /opt/rustguac/bin/guacenc in the .deb (debian/rules), the Docker runtime image and the release tarball (install-release.sh installs it when present). It needs only the ffmpeg libraries guacd is already built and shipped with, so no new dependencies. configure leaves guacenc out quietly when an ffmpeg library is missing, like the protocols, so check-guacd-plugins.sh now also fails the build when guacenc was not built.
357 lines
11 KiB
Bash
Executable File
357 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# dev.sh — Build and run rustguac + guacd for local development/testing.
|
|
#
|
|
# Usage:
|
|
# ./dev.sh build-guacd Build guacd from ../guacamole-server into .guacd-build/
|
|
# ./dev.sh start-guacd Start guacd in foreground on localhost:4822
|
|
# ./dev.sh build Build rustguac (cargo build)
|
|
# ./dev.sh run Build and run rustguac
|
|
# ./dev.sh start Build guacd (if needed), build rustguac, start both
|
|
# ./dev.sh stop Stop backgrounded guacd
|
|
# ./dev.sh deps Install build dependencies for guacd (apt, needs sudo)
|
|
# ./dev.sh status Show status of guacd and rustguac processes
|
|
# ./dev.sh generate-cert Generate self-signed TLS cert for dev (cert.pem + key.pem)
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
GUACD_SRC="${SCRIPT_DIR}/../guacamole-server"
|
|
GUACD_BUILD="${SCRIPT_DIR}/.guacd-build"
|
|
GUACD_PREFIX="${GUACD_BUILD}/install"
|
|
GUACD_BIN="${GUACD_PREFIX}/sbin/guacd"
|
|
GUACD_PID="${GUACD_BUILD}/guacd.pid"
|
|
GUACD_PORT="${GUACD_PORT:-4822}"
|
|
GUACD_LOG_LEVEL="${GUACD_LOG_LEVEL:-info}"
|
|
RECORDINGS_DIR="${SCRIPT_DIR}/recordings"
|
|
DEV_CERT="${SCRIPT_DIR}/cert.pem"
|
|
DEV_KEY="${SCRIPT_DIR}/key.pem"
|
|
DEV_CONFIG="${SCRIPT_DIR}/config.local.toml"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${GREEN}[dev]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[dev]${NC} $*"; }
|
|
error() { echo -e "${RED}[dev]${NC} $*" >&2; }
|
|
|
|
#--- Install build dependencies (Debian/Ubuntu) ---
|
|
cmd_deps() {
|
|
info "Installing guacd build dependencies..."
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
autoconf automake libtool pkg-config make gcc g++ \
|
|
libcairo2-dev libjpeg-dev libpng-dev libossp-uuid-dev libavcodec-dev \
|
|
libavformat-dev libavutil-dev libswscale-dev \
|
|
libpango1.0-dev libssh2-1-dev libssl-dev \
|
|
libvncserver-dev libtelnet-dev libwebsockets-dev \
|
|
libpulse-dev libwebp-dev libcunit1-dev \
|
|
freerdp3-dev libspice-client-glib-2.0-dev
|
|
|
|
# uuid-dev is the standard package on Debian; fall back to libossp-uuid-dev
|
|
sudo apt-get install -y uuid-dev 2>/dev/null || true
|
|
|
|
info "Dependencies installed."
|
|
}
|
|
|
|
#--- Apply guacd patches (FreeRDP 3.x / Debian 13 fixes) ---
|
|
apply_guacd_patches() {
|
|
local src="$1"
|
|
local patch_dir="${SCRIPT_DIR}/patches"
|
|
|
|
if [[ ! -d "$patch_dir" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
for patch in "$patch_dir"/*.patch; do
|
|
[[ -f "$patch" ]] || continue
|
|
if git -C "$src" apply --check "$patch" 2>/dev/null; then
|
|
info "Applying patch: $(basename "$patch")"
|
|
git -C "$src" apply "$patch"
|
|
else
|
|
info "Patch already applied or N/A: $(basename "$patch")"
|
|
fi
|
|
done
|
|
}
|
|
|
|
#--- Build guacd from source ---
|
|
cmd_build_guacd() {
|
|
if [[ ! -d "$GUACD_SRC" ]]; then
|
|
error "guacamole-server source not found at $GUACD_SRC"
|
|
error "Expected it at ../guacamole-server relative to rustguac"
|
|
exit 1
|
|
fi
|
|
|
|
apply_guacd_patches "$GUACD_SRC"
|
|
|
|
info "Building guacd from $GUACD_SRC"
|
|
info "Build dir: $GUACD_BUILD"
|
|
info "Install dir: $GUACD_PREFIX"
|
|
|
|
mkdir -p "$GUACD_BUILD"
|
|
|
|
# Run autoreconf in the source tree if configure doesn't exist
|
|
if [[ ! -f "$GUACD_SRC/configure" ]]; then
|
|
info "Running autoreconf..."
|
|
(cd "$GUACD_SRC" && autoreconf -fi)
|
|
fi
|
|
|
|
# Configure out-of-tree build
|
|
cd "$GUACD_BUILD"
|
|
if [[ ! -f "$GUACD_BUILD/Makefile" ]]; then
|
|
info "Configuring..."
|
|
"$GUACD_SRC/configure" \
|
|
--prefix="$GUACD_PREFIX" \
|
|
--with-ssh \
|
|
--with-vnc \
|
|
--with-rdp \
|
|
--with-spice \
|
|
--without-telnet \
|
|
--disable-kubernetes \
|
|
--disable-guaclog \
|
|
--disable-guacclip \
|
|
--disable-static
|
|
fi
|
|
|
|
info "Compiling..."
|
|
make -j"$(nproc)"
|
|
|
|
info "Installing to $GUACD_PREFIX..."
|
|
make install
|
|
|
|
info "guacd built successfully: $GUACD_BIN"
|
|
"$GUACD_BIN" -v
|
|
}
|
|
|
|
#--- Start guacd in foreground ---
|
|
cmd_start_guacd() {
|
|
if [[ ! -x "$GUACD_BIN" ]]; then
|
|
error "guacd not found at $GUACD_BIN"
|
|
error "Run: ./dev.sh build-guacd"
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure the library path includes our build
|
|
export LD_LIBRARY_PATH="${GUACD_PREFIX}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
info "Starting guacd on localhost:$GUACD_PORT (foreground, log_level=$GUACD_LOG_LEVEL)"
|
|
exec "$GUACD_BIN" -b 127.0.0.1 -l "$GUACD_PORT" -L "$GUACD_LOG_LEVEL" -f
|
|
}
|
|
|
|
#--- Start guacd in background ---
|
|
start_guacd_bg() {
|
|
if [[ ! -x "$GUACD_BIN" ]]; then
|
|
error "guacd not found at $GUACD_BIN — run: ./dev.sh build-guacd"
|
|
exit 1
|
|
fi
|
|
|
|
# Kill existing if running
|
|
stop_guacd_quiet
|
|
|
|
export LD_LIBRARY_PATH="${GUACD_PREFIX}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
info "Starting guacd in background on localhost:$GUACD_PORT..."
|
|
"$GUACD_BIN" -b 127.0.0.1 -l "$GUACD_PORT" -L "$GUACD_LOG_LEVEL" -f \
|
|
> "${GUACD_BUILD}/guacd.log" 2>&1 &
|
|
local pid=$!
|
|
echo "$pid" > "$GUACD_PID"
|
|
info "guacd started (pid=$pid)"
|
|
|
|
# Brief wait to check it didn't crash immediately
|
|
sleep 0.5
|
|
if ! kill -0 "$pid" 2>/dev/null; then
|
|
error "guacd failed to start. Log:"
|
|
cat "${GUACD_BUILD}/guacd.log"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
#--- Stop backgrounded guacd ---
|
|
stop_guacd_quiet() {
|
|
if [[ -f "$GUACD_PID" ]]; then
|
|
local pid
|
|
pid=$(cat "$GUACD_PID")
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null || true
|
|
wait "$pid" 2>/dev/null || true
|
|
fi
|
|
rm -f "$GUACD_PID"
|
|
fi
|
|
# Also kill any stray guacd from our build
|
|
pkill -f "$GUACD_BIN" 2>/dev/null || true
|
|
}
|
|
|
|
cmd_stop() {
|
|
info "Stopping guacd..."
|
|
stop_guacd_quiet
|
|
info "Stopped."
|
|
}
|
|
|
|
#--- Build rustguac ---
|
|
cmd_build() {
|
|
info "Building rustguac..."
|
|
cd "$SCRIPT_DIR"
|
|
cargo build 2>&1
|
|
info "rustguac built."
|
|
}
|
|
|
|
#--- Setup dev database with a dev admin ---
|
|
cmd_setup_db() {
|
|
local DB_PATH="${SCRIPT_DIR}/rustguac.db"
|
|
if [[ -f "$DB_PATH" ]]; then
|
|
info "Database already exists at $DB_PATH"
|
|
info "Current admins:"
|
|
cd "$SCRIPT_DIR"
|
|
cargo run -q -- list-admins
|
|
return 0
|
|
fi
|
|
|
|
info "Creating dev database and admin..."
|
|
cd "$SCRIPT_DIR"
|
|
cargo run -q -- add-admin --name dev
|
|
echo ""
|
|
info "Save the API key above for testing. Example usage:"
|
|
info " curl -H 'Authorization: Bearer <key>' http://localhost:8089/api/sessions"
|
|
}
|
|
|
|
#--- Run rustguac ---
|
|
cmd_run() {
|
|
cmd_build
|
|
mkdir -p "$RECORDINGS_DIR"
|
|
cmd_setup_db
|
|
|
|
info "Starting rustguac..."
|
|
cd "$SCRIPT_DIR"
|
|
if [[ -f "$DEV_CONFIG" ]]; then
|
|
info "Using config: $DEV_CONFIG"
|
|
exec cargo run -- --config "$DEV_CONFIG"
|
|
else
|
|
exec cargo run
|
|
fi
|
|
}
|
|
|
|
#--- Start everything ---
|
|
cmd_start() {
|
|
# Build guacd if not already built
|
|
if [[ ! -x "$GUACD_BIN" ]]; then
|
|
warn "guacd not built yet, building..."
|
|
cmd_build_guacd
|
|
fi
|
|
|
|
# Build rustguac
|
|
cmd_build
|
|
|
|
# Start guacd in background
|
|
start_guacd_bg
|
|
|
|
# Ensure recordings dir exists
|
|
mkdir -p "$RECORDINGS_DIR"
|
|
|
|
# Setup dev database if needed
|
|
cmd_setup_db
|
|
|
|
# Run rustguac in foreground (Ctrl+C stops it, then we clean up guacd)
|
|
info "Starting rustguac on localhost:8089..."
|
|
info "Press Ctrl+C to stop both."
|
|
trap 'echo; info "Shutting down..."; pkill -f "target/debug/rustguac" 2>/dev/null; stop_guacd_quiet; exit 0' INT TERM
|
|
|
|
cd "$SCRIPT_DIR"
|
|
if [[ -f "$DEV_CONFIG" ]]; then
|
|
info "Using config: $DEV_CONFIG"
|
|
cargo run -- --config "$DEV_CONFIG" &
|
|
else
|
|
cargo run &
|
|
fi
|
|
local rustguac_pid=$!
|
|
|
|
wait "$rustguac_pid" 2>/dev/null || true
|
|
stop_guacd_quiet
|
|
}
|
|
|
|
#--- Status ---
|
|
cmd_status() {
|
|
echo "=== guacd ==="
|
|
if [[ -f "$GUACD_PID" ]] && kill -0 "$(cat "$GUACD_PID")" 2>/dev/null; then
|
|
echo " Running (pid=$(cat "$GUACD_PID"), port=$GUACD_PORT)"
|
|
else
|
|
echo " Not running"
|
|
fi
|
|
if [[ -x "$GUACD_BIN" ]]; then
|
|
echo " Binary: $GUACD_BIN"
|
|
echo " Version: $("$GUACD_BIN" -v 2>&1 || echo unknown)"
|
|
else
|
|
echo " Not built"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== rustguac ==="
|
|
if pgrep -f "target/debug/rustguac" > /dev/null 2>&1; then
|
|
echo " Running (pid=$(pgrep -f 'target/debug/rustguac'))"
|
|
else
|
|
echo " Not running"
|
|
fi
|
|
if [[ -f "$SCRIPT_DIR/target/debug/rustguac" ]]; then
|
|
echo " Binary: $SCRIPT_DIR/target/debug/rustguac"
|
|
else
|
|
echo " Not built"
|
|
fi
|
|
}
|
|
|
|
#--- Generate self-signed TLS certificate for dev ---
|
|
cmd_generate_cert() {
|
|
if [[ -f "$DEV_CERT" && -f "$DEV_KEY" ]]; then
|
|
info "TLS cert already exists: $DEV_CERT"
|
|
info "Delete cert.pem and key.pem to regenerate."
|
|
return 0
|
|
fi
|
|
|
|
cmd_build
|
|
|
|
info "Generating self-signed TLS certificate..."
|
|
cd "$SCRIPT_DIR"
|
|
cargo run -q -- generate-cert --hostname localhost --out-dir "$SCRIPT_DIR"
|
|
info "Certificate generated: $DEV_CERT"
|
|
info "Private key generated: $DEV_KEY"
|
|
echo ""
|
|
info "Add to config.local.toml:"
|
|
info " [tls]"
|
|
info " cert_path = \"$DEV_CERT\""
|
|
info " key_path = \"$DEV_KEY\""
|
|
}
|
|
|
|
#--- Main ---
|
|
case "${1:-help}" in
|
|
deps) cmd_deps ;;
|
|
build-guacd) cmd_build_guacd ;;
|
|
start-guacd) cmd_start_guacd ;;
|
|
build) cmd_build ;;
|
|
run) cmd_run ;;
|
|
start) cmd_start ;;
|
|
stop) cmd_stop ;;
|
|
status) cmd_status ;;
|
|
setup-db) cmd_build && cmd_setup_db ;;
|
|
generate-cert) cmd_generate_cert ;;
|
|
help|*)
|
|
echo "Usage: $0 <command>"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " deps Install system build dependencies for guacd (needs sudo)"
|
|
echo " build-guacd Build guacd from ../guacamole-server into .guacd-build/"
|
|
echo " start-guacd Start guacd in foreground (for debugging)"
|
|
echo " build Build rustguac (cargo build)"
|
|
echo " run Build and run rustguac only"
|
|
echo " start Build everything, start guacd + rustguac together"
|
|
echo " stop Stop backgrounded guacd"
|
|
echo " setup-db Create dev database and admin API key"
|
|
echo " generate-cert Generate self-signed TLS cert+key for dev (localhost)"
|
|
echo " status Show process status"
|
|
echo ""
|
|
echo "Environment:"
|
|
echo " GUACD_PORT guacd listen port (default: 4822)"
|
|
echo " GUACD_LOG_LEVEL guacd log level: trace/debug/info/warning/error (default: info)"
|
|
;;
|
|
esac
|