# Module: Installer Generation # Purpose: Generates platform-specific installation scripts and packages # Dependencies: std log use std log # Create shell installers for different platforms export def create_shell_installers [ installer_config: record analysis_result: record ] { log info "Creating shell installers..." let start_time = (date now) let result = (do { mut created_installers = [] for platform in $installer_config.platforms { match $platform { "linux" | "macos" => { let installer_result = create_unix_shell_installer $platform $installer_config $analysis_result if $installer_result.status == "success" { $created_installers = ($created_installers | append $installer_result) } } "windows" => { let installer_result = create_windows_batch_installer $installer_config $analysis_result if $installer_result.status == "success" { $created_installers = ($created_installers | append $installer_result) } } _ => { log warning $"Unsupported platform for shell installer: ($platform)" } } } { status: "success" installers_created: ($created_installers | length) created_installers: $created_installers duration: ((date now) - $start_time) } } | complete) if $result.exit_code != 0 { { status: "failed" reason: $result.stderr duration: ((date now) - $start_time) } } else { $result.stdout } } # Create Unix shell installer export def create_unix_shell_installer [ platform: string installer_config: record analysis_result: record ] { let version = $analysis_result.version_info.version let components = $analysis_result.components let requirements = $analysis_result.requirements let installer_content = $"#!/bin/bash # Provisioning System Installer # Platform: ($platform) # Version: ($version) set -e # Colors for output RED='\\033[0;31m' GREEN='\\033[0;32m' YELLOW='\\033[1;33m' NC='\\033[0m' # No Color # Configuration INSTALL_USER=\"($requirements.system_user)\" INSTALL_GROUP=\"($requirements.system_group)\" SERVICE_NAME=\"provisioning\" # Installation directories BIN_DIR=\"/usr/local/bin\" LIB_DIR=\"/usr/local/lib/provisioning\" CONFIG_DIR=\"/etc/provisioning\" DATA_DIR=\"/var/lib/provisioning\" LOG_DIR=\"/var/log/provisioning\" # Functions log_info() { echo -e \"${GREEN}[INFO]${NC} $1\" } log_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\" } log_error() { echo -e \"${RED}[ERROR]${NC} $1\" } check_root() { if [[ $EUID -ne 0 ]]; then log_error \"This script must be run as root (use sudo)\" exit 1 fi } create_user() { if ! id \"$INSTALL_USER\" >/dev/null 2>&1; then log_info \"Creating user: $INSTALL_USER\" useradd -r -s /bin/false -m -d \"$DATA_DIR\" \"$INSTALL_USER\" usermod -a -G \"$INSTALL_GROUP\" \"$INSTALL_USER\" 2>/dev/null || true else log_info \"User $INSTALL_USER already exists\" fi } create_directories() { log_info \"Creating directories...\" mkdir -p \"$BIN_DIR\" \"$LIB_DIR\" \"$CONFIG_DIR\" \"$DATA_DIR\" \"$LOG_DIR\" # Set ownership chown -R \"$INSTALL_USER:$INSTALL_GROUP\" \"$DATA_DIR\" \"$LOG_DIR\" chmod 755 \"$DATA_DIR\" \"$LOG_DIR\" } install_binaries() { log_info \"Installing binaries...\" if [[ -d \"platform\" ]]; then cp platform/* \"$BIN_DIR/\" chmod +x \"$BIN_DIR\"/provisioning-* elif [[ -d \"core/bin\" ]]; then cp core/bin/* \"$BIN_DIR/\" chmod +x \"$BIN_DIR\"/provisioning* else log_error \"No binaries found to install\" return 1 fi } install_libraries() { if [[ -d \"core\" ]]; then log_info \"Installing core libraries...\" cp -r core/* \"$LIB_DIR/\" chown -R root:root \"$LIB_DIR\" find \"$LIB_DIR\" -type f -name \"*.nu\" -exec chmod 644 {} \\; fi } install_configuration() { if [[ -d \"config\" ]]; then log_info \"Installing configuration...\" cp config/*.toml \"$CONFIG_DIR/\" 2>/dev/null || true cp config/*.template \"$CONFIG_DIR/\" 2>/dev/null || true # Set secure permissions on config files chown -R root:\"$INSTALL_GROUP\" \"$CONFIG_DIR\" chmod 755 \"$CONFIG_DIR\" find \"$CONFIG_DIR\" -name \"*.toml\" -exec chmod 640 {} \\; fi } install_services() { if [[ -d \"services\" ]] && command -v systemctl >/dev/null 2>&1; then log_info \"Installing systemd services...\" cp services/*.service /etc/systemd/system/ 2>/dev/null || true systemctl daemon-reload # Enable but don't start services for service in services/*.service; do if [[ -f \"$service\" ]]; then service_name=$(basename \"$service\") log_info \"Enabling service: $service_name\" systemctl enable \"$service_name\" fi done fi } configure_environment() { log_info \"Configuring environment...\" # Create environment file cat > /etc/environment.d/provisioning.conf << EOF PROVISIONING_HOME=\"$LIB_DIR\" PROVISIONING_CONFIG=\"$CONFIG_DIR\" PROVISIONING_DATA=\"$DATA_DIR\" PROVISIONING_LOG=\"$LOG_DIR\" EOF # Create shell profile cat > /etc/profile.d/provisioning.sh << 'EOF' # Provisioning System Environment if [ -d \"/usr/local/bin\" ]; then case \":$PATH:\" in *:/usr/local/bin:*) ;; *) PATH=\"/usr/local/bin:$PATH\" ;; esac fi export PROVISIONING_HOME=\"/usr/local/lib/provisioning\" export PROVISIONING_CONFIG=\"/etc/provisioning\" EOF } setup_logrotate() { log_info \"Setting up log rotation...\" cat > /etc/logrotate.d/provisioning << 'EOF' /var/log/provisioning/*.log { daily missingok rotate 52 compress delaycompress notifempty create 644 provisioning provisioning } EOF } main() { log_info \"Starting Provisioning System installation...\" check_root create_user create_directories install_binaries install_libraries install_configuration if [[ \"$1\" != \"--no-services\" ]]; then install_services fi configure_environment setup_logrotate log_info \"Installation completed successfully!\" log_info \"\" log_info \"Next steps:\" log_info \" 1. Review configuration in $CONFIG_DIR\" log_info \" 2. Start services: sudo systemctl start provisioning\" log_info \" 3. Run 'provisioning help' to get started\" log_info \"\" log_info \"For more information, see the documentation in $LIB_DIR/docs\" } # Handle command line arguments case \"$1\" in --help|-h) echo \"Provisioning System Installer ($version)\" echo \"\" echo \"Usage: $0 [OPTIONS]\" echo \"\" echo \"Options:\" echo \" --no-services Skip service installation\" echo \" --help, -h Show this help message\" exit 0 ;; *) main \"$@\" ;; esac " let installer_file = ($installer_config.output_dir | path join $"install-($platform).sh") $installer_content | save $installer_file chmod +x $installer_file { platform: $platform status: "success" installer_type: "shell" installer_file: $installer_file size: ($installer_content | str length) } } # Create Windows batch installer export def create_windows_batch_installer [ installer_config: record analysis_result: record ] { let version = $analysis_result.version_info.version let components = $analysis_result.components let installer_content = $"@echo off REM Provisioning System Installer REM Platform: Windows REM Version: ($version) setlocal EnableDelayedExpansion REM Configuration set \"INSTALL_DIR=C:\\Program Files\\Provisioning\" set \"CONFIG_DIR=C:\\ProgramData\\Provisioning\" set \"SERVICE_NAME=ProvisioningService\" echo. echo ======================================== echo Provisioning System Installer ($version) echo ======================================== echo. REM Check for administrator privileges net session >nul 2>&1 if %errorLevel% neq 0 ( echo ERROR: This script must be run as Administrator echo Right-click and select \"Run as administrator\" pause exit /b 1 ) echo Creating directories... mkdir \"%INSTALL_DIR%\\bin\" 2>nul mkdir \"%INSTALL_DIR%\\lib\" 2>nul mkdir \"%CONFIG_DIR%\" 2>nul echo Installing binaries... if exist \"platform\\\" ( xcopy platform\\* \"%INSTALL_DIR%\\bin\\\" /Y /Q ) else if exist \"core\\bin\\\" ( xcopy core\\bin\\* \"%INSTALL_DIR%\\bin\\\" /Y /Q ) else ( echo ERROR: No binaries found to install pause exit /b 1 ) echo Installing libraries... if exist \"core\\\" ( xcopy core\\* \"%INSTALL_DIR%\\lib\\\" /Y /Q /S ) echo Installing configuration... if exist \"config\\\" ( xcopy config\\* \"%CONFIG_DIR%\\\" /Y /Q /S ) echo Configuring environment... REM Add installation directory to system PATH for /f \"usebackq tokens=2,*\" %%A in (\`reg query HKCU\\Environment /v PATH\`) do set \"current_path=%%B\" echo !current_path! | findstr /C:\"%INSTALL_DIR%\\bin\" >nul if !errorLevel! neq 0 ( setx PATH \"!current_path!;%INSTALL_DIR%\\bin\" echo Added %INSTALL_DIR%\\bin to PATH ) REM Set environment variables setx PROVISIONING_HOME \"%INSTALL_DIR%\" setx PROVISIONING_CONFIG \"%CONFIG_DIR%\" echo. echo Installation completed successfully! echo. echo Next steps: echo 1. Review configuration in %CONFIG_DIR% echo 2. Run 'provisioning-orchestrator --help' to get started echo 3. Check the documentation in %INSTALL_DIR%\\lib\\docs echo. echo NOTE: You may need to restart your command prompt for PATH changes to take effect. echo. pause " let installer_file = ($installer_config.output_dir | path join "install-windows.bat") $installer_content | save $installer_file { platform: "windows" status: "success" installer_type: "batch" installer_file: $installer_file size: ($installer_content | str length) } } # Create package installers (deb, rpm, msi) export def create_package_installers [ installer_config: record analysis_result: record ] { log info "Creating package installers..." let start_time = (date now) # Package creation would involve: # 1. Creating package control files # 2. Building packages with appropriate tools # 3. Signing packages if requested log warning "Package installer creation not fully implemented" { status: "skipped" reason: "package installers not fully implemented" installers_created: 0 duration: ((date now) - $start_time) } } # Create GUI installers export def create_gui_installers [ installer_config: record analysis_result: record ] { log info "Creating GUI installers..." let start_time = (date now) # GUI installer creation would involve: # 1. Creating installer definition files # 2. Using platform-specific tools (NSIS, InstallShield, etc.) # 3. Including custom installation wizards log warning "GUI installer creation not fully implemented" { status: "skipped" reason: "GUI installers not fully implemented" installers_created: 0 duration: ((date now) - $start_time) } } # Create uninstall scripts export def create_uninstall_scripts [ installer_config: record analysis_result: record ] { log info "Creating uninstall scripts..." let start_time = (date now) let result = (do { mut created_uninstallers = [] for platform in $installer_config.platforms { match $platform { "linux" | "macos" => { let uninstaller_result = create_unix_uninstaller $platform $installer_config $analysis_result if $uninstaller_result.status == "success" { $created_uninstallers = ($created_uninstallers | append $uninstaller_result) } } "windows" => { let uninstaller_result = create_windows_uninstaller $installer_config $analysis_result if $uninstaller_result.status == "success" { $created_uninstallers = ($created_uninstallers | append $uninstaller_result) } } _ => { log warning $"Unsupported platform for uninstaller: ($platform)" } } } { status: "success" uninstallers_created: ($created_uninstallers | length) created_uninstallers: $created_uninstallers duration: ((date now) - $start_time) } } | complete) if $result.exit_code != 0 { { status: "failed" reason: $result.stderr duration: ((date now) - $start_time) } } else { $result.stdout } } # Create Unix uninstaller export def create_unix_uninstaller [ platform: string installer_config: record analysis_result: record ] { let version = $analysis_result.version_info.version let requirements = $analysis_result.requirements let uninstaller_content = $"#!/bin/bash # Provisioning System Uninstaller # Platform: ($platform) # Version: ($version) set -e # Colors for output RED='\\033[0;31m' GREEN='\\033[0;32m' YELLOW='\\033[1;33m' NC='\\033[0m' log_info() { echo -e \"${GREEN}[INFO]${NC} $1\" } log_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\" } log_error() { echo -e \"${RED}[ERROR]${NC} $1\" } check_root() { if [[ $EUID -ne 0 ]]; then log_error \"This script must be run as root (use sudo)\" exit 1 fi } confirm_uninstall() { echo \"This will completely remove the Provisioning System from your system.\" echo \"This includes:\" echo \" - All binaries and libraries\" echo \" - Configuration files\" echo \" - Service definitions\" echo \" - Log files and data\" echo \"\" read -p \"Are you sure you want to continue? (y/N): \" -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info \"Uninstallation cancelled\" exit 0 fi } stop_services() { log_info \"Stopping services...\" if command -v systemctl >/dev/null 2>&1; then systemctl stop provisioning* 2>/dev/null || true systemctl disable provisioning* 2>/dev/null || true fi } remove_binaries() { log_info \"Removing binaries...\" rm -f /usr/local/bin/provisioning* } remove_libraries() { log_info \"Removing libraries...\" rm -rf /usr/local/lib/provisioning } remove_configuration() { log_info \"Removing configuration...\" rm -rf /etc/provisioning } remove_data() { if [[ \"$1\" == \"--keep-data\" ]]; then log_info \"Keeping data directory (--keep-data specified)\" else log_info \"Removing data and logs...\" rm -rf /var/lib/provisioning rm -rf /var/log/provisioning fi } remove_services() { log_info \"Removing service definitions...\" rm -f /etc/systemd/system/provisioning*.service if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload fi } remove_environment() { log_info \"Removing environment configuration...\" rm -f /etc/environment.d/provisioning.conf rm -f /etc/profile.d/provisioning.sh rm -f /etc/logrotate.d/provisioning } remove_user() { if [[ \"$1\" == \"--keep-user\" ]]; then log_info \"Keeping system user (--keep-user specified)\" else log_info \"Removing system user...\" userdel provisioning 2>/dev/null || true fi } main() { log_info \"Starting Provisioning System uninstallation...\" check_root confirm_uninstall stop_services remove_services remove_binaries remove_libraries remove_configuration remove_data \"$1\" remove_environment remove_user \"$1\" log_info \"Uninstallation completed successfully!\" log_info \"\" log_info \"Thank you for using the Provisioning System.\" } case \"$1\" in --help|-h) echo \"Provisioning System Uninstaller ($version)\" echo \"\" echo \"Usage: $0 [OPTIONS]\" echo \"\" echo \"Options:\" echo \" --keep-data Keep data directory and logs\" echo \" --keep-user Keep system user account\" echo \" --help, -h Show this help message\" exit 0 ;; *) main \"$@\" ;; esac " let uninstaller_file = ($installer_config.output_dir | path join $"uninstall-($platform).sh") $uninstaller_content | save $uninstaller_file chmod +x $uninstaller_file { platform: $platform status: "success" uninstaller_type: "shell" uninstaller_file: $uninstaller_file size: ($uninstaller_content | str length) } } # Create Windows uninstaller export def create_windows_uninstaller [ installer_config: record analysis_result: record ] { let version = $analysis_result.version_info.version let uninstaller_content = $"@echo off REM Provisioning System Uninstaller REM Platform: Windows REM Version: ($version) setlocal EnableDelayedExpansion echo. echo ========================================== echo Provisioning System Uninstaller ($version) echo ========================================== echo. REM Check for administrator privileges net session >nul 2>&1 if %errorLevel% neq 0 ( echo ERROR: This script must be run as Administrator pause exit /b 1 ) echo This will completely remove the Provisioning System from your system. echo. set /p \"confirm=Are you sure you want to continue? (y/N): \" if /I not \"!confirm!\"==\"y\" ( echo Uninstallation cancelled exit /b 0 ) echo. echo Stopping services... REM Stop any running services here echo Removing installation directory... if exist \"C:\\Program Files\\Provisioning\" ( rmdir /S /Q \"C:\\Program Files\\Provisioning\" ) echo Removing configuration... if exist \"C:\\ProgramData\\Provisioning\" ( rmdir /S /Q \"C:\\ProgramData\\Provisioning\" ) echo Removing environment variables... reg delete HKCU\\Environment /v PROVISIONING_HOME /f 2>nul reg delete HKCU\\Environment /v PROVISIONING_CONFIG /f 2>nul echo Removing from PATH... for /f \"usebackq tokens=2,*\" %%A in (\`reg query HKCU\\Environment /v PATH 2^>nul\`) do ( set \"current_path=%%B\" set \"new_path=!current_path:C:\\Program Files\\Provisioning\\bin;=!\" set \"new_path=!new_path:;C:\\Program Files\\Provisioning\\bin=!\" if not \"!new_path!\"==\"!current_path!\" ( setx PATH \"!new_path!\" echo Removed from PATH ) ) echo. echo Uninstallation completed successfully! echo Thank you for using the Provisioning System. echo. pause " let uninstaller_file = ($installer_config.output_dir | path join "uninstall-windows.bat") $uninstaller_content | save $uninstaller_file { platform: "windows" status: "success" uninstaller_type: "batch" uninstaller_file: $uninstaller_file size: ($uninstaller_content | str length) } }