Prechádzať zdrojové kódy

Snap: Migrate MongoDB from 3 to 7 only when "snap set wekan migrate-mongodb='true'". Not automatically.

Thanks to xet7 !
Lauri Ojansivu 1 týždeň pred
rodič
commit
ae01ea576c

+ 2 - 2
snap-src/bin/caddy-control

@@ -9,7 +9,7 @@ if [ "$CADDY_ENABLED" = "true" ]; then
     # The 'agree' option is no longer needed as Caddy 2 doesn't prompt for EULA
     # The 'agree' option is no longer needed as Caddy 2 doesn't prompt for EULA
     env LC_ALL=C caddy run --config $SNAP_COMMON/Caddyfile
     env LC_ALL=C caddy run --config $SNAP_COMMON/Caddyfile
 else
 else
-    echo "caddy is disabled. Stop service"
-    snapctl stop --disable ${SNAP_NAME}.caddy
+    echo "caddy is disabled. Service stopping disabled"
+    # snapctl stop --disable ${SNAP_NAME}.caddy
     # sleep here, in case snapctl fails to stop service so we do not restart too often
     # sleep here, in case snapctl fails to stop service so we do not restart too often
 fi
 fi

+ 8 - 8
snap-src/bin/logrotate-setup

@@ -62,10 +62,10 @@ ${MONGODB_LOG} {
         if [ -f "${SNAP_COMMON}/mongodb.pid" ]; then
         if [ -f "${SNAP_COMMON}/mongodb.pid" ]; then
             kill -USR1 \$(cat "${SNAP_COMMON}/mongodb.pid") 2>/dev/null || true
             kill -USR1 \$(cat "${SNAP_COMMON}/mongodb.pid") 2>/dev/null || true
         fi
         fi
-        # Alternative: restart MongoDB service if PID file doesn't exist
-        if [ ! -f "${SNAP_COMMON}/mongodb.pid" ]; then
-            snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
-        fi
+        # Alternative: restart MongoDB service if PID file doesn't exist - DISABLED
+        # if [ ! -f "${SNAP_COMMON}/mongodb.pid" ]; then
+        #     snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
+        # fi
     endscript
     endscript
 }
 }
 
 
@@ -85,7 +85,7 @@ ${WEKAN_APP_LOG} {
         fi
         fi
         # Alternative: restart Wekan service if PID file doesn't exist
         # Alternative: restart Wekan service if PID file doesn't exist
         if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
         if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
-            snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
+            # snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
         fi
         fi
     endscript
     endscript
 }
 }
@@ -106,7 +106,7 @@ ${WEKAN_ERROR_LOG} {
         fi
         fi
         # Alternative: restart Wekan service if PID file doesn't exist
         # Alternative: restart Wekan service if PID file doesn't exist
         if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
         if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
-            snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
+            # snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
         fi
         fi
     endscript
     endscript
 }
 }
