|
|
|
|
@ -1,38 +1,91 @@ |
|
|
|
|
#!/bin/bash |
|
|
|
|
|
|
|
|
|
# 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 $SNAP/bin/wekan-read-settings |
|
|
|
|
|
|
|
|
|
# Set up Node.js environment like wekan-control |
|
|
|
|
export NODE_PATH=$SNAP/bin |
|
|
|
|
|
|
|
|
|
# Configuration |
|
|
|
|
MIGRATION_STATUS="${SNAP_COMMON}/mongodb-migration-status.json" |
|
|
|
|
MIGRATION_LOG="${SNAP_COMMON}/mongodb-migration-log.txt" |
|
|
|
|
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> |
|
|
|
|
<head> |
|
|
|
|
<title>MongoDB Migration Progress</title> |
|
|
|
|
@ -119,50 +172,80 @@ serve_migration_progress() { |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<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 class="log-container"> |
|
|
|
|
<h3>Migration Log (Last 20 lines):</h3> |
|
|
|
|
<pre>$(tail -20 "$MIGRATION_LOG" 2>/dev/null || echo "No log available")</pre> |
|
|
|
|
<pre>${logContent}</pre> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<p style="text-align: center; margin-top: 30px; color: #666;"> |
|
|
|
|
<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> |
|
|
|
|
</div> |
|
|
|
|
</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 |
|
|
|
|
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 |
|
|
|
|
serve_migration_progress |
|
|
|
|
start_node_server |
|
|
|
|
|