c83ddf62a0
A member's tmux server keeps the version it started with until their last pane closes, but the dashboard asked it with TMUX_BIN, the newest tmux: a 3.8 client on a 3.6 server spun it at 100% CPU (three members needed a manual kill on 2026-10-15). - /opt/agenthub/libexec/tmux-member (install-system, in sudoers): runs a member's tmux call with the binary of THEIR running server (/proc/<pid>/exe, found from the socket in /proc/net/unix), else TMUX_BIN. It runs as the member and execs only a process they own. sudoArgv uses it once installed (linux-accounts readConf), TMUX_BIN until then. - Users → Members' tmux (GET /api/users/tmux): each member server's version beside the installed one, sessions, agents working. An admin restarts one (POST /api/users/:id/tmux-restart) or every idle outdated one (POST /api/users/tmux-restart-idle), with their password again, audited per member; a server that will not stop answers 409 ETMUXSTUCK naming its pid for root. - server-s3-system.test.js: `delete` is a provision action since Delete user, so the "unknown action" case now uses `purge`. Operators: run `sudo agenthub server install-system` once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.6 KiB
Bash
Executable File
35 lines
1.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# @file tmux-member.sh
|
|
# @description Server mode, one Linux user per account (S3): installed as
|
|
# /opt/agenthub/libexec/tmux-member, the one tmux the host may run AS a
|
|
# member (sudoers). Called as `tmux-member -S <socket> <tmux args…>`, it runs
|
|
# the args with the binary of the tmux server already listening on that
|
|
# socket (`/proc/<pid>/exe`, which still runs after an upgrade replaced the
|
|
# file), else with TMUX_BIN from /etc/agenthub/server.conf (no server yet:
|
|
# this call starts one, on the installed version). A client must match its
|
|
# server: a tmux 3.8 client asking a 3.6 server kept it at 100% CPU.
|
|
#
|
|
# It runs as the member and execs only a process THEY own (under hidepid they
|
|
# see no other), so it can run nothing they could not run themselves.
|
|
# @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
set -u
|
|
bin=$(sed -n 's/^TMUX_BIN=//p' /etc/agenthub/server.conf 2>/dev/null | head -n 1)
|
|
[[ "$bin" == /* ]] || { echo "tmux-member: no TMUX_BIN in /etc/agenthub/server.conf" >&2; exit 2; }
|
|
if [ "${1:-}" = -S ] && [ -n "${2:-}" ]; then
|
|
# /proc/net/unix: Num RefCount Protocol Flags Type St Inode Path; 00010000 = listening.
|
|
inode=$(awk -v s="$2" '$4 == "00010000" && $8 == s { print $7; exit }' /proc/net/unix 2>/dev/null)
|
|
if [ -n "$inode" ]; then
|
|
for d in /proc/[0-9]*; do
|
|
[ -O "$d" ] || continue
|
|
read -r comm <"$d/comm" 2>/dev/null || continue
|
|
[[ "$comm" == tmux* ]] || continue
|
|
for fd in "$d"/fd/*; do
|
|
if [ "$(readlink "$fd" 2>/dev/null)" = "socket:[$inode]" ] && [ -x "$d/exe" ]; then
|
|
exec "$d/exe" "$@"
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
exec "$bin" "$@"
|