From d08820c9c62e267fe69fa25c8d87710ee659fba2 Mon Sep 17 00:00:00 2001 From: MasterDraco Date: Wed, 5 Mar 2025 00:30:24 +0000 Subject: [PATCH] Enhance installer to detect existing installations and update seamlessly --- README.md | 26 +++++- main-installer.sh | 153 +++++++++++++++++++++++--------- modules/service-setup-module.sh | 81 +++++++++++++++-- 3 files changed, 207 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index e477b74..1d3ac09 100755 --- a/README.md +++ b/README.md @@ -9,8 +9,10 @@ A comprehensive web-based tool to automate and manage your Transmission torrent - **New**: One-click update feature with version checking - **New**: Automatic Transmission detection and installation - **New**: System status dashboard with update notifications +- **New**: Automatic detection of existing installations for seamless updates - **New**: About page with developer information - **Improved**: Better error handling for Transmission connection +- **Improved**: Enhanced update process that preserves existing configurations - **Fixed**: Various UI bugs and responsiveness issues ### v1.2.0 (2025-02-15) @@ -77,7 +79,10 @@ The bootstrap installer will: 3. Run the main installer which guides you through configuration 4. Set up the service and web interface -**New in v2.0.0:** The installer now detects if Transmission is installed and offers to install and configure it automatically if needed. +**New in v2.0.0:** +- The installer now detects if Transmission is installed and offers to install and configure it automatically if needed. +- The installer automatically detects existing installations and runs in update mode, preserving your existing configuration. +- When updating, only necessary files are modified while maintaining your custom settings and preferences. ### Manual Installation @@ -272,6 +277,25 @@ The system will: - Restore your configuration - Restart the service automatically +### Using the Installer + +You can also update by running the installer again: + +```bash +# Navigate to the installation directory +cd /opt/transmission-rss-manager + +# Run the installer with sudo +sudo ./main-installer.sh +``` + +The installer will: +1. Detect your existing installation automatically +2. Run in update mode +3. Preserve all your existing configurations +4. Update only the necessary files +5. Restart the service with your updated installation + ### Using the Command Line If you prefer to update via command line: diff --git a/main-installer.sh b/main-installer.sh index a399be9..c1da3bc 100755 --- a/main-installer.sh +++ b/main-installer.sh @@ -30,10 +30,28 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" # Check for installation type IS_UPDATE=false +INSTALLATION_DETECTED=false + +# Check for config.json file (primary indicator) if [ -f "${SCRIPT_DIR}/config.json" ]; then + INSTALLATION_DETECTED=true +fi + +# Check for service file (secondary indicator) +if [ -f "/etc/systemd/system/transmission-rss-manager.service" ]; then + INSTALLATION_DETECTED=true +fi + +# Check for data directory (tertiary indicator) +if [ -d "${SCRIPT_DIR}/data" ] && [ "$(ls -A "${SCRIPT_DIR}/data" 2>/dev/null)" ]; then + INSTALLATION_DETECTED=true +fi + +if [ "$INSTALLATION_DETECTED" = true ]; then IS_UPDATE=true echo -e "${YELLOW}Existing installation detected. Running in update mode.${NC}" echo -e "${GREEN}Your existing configuration will be preserved.${NC}" + echo -e "${GREEN}Only application files will be updated.${NC}" else echo -e "${GREEN}Fresh installation. Will create new configuration.${NC}" fi @@ -45,6 +63,7 @@ REQUIRED_MODULES=( "${SCRIPT_DIR}/modules/utils-module.sh" "${SCRIPT_DIR}/modules/dependencies-module.sh" "${SCRIPT_DIR}/modules/service-setup-module.sh" + "${SCRIPT_DIR}/modules/file-creator-module.sh" ) for module in "${REQUIRED_MODULES[@]}"; do @@ -60,6 +79,7 @@ source "${SCRIPT_DIR}/modules/utils-module.sh" # Load utilities first for loggin source "${SCRIPT_DIR}/modules/config-module.sh" source "${SCRIPT_DIR}/modules/dependencies-module.sh" source "${SCRIPT_DIR}/modules/service-setup-module.sh" +source "${SCRIPT_DIR}/modules/file-creator-module.sh" # Function to handle cleanup on error function cleanup_on_error() { @@ -78,48 +98,80 @@ trap 'cleanup_on_error "$BASH_COMMAND"' ERR # Execute the installation steps in sequence log "INFO" "Starting installation process..." -# Step 1: Gather configuration from user -log "INFO" "Gathering configuration..." -gather_configuration || { - log "ERROR" "Configuration gathering failed" - exit 1 -} - -# Step 2: Install dependencies -log "INFO" "Installing dependencies..." -install_dependencies || { - log "ERROR" "Dependency installation failed" - exit 1 -} - -# Step 3: Create installation directories -log "INFO" "Creating directories..." -create_directories || { - log "ERROR" "Directory creation failed" - exit 1 -} - -# Step 4: Create configuration files only (no application files since they're from git) -log "INFO" "Creating configuration files..." -create_config_files || { - log "ERROR" "Configuration file creation failed" - exit 1 -} - -# Step 5: Create service files and install the service -log "INFO" "Setting up service..." -setup_service || { - log "ERROR" "Service setup failed" - exit 1 -} - -# Step 6: Install npm dependencies -log "INFO" "Installing npm dependencies..." -cd "$SCRIPT_DIR" -npm install || { - log "ERROR" "NPM installation failed" - exit 1 -} +if [ "$IS_UPDATE" = true ]; then + log "INFO" "Running in update mode - preserving existing configuration..." + + # When updating, we only need to update core files and dependencies + # Configuration should be preserved + + # Step 1: Check dependencies (but don't reconfigure) + log "INFO" "Checking dependencies..." + install_dependencies || { + log "ERROR" "Dependency check failed" + exit 1 + } + + # Step the service configuration (will preserve existing settings) + log "INFO" "Updating service configuration..." + setup_service || { + log "ERROR" "Service update failed" + exit 1 + } + + # Install npm dependencies + log "INFO" "Updating npm dependencies..." + cd "$SCRIPT_DIR" + npm install || { + log "ERROR" "NPM installation failed" + exit 1 + } + +else + # This is a fresh installation - run all steps + + # Step 1: Gather configuration from user + log "INFO" "Gathering configuration..." + gather_configuration || { + log "ERROR" "Configuration gathering failed" + exit 1 + } + + # Step 2: Install dependencies + log "INFO" "Installing dependencies..." + install_dependencies || { + log "ERROR" "Dependency installation failed" + exit 1 + } + + # Step 3: Create installation directories + log "INFO" "Creating directories..." + create_directories || { + log "ERROR" "Directory creation failed" + exit 1 + } + + # Step 4: Create configuration files only (no application files since they're from git) + log "INFO" "Creating configuration files..." + create_config_files || { + log "ERROR" "Configuration file creation failed" + exit 1 + } + + # Step 5: Create service files and install the service + log "INFO" "Setting up service..." + setup_service || { + log "ERROR" "Service setup failed" + exit 1 + } + + # Step 6: Install npm dependencies + log "INFO" "Installing npm dependencies..." + cd "$SCRIPT_DIR" + npm install || { + log "ERROR" "NPM installation failed" + exit 1 + } +fi # Step 7: Set up update script log "INFO" "Setting up update script..." @@ -226,7 +278,13 @@ finalize_setup || { # Installation complete echo echo -e "${BOLD}${GREEN}==================================================${NC}" -echo -e "${BOLD}${GREEN} Installation Complete! ${NC}" + +if [ "$IS_UPDATE" = true ]; then + echo -e "${BOLD}${GREEN} Update Complete! ${NC}" +else + echo -e "${BOLD}${GREEN} Installation Complete! ${NC}" +fi + echo -e "${BOLD}${GREEN}==================================================${NC}" echo -e "You can access the web interface at: ${BOLD}http://localhost:$PORT${NC} or ${BOLD}http://your-server-ip:$PORT${NC}" echo -e "You may need to configure your firewall to allow access to port $PORT" @@ -237,5 +295,12 @@ echo -e " To view logs: ${YELLOW}journalctl -u $SERVICE_NAME${NC}" echo -e " To restart the service: ${YELLOW}systemctl restart $SERVICE_NAME${NC}" echo -e " To update the application: ${YELLOW}Use the Update button in the System Status section${NC}" echo -echo -e "Thank you for installing Transmission RSS Manager!" + +if [ "$IS_UPDATE" = true ]; then + echo -e "Thank you for updating Transmission RSS Manager!" + echo -e "The service has been restarted with the new version." +else + echo -e "Thank you for installing Transmission RSS Manager!" +fi + echo -e "${BOLD}==================================================${NC}" \ No newline at end of file diff --git a/modules/service-setup-module.sh b/modules/service-setup-module.sh index 2c7fdae..3dba137 100644 --- a/modules/service-setup-module.sh +++ b/modules/service-setup-module.sh @@ -33,14 +33,72 @@ function setup_service() { return 1 fi - # Create backup of existing service file if it exists - if [ -f "/etc/systemd/system/$SERVICE_NAME.service" ]; then - backup_file "/etc/systemd/system/$SERVICE_NAME.service" - fi - - # Create systemd service file + # Check if service file already exists SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service" - cat > "$SERVICE_FILE" << EOF + if [ -f "$SERVICE_FILE" ] && [ "$IS_UPDATE" = true ]; then + log "INFO" "Service file already exists. Preserving existing service configuration." + + # Extract existing JWT_SECRET if present to maintain session consistency + EXISTING_JWT_SECRET=$(grep "Environment=JWT_SECRET=" "$SERVICE_FILE" | cut -d'=' -f3) + + # Extract existing PORT if it differs from the configured one + EXISTING_PORT=$(grep "Environment=PORT=" "$SERVICE_FILE" | cut -d'=' -f3) + if [ -n "$EXISTING_PORT" ] && [ "$EXISTING_PORT" != "$PORT" ]; then + log "INFO" "Using existing port configuration: $EXISTING_PORT" + PORT=$EXISTING_PORT + fi + + # Create backup of existing service file + backup_file "$SERVICE_FILE" + + # Update the service file while preserving key settings + cat > "$SERVICE_FILE" << EOF +[Unit] +Description=Transmission RSS Manager +After=network.target transmission-daemon.service +Wants=network-online.target + +[Service] +Type=simple +User=$USER +WorkingDirectory=$INSTALL_DIR +ExecStart=/usr/bin/node $INSTALL_DIR/server.js +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal +Environment=PORT=$PORT +Environment=NODE_ENV=production +Environment=DEBUG_ENABLED=false +Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log +EOF + + # Preserve the existing JWT_SECRET if available + if [ -n "$EXISTING_JWT_SECRET" ]; then + echo "Environment=JWT_SECRET=$EXISTING_JWT_SECRET" >> "$SERVICE_FILE" + else + echo "# Generate a random JWT secret for security" >> "$SERVICE_FILE" + echo "Environment=JWT_SECRET=$(openssl rand -hex 32)" >> "$SERVICE_FILE" + fi + + # Close the service file definition + cat >> "$SERVICE_FILE" << EOF + +[Install] +WantedBy=multi-user.target +EOF + + else + # For fresh installations, create a new service file + log "INFO" "Creating new service file" + + # Create backup of existing service file if it exists + if [ -f "$SERVICE_FILE" ]; then + backup_file "$SERVICE_FILE" + fi + + # Create systemd service file + cat > "$SERVICE_FILE" << EOF [Unit] Description=Transmission RSS Manager After=network.target transmission-daemon.service @@ -65,6 +123,7 @@ Environment=JWT_SECRET=$(openssl rand -hex 32) [Install] WantedBy=multi-user.target EOF + fi # Create logs directory mkdir -p "$INSTALL_DIR/logs" @@ -146,6 +205,9 @@ server { } EOF + log "INFO" "Nginx configured to proxy connections from port 80 to port $PORT" + log "INFO" "You can access Transmission RSS Manager at http://your-server-ip/ (port 80) via Nginx" + # Check if Debian/Ubuntu style (need symlink between available and enabled) if [ "$NGINX_AVAILABLE_DIR" != "$NGINX_ENABLED_DIR" ]; then # Create symbolic link to enable the site (if it doesn't already exist) @@ -167,7 +229,10 @@ EOF # Check for port conflicts if ss -lnt | grep ":$PORT " &> /dev/null; then log "WARN" "Port $PORT is already in use. This may cause conflicts with the service." - log "WARN" "Consider changing the port if you encounter issues." + log "WARN" "The service will fail to start. Please stop any service using port $PORT and try again." + else + log "INFO" "You can access the web interface at: http://localhost:$PORT or http://your-server-ip:$PORT" + log "INFO" "You may need to configure your firewall to allow access to port $PORT" fi # Reload systemd