-
Notifications
You must be signed in to change notification settings - Fork 4
/
ec4docker
executable file
·268 lines (244 loc) · 11.4 KB
/
ec4docker
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#!/bin/bash
#
# EC4Docker - Elastic Cluster for Docker
# https://github.com/grycap/ec4docker
#
# Copyright (C) GRyCAP - I3M - UPV
# Developed by Carlos A. caralla@upv.es
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
function usage() {
echo "
EC4Docker - Elastic Cluster for Docker (v.0.10.3)
---------------------------------------------------
https://github.com/grycap/ec4docker
Copyright (C) GRyCAP - I3M - UPV
USAGE:
$0 < [--list|-l] [--create|-c] [--deploy-nodes|-d] | [--terminate|-t] > [[--config-file|-f] <config-file>][[--net|-n] <net-name>] [[--docker-host|-H] <hostname:port>] [[--front-end-image|-F] <image-id>] [[--working-node-image|-w] <image-id>] [[--server-name|-s] <frontend-name>] [[--node-basename|-b] <wn-name>] [[--node-count|-N] <number>] [--yes|-y] [--help|-h]"
echo "
--config-file | -f Indicate the path of the config file, where the details of the cluster are provided
--create | -c Create a cluster
--deploy-nodes | -d Deploy the nodes of the cluster
--docker-host | -H Indicate the hostname:port where the Docker daemon that you want to use is running, i.e. the Docker Swarm manager
--front-end-image | -F Indicate the name of the docker container image to use to deploy the front-end
--list | -l List the details of the cluster
--net | -n Indicate the name of the already created overlay network
--node-basename | -b Indicate the basename of the working nodes (it will be followed by a number for each node)
--node-count | -N Indicate the maximum number of nodes that the cluster will have
--server-name | -s Indicate the name of the front-end machine
--terminate | -t Terminate an already created cluster
--working-node-image | -w Indicate the name of the docker container image to use to deploy the working nodes
--yes | -y Assume yes
--help | -h Show this message and exit
"
}
CONFIG_FILE=$PWD/ec4docker.config
DEPLOY_NODES=False
ASSUME_YES=False
SETUP_CLUSTER=False
TERMINATE_CLUSTER=False
SHOW_CLUSTERS=False
MULTIFLAG=
DOCKER_NODE=
DOCKER_NETWORK=
ARR=( )
CMDLINE_EC4DOCK_SERVERNAME=
CMDLINE_EC4DOCK_MAXNODES=
CMDLINE_EC4DOCK_FRONTEND_IMAGENAME=
CMDLINE_EC4DOCK_WN_IMAGENAME=
CMDLINE_EC4DOCK_NODEBASENAME=
n=0
while [ $# -gt 0 ]; do
if [ "${1:0:1}" == "-" -a "${1:1:1}" != "-" ]; then
for f in $(echo "${1:1}" | sed 's/\(.\)/-\1 /g' ); do
ARR[$n]="$f"
n=$(($n+1))
done
else
ARR[$n]="$1"
n=$(($n+1))
fi
shift
done
n=0
while [ $n -lt ${#ARR[@]} ]; do
case "${ARR[$n]}" in
--server-name | -s) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CMDLINE_EC4DOCK_SERVERNAME="${ARR[$n]}";;
--node-count | -N) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CMDLINE_EC4DOCK_MAXNODES="${ARR[$n]}";;
--front-end-image | -F) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CMDLINE_EC4DOCK_FRONTEND_IMAGENAME="${ARR[$n]}";;
--working-node-image | -w) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CMDLINE_EC4DOCK_WN_IMAGENAME="${ARR[$n]}";;
--node-basename | -b) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CMDLINE_EC4DOCK_NODEBASENAME="${ARR[$n]}";;
--net | -n) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
DOCKER_NETWORK="${ARR[$n]}";;
--docker-host | -H) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
DOCKER_NODE="${ARR[$n]}";;
--list | -l) SHOW_CLUSTERS=True;;
--create | -c) SETUP_CLUSTER=True;;
--terminate | -t) TERMINATE_CLUSTER=True;;
--deploy-nodes | -d) DEPLOY_NODES=True;;
--yes | -y) ASSUME_YES=True;;
--config-file | -f) n=$(($n+1))
[ $n -ge ${#ARR[@]} ] && usage && exit 1
CONFIG_FILE="${ARR[$n]}";;
--help | -h) usage && exit 0;;
*) usage && exit 1;;
esac
n=$(($n+1))
done
function EXIT_ERROR() {
echo "ERROR: $1" >&2
usage
exit 1
}
# Read the configuration if exists
if [ ! -e "$CONFIG_FILE" ]; then
echo "WARNING: file $CONFIG_FILE does not exist... ignoring and getting default variables" >&2
else
source $CONFIG_FILE
fi
DOCKERCMD=docker
[ "$DOCKER_NODE" != "" ] && DOCKERCMD="docker -H $DOCKER_NODE"
NETWORK_STR=
[ "$DOCKER_NETWORK" != "" ] && NETWORK_STR="--net=$DOCKER_NETWORK"
# Set the default values if they are not set
EC4DOCK_SERVERNAME=${EC4DOCK_SERVERNAME:-ec4docker}
EC4DOCK_MAXNODES=${EC4DOCK_MAXNODES:-4}
EC4DOCK_FRONTEND_IMAGENAME=${EC4DOCK_FRONTEND_IMAGENAME:-ec4docker:frontend}
EC4DOCK_WN_IMAGENAME=${EC4DOCK_WN_IMAGENAME:-ec4docker:wn}
EC4DOCK_NODEBASENAME=${EC4DOCK_NODEBASENAME:-ec4docknode}
EC4DOCK_FRONTEND_DOCKER_OPTIONS=${EC4DOCK_FRONTEND_DOCKER_OPTIONS:-}
EC4DOCK_WN_DOCKER_OPTIONS=${EC4DOCK_WN_DOCKER_OPTIONS:-}
EC4DOCK_DOCKER_NETWORK=$DOCKER_NETWORK
# Check if some values are overridden in commandline
[ "$CMDLINE_EC4DOCK_SERVERNAME" != "" ] && EC4DOCK_SERVERNAME="$CMDLINE_EC4DOCK_SERVERNAME"
[ "$CMDLINE_EC4DOCK_MAXNODES" != "" ] && EC4DOCK_MAXNODES="$CMDLINE_EC4DOCK_MAXNODES"
[ "$CMDLINE_EC4DOCK_FRONTEND_IMAGENAME" != "" ] && EC4DOCK_FRONTEND_IMAGENAME="$CMDLINE_EC4DOCK_FRONTEND_IMAGENAME"
[ "$CMDLINE_EC4DOCK_WN_IMAGENAME" != "" ] && EC4DOCK_WN_IMAGENAME="$CMDLINE_EC4DOCK_WN_IMAGENAME"
[ "$CMDLINE_EC4DOCK_NODEBASENAME" != "" ] && EC4DOCK_NODEBASENAME="$CMDLINE_EC4DOCK_NODEBASENAME"
IPFIELD="{{.NetworkSettings.IPAddress}}"
[ "$EC4DOCK_DOCKER_NETWORK" != "" ] && IPFIELD="{{.NetworkSettings.Networks.$EC4DOCK_DOCKER_NETWORK.IPAddress}}"
function find_nodes() {
# We'll try to find any docker container with the corresponding name whose associated server has
# the provided IP.
IPADDR=$1
POSSIBLE_NODES=$($DOCKERCMD ps -a --format {{.Names}} | grep "$EC4DOCK_NODEBASENAME")
for N in $POSSIBLE_NODES; do
VARS=$($DOCKERCMD inspect -f '{{.Config.Env}}' $N | tr -d '[]' | tr ' ' '\n');
for V in $VARS; do
IFS=\= read VAR VALUE <<< $V
if [ "$VAR" == "EC4DOCK_SERVERIP" -a "$VALUE" == "$IPADDR" ]; then
echo -n "$N "
fi
done
done
}
function frontend_exists() {
IPADDR=$($DOCKERCMD inspect -f "$IPFIELD" $EC4DOCK_SERVERNAME 2> /dev/null)
if [ $? -eq 0 ]; then
return 0
else
return 1
fi
}
function terminate_cluster() {
# Check if the server exists and get its IP addresses
IPADDRESSES="$IPADDR $($DOCKERCMD inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" $EC4DOCK_SERVERNAME 2> /dev/null)"
# If the front-end exists, we'll try to terminate it
if [ $? -eq 0 ]; then
for IPADDR in $IPADDRESSES; do
echo "A container with name $EC4DOCK_SERVERNAME already exists"
WNS=$(find_nodes $IPADDR)
if [ "$WNS" != "" ]; then
echo "WARNING: Nodes '$WNS' seem to be part of the cluster"
fi
if [ "$ASSUME_YES" != "True" ]; then
read -p "Do you want me to kill container(s)? (y/N) " KILL
else
KILL=y
fi
if [ "$(echo $KILL | tr 'y' 'Y')" == "Y" ]; then
for WNNAME in $WNS; do
echo "killing container $WNNAME"
$DOCKERCMD stop $WNNAME > /dev/null 2> /dev/null
$DOCKERCMD rm $WNNAME > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: failed to terminate $WNNAME"
fi
done
echo "killing container $EC4DOCK_SERVERNAME"
$DOCKERCMD stop $EC4DOCK_SERVERNAME > /dev/null 2> /dev/null
$DOCKERCMD rm $EC4DOCK_SERVERNAME > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: failed to terminate $EC4DOCK_SERVERNAME"
fi
else
exit 1
fi
done
fi
}
function setup_cluster() {
# We execute the container
# - we have to run it in privileged mode because of torque requirements
$DOCKERCMD run -p 22 --privileged -v /var/run/docker.sock:/var/run/docker.sock $NETWORK_STR $EC4DOCK_FRONTEND_DOCKER_OPTIONS -e EC4DOCK_DOCKER_NETWORK="$DOCKER_NETWORK" -e EC4DOCK_DOCKER_NODE=$DOCKER_NODE -e EC4DOCK_WN_DOCKER_OPTIONS="$EC4DOCK_WN_DOCKER_OPTIONS" -e EC4DOCK_FRONTEND_DOCKER_OPTIONS="$EC4DOCK_FRONTEND_DOCKER_OPTIONS" -e "EC4DOCK_FRONTEND_IMAGENAME=$EC4DOCK_FRONTEND_IMAGENAME" -e "EC4DOCK_WN_IMAGENAME=$EC4DOCK_WN_IMAGENAME" -e "EC4DOCK_SERVERNAME=$EC4DOCK_SERVERNAME" -e "EC4DOCK_MAXNODES=$EC4DOCK_MAXNODES" -e "EC4DOCK_NODEBASENAME=$EC4DOCK_NODEBASENAME" -h $EC4DOCK_SERVERNAME --name $EC4DOCK_SERVERNAME -id $EC4DOCK_FRONTEND_IMAGENAME
if [ $? -eq 0 ]; then
if [ "$DEPLOY_NODES" == "True" ]; then
echo "waiting a bit to deploy the frontend"
sleep 10s
for n in $(seq 1 $EC4DOCK_MAXNODES); do
NODENAME=${EC4DOCK_NODEBASENAME}${n}
echo -n "starting node $NODENAME ..."
$DOCKERCMD exec $EC4DOCK_SERVERNAME /opt/ec4docker/poweron $NODENAME > /dev/null 2> /dev/null
if [ $? -eq 0 ]; then
echo -e "[\e[32msucceeded\e[0m]"
else
echo -e "[\e[31mfailed\e[0m]"
fi
done
fi
fi
return 0
}
if [ "$SHOW_CLUSTERS" == "True" ]; then
IPADDR=$($DOCKERCMD inspect -f "$IPFIELD" $EC4DOCK_SERVERNAME 2> /dev/null)
if [ $? -eq 0 ]; then
echo -n "A cluster with name $EC4DOCK_SERVERNAME is running with IP $IPADDR. Its nodes are: "
echo "$(find_nodes $IPADDR)"
fi
fi
if [ "$TERMINATE_CLUSTER" == "True" ]; then
terminate_cluster
fi
if [ "$SETUP_CLUSTER" == "True" ]; then
if frontend_exists; then
EXIT_ERROR "frontend already exists"
fi
setup_cluster
fi
if [ "$SETUP_CLUSTER" == "False" -a "$TERMINATE_CLUSTER" == "False" ]; then
echo "Neither --create or --terminate operations were stated, so we are doing nothing"
fi
exit 0