Skip to content

Commit

Permalink
Add tmux-cssh as replacement for clusterssh
Browse files Browse the repository at this point in the history
  • Loading branch information
vmcj committed Sep 12, 2024
1 parent 8ef0121 commit d76a4e4
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
130 changes: 130 additions & 0 deletions provision-contest/ansible/roles/clusterssh/files/tmux-cssh
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/bin/sh

hosts=""
ssh_options=""
tmux_name="cssh"
tmux_attach_current_session="false"

usage() {
echo "Usage: $0 [options] host [host ...]" >&2
echo "" >&2
echo "Spawns multiple synchronized SSH sessions inside a tmux session." >&2
echo "" >&2
echo "Options:" >&2
echo " -h Show help" >&2
echo " -c Use the current tmux session and just spawn a new window instead" >&2
echo " -n <name> Name of the tmux session or window (default: cssh)" >&2
echo " -o <ssh args> Additional SSH arguments" >&2
}

while [ $# -ne 0 ]; do
case $1 in
-n)
shift
if [ $# -eq 0 ]; then
usage
exit 2
fi
tmux_name="$1"
shift
;;
-c)
tmux_attach_current_session="true"
shift
;;
-o)
shift
if [ $# -eq 0 ]; then
usage
exit 2
fi
ssh_options="$1"
shift
;;
-h)
usage
exit 0
;;
-*)
usage
exit 2
;;
*)
hosts="${hosts}${hosts:+ }$1"
shift
;;
esac
done

if [ -z "${hosts}" ]; then
usage
exit 2
fi

# Find a name for a new session
n=0
while tmux has-session -t "${tmux_name}-${n}" 2>/dev/null; do n=$((n + 1)); done
tmux_session="${tmux_name}-${n}"

if [ "${tmux_attach_current_session}" = "true" ]; then
tmux_session="$(tmux display-message -p '#S')"
# Find a name for a new window
n=0
while tmux list-windows -F "#W" | grep -q "${tmux_name}-${n}" 2>/dev/null; do n=$((n + 1)); done
tmux_window="${tmux_name}-${n}"
tmux_window_options="-n ${tmux_window}"
fi

# If host doesn't look like a DNS name, it may be a CSSH cluster
if ! echo "${hosts}" | grep -q '[. ]'; then
for cfg in "${HOME}/.clusterssh/clusters" /etc/clusters; do
if [ -r "${cfg}" ]; then
h="$(sed -n "s/^${hosts} //p" <"${cfg}")"
if [ -n "${h}" ]; then
hosts="${h}"
break
fi
fi
# If there was no corresponding cluster name,
# just assume we have an unqualified domain name
done
fi

# Open a new session and split into new panes for each SSH session
for host in ${hosts}; do
if ! tmux has-session -t "${tmux_session}" 2>/dev/null; then
tmux new-session -s "${tmux_session}" -d "ssh ${ssh_options} ${host}"
elif [ "${tmux_attach_current_session}" = "true" ]; then
if ! tmux list-windows -F "#W" | grep -q "${tmux_window}" >/dev/null; then
# shellcheck disable=SC2086
tmux new-window ${tmux_window_options} "ssh ${ssh_options} ${host}"
else
tmux split-window -t "${tmux_window}" -d "ssh ${ssh_options} ${host}"
# We have to reset the layout after each new pane otherwise the panes
# quickly become too small to spawn any more
tmux select-layout -t "${tmux_session}" tiled
fi
else
tmux split-window -t "${tmux_session}" -d "ssh ${ssh_options} ${host}"
# We have to reset the layout after each new pane otherwise the panes
# quickly become too small to spawn any more
tmux select-layout -t "${tmux_session}" tiled
fi
done

# Synchronize panes by default
if [ "${tmux_attach_current_session}" = "true" ]; then
tmux set-window-option -t "${tmux_window}" synchronize-panes on
else
tmux set-window-option -t "${tmux_session}" synchronize-panes on
fi

if [ -n "${TMUX}" ]; then
# We are in a tmux, just switch to the new session
tmux switch-client -t "${tmux_session}"
else
# We are NOT in a tmux, attach to the new session
tmux attach-session -t "${tmux_session}"
fi

exit 0
43 changes: 43 additions & 0 deletions provision-contest/ansible/roles/clusterssh/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,46 @@
src: clusters.j2
dest: /home/domjudge/.clusterssh/clusters
mode: 0644

- name: Install tmux-cssh
when: not WF_RESTRICTED_NETWORK
get_url:
url: https://raw.githubusercontent.com/peikk0/tmux-cssh/master/tmux-cssh
dest: /usr/local/bin/tmux-cssh
mode: 0755
owner: root
group: root

- name: Install tmux-cssh
when: WF_RESTRICTED_NETWORK
copy:
src: tmux-cssh
dest: /usr/local/bin/tmux-cssh
mode: 0755
owner: root
group: root

- name: Set tmux-cssh shorthands
template:
owner: root
group: root
mode: 0755
src: tmux-cluster.sh.j2
dest: /usr/local/bin/{{ item.short }}
loop:
- short: ssh-jh
group: wfinal-judgehost
- short: ssh-jhanalyst
group: analyst-judgehost
- short: ssh-jhall
group: judgehost
- short: ssh-dom
group: wfinal-domserver
- short: ssh-domanalyst
group: analyst-domserver
- short: ssh-domall
group: domserver
- short: ssh-all
group: onprem
- short: ssh-admin
group: admin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/sh

tmux-cssh {% for host in groups[item.group] %}{{ host }} {% endfor %}

0 comments on commit d76a4e4

Please sign in to comment.