ezpm2gui 1.2.2 → 1.3.1
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 +45 -41
- package/dist/server/config/cron-jobs.json +18 -0
- package/dist/server/config/cron-scripts/6d8d5e1d-2bc8-463f-82a6-6c294f2b9dbe.sh +2 -0
- package/dist/server/config/remote-connections.json +22 -0
- package/dist/server/index.js +2 -0
- package/dist/server/routes/cronJobs.d.ts +7 -0
- package/dist/server/routes/cronJobs.js +189 -0
- package/dist/server/routes/remoteConnections.js +105 -0
- package/dist/server/services/CronJobService.d.ts +74 -0
- package/dist/server/services/CronJobService.js +407 -0
- package/dist/server/utils/remote-connection.d.ts +17 -0
- package/dist/server/utils/remote-connection.js +183 -14
- package/package.json +5 -1
- package/src/client/build/asset-manifest.json +6 -6
- package/src/client/build/index.html +1 -1
- package/src/client/build/static/css/main.d46bc75c.css +5 -0
- package/src/client/build/static/css/main.d46bc75c.css.map +1 -0
- package/src/client/build/static/js/main.b0e1c9b1.js +3 -0
- package/src/client/build/static/js/{main.31323a04.js.LICENSE.txt → main.b0e1c9b1.js.LICENSE.txt} +11 -0
- package/src/client/build/static/js/main.b0e1c9b1.js.map +1 -0
- package/src/client/build/static/css/main.672b8f26.css +0 -2
- package/src/client/build/static/css/main.672b8f26.css.map +0 -1
- package/src/client/build/static/js/main.31323a04.js +0 -156
- package/src/client/build/static/js/main.31323a04.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,30 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
A modern web-based graphical user interface for the PM2 process manager, built with TypeScript and Material UI.
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
|
|
7
5
|
## Features
|
|
8
6
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
7
|
+
- **Real-time process monitoring** - Keep track of all your PM2 processes in real-time
|
|
8
|
+
- **Process management** - Start, stop, restart, and delete processes with one click
|
|
9
|
+
- **System metrics dashboard** - Monitor CPU, memory usage, and uptime
|
|
10
|
+
- **Enhanced log streaming** - View and filter logs from multiple processes simultaneously
|
|
11
|
+
- **WebSocket for live updates** - Get instant updates without refreshing
|
|
12
|
+
- **Process CPU and memory charts** - Visualize performance metrics over time
|
|
13
|
+
- **Filter processes by status or name** - Quickly find the processes you need
|
|
14
|
+
- **Dark mode support** - Easy on the eyes for late-night monitoring
|
|
15
|
+
- **Cluster management** - Easily scale your Node.js applications
|
|
16
|
+
- **Application deployment** - Deploy new applications directly from the UI
|
|
17
|
+
- **Ecosystem configuration** - Create and manage your PM2 ecosystem files
|
|
18
|
+
- **PM2 modules support** - Manage and configure PM2 modules
|
|
19
|
+
- **Cron Jobs** - Schedule and manage automated tasks with visual cron expression builder
|
|
20
|
+
- **Remote Server Management** - Connect and manage PM2 on remote servers via SSH
|
|
21
|
+
- **Advanced Monitoring Dashboard** - Real-time performance charts with health scoring
|
|
22
|
+
- **Modern UI with Material UI components** - Clean and intuitive interface
|
|
23
|
+
- **Fully typed with TypeScript** - Robust and maintainable codebase
|
|
23
24
|
|
|
24
25
|
## Detailed Features
|
|
25
26
|
|
|
26
27
|
### Process Monitoring
|
|
27
28
|
Monitor all your PM2 processes in real-time with detailed information on CPU usage, memory consumption, uptime, and status. The intuitive interface makes it easy to identify issues at a glance.
|
|
28
29
|
|
|
30
|
+
### Remote Server Management
|
|
31
|
+
Connect to and manage PM2 processes on remote servers via secure SSH connections:
|
|
32
|
+
- Add multiple remote server connections with SSH credentials
|
|
33
|
+
- View and manage processes on remote servers
|
|
34
|
+
- Stream logs from remote processes in real-time
|
|
35
|
+
- Execute PM2 commands on remote machines
|
|
36
|
+
- Encrypted credential storage for security
|
|
37
|
+
|
|
38
|
+
### Cron Jobs
|
|
39
|
+
Schedule and automate tasks using PM2's cron restart feature:
|
|
40
|
+
- Visual cron expression builder with common presets
|
|
41
|
+
- Support for Node.js, Python, Shell, and .NET scripts
|
|
42
|
+
- Inline script editor or file-based execution
|
|
43
|
+
- Enable/disable jobs without deleting them
|
|
44
|
+
- View next execution times and job status
|
|
45
|
+
|
|
46
|
+
### Advanced Monitoring Dashboard
|
|
47
|
+
Get deeper insights into your system and process performance:
|
|
48
|
+
- Real-time performance charts for CPU, memory, and load
|
|
49
|
+
- System health score calculation
|
|
50
|
+
- Historical metrics tracking
|
|
51
|
+
- Process alerts for high resource usage
|
|
52
|
+
- Per-process performance visualization
|
|
53
|
+
|
|
29
54
|
### Application Deployment
|
|
30
55
|
Deploy new Node.js applications to PM2 directly from the UI. Configure all the necessary options including:
|
|
31
56
|
- Application name and script path
|
|
@@ -41,10 +66,11 @@ Easily scale your Node.js applications with the cluster management interface. Ad
|
|
|
41
66
|
|
|
42
67
|
### Log Streaming
|
|
43
68
|
View and filter logs from multiple processes simultaneously with the enhanced log streaming interface. Features include:
|
|
44
|
-
- Real-time log updates
|
|
45
|
-
- Filtering by log level or content
|
|
69
|
+
- Real-time log updates via WebSocket
|
|
70
|
+
- Filtering by process, log level, or content
|
|
46
71
|
- Pausing and resuming log streams
|
|
47
|
-
-
|
|
72
|
+
- Download logs for offline analysis
|
|
73
|
+
- Floating log panel for remote process logs
|
|
48
74
|
|
|
49
75
|
### Ecosystem Configuration
|
|
50
76
|
Generate and manage PM2 ecosystem configuration files directly from the UI. This makes it easy to set up complex application deployments and share configurations across your team.
|
|
@@ -66,28 +92,6 @@ Customize the ezPM2GUI interface to suit your preferences:
|
|
|
66
92
|
- Configure dashboard refresh intervals
|
|
67
93
|
- Adjust log display settings
|
|
68
94
|
|
|
69
|
-
## Screenshots
|
|
70
|
-
|
|
71
|
-
### Process Monitor
|
|
72
|
-
The main dashboard provides a comprehensive view of all your PM2 processes, showing CPU usage, memory consumption, uptime, and status at a glance.
|
|
73
|
-
|
|
74
|
-

