-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdeploy.sh
614 lines (554 loc) · 20.7 KB
/
deploy.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
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
#!/usr/bin/env bash
################################################################################
#
# ASKCOS Deployment Utilities
#
# ~ To streamline deployment commands ~
#
################################################################################
set -e # exit with nonzero exit code if anything fails
# Create environment variable files from examples if they don't exist
if [ ! -f ".env" ]; then
cp .env.example .env
fi
# Get docker compose variables from .env
set -a
source .env
set +a
# Default argument values
BUYABLES=""
CHEMICALS=""
REACTIONS=""
RETRO_TEMPLATES=""
FORWARD_TEMPLATES=""
SELEC_REFERENCES=""
DB_DROP=""
DROP_INDEXES=false
LOCAL=false
BACKUP_DIR=""
IGNORE_DIFF=false
COMMANDS=""
while (( "$#" )); do
case "$1" in
-h|--help|help)
usage
exit
;;
-f|--compose-file)
if [ -z "$COMPOSE_FILE" ]; then
COMPOSE_FILE=$2
else
COMPOSE_FILE=$COMPOSE_FILE:$2
fi
shift 2
;;
-p|--project-name)
COMPOSE_PROJECT_NAME=$2
shift 2
;;
-l|--local)
LOCAL=true
shift 1
;;
-v|--version)
VERSION_NUMBER=$2
shift 2
;;
-b|--buyables)
BUYABLES=$2
shift 2
;;
-c|--chemicals)
CHEMICALS=$2
shift 2
;;
-x|--reactions)
REACTIONS=$2
shift 2
;;
-r|--retro-templates)
RETRO_TEMPLATES=$2
shift 2
;;
-t|--forward-templates)
FORWARD_TEMPLATES=$2
shift 2
;;
-e|--selec-references)
SELEC_REFERENCES=$2
shift 2
;;
-a|--append)
echo 'The -a,--append argument is no longer necessary. Documents are appended by default.'
shift 1
;;
-z|--drop)
DB_DROP="--drop"
shift 1
;;
-i|--drop-indexes)
DROP_INDEXES=true
shift 1
;;
-n|--ignore-diff)
IGNORE_DIFF=true
shift 1
;;
-d|--backup-directory)
BACKUP_DIR=$2
shift 2
;;
--) # end argument parsing
shift
break
;;
-*) # any other flag
echo "Error: Unsupported flag $1" >&2 # print to stderr
exit 1
;;
*) # preserve positional arguments
COMMANDS="$COMMANDS $1"
shift
;;
esac
done
# Set positional arguments in their proper place
eval set -- "$COMMANDS"
# Export variables needed by docker compose
export VERSION_NUMBER
export COMPOSE_FILE
export COMPOSE_PROJECT_NAME
# Define various functions
diff-env() {
# V2 update: dropped customization from diff since Django is no longer used
if [ "$IGNORE_DIFF" = "true" ]; then
return 0
fi
output1="$(diff -u .env .env.example)" || true
if [ -n "$output1" ]; then
echo -e "\033[91m*** WARNING ***\033[00m"
echo "Local .env file is different from .env.example"
echo "This could be due to changes to the example or local changes."
echo "Please review the diff to determine if any changes are necessary:"
echo
echo "$output1"
echo
fi
if [ -n "$output1" ]; then
echo "Local configuration files differ from examples (see above)! What would you like to do?"
echo " (c)ontinue without changes (use -n flag to skip prompt and continue in the future)"
echo " (o)verwrite your local files with the examples (the above diff(s) will be applied)"
echo " (s)top and make changes manually"
read -rp '>>> ' response
case "$response" in
[Cc])
echo "Continuing without changes."
;;
[Oo])
echo "Overwriting local files."
cp .env.example .env
source .env
;;
[Ss])
echo "Stopping."
exit 1
;;
*)
echo "Unrecognized option. Stopping."
exit 1
;;
esac
fi
}
copy-nginx-conf() {
# always create the cert if not exist, even for http
# the cert and key files are volume mapped by docker compose, so creating them as files is more idiot-proof
# otherwise they might be created as directories
if [ ! -f "askcos.ssl.cert" ]; then
echo "Creating self-signed SSL certificates."
openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=US/ST=MA/L=BOS/O=askcos/CN=askcos.$RANDOM.com" -keyout askcos.ssl.key -out askcos.ssl.cert
echo
fi
if [ -f "nginx.conf" ]; then
echo "Found nginx config at ./nginx.conf"
return
fi
if [ "$PROTOCOL" = "http" ]; then
echo "Using default http nginx configuration."
cp nginx.http.conf nginx.conf
echo
elif [ "$PROTOCOL" = "https" ]; then
echo "Using default https nginx configuration."
cp nginx.https.conf nginx.conf
echo
fi
}
set-db-defaults() {
# Set default values for seeding database if values are not already defined
BUYABLES=${BUYABLES:-default}
RETRO_TEMPLATES=${RETRO_TEMPLATES:-default}
FORWARD_TEMPLATES=${FORWARD_TEMPLATES:-default}
CHEMICALS=${CHEMICALS:-default}
REACTIONS=${REACTIONS:-default}
SELEC_REFERENCES=${SELEC_REFERENCES:-default}
}
run-mongo-js() {
# arg 1 is js command
docker compose -f compose.yaml exec -T mongo \
bash -c 'mongosh --username ${MONGO_USER} --password ${MONGO_PW} --authenticationDatabase admin ${MONGO_HOST}/askcos --quiet --eval '"'$1'"
}
mongoimport() {
# arg 1 is collection name
# arg 2 is file path
# arg 3 is a flag to pass to docker compose exec, e.g. -d to detach
docker compose -f compose.yaml exec -T $3 mongo \
bash -c 'gunzip -c '$2' | mongoimport --host ${MONGO_HOST} --username ${MONGO_USER} --password ${MONGO_PW} --authenticationDatabase admin --db askcos --collection '$1' --type json --jsonArray --numInsertionWorkers 8 '${DB_DROP}
}
mongoimport_upsert() {
# arg 1 is collection name
# arg 2 is file path
# arg 3 is a flag to pass to docker compose exec, e.g. -d to detach
docker compose -f compose.yaml exec -T $3 mongo \
bash -c 'gunzip -c '$2' | mongoimport --host ${MONGO_HOST} --username ${MONGO_USER} --password ${MONGO_PW} --authenticationDatabase admin --db askcos --collection '$1' --type json --jsonArray --numInsertionWorkers 8 --mode upsert '${DB_DROP}
}
mongoexport() {
# arg 1 is collection name
# arg 2 is file path
# arg 3 is a flag to pass to docker compose exec, e.g. -d to detach
docker compose -f compose.yaml exec -T $3 mongo \
bash -c 'mongoexport --host ${MONGO_HOST} --username ${MONGO_USER} --password ${MONGO_PW} --authenticationDatabase admin --db askcos --collection '$1' --type json --jsonArray | gzip > '$2
}
precompute() {
# arg 1 is collection name, i.e., mode for precomputation
docker compose -f compose.yaml exec -T precompute \
/opt/conda/bin/python -m scripts.pre_compute --mode="$1"
}
index-db() {
if [ "$DROP_INDEXES" = "true" ]; then
echo "Dropping existing indexes in mongo database..."
run-mongo-js 'db.buyables.dropIndexes()'
run-mongo-js 'db.chemicals.dropIndexes()'
run-mongo-js 'db.reactions.dropIndexes()'
run-mongo-js 'db.retro_templates.dropIndexes()'
run-mongo-js 'db.sites_refs.dropIndexes()'
fi
echo "Adding indexes to mongo database..."
run-mongo-js 'db.buyables.createIndex({smiles: 1, source: 1})'
run-mongo-js 'db.chemicals.createIndex({smiles: 1, template_set: 1})'
run-mongo-js 'db.reactions.createIndex({reaction_id: 1, template_set: 1})'
run-mongo-js 'db.retro_templates.createIndex({index: 1, template_set: 1})'
run-mongo-js 'db.sites_refs.createIndexes([{index: 1}, {reactant: 1}])'
echo "Indexing complete."
echo
}
count-mongo-docs() {
echo "Buyables collection: $(run-mongo-js "db.buyables.estimatedDocumentCount({})" | tr -d '\r') / 509931 expected (default)"
echo "Chemicals collection: $(run-mongo-js "db.chemicals.estimatedDocumentCount({})" | tr -d '\r') / 19188359 expected (default)"
echo "Reactions collection: $(run-mongo-js "db.reactions.estimatedDocumentCount({})" | tr -d '\r') / 3052316 expected (default, 7072474 including cas)"
echo "Retro template collection: $(run-mongo-js "db.retro_templates.estimatedDocumentCount({})" | tr -d '\r') / 432538 expected (default, 612013 including cas)"
echo "Forward template collection: $(run-mongo-js "db.forward_templates.estimatedDocumentCount({})" | tr -d '\r') / 17089 expected (default)"
echo "Sites ref collection: $(run-mongo-js "db.sites_refs.estimatedDocumentCount({})" | tr -d '\r') / 123 expected (default)"
}
seed-db() {
if [ -z "$BUYABLES" ] && [ -z "$CHEMICALS" ] && [ -z "$REACTIONS" ] && [ -z "$RETRO_TEMPLATES" ] && [ -z "$FORWARD_TEMPLATES" ] && [ -z "$REFERENCES" ]; then
echo "Nothing to seed!"
echo "Example usages:"
echo " bash deploy.sh seed-db -r default seed only the default retro templates"
echo " bash deploy.sh seed-db -r templates.json.gz seed retro templates from local file templates.json.gz"
echo " bash deploy.sh seed-db -x default seed only the default reactions"
echo " bash deploy.sh seed-db -x reactions.json.gz seed reactions from local file reactions.json.gz"
echo " bash deploy.sh seed-db -c default seed only the default chemical (i.e., historian)"
echo " bash deploy.sh seed-db -c historian.json.gz seed chemicals from local file historian.json.gz"
echo " bash deploy.sh set-db-defaults seed-db seed all default collections"
return
fi
echo "Starting the mongo container for seeding db"
docker compose -f compose.yaml up -d mongo precompute
sleep 3
echo "Seeding mongo database..."
DATA_DIR="/usr/local/askcos-data/db"
if [ "$BUYABLES" = "default" ]; then
echo "Loading default buyables data..."
buyables_file="${DATA_DIR}/buyables/mcule_buyables_fd2.json.gz"
mongoimport_upsert buyables "$buyables_file"
buyables_file="${DATA_DIR}/buyables/chembridge_buyables.json.gz"
DB_DROP="" mongoimport_upsert buyables "$buyables_file"
buyables_file="${DATA_DIR}/buyables/buyables.json.gz"
DB_DROP="" mongoimport_upsert buyables "$buyables_file"
elif [ -f "$BUYABLES" ]; then
echo "Loading buyables data from $BUYABLES..."
buyables_file="${DATA_DIR}/buyables/$(basename "$BUYABLES")"
docker cp "$BUYABLES" "${COMPOSE_PROJECT_NAME}"-mongo-1:"$buyables_file"
mongoimport_upsert buyables "$buyables_file"
fi
if [ "$CHEMICALS" = "default" ]; then
echo "Loading default chemicals data..."
chemicals_file="${DATA_DIR}/historian/chemicals.json.gz"
mongoimport chemicals "$chemicals_file"
chemicals_file="${DATA_DIR}/historian/historian.pistachio.json.gz"
DB_DROP="" mongoimport chemicals "$chemicals_file"
chemicals_file="${DATA_DIR}/historian/historian.bkms_metabolic.json.gz"
DB_DROP="" mongoimport chemicals "$chemicals_file"
elif [ "$CHEMICALS" = "pistachio" ]; then
echo "Loading pistachio chemicals data..."
chemicals_file="${DATA_DIR}/historian/historian.pistachio.json.gz"
mongoimport chemicals "$chemicals_file"
elif [ "$CHEMICALS" = "bkms" ]; then
echo "Loading bkms chemicals data..."
chemicals_file="${DATA_DIR}/historian/historian.bkms_metabolic.json.gz"
mongoimport chemicals "$chemicals_file"
elif [ -f "$CHEMICALS" ]; then
echo "Loading chemicals data from $CHEMICALS..."
chemicals_file="${DATA_DIR}/historian/$(basename "$CHEMICALS")"
docker cp "$CHEMICALS" "${COMPOSE_PROJECT_NAME}"-mongo-1:"$chemicals_file"
mongoimport chemicals "$chemicals_file"
fi
if [ "$REACTIONS" = "default" ]; then
echo "Loading default reactions data..."
reactions_file="${DATA_DIR}/historian/reactions.pistachio.json.gz"
mongoimport_upsert reactions "$reactions_file"
reactions_file="${DATA_DIR}/historian/reactions.bkms_metabolic.json.gz"
DB_DROP="" mongoimport_upsert reactions "$reactions_file"
reactions_file="${DATA_DIR}/historian/reactions.USPTO_FULL.json.gz"
DB_DROP="" mongoimport_upsert reactions "$reactions_file"
reactions_file="${DATA_DIR}/historian/reactions.cas.min.json.gz"
if [ -f "$reactions_file" ]; then
DB_DROP="" mongoimport_upsert reactions "$reactions_file"
fi
precompute reactions
elif [ "$REACTIONS" = "pistachio" ]; then
echo "Loading pistachio reactions data..."
reactions_file="${DATA_DIR}/historian/reactions.pistachio.json.gz"
mongoimport_upsert reactions "$reactions_file"
elif [ "$REACTIONS" = "cas" ]; then
echo "Loading cas reactions data..."
reactions_file="${DATA_DIR}/historian/reactions.cas.min.json.gz"
mongoimport_upsert reactions "$reactions_file"
elif [ "$REACTIONS" = "bkms" ]; then
echo "Loading bkms reactions data..."
reactions_file="${DATA_DIR}/historian/reactions.bkms_metabolic.json.gz"
mongoimport_upsert reactions "$reactions_file"
precompute reactions
elif [ "$REACTIONS" = "USPTO_FULL" ]; then
echo "Loading USPTO_FULL reactions data..."
reactions_file="${DATA_DIR}/historian/reactions.USPTO_FULL.json.gz"
mongoimport_upsert reactions "$reactions_file"
precompute reactions
elif [ -f "$REACTIONS" ]; then
echo "Loading reactions data from $REACTIONS..."
reactions_file="${DATA_DIR}/historian/$(basename "$REACTIONS")"
docker cp "$REACTIONS" "${COMPOSE_PROJECT_NAME}"-mongo-1:"$reactions_file"
mongoimport_upsert reactions "$reactions_file"
precompute reactions
fi
if [ "$RETRO_TEMPLATES" = "default" ]; then
echo "Loading default retrosynthetic templates..."
retro_file="${DATA_DIR}/templates/retro.templates.reaxys.json.gz"
mongoimport retro_templates "$retro_file"
retro_file="${DATA_DIR}/templates/retro.templates.pistachio.json.gz"
DB_DROP="" mongoimport retro_templates "$retro_file"
retro_file="${DATA_DIR}/templates/retro.templates.bkms_metabolic.json.gz"
DB_DROP="" mongoimport retro_templates "$retro_file"
retro_file="${DATA_DIR}/templates/retro.templates.pistachio_ringbreaker.json.gz"
DB_DROP="" mongoimport retro_templates "$retro_file"
retro_file="${DATA_DIR}/templates/retro.templates.reaxys_biocatalysis.json.gz"
DB_DROP="" mongoimport retro_templates "$retro_file"
retro_file="${DATA_DIR}/templates/retro.templates.cas.json.gz"
if [ -f "retro_file" ]; then
DB_DROP="" mongoimport retro_templates "$retro_file"
fi
elif [ "$RETRO_TEMPLATES" = "pistachio" ]; then
echo "Loading pistachio retrosynthetic templates..."
retro_file="${DATA_DIR}/templates/retro.templates.pistachio.json.gz"
mongoimport retro_templates "$retro_file"
elif [ "$RETRO_TEMPLATES" = "cas" ]; then
echo "Loading cas retrosynthetic templates..."
retro_file="${DATA_DIR}/templates/retro.templates.cas.json.gz"
mongoimport retro_templates "$retro_file"
elif [ "$RETRO_TEMPLATES" = "bkms" ]; then
echo "Loading bkms retrosynthetic templates..."
retro_file="${DATA_DIR}/templates/retro.templates.bkms_metabolic.json.gz"
mongoimport retro_templates "$retro_file"
elif [ "$RETRO_TEMPLATES" = "ringbreaker" ]; then
echo "Loading ringbreaker retrosynthetic templates..."
retro_file="${DATA_DIR}/templates/retro.templates.pistachio_ringbreaker.json.gz"
mongoimport retro_templates "$retro_file"
elif [ -f "$RETRO_TEMPLATES" ]; then
echo "Loading retrosynthetic templates from $RETRO_TEMPLATES ..."
retro_file="${DATA_DIR}/templates/$(basename "$RETRO_TEMPLATES")"
docker cp "$RETRO_TEMPLATES" "${COMPOSE_PROJECT_NAME}"-mongo-1:"$retro_file"
mongoimport retro_templates "$retro_file"
fi
if [ "$FORWARD_TEMPLATES" = "default" ]; then
echo "Loading default forward templates..."
forward_file="${DATA_DIR}/templates/forward.templates.json.gz"
mongoimport forward_templates "$forward_file"
elif [ -f "$FORWARD_TEMPLATES" ]; then
echo "Loading forward templates from $FORWARD_TEMPLATES ..."
forward_file="${DATA_DIR}/templates/$(basename "$FORWARD_TEMPLATES")"
docker cp "$FORWARD_TEMPLATES" "${COMPOSE_PROJECT_NAME}"-mongo-1:"$forward_file"
mongoimport forward_templates "$forward_file"
fi
if [ "$SELEC_REFERENCES" = "default" ]; then
echo "Loading default model references..."
refs_file="${DATA_DIR}/references/site_selectivity.refs.json.gz"
mongoimport sites_refs "$refs_file"
fi
index-db
echo "Seeding db completed."
count-mongo-docs
docker compose -f compose.yaml rm -sf mongo precompute
echo
}
generate-deployment-scripts() {
python scripts/pre_deploy.py
}
get-images() {
echo "Getting images using the script from the latest deployment directory"
echo " bash deployment/deployment_latest/get_images.sh"
bash deployment/deployment_latest/get_images.sh
echo "Images ready."
}
download-db-data() {
echo "Downloading data for db using scripts/download_data.sh"
bash scripts/download_data.sh
echo "Data downloaded."
}
start-services() {
echo "Start services using the script from the latest deployment directory"
echo " bash deployment/deployment_latest/start_services.sh"
bash deployment/deployment_latest/start_services.sh
echo "Services started."
}
stop-services() {
echo "Stop services using the script from the latest deployment directory"
echo " bash deployment/deployment_latest/stop_services.sh"
bash deployment/deployment_latest/stop_services.sh
echo "Services stopped."
}
remove-volumes() {
docker compose -f compose.yaml down -v
}
export_volume() {
volume=$1
directory=$2
filename=$3
volume_name=${COMPOSE_PROJECT_NAME}_${volume}
docker run --rm -v "${volume_name}":/src -v "${directory}":/dest alpine tar -czf /dest/"${filename}" /src
}
import_volume() {
volume=$1
directory=$2
filename=$3
volume_name=${COMPOSE_PROJECT_NAME}_${volume}
docker run --rm -v "${volume_name}":/dest -v "${directory}":/src alpine tar -xzf /src/"${filename}" -C /dest --strip 1
}
backup() {
if [ -z "$BACKUP_DIR" ]; then
BACKUP_DIR="$(pwd)/backup/$(date +%Y%m%d%s)"
fi
mkdir -p "${BACKUP_DIR}"
echo "Backing up data to ${BACKUP_DIR}"
echo "This may take a few minutes..."
export_volume askcosv2_mongo_data "${BACKUP_DIR}" mongo_data.tar.gz
echo "Backup complete."
}
restore() {
if [ -z "$BACKUP_DIR" ]; then
BACKUP_DIR="$(pwd)/backup/$(ls -t backup | head -1)"
fi
echo "Restoring data from ${BACKUP_DIR}"
echo "This may take a few minutes..."
import_volume askcosv2_mongo_data "${BACKUP_DIR}" mongo_data.tar.gz
echo "Restore complete."
}
post-update-message() {
echo
echo -e "\033[92m================================================================================\033[00m"
echo
echo "The local ASKCOS deployment has been updated to version ${VERSION_NUMBER}!"
echo
echo " ~~~ Thank you for using ASKCOS! ~~~"
echo
echo -e "\033[92m================================================================================\033[00m"
}
# Handle positional arguments, which should be commands
if [ $# -eq 0 ]; then
# No arguments
echo "Must provide a valid task, e.g. deploy|update."
echo "See 'deploy.sh help' for more options."
exit 1;
else
for arg in "$@"
do
case "$arg" in
clean-data | start-db-services | save-db | seed-db | copy-nginx-conf | pull-images | generate-deployment-scripts | \
start-web-services | start-ml-servers | start-celery-workers | set-db-defaults | count-mongo-docs | \
backup | restore | index-db | diff-env | post-update-message | old-messages | get-images | download-db-data)
# This is a defined function, so execute it
$arg
;;
pre-deploy)
copy-nginx-conf
diff-env
generate-deployment-scripts
get-images
download-db-data
set-db-defaults
seed-db
;;
deploy)
# Normal first deployment, do everything (pre-deploy + start-backend-services)
copy-nginx-conf
diff-env
generate-deployment-scripts
get-images
download-db-data
set-db-defaults
seed-db
start-services
;;
update)
# Update an existing configuration, database seeding is not performed
copy-nginx-conf
diff-env
generate-deployment-scripts
get-images
start-services
post-update-message
;;
start)
# (Re)start existing deployment
start-services
;;
stop)
# Stop and remove currently running containers
stop-services
;;
clean)
# Clean up current deployment including all data volumes
echo "This will stop and remove all containers and also remove all data volumes, including user data."
echo "Are you sure you want to continue?"
read -rp 'Continue (y/N): ' response
case "$response" in
[Yy] | [Yy][Ee][Ss])
echo "Cleaning deployment."
stop-services
remove-volumes
;;
*)
echo "Doing nothing."
;;
esac
;;
restart)
# Stop and remove currently running containers before starting
stop-services
start-services
;;
*)
echo "Error: Unsupported command $arg" >&2 # print to stderr
exit 1;
esac
done
fi