ezpm2gui 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +202 -14
- package/bin/ezpm2gui.js +40 -44
- package/bin/ezpm2gui.ts +51 -0
- package/bin/generate-ecosystem.js +24 -22
- package/bin/generate-ecosystem.ts +56 -0
- package/dist/server/config/project-configs.json +236 -0
- package/dist/server/index.js +64 -19
- package/dist/server/logs/deployment.log +12 -0
- package/dist/server/routes/clusterManagement.d.ts +3 -0
- package/dist/server/routes/clusterManagement.js +152 -0
- package/dist/server/routes/deployApplication.d.ts +3 -0
- package/dist/server/routes/deployApplication.js +310 -0
- package/dist/server/routes/logStreaming.d.ts +5 -0
- package/dist/server/routes/logStreaming.js +276 -0
- package/dist/server/routes/modules.d.ts +3 -0
- package/dist/server/routes/modules.js +106 -0
- package/dist/server/routes/processConfig.d.ts +3 -0
- package/dist/server/routes/processConfig.js +118 -0
- package/dist/server/routes/remoteConnections.d.ts +3 -0
- package/dist/server/routes/remoteConnections.js +634 -0
- package/dist/server/services/ProjectSetupService.d.ts +72 -0
- package/dist/server/services/ProjectSetupService.js +327 -0
- package/dist/server/utils/dialog.d.ts +1 -0
- package/dist/server/utils/dialog.js +16 -0
- package/dist/server/utils/encryption.d.ts +12 -0
- package/dist/server/utils/encryption.js +72 -0
- package/dist/server/utils/pm2-connection.d.ts +16 -0
- package/dist/server/utils/pm2-connection.js +141 -0
- package/dist/server/utils/remote-connection.d.ts +152 -0
- package/dist/server/utils/remote-connection.js +590 -0
- package/dist/server/utils/upload.d.ts +3 -0
- package/dist/server/utils/upload.js +39 -0
- package/package.json +65 -49
- package/src/client/build/asset-manifest.json +6 -6
- package/src/client/build/favicon.ico +2 -0
- package/src/client/build/index.html +1 -1
- package/src/client/build/logo192.svg +7 -0
- package/src/client/build/logo512.svg +7 -0
- package/src/client/build/manifest.json +5 -6
- package/src/client/build/static/css/main.672b8f26.css +2 -0
- package/src/client/build/static/css/main.672b8f26.css.map +1 -0
- package/src/client/build/static/js/main.31323a04.js +156 -0
- package/src/client/build/static/js/{main.dde30e92.js.LICENSE.txt → main.31323a04.js.LICENSE.txt} +19 -0
- package/src/client/build/static/js/main.31323a04.js.map +1 -0
- package/ .npmignore +0 -39
- package/install.bat +0 -22
- package/install.sh +0 -23
- package/src/client/build/static/css/main.c1cbda3a.css +0 -2
- package/src/client/build/static/css/main.c1cbda3a.css.map +0 -1
- package/src/client/build/static/js/main.dde30e92.js +0 -3
- package/src/client/build/static/js/main.dde30e92.js.map +0 -1
- package/src/client/package-lock.json +0 -16192
- package/src/client/package.json +0 -39
- package/src/client/public/index.html +0 -20
- package/src/client/public/manifest.json +0 -25
- package/src/index.ts +0 -24
- package/src/server/index.ts +0 -240
- package/tsconfig.json +0 -18
package/src/client/package.json
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ezpm2gui-client",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"dependencies": {
|
|
6
|
-
"axios": "^1.9.0",
|
|
7
|
-
"chart.js": "^4.4.9",
|
|
8
|
-
"react": "^18.2.0",
|
|
9
|
-
"react-dom": "^18.2.0",
|
|
10
|
-
"react-chartjs-2": "^5.2.0",
|
|
11
|
-
"react-scripts": "5.0.1",
|
|
12
|
-
"socket.io-client": "^4.8.1"
|
|
13
|
-
},
|
|
14
|
-
"scripts": {
|
|
15
|
-
"start": "react-scripts start",
|
|
16
|
-
"build": "react-scripts build",
|
|
17
|
-
"test": "react-scripts test",
|
|
18
|
-
"eject": "react-scripts eject"
|
|
19
|
-
},
|
|
20
|
-
"eslintConfig": {
|
|
21
|
-
"extends": [
|
|
22
|
-
"react-app",
|
|
23
|
-
"react-app/jest"
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
"browserslist": {
|
|
27
|
-
"production": [
|
|
28
|
-
">0.2%",
|
|
29
|
-
"not dead",
|
|
30
|
-
"not op_mini all"
|
|
31
|
-
],
|
|
32
|
-
"development": [
|
|
33
|
-
"last 1 chrome version",
|
|
34
|
-
"last 1 firefox version",
|
|
35
|
-
"last 1 safari version"
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
"proxy": "http://localhost:3001"
|
|
39
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<meta name="theme-color" content="#4a90e2" />
|
|
8
|
-
<meta
|
|
9
|
-
name="description"
|
|
10
|
-
content="ezPM2GUI - A modern interface for PM2 process manager"
|
|
11
|
-
/>
|
|
12
|
-
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
13
|
-
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
14
|
-
<title>ezPM2GUI - PM2 Process Manager</title>
|
|
15
|
-
</head>
|
|
16
|
-
<body>
|
|
17
|
-
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
18
|
-
<div id="root"></div>
|
|
19
|
-
</body>
|
|
20
|
-
</html>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"short_name": "ezPM2GUI",
|
|
3
|
-
"name": "ezPM2GUI - Modern PM2 Interface",
|
|
4
|
-
"icons": [
|
|
5
|
-
{
|
|
6
|
-
"src": "favicon.ico",
|
|
7
|
-
"sizes": "64x64 32x32 24x24 16x16",
|
|
8
|
-
"type": "image/x-icon"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"src": "logo192.png",
|
|
12
|
-
"type": "image/png",
|
|
13
|
-
"sizes": "192x192"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"src": "logo512.png",
|
|
17
|
-
"type": "image/png",
|
|
18
|
-
"sizes": "512x512"
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
"start_url": ".",
|
|
22
|
-
"display": "standalone",
|
|
23
|
-
"theme_color": "#4a90e2",
|
|
24
|
-
"background_color": "#f8f9fa"
|
|
25
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// src/index.ts - Main entry point for programmatic usage
|
|
2
|
-
import { createServer } from './server/index';
|
|
3
|
-
|
|
4
|
-
interface StartOptions {
|
|
5
|
-
port?: number;
|
|
6
|
-
host?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Start the ezPM2GUI server
|
|
11
|
-
* @param options Configuration options
|
|
12
|
-
* @returns The HTTP server instance
|
|
13
|
-
*/
|
|
14
|
-
export function start(options: StartOptions = {}) {
|
|
15
|
-
const port = options.port || process.env.PORT || 3001;
|
|
16
|
-
const host = options.host || process.env.HOST || 'localhost';
|
|
17
|
-
|
|
18
|
-
process.env.PORT = port.toString();
|
|
19
|
-
process.env.HOST = host;
|
|
20
|
-
|
|
21
|
-
return createServer();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default { start };
|
package/src/server/index.ts
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import http from 'http';
|
|
3
|
-
import { Server as SocketIOServer } from 'socket.io';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import pm2 from 'pm2';
|
|
6
|
-
import os from 'os';
|
|
7
|
-
import { execSync } from 'child_process';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Create and configure the express server
|
|
11
|
-
*/
|
|
12
|
-
export function createServer() {
|
|
13
|
-
// Initialize Express app
|
|
14
|
-
const app = express();
|
|
15
|
-
const server = http.createServer(app);
|
|
16
|
-
const io = new SocketIOServer(server, {
|
|
17
|
-
cors: {
|
|
18
|
-
origin: '*',
|
|
19
|
-
methods: ['GET', 'POST']
|
|
20
|
-
}
|
|
21
|
-
}); // Serve static files from the React app build directory
|
|
22
|
-
const staticPath = 'D:/Personal/ezpm2gui/src/client/build';
|
|
23
|
-
console.log('Serving static files from:', staticPath);
|
|
24
|
-
const fs = require('fs');
|
|
25
|
-
if (fs.existsSync(staticPath)) {
|
|
26
|
-
app.use(express.static(staticPath));
|
|
27
|
-
} else {
|
|
28
|
-
console.error('Static files directory not found at:', staticPath);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// PM2 API endpoints
|
|
32
|
-
app.get('/api/processes', (req, res) => {
|
|
33
|
-
pm2.connect((err) => {
|
|
34
|
-
if (err) {
|
|
35
|
-
console.error(err);
|
|
36
|
-
res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
pm2.list((err, processList) => {
|
|
41
|
-
pm2.disconnect();
|
|
42
|
-
if (err) {
|
|
43
|
-
console.error(err);
|
|
44
|
-
res.status(500).json({ error: 'Failed to get PM2 processes' });
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
res.json(processList);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Action endpoints (start, stop, restart, delete)
|
|
53
|
-
app.post('/api/process/:id/:action', (req, res) => {
|
|
54
|
-
const { id, action } = req.params;
|
|
55
|
-
|
|
56
|
-
pm2.connect((err) => {
|
|
57
|
-
if (err) {
|
|
58
|
-
console.error(err);
|
|
59
|
-
res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const processAction = (actionName: string, cb: (err: Error | null) => void) => {
|
|
64
|
-
switch (actionName) {
|
|
65
|
-
case 'start':
|
|
66
|
-
pm2.start(id, cb);
|
|
67
|
-
break;
|
|
68
|
-
case 'stop':
|
|
69
|
-
pm2.stop(id, cb);
|
|
70
|
-
break;
|
|
71
|
-
case 'restart':
|
|
72
|
-
pm2.restart(id, cb);
|
|
73
|
-
break;
|
|
74
|
-
case 'delete':
|
|
75
|
-
pm2.delete(id, cb);
|
|
76
|
-
break;
|
|
77
|
-
default:
|
|
78
|
-
cb(new Error('Invalid action'));
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
processAction(action, (err) => {
|
|
83
|
-
pm2.disconnect();
|
|
84
|
-
if (err) {
|
|
85
|
-
console.error(err);
|
|
86
|
-
res.status(500).json({ error: `Failed to ${action} process` });
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
res.json({ success: true, message: `Process ${id} ${action} request received` });
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Get system metrics
|
|
95
|
-
app.get('/api/metrics', (req, res) => {
|
|
96
|
-
const metrics = {
|
|
97
|
-
loadAvg: os.loadavg(),
|
|
98
|
-
memory: {
|
|
99
|
-
total: os.totalmem(),
|
|
100
|
-
free: os.freemem(),
|
|
101
|
-
used: os.totalmem() - os.freemem()
|
|
102
|
-
},
|
|
103
|
-
uptime: os.uptime(),
|
|
104
|
-
cpus: os.cpus().length
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
res.json(metrics);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Get process logs
|
|
111
|
-
app.get('/api/logs/:id/:type', (req, res) => {
|
|
112
|
-
const { id, type } = req.params;
|
|
113
|
-
const logType = type === 'err' ? 'err' : 'out';
|
|
114
|
-
|
|
115
|
-
pm2.connect((err) => {
|
|
116
|
-
if (err) {
|
|
117
|
-
console.error(err);
|
|
118
|
-
res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
pm2.describe(id, (err, processDesc: any) => {
|
|
123
|
-
if (err || !processDesc || processDesc.length === 0) {
|
|
124
|
-
pm2.disconnect();
|
|
125
|
-
res.status(404).json({ error: 'Process not found' });
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const logPath = processDesc[0]?.pm2_env?.[`pm_${logType}_log_path`];
|
|
130
|
-
|
|
131
|
-
if (!logPath) {
|
|
132
|
-
pm2.disconnect();
|
|
133
|
-
res.status(404).json({ error: `Log file for ${logType} not found` });
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
try {
|
|
138
|
-
// Read the log file using Node.js fs instead of exec
|
|
139
|
-
const fs = require('fs');
|
|
140
|
-
let logContent = '';
|
|
141
|
-
|
|
142
|
-
if (fs.existsSync(logPath)) {
|
|
143
|
-
// Read the last part of the file (up to 10KB to avoid huge responses)
|
|
144
|
-
const stats = fs.statSync(logPath);
|
|
145
|
-
const fileSize = stats.size;
|
|
146
|
-
const readSize = Math.min(fileSize, 10 * 1024); // 10KB max
|
|
147
|
-
const position = Math.max(0, fileSize - readSize);
|
|
148
|
-
|
|
149
|
-
const buffer = Buffer.alloc(readSize);
|
|
150
|
-
const fd = fs.openSync(logPath, 'r');
|
|
151
|
-
fs.readSync(fd, buffer, 0, readSize, position);
|
|
152
|
-
fs.closeSync(fd);
|
|
153
|
-
|
|
154
|
-
logContent = buffer.toString('utf8');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const logs = logContent.split('\n').filter((line: string) => line.trim() !== '');
|
|
158
|
-
|
|
159
|
-
pm2.disconnect();
|
|
160
|
-
res.json({ logs });
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error(`Error reading log file: ${error}`);
|
|
163
|
-
pm2.disconnect();
|
|
164
|
-
res.status(500).json({ error: 'Failed to read log file' });
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// WebSocket for real-time updates
|
|
171
|
-
io.on('connection', (socket) => {
|
|
172
|
-
console.log('Client connected');
|
|
173
|
-
|
|
174
|
-
// Send process updates every 3 seconds
|
|
175
|
-
const processInterval = setInterval(() => {
|
|
176
|
-
pm2.connect((err) => {
|
|
177
|
-
if (err) {
|
|
178
|
-
console.error(err);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
pm2.list((err, processList) => {
|
|
183
|
-
pm2.disconnect();
|
|
184
|
-
if (err) {
|
|
185
|
-
console.error(err);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
socket.emit('processes', processList);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
}, 3000);
|
|
192
|
-
|
|
193
|
-
// Send system metrics every 2 seconds
|
|
194
|
-
const metricsInterval = setInterval(() => {
|
|
195
|
-
const metrics = {
|
|
196
|
-
loadAvg: os.loadavg(),
|
|
197
|
-
memory: {
|
|
198
|
-
total: os.totalmem(),
|
|
199
|
-
free: os.freemem(),
|
|
200
|
-
used: os.totalmem() - os.freemem()
|
|
201
|
-
},
|
|
202
|
-
uptime: os.uptime(),
|
|
203
|
-
cpus: os.cpus().length
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
socket.emit('metrics', metrics);
|
|
207
|
-
}, 2000);
|
|
208
|
-
|
|
209
|
-
socket.on('disconnect', () => {
|
|
210
|
-
console.log('Client disconnected');
|
|
211
|
-
clearInterval(processInterval);
|
|
212
|
-
clearInterval(metricsInterval);
|
|
213
|
-
});
|
|
214
|
-
}); // Catch-all route to return the React app
|
|
215
|
-
app.get('*', (req, res) => {
|
|
216
|
-
const indexPath = 'D:/Personal/ezpm2gui/src/client/build/index.html';
|
|
217
|
-
console.log('Trying to serve index.html from:', indexPath);
|
|
218
|
-
const fs = require('fs');
|
|
219
|
-
if (fs.existsSync(indexPath)) {
|
|
220
|
-
res.sendFile(indexPath);
|
|
221
|
-
} else {
|
|
222
|
-
console.error('Index.html file not found at:', indexPath);
|
|
223
|
-
res.status(404).send('File not found. Please check server configuration.');
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// Return the server instance
|
|
228
|
-
return server;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Only start the server if this file is run directly
|
|
232
|
-
if (require.main === module) {
|
|
233
|
-
const PORT = process.env.PORT || 3001;
|
|
234
|
-
const HOST = process.env.HOST || 'localhost';
|
|
235
|
-
|
|
236
|
-
const server = createServer();
|
|
237
|
-
server.listen(PORT, () => {
|
|
238
|
-
console.log(`Server running on http://${HOST}:${PORT}`);
|
|
239
|
-
});
|
|
240
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2019",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"lib": ["es2019", "dom"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": false,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"noImplicitAny": false,
|
|
14
|
-
"declaration": true
|
|
15
|
-
},
|
|
16
|
-
"include": ["src/**/*.ts"],
|
|
17
|
-
"exclude": ["node_modules", "**/*.test.ts", "src/client"]
|
|
18
|
-
}
|