@@ -131,8 +131,8 @@ ${SNAP_COMMON}/*.log {
         done
         done
         # Restart services if no PID files found
         # Restart services if no PID files found
         if [ ! -f "${SNAP_COMMON}/mongodb.pid" ] && [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
         if [ ! -f "${SNAP_COMMON}/mongodb.pid" ] && [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
-            snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
-            snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
+            # snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
+            # snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
         fi
         fi
     endscript
     endscript
 }
 }

+ 55 - 6
snap-src/bin/mongodb-control

@@ -1,5 +1,9 @@
 #!/bin/bash
 #!/bin/bash
 
 
+# MongoDB Control Script
+# IMPORTANT: Migration is only triggered when MIGRATE_MONGODB=true environment variable is set
+# IMPORTANT: No snap settings or channel changes are made during migration
+
 # get wekan/mongo settings
 # get wekan/mongo settings
 source $SNAP/bin/wekan-read-settings
 source $SNAP/bin/wekan-read-settings
 
 
@@ -9,7 +13,7 @@ if [ "true" == "${DISABLE_MONGODB}" ]; then
     exit 0
     exit 0
 fi
 fi
 
 
-# Check if MongoDB migration is needed and handle it
+# Migration checking and handling - controlled by MIGRATE_MONGODB environment variable
 MIGRATION_STATUS="${SNAP_COMMON}/mongodb-migration-status.json"
 MIGRATION_STATUS="${SNAP_COMMON}/mongodb-migration-status.json"
 MIGRATION_LOG="${SNAP_COMMON}/mongodb-migration-log.txt"
 MIGRATION_LOG="${SNAP_COMMON}/mongodb-migration-log.txt"
 REVERT_FILE="${SNAP_COMMON}/revert-mongodb-migration.txt"
 REVERT_FILE="${SNAP_COMMON}/revert-mongodb-migration.txt"
@@ -33,10 +37,23 @@ check_migration_needed() {
     return 1
     return 1
 }
 }
 
 
-# Handle migration
+# Handle migration - only if MIGRATE_MONGODB=true
 handle_migration() {
 handle_migration() {
     echo "MongoDB migration needed, starting migration process..."
     echo "MongoDB migration needed, starting migration process..."
 
 
+    # Stop Wekan (meteor) process before migration
+    echo "Stopping Wekan (meteor) process for migration..."
+    snapctl stop --disable ${SNAP_NAME}.wekan || true
+    snapctl stop --disable ${SNAP_NAME} || true
+    
+    # Wait a moment for processes to stop
+    sleep 2
+    
+    # Kill any remaining meteor/node processes
+    pkill -f "node.*main.js" || true
+    pkill -f "meteor" || true
+    sleep 1
+
     # Start migration web interface in background
     # Start migration web interface in background
     $SNAP/bin/mongodb-migration-web &
     $SNAP/bin/mongodb-migration-web &
     local web_pid=$!
     local web_pid=$!
@@ -51,6 +68,11 @@ handle_migration() {
             kill "$web_pid" 2>/dev/null || true
             kill "$web_pid" 2>/dev/null || true
             rm -f "${SNAP_COMMON}/migration-web.pid"
             rm -f "${SNAP_COMMON}/migration-web.pid"
         fi
         fi
+        
+        # Clean up temporary Node.js server file
+        rm -f "${SNAP_COMMON}/migration-web-server.js"
+        
+        echo "Migration completed. Wekan will be restarted automatically."
     else
     else
         echo "MongoDB migration failed"
         echo "MongoDB migration failed"
         # Kill migration web interface
         # Kill migration web interface
@@ -59,21 +81,48 @@ handle_migration() {
             kill "$web_pid" 2>/dev/null || true
             kill "$web_pid" 2>/dev/null || true
             rm -f "${SNAP_COMMON}/migration-web.pid"
             rm -f "${SNAP_COMMON}/migration-web.pid"
         fi
         fi
+        
+        # Clean up temporary Node.js server file
+        rm -f "${SNAP_COMMON}/migration-web-server.js"
+        
         exit 1
         exit 1
     fi
     fi
 }
 }
 
 
 # Check if revert is requested
 # Check if revert is requested
 if [ -f "$REVERT_FILE" ]; then
 if [ -f "$REVERT_FILE" ]; then
-    echo "Revert requested, stopping MongoDB and reverting migration..."
+    echo "Revert requested, stopping Wekan and MongoDB, then reverting migration..."
+    
+    # Stop Wekan (meteor) process before revert
+    echo "Stopping Wekan (meteor) process for revert..."
+    snapctl stop --disable ${SNAP_NAME}.wekan || true
+    snapctl stop --disable ${SNAP_NAME} || true
+    
+    # Wait a moment for processes to stop
+    sleep 2
+    
+    # Kill any remaining meteor/node processes
+    pkill -f "node.*main.js" || true
+    pkill -f "meteor" || true
+    sleep 1
+    
+    # Stop MongoDB
     snapctl stop --disable ${SNAP_NAME}.mongodb
     snapctl stop --disable ${SNAP_NAME}.mongodb
+    
+    # Run migration (which will handle revert)
     $SNAP/bin/mongodb-migrate
     $SNAP/bin/mongodb-migrate
     exit $?
     exit $?
 fi
 fi
 
 
-# Check if migration is needed
-if check_migration_needed; then
-    handle_migration
+# Check if migration is needed - only if MIGRATE_MONGODB=true
+if [ "$MIGRATE_MONGODB" = "true" ]; then
+    if check_migration_needed; then
+        handle_migration
+    else
+        echo "MIGRATE_MONGODB=true but no migration needed"
+    fi
+else
+    echo "MIGRATE_MONGODB not set to 'true' - skipping migration check"
 fi
 fi
 
 
 # make sure we have set minimum env variables for locale
 # make sure we have set minimum env variables for locale

+ 38 - 29
snap-src/bin/mongodb-migrate

@@ -3,7 +3,9 @@
 # MongoDB Migration Script from version 3 to 7
 # MongoDB Migration Script from version 3 to 7
 # This script handles migration with disk space checks, progress tracking, and error handling
 # This script handles migration with disk space checks, progress tracking, and error handling
 #
 #
+# IMPORTANT: Migration is only triggered when MIGRATE_MONGODB=true environment variable is set
 # IMPORTANT: All operations are contained within SNAP_COMMON directory
 # IMPORTANT: All operations are contained within SNAP_COMMON directory
+# IMPORTANT: No snap settings or channel changes are made during migration
 # This is the only writable directory in a snap environment
 # This is the only writable directory in a snap environment
 
 
 set -e
 set -e
@@ -423,17 +425,19 @@ rotate_migration_logs() {
     fi
     fi
 }
 }
 
 
-# Reset MONGO_LOG_DESTINATION to devnull after successful migration
+# Reset MONGO_LOG_DESTINATION to devnull after successful migration - DISABLED
+# Snap settings changes are permanently disabled during migration
 reset_mongo_log_destination() {
 reset_mongo_log_destination() {
-    log_message "Resetting MONGO_LOG_DESTINATION to devnull after successful migration"
+    log_message "MONGO_LOG_DESTINATION reset disabled - snap settings changes not allowed during migration"
     
     
-    # Use snap set to change the setting back to devnull
-    if snap set wekan mongo-log-destination="devnull" 2>/dev/null; then
-        log_success "MONGO_LOG_DESTINATION reset to devnull successfully"
-    else
-        log_error "Failed to reset MONGO_LOG_DESTINATION to devnull"
-        # Don't fail the migration for this setting issue
-    fi
+    # Snap settings changes permanently disabled during migration
+    # This ensures no snap configuration is modified during the migration process
+    # if snap set wekan mongo-log-destination="devnull" 2>/dev/null; then
+    #     log_success "MONGO_LOG_DESTINATION reset to devnull successfully"
+    # else
+    #     log_error "Failed to reset MONGO_LOG_DESTINATION to devnull"
+    #     # Don't fail the migration for this setting issue
+    # fi
 }
 }
 
 
 # Migrate raw MongoDB 3 database files
 # Migrate raw MongoDB 3 database files
@@ -568,20 +572,25 @@ switch_to_stable_channel() {
     local snap_name="$1"
     local snap_name="$1"
     local current_channel=$(get_current_snap_channel "$snap_name")
     local current_channel=$(get_current_snap_channel "$snap_name")
 
 
-    if [ "$current_channel" != "stable" ] && [ "$current_channel" != "unknown" ]; then
-        log_message "Switching $snap_name from $current_channel to stable channel"
-
-        if snap refresh "$snap_name" --channel=stable; then
-            log_success "Successfully switched $snap_name to stable channel"
-            return 0
-        else
-            log_error "Failed to switch $snap_name to stable channel"
-            return 1
-        fi
-    else
-        log_message "$snap_name is already on stable channel or not installed"
-        return 0
-    fi
+    log_message "Snap channel switching disabled - not changing $snap_name channel (currently: $current_channel)"
+    log_message "Snap channel changes are permanently disabled during migration"
+    return 0
+    
+    # Snap channel switching permanently disabled during migration
+    # This ensures no snap channels are modified during the migration process
+    # if [ "$current_channel" != "stable" ] && [ "$current_channel" != "unknown" ]; then
+    #     log_message "Switching $snap_name from $current_channel to stable channel"
+    #     if snap refresh "$snap_name" --channel=stable; then
+    #         log_success "Successfully switched $snap_name to stable channel"
+    #         return 0
+    #     else
+    #         log_error "Failed to switch $snap_name to stable channel"
+    #         return 1
+    #     fi
+    # else
+    #     log_message "$snap_name is already on stable channel or not installed"
+    #     return 0
+    # fi
 }
 }
 
 
 switch_all_wekan_snaps_to_stable() {
 switch_all_wekan_snaps_to_stable() {
@@ -786,9 +795,9 @@ revert_migration() {
         return 1
         return 1
     fi
     fi
 
 
-    # Stop MongoDB 7
-    log_message "Stopping MongoDB 7"
-    snapctl stop --disable "${SNAP_NAME}.mongodb"
+    # Stop MongoDB 7 - DISABLED
+    log_message "MongoDB stopping disabled - not using snapctl stop"
+    # snapctl stop --disable "${SNAP_NAME}.mongodb"
 
 
     # Remove MongoDB 7 version marker
     # Remove MongoDB 7 version marker
     rm -f "${SNAP_COMMON}/mongodb-version-7"
     rm -f "${SNAP_COMMON}/mongodb-version-7"
@@ -824,9 +833,9 @@ revert_migration() {
     # Clear migration status
     # Clear migration status
     rm -f "$MIGRATION_STATUS"
     rm -f "$MIGRATION_STATUS"
 
 
-    # Start MongoDB 3
-    log_message "Starting MongoDB 3"
-    snapctl start --enable "${SNAP_NAME}.mongodb"
+    # Start MongoDB 3 - DISABLED
+    log_message "MongoDB starting disabled - not using snapctl start"
+    # snapctl start --enable "${SNAP_NAME}.mongodb"
 
 
     log_success "Migration reverted successfully"
     log_success "Migration reverted successfully"
     return 0
     return 0

+ 139 - 56
snap-src/bin/mongodb-migration-web

@@ -1,38 +1,91 @@
 #!/bin/bash
 #!/bin/bash
 
 
 # MongoDB Migration Web Interface
 # MongoDB Migration Web Interface
-# Serves migration progress at ROOT_URL/migration-progress
+# Serves migration progress at ROOT_URL/migration-progress using Node.js
 
 
 # Source settings
 # Source settings
 source $SNAP/bin/wekan-read-settings
 source $SNAP/bin/wekan-read-settings
 
 
+# Set up Node.js environment like wekan-control
+export NODE_PATH=$SNAP/bin
+
 # Configuration
 # Configuration
 MIGRATION_STATUS="${SNAP_COMMON}/mongodb-migration-status.json"
 MIGRATION_STATUS="${SNAP_COMMON}/mongodb-migration-status.json"
 MIGRATION_LOG="${SNAP_COMMON}/mongodb-migration-log.txt"
 MIGRATION_LOG="${SNAP_COMMON}/mongodb-migration-log.txt"
 MIGRATION_PROGRESS="${SNAP_COMMON}/mongodb-migration-progress.html"
 MIGRATION_PROGRESS="${SNAP_COMMON}/mongodb-migration-progress.html"
-PORT="${MIGRATION_WEB_PORT:-8081}"
-
-# Create a simple HTTP server using netcat and bash
-serve_migration_progress() {
-    while true; do
-        {
-            echo "HTTP/1.1 200 OK"
-            echo "Content-Type: text/html; charset=utf-8"
-            echo "Cache-Control: no-cache"
-            echo "Connection: close"
-            echo ""
-
-            # Generate HTML page
-            if [ -f "$MIGRATION_STATUS" ]; then
-                local status=$(jq -r '.status' "$MIGRATION_STATUS" 2>/dev/null || echo "unknown")
-                local step=$(jq -r '.step' "$MIGRATION_STATUS" 2>/dev/null || echo "0")
-                local total_steps=$(jq -r '.total_steps' "$MIGRATION_STATUS" 2>/dev/null || echo "0")
-                local percentage=$(jq -r '.percentage' "$MIGRATION_STATUS" 2>/dev/null || echo "0")
-                local description=$(jq -r '.description' "$MIGRATION_STATUS" 2>/dev/null || echo "Unknown")
-                local timestamp=$(jq -r '.timestamp' "$MIGRATION_STATUS" 2>/dev/null || echo "Unknown")
-
-                cat << EOF
-<!DOCTYPE html>
+# Use same PORT as wekan-control, but add 1 to avoid conflicts
+MIGRATION_PORT=$((PORT + 1))
+
+# Create Node.js HTTP server script
+create_node_server() {
+    cat > "${SNAP_COMMON}/migration-web-server.js" << 'EOF'
+const http = require('http');
+const fs = require('fs');
+const path = require('path');
+
+const PORT = process.env.MIGRATION_PORT || 8081;
+const SNAP_COMMON = process.env.SNAP_COMMON;
+const ROOT_URL = process.env.ROOT_URL || 'http://127.0.0.1';
+const MIGRATION_STATUS = path.join(SNAP_COMMON, 'mongodb-migration-status.json');
+const MIGRATION_LOG = path.join(SNAP_COMMON, 'mongodb-migration-log.txt');
+
+function readFileSafe(filePath) {
+    try {
+        return fs.readFileSync(filePath, 'utf8');
+    } catch (error) {
+        return null;
+    }
+}
+
+function getMigrationStatus() {
+    const statusContent = readFileSafe(MIGRATION_STATUS);
+    if (!statusContent) {
+        return null;
+    }
+    
+    try {
+        return JSON.parse(statusContent);
+    } catch (error) {
+        return null;
+    }
+}
+
+function getMigrationLog() {
+    const logContent = readFileSafe(MIGRATION_LOG);
+    if (!logContent) {
+        return 'No log available';
+    }
+    
+    const lines = logContent.split('\n');
+    return lines.slice(-20).join('\n');
+}
+
+function generateHTML(status) {
+    if (!status) {
+        return `<!DOCTYPE html>
+<html>
+<head>
+    <title>MongoDB Migration Progress</title>
+    <meta http-equiv="refresh" content="5">
+    <style>
+        body { font-family: Arial, sans-serif; margin: 40px; }
+        .container { max-width: 800px; margin: 0 auto; text-align: center; }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <h1>MongoDB Migration</h1>
+        <p>No migration in progress.</p>
+        <p><em>This page will refresh automatically every 5 seconds.</em></p>
+    </div>
+</body>
+</html>`;
+    }
+
+    const { status: statusValue, step, total_steps, percentage, description, timestamp } = status;
+    const logContent = getMigrationLog();
+
+    return `<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
     <title>MongoDB Migration Progress</title>
     <title>MongoDB Migration Progress</title>
@@ -119,50 +172,80 @@ serve_migration_progress() {
         </div>
         </div>
 
 
         <div class="status">
         <div class="status">
-            <p><span class="status-indicator status-${status}"></span><strong>Status:</strong> ${status}</p>
-            <p><strong>Progress:</strong> $step of $total_steps steps</p>
-            <p><strong>Current Step:</strong> $description</p>
-            <p><strong>Last Updated:</strong> $timestamp</p>
+            <p><span class="status-indicator status-${statusValue}"></span><strong>Status:</strong> ${statusValue}</p>
+            <p><strong>Progress:</strong> ${step} of ${total_steps} steps</p>
+            <p><strong>Current Step:</strong> ${description}</p>
+            <p><strong>Last Updated:</strong> ${timestamp}</p>
         </div>
         </div>
 
 
         <div class="log-container">
         <div class="log-container">
             <h3>Migration Log (Last 20 lines):</h3>
             <h3>Migration Log (Last 20 lines):</h3>
-            <pre>$(tail -20 "$MIGRATION_LOG" 2>/dev/null || echo "No log available")</pre>
+            <pre>${logContent}</pre>
         </div>
         </div>
 
 
         <p style="text-align: center; margin-top: 30px; color: #666;">
         <p style="text-align: center; margin-top: 30px; color: #666;">
             <em>This page will refresh automatically every 5 seconds.</em><br>
             <em>This page will refresh automatically every 5 seconds.</em><br>
-            <em>Migration URL: ${ROOT_URL:-http://localhost:8080}/migration-progress</em>
+            <em>Migration URL: ${ROOT_URL}/migration-progress</em>
         </p>
         </p>
     </div>
     </div>
 </body>
 </body>
-</html>
-EOF
-            else
-                cat << EOF
-<!DOCTYPE html>
-<html>
-<head>
-    <title>MongoDB Migration Progress</title>
-    <meta http-equiv="refresh" content="5">
-    <style>
-        body { font-family: Arial, sans-serif; margin: 40px; }
-        .container { max-width: 800px; margin: 0 auto; text-align: center; }
-    </style>
-</head>
-<body>
-    <div class="container">
-        <h1>MongoDB Migration</h1>
-        <p>No migration in progress.</p>
-        <p><em>This page will refresh automatically every 5 seconds.</em></p>
-    </div>
-</body>
-</html>
+</html>`;
+}
+
+const server = http.createServer((req, res) => {
+    if (req.url === '/migration-progress' || req.url === '/') {
+        const status = getMigrationStatus();
+        const html = generateHTML(status);
+        
+        res.writeHead(200, {
+            'Content-Type': 'text/html; charset=utf-8',
+            'Cache-Control': 'no-cache',
+            'Connection': 'close'
+        });
+        res.end(html);
+    } else {
+        res.writeHead(404, { 'Content-Type': 'text/plain' });
+        res.end('Not Found');
+    }
+});
+
+server.listen(PORT, () => {
+    console.log(`MongoDB Migration Web Server running on port ${PORT}`);
+});
+
+// Handle graceful shutdown
+process.on('SIGTERM', () => {
+    console.log('Received SIGTERM, shutting down gracefully');
+    server.close(() => {
+        process.exit(0);
+    });
+});
+
+process.on('SIGINT', () => {
+    console.log('Received SIGINT, shutting down gracefully');
+    server.close(() => {
+        process.exit(0);
+    });
+});
 EOF
 EOF
-            fi
-        } | nc -l -p "$PORT" -q 1
-    done
+}
+
+# Start the Node.js web server
+start_node_server() {
+    echo "Starting MongoDB migration web server using Node.js..."
+    echo "Migration server will be available at: ${ROOT_URL}/migration-progress"
+    echo "Migration server port: ${MIGRATION_PORT}"
+    
+    # Create the Node.js server script
+    create_node_server
+    
+    # Export environment variables for the Node.js process
+    export MIGRATION_PORT
+    export ROOT_URL
+    
+    # Start the server using Node.js from SNAP/bin
+    $NODE_PATH/node "${SNAP_COMMON}/migration-web-server.js"
 }
 }
 
 
 # Start the web server
 # Start the web server
-serve_migration_progress
+start_node_server