mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Refactor: Replace screenshot functionality with mock data generation
This commit is contained in:
@@ -16,6 +16,7 @@ build/
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
socket-debug.log
|
||||
|
||||
# Reports
|
||||
reports/
|
||||
@@ -39,3 +40,6 @@ scripts/release.sh
|
||||
# Release process
|
||||
.release-prompt.md
|
||||
.commit-prompt.md
|
||||
|
||||
# Development tools
|
||||
/tmp/pulse-*.log
|
||||
|
||||
@@ -148,16 +148,6 @@ docker run -d -p 7654:7654 --env-file .env --name pulse-app --restart unless-sto
|
||||
- Responsive design that works on desktop and mobile
|
||||
- WebSocket connection for live updates
|
||||
|
||||
## 📱 More Screenshots
|
||||
|
||||
### Resource Details
|
||||

|
||||
*Detailed resource monitoring with real-time graphs*
|
||||
|
||||
### Mobile View
|
||||

|
||||
*Responsive mobile interface*
|
||||
|
||||
## ❓ Troubleshooting
|
||||
|
||||
1. **Connection Issues**: Verify your ProxMox node details in `.env`
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 355 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 323 KiB |
Generated
+1109
-26
File diff suppressed because it is too large
Load Diff
@@ -44,7 +44,9 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^4.21.2",
|
||||
"node-fetch": "^2.7.0",
|
||||
"puppeteer": "^24.3.1",
|
||||
"socket.io": "^4.8.1",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.3",
|
||||
"winston": "^3.17.0"
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# Pulse Development Tools
|
||||
|
||||
**⚠️ DEVELOPMENT USE ONLY ⚠️**
|
||||
|
||||
These tools are for development and testing purposes only. They are not part of the main Pulse application and should not be used in production environments.
|
||||
|
||||
## Mock Data Generator
|
||||
|
||||
This directory contains a tool for generating simulated data for the Pulse application. This is useful for development, testing, and creating documentation without needing a real Proxmox environment.
|
||||
|
||||
### Available Tools
|
||||
|
||||
1. **generate-mock-data.js** - Generates simulated data for the Pulse application
|
||||
2. **debug-socket.js** - Debug proxy for troubleshooting socket communication
|
||||
3. **debug-proxy.sh** - Runs the application with the debug proxy
|
||||
|
||||
### Quick Start
|
||||
|
||||
To use the mock data generator:
|
||||
|
||||
```bash
|
||||
# Start the mock data server
|
||||
node scripts/generate-mock-data.js
|
||||
|
||||
# In another terminal, start the frontend
|
||||
cd frontend
|
||||
VITE_API_URL=http://localhost:7655 npm run dev
|
||||
```
|
||||
|
||||
The mock data server will run on port 7655 and provide simulated data to the frontend.
|
||||
|
||||
### Simulated Data
|
||||
|
||||
The generator creates:
|
||||
|
||||
- A single Proxmox node with realistic specifications
|
||||
- 10 virtual machines with various configurations
|
||||
- 10 containers with various configurations
|
||||
- Realistic resource usage metrics that update every 2 seconds
|
||||
|
||||
The VMs and containers have:
|
||||
- Different operating systems (Ubuntu, Debian, CentOS, Windows, etc.)
|
||||
- Varying CPU, memory, and disk configurations
|
||||
- Realistic network throughput
|
||||
- A mix of running and stopped states
|
||||
|
||||
### Customizing the Data
|
||||
|
||||
You can modify the `generate-mock-data.js` script to change:
|
||||
|
||||
- The node specifications
|
||||
- The number and types of VMs and containers
|
||||
- The resource usage patterns
|
||||
- The update frequency
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you encounter issues with the socket communication, you can use the debug proxy:
|
||||
|
||||
```bash
|
||||
./scripts/debug-proxy.sh
|
||||
```
|
||||
|
||||
This will run the application with a debug proxy that logs all socket messages to `socket-debug.log`.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Pulse Scripts
|
||||
|
||||
This directory contains various scripts used for development, testing, and maintenance of the Pulse application.
|
||||
|
||||
## Development Tools
|
||||
|
||||
These scripts are for development and testing purposes only. They are not part of the main Pulse application and should not be used in production environments.
|
||||
|
||||
For more information about the development tools, see [README-dev-tools.md](README-dev-tools.md).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
- **generate-mock-data.js** - Generates simulated data for development and testing
|
||||
- **debug-socket.js** - Debug proxy for troubleshooting socket communication
|
||||
- **debug-proxy.sh** - Runs the application with the debug proxy
|
||||
|
||||
## Production Scripts
|
||||
|
||||
There are currently no production scripts in this directory.
|
||||
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Pulse Debug Proxy
|
||||
# This script handles everything needed for testing with simulated data
|
||||
# and includes a debug proxy to log all socket.io messages
|
||||
|
||||
# Colors for terminal output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Port configuration
|
||||
MOCK_PORT=7655
|
||||
PROXY_PORT=7656
|
||||
FRONTEND_PORT=3000
|
||||
|
||||
echo -e "${BLUE}"
|
||||
echo "╔════════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ Pulse Debug Proxy ║"
|
||||
echo "║ ║"
|
||||
echo "║ This script will: ║"
|
||||
echo "║ 1. Kill any existing Node.js processes ║"
|
||||
echo "║ 2. Start the mock data server ║"
|
||||
echo "║ 3. Start the debug proxy ║"
|
||||
echo "║ 4. Start the frontend with connection to the proxy ║"
|
||||
echo "║ 5. Log all socket.io messages for debugging ║"
|
||||
echo "║ ║"
|
||||
echo "╚════════════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Check for required commands
|
||||
if ! command_exists node; then
|
||||
echo -e "${RED}Error: Node.js is not installed. Please install Node.js to continue.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Kill any existing Node.js processes
|
||||
echo -e "${YELLOW}Killing any existing Node.js processes...${NC}"
|
||||
pkill -f "node scripts/generate-mock-data.js" 2>/dev/null
|
||||
pkill -f "node scripts/debug-socket.js" 2>/dev/null
|
||||
pkill -f "vite" 2>/dev/null
|
||||
sleep 1
|
||||
|
||||
# Check if ports are in use
|
||||
port_check() {
|
||||
lsof -i:$1 >/dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
if port_check $MOCK_PORT; then
|
||||
echo -e "${RED}Error: Port $MOCK_PORT is already in use. Please free this port and try again.${NC}"
|
||||
echo -e "${YELLOW}You can try: lsof -i:$MOCK_PORT to see what's using it.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if port_check $PROXY_PORT; then
|
||||
echo -e "${RED}Error: Port $PROXY_PORT is already in use. Please free this port and try again.${NC}"
|
||||
echo -e "${YELLOW}You can try: lsof -i:$PROXY_PORT to see what's using it.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if port_check $FRONTEND_PORT; then
|
||||
echo -e "${RED}Error: Port $FRONTEND_PORT is already in use. Please free this port and try again.${NC}"
|
||||
echo -e "${YELLOW}You can try: lsof -i:$FRONTEND_PORT to see what's using it.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the mock data server
|
||||
echo -e "${GREEN}Starting mock data server on port $MOCK_PORT...${NC}"
|
||||
node scripts/generate-mock-data.js > /tmp/pulse-mock-server.log 2>&1 &
|
||||
MOCK_PID=$!
|
||||
|
||||
# Wait for the mock server to start
|
||||
echo -e "${YELLOW}Waiting for mock server to start...${NC}"
|
||||
sleep 2
|
||||
|
||||
# Check if mock server is running
|
||||
if ! ps -p $MOCK_PID > /dev/null; then
|
||||
echo -e "${RED}Error: Mock server failed to start. Check /tmp/pulse-mock-server.log for details.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the debug proxy
|
||||
echo -e "${GREEN}Starting debug proxy on port $PROXY_PORT...${NC}"
|
||||
node scripts/debug-socket.js > /tmp/pulse-debug-proxy.log 2>&1 &
|
||||
PROXY_PID=$!
|
||||
|
||||
# Wait for the proxy to start
|
||||
echo -e "${YELLOW}Waiting for debug proxy to start...${NC}"
|
||||
sleep 2
|
||||
|
||||
# Check if proxy is running
|
||||
if ! ps -p $PROXY_PID > /dev/null; then
|
||||
echo -e "${RED}Error: Debug proxy failed to start. Check /tmp/pulse-debug-proxy.log for details.${NC}"
|
||||
kill $MOCK_PID
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the frontend
|
||||
echo -e "${GREEN}Starting frontend on port $FRONTEND_PORT...${NC}"
|
||||
cd frontend && VITE_API_URL=http://localhost:$PROXY_PORT npm run dev > /tmp/pulse-frontend.log 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
# Wait for the frontend to start
|
||||
echo -e "${YELLOW}Waiting for frontend to start...${NC}"
|
||||
sleep 5
|
||||
|
||||
# Check if frontend is running
|
||||
if ! ps -p $FRONTEND_PID > /dev/null; then
|
||||
echo -e "${RED}Error: Frontend failed to start. Check /tmp/pulse-frontend.log for details.${NC}"
|
||||
kill $MOCK_PID
|
||||
kill $PROXY_PID
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Open the browser
|
||||
echo -e "${GREEN}Opening browser to http://localhost:$FRONTEND_PORT${NC}"
|
||||
if command_exists open; then
|
||||
# macOS
|
||||
open "http://localhost:$FRONTEND_PORT"
|
||||
elif command_exists xdg-open; then
|
||||
# Linux
|
||||
xdg-open "http://localhost:$FRONTEND_PORT"
|
||||
elif command_exists explorer; then
|
||||
# Windows
|
||||
explorer "http://localhost:$FRONTEND_PORT"
|
||||
else
|
||||
echo -e "${YELLOW}Could not automatically open browser. Please open http://localhost:$FRONTEND_PORT manually.${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Everything is running in debug mode!${NC}"
|
||||
echo -e "${YELLOW}All socket.io messages are being logged to ./socket-debug.log${NC}"
|
||||
echo -e "${YELLOW}Press Ctrl+C when you're done to stop all processes.${NC}"
|
||||
|
||||
# Function to clean up on exit
|
||||
cleanup() {
|
||||
echo -e "\n${GREEN}Cleaning up...${NC}"
|
||||
kill $MOCK_PID 2>/dev/null
|
||||
kill $PROXY_PID 2>/dev/null
|
||||
kill $FRONTEND_PID 2>/dev/null
|
||||
echo -e "${GREEN}Done! Debug logs are available in ./socket-debug.log${NC}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Set up trap to catch Ctrl+C
|
||||
trap cleanup SIGINT
|
||||
|
||||
# Wait for user to press Ctrl+C
|
||||
wait
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Socket.io Debug Proxy for Pulse
|
||||
*
|
||||
* This script creates a proxy server that sits between the frontend and backend,
|
||||
* logging all socket.io messages to help debug connection issues.
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const http = require('http');
|
||||
const { Server: SocketServer } = require('socket.io');
|
||||
const { io: SocketClient } = require('socket.io-client');
|
||||
const fs = require('fs');
|
||||
|
||||
// Create Express app and HTTP server for the proxy
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = new SocketServer(server, {
|
||||
cors: {
|
||||
origin: '*',
|
||||
methods: ['GET', 'POST']
|
||||
}
|
||||
});
|
||||
|
||||
// Configuration
|
||||
const PROXY_PORT = 7656;
|
||||
const BACKEND_PORT = 7655;
|
||||
const BACKEND_URL = `http://localhost:${BACKEND_PORT}`;
|
||||
const LOG_FILE = './socket-debug.log';
|
||||
|
||||
// Clear previous log file
|
||||
fs.writeFileSync(LOG_FILE, '--- Socket.io Debug Log ---\n\n');
|
||||
|
||||
// Helper function to log messages
|
||||
const logMessage = (direction, type, data) => {
|
||||
const timestamp = new Date().toISOString();
|
||||
const message = `[${timestamp}] ${direction} | ${type} | ${JSON.stringify(data, null, 2)}\n`;
|
||||
|
||||
console.log(`${direction} | ${type}`);
|
||||
fs.appendFileSync(LOG_FILE, message);
|
||||
};
|
||||
|
||||
// Connect to the real backend with reconnection options
|
||||
const backendSocket = SocketClient(BACKEND_URL, {
|
||||
transports: ['websocket', 'polling'],
|
||||
reconnection: true,
|
||||
reconnectionAttempts: 10,
|
||||
reconnectionDelay: 1000
|
||||
});
|
||||
|
||||
// Handle connections from the frontend
|
||||
io.on('connection', (frontendSocket) => {
|
||||
console.log(`Frontend connected: ${frontendSocket.id}`);
|
||||
logMessage('INFO', 'FRONTEND_CONNECTED', { socketId: frontendSocket.id });
|
||||
|
||||
// Request initial data from backend when frontend connects
|
||||
// This ensures we capture the initial data messages
|
||||
if (backendSocket.connected) {
|
||||
console.log('Requesting initial data from backend');
|
||||
logMessage('INFO', 'REQUESTING_INITIAL_DATA', {});
|
||||
|
||||
// Emit a custom message to request initial data
|
||||
// The backend should respond with the initial data messages
|
||||
backendSocket.emit('requestInitialData');
|
||||
}
|
||||
|
||||
// Handle messages from frontend to backend
|
||||
frontendSocket.onAny((event, ...args) => {
|
||||
logMessage('FRONTEND → BACKEND', event, args);
|
||||
backendSocket.emit(event, ...args);
|
||||
});
|
||||
|
||||
// Handle disconnection
|
||||
frontendSocket.on('disconnect', () => {
|
||||
console.log(`Frontend disconnected: ${frontendSocket.id}`);
|
||||
logMessage('INFO', 'FRONTEND_DISCONNECTED', { socketId: frontendSocket.id });
|
||||
});
|
||||
|
||||
// Forward backend messages to frontend
|
||||
backendSocket.onAny((event, ...args) => {
|
||||
logMessage('BACKEND → FRONTEND', event, args);
|
||||
frontendSocket.emit(event, ...args);
|
||||
});
|
||||
});
|
||||
|
||||
// Handle backend connection events
|
||||
backendSocket.on('connect', () => {
|
||||
console.log(`Connected to backend: ${backendSocket.id}`);
|
||||
logMessage('INFO', 'BACKEND_CONNECTED', { socketId: backendSocket.id });
|
||||
});
|
||||
|
||||
backendSocket.on('reconnect', (attemptNumber) => {
|
||||
console.log(`Reconnected to backend after ${attemptNumber} attempts`);
|
||||
logMessage('INFO', 'BACKEND_RECONNECTED', { attemptNumber });
|
||||
});
|
||||
|
||||
backendSocket.on('disconnect', () => {
|
||||
console.log('Disconnected from backend');
|
||||
logMessage('INFO', 'BACKEND_DISCONNECTED', {});
|
||||
});
|
||||
|
||||
backendSocket.on('connect_error', (err) => {
|
||||
console.error(`Backend connection error: ${err.message}`);
|
||||
logMessage('ERROR', 'BACKEND_CONNECTION_ERROR', { error: err.message });
|
||||
});
|
||||
|
||||
// Start the proxy server
|
||||
server.listen(PROXY_PORT, () => {
|
||||
console.log(`
|
||||
╔════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ Socket.io Debug Proxy ║
|
||||
║ ║
|
||||
║ Proxy running on port ${PROXY_PORT} ║
|
||||
║ Forwarding to backend on port ${BACKEND_PORT} ║
|
||||
║ ║
|
||||
║ All messages are being logged to ${LOG_FILE} ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════════════════╝
|
||||
`);
|
||||
});
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* Mock Data Generator for Pulse
|
||||
*
|
||||
* This script generates simulated data for development and testing.
|
||||
* It overrides the socket connection to provide consistent, visually appealing data.
|
||||
*
|
||||
* Usage:
|
||||
* 1. Run this script with Node.js
|
||||
* 2. Open the app in your browser
|
||||
* 3. Use the app with simulated data
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const http = require('http');
|
||||
const { Server } = require('socket.io');
|
||||
const path = require('path');
|
||||
|
||||
// Create Express app and HTTP server
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = new Server(server, {
|
||||
cors: {
|
||||
origin: '*',
|
||||
methods: ['GET', 'POST']
|
||||
}
|
||||
});
|
||||
|
||||
// Port for the mock server
|
||||
const PORT = 7655;
|
||||
|
||||
// Generate a random number between min and max
|
||||
const randomBetween = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
|
||||
|
||||
// Generate a random floating point number between min and max with specified precision
|
||||
const randomFloatBetween = (min, max, precision = 2) => {
|
||||
const value = Math.random() * (max - min) + min;
|
||||
return parseFloat(value.toFixed(precision));
|
||||
};
|
||||
|
||||
// Generate a random IP address
|
||||
const randomIP = () => {
|
||||
return `192.168.${randomBetween(1, 254)}.${randomBetween(1, 254)}`;
|
||||
};
|
||||
|
||||
// Generate a random MAC address
|
||||
const randomMAC = () => {
|
||||
return Array(6).fill(0).map(() => {
|
||||
const part = randomBetween(0, 255).toString(16);
|
||||
return part.length === 1 ? `0${part}` : part;
|
||||
}).join(':');
|
||||
};
|
||||
|
||||
// Generate node data
|
||||
const generateNodes = () => {
|
||||
return [
|
||||
{
|
||||
id: "node-1",
|
||||
name: "proxmox-01",
|
||||
status: "online",
|
||||
ip: "192.168.1.100",
|
||||
uptime: 1209600, // 14 days
|
||||
cpu: {
|
||||
cores: 32,
|
||||
usage: 45.5
|
||||
},
|
||||
memory: {
|
||||
total: 137438953472, // 128 GB
|
||||
used: 35.2
|
||||
},
|
||||
disk: {
|
||||
total: 4398046511104, // 4 TB
|
||||
used: 42.8
|
||||
},
|
||||
network: {
|
||||
interfaces: ["eth0", "eth1"],
|
||||
throughput: {
|
||||
in: 52428800, // 50 MB/s
|
||||
out: 20971520 // 20 MB/s
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
// Generate guest data with explicit VM and container types
|
||||
const generateGuests = () => {
|
||||
// VM names and OS combinations
|
||||
const vmTemplates = [
|
||||
{ name: "ubuntu-web", os: "ubuntu" },
|
||||
{ name: "debian-db", os: "debian" },
|
||||
{ name: "centos-app", os: "centos" },
|
||||
{ name: "windows-ad", os: "windows" },
|
||||
{ name: "fedora-dev", os: "fedora" },
|
||||
{ name: "arch-build", os: "arch" },
|
||||
{ name: "windows-rdp", os: "windows" },
|
||||
{ name: "ubuntu-mail", os: "ubuntu" },
|
||||
{ name: "debian-proxy", os: "debian" },
|
||||
{ name: "centos-monitor", os: "centos" }
|
||||
];
|
||||
|
||||
// Container names and OS combinations
|
||||
const containerTemplates = [
|
||||
{ name: "nginx-proxy", os: "alpine" },
|
||||
{ name: "postgres-db", os: "debian" },
|
||||
{ name: "redis-cache", os: "alpine" },
|
||||
{ name: "nodejs-api", os: "debian" },
|
||||
{ name: "python-worker", os: "alpine" },
|
||||
{ name: "php-app", os: "debian" },
|
||||
{ name: "mariadb-db", os: "debian" },
|
||||
{ name: "mongodb-db", os: "debian" },
|
||||
{ name: "haproxy-lb", os: "alpine" },
|
||||
{ name: "elasticsearch", os: "debian" }
|
||||
];
|
||||
|
||||
const guests = [];
|
||||
|
||||
// Generate VMs (10 VMs)
|
||||
vmTemplates.forEach((template, index) => {
|
||||
const vmId = 100 + index;
|
||||
const cpuCores = randomBetween(2, 8);
|
||||
const memoryGB = cpuCores * 2; // 2GB per core as a rule of thumb
|
||||
const diskGB = randomBetween(50, 200);
|
||||
|
||||
guests.push({
|
||||
id: `vm-${vmId}`,
|
||||
name: `${template.name}-${vmId}`,
|
||||
node: "node-1",
|
||||
type: "qemu",
|
||||
status: Math.random() > 0.2 ? "running" : "stopped", // 80% running, 20% stopped
|
||||
os: template.os,
|
||||
ip: Math.random() > 0.2 ? randomIP() : null, // 80% have IPs
|
||||
mac: randomMAC(),
|
||||
uptime: Math.random() > 0.2 ? randomBetween(3600, 2592000) : 0, // 1 hour to 30 days
|
||||
cpu: {
|
||||
cores: cpuCores,
|
||||
usage: Math.random() > 0.2 ? randomFloatBetween(5, 85) : 0
|
||||
},
|
||||
memory: {
|
||||
total: memoryGB * 1073741824, // Convert GB to bytes
|
||||
used: Math.random() > 0.2 ? randomFloatBetween(10, 90) : 0
|
||||
},
|
||||
disk: {
|
||||
total: diskGB * 1073741824, // Convert GB to bytes
|
||||
used: Math.random() > 0.2 ? randomFloatBetween(10, 80) : 0
|
||||
},
|
||||
network: {
|
||||
interfaces: ["eth0"],
|
||||
throughput: {
|
||||
in: Math.random() > 0.2 ? randomBetween(1048576, 20971520) : 0, // 1-20 MB/s
|
||||
out: Math.random() > 0.2 ? randomBetween(524288, 10485760) : 0 // 0.5-10 MB/s
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Generate Containers (10 containers)
|
||||
containerTemplates.forEach((template, index) => {
|
||||
const containerId = 200 + index;
|
||||
const cpuCores = randomBetween(1, 4);
|
||||
const memoryGB = cpuCores; // 1GB per core for containers
|
||||
const diskGB = randomBetween(10, 50);
|
||||
|
||||
guests.push({
|
||||
id: `ct-${containerId}`,
|
||||
name: `${template.name}-${containerId}`,
|
||||
node: "node-1",
|
||||
type: "lxc",
|
||||
status: Math.random() > 0.2 ? "running" : "stopped", // 80% running, 20% stopped
|
||||
os: template.os,
|
||||
ip: Math.random() > 0.2 ? randomIP() : null, // 80% have IPs
|
||||
mac: randomMAC(),
|
||||
uptime: Math.random() > 0.2 ? randomBetween(3600, 2592000) : 0, // 1 hour to 30 days
|
||||
cpu: {
|
||||
cores: cpuCores,
|
||||
usage: Math.random() > 0.2 ? randomFloatBetween(5, 85) : 0
|
||||
},
|
||||
memory: {
|
||||
total: memoryGB * 1073741824, // Convert GB to bytes
|
||||
used: Math.random() > 0.2 ? randomFloatBetween(10, 90) : 0
|
||||
},
|
||||
disk: {
|
||||
total: diskGB * 1073741824, // Convert GB to bytes
|
||||
used: Math.random() > 0.2 ? randomFloatBetween(10, 80) : 0
|
||||
},
|
||||
network: {
|
||||
interfaces: ["eth0"],
|
||||
throughput: {
|
||||
in: Math.random() > 0.2 ? randomBetween(524288, 10485760) : 0, // 0.5-10 MB/s
|
||||
out: Math.random() > 0.2 ? randomBetween(262144, 5242880) : 0 // 0.25-5 MB/s
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return guests;
|
||||
};
|
||||
|
||||
// Generate metrics data with the exact same structure as the guests
|
||||
const generateMetrics = (guests) => {
|
||||
// Create a metrics array with the same structure that your app expects
|
||||
const metrics = [];
|
||||
|
||||
// For each guest, create a metrics entry
|
||||
guests.forEach(guest => {
|
||||
if (guest.status === 'running') {
|
||||
// For running guests, use their current values
|
||||
metrics.push({
|
||||
guestId: guest.id,
|
||||
timestamp: Date.now(),
|
||||
metrics: { // Add this wrapper object to match the expected structure
|
||||
cpu: guest.cpu.usage,
|
||||
memory: {
|
||||
total: guest.memory.total,
|
||||
used: guest.memory.used,
|
||||
percentUsed: guest.memory.used // This is already a percentage in our mock data
|
||||
},
|
||||
disk: {
|
||||
total: guest.disk.total,
|
||||
used: guest.disk.used,
|
||||
percentUsed: guest.disk.used // This is already a percentage in our mock data
|
||||
},
|
||||
network: {
|
||||
inRate: guest.network.throughput.in,
|
||||
outRate: guest.network.throughput.out,
|
||||
history: Array(10).fill(0).map(() => ({
|
||||
in: randomBetween(Math.max(0, guest.network.throughput.in * 0.8), guest.network.throughput.in * 1.2),
|
||||
out: randomBetween(Math.max(0, guest.network.throughput.out * 0.8), guest.network.throughput.out * 1.2)
|
||||
}))
|
||||
}
|
||||
},
|
||||
history: {
|
||||
cpu: Array(10).fill(0).map(() =>
|
||||
randomFloatBetween(Math.max(0, guest.cpu.usage - 20), Math.min(100, guest.cpu.usage + 20))
|
||||
),
|
||||
memory: Array(10).fill(0).map(() =>
|
||||
randomFloatBetween(Math.max(0, guest.memory.used - 15), Math.min(100, guest.memory.used + 15))
|
||||
),
|
||||
disk: Array(10).fill(0).map(() =>
|
||||
randomFloatBetween(Math.max(0, guest.disk.used - 5), Math.min(100, guest.disk.used + 5))
|
||||
)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return metrics;
|
||||
};
|
||||
|
||||
// Function to send initial data to a socket
|
||||
const sendInitialData = (socket) => {
|
||||
// Generate simulated data with hardcoded values
|
||||
const nodes = generateNodes();
|
||||
const guests = generateGuests();
|
||||
|
||||
// Log what we're sending
|
||||
console.log(`Sending data for ${nodes.length} nodes and ${guests.length} guests`);
|
||||
|
||||
// Send initial data
|
||||
socket.emit('message', { type: 'CONNECTED', payload: { server: 'Pulse Mock Data Generator' } });
|
||||
console.log('Sent CONNECTED message');
|
||||
|
||||
socket.emit('message', { type: 'NODE_STATUS_UPDATE', payload: nodes });
|
||||
console.log('Sent NODE_STATUS_UPDATE message');
|
||||
|
||||
socket.emit('message', { type: 'GUEST_STATUS_UPDATE', payload: guests });
|
||||
console.log('Sent GUEST_STATUS_UPDATE message');
|
||||
|
||||
// Generate and send initial metrics
|
||||
const metrics = generateMetrics(guests);
|
||||
console.log(`Sending metrics for ${metrics.length} guests`);
|
||||
|
||||
socket.emit('message', { type: 'METRICS_UPDATE', payload: metrics });
|
||||
console.log('Sent initial METRICS_UPDATE message');
|
||||
|
||||
return { nodes, guests, metrics };
|
||||
};
|
||||
|
||||
// Socket.io connection handler
|
||||
io.on('connection', (socket) => {
|
||||
console.log('Client connected with ID:', socket.id);
|
||||
|
||||
// Send initial data
|
||||
const { nodes, guests } = sendInitialData(socket);
|
||||
|
||||
// Handle request for initial data
|
||||
socket.on('requestInitialData', () => {
|
||||
console.log('Received request for initial data from client:', socket.id);
|
||||
sendInitialData(socket);
|
||||
});
|
||||
|
||||
// Send updated metrics every 2 seconds
|
||||
const metricsInterval = setInterval(() => {
|
||||
const updatedMetrics = generateMetrics(guests);
|
||||
socket.emit('message', { type: 'METRICS_UPDATE', payload: updatedMetrics });
|
||||
console.log(`Sent updated metrics at ${new Date().toLocaleTimeString()}`);
|
||||
}, 2000);
|
||||
|
||||
// Clean up on disconnect
|
||||
socket.on('disconnect', () => {
|
||||
console.log('Client disconnected:', socket.id);
|
||||
clearInterval(metricsInterval);
|
||||
});
|
||||
});
|
||||
|
||||
// Start the server
|
||||
server.listen(PORT, () => {
|
||||
console.log(`
|
||||
╔════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ Pulse Mock Data Generator ║
|
||||
║ ║
|
||||
║ Server running on port ${PORT} ║
|
||||
║ ║
|
||||
║ To use: ║
|
||||
║ 1. Make sure your frontend is connected to this server ║
|
||||
║ 2. Use the app with simulated data ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════════════════╝
|
||||
`);
|
||||
});
|
||||
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
# Pulse Mock Data Helper
|
||||
# This script handles everything needed for running Pulse with simulated data
|
||||
|
||||
# Colors for terminal output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to display a fancy header
|
||||
function display_header {
|
||||
clear
|
||||
echo -e "${BLUE}╔═════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}║ Pulse Mock Data Helper ║${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}╚═════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Display the header
|
||||
display_header
|
||||
|
||||
# Check if we're in the right directory
|
||||
if [ ! -f "package.json" ]; then
|
||||
echo -e "${RED}Error: This script must be run from the root of the Pulse project.${NC}"
|
||||
echo -e "${YELLOW}Please cd to the project root and try again.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Kill any existing processes
|
||||
echo -e "${YELLOW}Cleaning up any existing processes...${NC}"
|
||||
pkill -f "node scripts/generate-mock-data.js" 2>/dev/null
|
||||
pkill -f "node scripts/debug-socket.js" 2>/dev/null
|
||||
pkill -f "npm run dev" 2>/dev/null
|
||||
pkill -f "vite" 2>/dev/null
|
||||
|
||||
# Wait a moment for processes to terminate
|
||||
sleep 1
|
||||
|
||||
# Check if ports are in use
|
||||
function check_port {
|
||||
if lsof -i:$1 > /dev/null 2>&1; then
|
||||
echo -e "${RED}Error: Port $1 is already in use. Please free this port and try again.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_port 7655 # Mock data server port
|
||||
check_port 5173 # Vite dev server port
|
||||
|
||||
# Start the mock data server
|
||||
echo -e "${GREEN}Starting mock data server...${NC}"
|
||||
node scripts/generate-mock-data.js > /tmp/pulse-mock-server.log 2>&1 &
|
||||
MOCK_SERVER_PID=$!
|
||||
|
||||
# Wait for the mock data server to start
|
||||
echo -e "${YELLOW}Waiting for mock data server to start...${NC}"
|
||||
sleep 2
|
||||
|
||||
# Check if the mock data server is running
|
||||
if ! ps -p $MOCK_SERVER_PID > /dev/null; then
|
||||
echo -e "${RED}Error: Mock data server failed to start.${NC}"
|
||||
echo -e "${YELLOW}Check the logs at /tmp/pulse-mock-server.log for details.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the frontend
|
||||
echo -e "${GREEN}Starting frontend...${NC}"
|
||||
cd frontend
|
||||
VITE_API_URL=http://localhost:7655 npm run dev > /tmp/pulse-frontend.log 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
# Wait for the frontend to start
|
||||
echo -e "${YELLOW}Waiting for frontend to start...${NC}"
|
||||
sleep 5
|
||||
|
||||
# Check if the frontend is running
|
||||
if ! ps -p $FRONTEND_PID > /dev/null; then
|
||||
echo -e "${RED}Error: Frontend failed to start.${NC}"
|
||||
echo -e "${YELLOW}Check the logs at /tmp/pulse-frontend.log for details.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Open the browser
|
||||
echo -e "${GREEN}Opening browser...${NC}"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
open http://localhost:5173
|
||||
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
xdg-open http://localhost:5173
|
||||
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
||||
start http://localhost:5173
|
||||
else
|
||||
echo -e "${YELLOW}Please open http://localhost:5173 in your browser.${NC}"
|
||||
fi
|
||||
|
||||
# Display success message
|
||||
echo -e "${GREEN}Everything is running! The application is now available at http://localhost:5173${NC}"
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop all processes when you're done.${NC}"
|
||||
|
||||
# Wait for user to press Ctrl+C
|
||||
trap "echo -e '${YELLOW}Stopping all processes...${NC}'; kill $MOCK_SERVER_PID $FRONTEND_PID 2>/dev/null; echo -e '${GREEN}Done! All processes have been stopped.${NC}'; exit 0" INT
|
||||
wait
|
||||
Reference in New Issue
Block a user