Files
DeeJanuzandClaude Opus 5.5 0280e7441d Installers: ask for sudo in the terminal, and cope with SteamVR off
- frame_sudo (scripts/_env.sh) replaces three copies of sudo_run. On
  the Frame it asks in the terminal even when stdin isn't one, which
  install.sh's steps never had: saying yes to the Bluetooth fixes or
  hand tracking stopped the install with "no terminal for sudo".
  From a PC it asks through ssh -t when .env has no password.
- start_with_steamvr: the pointer, power, and gaze services restart
  when SteamVR runs (a re-install runs the new code) and are left to
  start with it when it doesn't, instead of failing the install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 15:04:49 -06:00

54 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Install, start, stop, or inspect hand tracking on the Frame: ft-camd (the camera broker) and
# ft-hands (the tracker), user services that stop with SteamVR. They don't start with it:
# ft-handsctl on|off (on the Frame) or hands/run.sh start|stop.
# Usage: hands/run.sh install|uninstall
# hands/run.sh caps # give ft-camd its capabilities again (a rebuild clears them)
# hands/run.sh start|stop|restart|status|log [lines]
# install and caps need the password (sudo setcap, once per build of ft-camd): it's asked in
# the terminal, on the Frame or from a PC (frame_sudo in scripts/_env.sh, which also takes it
# from the repo's .env).
set -euo pipefail
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
. "$root/scripts/_env.sh"
frame="$root/scripts/frame.sh"
units="frametop-camd.service frametop-hands.service"
# pidfd_getfd on XRService (ptrace_scope=1), system-wide tracepoints, and their root-only
# format files. ft-camd drops them all once it has set up.
caps=cap_sys_ptrace,cap_perfmon,cap_dac_read_search+ep
sudo_run() { frame_sudo "$1"; }
set_caps() { # only when missing: a rebuild clears them, a reinstall doesn't
local bin
bin=$(printf %q "$FRAME_REPO/hands/build/ft-camd")
if on_frame "getcap $bin | grep -q cap_sys_ptrace"; then
echo "ft-camd has its capabilities"
return
fi
sudo_run "setcap $caps $bin && getcap $bin"
}
states="for u in $units; do echo \"\$u: \$(systemctl --user is-active \$u)\"; done"
case ${1:-status} in
install)
"$root/hands/build.sh"
set_caps
for u in $units; do
fill_template "$root/hands/$u" | on_frame "mkdir -p ~/.config/systemd/user && cat > ~/.config/systemd/user/$u"
done
# Installed but not started with SteamVR: ft-handsctl on|off (linked into ~/.local/bin).
"$frame" --host "set -e; systemctl --user daemon-reload; systemctl --user disable $units 2>/dev/null || true
mkdir -p ~/.local/bin && ln -sfn $(printf %q "$FRAME_REPO/hands/ft-handsctl") ~/.local/bin/ft-handsctl
$states; echo 'start it with: ft-handsctl on'" ;;
caps) set_caps ;;
uninstall) "$frame" --host "systemctl --user disable --now $units 2>/dev/null
for u in $units; do rm -f ~/.config/systemd/user/\$u; done; systemctl --user daemon-reload
[ -L ~/.local/bin/ft-handsctl ] && rm -f ~/.local/bin/ft-handsctl; echo removed" ;;
start|stop|restart) "$frame" --host "systemctl --user $1 $units; $states" ;;
status) "$frame" --host "$states; journalctl --user -u frametop-hands.service --no-pager -o cat -n 4" || true ;;
log) "$frame" --host "journalctl --user -u frametop-camd.service -u frametop-hands.service --no-pager -o short -n ${2:-30}" ;;
*) echo "usage: $0 install|uninstall|caps|start|stop|restart|status|log [lines]" >&2; exit 2 ;;
esac