Add sandbox/deployment.sh
This commit is contained in:
277
sandbox/deployment.sh
Normal file
277
sandbox/deployment.sh
Normal file
@@ -0,0 +1,277 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
usage() {
|
||||
cat <<EOU
|
||||
Usage: $0 COMMAND -n NODE_NAME -w STACK_NAME -N NODE_SETTINGS.env -P PROJECT_SETTINGS.env -f COMPOSE.yml [-u] [-s SECRETS.env]
|
||||
|
||||
COMMAND
|
||||
check - test composer files syntax and print final config
|
||||
deploy - deploy to node
|
||||
run - deploy here without swarm
|
||||
stop - stop here without swarm
|
||||
|
||||
Required arguments:
|
||||
-f COMPOSE - compose file (multivalue option)
|
||||
-w STACK_NAME - stack name for swarm. Required for COMMAND=deploy
|
||||
|
||||
Optional arguments:
|
||||
-N SETTINGS - node settings (multivalue option)
|
||||
-P SETTINGS - product settings (multivalue option)
|
||||
-n NODE_NAME - node name.
|
||||
-u - update images from registry on deploy
|
||||
-s SECRETS.env - path to env file for override secrets versions.
|
||||
|
||||
EOU
|
||||
1>&2; exit 1;
|
||||
}
|
||||
|
||||
COMMAND=$1
|
||||
shift
|
||||
|
||||
commands=('deploy','check','run','stop')
|
||||
|
||||
if [[ ! "${commands[@]}" =~ "${COMMAND}" ]]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
COMPOSERS=()
|
||||
NODE_NAME=""
|
||||
NODE_SETTINGS=()
|
||||
PRODUCT_SETTINGS=()
|
||||
SECRET_SETTINGS=""
|
||||
STACK_NAME=""
|
||||
DO_UPDATE="no"
|
||||
|
||||
while getopts ":n:N:P:w:s:f:h:u" o; do
|
||||
case "${o}" in
|
||||
n)
|
||||
NODE_NAME="${OPTARG}"
|
||||
;;
|
||||
N)
|
||||
NODE_SETTINGS+=("${OPTARG}")
|
||||
;;
|
||||
P)
|
||||
PRODUCT_SETTINGS+=("${OPTARG}")
|
||||
;;
|
||||
s)
|
||||
SECRET_SETTINGS="${OPTARG}"
|
||||
;;
|
||||
f)
|
||||
COMPOSERS+=("${OPTARG}")
|
||||
;;
|
||||
w)
|
||||
STACK_NAME=${OPTARG}
|
||||
;;
|
||||
u)
|
||||
DO_UPDATE="yes"
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ "${COMMAND}" == "" ] || [ "${COMPOSERS}" == "" ]; then
|
||||
echo "Required arguments missing"
|
||||
usage
|
||||
fi
|
||||
|
||||
# building node settings
|
||||
if [ -f "$NODE_NAME.env" ]; then
|
||||
set +a
|
||||
. "$NODE_NAME.env"
|
||||
set -a
|
||||
fi
|
||||
|
||||
for NODE_SETTING in "${NODE_SETTINGS[@]}"; do
|
||||
. $NODE_SETTING
|
||||
done
|
||||
|
||||
# building project settings
|
||||
bash -c "echo ''> .project.tmp.env"
|
||||
for PRODUCT_SETTING in "${PRODUCT_SETTINGS[@]}"; do
|
||||
bash -c "cat $PRODUCT_SETTING >> .project.tmp.env"
|
||||
done
|
||||
|
||||
export PROJECT_SETTINGS=".project.tmp.env"
|
||||
|
||||
grep ^CLIENT_API .project.tmp.env | sed 's/^CLIENT_//' > .project.client.tmp.env
|
||||
grep ^ADMIN_API .project.tmp.env | sed 's/^ADMIN_//' > .project.admin.tmp.env
|
||||
grep ^I_CLIENT_API .project.tmp.env | sed 's/^I_CLIENT_//' > .project.i_client.tmp.env
|
||||
grep ^REPORT_GENERATOR .project.tmp.env | sed 's/^REPORT_GENERATOR_//' > .project.renderer.tmp.env
|
||||
|
||||
# special default variables
|
||||
export MYSQL_HOST_DIR=${MYSQL_HOST_DIR:-"/home/dockns-root/mysql_data"}
|
||||
export DOCKER_REGISTRY=${DOCKER_REGISTRY:-"docker-registry.smarthomedevs.work/issuing"}
|
||||
export REPLICAS=${REPLICAS:-"1"}
|
||||
export TAG=${TAG:-"latest"}
|
||||
export PUBLIC_NODE_IP=${PUBLIC_NODE_IP:-"0.0.0.0"}
|
||||
|
||||
# parse secret names from composer
|
||||
COMPOSER_FILE_ARGS=""
|
||||
COMPOSER_SWARM_ARGS=""
|
||||
|
||||
for COMPOSER in "${COMPOSERS[@]}"; do
|
||||
|
||||
COMPOSER_FILE_ARGS+=" -f $COMPOSER"
|
||||
COMPOSER_SWARM_ARGS+=" -c $COMPOSER"
|
||||
|
||||
IFS=$'\n' tag_vars=($(grep "TAG_" $COMPOSER | sed 's/.*\$TAG_/TAG_/'))
|
||||
for tag_var in "${tag_vars[@]}"; do
|
||||
if [[ "${!tag_var}" == "" ]]; then
|
||||
eval "export $tag_var='$TAG'"
|
||||
fi
|
||||
done
|
||||
|
||||
IFS=$'\n' secret_vars=($(grep "SV_" $COMPOSER | sed 's/.*\.\$//'))
|
||||
for secret in "${secret_vars[@]}"; do
|
||||
if [[ "${!secret}" == "" ]]; then
|
||||
eval "export $secret='0'"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
EXIT=0
|
||||
|
||||
# building secret settings
|
||||
if [ -f "$SECRET_SETTINGS" ]; then
|
||||
. $SECRET_SETTINGS
|
||||
fi
|
||||
|
||||
if [[ "$COMMAND" == "check" ]]; then
|
||||
bash -c "docker compose $COMPOSER_FILE_ARGS config"
|
||||
EXIT=$?
|
||||
fi
|
||||
|
||||
if [[ "$COMMAND" == "deploy" ]]; then
|
||||
if [ "$STACK_NAME" == "" ]; then
|
||||
echo ""
|
||||
echo "STACK_NAME required"
|
||||
echo ""
|
||||
usage
|
||||
fi
|
||||
if [[ "$DO_UPDATE" == "yes" ]]; then
|
||||
REGISTRY_AUTH="--with-registry-auth"
|
||||
else
|
||||
REGISTRY_AUTH=""
|
||||
fi
|
||||
|
||||
[[ -f "control.sh" ]] && [[ "$NODE_NAME" != "" ]] && eval $(./control.sh $NODE_NAME)
|
||||
|
||||
if [[ "$FORCE_DEPLOY" != "1" ]]; then
|
||||
|
||||
for cron_part in 'cron' 'schedule'; do
|
||||
CRON_SERVICE_NAME=$(docker service ls --filter name=${STACK_NAME}_${cron_part} --format '{{.Name}}')
|
||||
if [[ "$CRON_SERVICE_NAME" != "" ]]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
TASK_SERVICE_NAME=$(docker service ls --filter name=${STACK_NAME}_task_template --format '{{.Name}}')
|
||||
|
||||
TASK_CONTAINER_ID=""
|
||||
if [[ "$TASK_CONTAINER_NAME" != "" ]]; then
|
||||
TASK_CONTAINER_ID=$(docker ps --filter name="$TASK_SERVICE_NAME" --format '{{.ID}}')
|
||||
fi
|
||||
|
||||
if [[ "$TASK_CONTAINER_ID" != "" ]]; then
|
||||
docker service scale $CRON_SERVICE_NAME=0 || exit 255
|
||||
RUNNUNG_TASKS=$(docker exec -it $TASK_CONTAINER_ID ps axuf | grep nameless)
|
||||
if [[ "$RUNNING_TASKS" != "" ]]; then
|
||||
echo "Running tasks found! Can't deploy";
|
||||
exit 255;
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$CRON_SERVICE_NAME" != "" ]]; then
|
||||
docker service scale $CRON_SERVICE_NAME=0 || exit 255
|
||||
fi
|
||||
|
||||
if [[ "$TASK_CONTAINER_ID" != "" ]]; then
|
||||
RUNNUNG_TASKS=$(docker exec -it $TASK_CONTAINER_ID ps axuf | grep nameless)
|
||||
if [[ "$RUNNING_TASKS" != "" ]]; then
|
||||
echo "Scheduler is stopped but running tasks found! Can't deploy";
|
||||
exit 255;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
bash -c "docker stack deploy --prune $COMPOSER_SWARM_ARGS $REGISTRY_AUTH $STACK_NAME"
|
||||
|
||||
EXIT=$?
|
||||
|
||||
if [ $EXIT -ne 0 ]
|
||||
then
|
||||
echo "Deploy failed"
|
||||
exit $EXIT
|
||||
fi
|
||||
|
||||
echo "Waiting for services..."
|
||||
|
||||
while true; do
|
||||
|
||||
IFS=$'\n' services=($(docker service ls | grep $STACK_NAME | awk '{print $2,$4}'));
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Something went wrong"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
is_ready=1
|
||||
all_services=0
|
||||
bad_services=0
|
||||
|
||||
for line in "${services[@]}"
|
||||
do
|
||||
all_services=$((all_services+1))
|
||||
IFS=$' ' service_status=($line)
|
||||
re="migrate|test_setup"
|
||||
if ! [[ "${service_status[0]}" =~ $re ]]
|
||||
then
|
||||
IFS=$'/' replicas=(${service_status[1]})
|
||||
if [ ${replicas[0]} -lt ${replicas[1]} ]
|
||||
then
|
||||
is_ready=0
|
||||
bad_services=$((bad_services+1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $is_ready -eq 1 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 5;
|
||||
echo "Services: $all_services, but $bad_services is not ready yet"
|
||||
done
|
||||
|
||||
echo "Done."
|
||||
fi
|
||||
|
||||
if [[ "$COMMAND" == "run" ]]; then
|
||||
bash -c "docker compose $COMPOSER_FILE_ARGS down"
|
||||
if [[ "$DO_UPDATE" == "yes" ]]; then
|
||||
bash -c "docker compose $COMPOSER_FILE_ARGS pull"
|
||||
fi
|
||||
|
||||
bash -c "docker compose $COMPOSER_FILE_ARGS up -d"
|
||||
EXIT=$?
|
||||
fi
|
||||
|
||||
if [[ "$COMMAND" == "stop" ]]; then
|
||||
bash -c "docker compose $COMPOSER_FILE_ARGS down"
|
||||
EXIT=$?
|
||||
fi
|
||||
|
||||
rm .project*.tmp.env
|
||||
|
||||
exit $EXIT
|
||||
Reference in New Issue
Block a user