keycloak-scim/testsuite/performance/tests/docker-compose.sh

371 lines
15 KiB
Bash
Executable file

#!/bin/bash
### FUNCTIONS ###
function runCommand() {
echo "$1"
if ! eval "$1" ; then
echo "Execution of command failed."
echo "Command: \"$1\""
exit 1;
fi
}
function generateDockerComposeFile() {
echo "Generating $( basename "$DOCKER_COMPOSE_FILE" )"
local TEMPLATES_PATH=$DEPLOYMENT
cat $TEMPLATES_PATH/docker-compose-base.yml > $DOCKER_COMPOSE_FILE
case "$DEPLOYMENT" in
cluster)
I=0
for CPUSET in $KEYCLOAK_CPUSETS ; do
I=$((I+1))
sed -e s/%I%/$I/ -e s/%CPUSET%/$CPUSET/ $TEMPLATES_PATH/docker-compose-keycloak.yml >> $DOCKER_COMPOSE_FILE
done
;;
crossdc)
I=0
for CPUSET in $KEYCLOAK_DC1_CPUSETS ; do
I=$((I+1))
sed -e s/%I%/$I/ -e s/%CPUSET%/$CPUSET/ $TEMPLATES_PATH/docker-compose-keycloak_dc1.yml >> $DOCKER_COMPOSE_FILE
done
I=0
for CPUSET in $KEYCLOAK_DC2_CPUSETS ; do
I=$((I+1))
sed -e s/%I%/$I/ -e s/%CPUSET%/$CPUSET/ $TEMPLATES_PATH/docker-compose-keycloak_dc2.yml >> $DOCKER_COMPOSE_FILE
done
;;
esac
}
function inspectDockerPortMapping() {
local PORT="$1"
local CONTAINER="$2"
local INSPECT_COMMAND="docker inspect --format='{{(index (index .NetworkSettings.Ports \"$PORT\") 0).HostPort}}' $CONTAINER"
MAPPED_PORT="$( eval "$INSPECT_COMMAND" )"
if [ -z "$MAPPED_PORT" ]; then
echo "Error finding mapped port for $CONTAINER."
exit 1
fi
}
function generateProvisionedSystemProperties() {
echo "Generating $PROVISIONED_SYSTEM_PROPERTIES_FILE"
echo "deployment=$DEPLOYMENT" > $PROVISIONED_SYSTEM_PROPERTIES_FILE
echo "keycloak.docker.services=$KEYCLOAK_SERVICES" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
case "$DEPLOYMENT" in
singlenode)
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_keycloak_1
echo "keycloak.frontend.servers=http://localhost:$MAPPED_PORT/auth" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
;;
cluster)
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_loadbalancer_1
echo "keycloak.frontend.servers=http://localhost:$MAPPED_PORT/auth" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
BACKEND_URLS=""
for SERVICE in $KEYCLOAK_SERVICES ; do
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_${SERVICE}_1
BACKEND_URLS="$BACKEND_URLS http://localhost:$MAPPED_PORT/auth"
done
echo "keycloak.backend.servers=$BACKEND_URLS" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
;;
crossdc)
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_loadbalancer_dc1_1
KC_DC1_PORT=$MAPPED_PORT
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_loadbalancer_dc2_1
KC_DC2_PORT=$MAPPED_PORT
echo "keycloak.frontend.servers=http://localhost:$KC_DC1_PORT/auth http://localhost:$KC_DC2_PORT/auth" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
BACKEND_URLS=""
for SERVICE in $KEYCLOAK_SERVICES ; do
inspectDockerPortMapping 8080/tcp ${PROJECT_NAME}_${SERVICE}_1
BACKEND_URLS="$BACKEND_URLS http://localhost:$MAPPED_PORT/auth"
done
echo "keycloak.backend.servers=$BACKEND_URLS" >> $PROVISIONED_SYSTEM_PROPERTIES_FILE
;;
esac
}
function loadProvisionedSystemProperties() {
if [ -f $PROVISIONED_SYSTEM_PROPERTIES_FILE ]; then
echo "Loading $PROVISIONED_SYSTEM_PROPERTIES_FILE"
export DEPLOYMENT=$( grep -Po "(?<=^deployment=).*" $PROVISIONED_SYSTEM_PROPERTIES_FILE )
export KEYCLOAK_SERVICES=$( grep -Po "(?<=^keycloak.docker.services=).*" $PROVISIONED_SYSTEM_PROPERTIES_FILE )
else
echo "$PROVISIONED_SYSTEM_PROPERTIES_FILE not found."
fi
}
function removeProvisionedSystemProperties() {
rm -f $PROVISIONED_SYSTEM_PROPERTIES_FILE
}
function isTestDeployment() {
IS_TEST_DEPLOYMENT=false
case "$DEPLOYMENT" in
singlenode|cluster|crossdc) IS_TEST_DEPLOYMENT=true ;;
esac
$IS_TEST_DEPLOYMENT
}
function validateNotEmpty() {
VARIABLE_NAME=$1
VARIABLE_VALUE=$2
# echo "$VARIABLE_NAME: $VARIABLE_VALUE"
if [ -z "$VARIABLE_VALUE" ]; then echo "$VARIABLE_NAME must contain at least one item."; exit 1; fi
}
### SCRIPT ###
cd "$(dirname "$0")"
. ./common.sh
cd $PROJECT_BUILD_DIRECTORY/docker-compose
PROJECT_NAME=performance
export DEPLOYMENT="${DEPLOYMENT:-singlenode}"
if isTestDeployment ; then loadProvisionedSystemProperties; fi
export OPERATION="${OPERATION:-provision}"
echo "DEPLOYMENT: $DEPLOYMENT"
case "$DEPLOYMENT" in
singlenode) DOCKER_COMPOSE_FILE=docker-compose.yml ;;
cluster) DOCKER_COMPOSE_FILE=docker-compose-cluster.yml ;;
crossdc) DOCKER_COMPOSE_FILE=docker-compose-crossdc.yml ;;
monitoring) DOCKER_COMPOSE_FILE=docker-compose-monitoring.yml ; DELETE_DATA="${DELETE_DATA:-false}" ;;
*)
echo "Deployment '$DEPLOYMENT' not supported by provisioner '$PROVISIONER'."
exit 1
;;
esac
echo "OPERATION: $OPERATION"
case "$OPERATION" in
provision)
case "$DEPLOYMENT" in
singlenode)
BASE_SERVICES="mariadb"
KEYCLOAK_SERVICES="keycloak"
validateNotEmpty DB_CPUSETS $DB_CPUSETS
DB_CPUSETS_ARRAY=( $DB_CPUSETS )
DB_CPUSET=${DB_CPUSETS_ARRAY[0]}
validateNotEmpty KEYCLOAK_CPUSETS $KEYCLOAK_CPUSETS
KEYCLOAK_CPUSETS_ARRAY=( $KEYCLOAK_CPUSETS )
KEYCLOAK_CPUSET=${KEYCLOAK_CPUSETS_ARRAY[0]}
echo "DB_CPUSET: $DB_CPUSET"
echo "KEYCLOAK_CPUSET: $KEYCLOAK_CPUSET"
echo "BASE_SERVICES: $BASE_SERVICES"
echo "KEYCLOAK_SERVICES: $KEYCLOAK_SERVICES"
;;
cluster)
BASE_SERVICES="mariadb loadbalancer"
validateNotEmpty DB_CPUSETS $DB_CPUSETS
DB_CPUSETS_ARRAY=( $DB_CPUSETS )
DB_CPUSET=${DB_CPUSETS_ARRAY[0]}
validateNotEmpty LB_CPUSETS $LB_CPUSETS
LB_CPUSETS_ARRAY=( $LB_CPUSETS )
LB_CPUSET=${LB_CPUSETS_ARRAY[0]}
validateNotEmpty KEYCLOAK_CPUSETS $KEYCLOAK_CPUSETS
KEYCLOAK_CPUSETS_ARRAY=( $KEYCLOAK_CPUSETS )
KEYCLOAK_MAX_SCALE=${#KEYCLOAK_CPUSETS_ARRAY[@]}
KEYCLOAK_SCALE="${KEYCLOAK_SCALE:-$KEYCLOAK_MAX_SCALE}"
if [ $KEYCLOAK_SCALE -gt $KEYCLOAK_MAX_SCALE ]; then KEYCLOAK_SCALE=$KEYCLOAK_MAX_SCALE; fi
if [ $KEYCLOAK_SCALE -lt 1 ]; then KEYCLOAK_SCALE=1; fi
echo "DB_CPUSET: $DB_CPUSET"
echo "KEYCLOAK_CPUSETS: $KEYCLOAK_CPUSETS"
echo "KEYCLOAK_SCALE: ${KEYCLOAK_SCALE} (max ${KEYCLOAK_MAX_SCALE})"
KEYCLOAK_SERVICES=""
STOPPED_KEYCLOAK_SERVICES=""
for ((i=1; i<=$KEYCLOAK_MAX_SCALE; i++)) ; do
if (( $i <= $KEYCLOAK_SCALE )) ; then
KEYCLOAK_SERVICES="$KEYCLOAK_SERVICES keycloak_$i"
else
STOPPED_KEYCLOAK_SERVICES="$STOPPED_KEYCLOAK_SERVICES keycloak_$i"
fi
done
echo "BASE_SERVICES: $BASE_SERVICES"
echo "KEYCLOAK_SERVICES: $KEYCLOAK_SERVICES"
generateDockerComposeFile
;;
crossdc)
BASE_SERVICES="mariadb_dc1 mariadb_dc2 infinispan_dc1 infinispan_dc2 loadbalancer_dc1 loadbalancer_dc2"
validateNotEmpty DB_DC1_CPUSETS $DB_DC1_CPUSETS
validateNotEmpty DB_DC2_CPUSETS $DB_DC2_CPUSETS
DB_DC1_CPUSETS_ARRAY=( $DB_DC1_CPUSETS )
DB_DC2_CPUSETS_ARRAY=( $DB_DC2_CPUSETS )
DB_DC1_CPUSET=${DB_DC1_CPUSETS_ARRAY[0]}
DB_DC2_CPUSET=${DB_DC2_CPUSETS_ARRAY[0]}
echo "DB_DC1_CPUSET: $DB_DC1_CPUSET"
echo "DB_DC2_CPUSET: $DB_DC2_CPUSET"
validateNotEmpty LB_DC1_CPUSETS $LB_DC1_CPUSETS
validateNotEmpty LB_DC2_CPUSETS $LB_DC2_CPUSETS
LB_DC1_CPUSETS_ARRAY=( $LB_DC1_CPUSETS )
LB_DC2_CPUSETS_ARRAY=( $LB_DC2_CPUSETS )
LB_DC1_CPUSET=${LB_DC1_CPUSETS_ARRAY[0]}
LB_DC2_CPUSET=${LB_DC2_CPUSETS_ARRAY[0]}
echo "LB_DC1_CPUSET: $LB_DC1_CPUSET"
echo "LB_DC2_CPUSET: $LB_DC2_CPUSET"
validateNotEmpty INFINISPAN_DC1_CPUSETS $INFINISPAN_DC1_CPUSETS
validateNotEmpty INFINISPAN_DC2_CPUSETS $INFINISPAN_DC2_CPUSETS
INFINISPAN_DC1_CPUSETS_ARRAY=( $INFINISPAN_DC1_CPUSETS )
INFINISPAN_DC2_CPUSETS_ARRAY=( $INFINISPAN_DC2_CPUSETS )
INFINISPAN_DC1_CPUSET=${INFINISPAN_DC1_CPUSETS_ARRAY[0]}
INFINISPAN_DC2_CPUSET=${INFINISPAN_DC2_CPUSETS_ARRAY[0]}
echo "INFINISPAN_DC1_CPUSET: $INFINISPAN_DC1_CPUSET"
echo "INFINISPAN_DC2_CPUSET: $INFINISPAN_DC2_CPUSET"
validateNotEmpty KEYCLOAK_DC1_CPUSETS $KEYCLOAK_DC1_CPUSETS
validateNotEmpty KEYCLOAK_DC2_CPUSETS $KEYCLOAK_DC2_CPUSETS
KEYCLOAK_DC1_CPUSETS_ARRAY=( $KEYCLOAK_DC1_CPUSETS )
KEYCLOAK_DC2_CPUSETS_ARRAY=( $KEYCLOAK_DC2_CPUSETS )
KEYCLOAK_DC1_MAX_SCALE=${#KEYCLOAK_DC1_CPUSETS_ARRAY[@]}
KEYCLOAK_DC2_MAX_SCALE=${#KEYCLOAK_DC2_CPUSETS_ARRAY[@]}
KEYCLOAK_DC1_SCALE="${KEYCLOAK_DC1_SCALE:-$KEYCLOAK_DC1_MAX_SCALE}"
KEYCLOAK_DC2_SCALE="${KEYCLOAK_DC2_SCALE:-$KEYCLOAK_DC2_MAX_SCALE}"
if [ $KEYCLOAK_DC1_SCALE -gt $KEYCLOAK_DC1_MAX_SCALE ]; then KEYCLOAK_DC1_SCALE=$KEYCLOAK_DC1_MAX_SCALE; fi
if [ $KEYCLOAK_DC1_SCALE -lt 1 ]; then KEYCLOAK_DC1_SCALE=1; fi
if [ $KEYCLOAK_DC2_SCALE -gt $KEYCLOAK_DC2_MAX_SCALE ]; then KEYCLOAK_DC2_SCALE=$KEYCLOAK_DC2_MAX_SCALE; fi
if [ $KEYCLOAK_DC2_SCALE -lt 1 ]; then KEYCLOAK_DC2_SCALE=1; fi
echo "KEYCLOAK_DC1_CPUSETS: ${KEYCLOAK_DC1_CPUSETS}"
echo "KEYCLOAK_DC2_CPUSETS: ${KEYCLOAK_DC2_CPUSETS}"
echo "KEYCLOAK_DC1_SCALE: ${KEYCLOAK_DC1_SCALE} (max ${KEYCLOAK_DC1_MAX_SCALE})"
echo "KEYCLOAK_DC2_SCALE: ${KEYCLOAK_DC2_SCALE} (max ${KEYCLOAK_DC2_MAX_SCALE})"
KEYCLOAK_SERVICES=""
STOPPED_KEYCLOAK_SERVICES=""
for ((i=1; i<=$KEYCLOAK_DC1_MAX_SCALE; i++)) ; do
if (( $i <= $KEYCLOAK_DC1_SCALE )) ; then
KEYCLOAK_SERVICES="$KEYCLOAK_SERVICES keycloak_dc1_$i"
else
STOPPED_KEYCLOAK_SERVICES="$STOPPED_KEYCLOAK_SERVICES keycloak_dc1_$i"
fi
done
for ((i=1; i<=$KEYCLOAK_DC2_MAX_SCALE; i++)) ; do
if (( $i <= $KEYCLOAK_DC2_SCALE )) ; then
KEYCLOAK_SERVICES="$KEYCLOAK_SERVICES keycloak_dc2_$i"
else
STOPPED_KEYCLOAK_SERVICES="$STOPPED_KEYCLOAK_SERVICES keycloak_dc2_$i"
fi
done
echo "BASE_SERVICES: $BASE_SERVICES"
echo "KEYCLOAK_SERVICES: $KEYCLOAK_SERVICES"
generateDockerComposeFile
;;
esac
runCommand "docker-compose -f $DOCKER_COMPOSE_FILE -p ${PROJECT_NAME} up -d --build $BASE_SERVICES $KEYCLOAK_SERVICES"
if [ ! -z "$STOPPED_KEYCLOAK_SERVICES" ] ; then
echo "STOPPED_KEYCLOAK_SERVICES: $STOPPED_KEYCLOAK_SERVICES"
runCommand "docker-compose -f $DOCKER_COMPOSE_FILE -p ${PROJECT_NAME} stop $STOPPED_KEYCLOAK_SERVICES"
fi
if isTestDeployment ; then
generateProvisionedSystemProperties;
$PROJECT_BASEDIR/healthcheck.sh
fi
;;
teardown)
DELETE_DATA="${DELETE_DATA:-true}"
echo "DELETE_DATA: $DELETE_DATA"
if "$DELETE_DATA" ; then VOLUMES_ARG="-v"; else VOLUMES_ARG=""; fi
runCommand "docker-compose -f $DOCKER_COMPOSE_FILE -p ${PROJECT_NAME} down $VOLUMES_ARG"
if isTestDeployment ; then removeProvisionedSystemProperties; fi
;;
export-dump|import-dump)
loadProvisionedSystemProperties
echo "KEYCLOAK_SERVICES: $KEYCLOAK_SERVICES"
if [ -z "$KEYCLOAK_SERVICES" ]; then echo "Unable to load KEYCLOAK_SERVICES"; exit 1; fi
case "$DEPLOYMENT" in
singlenode|cluster) export DB_CONTAINER=${PROJECT_NAME}_mariadb_1 ;;
crossdc) export DB_CONTAINER=${PROJECT_NAME}_mariadb_dc1_1 ;;
*) echo "Deployment '$DEPLOYMENT' doesn't support operation '$OPERATION'." ; exit 1 ;;
esac
if [ -z "$DATASET" ]; then echo "Operation '$OPERATION' requires DATASET parameter."; exit 1; fi
echo "DATASET: $DATASET"
echo "Stopping Keycloak services."
runCommand "docker-compose -f $DOCKER_COMPOSE_FILE -p ${PROJECT_NAME} stop $KEYCLOAK_SERVICES"
cd $PROJECT_BASEDIR/datasets
case "$OPERATION" in
export-dump)
echo "Exporting $DATASET.sql."
if docker exec $DB_CONTAINER /usr/bin/mysqldump -u root --password=root keycloak > $DATASET.sql ; then
echo "Compressing $DATASET.sql."
gzip $DATASET.sql
fi
;;
import-dump)
DUMP_DOWNLOAD_SITE=${DUMP_DOWNLOAD_SITE:-https://downloads.jboss.org/keycloak-qe}
if [ ! -f "$DATASET.sql.gz" ]; then
echo "Downloading dump file."
if ! curl -f -O $DUMP_DOWNLOAD_SITE/$DATASET.properties -O $DUMP_DOWNLOAD_SITE/$DATASET.sql.gz ; then
echo Download failed.
exit 1
fi
fi
echo "Importing $DATASET.sql.gz"
set -o pipefail
if ! zcat $DATASET.sql.gz | docker exec -i $DB_CONTAINER /usr/bin/mysql -u root --password=root keycloak ; then
echo Import failed.
exit 1
fi
;;
esac
cd $PROJECT_BUILD_DIRECTORY/docker-compose
echo "Starting Keycloak services."
runCommand "docker-compose -f $DOCKER_COMPOSE_FILE -p ${PROJECT_NAME} up -d --no-recreate $KEYCLOAK_SERVICES"
# need to update mapped ports
generateProvisionedSystemProperties
$PROJECT_BASEDIR/healthcheck.sh
;;
*)
echo "Unsupported operation: '$OPERATION'"
exit 1
;;
esac