Initial Commit

This commit is contained in:
Nishan
2025-04-02 10:39:59 +05:30
commit d8b69865f6
387 changed files with 28558 additions and 0 deletions

135
scripts/COMPOSE-DEPLOY.md Normal file
View File

@@ -0,0 +1,135 @@
# CK-X Simulator Deployment Guide
This guide provides instructions for deploying the CK-X Simulator on different operating systems.
## Prerequisites
- Docker Desktop (Windows/Mac) or Docker Engine (Linux)
- 4GB RAM minimum (8GB recommended)
- 10GB free disk space
- Internet connection
- Port 30080 available
## Quick Install
### Linux & macOS
Open Terminal and run:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/nishanb/ck-x/main/scripts/install.sh)
```
### Windows
Open PowerShell as Administrator and run:
```powershell
irm https://raw.githubusercontent.com/nishanb/ck-x/main/scripts/install.ps1 | iex
```
## Manual Installation
# By cloning the repository
1. Clone the repository:
```bash
git clone https://github.com/nishanb/ck-x.git
cd ck-x
```
2. Build and start the services using Docker Compose:
```bash
docker compose up -d
```
### Via Script
If you prefer to install manually or the quick install doesn't work:
1. Download the installation script:
- Linux/macOS: [install.sh](https://raw.githubusercontent.com/nishanb/ck-x/main/script/install.sh)
- Windows: [install.ps1](https://raw.githubusercontent.com/nishanb/ck-x/main/script/install.ps1)
2. Run the script:
- Linux/macOS:
```bash
chmod +x install.sh
./install.sh
```
- Windows (in PowerShell as Administrator):
```powershell
.\install.ps1
```
## Post-Installation
After successful installation, you can access CK-X Simulator at:
```
http://localhost:30080
```
## Managing CK-X Simulator
### Start Services
```bash
docker compose up -d
```
### Stop Services
```bash
docker compose down
```
### View Logs
```bash
docker compose logs -f
```
### Update
```bash
docker compose pull
docker compose up -d
```
## Troubleshooting
### Common Issues
1. **Port 30080 Already in Use**
- Check what's using the port:
- Windows: `netstat -ano | findstr :30080`
- Linux/Mac: `lsof -i :30080`
- Stop the conflicting service or change the port in docker-compose.yml
2. **Docker Not Running**
- Windows/Mac: Start Docker Desktop
- Linux: `sudo systemctl start docker`
3. **Permission Issues**
- Windows: Run PowerShell as Administrator
- Linux: Add user to docker group or use sudo
4. **Services Not Starting**
- Check logs: `docker compose logs -f`
- Ensure sufficient system resources
### Getting Help
If you encounter issues:
1. Check the logs: `docker compose logs -f`
2. Visit our [GitHub Issues](https://github.com/nishanb/ck-x/issues)
3. Contact support with logs and system information
## Uninstallation
To completely remove CK-X Simulator:
```bash
# Stop and remove containers
docker compose down
# Remove downloaded files
cd ..
rm -rf ck-x-simulator
```

View File

@@ -0,0 +1,107 @@
# CK-X Simulator Scripts
This directory contains utility scripts for the CK-X Simulator project.
## Build and Push Script
The `build-and-push.sh` script automates the process of building and pushing all Docker images defined in the compose.yaml file to Docker Hub.
### Prerequisites
- Docker installed and running
- Docker Hub account
- Logged in to Docker Hub via `docker login`
### Usage
1. Ensure you are logged in to Docker Hub:
```
docker login
```
2. (Optional) Set your Docker Hub username if different from the default:
```
export DOCKER_HUB_USERNAME=yourusername
```
3. Run the script from the `script` directory:
```
cd script
./build-and-push.sh
```
Or run it from anywhere by providing the full path:
```
/path/to/killer-clone/script/build-and-push.sh
```
4. When prompted, enter a tag for the images:
- Press Enter to use the default tag "latest"
- Or enter a custom tag (e.g., "v1.0.0", "dev", "staging")
### Dealing with Docker Login Issues
If you encounter problems with the Docker login check:
1. The script now uses multiple methods to verify login status, which should be more reliable
2. If you're sure you're logged in but the script doesn't detect it, you can choose to continue anyway when prompted
3. You can completely skip the login check by setting an environment variable:
```
export SKIP_LOGIN_CHECK=true
./build-and-push.sh
```
### What the Script Does
1. Checks if you're logged in to Docker Hub (with improved reliability)
2. Determines the correct paths to all project directories
3. Prompts for a tag name for the images
4. Lists all images that will be built and pushed with the specified tag
5. Asks for confirmation before proceeding
6. Builds and pushes each image in sequence:
- ck-x-simulator-remote-desktop
- ck-x-simulator-webapp
- ck-x-simulator-nginx
- ck-x-simulator-jumphost
- ck-x-simulator-remote-terminal
- ck-x-simulator-cluster
- ck-x-simulator-facilitator
### Examples
Build with the default "latest" tag:
```
cd script
./build-and-push.sh
# Press Enter when prompted for tag
```
Build with a version tag:
```
cd script
./build-and-push.sh
# Enter "v1.2.3" when prompted for tag
```
Build with environment-specific tag:
```
cd script
./build-and-push.sh
# Enter "staging" or "production" when prompted for tag
```
Skip the Docker login check:
```
cd script
SKIP_LOGIN_CHECK=true ./build-and-push.sh
```
### Troubleshooting
If you encounter any issues:
1. Make sure you are logged in to Docker Hub
2. If the login check fails but you're sure you're logged in, try the SKIP_LOGIN_CHECK option
3. Ensure all directories referenced in the script exist
4. Make sure you're running the script from the correct location (inside the `script` directory)
5. Check that you have the necessary permissions to build and push images
6. Verify your Docker Hub account has sufficient privileges

View File

@@ -0,0 +1,165 @@
#!/bin/bash
# Script to build and push Docker images for CK-X Simulator
# This script builds all images defined in the compose.yaml file and pushes them to Docker Hub
# Set variables
DOCKER_HUB_USERNAME=${DOCKER_HUB_USERNAME:-nishanb}
REGISTRY="${DOCKER_HUB_USERNAME}"
SKIP_LOGIN_CHECK=${SKIP_LOGIN_CHECK:-false}
# Get the script directory to handle relative paths correctly
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Define color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Print header
echo -e "${GREEN}=======================================${NC}"
echo -e "${GREEN} CK-X Simulator - Build & Push Tool ${NC}"
echo -e "${GREEN}=======================================${NC}"
echo
# Check if user is logged in to Docker Hub (with option to skip)
if [ "$SKIP_LOGIN_CHECK" != "true" ]; then
echo -e "${YELLOW}Checking Docker Hub login status...${NC}"
# Try multiple methods to check login status
if [ -f ~/.docker/config.json ]; then
if grep -q "auth" ~/.docker/config.json; then
echo -e "${GREEN}Docker credentials found in config file.${NC}"
LOGIN_STATUS=0
else
echo -e "${RED}No credentials found in Docker config file.${NC}"
LOGIN_STATUS=1
fi
else
# Try the docker info method
docker info 2>/dev/null | grep -q Username
LOGIN_STATUS=$?
if [ $LOGIN_STATUS -ne 0 ]; then
echo -e "${RED}You do not appear to be logged in to Docker Hub.${NC}"
else
echo -e "${GREEN}You appear to be logged in to Docker Hub.${NC}"
fi
fi
# Allow user to continue anyway
if [ $LOGIN_STATUS -ne 0 ]; then
echo -e "${YELLOW}You might need to log in using: docker login${NC}"
echo -e "${YELLOW}However, you can still continue if you're sure you're logged in.${NC}"
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Operation cancelled by user.${NC}"
exit 0
fi
echo -e "${GREEN}Continuing with build and push process...${NC}"
else
echo -e "${GREEN}You are logged in to Docker Hub.${NC}"
fi
else
echo -e "${YELLOW}Skipping Docker Hub login check as requested.${NC}"
fi
echo
# Ask for tag
echo -e "${YELLOW}Please enter tag for the images (default: latest):${NC}"
read -r TAG_INPUT
TAG="${TAG_INPUT:-latest}"
echo -e "${GREEN}Using tag: ${TAG}${NC}"
echo
# Function to build and push a single image
build_and_push() {
local COMPONENT=$1
local CONTEXT_PATH=$2
local IMAGE_NAME="${REGISTRY}/ck-x-simulator-${COMPONENT}:${TAG}"
echo -e "${YELLOW}Building image: ${IMAGE_NAME}${NC}"
echo -e "Context path: ${CONTEXT_PATH}"
# Check if the context path exists
if [ ! -d "${CONTEXT_PATH}" ]; then
echo -e "${RED}Error: Context path '${CONTEXT_PATH}' does not exist!${NC}"
exit 1
fi
# Build the image
docker build -t ${IMAGE_NAME} ${CONTEXT_PATH}
if [ $? -eq 0 ]; then
echo -e "${GREEN}Successfully built ${IMAGE_NAME}${NC}"
# Push the image
echo -e "${YELLOW}Pushing image: ${IMAGE_NAME}${NC}"
docker push ${IMAGE_NAME}
if [ $? -eq 0 ]; then
echo -e "${GREEN}Successfully pushed ${IMAGE_NAME}${NC}"
else
echo -e "${RED}Failed to push ${IMAGE_NAME}${NC}"
exit 1
fi
else
echo -e "${RED}Failed to build ${IMAGE_NAME}${NC}"
exit 1
fi
echo
}
# Confirm before proceeding
echo -e "${YELLOW}This script will build and push the following images with tag '${TAG}':${NC}"
echo " - ${REGISTRY}/ck-x-simulator-remote-desktop:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-webapp:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-nginx:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-jumphost:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-remote-terminal:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-cluster:${TAG}"
echo " - ${REGISTRY}/ck-x-simulator-facilitator:${TAG}"
echo
read -p "Do you want to continue? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Operation cancelled by user.${NC}"
exit 0
fi
# Build and push each image
echo -e "${GREEN}Starting build and push process...${NC}"
echo
# Remote Desktop
build_and_push "remote-desktop" "${PROJECT_ROOT}/remote-desktop"
# Web Application
build_and_push "webapp" "${PROJECT_ROOT}/app"
# Nginx
build_and_push "nginx" "${PROJECT_ROOT}/nginx"
# Jump Host
build_and_push "jumphost" "${PROJECT_ROOT}/jumphost"
# Remote Terminal
build_and_push "remote-terminal" "${PROJECT_ROOT}/remote-terminal"
# Kubernetes Cluster
build_and_push "cluster" "${PROJECT_ROOT}/kind-cluster"
# Facilitator
build_and_push "facilitator" "${PROJECT_ROOT}/facilitator"
echo -e "${GREEN}=======================================${NC}"
echo -e "${GREEN} All images built and pushed successfully! ${NC}"
echo -e "${GREEN} Tag: ${TAG} ${NC}"
echo -e "${GREEN}=======================================${NC}"
# Done
exit 0

319
scripts/install.ps1 Normal file
View File

@@ -0,0 +1,319 @@
# PowerShell script for installing CK-X Simulator
# Requires PowerShell 5.0 or higher
# Color definitions for output
$Red = [System.Console]::ForegroundColor = "Red"
$Green = [System.Console]::ForegroundColor = "Green"
$Yellow = [System.Console]::ForegroundColor = "Yellow"
$Blue = [System.Console]::ForegroundColor = "Blue"
$Cyan = [System.Console]::ForegroundColor = "Cyan"
$DefaultColor = [System.Console]::ResetColor()
# Function to print colored text
function Write-ColorOutput {
param (
[string]$Message,
[string]$Color
)
if ($Color -eq "Red") {
Write-Host $Message -ForegroundColor Red
} elseif ($Color -eq "Green") {
Write-Host $Message -ForegroundColor Green
} elseif ($Color -eq "Yellow") {
Write-Host $Message -ForegroundColor Yellow
} elseif ($Color -eq "Blue") {
Write-Host $Message -ForegroundColor Blue
} elseif ($Color -eq "Cyan") {
Write-Host $Message -ForegroundColor Cyan
} else {
Write-Host $Message
}
}
# ASCII Art and Description
function Print-Header {
Write-ColorOutput "`n" "Blue"
Write-ColorOutput "░█████╗░██╗░░██╗░░░░░░██╗░░██╗ ░██████╗██╗███╗░░░███╗██╗░░░██╗██╗░░░░░░█████╗░████████╗░█████╗░██████╗░" "Blue"
Write-ColorOutput "██╔══██╗██║░██╔╝░░░░░░╚██╗██╔╝ ██╔════╝██║████╗░████║██║░░░██║██║░░░░░██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗" "Blue"
Write-ColorOutput "██║░░╚═╝█████═╝░█████╗░╚███╔╝░ ╚█████╗░██║██╔████╔██║██║░░░██║██║░░░░░███████║░░░██║░░░██║░░██║██████╔╝" "Blue"
Write-ColorOutput "██║░░██╗██╔═██╗░╚════╝░██╔██╗░ ░╚═══██╗██║██║╚██╔╝██║██║░░░██║██║░░░░░██╔══██║░░░██║░░░██║░░██║██╔══██╗" "Blue"
Write-ColorOutput "╚█████╔╝██║░╚██╗░░░░░░██╔╝╚██╗ ██████╔╝██║██║░╚═╝░██║╚██████╔╝███████╗██║░░██║░░░██║░░░╚█████╔╝██║░░██║" "Blue"
Write-ColorOutput "░╚════╝░╚═╝░░╚═╝░░░░░░╚═╝░░╚═╝ ╚═════╝░╚═╝╚═╝░░░░░╚═╝░╚═════╝░╚══════╝╚═╝░░╚═╝░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝" "Blue"
Write-ColorOutput "`n" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
Write-ColorOutput "CK-X Simulator: Kubernetes Certification Exam Simulator" "Cyan"
Write-ColorOutput "Practice in a realistic environment for CKA, CKAD, and more" "Cyan"
Write-ColorOutput "==============================================================" "Cyan"
Write-ColorOutput " Facing any issues? Please report at: https://github.com/nishanb/ck-x/issues" "Cyan"
Write-Host ""
}
# Function to check if running as administrator
function Test-Administrator {
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal $user
return $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
# Function to check if a command exists
function Test-Command {
param($Command)
return [bool](Get-Command -Name $Command -ErrorAction SilentlyContinue)
}
# Function to check if Docker is running
function Test-DockerRunning {
try {
$dockerInfo = docker info 2>&1
if ($LASTEXITCODE -eq 0) {
return $true
} else {
return $false
}
} catch {
return $false
}
}
# Function to check system requirements
function Check-Requirements {
Write-ColorOutput "Checking System Requirements" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
# Check if running as administrator
if (-not (Test-Administrator)) {
Write-ColorOutput "✗ This script must be run as Administrator" "Red"
Write-ColorOutput "Please right-click PowerShell and select 'Run as Administrator'" "Yellow"
exit 1
}
Write-ColorOutput "✓ Running with Administrator privileges" "Green"
# Check Docker Desktop
if (-not (Test-Command docker)) {
Write-ColorOutput "✗ Docker is not installed" "Red"
Write-ColorOutput "Please install Docker Desktop first:" "Yellow"
Write-ColorOutput "Visit https://docs.docker.com/desktop/windows/install/ for installation instructions." "Cyan"
exit 1
}
Write-ColorOutput "✓ Docker is installed" "Green"
# Check if Docker is running
if (-not (Test-DockerRunning)) {
Write-ColorOutput "✗ Docker is not running" "Red"
Write-ColorOutput "Please start Docker and try again:" "Yellow"
Write-ColorOutput "1. Open Docker Desktop" "Cyan"
Write-ColorOutput "2. Wait for Docker to start" "Cyan"
Write-ColorOutput "3. Run this script again" "Cyan"
exit 1
}
Write-ColorOutput "" ""
# Check Docker Compose (built into Docker Desktop for Windows)
$composeTest = docker compose version 2>&1
if ($LASTEXITCODE -ne 0) {
Write-ColorOutput "✗ Docker Compose is not installed or not working properly" "Red"
Write-ColorOutput "Please ensure Docker Desktop is properly installed with Docker Compose" "Yellow"
exit 1
}
Write-ColorOutput "✓ Docker Compose is installed" "Green"
# Check curl or equivalent
if (-not (Test-Command curl) -and -not (Test-Command Invoke-WebRequest)) {
Write-ColorOutput "✗ Neither curl nor Invoke-WebRequest is available" "Red"
Write-ColorOutput "Please ensure you have PowerShell 3.0 or higher" "Yellow"
exit 1
}
Write-ColorOutput "✓ Download capabilities are available" "Green"
Write-ColorOutput "✓ All system requirements satisfied" "Green"
Write-Host ""
}
# Function to check if ports are available
function Check-Ports {
$port = 30080
Write-ColorOutput "Checking Port Availability" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
try {
# Check if port is in use
$portInUse = $false
$connections = Get-NetTCPConnection -ErrorAction SilentlyContinue | Where-Object {$_.LocalPort -eq $port}
if ($connections) {
$portInUse = $true
} else {
# Try to create a TCP listener as a secondary check
$listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Any, $port)
try {
$listener.Start()
$listener.Stop()
} catch {
$portInUse = $true
}
}
if ($portInUse) {
Write-ColorOutput "✗ Port $port is already in use" "Red"
Write-ColorOutput "Please free this port and try again" "Yellow"
exit 1
}
Write-ColorOutput "✓ Port $port is available" "Green"
Write-Host ""
} catch {
Write-ColorOutput "Warning: Could not reliably check port availability" "Yellow"
Write-Host ""
}
}
# Function to wait for service health
function Wait-ForService {
param($Service)
$maxAttempts = 30
$attempt = 1
while ($attempt -le $maxAttempts) {
$health = docker compose ps $Service | Select-String "healthy"
if ($health) {
return $true
}
Start-Sleep -Seconds 2
$attempt++
}
Write-ColorOutput "✗ Timeout waiting for $Service to be ready" "Red"
return $false
}
# Function to open browser
function Open-Browser {
$url = "http://localhost:30080"
Write-ColorOutput "Opening Browser" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
try {
Start-Process $url
Write-ColorOutput "✓ Browser opened successfully" "Green"
return $true
} catch {
try {
[System.Diagnostics.Process]::Start("cmd", "/c start $url")
Write-ColorOutput "✓ Browser opened successfully" "Green"
return $true
} catch {
Write-ColorOutput "Could not automatically open browser. Please visit:" "Yellow"
Write-ColorOutput "http://localhost:30080" "Green"
return $false
}
}
}
# Main installation function
function Install-CKX {
Print-Header
# Check requirements
Check-Requirements
# Check port
Check-Ports
# Create project directory
Write-ColorOutput "Setting Up Installation" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
Write-ColorOutput "Creating project directory..." "Yellow"
$installDir = "ck-x-simulator"
if (-not (Test-Path $installDir)) {
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
}
Set-Location $installDir
# Download docker-compose.yml
Write-ColorOutput "Downloading Docker Compose file..." "Yellow"
$composeUrl = "https://raw.githubusercontent.com/nishanb/ck-x/main/docker-compose.yml"
if (Test-Command curl) {
curl.exe -fsSL $composeUrl -o docker-compose.yml
} else {
Invoke-WebRequest -Uri $composeUrl -OutFile docker-compose.yml
}
if (-not (Test-Path "docker-compose.yml")) {
Write-ColorOutput "✗ Failed to download docker-compose.yml" "Red"
exit 1
}
Write-ColorOutput "✓ Docker Compose file downloaded" "Green"
# Pull images
Write-ColorOutput "Pulling Docker images..." "Yellow"
docker compose pull
if ($LASTEXITCODE -ne 0) {
Write-ColorOutput "✗ Failed to pull Docker images" "Red"
exit 1
}
Write-ColorOutput "✓ Docker images pulled successfully" "Green"
# Start services
Write-ColorOutput "Starting CK-X services..." "Yellow"
docker compose up -d
if ($LASTEXITCODE -ne 0) {
Write-ColorOutput "✗ Failed to start services" "Red"
exit 1
}
Write-ColorOutput "✓ Services started" "Green"
# Wait for services
Write-ColorOutput "Waiting for services to initialize..." "Yellow"
$webappReady = Wait-ForService "webapp"
if (-not $webappReady) { exit 1 }
$facilitatorReady = Wait-ForService "facilitator"
if (-not $facilitatorReady) { exit 1 }
Write-ColorOutput "✓ All services initialized successfully" "Green"
Write-Host ""
Write-ColorOutput "Installation Complete!" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
Write-ColorOutput "✓ CK-X Simulator has been installed successfully" "Green"
# Wait a bit for the service to be fully ready
Start-Sleep -Seconds 5
# Try to open browser
Open-Browser
Write-Host ""
Write-ColorOutput "Useful Commands" "Blue"
Write-ColorOutput "==============================================================" "Cyan"
Write-ColorOutput "CK-X Simulator has been installed in: " -NoNewline
Write-ColorOutput "$(Get-Location), run all below commands from this directory" "Green"
Write-ColorOutput "To stop CK-X: " -NoNewline
Write-ColorOutput "docker compose down" "Green"
Write-ColorOutput "To Restart CK-X: " -NoNewline
Write-ColorOutput "docker compose restart" "Green"
Write-ColorOutput "To clean up all containers and images: " -NoNewline
Write-ColorOutput "docker system prune -a" "Green"
Write-ColorOutput "To remove only CK-X images: " -NoNewline
Write-ColorOutput "docker compose down --rmi all" "Green"
Write-Host ""
Write-ColorOutput "Thank you for installing CK-X Simulator!" "Cyan"
}
# Check if running as Administrator
if (-not (Test-Administrator)) {
Write-Host "This script requires Administrator privileges. Please re-run as Administrator." -ForegroundColor Red
exit 1
}
# Run the installation
try {
Install-CKX
} catch {
Write-Host "An error occurred during installation: $_" -ForegroundColor Red
exit 1
}

