#!/bin/bash # TSYSDevStack SupportStack Demo - Control Script # Provides start/stop/uninstall/update/test functionality for the MVP stack set -e # Exit on any error # Load environment settings SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(dirname "$SCRIPT_DIR")" CONFIG_DIR="${ROOT_DIR}/config" COMPOSE_DIR="${ROOT_DIR}/docker-compose" ROOT_ENV_FILE="${ROOT_DIR}/TSYSDevStack-SupportStack-Demo-Settings" CONFIG_ENV_FILE="${CONFIG_DIR}/TSYSDevStack-SupportStack-Demo-Settings" if [ -f "$ROOT_ENV_FILE" ]; then ENV_FILE="$ROOT_ENV_FILE" elif [ -f "$CONFIG_ENV_FILE" ]; then ENV_FILE="$CONFIG_ENV_FILE" else echo "Error: Environment settings file not found. Expected at $ROOT_ENV_FILE or $CONFIG_ENV_FILE" exit 1 fi # Set UID/GID defaults prior to sourcing environment file so runtime values override placeholders export TSYSDEVSTACK_UID="$(id -u)" export TSYSDEVSTACK_GID="$(id -g)" export TSYSDEVSTACK_DOCKER_GID="$(getent group docker >/dev/null 2>&1 && getent group docker | cut -d: -f3 || echo "996")" # Source the environment file to get all variables source "$ENV_FILE" # Explicitly export all environment variables for docker compose export TSYSDEVSTACK_ENVIRONMENT export TSYSDEVSTACK_PROJECT_NAME export TSYSDEVSTACK_NETWORK_NAME export DOCKER_SOCKET_PROXY_NAME export DOCKER_SOCKET_PROXY_IMAGE export DOCKER_SOCKET_PROXY_SOCKET_PATH export DOCKER_SOCKET_PROXY_NETWORK export DOCKER_SOCKET_PROXY_CONTAINERS export DOCKER_SOCKET_PROXY_IMAGES export DOCKER_SOCKET_PROXY_NETWORKS export DOCKER_SOCKET_PROXY_VOLUMES export DOCKER_SOCKET_PROXY_BUILD export DOCKER_SOCKET_PROXY_MANIFEST export DOCKER_SOCKET_PROXY_PLUGINS export DOCKER_SOCKET_PROXY_VERSION export HOMEPAGE_NAME export HOMEPAGE_IMAGE export HOMEPAGE_PORT export HOMEPAGE_NETWORK export HOMEPAGE_CONFIG_PATH export WAKAAPI_NAME export WAKAAPI_IMAGE export WAKAAPI_PORT export WAKAAPI_NETWORK export WAKAAPI_CONFIG_PATH export WAKAAPI_WAKATIME_API_KEY export WAKAAPI_DATABASE_PATH export MAILHOG_NAME export MAILHOG_IMAGE export MAILHOG_SMTP_PORT export MAILHOG_UI_PORT export MAILHOG_NETWORK export DOCKER_SOCKET_PROXY_MEM_LIMIT export DOCKER_SOCKET_PROXY_CPU_LIMIT export HOMEPAGE_MEM_LIMIT export HOMEPAGE_CPU_LIMIT export WAKAAPI_MEM_LIMIT export WAKAAPI_CPU_LIMIT export MAILHOG_MEM_LIMIT export MAILHOG_CPU_LIMIT export HEALTH_CHECK_INTERVAL export HEALTH_CHECK_TIMEOUT export HEALTH_CHECK_START_PERIOD export HEALTH_CHECK_RETRIES export DOCKER_SOCKET_PROXY_CONNECTION_TIMEOUT export HOMEPAGE_STARTUP_TIMEOUT export WAKAAPI_INITIALIZATION_TIMEOUT export DOCKER_COMPOSE_STARTUP_TIMEOUT export BIND_ADDRESS export TSYSDEVSTACK_UID export TSYSDEVSTACK_GID export TSYSDEVSTACK_DOCKER_GID # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging function log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } compose() { docker compose -p "$TSYSDEVSTACK_PROJECT_NAME" "$@" } # Function to check if docker is available check_docker() { if ! command -v docker &> /dev/null; then log_error "Docker is not installed or not in PATH" exit 1 fi if ! docker info &> /dev/null; then log_error "Docker is not running or not accessible" exit 1 fi } # Function to create the shared network create_network() { log "Creating shared network: $TSYSDEVSTACK_NETWORK_NAME" if ! docker network inspect "$TSYSDEVSTACK_NETWORK_NAME" >/dev/null 2>&1; then docker network create \ --driver bridge \ --label tsysdevstack.component="supportstack-demo" \ --label tsysdevstack.environment="$TSYSDEVSTACK_ENVIRONMENT" \ "$TSYSDEVSTACK_NETWORK_NAME" log_success "Network created: $TSYSDEVSTACK_NETWORK_NAME" else log "Network already exists: $TSYSDEVSTACK_NETWORK_NAME" fi } # Function to remove the shared network remove_network() { log "Removing shared network: $TSYSDEVSTACK_NETWORK_NAME" if docker network inspect "$TSYSDEVSTACK_NETWORK_NAME" >/dev/null 2>&1; then docker network rm "$TSYSDEVSTACK_NETWORK_NAME" log_success "Network removed: $TSYSDEVSTACK_NETWORK_NAME" else log "Network does not exist: $TSYSDEVSTACK_NETWORK_NAME" fi } # Function to start the MVP stack start() { log "Starting TSYSDevStack SupportStack Demo MVP" check_docker log "Using environment file: $ENV_FILE" create_network # Start docker-socket-proxy first (dependency for homepage) log "Starting docker-socket-proxy..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" up -d log_success "docker-socket-proxy started" else log_warning "docker-socket-proxy compose file not found, skipping..." fi # Wait for docker socket proxy to be ready log "Waiting for docker-socket-proxy to be ready..." sleep 10 # Start homepage log "Starting homepage..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" up -d log_success "homepage started" else log_warning "homepage compose file not found, skipping..." fi # Wait for homepage to be ready log "Waiting for homepage to be ready..." sleep 15 # Start wakaapi log "Starting wakaapi..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" up -d log_success "wakaapi started" else log_warning "wakaapi compose file not found, skipping..." fi # Start mailhog log "Starting mailhog..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" up -d log_success "mailhog started" else log_warning "mailhog compose file not found, skipping..." fi # Wait for services to be ready log "Waiting for all services to be ready..." sleep 20 log_success "MVP stack started successfully" echo "Homepage available at: http://$BIND_ADDRESS:$HOMEPAGE_PORT" echo "WakaAPI available at: http://$BIND_ADDRESS:$WAKAAPI_PORT" echo "Mailhog available at: http://$BIND_ADDRESS:$MAILHOG_UI_PORT (SMTP on $MAILHOG_SMTP_PORT)" } # Function to stop the MVP stack stop() { log "Stopping TSYSDevStack SupportStack Demo MVP" check_docker # Stop mailhog log "Stopping mailhog..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" down log_success "mailhog stopped" else log_warning "mailhog compose file not found, skipping..." fi # Stop wakaapi log "Stopping wakaapi..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" down log_success "wakaapi stopped" else log_warning "wakaapi compose file not found, skipping..." fi # Stop homepage log "Stopping homepage..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" down log_success "homepage stopped" else log_warning "homepage compose file not found, skipping..." fi # Stop docker-socket-proxy last log "Stopping docker-socket-proxy..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" down log_success "docker-socket-proxy stopped" else log_warning "docker-socket-proxy compose file not found, skipping..." fi log_success "MVP stack stopped successfully" } # Function to uninstall the MVP stack uninstall() { log "Uninstalling TSYSDevStack SupportStack Demo MVP" check_docker # Stop all services first stop # Remove containers, volumes, and networks log "Removing containers and volumes..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" down -v fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" down -v fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" down -v fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" down -v fi # Remove the shared network remove_network log_success "MVP stack uninstalled successfully" } # Function to update the MVP stack update() { log "Updating TSYSDevStack SupportStack Demo MVP" check_docker # Pull the latest images log "Pulling latest images..." if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" pull log_success "docker-socket-proxy images updated" fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" pull log_success "homepage images updated" fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" pull log_success "wakaapi images updated" fi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ]; then compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" pull log_success "mailhog images updated" fi log "Restarting services with updated images..." stop start log_success "MVP stack updated successfully" } # Function to run tests test() { log "Running tests for TSYSDevStack SupportStack Demo MVP" check_docker # Add test functions here log "Checking if services are running..." # Check docker-socket-proxy if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ]; then if compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-docker-socket-proxy.yml" ps | grep -q "Up"; then log_success "docker-socket-proxy is running" else log_error "docker-socket-proxy is not running" fi fi # Check homepage if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ]; then if compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-homepage.yml" ps | grep -q "Up"; then log_success "homepage is running" else log_error "homepage is not running" fi fi # Check wakaapi if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ]; then if compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-wakaapi.yml" ps | grep -q "Up"; then log_success "wakaapi is running" else log_error "wakaapi is not running" fi fi # Check mailhog if [ -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ]; then if compose -f "${COMPOSE_DIR}/tsysdevstack-supportstack-demo-DockerCompose-mailhog.yml" ps | grep -q "Up"; then log_success "mailhog is running" else log_error "mailhog is not running" fi fi # Run any unit/integration tests if available TESTS_DIR="$(dirname "$SCRIPT_DIR")/tests" if [ -d "$TESTS_DIR" ]; then log "Running specific tests from $TESTS_DIR..." # Run individual test scripts for test_script in "$TESTS_DIR"/*.sh; do if [ -f "$test_script" ] && [ -r "$test_script" ] && [ -x "$test_script" ]; then log "Running test: $test_script" "$test_script" if [ $? -eq 0 ]; then log_success "Test completed: $(basename "$test_script")" else log_error "Test failed: $(basename "$test_script")" fi fi done log_success "Tests completed" else log_warning "No tests directory found at $TESTS_DIR" fi log_success "Test execution completed" } # Function to display help show_help() { cat << EOF TSYSDevStack SupportStack Demo - Control Script Usage: $0 {start|stop|uninstall|update|test|help} Commands: start Start the MVP stack (docker-socket-proxy, homepage, wakaapi) stop Stop the MVP stack uninstall Uninstall the MVP stack (stop and remove all containers, volumes, and networks) update Update the MVP stack to latest images and restart test Run tests to verify the stack functionality help Show this help message Examples: $0 start $0 stop $0 uninstall $0 update $0 test EOF } # Main script logic case "$1" in start) start ;; stop) stop ;; uninstall) uninstall ;; update) update ;; test) test ;; help|--help|-h) show_help ;; *) if [ -z "$1" ]; then log_error "No command provided. Use $0 help for usage information." else log_error "Unknown command: $1. Use $0 help for usage information." fi show_help exit 1 ;; esac