Skip to content

Commit b4e50c0

Browse files
committed
Add tmux-cssh as replacement for clusterssh
1 parent 8810588 commit b4e50c0

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/sh
2+
3+
hosts=""
4+
ssh_options=""
5+
tmux_name="cssh"
6+
tmux_attach_current_session="false"
7+
8+
usage() {
9+
echo "Usage: $0 [options] host [host ...]" >&2
10+
echo "" >&2
11+
echo "Spawns multiple synchronized SSH sessions inside a tmux session." >&2
12+
echo "" >&2
13+
echo "Options:" >&2
14+
echo " -h Show help" >&2
15+
echo " -c Use the current tmux session and just spawn a new window instead" >&2
16+
echo " -n <name> Name of the tmux session or window (default: cssh)" >&2
17+
echo " -o <ssh args> Additional SSH arguments" >&2
18+
}
19+
20+
while [ $# -ne 0 ]; do
21+
case $1 in
22+
-n)
23+
shift
24+
if [ $# -eq 0 ]; then
25+
usage
26+
exit 2
27+
fi
28+
tmux_name="$1"
29+
shift
30+
;;
31+
-c)
32+
tmux_attach_current_session="true"
33+
shift
34+
;;
35+
-o)
36+
shift
37+
if [ $# -eq 0 ]; then
38+
usage
39+
exit 2
40+
fi
41+
ssh_options="$1"
42+
shift
43+
;;
44+
-h)
45+
usage
46+
exit 0
47+
;;
48+
-*)
49+
usage
50+
exit 2
51+
;;
52+
*)
53+
hosts="${hosts}${hosts:+ }$1"
54+
shift
55+
;;
56+
esac
57+
done
58+
59+
if [ -z "${hosts}" ]; then
60+
usage
61+
exit 2
62+
fi
63+
64+
# Find a name for a new session
65+
n=0
66+
while tmux has-session -t "${tmux_name}-${n}" 2>/dev/null; do n=$((n + 1)); done
67+
tmux_session="${tmux_name}-${n}"
68+
69+
if [ "${tmux_attach_current_session}" = "true" ]; then
70+
tmux_session="$(tmux display-message -p '#S')"
71+
# Find a name for a new window
72+
n=0
73+
while tmux list-windows -F "#W" | grep -q "${tmux_name}-${n}" 2>/dev/null; do n=$((n + 1)); done
74+
tmux_window="${tmux_name}-${n}"
75+
tmux_window_options="-n ${tmux_window}"
76+
fi
77+
78+
# If host doesn't look like a DNS name, it may be a CSSH cluster
79+
if ! echo "${hosts}" | grep -q '[. ]'; then
80+
for cfg in "${HOME}/.clusterssh/clusters" /etc/clusters; do
81+
if [ -r "${cfg}" ]; then
82+
h="$(sed -n "s/^${hosts} //p" <"${cfg}")"
83+
if [ -n "${h}" ]; then
84+
hosts="${h}"
85+
break
86+
fi
87+
fi
88+
# If there was no corresponding cluster name,
89+
# just assume we have an unqualified domain name
90+
done
91+
fi
92+
93+
# Open a new session and split into new panes for each SSH session
94+
for host in ${hosts}; do
95+
if ! tmux has-session -t "${tmux_session}" 2>/dev/null; then
96+
tmux new-session -s "${tmux_session}" -d "ssh ${ssh_options} ${host}"
97+
elif [ "${tmux_attach_current_session}" = "true" ]; then
98+
if ! tmux list-windows -F "#W" | grep -q "${tmux_window}" >/dev/null; then
99+
# shellcheck disable=SC2086
100+
tmux new-window ${tmux_window_options} "ssh ${ssh_options} ${host}"
101+
else
102+
tmux split-window -t "${tmux_window}" -d "ssh ${ssh_options} ${host}"
103+
# We have to reset the layout after each new pane otherwise the panes
104+
# quickly become too small to spawn any more
105+
tmux select-layout -t "${tmux_session}" tiled
106+
fi
107+
else
108+
tmux split-window -t "${tmux_session}" -d "ssh ${ssh_options} ${host}"
109+
# We have to reset the layout after each new pane otherwise the panes
110+
# quickly become too small to spawn any more
111+
tmux select-layout -t "${tmux_session}" tiled
112+
fi
113+
done
114+
115+
# Synchronize panes by default
116+
if [ "${tmux_attach_current_session}" = "true" ]; then
117+
tmux set-window-option -t "${tmux_window}" synchronize-panes on
118+
else
119+
tmux set-window-option -t "${tmux_session}" synchronize-panes on
120+
fi
121+
122+
if [ -n "${TMUX}" ]; then
123+
# We are in a tmux, just switch to the new session
124+
tmux switch-client -t "${tmux_session}"
125+
else
126+
# We are NOT in a tmux, attach to the new session
127+
tmux attach-session -t "${tmux_session}"
128+
fi
129+
130+
exit 0

provision-contest/ansible/roles/clusterssh/tasks/main.yml

+43
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,46 @@
2222
src: clusters.j2
2323
dest: /home/domjudge/.clusterssh/clusters
2424
mode: 0644
25+
26+
- name: Install tmux-cssh
27+
when: not WF_RESTRICTED_NETWORK
28+
get_url:
29+
url: https://raw.githubusercontent.com/peikk0/tmux-cssh/master/tmux-cssh
30+
dest: /usr/local/bin/tmux-cssh
31+
mode: 0755
32+
owner: root
33+
group: root
34+
35+
- name: Install tmux-cssh
36+
when: WF_RESTRICTED_NETWORK
37+
copy:
38+
src: tmux-cssh
39+
dest: /usr/local/bin/tmux-cssh
40+
mode: 0755
41+
owner: root
42+
group: root
43+
44+
- name: Set tmux-cssh shorthands
45+
template:
46+
owner: root
47+
group: root
48+
mode: 0755
49+
src: tmux-cluster.sh.j2
50+
dest: /usr/local/bin/{{ item.short }}
51+
loop:
52+
- short: ssh-jh
53+
group: wfinal-judgehost
54+
- short: ssh-jhanalyst
55+
group: analyst-judgehost
56+
- short: ssh-jhall
57+
group: judgehost
58+
- short: ssh-dom
59+
group: wfinal-domserver
60+
- short: ssh-domanalyst
61+
group: analyst-domserver
62+
- short: ssh-domall
63+
group: domserver
64+
- short: ssh-all
65+
group: onprem
66+
- short: ssh-admin
67+
group: admin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/sh
2+
3+
tmux-cssh {% for host in groups[item.group] %}{{ host }} {% endfor %}

0 commit comments

Comments
 (0)