233
scripts/install.sh Executable file
View File

@@ -0,0 +1,233 @@
#!/bin/bash
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# ASCII Art and Description
print_header() {
echo -e "${BLUE}"
echo "░█████╗░██╗░░██╗░░░░░░██╗░░██╗  ░██████╗██╗███╗░░░███╗██╗░░░██╗██╗░░░░░░█████╗░████████╗░█████╗░██████╗░"
echo "██╔══██╗██║░██╔╝░░░░░░╚██╗██╔╝  ██╔════╝██║████╗░████║██║░░░██║██║░░░░░██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗"
echo "██║░░╚═╝█████═╝░█████╗░╚███╔╝░  ╚█████╗░██║██╔████╔██║██║░░░██║██║░░░░░███████║░░░██║░░░██║░░██║██████╔╝"
echo "██║░░██╗██╔═██╗░╚════╝░██╔██╗░  ░╚═══██╗██║██║╚██╔╝██║██║░░░██║██║░░░░░██╔══██║░░░██║░░░██║░░██║██╔══██╗"
echo "╚█████╔╝██║░╚██╗░░░░░░██╔╝╚██╗  ██████╔╝██║██║░╚═╝░██║╚██████╔╝███████╗██║░░██║░░░██║░░░╚█████╔╝██║░░██║"
echo "░╚════╝░╚═╝░░╚═╝░░░░░░╚═╝░░╚═╝  ╚═════╝░╚═╝╚═╝░░░░░╚═╝░╚═════╝░╚══════╝╚═╝░░╚═╝░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝"
echo -e "${NC}"
echo -e "${CYAN}==============================================================${NC}"
echo -e "${CYAN}CK-X Simulator: Kubernetes Certification Exam Simulator${NC}"
echo -e "${CYAN}Practice in a realistic environment for CKA, CKAD, and more${NC}"
echo -e "${CYAN}==============================================================${NC}"
echo -e "${CYAN} Facing any issues? Please report at: https://github.com/nishanb/ck-x/issues${NC}"
echo
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to check if Docker is running
check_docker_running() {
if ! docker info >/dev/null 2>&1; then
echo -e "${RED}✗ Docker is not running${NC}"
echo -e "${YELLOW}Please start Docker and try again:${NC}"
echo -e "${CYAN}1. Open Docker Desktop${NC}"
echo -e "${CYAN}2. Wait for Docker to start${NC}"
echo -e "${CYAN}3. Run this script again${NC}"
exit 1
fi
echo
}
# Function to check system requirements
check_requirements() {
echo -e "${BLUE}Checking System Requirements${NC}"
echo -e "${CYAN}==============================================================${NC}"
# Check Docker
if ! command_exists docker; then
echo -e "${RED}✗ Docker is not installed${NC}"
echo -e "${YELLOW}Please install Docker first:${NC}"
echo -e "${CYAN}Visit https://docs.docker.com/get-docker/ for installation instructions${NC}"
exit 1
fi
echo -e "${GREEN}✓ Docker is installed${NC}"
# Check if Docker is running
check_docker_running
# Check Docker Compose
if ! command_exists docker compose; then
echo -e "${RED}✗ Docker Compose is not installed${NC}"
echo -e "${YELLOW}Please install Docker Compose:${NC}"
echo -e "${CYAN}Visit https://docs.docker.com/compose/install/ for installation instructions${NC}"
exit 1
fi
echo -e "${GREEN}✓ Docker Compose is installed${NC}"
# Check curl
if ! command_exists curl; then
echo -e "${RED}✗ curl is not installed${NC}"
echo -e "${YELLOW}Please install curl first${NC}"
exit 1
fi
echo -e "${GREEN}✓ curl is installed${NC}"
echo -e "${GREEN}✓ All system requirements satisfied${NC}"
echo
}
# Function to check if ports are available
check_ports() {
local port=30080
echo -e "${BLUE}Checking Port Availability${NC}"
echo -e "${CYAN}==============================================================${NC}"
# Try different methods to check port availability
if command_exists ss; then
# Using ss (modern alternative to netstat)
if ss -tuln | grep -q ":${port} "; then
echo -e "${RED}✗ Port ${port} is already in use${NC}"
echo -e "${YELLOW}Please free this port and try again${NC}"
exit 1
fi
elif command_exists lsof; then
# Using lsof
if lsof -i :${port} >/dev/null 2>&1; then
echo -e "${RED}✗ Port ${port} is already in use${NC}"
echo -e "${YELLOW}Please free this port and try again${NC}"
exit 1
fi
else
# Fallback: try to bind to the port
if timeout 1 bash -c ">/dev/tcp/localhost/${port}" 2>/dev/null; then
echo -e "${RED}✗ Port ${port} is already in use${NC}"
echo -e "${YELLOW}Please free this port and try again${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Port ${port} is available${NC}"
echo
}
# Function to wait for service health (modified to be silent)
wait_for_service() {
local service=$1
local max_attempts=30
local attempt=1
# No output headers here anymore
while [ $attempt -le $max_attempts ]; do
if docker compose ps $service | grep -q "healthy"; then
return 0
fi
# No progress dots
sleep 2
attempt=$((attempt + 1))
done
echo -e "${RED}✗ Timeout waiting for $service to be ready${NC}"
return 1
}
# Function to open browser
open_browser() {
local url="http://localhost:30080"
echo -e "${BLUE}Opening Browser${NC}"
echo -e "${CYAN}==============================================================${NC}"
# Try different methods to open browser
if command_exists xdg-open; then
# Linux with desktop environment
xdg-open $url 2>/dev/null && echo -e "${GREEN}✓ Browser opened successfully${NC}" && return 0
elif command_exists open; then
# macOS
open $url 2>/dev/null && echo -e "${GREEN}✓ Browser opened successfully${NC}" && return 0
elif command_exists python3; then
# Try Python as fallback
python3 -m webbrowser $url 2>/dev/null && echo -e "${GREEN}✓ Browser opened successfully${NC}" && return 0
elif command_exists python; then
# Try Python 2 as last resort
python -m webbrowser $url 2>/dev/null && echo -e "${GREEN}✓ Browser opened successfully${NC}" && return 0
fi
echo -e "${YELLOW}Could not automatically open browser. Please visit:${NC}"
echo -e "${GREEN}http://localhost:30080${NC}"
return 1
}
# Main installation process
main() {
print_header
# Check requirements
check_requirements
# Check port
check_ports
# Create project directory
echo -e "${BLUE}Setting Up Installation${NC}"
echo -e "${CYAN}==============================================================${NC}"
echo -e "${YELLOW}Creating project directory...${NC}"
mkdir -p ck-x-simulator && cd ck-x-simulator
# Download docker-compose.yml
echo -e "${YELLOW}Downloading Docker Compose file...${NC}"
curl -fsSL https://raw.githubusercontent.com/nishanb/ck-x/main/docker-compose.yml -o docker-compose.yml
if [ ! -f docker-compose.yml ]; then
echo -e "${RED}✗ Failed to download docker-compose.yml${NC}"
exit 1
fi
echo -e "${GREEN}✓ Docker Compose file downloaded${NC}"
# Pull images
echo -e "${YELLOW}Pulling Docker images...${NC}"
docker compose pull
echo -e "${GREEN}✓ Docker images pulled successfully${NC}"
# Start services
echo -e "${YELLOW}Starting CK-X services...${NC}"
docker compose up -d
echo -e "${GREEN}✓ Services started${NC}"
# Combined waiting message instead of individual service wait messages
echo -e "${YELLOW}Waiting for services to initialize...${NC}"
wait_for_service "webapp" || exit 1
wait_for_service "facilitator" || exit 1
echo -e "${GREEN}✓ All services initialized successfully${NC}"
echo -e "\n${BLUE}Installation Complete!${NC}"
echo -e "${CYAN}==============================================================${NC}"
echo -e "${GREEN}✓ CK-X Simulator has been installed successfully${NC}"
# Wait a bit for the service to be fully ready
sleep 5
# Try to open browser
open_browser
echo -e "\n${BLUE}Useful Commands${NC}"
echo -e "${CYAN}==============================================================${NC}"
echo -e "${YELLOW}CK-X Simulator has been installed in:${NC} ${GREEN}$(pwd)${NC}, run all below commands from this directory"
echo -e "${YELLOW}To stop CK-X ${GREEN}docker compose down${NC}"
echo -e "${YELLOW}To Restart CK-X:${NC} ${GREEN}docker compose restart${NC}"
echo -e "${YELLOW}To clean up all containers and images:${NC} ${GREEN}docker system prune -a${NC}"
echo -e "${YELLOW}To remove only CK-X images:${NC} ${GREEN}docker compose down --rmi all${NC}"
echo
echo -e "${CYAN}Thank you for installing CK-X Simulator!${NC}"
}
# Run main function
main