Mercurial > sat_docs
comparison docker_legacy/libervia_cont.sh @ 164:29873a41aae1
docker: new docker files are now in sat main repos, this one is legacy
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 01 Jan 2021 18:33:52 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
163:a63f6d360326 | 164:29873a41aae1 |
---|---|
1 #!/bin/sh | |
2 | |
3 # Libervia container manager | |
4 # Copyright (C) 2014-2016 Jérôme Poisson (goffi@goffi.org) | |
5 | |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 VERSION="0.3.0" | |
20 APP_NAME="Libervia" | |
21 ACCOUNT="salutatoi" | |
22 | |
23 # environment variables that can be used for configuration: | |
24 # SAT_CONT_TLS_DIR for TLS certificates directory | |
25 # SAT_CONT_DOMAIN for the host name | |
26 # SAT_CONT_BACKUP_DIR is the directory where tar.gz backup will be written | |
27 # SAT_CONT_DK_EXTRA is used for extra options (used with all containers but sat_data) | |
28 # SAT_CONT_PORT_<port> is used to specify port when -p is used, <port> must be an exposed port | |
29 | |
30 CONTAINERS="prosody sat_pubsub salut sat libervia" | |
31 TEST_CONT="libervia" # container used to test status | |
32 MAINT_CONT="debian:jessie" # container used for maintenance | |
33 | |
34 DK_DETACH="-d" | |
35 DK_TERM="-ti" | |
36 | |
37 VOLUME_NAME="data" | |
38 VOLUME_CONT="$ACCOUNT/$VOLUME_NAME" | |
39 VOLUME_ALIAS="sat_data" | |
40 DK_VOLUME="--volumes-from $VOLUME_ALIAS" | |
41 | |
42 PUBLIC=0 | |
43 | |
44 PROSODY_PORTS="5222 5269 5280 5281" | |
45 PORT_5222_NAME="XMPP client to server" | |
46 PORT_5269_NAME="XMPP server to server" | |
47 PORT_5280_NAME="HTTP Upload" | |
48 PORT_5281_NAME="HTTP Upload (HTTPS)" | |
49 SAT_PORTS="10143 10125" | |
50 PORT_10143_NAME="IMAP server" | |
51 PORT_10125_NAME="SMTP server" | |
52 LIBERVIA_PORTS="8080 8443" | |
53 PORT_8080_NAME="HTTP" | |
54 PORT_8443_NAME="HTTPS" | |
55 NO_PORT="No public port" | |
56 | |
57 DOCKER_EXE="docker" | |
58 | |
59 USAGE="Usage: $0 [start|stop|restart|status|update|backup|restore|ports|config|stats] [ARGS...]" | |
60 | |
61 HELP_SITE="https://wiki.goffi.org/wiki/Docker/en" | |
62 HELP_MUC="sat@chat.jabberfr.org" | |
63 | |
64 CONT_CERT_DIR="/usr/share/sat/certificates" | |
65 DEFAULT_TMP_DIR="/tmp/tmp_sat_docker" | |
66 | |
67 eprintf() | |
68 { | |
69 >&2 printf "$@" | |
70 } | |
71 | |
72 get_dyn_var() { | |
73 # get dynamicly variable based on given name | |
74 | |
75 name=$1 | |
76 var_type=$2 | |
77 name_upp=$(echo "$name" | tr '[:lower:]' '[:upper:]') | |
78 case $var_type in | |
79 ports) eval echo "\$${name_upp}_PORTS";; | |
80 port_name) eval echo "\$PORT_${name_upp}_NAME";; | |
81 esac | |
82 } | |
83 | |
84 list_ports() { | |
85 # list used ports in currently running containers | |
86 | |
87 for cont in $CONTAINERS; do | |
88 # we get variable name with uppercase container name | |
89 # some magic to get the ports | |
90 ports=$(get_dyn_var $cont ports) | |
91 | |
92 [ -n "$ports" ] && printf "== $cont ==\n\n" | |
93 | |
94 for port in $ports; do | |
95 # some magic to get port human readable name | |
96 port_name=$(get_dyn_var $port port_name) | |
97 real_port=$(docker port $cont $port 2>&1) | |
98 if [ $? -ne 0 ]; then | |
99 real_port=$NO_PORT | |
100 fi | |
101 | |
102 # we now show the ports with nice alignment | |
103 desc="port $port ($port_name):" | |
104 nb_tabs=$((5-${#desc}/8)) | |
105 printf "$desc" | |
106 for i in $(seq $nb_tabs); do | |
107 printf "\t" | |
108 done | |
109 printf "$real_port\n" | |
110 done | |
111 [ -n "$ports" ] && printf '\n' | |
112 done | |
113 } | |
114 | |
115 public_ports_arg() { | |
116 # create Docker arg to have public ports corresponding to container ports | |
117 | |
118 if [ $PUBLIC -ne 1 ]; then | |
119 return | |
120 fi | |
121 cont=$1 | |
122 ports=$(get_dyn_var $cont ports) | |
123 ARG="" | |
124 for port in $ports; do | |
125 host_port=$(eval echo "\$SAT_CONT_PORT_${port}") | |
126 if [ -z "$host_port" ]; then | |
127 host_port=$port | |
128 fi | |
129 if [ "$host_port" != 0 ]; then | |
130 ARG="$ARG -p $host_port:$port" | |
131 fi | |
132 done | |
133 echo $ARG | |
134 } | |
135 | |
136 download_missing() { | |
137 # download images wich are not present locally | |
138 for cont in $CONTAINERS $VOLUME_NAME; do | |
139 image="$ACCOUNT/$cont" | |
140 docker inspect $image:latest > /dev/null 2>&1 | |
141 if [ $? -ne 0 ]; then | |
142 printf "$image is not present locally, downloading it\n" | |
143 docker pull $image:latest | |
144 if [ $? -eq 0 ]; then | |
145 printf "\nDownload of latest $image finished\n\n" | |
146 else | |
147 eprintf "\nError while downloading $image, please check your connection and logs\n" | |
148 return 1 | |
149 fi | |
150 fi | |
151 done | |
152 } | |
153 | |
154 check_docker() { | |
155 which $DOCKER_EXE > /dev/null 2>&1 | |
156 if [ $? -ne 0 ]; then | |
157 printf "Docker is not installed or not accessible, please install it.\nYou can check $HELP_SITE for instructions\n" | |
158 return 1 | |
159 fi | |
160 } | |
161 | |
162 check_docker_version() { | |
163 # check if current docker version is greater than or equal to the requested one | |
164 wanted_major=$1 | |
165 wanted_minor=$2 | |
166 wanted_rev=$3 | |
167 raw=$(docker --version | grep -o '\([0-9]\+\)\.[0-9]\+\.[0-9]\+') | |
168 docker_major=$(echo "$raw" | cut -d . -f 1) | |
169 docker_minor=$(echo "$raw" | cut -d . -f 2) | |
170 docker_rev=$(echo "$raw" | cut -d . -f 3) | |
171 for name in major minor rev; do | |
172 docker_val=$(eval echo \$docker_$name) | |
173 wanted_val=$(eval echo \$wanted_$name) | |
174 if [ $docker_val -gt $wanted_val ]; then | |
175 return 0 | |
176 fi | |
177 if [ $docker_val -lt $wanted_val ]; then | |
178 return 1 | |
179 fi | |
180 done | |
181 | |
182 # wanted version and docker version are the same | |
183 return 0 | |
184 } | |
185 | |
186 parse_run_args() { | |
187 # manage arguments for run command | |
188 | |
189 while [ $# -gt 0 ]; do | |
190 case "$1" in | |
191 | |
192 -h|--help) | |
193 cat << OPT_END | |
194 options available for the run command: | |
195 | |
196 -h, --help display this help message | |
197 -p, --public publish using true ports | |
198 -d DOMAIN, --domain DOMAIN use DOMAIN as domain name | |
199 OPT_END | |
200 exit 0 | |
201 ;; | |
202 | |
203 -d|--domain) | |
204 shift | |
205 if [ $# -eq 0 ]; then | |
206 printf "no domain given, --domain must be followed by a domain\n" | |
207 exit 1 | |
208 fi | |
209 SAT_CONT_DOMAIN="$1" | |
210 shift | |
211 ;; | |
212 | |
213 -p|--public) | |
214 shift | |
215 PUBLIC=1 | |
216 ;; | |
217 | |
218 *) printf "Invalid argument, please check \"$0 run --help\"\n" | |
219 exit 1 | |
220 ;; | |
221 esac | |
222 done | |
223 } | |
224 | |
225 check_docker || exit 1 | |
226 | |
227 if [ $# -ge 1 ];then | |
228 case $1 in | |
229 start) CMD=START;; | |
230 stop) CMD=STOP;; | |
231 restart) CMD=RESTART;; | |
232 status) CMD=STATUS;; | |
233 update) CMD=UPDATE;; | |
234 backup) CMD=BACKUP;; | |
235 restore) CMD=RESTORE;; | |
236 ports) CMD=PORTS;; | |
237 config) CMD=CONFIG;; | |
238 stats) CMD=STATS;; | |
239 -v|--version) printf "$VERSION\n"; exit 0;; | |
240 -h|--help) printf "$USAGE\n\nYou can check $HELP_SITE for instructions, or go to $HELP_MUC XMPP MUC room for help\n"; exit 0;; | |
241 *) echo $USAGE | |
242 exit 1 | |
243 esac | |
244 shift | |
245 else | |
246 CMD=START | |
247 fi | |
248 | |
249 case $CMD in | |
250 START) | |
251 parse_run_args "$@" | |
252 download_missing || exit 1 | |
253 | |
254 printf "Running data container... " | |
255 # we use -d even if data container doesn't stay in background to get id of the container | |
256 docker_id=$(docker run -d --name $VOLUME_ALIAS $VOLUME_CONT 2>&1) | |
257 if [ $? -eq 0 ]; then | |
258 printf "OK ($docker_id)\n" | |
259 else | |
260 echo $docker_id | grep Conflict > /dev/null 2>&1 | |
261 if [ $? -eq 0 ]; then | |
262 printf "A data container already exists ($VOLUME_ALIAS), use \"docker ps -a\" to see it\n" | |
263 else | |
264 eprintf "Error, please check data volume\nerror message: $docker_id\n" | |
265 exit 1 | |
266 fi | |
267 fi | |
268 printf "\nRunning Libervia\n\n" | |
269 # we first check if we need to mount TLS directory | |
270 if [ -n "$SAT_CONT_TLS_DIR" ]; then | |
271 printf "$SAT_CONT_TLS_DIR will be used for TLS certificate\n" | |
272 DK_TLS="--volume=$SAT_CONT_TLS_DIR:$CONT_CERT_DIR" | |
273 fi | |
274 for CONT in $CONTAINERS; do | |
275 case $CONT in | |
276 prosody) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME $DK_TLS $(public_ports_arg $CONT) --name prosody" | |
277 if [ -n "$SAT_CONT_DOMAIN" ]; then | |
278 OPTS="-e DOMAIN=$SAT_CONT_DOMAIN $OPTS" | |
279 fi | |
280 ;; | |
281 sat_pubsub) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --name sat_pubsub --link=prosody:prosody";; | |
282 salut) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --name salut --link=prosody:prosody";; | |
283 sat) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME -P $(public_ports_arg $CONT) --name sat --link=prosody:prosody";; | |
284 libervia) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --volumes-from sat $DK_TLS -P $(public_ports_arg $CONT) --name libervia --link=sat:sat";; | |
285 *) eprintf "Unkown container $CONT\n"; exit 1 | |
286 esac | |
287 printf "Launching $CONT... " | |
288 docker_id=$(docker run $OPTS $SAT_CONT_DK_EXTRA $ACCOUNT/$CONT 2>&1) | |
289 if [ $? -eq 0 ]; then | |
290 printf "OK ($docker_id)\n" | |
291 else | |
292 eprintf "Error, please check container or ask help on XMPP MUC sat@chat.jabberfr.org\nerror message: $docker_id\n" | |
293 eprintf "Abandon\n" | |
294 exit 1 | |
295 fi | |
296 done | |
297 printf '\nLibervia is launched and should be reachable in a couple of seconds.\nYou can check logs with "docker logs -f libervia" (or any other container name).\n' | |
298 printf "An \"admin\" account has been created, you can check its password on $VOLUME_ALIAS container, in file /home/sat/ADMIN_PWD. Config can be tuned on this container.\n" | |
299 printf 'Below are the ports used to connect, you can go with your browser to Libervia HTTP(S) port.\n\n' | |
300 list_ports | |
301 ;; | |
302 STOP) | |
303 printf "stopping Libervia\n" | |
304 REVERSED="" | |
305 for CONT in $CONTAINERS; do | |
306 REVERSED="$CONT $REVERSED" | |
307 done; | |
308 for CONT in $REVERSED; do | |
309 printf "\nStopping container $CONT" | |
310 docker stop $CONT > /dev/null 2>&1 || eprintf "... Error while stopping $CONT\n" | |
311 printf "\rDeleting container $CONT" | |
312 docker rm -v $CONT > /dev/null 2>&1 || eprintf "... Error while removing $CONT\n" | |
313 done | |
314 printf "\n" | |
315 ;; | |
316 RESTART) | |
317 printf "restarting containers...\n" | |
318 "$0" stop && "$0" start "$@" | |
319 ;; | |
320 STATUS) | |
321 docker inspect $TEST_CONT > /dev/null 2>&1 | |
322 if [ $? -eq 0 ]; then | |
323 printf "$APP_NAME is running" | |
324 # we test the presence of "starting on xxxx" (where xxxx is one of the exposed ports) | |
325 # this is not really reliable as ports can be changed in configuration | |
326 # but in most case it should work OK | |
327 PORTS_REGEX=$(get_dyn_var $TEST_CONT ports | sed 's/ /\\|/') | |
328 docker logs $TEST_CONT | grep "starting on \($PORTS_REGEX\)" > /dev/null 2>&1 | |
329 if [ $? -ne 0 ]; then | |
330 printf " but no server is started\n" | |
331 exit 2 | |
332 fi | |
333 printf "\n" | |
334 exit 0 | |
335 else | |
336 printf "$APP_NAME is not running\n" | |
337 exit 1 | |
338 fi | |
339 ;; | |
340 UPDATE) | |
341 printf "updating images...\n" | |
342 errors=0 | |
343 for CONT in $CONTAINERS data; do | |
344 printf "\n*** updating $CONT ***\n" | |
345 docker pull $ACCOUNT/$CONT:latest | |
346 if [ $? -ne 0 ]; then | |
347 eprintf "\nError while updating $ACCOUNT/$CONT\n" | |
348 errors=1 | |
349 fi | |
350 done | |
351 if [ $errors -eq 0 ]; then | |
352 printf "\n\nImages are up-to-date\n" | |
353 else | |
354 eprintf "\n\nSome errors happened while updating images\n" | |
355 exit 1 | |
356 fi | |
357 ;; | |
358 BACKUP) | |
359 case $# in | |
360 0) SAT_CONT_BACKUP_DIR="$(pwd)";; | |
361 1) SAT_CONT_BACKUP_DIR="$1";; | |
362 *) printf "syntaxe is $0 backup [backup_dir_absolute_path]\n[backup_dir_absolute_path] default to current working dir\n" | |
363 exit 1 | |
364 ;; | |
365 esac | |
366 SAT_CONT_BACKUP_DIR=$(echo $SAT_CONT_BACKUP_DIR | sed 's%^\/*\|\/*$%\/%g') # we want to be sure that path starts and finishes with "/" | |
367 filename="sat_data_backup_$(date '+%Y-%m-%d_%H:%M:%S').tar.gz" | |
368 printf "backing up data container to ${SAT_CONT_BACKUP_DIR}${filename}\n\n" | |
369 docker run --rm $DK_VOLUME -v "$SAT_CONT_BACKUP_DIR:/backup" $MAINT_CONT tar zcvf "/backup/$filename" -C / -h volumes | |
370 if [ $? -eq 0 ]; then | |
371 printf "\nBackup finished and available at ${SAT_CONT_BACKUP_DIR}${filename}\n" | |
372 else | |
373 eprintf "\nBackup Error !\n" | |
374 exit 1 | |
375 fi | |
376 ;; | |
377 RESTORE) | |
378 if [ $# -ne 1 ]; then | |
379 printf "syntaxe is $0 restore <backup_file.tar.gz>\n" | |
380 exit 1 | |
381 fi | |
382 docker run --name $VOLUME_ALIAS $VOLUME_CONT > /dev/null 2>&1 | |
383 if [ $? -ne 0 ]; then | |
384 eprintf "Can't create $VOLUME_ALIAS container.\n\ | |
385 If you have an existing one, please remove it with \"docker rm -v $VOLUME_ALIAS\" (/!\\ it will remove *ALL* your data)\n\n\ | |
386 Hint: you can also rename your current data container with \"docker rename $VOLUME_ALIAS new_container_name\"\n" | |
387 exit 1 | |
388 fi | |
389 | |
390 printf "restoring $1 to $VOLUME_ALIAS container\n\n" | |
391 HOST_BACKUP_DIR=$(dirname "$1") | |
392 HOST_BACKUP_NAME=$(basename "$1") | |
393 if [ $HOST_BACKUP_DIR = "." ]; then | |
394 # workaround for a Docker bug (container crash if "." is used) | |
395 HOST_BACKUP_DIR=$(pwd) | |
396 fi | |
397 docker run --rm $DK_VOLUME -v "$HOST_BACKUP_DIR:/backup" $MAINT_CONT tar zxvf "/backup/$HOST_BACKUP_NAME" -C / -h volumes | |
398 if [ $? -eq 0 ]; then | |
399 printf "\nRestore finished\n" | |
400 else | |
401 eprintf "\nRestore Error !\n" | |
402 exit 1 | |
403 fi | |
404 ;; | |
405 PORTS) | |
406 list_ports | |
407 ;; | |
408 CONFIG) | |
409 case $# in | |
410 0) CONF="libervia";; | |
411 1) CONF="$1";; | |
412 *) CONF="";; | |
413 esac | |
414 case $CONF in | |
415 libervia) | |
416 CONT_CONF_FILE="/home/sat/.config/sat/sat.conf" | |
417 ;; | |
418 prosody) | |
419 CONT_CONF_FILE="/etc/prosody/prosody_sat_cfg/prosody.cfg.lua" | |
420 ;; | |
421 *) printf "\nPlease enter type of configuration to edit (libervia, prosody)\n" | |
422 exit 1 | |
423 ;; | |
424 esac | |
425 | |
426 HOST_CONF_FILE=$(basename $CONT_CONF_FILE) | |
427 | |
428 printf "\ngetting configuration for $CONF\n" | |
429 # we copy config file to a temporary dit | |
430 # then edit with $EDITOR and put it back | |
431 | |
432 TMP_DIR=$(mktemp -d 2>/dev/null) | |
433 if [ $? -ne 0 ]; then | |
434 TMP_DIR="$DEFAULT_TMP_DIR" | |
435 mkdir -p "$TMP_DIR" | |
436 fi | |
437 | |
438 docker cp "$VOLUME_ALIAS:$CONT_CONF_FILE" "$TMP_DIR/" | |
439 "$EDITOR" "$TMP_DIR/$HOST_CONF_FILE" | |
440 if [ $? -eq 0 -a -s "$TMP_DIR/$HOST_CONF_FILE" ]; then | |
441 printf "updating configuration\n" | |
442 check_docker_version 1 8 0 | |
443 if [ $? -eq 0 ]; then | |
444 docker cp "$TMP_DIR/$HOST_CONF_FILE" "$VOLUME_ALIAS:$CONT_CONF_FILE" | |
445 else | |
446 eprintf "Old Docker version detected, using workaround, please update!\n" | |
447 docker run --rm $DK_VOLUME -v "$TMP_DIR:/tmp_config" $MAINT_CONT /bin/cp -f "/tmp_config/$HOST_CONF_FILE" "$CONT_CONF_FILE" | |
448 fi | |
449 # "docker cp" copy file on container as root, if an option is available later to change this behaviour, | |
450 # the following operation could be removed | |
451 printf "ownership fix..." | |
452 docker run --rm $DK_VOLUME $MAINT_CONT /bin/chown 1000:1000 "$CONT_CONF_FILE" | |
453 printf "done\n" | |
454 fi | |
455 rm -rf "$TMP_DIR" | |
456 ;; | |
457 STATS) | |
458 if [ -n "$1" -a "$1" != "--no-stream" ]; then | |
459 printf "usage: $0 stats [--no-stream]\n" | |
460 exit 1 | |
461 fi | |
462 docker stats $1 $CONTAINERS | |
463 ;; | |
464 *) eprintf "Error: unknown command !" | |
465 exit 2 | |
466 esac |