4ae50fa5255be82566187f8cdbf5591152d3cf34 braney Sat Aug 22 14:49:40 2026 -0700 ts: add the ticket-sandbox scripts, refs #37867 ts parks a Redmine ticket as its own frozen browser instance on hgwdev: a full copy of cgi-bin-$USER and htdocs-$USER served by a private loopback httpd, with the databases, /gbdb, and trash left shared. Generalized from the personal version: per-user sandbox paths, TS_ROOT for the instance directory, and existence checks in create. diff --git src/utils/ts/ts.mac src/utils/ts/ts.mac new file mode 100755 index 00000000000..2e7d4daefeb --- /dev/null +++ src/utils/ts/ts.mac @@ -0,0 +1,68 @@ +#!/bin/bash +# +# ts (laptop side) - reach and drive UCSC "ticket sandbox" browsers parked on +# hgwdev. refs #37867 +# +# The real tool lives on hgwdev at ~/ticketSandboxes/bin/ts and does the freezing +# and httpd management there. This thin wrapper, meant for your Mac, runs those +# subcommands over ssh and opens the local ssh -L tunnel so you can point a +# browser at a parked instance. +# +# ts NNNNN open a tunnel to parked ticket NNNNN, print its URL +# ts tunnel NNNNN same +# ts list list parked tickets on hgwdev +# ts create NNNNN [note] run remotely on hgwdev (freeze + start) +# ts sync|start|stop|remove NNNNN +# +# Set HGWDEV to override the host (default hgwdev.gi.ucsc.edu); e.g. if you have +# a "Host hgwdev" block in ~/.ssh/config, run: HGWDEV=hgwdev ts list +# Set TS_REMOTE to override the path of the real ts on hgwdev (default +# ticketSandboxes/bin/ts, relative to your hgwdev home). +# +set -eu + +HGWDEV="${HGWDEV:-hgwdev.gi.ucsc.edu}" +REMOTE="${TS_REMOTE:-ticketSandboxes/bin/ts}" # path under your hgwdev home + +# tunnel makes two ssh connections (port lookup, then the tunnel). With key +# auth set up neither prompts; do NOT use ControlMaster/ControlPersist here, its +# backgrounded master swallows the Ctrl-C that should close the foreground tunnel. + +usage() { + sed -n '11,20p' "$0" | sed 's/^#\{0,1\} \{0,1\}//' + exit 1 +} + +[ $# -ge 1 ] || usage +sub="$1" + +case "$sub" in + -h|--help|help) usage;; +esac + +# a bare ticket number is shorthand for "tunnel" +if printf '%s' "$sub" | grep -qE '^[0-9]+$'; then + set -- tunnel "$sub" + sub=tunnel +fi + +case "$sub" in + tunnel) + [ $# -eq 2 ] || usage + tkt="$2" + printf '%s' "$tkt" | grep -qE '^[0-9]+$' || { echo "ts: ticket must be numeric" >&2; exit 1; } + port="$(ssh "$HGWDEV" "$REMOTE port $tkt")" || exit 1 + [ -n "$port" ] || { echo "ts: no port for ticket $tkt" >&2; exit 1; } + echo "Tunnel: localhost:$port -> $HGWDEV (ticket $tkt)" + echo "Open: http://localhost:$port/cgi-bin/hgTracks" + echo "Ctrl-C closes the tunnel." + exec ssh -N -L "$port:localhost:$port" "$HGWDEV" + ;; + list|create|sync|start|stop|remove) + # run the real ts on hgwdev; use a login shell so PATH has ss/httpd + cmd="$REMOTE" + for a in "$@"; do cmd="$cmd $(printf '%q' "$a")"; done + exec ssh -t "$HGWDEV" "bash -lc $(printf '%q' "$cmd")" + ;; + *) usage;; +esac