|
|
75
|
-
|
|
76
|
-
### System Metrics & Process Management
|
|
77
|
-
Monitor your system resources and manage PM2 processes with intuitive controls for start, stop, restart, and delete operations.
|
|
78
|
-
|
|
79
|
-

|
|
80
|
-
|
|
81
|
-
### Deploy New Application
|
|
82
|
-
Easily deploy new Node.js applications to PM2 with a user-friendly form interface. Configure all PM2 options including instances, execution mode, working directory, and environment variables.
|
|
83
|
-
|
|
84
|
-

|
|
85
|
-
|
|
86
|
-
### Application Settings
|
|
87
|
-
Customize the ezPM2GUI interface and configure your PM2 connection settings to match your environment.
|
|
88
|
-
|
|
89
|
-

|
|
90
|
-
|
|
91
95
|
## Installation
|
|
92
96
|
|
|
93
97
|
### Global Installation
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "cv-forge",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scriptType": "shell",
|
|
6
|
+
"scriptMode": "inline",
|
|
7
|
+
"scriptPath": "",
|
|
8
|
+
"inlineScript": "echo \"Installing CV Forge\"\nnpm install -g cv-forge",
|
|
9
|
+
"cronExpression": "* * * * *",
|
|
10
|
+
"args": [],
|
|
11
|
+
"env": {},
|
|
12
|
+
"cwd": "",
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"id": "6d8d5e1d-2bc8-463f-82a6-6c294f2b9dbe",
|
|
15
|
+
"createdAt": "2025-11-03T15:46:21.776Z",
|
|
16
|
+
"updatedAt": "2025-11-03T15:50:34.133Z"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"connections": [
|
|
3
|
+
{
|
|
4
|
+
"id": "192.168.50.100-22-oll-dev",
|
|
5
|
+
"name": "ascend",
|
|
6
|
+
"host": "192.168.50.100",
|
|
7
|
+
"port": 22,
|
|
8
|
+
"username": "oll-dev",
|
|
9
|
+
"password": "42eb428a6d0ca614741be36634da53791a5273626acd5d59502780066ce6005e",
|
|
10
|
+
"useSudo": true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "172.26.252.123-22-chandan",
|
|
14
|
+
"name": "wsl",
|
|
15
|
+
"host": "172.26.252.123",
|
|
16
|
+
"port": 22,
|
|
17
|
+
"username": "chandan",
|
|
18
|
+
"password": "65350d6eb4851ac4386b23b596ea08ed",
|
|
19
|
+
"useSudo": true
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/dist/server/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const processConfig_1 = __importDefault(require("./routes/processConfig"));
|
|
|
14
14
|
const deployApplication_1 = __importDefault(require("./routes/deployApplication"));
|
|
15
15
|
const modules_1 = __importDefault(require("./routes/modules"));
|
|
16
16
|
const remoteConnections_1 = __importDefault(require("./routes/remoteConnections"));
|
|
17
|
+
const cronJobs_1 = __importDefault(require("./routes/cronJobs"));
|
|
17
18
|
const logStreaming_1 = require("./routes/logStreaming");
|
|
18
19
|
const pm2_connection_1 = require("./utils/pm2-connection");
|
|
19
20
|
const remote_connection_1 = require("./utils/remote-connection");
|
|
@@ -47,6 +48,7 @@ function createServer() {
|
|
|
47
48
|
app.use('/api/deploy', deployApplication_1.default);
|
|
48
49
|
app.use('/api/modules', modules_1.default);
|
|
49
50
|
app.use('/api/remote', remoteConnections_1.default);
|
|
51
|
+
app.use('/api/cron-jobs', cronJobs_1.default);
|
|
50
52
|
// Setup log streaming with Socket.IO
|
|
51
53
|
(0, logStreaming_1.setupLogStreaming)(io); // PM2 API endpoints
|
|
52
54
|
app.get('/api/processes', async (req, res) => {
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cron Jobs API Routes
|
|
4
|
+
* Manages scheduled tasks using PM2's cron_restart feature
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const express_1 = require("express");
|
|
11
|
+
const CronJobService_1 = __importDefault(require("../services/CronJobService"));
|
|
12
|
+
const router = (0, express_1.Router)();
|
|
13
|
+
/**
|
|
14
|
+
* GET /api/cron-jobs
|
|
15
|
+
* Get all cron jobs
|
|
16
|
+
*/
|
|
17
|
+
router.get('/', async (req, res) => {
|
|
18
|
+
try {
|
|
19
|
+
const jobs = CronJobService_1.default.getCronJobs();
|
|
20
|
+
res.json({ success: true, data: jobs });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('Error getting cron jobs:', error);
|
|
24
|
+
res.status(500).json({ success: false, error: error.message });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* GET /api/cron-jobs/status
|
|
29
|
+
* Get status of all cron jobs including PM2 process info
|
|
30
|
+
*/
|
|
31
|
+
router.get('/status', async (req, res) => {
|
|
32
|
+
try {
|
|
33
|
+
const statuses = await CronJobService_1.default.getCronJobsStatus();
|
|
34
|
+
res.json({ success: true, data: statuses });
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error('Error getting cron job statuses:', error);
|
|
38
|
+
res.status(500).json({ success: false, error: error.message });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* GET /api/cron-jobs/:id
|
|
43
|
+
* Get a specific cron job by ID
|
|
44
|
+
*/
|
|
45
|
+
router.get('/:id', (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const job = CronJobService_1.default.getCronJob(req.params.id);
|
|
48
|
+
if (!job) {
|
|
49
|
+
return res.status(404).json({ success: false, error: 'Cron job not found' });
|
|
50
|
+
}
|
|
51
|
+
res.json({ success: true, data: job });
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error('Error getting cron job:', error);
|
|
55
|
+
res.status(500).json({ success: false, error: error.message });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* POST /api/cron-jobs
|
|
60
|
+
* Create a new cron job
|
|
61
|
+
*/
|
|
62
|
+
router.post('/', async (req, res) => {
|
|
63
|
+
try {
|
|
64
|
+
const config = req.body;
|
|
65
|
+
// Validate required fields
|
|
66
|
+
if (!config.name || !config.scriptType || !config.cronExpression) {
|
|
67
|
+
return res.status(400).json({
|
|
68
|
+
success: false,
|
|
69
|
+
error: 'Missing required fields: name, scriptType, cronExpression'
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Validate script mode specific requirements
|
|
73
|
+
if (config.scriptMode === 'file' && !config.scriptPath) {
|
|
74
|
+
return res.status(400).json({
|
|
75
|
+
success: false,
|
|
76
|
+
error: 'Script path is required when using file mode'
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (config.scriptMode === 'inline' && !config.inlineScript) {
|
|
80
|
+
return res.status(400).json({
|
|
81
|
+
success: false,
|
|
82
|
+
error: 'Inline script content is required when using inline mode'
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const job = await CronJobService_1.default.createCronJob(config);
|
|
86
|
+
res.json({ success: true, data: job });
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error('Error creating cron job:', error);
|
|
90
|
+
res.status(400).json({ success: false, error: error.message });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* PUT /api/cron-jobs/:id
|
|
95
|
+
* Update a cron job
|
|
96
|
+
*/
|
|
97
|
+
router.put('/:id', async (req, res) => {
|
|
98
|
+
try {
|
|
99
|
+
const updates = req.body;
|
|
100
|
+
const job = await CronJobService_1.default.updateCronJob(req.params.id, updates);
|
|
101
|
+
res.json({ success: true, data: job });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Error updating cron job:', error);
|
|
105
|
+
res.status(400).json({ success: false, error: error.message });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* DELETE /api/cron-jobs/:id
|
|
110
|
+
* Delete a cron job
|
|
111
|
+
*/
|
|
112
|
+
router.delete('/:id', async (req, res) => {
|
|
113
|
+
try {
|
|
114
|
+
await CronJobService_1.default.deleteCronJob(req.params.id);
|
|
115
|
+
res.json({ success: true, message: 'Cron job deleted successfully' });
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error('Error deleting cron job:', error);
|
|
119
|
+
res.status(400).json({ success: false, error: error.message });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
/**
|
|
123
|
+
* POST /api/cron-jobs/:id/toggle
|
|
124
|
+
* Toggle cron job enabled state
|
|
125
|
+
*/
|
|
126
|
+
router.post('/:id/toggle', async (req, res) => {
|
|
127
|
+
try {
|
|
128
|
+
const job = await CronJobService_1.default.toggleCronJob(req.params.id);
|
|
129
|
+
res.json({ success: true, data: job });
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error('Error toggling cron job:', error);
|
|
133
|
+
res.status(400).json({ success: false, error: error.message });
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* POST /api/cron-jobs/:id/start
|
|
138
|
+
* Manually start a cron job
|
|
139
|
+
*/
|
|
140
|
+
router.post('/:id/start', async (req, res) => {
|
|
141
|
+
try {
|
|
142
|
+
await CronJobService_1.default.startCronJob(req.params.id);
|
|
143
|
+
res.json({ success: true, message: 'Cron job started successfully' });
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error('Error starting cron job:', error);
|
|
147
|
+
res.status(400).json({ success: false, error: error.message });
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
/**
|
|
151
|
+
* POST /api/cron-jobs/:id/stop
|
|
152
|
+
* Manually stop a cron job
|
|
153
|
+
*/
|
|
154
|
+
router.post('/:id/stop', async (req, res) => {
|
|
155
|
+
try {
|
|
156
|
+
await CronJobService_1.default.stopCronJob(req.params.id);
|
|
157
|
+
res.json({ success: true, message: 'Cron job stopped successfully' });
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error('Error stopping cron job:', error);
|
|
161
|
+
res.status(400).json({ success: false, error: error.message });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
/**
|
|
165
|
+
* POST /api/cron-jobs/validate
|
|
166
|
+
* Validate a cron expression
|
|
167
|
+
*/
|
|
168
|
+
router.post('/validate', (req, res) => {
|
|
169
|
+
try {
|
|
170
|
+
const { expression } = req.body;
|
|
171
|
+
if (!expression) {
|
|
172
|
+
return res.status(400).json({ success: false, error: 'Expression is required' });
|
|
173
|
+
}
|
|
174
|
+
const validation = CronJobService_1.default.validateCronExpression(expression);
|
|
175
|
+
const description = CronJobService_1.default.getCronDescription(expression);
|
|
176
|
+
res.json({
|
|
177
|
+
success: true,
|
|
178
|
+
data: {
|
|
179
|
+
...validation,
|
|
180
|
+
description
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error('Error validating cron expression:', error);
|
|
186
|
+
res.status(400).json({ success: false, error: error.message });
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
exports.default = router;
|
|
@@ -606,6 +606,111 @@ router.post('/connections', (req, res) => {
|
|
|
606
606
|
});
|
|
607
607
|
}
|
|
608
608
|
});
|
|
609
|
+
/**
|
|
610
|
+
* Update an existing remote connection configuration
|
|
611
|
+
* PUT /api/remote/connections/:connectionId
|
|
612
|
+
*/
|
|
613
|
+
router.put('/connections/:connectionId', async (req, res) => {
|
|
614
|
+
try {
|
|
615
|
+
const { connectionId } = req.params;
|
|
616
|
+
const connectionConfig = req.body;
|
|
617
|
+
if (!connectionConfig.name || !connectionConfig.host || !connectionConfig.username) {
|
|
618
|
+
return res.status(400).json({
|
|
619
|
+
success: false,
|
|
620
|
+
error: 'Missing required connection parameters: name, host, or username'
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
// Ensure port is set
|
|
624
|
+
if (!connectionConfig.port) {
|
|
625
|
+
connectionConfig.port = 22;
|
|
626
|
+
}
|
|
627
|
+
// Update the connection
|
|
628
|
+
const success = await remote_connection_1.remoteConnectionManager.updateConnection(connectionId, connectionConfig);
|
|
629
|
+
if (!success) {
|
|
630
|
+
return res.status(404).json({
|
|
631
|
+
success: false,
|
|
632
|
+
error: 'Connection not found'
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
res.json({
|
|
636
|
+
success: true,
|
|
637
|
+
message: 'Connection updated successfully'
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
res.status(500).json({
|
|
642
|
+
success: false,
|
|
643
|
+
error: `Server error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
/**
|
|
648
|
+
* Delete a remote connection configuration
|
|
649
|
+
* DELETE /api/remote/connections/:connectionId
|
|
650
|
+
*/
|
|
651
|
+
router.delete('/connections/:connectionId', async (req, res) => {
|
|
652
|
+
try {
|
|
653
|
+
const { connectionId } = req.params;
|
|
654
|
+
// Close the connection if it's open
|
|
655
|
+
await remote_connection_1.remoteConnectionManager.closeConnection(connectionId);
|
|
656
|
+
// Delete the connection configuration
|
|
657
|
+
const success = remote_connection_1.remoteConnectionManager.deleteConnection(connectionId);
|
|
658
|
+
if (!success) {
|
|
659
|
+
return res.status(404).json({
|
|
660
|
+
success: false,
|
|
661
|
+
error: 'Connection not found'
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
res.json({
|
|
665
|
+
success: true,
|
|
666
|
+
message: 'Connection deleted successfully'
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
res.status(500).json({
|
|
671
|
+
success: false,
|
|
672
|
+
error: `Server error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
/**
|
|
677
|
+
* Install PM2 on a remote server
|
|
678
|
+
* POST /api/remote/:connectionId/install-pm2
|
|
679
|
+
*/
|
|
680
|
+
router.post('/:connectionId/install-pm2', async (req, res) => {
|
|
681
|
+
try {
|
|
682
|
+
const { connectionId } = req.params;
|
|
683
|
+
const connection = remote_connection_1.remoteConnectionManager.getConnection(connectionId);
|
|
684
|
+
if (!connection) {
|
|
685
|
+
return res.status(404).json({
|
|
686
|
+
success: false,
|
|
687
|
+
error: 'Connection not found'
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
// Install PM2
|
|
691
|
+
const result = await connection.installPM2();
|
|
692
|
+
if (result.code === 0) {
|
|
693
|
+
res.json({
|
|
694
|
+
success: true,
|
|
695
|
+
message: 'PM2 installed successfully',
|
|
696
|
+
output: result.stdout
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
res.status(400).json({
|
|
701
|
+
success: false,
|
|
702
|
+
error: 'Failed to install PM2',
|
|
703
|
+
output: result.stderr || result.stdout
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
res.status(500).json({
|
|
709
|
+
success: false,
|
|
710
|
+
error: `Failed to install PM2: ${error.message}`
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
});
|
|
609
714
|
/**
|
|
610
715
|
* Delete a connection configuration
|
|
611
716
|
* DELETE /api/remote/connections/:connectionId
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron Job Service - Manages PM2 processes with cron_restart
|
|
3
|
+
*/
|
|
4
|
+
import { CronJobConfig, CronJobStatus } from '../../types/cron';
|
|
5
|
+
export declare class CronJobService {
|
|
6
|
+
private static instance;
|
|
7
|
+
private constructor();
|
|
8
|
+
static getInstance(): CronJobService;
|
|
9
|
+
private ensureConfigFile;
|
|
10
|
+
private readConfig;
|
|
11
|
+
private writeConfig;
|
|
12
|
+
/**
|
|
13
|
+
* Validate cron expression
|
|
14
|
+
*/
|
|
15
|
+
validateCronExpression(expression: string): {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
nextRun?: Date;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Get human-readable description of cron expression
|
|
22
|
+
*/
|
|
23
|
+
getCronDescription(expression: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get script path for inline scripts (creates temp file)
|
|
26
|
+
*/
|
|
27
|
+
private getScriptPath;
|
|
28
|
+
/**
|
|
29
|
+
* Get file extension for script type
|
|
30
|
+
*/
|
|
31
|
+
private getScriptExtension;
|
|
32
|
+
/**
|
|
33
|
+
* Convert CronJobConfig to PM2 start options
|
|
34
|
+
*/
|
|
35
|
+
private toPM2Options;
|
|
36
|
+
/**
|
|
37
|
+
* Create a new cron job
|
|
38
|
+
*/
|
|
39
|
+
createCronJob(config: Omit<CronJobConfig, 'id' | 'createdAt' | 'updatedAt'>): Promise<CronJobConfig>;
|
|
40
|
+
/**
|
|
41
|
+
* Get all cron jobs
|
|
42
|
+
*/
|
|
43
|
+
getCronJobs(): CronJobConfig[];
|
|
44
|
+
/**
|
|
45
|
+
* Get a single cron job by ID
|
|
46
|
+
*/
|
|
47
|
+
getCronJob(id: string): CronJobConfig | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Update a cron job
|
|
50
|
+
*/
|
|
51
|
+
updateCronJob(id: string, updates: Partial<CronJobConfig>): Promise<CronJobConfig>;
|
|
52
|
+
/**
|
|
53
|
+
* Delete a cron job
|
|
54
|
+
*/
|
|
55
|
+
deleteCronJob(id: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Start a cron job (start PM2 process with cron_restart)
|
|
58
|
+
*/
|
|
59
|
+
startCronJob(id: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Stop a cron job (delete PM2 process)
|
|
62
|
+
*/
|
|
63
|
+
stopCronJob(id: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Get status of all cron jobs (including PM2 process info)
|
|
66
|
+
*/
|
|
67
|
+
getCronJobsStatus(): Promise<CronJobStatus[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Toggle cron job enabled state
|
|
70
|
+
*/
|
|
71
|
+
toggleCronJob(id: string): Promise<CronJobConfig>;
|
|
72
|
+
}
|
|
73
|
+
declare const _default: CronJobService;
|
|
74
|
+
export default _default;
|