798c382a4e6e6f2e9ecaf6c47300f8cc2a6e0074
braney
  Mon Aug 24 08:54:58 2026 -0700
ts: add a conf subcommand to rewrite httpd.conf without re-freezing, refs #37867

The CORS scoping fix in 4d9755a1 changed the httpd.conf template, but a
parked instance keeps the conf it was created with.  All three parked
instances therefore still set Access-Control-Allow-Origin at server
scope, including on cgi-bin.  That is the hole 4d9755a1 closed in the
template only.

The one way to pick up a template change was "ts sync", and cmd_sync
calls freeze before writeConf.  For a park whose whole point is the
frozen code, re-freezing to the current live sandbox throws away the
thing being kept.  There was no way to update only the config.

"ts conf NNNNN" rewrites httpd.conf from the current template, leaves
the frozen cgi-bin and htdocs alone, and restarts the httpd if it was
running.  Ran it on all three parked instances: cgi-bin now sends no
Access-Control header, htdocs and trash send both.

diff --git src/utils/ts/ts.mac src/utils/ts/ts.mac
index 2e7d4daefeb..d6cbcd84bb2 100755
--- src/utils/ts/ts.mac
+++ src/utils/ts/ts.mac
@@ -1,68 +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
+#   ts sync|conf|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)
+    list|create|sync|conf|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