@zappinginc/zm2 6.0.14
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/.claude/settings.local.json +8 -0
- package/.gitattributes +4 -0
- package/.mocharc.js +14 -0
- package/CHANGELOG.md +2416 -0
- package/CLAUDE.md +84 -0
- package/CONTRIBUTING.md +124 -0
- package/GNU-AGPL-3.0.txt +665 -0
- package/LICENSE +1 -0
- package/README.md +248 -0
- package/bin/zm2 +3 -0
- package/bin/zm2-dev +3 -0
- package/bin/zm2-docker +3 -0
- package/bin/zm2-runtime +3 -0
- package/bin/zm2-windows +3 -0
- package/bin/zm2.ps1 +3 -0
- package/bun.lock +421 -0
- package/constants.js +114 -0
- package/index.js +13 -0
- package/lib/API/Configuration.js +212 -0
- package/lib/API/Containerizer.js +335 -0
- package/lib/API/Dashboard.js +459 -0
- package/lib/API/Deploy.js +117 -0
- package/lib/API/Extra.js +775 -0
- package/lib/API/ExtraMgmt/Docker.js +30 -0
- package/lib/API/Log.js +315 -0
- package/lib/API/LogManagement.js +371 -0
- package/lib/API/Modules/LOCAL.js +122 -0
- package/lib/API/Modules/Modularizer.js +148 -0
- package/lib/API/Modules/NPM.js +445 -0
- package/lib/API/Modules/TAR.js +362 -0
- package/lib/API/Modules/flagExt.js +46 -0
- package/lib/API/Modules/index.js +120 -0
- package/lib/API/Monit.js +247 -0
- package/lib/API/Serve.js +343 -0
- package/lib/API/Startup.js +629 -0
- package/lib/API/UX/helpers.js +213 -0
- package/lib/API/UX/index.js +9 -0
- package/lib/API/UX/pm2-describe.js +193 -0
- package/lib/API/UX/pm2-ls-minimal.js +31 -0
- package/lib/API/UX/pm2-ls.js +483 -0
- package/lib/API/Version.js +382 -0
- package/lib/API/interpreter.json +12 -0
- package/lib/API/pm2-plus/PM2IO.js +372 -0
- package/lib/API/pm2-plus/auth-strategies/CliAuth.js +288 -0
- package/lib/API/pm2-plus/auth-strategies/WebAuth.js +187 -0
- package/lib/API/pm2-plus/helpers.js +97 -0
- package/lib/API/pm2-plus/link.js +126 -0
- package/lib/API/pm2-plus/pres/motd +16 -0
- package/lib/API/pm2-plus/pres/motd.update +26 -0
- package/lib/API/pm2-plus/pres/welcome +28 -0
- package/lib/API/pm2-plus/process-selector.js +52 -0
- package/lib/API/schema.json +379 -0
- package/lib/API.js +1931 -0
- package/lib/Client.js +776 -0
- package/lib/Common.js +911 -0
- package/lib/Configuration.js +304 -0
- package/lib/Daemon.js +456 -0
- package/lib/Event.js +37 -0
- package/lib/God/ActionMethods.js +909 -0
- package/lib/God/ClusterMode.js +97 -0
- package/lib/God/ForkMode.js +297 -0
- package/lib/God/Methods.js +265 -0
- package/lib/God/Reload.js +240 -0
- package/lib/God.js +632 -0
- package/lib/HttpInterface.js +76 -0
- package/lib/ProcessContainer.js +305 -0
- package/lib/ProcessContainerBun.js +360 -0
- package/lib/ProcessContainerFork.js +42 -0
- package/lib/ProcessContainerForkBun.js +33 -0
- package/lib/ProcessUtils.js +55 -0
- package/lib/TreeKill.js +118 -0
- package/lib/Utility.js +430 -0
- package/lib/VersionCheck.js +46 -0
- package/lib/Watcher.js +117 -0
- package/lib/Worker.js +169 -0
- package/lib/binaries/CLI.js +1041 -0
- package/lib/binaries/DevCLI.js +183 -0
- package/lib/binaries/Runtime.js +101 -0
- package/lib/binaries/Runtime4Docker.js +192 -0
- package/lib/completion.js +229 -0
- package/lib/completion.sh +40 -0
- package/lib/motd +36 -0
- package/lib/templates/Dockerfiles/Dockerfile-java.tpl +7 -0
- package/lib/templates/Dockerfiles/Dockerfile-nodejs.tpl +8 -0
- package/lib/templates/Dockerfiles/Dockerfile-ruby.tpl +7 -0
- package/lib/templates/ecosystem-es.tpl +24 -0
- package/lib/templates/ecosystem-simple-es.tpl +8 -0
- package/lib/templates/ecosystem-simple.tpl +6 -0
- package/lib/templates/ecosystem.tpl +22 -0
- package/lib/templates/init-scripts/launchd.tpl +35 -0
- package/lib/templates/init-scripts/openrc.tpl +52 -0
- package/lib/templates/init-scripts/pm2-init-amazon.sh +86 -0
- package/lib/templates/init-scripts/rcd-openbsd.tpl +41 -0
- package/lib/templates/init-scripts/rcd.tpl +44 -0
- package/lib/templates/init-scripts/smf.tpl +43 -0
- package/lib/templates/init-scripts/systemd-online.tpl +22 -0
- package/lib/templates/init-scripts/systemd.tpl +22 -0
- package/lib/templates/init-scripts/upstart.tpl +103 -0
- package/lib/templates/logrotate.d/pm2 +10 -0
- package/lib/templates/sample-apps/http-server/README.md +14 -0
- package/lib/templates/sample-apps/http-server/api.js +9 -0
- package/lib/templates/sample-apps/http-server/ecosystem.config.js +14 -0
- package/lib/templates/sample-apps/http-server/package.json +11 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/README.md +45 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/custom-metrics.js +66 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/package.json +11 -0
- package/lib/templates/sample-apps/python-app/README.md +4 -0
- package/lib/templates/sample-apps/python-app/echo.py +7 -0
- package/lib/templates/sample-apps/python-app/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/python-app/package.json +11 -0
- package/lib/tools/Config.js +248 -0
- package/lib/tools/IsAbsolute.js +20 -0
- package/lib/tools/copydirSync.js +101 -0
- package/lib/tools/deleteFolderRecursive.js +19 -0
- package/lib/tools/find-package-json.js +74 -0
- package/lib/tools/fmt.js +72 -0
- package/lib/tools/isbinaryfile.js +94 -0
- package/lib/tools/json5.js +752 -0
- package/lib/tools/open.js +63 -0
- package/lib/tools/passwd.js +58 -0
- package/lib/tools/promise.min.js +1 -0
- package/lib/tools/sexec.js +55 -0
- package/lib/tools/treeify.js +113 -0
- package/lib/tools/which.js +120 -0
- package/lib/tools/xdg-open +861 -0
- package/package.json +219 -0
- package/paths.js +93 -0
- package/pm2 +11 -0
- package/preinstall.js +24 -0
- package/run.sh +9 -0
- package/types/index.d.ts +722 -0
- package/types/tsconfig.json +14 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const cst = require('../../../../constants.js');
|
|
5
|
+
|
|
6
|
+
const AuthStrategy = require('@pm2/js-api/src/auth_strategies/strategy')
|
|
7
|
+
const http = require('http')
|
|
8
|
+
const fs = require('fs')
|
|
9
|
+
const url = require('url')
|
|
10
|
+
const exec = require('child_process').exec
|
|
11
|
+
const tryEach = require('async/tryEach');
|
|
12
|
+
|
|
13
|
+
module.exports = class WebStrategy extends AuthStrategy {
|
|
14
|
+
// the client will try to call this but we handle this part ourselves
|
|
15
|
+
retrieveTokens (km, cb) {
|
|
16
|
+
this.authenticated = false
|
|
17
|
+
this.callback = cb
|
|
18
|
+
this.km = km
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// so the cli know if we need to tell user to login/register
|
|
22
|
+
isAuthenticated () {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
if (this.authenticated) return resolve(true)
|
|
25
|
+
|
|
26
|
+
let tokensPath = cst.PM2_IO_ACCESS_TOKEN
|
|
27
|
+
fs.readFile(tokensPath, (err, tokens) => {
|
|
28
|
+
if (err && err.code === 'ENOENT') return resolve(false)
|
|
29
|
+
if (err) return reject(err)
|
|
30
|
+
|
|
31
|
+
// verify that the token is valid
|
|
32
|
+
try {
|
|
33
|
+
tokens = JSON.parse(tokens || '{}')
|
|
34
|
+
} catch (err) {
|
|
35
|
+
fs.unlinkSync(tokensPath)
|
|
36
|
+
return resolve(false)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// if the refresh tokens is here, the user could be automatically authenticated
|
|
40
|
+
return resolve(typeof tokens.refresh_token === 'string')
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// called when we are sure the user asked to be logged in
|
|
46
|
+
_retrieveTokens (optionalCallback) {
|
|
47
|
+
const km = this.km
|
|
48
|
+
const cb = this.callback
|
|
49
|
+
|
|
50
|
+
let verifyToken = (refresh) => {
|
|
51
|
+
return km.auth.retrieveToken({
|
|
52
|
+
client_id: this.client_id,
|
|
53
|
+
refresh_token: refresh
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
tryEach([
|
|
57
|
+
// try to find the token via the environment
|
|
58
|
+
(next) => {
|
|
59
|
+
if (!process.env.PM2_IO_TOKEN) {
|
|
60
|
+
return next(new Error('No token in env'))
|
|
61
|
+
}
|
|
62
|
+
verifyToken(process.env.PM2_IO_TOKEN)
|
|
63
|
+
.then((res) => {
|
|
64
|
+
return next(null, res.data)
|
|
65
|
+
}).catch(next)
|
|
66
|
+
},
|
|
67
|
+
// try to find it in the file system
|
|
68
|
+
(next) => {
|
|
69
|
+
fs.readFile(cst.PM2_IO_ACCESS_TOKEN, (err, tokens) => {
|
|
70
|
+
if (err) return next(err)
|
|
71
|
+
// verify that the token is valid
|
|
72
|
+
tokens = JSON.parse(tokens || '{}')
|
|
73
|
+
if (new Date(tokens.expire_at) > new Date(new Date().toISOString())) {
|
|
74
|
+
return next(null, tokens)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
verifyToken(tokens.refresh_token)
|
|
78
|
+
.then((res) => {
|
|
79
|
+
return next(null, res.data)
|
|
80
|
+
}).catch(next)
|
|
81
|
+
})
|
|
82
|
+
},
|
|
83
|
+
// otherwise make the whole flow
|
|
84
|
+
(next) => {
|
|
85
|
+
return this.loginViaWeb((data) => {
|
|
86
|
+
// verify that the token is valid
|
|
87
|
+
verifyToken(data.access_token)
|
|
88
|
+
.then((res) => {
|
|
89
|
+
return next(null, res.data)
|
|
90
|
+
}).catch(err => next(err))
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
], (err, result) => {
|
|
94
|
+
// if present run the optional callback
|
|
95
|
+
if (typeof optionalCallback === 'function') {
|
|
96
|
+
optionalCallback(err, result)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (result.refresh_token) {
|
|
100
|
+
this.authenticated = true
|
|
101
|
+
let file = cst.PM2_IO_ACCESS_TOKEN
|
|
102
|
+
fs.writeFile(file, JSON.stringify(result), () => {
|
|
103
|
+
return cb(err, result)
|
|
104
|
+
})
|
|
105
|
+
} else {
|
|
106
|
+
return cb(err, result)
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
loginViaWeb (cb) {
|
|
112
|
+
const redirectURL = `${this.oauth_endpoint}${this.oauth_query}`
|
|
113
|
+
|
|
114
|
+
console.log(`${cst.PM2_IO_MSG} Please follow the popup or go to this URL :`, '\n', ' ', redirectURL)
|
|
115
|
+
|
|
116
|
+
let shutdown = false
|
|
117
|
+
let server = http.createServer((req, res) => {
|
|
118
|
+
// only handle one request
|
|
119
|
+
if (shutdown === true) return res.end()
|
|
120
|
+
shutdown = true
|
|
121
|
+
|
|
122
|
+
let query = url.parse(req.url, true).query
|
|
123
|
+
|
|
124
|
+
res.write(`
|
|
125
|
+
<head>
|
|
126
|
+
<script>
|
|
127
|
+
</script>
|
|
128
|
+
</head>
|
|
129
|
+
<body>
|
|
130
|
+
<h2 style="text-align: center">
|
|
131
|
+
You can go back to your terminal now :)
|
|
132
|
+
</h2>
|
|
133
|
+
</body>`)
|
|
134
|
+
res.end()
|
|
135
|
+
server.close()
|
|
136
|
+
return cb(query)
|
|
137
|
+
})
|
|
138
|
+
server.listen(43532, () => {
|
|
139
|
+
this.open(redirectURL)
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
deleteTokens (km) {
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
// revoke the refreshToken
|
|
146
|
+
km.auth.revoke()
|
|
147
|
+
.then(res => {
|
|
148
|
+
// remove the token from the filesystem
|
|
149
|
+
let file = cst.PM2_IO_ACCESS_TOKEN
|
|
150
|
+
fs.unlinkSync(file)
|
|
151
|
+
return resolve(res)
|
|
152
|
+
}).catch(reject)
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
open (target, appName, callback) {
|
|
157
|
+
let opener
|
|
158
|
+
const escape = function (s) {
|
|
159
|
+
return s.replace(/"/g, '\\"')
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (typeof (appName) === 'function') {
|
|
163
|
+
callback = appName
|
|
164
|
+
appName = null
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
switch (process.platform) {
|
|
168
|
+
case 'darwin': {
|
|
169
|
+
opener = appName ? `open -a "${escape(appName)}"` : `open`
|
|
170
|
+
break
|
|
171
|
+
}
|
|
172
|
+
case 'win32': {
|
|
173
|
+
opener = appName ? `start "" ${escape(appName)}"` : `start ""`
|
|
174
|
+
break
|
|
175
|
+
}
|
|
176
|
+
default: {
|
|
177
|
+
opener = appName ? escape(appName) : `xdg-open`
|
|
178
|
+
break
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (process.env.SUDO_USER) {
|
|
183
|
+
opener = 'sudo -u ' + process.env.SUDO_USER + ' ' + opener
|
|
184
|
+
}
|
|
185
|
+
return exec(`${opener} "${escape(target)}"`, callback)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
var cst = require('../../../constants.js');
|
|
3
|
+
var Common = require('../../Common.js');
|
|
4
|
+
|
|
5
|
+
const chalk = require('ansis');
|
|
6
|
+
const forEach = require('async/forEach');
|
|
7
|
+
const open = require('../../tools/open.js');
|
|
8
|
+
const Modules = require('../Modules');
|
|
9
|
+
|
|
10
|
+
function processesAreAlreadyMonitored(CLI, cb) {
|
|
11
|
+
CLI.Client.executeRemote('getMonitorData', {}, function(err, list) {
|
|
12
|
+
if (err) return cb(false);
|
|
13
|
+
var l = list.filter(l => l.pm2_env.km_link == true)
|
|
14
|
+
var l2 = list.filter(l => l.name == 'pm2-server-monit')
|
|
15
|
+
|
|
16
|
+
return cb(l.length > 0 && l2.length > 0 ? true : false)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = function(CLI) {
|
|
21
|
+
CLI.prototype.openDashboard = function() {
|
|
22
|
+
if (!this.gl_interact_infos) {
|
|
23
|
+
Common.printError(chalk.bold.white('Agent if offline, type `$ pm2 plus` to log in'));
|
|
24
|
+
return this.exitCli(cst.ERROR_EXIT);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var uri = `https://app.pm2.io/#/r/${this.gl_interact_infos.public_key}`
|
|
28
|
+
console.log(cst.PM2_IO_MSG + ` Opening ${uri}`)
|
|
29
|
+
open(uri);
|
|
30
|
+
setTimeout(_ => {
|
|
31
|
+
this.exitCli();
|
|
32
|
+
}, 200);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
CLI.prototype.clearSetup = function (opts, cb) {
|
|
36
|
+
const modules = ['event-loop-inspector']
|
|
37
|
+
this.gl_is_km_linked = false
|
|
38
|
+
|
|
39
|
+
forEach(modules, (_module, next) => {
|
|
40
|
+
Modules.uninstall(this, _module, () => {
|
|
41
|
+
next()
|
|
42
|
+
});
|
|
43
|
+
}, (err) => {
|
|
44
|
+
this.reload('all', () => {
|
|
45
|
+
return cb()
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Install required package and enable flags for current running processes
|
|
52
|
+
*/
|
|
53
|
+
CLI.prototype.minimumSetup = function (opts, cb) {
|
|
54
|
+
var self = this;
|
|
55
|
+
this.gl_is_km_linked = true
|
|
56
|
+
|
|
57
|
+
function install(cb) {
|
|
58
|
+
var modules = []
|
|
59
|
+
|
|
60
|
+
if (opts.type === 'enterprise' || opts.type === 'plus') {
|
|
61
|
+
modules = ['pm2-logrotate', 'pm2-server-monit']
|
|
62
|
+
if (opts.type === 'enterprise') {
|
|
63
|
+
modules.push('deep-metrics')
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
forEach(modules, (_module, next) => {
|
|
68
|
+
Modules.install(self, _module, {}, () => {
|
|
69
|
+
next()
|
|
70
|
+
});
|
|
71
|
+
}, (err) => {
|
|
72
|
+
self.reload('all', () => {
|
|
73
|
+
return cb()
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
processesAreAlreadyMonitored(self, (already_monitored) => {
|
|
79
|
+
if (already_monitored) {
|
|
80
|
+
console.log(cst.PM2_IO_MSG + ` PM2 ${opts.type || ''} bundle already installed`);
|
|
81
|
+
return cb()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (opts.installAll)
|
|
85
|
+
return install(cb)
|
|
86
|
+
|
|
87
|
+
// promptly.confirm(chalk.bold('Install all pm2 plus dependencies ? (y/n)'), (err, answer) => {
|
|
88
|
+
// if (!err && answer === true)
|
|
89
|
+
return install(cb)
|
|
90
|
+
// self.reload('all', () => {
|
|
91
|
+
// return cb()
|
|
92
|
+
// })
|
|
93
|
+
// });
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
|
|
2
|
+
var cst = require('../../../constants.js');
|
|
3
|
+
var Common = require('../../Common.js');
|
|
4
|
+
var chalk = require('ansis');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var KMDaemon = require('@pm2/agent/src/InteractorClient');
|
|
7
|
+
var pkg = require('../../../package.json')
|
|
8
|
+
|
|
9
|
+
module.exports = function(CLI) {
|
|
10
|
+
|
|
11
|
+
CLI.prototype.linkManagement = function(cmd, public_key, machine, opts, cb) {
|
|
12
|
+
var that = this;
|
|
13
|
+
|
|
14
|
+
// pm2 link stop || kill
|
|
15
|
+
if (cmd == 'stop' || cmd == 'kill') {
|
|
16
|
+
that.gl_is_km_linked = false
|
|
17
|
+
console.log(cst.PM2_IO_MSG + ' Stopping agent...');
|
|
18
|
+
|
|
19
|
+
return that.killAgent(function(err) {
|
|
20
|
+
if (err) {
|
|
21
|
+
Common.printError(err);
|
|
22
|
+
return process.exit(cst.ERROR_EXIT);
|
|
23
|
+
}
|
|
24
|
+
console.log(cst.PM2_IO_MSG + ' Stopped');
|
|
25
|
+
|
|
26
|
+
that.reload('all', () => {
|
|
27
|
+
return process.exit(cst.SUCCESS_EXIT);
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// pm2 link info
|
|
33
|
+
if (cmd == 'info') {
|
|
34
|
+
console.log(cst.PM2_IO_MSG + ' Getting agent information...');
|
|
35
|
+
that.agentInfos(function(err, infos) {
|
|
36
|
+
if (err) {
|
|
37
|
+
console.error(cst.PM2_IO_MSG_ERR + ' ' + err.message);
|
|
38
|
+
return that.exitCli(cst.ERROR_EXIT);
|
|
39
|
+
}
|
|
40
|
+
console.log(infos);
|
|
41
|
+
return that.exitCli(cst.SUCCESS_EXIT);
|
|
42
|
+
});
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// pm2 link delete
|
|
47
|
+
if (cmd == 'delete') {
|
|
48
|
+
that.gl_is_km_linked = false
|
|
49
|
+
console.log(cst.PM2_IO_MSG + ' Permanently disable agent...');
|
|
50
|
+
that.killAgent(function(err) {
|
|
51
|
+
try {
|
|
52
|
+
fs.unlinkSync(cst.INTERACTION_CONF);
|
|
53
|
+
} catch(e) {
|
|
54
|
+
console.log(cst.PM2_IO_MSG + ' No interaction config file found');
|
|
55
|
+
return process.exit(cst.SUCCESS_EXIT);
|
|
56
|
+
}
|
|
57
|
+
console.log(cst.PM2_IO_MSG + ' Agent interaction ended');
|
|
58
|
+
if (!cb)
|
|
59
|
+
return process.exit(cst.SUCCESS_EXIT);
|
|
60
|
+
return cb()
|
|
61
|
+
});
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (cmd && !public_key) {
|
|
66
|
+
console.error(cst.PM2_IO_MSG + ' Command [%s] unknown or missing public key', cmd);
|
|
67
|
+
return process.exit(cst.ERROR_EXIT);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// pm2 link xxx yyy
|
|
71
|
+
var infos;
|
|
72
|
+
|
|
73
|
+
if (!cmd) {
|
|
74
|
+
infos = null;
|
|
75
|
+
}
|
|
76
|
+
else
|
|
77
|
+
infos = {
|
|
78
|
+
public_key : public_key,
|
|
79
|
+
secret_key : cmd,
|
|
80
|
+
machine_name : machine,
|
|
81
|
+
info_node : opts.infoNode || null,
|
|
82
|
+
pm2_version: pkg.version
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
that.link(infos, cb)
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
CLI.prototype.link = function(infos, cb) {
|
|
89
|
+
var that = this;
|
|
90
|
+
|
|
91
|
+
process.env.WS_JSON_PATCH = true
|
|
92
|
+
|
|
93
|
+
KMDaemon.launchAndInteract(cst, infos, function(err, dt) {
|
|
94
|
+
if (err) {
|
|
95
|
+
Common.printError(cst.PM2_IO_MSG + ' Run `$ pm2 plus` to connect')
|
|
96
|
+
return that.exitCli(cst.ERROR_EXIT);
|
|
97
|
+
}
|
|
98
|
+
console.log(chalk.bold.green('[+] PM2+ activated!'))
|
|
99
|
+
if (!cb) {
|
|
100
|
+
return that.exitCli(cst.SUCCESS_EXIT);
|
|
101
|
+
}
|
|
102
|
+
return cb(null, dt)
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
CLI.prototype.agentInfos = function(cb) {
|
|
107
|
+
KMDaemon.getInteractInfo(this._conf, function(err, data) {
|
|
108
|
+
if (err)
|
|
109
|
+
return cb(Common.retErr(err));
|
|
110
|
+
return cb(null, data);
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
CLI.prototype.killAgent = function(cb) {
|
|
115
|
+
var that = this;
|
|
116
|
+
KMDaemon.killInteractorDaemon(that._conf, function(err) {
|
|
117
|
+
if (err)
|
|
118
|
+
return cb ? cb(Common.retErr(err)) : that.exitCli(cst.SUCCESS_EXIT);
|
|
119
|
+
return cb ? cb(null) : that.exitCli(cst.SUCCESS_EXIT);
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
CLI.prototype.unlink = function(cb) {
|
|
124
|
+
this.linkManagement('delete', cb);
|
|
125
|
+
};
|
|
126
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
██████╗ ███╗ ███╗██████╗ ██╗ ██╗ ██████╗
|
|
3
|
+
██╔══██╗████╗ ████║╚════██╗ ██║ ██╔╝██╔═══██╗
|
|
4
|
+
██████╔╝██╔████╔██║ █████╔╝ ██║ ██╔╝ ██║ ██║
|
|
5
|
+
██╔═══╝ ██║╚██╔╝██║██╔═══╝ ██║ ██╔╝ ██║ ██║
|
|
6
|
+
██║ ██║ ╚═╝ ██║███████╗ ██║██╔╝ ╚██████╔╝
|
|
7
|
+
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝╚═╝ ╚═════╝
|
|
8
|
+
|
|
9
|
+
https://pm2.io/
|
|
10
|
+
|
|
11
|
+
Harden your Node.js Production Environment
|
|
12
|
+
|
|
13
|
+
- Real-time Monitoring Web Interface
|
|
14
|
+
- Pro Active Alerting System
|
|
15
|
+
- Production Profiling for Memory and CPU
|
|
16
|
+
- PM2 Runtime High Availability Fallback
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
-------------
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
██████╗ ███╗ ███╗██████╗ ██╗ ██╗ ██████╗
|
|
6
|
+
██╔══██╗████╗ ████║╚════██╗ ██║ ██╔╝██╔═══██╗
|
|
7
|
+
██████╔╝██╔████╔██║ █████╔╝ ██║ ██╔╝ ██║ ██║
|
|
8
|
+
██╔═══╝ ██║╚██╔╝██║██╔═══╝ ██║ ██╔╝ ██║ ██║
|
|
9
|
+
██║ ██║ ╚═╝ ██║███████╗ ██║██╔╝ ╚██████╔╝
|
|
10
|
+
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝╚═╝ ╚═════╝
|
|
11
|
+
|
|
12
|
+
https://pm2.io/
|
|
13
|
+
|
|
14
|
+
Harden your Node.js Production Environment
|
|
15
|
+
|
|
16
|
+
- Real-time Monitoring Web Interface
|
|
17
|
+
- Pro Active Alerting System
|
|
18
|
+
- Production Profiling for Memory and CPU
|
|
19
|
+
- ZM2 Runtime High Availability Fallback
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Start using it by typing:
|
|
23
|
+
|
|
24
|
+
$ zm2 plus
|
|
25
|
+
|
|
26
|
+
-------------
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
-------------
|
|
3
|
+
|
|
4
|
+
PM2 Plus Edition
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
PM2 Plus is a monitoring dashboard
|
|
8
|
+
specialized for Node.js Apps.
|
|
9
|
+
|
|
10
|
+
Create an account:
|
|
11
|
+
$ pm2 plus register
|
|
12
|
+
|
|
13
|
+
Connect your local PM2 to the PM2 Plus servers:
|
|
14
|
+
$ pm2 plus connect
|
|
15
|
+
|
|
16
|
+
See our UI with your own realtime dashboard:
|
|
17
|
+
$ pm2 plus web
|
|
18
|
+
|
|
19
|
+
More details available there:
|
|
20
|
+
http://pm2.io/plus
|
|
21
|
+
|
|
22
|
+
-------------
|
|
23
|
+
|
|
24
|
+
Having complex or specific needs?
|
|
25
|
+
You can also checkout our enterprise offer at:
|
|
26
|
+
http://pm2.io/enterprise
|
|
27
|
+
|
|
28
|
+
-------------
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const forEachLimit = require('async/forEachLimit');
|
|
3
|
+
|
|
4
|
+
var cst = require('../../../constants.js');
|
|
5
|
+
var Common = require('../../Common.js');
|
|
6
|
+
|
|
7
|
+
module.exports = function(CLI) {
|
|
8
|
+
/**
|
|
9
|
+
* Monitor Selectively Processes (auto filter in interaction)
|
|
10
|
+
* @param String state 'monitor' or 'unmonitor'
|
|
11
|
+
* @param String target <pm_id|name|all>
|
|
12
|
+
* @param Function cb callback
|
|
13
|
+
*/
|
|
14
|
+
CLI.prototype.monitorState = function(state, target, cb) {
|
|
15
|
+
var that = this;
|
|
16
|
+
|
|
17
|
+
if (!target) {
|
|
18
|
+
Common.printError(cst.PREFIX_MSG_ERR + 'Please specify an <app_name|pm_id>');
|
|
19
|
+
return cb ? cb(new Error('argument missing')) : that.exitCli(cst.ERROR_EXIT);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function monitor (pm_id, cb) {
|
|
23
|
+
// State can be monitor or unmonitor
|
|
24
|
+
that.Client.executeRemote(state, pm_id, cb);
|
|
25
|
+
}
|
|
26
|
+
if (target === 'all') {
|
|
27
|
+
that.Client.getAllProcessId(function (err, procs) {
|
|
28
|
+
if (err) {
|
|
29
|
+
Common.printError(err);
|
|
30
|
+
return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
|
|
31
|
+
}
|
|
32
|
+
forEachLimit(procs, 1, monitor, function (err, res) {
|
|
33
|
+
return typeof cb === 'function' ? cb(err, res) : that.speedList();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
} else if (!Number.isInteger(parseInt(target))) {
|
|
37
|
+
this.Client.getProcessIdByName(target, true, function (err, procs) {
|
|
38
|
+
if (err) {
|
|
39
|
+
Common.printError(err);
|
|
40
|
+
return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
|
|
41
|
+
}
|
|
42
|
+
forEachLimit(procs, 1, monitor, function (err, res) {
|
|
43
|
+
return typeof cb === 'function' ? cb(err, res) : that.speedList();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
monitor(parseInt(target), function (err, res) {
|
|
48
|
+
return typeof cb === 'function' ? cb(err, res) : that.speedList();
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|