provisioning/tools/distribution/installer_generator.nu

733 lines
19 KiB
Plaintext
Raw Normal View History

# 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)
}
}