#!/bin/bash # Infrastructure Verification for Lab 03 # Verifies docker-compose.yml is correctly deployed with resource limits and healthchecks set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; YELLOW='\033[1;33m'; BOLD='\033[1m'; NC='\033[0m' pass_count=0; fail_count=0 inc_pass() { ((pass_count++)) || true; } inc_fail() { ((fail_count++)) || true; } print_header() { echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║${NC} ${BOLD}$1${NC}" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}" } print_test() { echo -e "\n${BLUE}[TEST]${NC} $1"; } print_pass() { echo -e " ${GREEN}[✓]${NC} $1"; inc_pass; } print_fail() { echo -e " ${RED}[✗]${NC} $1"; inc_fail; } cd "$(dirname "$0")/.." print_header "Lab 03 Infrastructure Verification" # File and syntax print_test "Verifying docker-compose.yml exists and valid" [[ -f "docker-compose.yml" ]] && print_pass "docker-compose.yml found" || { print_fail "docker-compose.yml not found"; exit 1; } docker compose config &> /dev/null && print_pass "Syntax valid" || { print_fail "Syntax error"; exit 1; } # Services and limits print_test "Checking INF-03 compliance (resource limits)" SERVICES=$(docker compose config --services 2>/dev/null) NON_COMPLIANT=0 for s in $SERVICES; do has_cpu=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep -c "cpus:" || echo "0") has_mem=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep -c "memory:" || echo "0") if [[ $has_cpu -eq 0 || $has_mem -eq 0 ]]; then print_fail " $s: missing limits" ((NON_COMPLIANT++)) || true else cpu_val=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep "cpus:" | sed 's/.*cpus: //' | tr -d ' "') mem_val=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep "memory:" | sed 's/.*memory: //' | tr -d " '""") print_pass " $s: cpus=$cpu_val, memory=$mem_val" fi done [[ $NON_COMPLIANT -eq 0 ]] && print_pass "INF-03 COMPLIANT" || print_fail "INF-03 VIOLATION: $NON_COMPLIANT services" # Healthchecks print_test "Verifying healthcheck configuration" MISSING_HC=0 for s in $SERVICES; do has_hc=$(docker compose config 2>/dev/null | grep -A50 "^$s:" | grep -c "healthcheck:" || echo "0") [[ $has_hc -gt 0 ]] && print_pass " $s: healthcheck configured" || { print_fail " $s: missing healthcheck"; ((MISSING_HC++)); } done [[ $MISSING_HC -eq 0 ]] && print_pass "All services have healthchecks" || print_fail "$MISSING_HC missing healthchecks" # Deploy and verify print_test "Starting services" docker compose up -d &> /dev/null && print_pass "Services started" && sleep 8 || { print_fail "Failed to start"; exit 1; } print_test "Checking running containers" RUNNING=$(docker compose ps --services --filter "status=running" | wc -l) [[ $RUNNING -ge 4 ]] && print_pass "$RUNNING containers running" || print_fail "Only $RUNNING containers" # Enforcement print_test "Verifying resource limits enforced" ENFORCED=0 for s in $SERVICES; do c="lab03-$s" if docker ps --format '{{.Names}}' | grep -q "$c"; then nano_cpus=$(docker inspect "$c" --format '{{.HostConfig.NanoCpus}}' 2>/dev/null || echo "0") mem_bytes=$(docker inspect "$c" --format '{{.HostConfig.Memory}}' 2>/dev/null || echo "0") [[ $nano_cpus -gt 0 && $mem_bytes -gt 0 ]] && print_pass " $c: limits enforced" || print_fail " $c: limits not applied" [[ $nano_cpus -gt 0 && $mem_bytes -gt 0 ]] && ((ENFORCED++)) || true fi done [[ $ENFORCED -gt 0 ]] && print_pass "Limits enforced for $ENFORCED containers" # Summary print_header "Summary" echo "Tests: $((pass_count + fail_count)) | ${GREEN}Passed: $pass_count${NC} ${RED}Failed: $fail_count${NC}" [[ $fail_count -eq 0 ]] && { echo -e "\n${GREEN}${BOLD}✓ ALL CHECKS PASSED${NC}\n"; exit 0; } || { echo -e "\n${RED}Some checks failed${NC}\n"; exit 1; }