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