-
Notifications
You must be signed in to change notification settings - Fork 1
/
pdscreen.sh
executable file
·157 lines (132 loc) · 4.56 KB
/
pdscreen.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
# Description: Generate screen sessions arranged in a split view from genders query
# Dependencies: screen, genders
### VARIABLES ###
user="$USER"
query=""
nodes=()
nodeCount=""
gendersFile="/etc/genders"
screenrcDefault=""
screenrcTemp="/tmp/screenrc.${USER}"
### DOCUMENTATION ###
function usage {
cat << EOF
Usage: pdscreen.sh [-d <domain>] [-u <username> ] <query>
pdscreen.sh [-d <domain>] [-u <username> ] -n <hostname> [-n <hostname> ...]
pdscreen.sh -h
Options:
-n Specifies the name of the host to connect to
-d Append <domain> to each hostname
-u Specifies user to login to hosts as (defaults to local user)
-h Shows usage information
Notes:
<query> can be any valid genders query returning up to 25 hosts. More than
that and the script will exit.
EOF
exit
}
### HELPER FUNCTIONS ###
function error { IFS='\n' printf >&2 "[1;31mERROR: %s[0m\n" "$*" ;}
function success { IFS='\n' printf >&2 "[1;32mSUCCESS: %s[0m\n" "$*" ;}
function warning { IFS='\n' printf >&2 "[1;33mWARNING: %s[0m\n" "$*" ;}
function prompt { IFS='\n' printf >&2 "[1;36m%s[0m\n" "$*" ;}
function quit { prompt "Exiting..." ; exit 0 ;}
### PRIMARY FUNCTIONS ###
function check_dependencies {
command -v screen 2> /dev/null >&2 || error "'screen' not in your PATH."
command -v nodeattr 2> /dev/null >&2 || error "'nodeattr' not in your PATH."
[ -f ${HOME}/.screenrc ] \
&& screenrcDefault="${HOME}/.screenrc" \
|| screenrcDefault="/etc/screenrc"
}
function parse_arguments {
if [ $# -eq 0 ] ; then
error 'Missing argument.' ; exit 2
elif [ "$1" == '-' ] ; then
error "Unknown option: $1" ; usage ; exit 2
else
while getopts "hu:d:n:" opt ; do
case $opt in
h) usage ;;
n) nodes+=("$OPTARG") ;;
d) domain="$OPTARG" ;;
u) user="$OPTARG" ;;
*) query="$*" ;;
\?) error "Unknown option: -$OPTARG" ; usage ; exit 2 ;;
:) error "-$OPTARG requires an argument." ; usage ; exit 2 ;;
esac
done
fi
shift $((OPTIND-1)) # Cleaning up arguments
query="$*"
}
function append_domain {
for i in $( seq 0 $(($nodeCount - 1)) ) ; do # Index equals array length - 1
nodes[$i]+="$domain" # Iterate over array and append domain to each item
done
}
function count_nodes {
if [ ! $nodes ] ; then
nodes=( $(nodeattr -s $query -f $gendersFile) )
fi
nodeCount=${#nodes[*]}
if [ $domain ] ; then
append_domain
fi
if [ $nodeCount -eq 1 ] ; then # 1: onebyone
warning "Only one node returned. Just use screen." ; quit
elif [ $nodeCount -le 2 ] ; then # 2: onebytwo
hsplit=1 vsplit=1 windows=2 layout=twobyone
elif [ $nodeCount -le 4 ] ; then # 4: twobytwo
hsplit=1 vsplit=2 windows=4 layout=twobytwo
elif [ $nodeCount -le 6 ] ; then # 6: threebytwo
hsplit=1 vsplit=3 windows=6 layout=threebytwo
elif [ $nodeCount -le 9 ] ; then # 9: threebythree
hsplit=2 vsplit=3 windows=9 layout=threebythree
elif [ $nodeCount -le 12 ] ; then # 12: threebyfour
hsplit=3 vsplit=3 windows=12 layout=fourbythree
elif [ $nodeCount -le 16 ] ; then # 16: fourbyfour
hsplit=3 vsplit=4 windows=16 layout=fourbyfour
elif [ $nodeCount -le 20 ] ; then # 20: fourbyfive
hsplit=4 vsplit=4 windows=20 layout=fivebyfour
elif [ $nodeCount -le 25 ] ; then # 25: fivebyfive
hsplit=4 vsplit=5 windows=25 layout=fivebyfive
else
error "Too many nodes. Try revising your genders query."
exit
fi
}
function write_screenrc {
cp $screenrcDefault $screenrcTemp
echo "defdynamictitle off" >> $screenrcTemp # Fix name of each window to hostname
echo "layout autosave on" >> $screenrcTemp # Automatically remember layout
echo "mousetrack on" >> $screenrcTemp # Useful to be able to mouse around larger layouts
# Create the horizontal splits first
i=$hsplit
until [ $i -eq 0 ] ; do
echo 'split' >> $screenrcTemp
let i--
done
for ((j=0; $j<$windows; j++)) ; do
if [ ! -z ${nodes[$j]} ] ; then
# Make new screen window and login to the remote host
echo "screen -t ${nodes[$j]} ssh ${user}@${nodes[$j]}" >> $screenrcTemp
fi
# Create a vertical split if we're not at the end of the row
if [ $(( ($j+1) % $vsplit )) -ne 0 ] ; then
echo 'split -v' >> $screenrcTemp
fi
echo 'focus' >> $screenrcTemp
done
echo "layout save $layout" >> $screenrcTemp
}
### MAIN ###
check_dependencies
parse_arguments $@
# Gather list of nodes and count them
count_nodes
# Generate appropriate screen layout
write_screenrc
# Launch screen with layout
screen -c $screenrcTemp