From b32845f6567b07a4ba132493a3a6fd2f59fa0231 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 5 Feb 2025 03:40:32 +0000 Subject: [PATCH] Adjust setup.sh to check existing DB and include ReadMe --- .../infrastructure/Build-Containers.ps1 | 81 --------- .../infrastructure/Manage-Containers.ps1 | 89 --------- ef-migration/infrastructure/ReadMe.md | 171 ++++++++++++++++++ .../infrastructure/sql-server/setup.sh | 29 +-- 4 files changed, 186 insertions(+), 184 deletions(-) delete mode 100644 ef-migration/infrastructure/Build-Containers.ps1 delete mode 100644 ef-migration/infrastructure/Manage-Containers.ps1 create mode 100644 ef-migration/infrastructure/ReadMe.md diff --git a/ef-migration/infrastructure/Build-Containers.ps1 b/ef-migration/infrastructure/Build-Containers.ps1 deleted file mode 100644 index 6799c1c..0000000 --- a/ef-migration/infrastructure/Build-Containers.ps1 +++ /dev/null @@ -1,81 +0,0 @@ -# Build-Containers.ps1 -param ( - [switch]$Force -) - -$ErrorActionPreference = "Stop" - -function Test-WSLRequirements { - Write-Host "Checking WSL requirements..." -ForegroundColor Yellow - - # Check if WSL is installed - $wslInstalled = Get-Command wsl.exe -ErrorAction SilentlyContinue - if (-not $wslInstalled) { - Write-Host "WSL is not installed. Please run the following commands as Administrator:" -ForegroundColor Red - Write-Host "wsl --install" -ForegroundColor Yellow - Write-Host "Then restart your computer and run:" -ForegroundColor Yellow - Write-Host "wsl --install -d Ubuntu" -ForegroundColor Yellow - return $false - } - - # Check if any distribution is installed - $wslDistros = wsl --list - if ($LASTEXITCODE -ne 0 -or $wslDistros -match "no installed distributions") { - Write-Host "No WSL distribution found. Please run the following command as Administrator:" -ForegroundColor Red - Write-Host "wsl --install -d Ubuntu" -ForegroundColor Yellow - return $false - } - - # Check if Docker Desktop is running - $dockerPs = Get-Process "Docker Desktop" -ErrorAction SilentlyContinue - if (-not $dockerPs) { - Write-Host "Docker Desktop is not running. Please start Docker Desktop and try again." -ForegroundColor Red - return $false - } - - Write-Host "WSL requirements checked successfully!" -ForegroundColor Green - return $true -} - -# Check WSL requirements -if (-not (Test-WSLRequirements)) { - exit 1 -} - -Write-Host "Starting Docker build process..." -ForegroundColor Green - -# Define container names -$containerName = "st-db" -$imageName = "st-database" - -# Get the current script directory -$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path -$sqlServerPath = Join-Path $scriptPath "sql-server" - -# Verify Dockerfile exists -if (-not (Test-Path (Join-Path $sqlServerPath "Dockerfile"))) { - Write-Host "Dockerfile not found in $sqlServerPath" -ForegroundColor Red - exit 1 -} - -try { - # Change to the SQL Server directory - Push-Location $sqlServerPath - - # Build the Docker image - Write-Host "Building Docker image '$imageName'..." -ForegroundColor Yellow - docker build -t $imageName . - - if ($LASTEXITCODE -eq 0) { - Write-Host "Docker image built successfully!" -ForegroundColor Green - } else { - Write-Host "Failed to build Docker image" -ForegroundColor Red - exit 1 - } -} catch { - Write-Host "An error occurred: $_" -ForegroundColor Red - exit 1 -} finally { - # Return to original directory - Pop-Location -} \ No newline at end of file diff --git a/ef-migration/infrastructure/Manage-Containers.ps1 b/ef-migration/infrastructure/Manage-Containers.ps1 deleted file mode 100644 index b5eab07..0000000 --- a/ef-migration/infrastructure/Manage-Containers.ps1 +++ /dev/null @@ -1,89 +0,0 @@ -# Manage-Containers.ps1 -param ( - [Parameter(Mandatory=$true)] - [ValidateSet('run', 'stop', 'remove')] - [string]$Action, - [switch]$Force -) - -$ErrorActionPreference = "Stop" - -# Define container names -$containerName = "st-db" -$imageName = "st-database" - -function Start-Container { - Write-Host "Starting container '$containerName'..." -ForegroundColor Yellow - - # Check if container exists and is stopped - $existingContainer = docker ps -a --filter "name=$containerName" --format "{{.Names}}" - if ($existingContainer) { - Write-Host "Container already exists, starting it..." -ForegroundColor Yellow - docker start $containerName - } else { - # Run new container - Write-Host "Creating and starting new container..." -ForegroundColor Yellow - docker run -d -p 1433:1433 --name $containerName $imageName - } - - if ($LASTEXITCODE -eq 0) { - Write-Host "Container started successfully!" -ForegroundColor Green - } else { - Write-Host "Failed to start container" -ForegroundColor Red - exit 1 - } -} - -function Stop-Container { - Write-Host "Stopping container '$containerName'..." -ForegroundColor Yellow - - # Check if container exists and is running - $runningContainer = docker ps --filter "name=$containerName" --format "{{.Names}}" - if ($runningContainer) { - docker stop $containerName - if ($LASTEXITCODE -eq 0) { - Write-Host "Container stopped successfully!" -ForegroundColor Green - } else { - Write-Host "Failed to stop container" -ForegroundColor Red - exit 1 - } - } else { - Write-Host "Container is not running" -ForegroundColor Yellow - } -} - -function Remove-Container { - Write-Host "Removing container '$containerName'..." -ForegroundColor Yellow - - # Stop container if running - $runningContainer = docker ps --filter "name=$containerName" --format "{{.Names}}" - if ($runningContainer) { - Write-Host "Stopping container first..." -ForegroundColor Yellow - docker stop $containerName - } - - # Remove container - $existingContainer = docker ps -a --filter "name=$containerName" --format "{{.Names}}" - if ($existingContainer) { - docker rm $containerName - if ($LASTEXITCODE -eq 0) { - Write-Host "Container removed successfully!" -ForegroundColor Green - } else { - Write-Host "Failed to remove container" -ForegroundColor Red - exit 1 - } - } else { - Write-Host "Container does not exist" -ForegroundColor Yellow - } -} - -try { - switch ($Action) { - 'run' { Start-Container } - 'stop' { Stop-Container } - 'remove' { Remove-Container } - } -} catch { - Write-Host "An error occurred: $_" -ForegroundColor Red - exit 1 -} \ No newline at end of file diff --git a/ef-migration/infrastructure/ReadMe.md b/ef-migration/infrastructure/ReadMe.md new file mode 100644 index 0000000..37cf0e7 --- /dev/null +++ b/ef-migration/infrastructure/ReadMe.md @@ -0,0 +1,171 @@ +# SQL Server Container Setup + +This repository contains a containerized SQL Server setup with initialization scripts and configuration options. + +## Prerequisites + +- Docker and Docker Compose installed on your system +- At least 2GB of available memory for SQL Server +- Port 1433 available on your host machine + +## Quick Start + +### Starting the Container + +With environment variables: +```bash +docker-compose -f docker-compose-infra.yml up -d +``` + +Without environment variables (uses defaults): +```bash +ACCEPT_EULA=Y MSSQL_PID=Express SA_PASSWORD=YourStrong@Passw0rd docker-compose -f docker-compose-infra.yml up -d +``` + +### Building the Container + +```bash +docker-compose -f docker-compose-infra.yml build +``` + +### Stopping and Removing the Container + +Stop the container: +```bash +docker-compose -f docker-compose-infra.yml down +``` + +Remove container and persistent volume: +```bash +docker-compose -f docker-compose-infra.yml down -v +``` + +## Configuration + +### Environment Variables + +| Variable | Description | Default Value | +|----------|-------------|---------------| +| SA_PASSWORD | SQL Server SA user password | YourStrong@Passw0rd | +| DROP_DATABASE | Flag to drop existing database on startup | false | +| ACCEPT_EULA | Accept SQL Server EULA | Y | +| MSSQL_PID | SQL Server edition | Express | + +### Ports + +- **1433**: SQL Server port (mapped to host machine) + +### Volumes + +- **sqlserver_data**: Persistent storage for SQL Server data +- **./logs**: Container logs directory + +## Setup Process + +The container uses `setup.sh` as its entry point, which handles the complete initialization process: + +### Startup Sequence + +1. Starts SQL Server in the background +2. Waits up to 50 seconds for SQL Server to be ready +3. Performs health checks using sqlcmd +4. Handles database initialization or reset based on environment variables + +### Database Management + +- Checks for existing database (`st-database`) +- Drops database if DROP_DATABASE=true +- Verifies database initialization status by checking for key tables +- Runs initialization scripts only if needed + +### Script Execution Order + +1. Runs `init.sql` to create the database and schemas +2. Executes all SQL scripts in the `schemas` directory +3. Handles GO statements automatically with proper spacing +4. Maintains container operation after setup + +### Error Handling + +- Provides detailed logging for each step +- Continues despite non-critical script errors +- Exits with proper status codes for critical failures + +## Database Initialization + +The container automatically: + +1. Initializes SQL Server +2. Creates the database 'st-database' if it doesn't exist +3. Creates the following schemas: + - fp + - fw + - int + - ob + +### Database Reset + +To reset the database: +```bash +DROP_DATABASE=true docker-compose -f docker-compose-infra.yml up -d +``` + +## Extract Scripts + +The container includes several utility scripts for managing database objects: + +### extract_tables.sh +- Extracts table definitions into separate files +- Usage: `./extract_tables.sh ` +- Output directory: `sql_objects/tables` + +### extract_constraints.sh +- Extracts table constraints and foreign keys +- Usage: `./extract_constraints.sh ` +- Output directories: + - `sql_objects/constraints` + - `sql_objects/foreign_keys` + +### extract_indexes.sh +- Extracts index definitions +- Usage: `./extract_indexes.sh ` +- Output directories: + - `sql_objects/indexes/clustered` + - `sql_objects/indexes/nonclustered` + - `sql_objects/indexes/unique_clustered` + +### extract_views.sh +- Extracts view definitions +- Usage: `./extract_views.sh ` +- Output directory: `sql_objects/views` + +### extract_procedures.sh +- Extracts stored procedure definitions +- Usage: `./extract_procedures.sh ` +- Output directory: `sql_objects/procedures` + +## Resource Limits + +The container is configured with the following resource constraints: + +- Memory: 2GB minimum (required for SQL Server) +- CPU: Limited to 1 core, with 0.25 core reserved + +## Health Checks + +The container includes a health check that: +- Runs every 10 seconds +- Verifies SQL Server connectivity +- Allows 10 retries before marking as unhealthy +- Has a 10-second startup grace period + +## Troubleshooting + +If the container fails to start: +1. Ensure at least 2GB of memory is available +2. Check the logs directory for detailed error messages +3. Verify the port 1433 is not in use by another service +4. Check SQL Server logs: `docker logs sql1` +5. Verify SQL Server is running: `docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -Q "SELECT @@VERSION"` + +The container will automatically restart unless explicitly stopped. \ No newline at end of file diff --git a/ef-migration/infrastructure/sql-server/setup.sh b/ef-migration/infrastructure/sql-server/setup.sh index 6e0245c..e194c9d 100644 --- a/ef-migration/infrastructure/sql-server/setup.sh +++ b/ef-migration/infrastructure/sql-server/setup.sh @@ -40,20 +40,21 @@ fi # Check if database already exists and has tables echo "Checking if database is already initialized..." -DB_INITIALIZED=$(sqlcmd -S localhost -U sa -P $SA_PASSWORD -Q " -IF EXISTS ( - SELECT 1 - FROM sys.databases - WHERE name = 'st-database' - AND EXISTS ( - SELECT 1 - FROM st-database.sys.tables - WHERE name = 'AMAssumptionView' - ) -) -SELECT 1 -ELSE -SELECT 0" -h -1) +echo "Checking if database is already initialized..." +DB_INITIALIZED=$(sqlcmd -S localhost -U sa -P $SA_PASSWORD -h -1 -Q " +DECLARE @DBExists BIT = 0; + +IF EXISTS (SELECT 1 FROM sys.databases WHERE name = 'st-database') +BEGIN + -- Set the context to the target database + EXEC('USE [st-database]; + IF EXISTS (SELECT 1 FROM sys.tables WHERE name = ''AMAssumptionView'') + BEGIN + SET @DBExists = 1; + END'); +END; + +SELECT @DBExists;") if [ "$DB_INITIALIZED" = "1" ]; then echo "Database st-database already exists and is initialized. Skipping setup."