Last active
September 24, 2025 13:56
-
-
Save JKamsker/66bda2c1196276339a479ea1857cf606 to your computer and use it in GitHub Desktop.
codex-web-installscripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Parameterizable .NET setup script with parallel execution, smart caching, and tool integration. | |
| # install with eg: curl -sSL ... | bash -s -- -v 7.0 -t "dotnet-ef,dotnet-aspnet-codegenerator,dotnet-try" | |
| set -e | |
| # --- Default Configuration --- | |
| DOTNET_VERSION="8.0" # Default .NET version | |
| APP_DIR="/app" # Default application directory | |
| # Default global tools. If a tool name is passed without a version, | |
| # it will be automatically pinned to the major .NET version being installed (e.g., "dotnet-ef" -> "dotnet-ef:8.*"). | |
| DEFAULT_TOOLS=( | |
| "dotnet-ef" | |
| "dotnet-aspnet-codegenerator" | |
| "dotnet-dev-certs" | |
| ) | |
| GLOBAL_TOOLS=() # This will be populated based on user input or defaults | |
| # --- Argument Parsing --- | |
| while [[ "$#" -gt 0 ]]; do | |
| case $1 in | |
| -v|--version) DOTNET_VERSION="$2"; shift ;; | |
| -a|--app-dir) APP_DIR="$2"; shift ;; | |
| -t|--tools) IFS=',' read -r -a GLOBAL_TOOLS <<< "$2"; shift ;; | |
| -h|--help) | |
| echo "Usage: $0 [-v version] [-a app_dir] [-t tool1,tool2:version,...]" | |
| echo " -v, --version .NET version to install (e.g., 8.0, 7.0, 6.0). Default: 8.0" | |
| echo " -a, --app-dir Application directory for 'dotnet restore'. Default: /app" | |
| echo " -t, --tools Comma-separated list of global tools to install." | |
| echo " (e.g., \"dotnet-ef,some-tool:1.2.3\")" | |
| exit 0 | |
| ;; | |
| *) echo "Unknown parameter passed: $1"; exit 1 ;; | |
| esac | |
| shift | |
| done | |
| # --- Final Configuration Setup --- | |
| DOTNET_INSTALL_DIR="$HOME/.dotnet" | |
| DOTNET_CHANNEL="$DOTNET_VERSION" # The channel typically matches the major.minor version | |
| DOTNET_MAJOR_VERSION=$(echo "$DOTNET_VERSION" | cut -d. -f1) | |
| # If no custom tools were provided, use the defaults | |
| if [ ${#GLOBAL_TOOLS[@]} -eq 0 ]; then | |
| GLOBAL_TOOLS=("${DEFAULT_TOOLS[@]}") | |
| fi | |
| # Auto-pin tool versions if not specified | |
| for i in "${!GLOBAL_TOOLS[@]}"; do | |
| tool_spec="${GLOBAL_TOOLS[i]}" | |
| if [[ "$tool_spec" != *":"* ]]; then | |
| # If no version is specified, pin it to the major .NET version | |
| GLOBAL_TOOLS[i]="${tool_spec}:${DOTNET_MAJOR_VERSION}.*" | |
| fi | |
| done | |
| # --- Helper Functions --- | |
| command_exists() { command -v "$1" >/dev/null 2>&1; } | |
| add_to_path_if_missing() { | |
| local path_entry="$1" | |
| local bashrc_path="$HOME/.bashrc" | |
| if ! grep -qF "$path_entry" "$bashrc_path" 2>/dev/null; then | |
| echo "$path_entry" >> "$bashrc_path" | |
| fi | |
| } | |
| setup_current_path() { | |
| export DOTNET_ROOT="$DOTNET_INSTALL_DIR" | |
| export PATH="$PATH:$DOTNET_ROOT:$HOME/.dotnet/tools" | |
| } | |
| setup_project_deps() { | |
| if [ -d "$APP_DIR" ]; then | |
| ( | |
| cd "$APP_DIR" | |
| if find . -maxdepth 2 -name "*.sln" | head -1 | read -r sln_file; then | |
| echo "Restoring solution packages for $sln_file..." | |
| dotnet restore "$sln_file" --verbosity quiet | |
| elif find . -maxdepth 2 -name "*.csproj" -o -name "*.fsproj" -o -name "*.vbproj" | head -1 | read -r proj_file; then | |
| echo "Restoring project packages for $proj_file..." | |
| dotnet restore "$proj_file" --verbosity quiet | |
| else | |
| echo "ℹ️ No .NET project or solution files found in $APP_DIR" | |
| fi | |
| ) & | |
| echo $! | |
| else | |
| echo "0" | |
| fi | |
| } | |
| install_global_tools() { | |
| echo "Installing/updating .NET global tools..." | |
| local pids=() | |
| for tool_spec in "${GLOBAL_TOOLS[@]}"; do | |
| local tool_name="${tool_spec%%:*}" | |
| local tool_version="${tool_spec##*:}" | |
| local version_arg="" | |
| if [[ "$tool_name" != "$tool_version" ]]; then | |
| version_arg="--version $tool_version" | |
| fi | |
| echo "Installing/updating $tool_spec..." | |
| # Use 'update' which installs if not present, making it idempotent | |
| dotnet tool update --global "$tool_name" $version_arg --verbosity quiet & | |
| pids+=($!) | |
| done | |
| for pid in "${pids[@]}"; do wait "$pid" 2>/dev/null || true; done | |
| echo "✅ Global tools setup complete" | |
| } | |
| # --- Main Execution Logic --- | |
| echo "🚀 Starting .NET setup for version $DOTNET_VERSION..." | |
| echo " - App Directory: $APP_DIR" | |
| echo " - Global Tools: ${GLOBAL_TOOLS[*]}" | |
| if command_exists dotnet && dotnet --version >/dev/null 2>&1; then | |
| INSTALLED_VERSION=$(dotnet --version) | |
| if [[ "$INSTALLED_VERSION" == "$DOTNET_VERSION"* ]]; then | |
| echo "✅ .NET version $DOTNET_VERSION is already installed." | |
| setup_current_path | |
| install_global_tools & | |
| TOOLS_PID=$! | |
| PROJECT_PID=$(setup_project_deps) | |
| wait $TOOLS_PID 2>/dev/null || true | |
| if [ "$PROJECT_PID" -ne 0 ]; then wait $PROJECT_PID 2>/dev/null || true; fi | |
| echo "✅ Script execution complete (.NET was already set up)!" | |
| exit 0 | |
| else | |
| echo "Found different .NET version ($INSTALLED_VERSION). Installing $DOTNET_VERSION." | |
| fi | |
| fi | |
| # --- Parallel Setup: System Dependencies & .NET Installation Script --- | |
| echo "Setting up system dependencies and downloading .NET installer..." | |
| { | |
| export DEBIAN_FRONTEND=noninteractive | |
| sudo -E apt-get update -qq | |
| sudo -E apt-get install -y -qq --no-install-recommends \ | |
| wget ca-certificates git curl libc6 libgcc1 libgssapi-krb5-2 libicu-dev libssl-dev libstdc++6 zlib1g || { | |
| echo "Warning: Some system packages may have failed to install." | |
| } | |
| echo "✅ System dependencies installed" | |
| } & DEPS_PID=$! | |
| TEMP_DIR=$(mktemp -d) | |
| { | |
| cd "$TEMP_DIR" && wget -q https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && chmod +x dotnet-install.sh | |
| echo "✅ .NET installer downloaded" | |
| } & DOWNLOAD_PID=$! | |
| wait $DEPS_PID && wait $DOWNLOAD_PID | |
| # --- Install .NET --- | |
| echo "Installing .NET $DOTNET_VERSION..." | |
| ARCH=$(dpkg --print-architecture) | |
| case $ARCH in | |
| amd64) DOTNET_ARCH="x64" ;; | |
| arm64) DOTNET_ARCH="arm64" ;; | |
| *) echo "Unsupported architecture: $ARCH"; exit 1 ;; | |
| esac | |
| "$TEMP_DIR/dotnet-install.sh" --channel "$DOTNET_CHANNEL" --install-dir "$DOTNET_INSTALL_DIR" --architecture "$DOTNET_ARCH" --no-path | |
| rm -rf "$TEMP_DIR" | |
| # --- Setup PATH and Environment --- | |
| echo "Configuring PATH and environment variables..." | |
| add_to_path_if_missing "export DOTNET_ROOT=\"$DOTNET_INSTALL_DIR\"" | |
| add_to_path_if_missing 'export PATH="$PATH:$DOTNET_ROOT:$HOME/.dotnet/tools"' | |
| add_to_path_if_missing "export DOTNET_CLI_TELEMETRY_OPTOUT=1" | |
| add_to_path_if_missing "export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1" | |
| add_to_path_if_missing "export DOTNET_NOLOGO=1" | |
| setup_current_path # For the current session | |
| export DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 DOTNET_NOLOGO=1 | |
| if ! command_exists dotnet; then echo "❌ Error: 'dotnet' command not found after installation."; exit 1; fi | |
| echo "✅ .NET $(dotnet --version) installed successfully" | |
| # --- Post-Install Configuration --- | |
| echo "Running post-install tasks..." | |
| install_global_tools & | |
| TOOLS_PID=$! | |
| PROJECT_PID=$(setup_project_deps) | |
| wait $TOOLS_PID 2>/dev/null || true | |
| if [ "$PROJECT_PID" -ne 0 ]; then wait $PROJECT_PID 2>/dev/null || true; fi | |
| echo "✅ .NET $DOTNET_VERSION setup complete!" | |
| echo "Installed components:" | |
| echo " - .NET SDK: $(dotnet --version)" | |
| echo " - Global Tools: ${GLOBAL_TOOLS[*]}" | |
| echo "💡 Run 'source ~/.bashrc' or restart your shell to apply PATH changes permanently." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Optimized .NET 6 setup script with parallel execution, smart caching, EF integration, and Git CLI | |
| set -e | |
| # Configuration | |
| DOTNET_INSTALL_DIR="$HOME/.dotnet" | |
| APP_DIR="/app" # Default application directory in Jules VM | |
| DOTNET_VERSION="6.0" | |
| DOTNET_CHANNEL="6.0" | |
| # Global tools to install, with version pinning for compatibility with .NET 6 | |
| # Format: "tool-name:version-string" or just "tool-name" for latest | |
| GLOBAL_TOOLS=( | |
| "dotnet-ef:6.*" | |
| "dotnet-aspnet-codegenerator:6.*" | |
| "dotnet-dev-certs" | |
| ) | |
| # Function to check if command exists | |
| command_exists() { | |
| command -v "$1" >/dev/null 2>&1 | |
| } | |
| # Function to add PATH to bashrc only if not present | |
| add_to_path_if_missing() { | |
| local path_entry="$1" | |
| local bashrc_path="$HOME/.bashrc" | |
| if ! grep -qF "$path_entry" "$bashrc_path" 2>/dev/null; then | |
| echo "$path_entry" >> "$bashrc_path" | |
| echo "Added to PATH: $path_entry" | |
| fi | |
| } | |
| # Function to setup PATH for current session | |
| setup_current_path() { | |
| export PATH="$PATH:$DOTNET_INSTALL_DIR:$HOME/.dotnet/tools" | |
| export DOTNET_ROOT="$DOTNET_INSTALL_DIR" | |
| } | |
| echo "Starting optimized .NET 6 and Git setup..." | |
| # Function to setup project dependencies | |
| setup_project_deps() { | |
| if [ -d "$APP_DIR" ]; then | |
| ( | |
| cd "$APP_DIR" | |
| # Look for solution files first, then project files | |
| if find . -maxdepth 2 -name "*.sln" | head -1 | read -r sln_file; then | |
| echo "Found solution file: $sln_file" | |
| echo "Restoring solution packages..." | |
| dotnet restore "$sln_file" --verbosity quiet | |
| echo "✅ Solution packages restored" | |
| elif find . -maxdepth 2 -name "*.csproj" -o -name "*.fsproj" -o -name "*.vbproj" | head -1 | read -r proj_file; then | |
| echo "Found project file: $proj_file" | |
| echo "Restoring project packages..." | |
| dotnet restore "$proj_file" --verbosity quiet | |
| echo "✅ Project packages restored" | |
| else | |
| echo "ℹ️ No .NET project or solution files found" | |
| fi | |
| ) & | |
| echo $! # Return PID of background process | |
| else | |
| echo "0" # Indicate no project directory | |
| fi | |
| } | |
| # Function to install global tools (UPDATED LOGIC) | |
| install_global_tools() { | |
| echo "Installing .NET global tools..." | |
| local pids=() | |
| for tool_spec in "${GLOBAL_TOOLS[@]}"; do | |
| # Parse tool name and version from "name:version" format | |
| local tool_name="${tool_spec%%:*}" | |
| local tool_version="${tool_spec##*:}" | |
| local version_arg="" | |
| if [[ "$tool_name" != "$tool_version" ]]; then | |
| version_arg="--version $tool_version" | |
| fi | |
| if ! dotnet tool list -g | grep -q "$tool_name"; then | |
| echo "Installing $tool_spec..." | |
| # Note: The $version_arg is intentionally not quoted to allow it to be empty | |
| dotnet tool install --global "$tool_name" $version_arg --verbosity quiet & | |
| pids+=($!) | |
| else | |
| echo "✅ $tool_name already installed" | |
| fi | |
| done | |
| # Wait for all tool installations to complete | |
| for pid in "${pids[@]}"; do | |
| wait "$pid" 2>/dev/null || true | |
| done | |
| echo "✅ Global tools installation complete" | |
| } | |
| # Check if .NET is already installed and working | |
| if command_exists dotnet && dotnet --version >/dev/null 2>&1; then | |
| INSTALLED_VERSION=$(dotnet --version | cut -d. -f1-2) | |
| if [ "$INSTALLED_VERSION" = "$DOTNET_VERSION" ]; then | |
| echo "✅ .NET $DOTNET_VERSION already installed and working" | |
| setup_current_path | |
| install_global_tools & | |
| TOOLS_PID=$! | |
| if [ -d "$APP_DIR" ]; then | |
| echo "Setting up project dependencies..." | |
| PROJECT_PID=$(setup_project_deps) | |
| if [ "$PROJECT_PID" -ne 0 ]; then | |
| wait $PROJECT_PID 2>/dev/null || true | |
| fi | |
| fi | |
| wait $TOOLS_PID 2>/dev/null || true | |
| echo "✅ All dependencies setup complete" | |
| echo "✅ Script execution complete (.NET was already set up)!" | |
| exit 0 | |
| else | |
| echo "Different .NET version found ($INSTALLED_VERSION), will install .NET $DOTNET_VERSION" | |
| fi | |
| fi | |
| # --- Parallel Setup: System Dependencies & .NET Installation --- | |
| echo "Setting up system dependencies and .NET in parallel..." | |
| { | |
| echo "Installing system dependencies..." | |
| export DEBIAN_FRONTEND=noninteractive | |
| sudo -E apt-get update -qq | |
| sudo -E apt-get install -y -qq --no-install-recommends \ | |
| -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \ | |
| wget ca-certificates apt-transport-https software-properties-common \ | |
| libc6 libgcc1 libgssapi-krb5-2 libicu-dev libssl-dev libstdc++6 zlib1g \ | |
| curl git || { | |
| echo "Warning: Some packages may have failed to install, continuing..." | |
| } | |
| echo "✅ System dependencies installation complete" | |
| } & | |
| DEPS_PID=$! | |
| ARCH=$(dpkg --print-architecture) | |
| case $ARCH in | |
| amd64) DOTNET_ARCH="x64" ;; | |
| arm64) DOTNET_ARCH="arm64" ;; | |
| armhf) DOTNET_ARCH="arm" ;; | |
| *) echo "Unsupported architecture: $ARCH"; exit 1 ;; | |
| esac | |
| TEMP_DIR=$(mktemp -d) | |
| { | |
| echo "Downloading .NET $DOTNET_VERSION..." | |
| cd "$TEMP_DIR" | |
| wget -q https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh | |
| chmod +x dotnet-install.sh | |
| echo "✅ .NET download preparation complete" | |
| } & | |
| DOWNLOAD_PID=$! | |
| wait $DEPS_PID | |
| wait $DOWNLOAD_PID | |
| # --- Install .NET --- | |
| echo "Installing .NET $DOTNET_VERSION..." | |
| cd "$TEMP_DIR" | |
| ./dotnet-install.sh --channel $DOTNET_CHANNEL --install-dir "$DOTNET_INSTALL_DIR" --architecture "$DOTNET_ARCH" --verbose | |
| cd / | |
| rm -rf "$TEMP_DIR" | |
| # --- Setup PATH --- | |
| echo "Configuring PATH..." | |
| add_to_path_if_missing "export PATH=\"\$PATH:$DOTNET_INSTALL_DIR\"" | |
| add_to_path_if_missing "export PATH=\"\$PATH:\$HOME/.dotnet/tools\"" | |
| add_to_path_if_missing "export DOTNET_ROOT=\"$DOTNET_INSTALL_DIR\"" | |
| setup_current_path | |
| if ! command_exists dotnet; then | |
| echo "❌ Error: .NET command not found after installation" | |
| exit 1 | |
| fi | |
| echo "✅ .NET $(dotnet --version) installed successfully" | |
| # --- .NET Configuration --- | |
| echo "Configuring .NET..." | |
| { | |
| export DOTNET_CLI_TELEMETRY_OPTOUT=1 | |
| export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 | |
| export DOTNET_NOLOGO=1 | |
| add_to_path_if_missing "export DOTNET_CLI_TELEMETRY_OPTOUT=1" | |
| add_to_path_if_missing "export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1" | |
| add_to_path_if_missing "export DOTNET_NOLOGO=1" | |
| } & | |
| { | |
| echo "Warming up .NET CLI..." | |
| dotnet --info >/dev/null 2>&1 | |
| echo "✅ .NET CLI warmed up" | |
| } & | |
| install_global_tools & | |
| TOOLS_PID=$! | |
| if [ -d "$APP_DIR" ]; then | |
| echo "App directory found, will restore packages after .NET setup..." | |
| NEED_DEPS=true | |
| else | |
| echo "No app directory found at $APP_DIR" | |
| NEED_DEPS=false | |
| fi | |
| wait | |
| if [ "$NEED_DEPS" = true ]; then | |
| echo "Installing project dependencies..." | |
| PROJECT_PID=$(setup_project_deps) | |
| if [ "$PROJECT_PID" -ne 0 ]; then | |
| wait $PROJECT_PID 2>/dev/null || true | |
| fi | |
| if [ -d "$APP_DIR" ]; then | |
| ( | |
| cd "$APP_DIR" | |
| if find . -name "*.csproj" -exec grep -l "Microsoft.EntityFrameworkCore" {} \; | head -1 >/dev/null 2>&1; then | |
| echo "Entity Framework detected, verifying EF tools..." | |
| if ! command_exists dotnet-ef; then | |
| echo "Installing Entity Framework tools for .NET 6..." | |
| # CORRECTED FALLBACK INSTALL | |
| dotnet tool install --global dotnet-ef --version "6.*" --verbosity quiet | |
| else | |
| echo "✅ Entity Framework tools ready" | |
| fi | |
| fi | |
| ) | |
| fi | |
| fi | |
| wait $TOOLS_PID 2>/dev/null || true | |
| echo "✅ Optimized .NET 6 and Git setup complete!" | |
| echo "" | |
| echo "Installed components:" | |
| echo " - .NET $(dotnet --version)" | |
| echo " - Git CLI" | |
| echo " - Entity Framework Core tools" | |
| echo " - ASP.NET Core code generator" | |
| echo " - Development certificates tool" | |
| echo "" | |
| echo "Run 'source ~/.bashrc' or restart your shell to use the tools in new sessions." | |
| echo "" | |
| echo "Quick start commands:" | |
| echo " dotnet --version # Check .NET version" | |
| echo " git --version # Check Git version" | |
| echo " dotnet new --list # List project templates" | |
| echo " dotnet ef --version # Check EF tools version" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| SA_PASSWORD="${SA_PASSWORD:-ChangeMe_SA_Th!sIsStr0ng}" | |
| APP_LOGIN="${APP_LOGIN:-myapp_login}" | |
| APP_PASSWORD="${APP_PASSWORD:-ChangeMe_App_Th!sIsStr0ng}" | |
| APP_DATABASE="${APP_DATABASE:-MyAppDb}" | |
| MSSQL_PID="${MSSQL_PID:-Developer}" | |
| ARCH="$(dpkg --print-architecture)" | |
| KEYRING="/usr/share/keyrings/microsoft-prod.gpg" | |
| apt-get update -y | |
| apt-get install -y --no-install-recommends \ | |
| curl ca-certificates gnupg locales procps iproute2 \ | |
| libunwind8 libuuid1 libkrb5-3 libgssapi-krb5-2 lsof \ | |
| software-properties-common | |
| install -d -m 0755 /usr/share/keyrings | |
| if [[ ! -f "${KEYRING}" ]]; then | |
| curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \ | |
| | gpg --dearmor \ | |
| | tee "${KEYRING}" > /dev/null | |
| fi | |
| cat <<REPO >/etc/apt/sources.list.d/mssql-server-preview.list | |
| deb [arch=${ARCH} signed-by=${KEYRING}] https://packages.microsoft.com/ubuntu/22.04/mssql-server-preview jammy main | |
| REPO | |
| cat <<REPO >/etc/apt/sources.list.d/jammy-ldap.list | |
| deb [arch=${ARCH}] http://archive.ubuntu.com/ubuntu jammy main | |
| deb [arch=${ARCH}] http://security.ubuntu.com/ubuntu jammy-security main | |
| REPO | |
| cat <<REPO >/etc/apt/sources.list.d/msprod.list | |
| deb [arch=${ARCH} signed-by=${KEYRING}] https://packages.microsoft.com/ubuntu/22.04/prod jammy main | |
| REPO | |
| cat <<'PREF' >/etc/apt/preferences.d/mssql-libldap.pref | |
| Package: libldap-2.5-0 libldap-common | |
| Pin: release n=jammy-security | |
| Pin-Priority: 1001 | |
| Package: libldap-2.5-0 libldap-common | |
| Pin: release n=jammy | |
| Pin-Priority: 1000 | |
| Package: libldap-2.5-0 libldap-common | |
| Pin: release n=noble | |
| Pin-Priority: -1 | |
| PREF | |
| apt-get update -y | |
| apt-get install -y --allow-downgrades libldap-2.5-0/jammy-security libldap-common/jammy-security | |
| ACCEPT_EULA=Y apt-get install -y mssql-server msodbcsql18 mssql-tools18 unixodbc unixodbc-dev | |
| if [[ ! -f /var/opt/mssql/data/master.mdf ]]; then | |
| ACCEPT_EULA=Y MSSQL_SA_PASSWORD="${SA_PASSWORD}" MSSQL_PID="${MSSQL_PID}" \ | |
| /opt/mssql/bin/mssql-conf -n setup || true | |
| else | |
| echo "SQL Server data directory detected; resetting SA password to the configured value." | |
| chown -R mssql:mssql /var/opt/mssql | |
| ACCEPT_EULA=Y MSSQL_SA_PASSWORD="${SA_PASSWORD}" \ | |
| /opt/mssql/bin/mssql-conf -n set-sa-password || true | |
| fi | |
| cat <<MSG | |
| ✅ SQL Server packages installed. | |
| To start the engine in this container run: | |
| ACCEPT_EULA=Y /opt/mssql/bin/sqlservr | |
| Once the engine is running you can connect with: | |
| /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P '${SA_PASSWORD}' -C | |
| MSG | |
| if [[ -n "${APP_DATABASE}" ]] && [[ -n "${APP_LOGIN}" ]] && [[ -n "${APP_PASSWORD}" ]]; then | |
| echo "Preparing optional application database bootstrap scripts in /var/opt/mssql." | |
| cat <<SQL >/var/opt/mssql/create-app-database.sql | |
| :setvar AppDb ${APP_DATABASE} | |
| :setvar AppLogin ${APP_LOGIN} | |
| :setvar AppPassword ${APP_PASSWORD} | |
| IF DB_ID(N'\$(AppDb)') IS NULL | |
| BEGIN | |
| DECLARE @sql nvarchar(max) = N'CREATE DATABASE ' + QUOTENAME(N'\$(AppDb)'); | |
| EXEC (@sql); | |
| END | |
| GO | |
| IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'\$(AppLogin)') | |
| BEGIN | |
| DECLARE @sql nvarchar(max) = N'CREATE LOGIN ' + QUOTENAME(N'\$(AppLogin)') | |
| + N' WITH PASSWORD = ''' + REPLACE(N'\$(AppPassword)', '''', '''''') + N''', CHECK_POLICY = ON, CHECK_EXPIRATION = OFF'; | |
| EXEC (@sql); | |
| END | |
| GO | |
| USE \$(AppDb); | |
| GO | |
| IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = N'\$(AppLogin)') | |
| BEGIN | |
| DECLARE @sql nvarchar(max) = N'CREATE USER ' + QUOTENAME(N'\$(AppLogin)') + N' FOR LOGIN ' + QUOTENAME(N'\$(AppLogin)'); | |
| EXEC (@sql); | |
| END | |
| GO | |
| IF NOT EXISTS ( | |
| SELECT 1 | |
| FROM sys.database_role_members drm | |
| JOIN sys.database_principals rp ON rp.principal_id = drm.role_principal_id AND rp.name = N'db_owner' | |
| JOIN sys.database_principals mp ON mp.principal_id = drm.member_principal_id AND mp.name = N'\$(AppLogin)' | |
| ) | |
| BEGIN | |
| DECLARE @sql nvarchar(max) = N'ALTER ROLE db_owner ADD MEMBER ' + QUOTENAME(N'\$(AppLogin)'); | |
| EXEC (@sql); | |
| END | |
| GO | |
| SQL | |
| cat <<INSTR | |
| To apply the optional database bootstrap once SQL Server is running: | |
| /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P '${SA_PASSWORD}' -C -i /var/opt/mssql/create-app-database.sql | |
| INSTR | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment