pm2
Advanced tools
Comparing version 3.4.1 to 3.5.0
@@ -871,2 +871,3 @@ /** | ||
var appConf = {}; | ||
var staticConf = []; | ||
var deployConf = {}; | ||
@@ -915,2 +916,4 @@ var apps_info = []; | ||
deployConf = config.deploy; | ||
if (config.static) | ||
staticConf = config.static; | ||
if (config.apps) | ||
@@ -934,2 +937,20 @@ appConf = config.apps; | ||
// Add statics to apps | ||
staticConf.forEach(function(serve) { | ||
appConf.push({ | ||
name: serve.name ? serve.name : `static-page-server-${serve.port}`, | ||
script: path.resolve(__dirname, 'API', 'Serve.js'), | ||
env: { | ||
PM2_SERVE_PORT: serve.port, | ||
PM2_SERVE_PATH: serve.path, | ||
PM2_SERVE_SPA: serve.spa, | ||
PM2_SERVE_DIRECTORY: serve.directory, | ||
PM2_SERVE_BASIC_AUTH: serve.basic_auth !== undefined, | ||
PM2_SERVE_BASIC_AUTH_USERNAME: serve.basic_auth ? serve.basic_auth.username : null, | ||
PM2_SERVE_BASIC_AUTH_PASSWORD: serve.basic_auth ? serve.basic_auth.password : null, | ||
PM2_SERVE_MONITOR: serve.monitor | ||
} | ||
}); | ||
}); | ||
// Here we pick only the field we want from the CLI when starting a JSON | ||
@@ -1592,7 +1613,6 @@ appConf.forEach(function(app) { | ||
if (that.gl_interact_infos) { | ||
Common.printOut('%s PM2+ activated | Web: %s | Server: %s | Conn: %s', | ||
Common.printOut('%s PM2+ activated | Instance Name: %s | Dash: %s', | ||
chalk.green.bold('⇆'), | ||
chalk.bold('https://app.pm2.io/#/r/' + that.gl_interact_infos.public_key), | ||
chalk.bold(that.gl_interact_infos.machine_name), | ||
that.gl_interact_infos.agent_transport_websocket === 'true' ? 'Websocket' : 'Axon'); | ||
chalk.bold('https://app.pm2.io/#/r/' + that.gl_interact_infos.public_key)) | ||
if (that.gl_interact_infos.info_node != 'https://root.keymetrics.io') { | ||
@@ -1599,0 +1619,0 @@ Common.printOut(`PM2+ on-premise link: ${that.gl_interact_infos.info_node}`) |
@@ -68,3 +68,3 @@ 'use strict' | ||
*/ | ||
UX.describeTable = function(process) { | ||
UX.describeTable = function(proc) { | ||
var table = new Table({ | ||
@@ -74,3 +74,3 @@ style : {'padding-left' : 1, head : ['cyan', 'bold'], compact : true} | ||
var pm2_env = process.pm2_env; | ||
var pm2_env = proc.pm2_env; | ||
@@ -163,3 +163,3 @@ var created_at = 'N/A'; | ||
{ 'revision' : pm2_env.versioning.revision }, | ||
{ 'comment' : pm2_env.versioning.comment.trim() }, | ||
{ 'comment' : pm2_env.versioning.comment ? pm2_env.versioning.comment.trim() : '' }, | ||
{ 'branch' : pm2_env.versioning.branch } | ||
@@ -192,3 +192,5 @@ ); | ||
var obj = {}; | ||
var value = pm2_env.axm_monitor[key].hasOwnProperty("value") ? pm2_env.axm_monitor[key].value : pm2_env.axm_monitor[key]; | ||
var metric_name = pm2_env.axm_monitor[key].hasOwnProperty("value") ? pm2_env.axm_monitor[key].value : pm2_env.axm_monitor[key] | ||
var metric_unit = pm2_env.axm_monitor[key].hasOwnProperty("unit") ? pm2_env.axm_monitor[key].unit : '' | ||
var value = `${metric_name} ${metric_unit}`; | ||
obj[key] = value; | ||
@@ -201,2 +203,26 @@ safe_push(table_probes, obj); | ||
var table_env = new Table({ | ||
style : {'padding-left' : 1, head : ['cyan', 'bold'], compact : true} | ||
}); | ||
console.log(chalk.inverse.bold(' Divergent env variables from local env ')); | ||
var _env = Common.safeExtend({}, pm2_env) | ||
var diff_env = {} | ||
Object.keys(process.env).forEach(k => { | ||
if (!_env[k] || _env[k] != process.env[k]) { | ||
diff_env[k] = process.env[k] | ||
} | ||
}) | ||
Object.keys(diff_env).forEach(function(key) { | ||
var obj = {}; | ||
obj[key] = _env[key]; | ||
safe_push(table_env, obj); | ||
}); | ||
console.log(table_env.toString()); | ||
console.log() | ||
Common.printOut(chalk.white.italic(' Add your own code metrics: http://bit.ly/code-metrics')); | ||
@@ -216,5 +242,4 @@ Common.printOut(chalk.white.italic(' Use `pm2 logs %s [--lines 1000]` to display logs'), pm2_env.name); | ||
UX.dispAsTable = function(list, commander) { | ||
var stacked = (process.stdout.columns || 90) < 90; | ||
var app_head = stacked ? ['Name', 'id', 'mode', 'status', '↺', 'cpu', 'memory'] : | ||
['App name', 'id', 'version', 'mode', 'pid', 'status', 'restart', 'uptime', 'cpu', 'mem', 'user', 'watching']; | ||
var stacked = (process.stdout.columns || 100) < 100; | ||
var app_head = stacked ? ['Name', 'id', 'mode', 'status', '↺', 'cpu', 'memory'] : ['App name', 'id', 'version', 'mode', 'pid', 'status', 'restart', 'uptime', 'cpu', 'mem', 'user', 'watching']; | ||
var mod_head = stacked ? ['Module', 'id', 'status', 'cpu', 'mem'] : | ||
@@ -221,0 +246,0 @@ ['Module', 'id', 'version', 'pid', 'status', 'restart', 'cpu', 'memory', 'user']; |
@@ -39,2 +39,4 @@ /** | ||
this.logLines = [] | ||
this.list = blessed.list({ | ||
@@ -75,3 +77,3 @@ top: '0', | ||
this.logBox = blessed.box({ | ||
this.logBox = blessed.list({ | ||
label: ' Global Logs ', | ||
@@ -359,8 +361,14 @@ top: '0', | ||
var logs = data.data.split('\n'); | ||
logs.forEach(function(log) { | ||
var logs = data.data.split('\n') | ||
logs.forEach((log) => { | ||
if (log.length > 0) { | ||
that.logBox.pushLine(color + data.process.name + '{/} > ' + log); | ||
this.logLines.push(color + data.process.name + '{/} > ' + log) | ||
if (this.logLines.length > 200) { | ||
this.logLines.shift() | ||
} | ||
} | ||
}); | ||
}) | ||
this.logBox.setItems(this.logLines) | ||
if (!this.logBox.focused) { | ||
@@ -367,0 +375,0 @@ this.logBox.setScrollPerc(100); |
@@ -470,5 +470,9 @@ | ||
* @param {Number} opts.port port on which http will bind | ||
* @param {Boolean} opts.spa single page app served | ||
* @param {String} opts.basicAuthUsername basic auth username | ||
* @param {String} opts.basicAuthPassword basic auth password | ||
* @param {Object} commander commander object | ||
* @param {Function} cb optional callback | ||
*/ | ||
CLI.prototype.serve = function (target_path, port, opts, cb) { | ||
CLI.prototype.serve = function (target_path, port, opts, commander, cb) { | ||
var that = this; | ||
@@ -480,4 +484,6 @@ var servePort = process.env.PM2_SERVE_PORT || port || 8080; | ||
if (!opts.name || typeof(opts.name) == 'function') | ||
opts.name = 'static-page-server-' + servePort; | ||
if (typeof commander.name === 'string') | ||
opts.name = commander.name | ||
else | ||
opts.name = 'static-page-server-' + servePort | ||
if (!opts.env) | ||
@@ -487,2 +493,11 @@ opts.env = {}; | ||
opts.env.PM2_SERVE_PATH = servePath; | ||
opts.env.PM2_SERVE_SPA = opts.spa; | ||
if (opts.basicAuthUsername && opts.basicAuthPassword) { | ||
opts.env.PM2_SERVE_BASIC_AUTH = 'true'; | ||
opts.env.PM2_SERVE_BASIC_AUTH_USERNAME = opts.basicAuthUsername; | ||
opts.env.PM2_SERVE_BASIC_AUTH_PASSWORD = opts.basicAuthPassword; | ||
} | ||
if (opts.monitor) { | ||
opts.env.PM2_SERVE_MONITOR = opts.monitor | ||
} | ||
opts.cwd = servePath; | ||
@@ -598,3 +613,4 @@ | ||
bus.on('log:*', function(type, data) { | ||
Dashboard.log(type, data); | ||
if (Dashboard.list.selected == data.process.pm_id) | ||
Dashboard.log(type, data) | ||
}) | ||
@@ -601,0 +617,0 @@ }); |
@@ -6,2 +6,4 @@ /** | ||
*/ | ||
'use strict'; | ||
var fs = require('fs'); | ||
@@ -201,14 +203,56 @@ var http = require('http'); | ||
var options = { | ||
port: process.env.PM2_SERVE_PORT || process.argv[3] || 8080, | ||
path: path.resolve(process.env.PM2_SERVE_PATH || process.argv[2] || '.') | ||
path: path.resolve(process.env.PM2_SERVE_PATH || process.argv[2] || '.'), | ||
spa: process.env.PM2_SERVE_SPA === 'true', | ||
homepage: process.env.PM2_SERVE_HOMEPAGE || '/index.html', | ||
basic_auth: process.env.PM2_SERVE_BASIC_AUTH === 'true' ? { | ||
username: process.env.PM2_SERVE_BASIC_AUTH_USERNAME, | ||
password: process.env.PM2_SERVE_BASIC_AUTH_PASSWORD | ||
} : null, | ||
monitor: process.env.PM2_SERVE_MONITOR | ||
}; | ||
if (typeof options.monitor === 'string' && options.monitor !== '') { | ||
try { | ||
let fileContent = fs.readFileSync(path.join(process.env.PM2_HOME, 'agent.json5')).toString() | ||
// Handle old configuration with json5 | ||
fileContent = fileContent.replace(/\s(\w+):/g, '"$1":') | ||
// parse | ||
let conf = JSON.parse(fileContent) | ||
options.monitorBucket = conf.public_key | ||
} catch (e) { | ||
console.log('Interaction file does not exist') | ||
} | ||
} | ||
// start an HTTP server | ||
http.createServer(function (request, response) { | ||
var file = url.parse(request.url).pathname; | ||
if (options.basic_auth) { | ||
if (!request.headers.authorization || request.headers.authorization.indexOf('Basic ') === -1) { | ||
return sendBasicAuthResponse(response) | ||
} | ||
var user = parseBasicAuth(request.headers.authorization) | ||
if (user.username !== options.basic_auth.username || user.password !== options.basic_auth.password) { | ||
return sendBasicAuthResponse(response) | ||
} | ||
} | ||
serveFile(request.url, request, response); | ||
}).listen(options.port, function (err) { | ||
if (err) { | ||
console.error(err); | ||
process.exit(1); | ||
} | ||
console.log('Exposing %s directory on port %d', options.path, options.port); | ||
}); | ||
function serveFile(uri, request, response) { | ||
var file = url.parse(uri || request.url).pathname; | ||
if (file === '/' || file === '') { | ||
file = '/index.html'; | ||
file = options.homepage; | ||
request.wantHomepage = true; | ||
} | ||
@@ -228,28 +272,70 @@ var filePath = path.resolve(options.path + file); | ||
if (error) { | ||
console.error('[%s] Error while serving %s with content-type %s : %s', | ||
Date.now(), filePath, contentType, error.message || error); | ||
if ((!options.spa || request.wantHomepage)) { | ||
console.error('[%s] Error while serving %s with content-type %s : %s', | ||
new Date(), filePath, contentType, error.message || error); | ||
} | ||
if (!isNode4) | ||
errorMeter.mark(); | ||
if (error.code === 'ENOENT') { | ||
if (options.spa && !request.wantHomepage) { | ||
request.wantHomepage = true; | ||
return serveFile(`/${path.basename(file)}`, request, response); | ||
} else if (options.spa && file !== options.homepage) { | ||
return serveFile(options.homepage, request, response); | ||
} | ||
fs.readFile(options.path + '/404.html', function (err, content) { | ||
content = err ? '404 Not Found' : content; | ||
response.writeHead(404, { 'Content-Type': 'text/html' }); | ||
response.end(content, 'utf-8'); | ||
return response.end(content, 'utf-8'); | ||
}); | ||
} else { | ||
response.writeHead(500); | ||
response.end('Sorry, check with the site admin for error: ' + error.code + ' ..\n'); | ||
return; | ||
} | ||
} else { | ||
response.writeHead(200, { 'Content-Type': contentType }); | ||
response.end(content, 'utf-8'); | ||
debug('[%s] Serving %s with content-type %s', Date.now(), filePath, contentType); | ||
response.writeHead(500); | ||
return response.end('Sorry, check with the site admin for error: ' + error.code + ' ..\n'); | ||
} | ||
response.writeHead(200, { 'Content-Type': contentType }); | ||
if (options.monitorBucket && contentType === 'text/html') { | ||
content = content.toString().replace('</body>', ` | ||
<script> | ||
;(function (b,e,n,o,i,t) { | ||
b[o]=b[o]||function(f){(b[o].c=b[o].c||[]).push(f)}; | ||
t=e.createElement(i);e=e.getElementsByTagName(i)[0]; | ||
t.async=1;t.src=n;e.parentNode.insertBefore(t,e); | ||
}(window,document,'https://apm.pm2.io/pm2-io-apm-browser.v1.js','pm2Ready','script')) | ||
pm2Ready(function(apm) { | ||
apm.setBucket('${options.monitorBucket}') | ||
apm.setApplication('${options.monitor}') | ||
apm.reportTimings() | ||
apm.reportIssues() | ||
}) | ||
</script> | ||
</body> | ||
`); | ||
} | ||
response.end(content, 'utf-8'); | ||
debug('[%s] Serving %s with content-type %s', Date.now(), filePath, contentType); | ||
}); | ||
}).listen(options.port, function (err) { | ||
if (err) { | ||
console.error(err); | ||
process.exit(1); | ||
} | ||
function parseBasicAuth(auth) { | ||
// auth is like `Basic Y2hhcmxlczoxMjM0NQ==` | ||
var tmp = auth.split(' '); | ||
var buf = Buffer.from(tmp[1], 'base64'); | ||
var plain = buf.toString(); | ||
var creds = plain.split(':'); | ||
return { | ||
username: creds[0], | ||
password: creds[1] | ||
} | ||
console.log('Exposing %s directory on port %d', options.path, options.port); | ||
}); | ||
} | ||
function sendBasicAuthResponse(response) { | ||
response.writeHead(401, { | ||
'Content-Type': 'text/html', | ||
'WWW-Authenticate': 'Basic realm="Authentication service"' | ||
}); | ||
return response.end('401 Unauthorized'); | ||
} |
@@ -140,3 +140,3 @@ /** | ||
commands = [ | ||
'launchctl remove ' + launchd_service_name, | ||
'launchctl remove ' + launchd_service_name + ' || true', | ||
'rm ' + destination | ||
@@ -143,0 +143,0 @@ ]; |
@@ -144,10 +144,13 @@ /** | ||
var readyCb = function ready(proc) { | ||
if (proc.pm2_env.vizion !== false && proc.pm2_env.vizion !== "false") | ||
God.finalizeProcedure(proc); | ||
else | ||
God.notify('online', proc); | ||
// If vizion enabled run versioning retrieval system | ||
if (proc.pm2_env.vizion !== false && proc.pm2_env.vizion !== "false") | ||
God.finalizeProcedure(proc); | ||
else | ||
God.notify('online', proc); | ||
proc.pm2_env.status = cst.ONLINE_STATUS; | ||
console.log(`App [${proc.pm2_env.name}:${proc.pm2_env.pm_id}] online`); | ||
if (cb) cb(null, proc); | ||
if (proc.pm2_env.status !== cst.ERRORED_STATUS) | ||
proc.pm2_env.status = cst.ONLINE_STATUS | ||
console.log(`App [${proc.pm2_env.name}:${proc.pm2_env.pm_id}] online`); | ||
if (cb) cb(null, proc); | ||
} | ||
@@ -474,3 +477,4 @@ | ||
proc.pm2_env.status == cst.STOPPED_STATUS || | ||
proc.pm2_env.status == cst.STOPPING_STATUS) { | ||
proc.pm2_env.status == cst.STOPPING_STATUS || | ||
proc.pm2_env.status == cst.ERRORED_STATUS) { | ||
return console.error('Cancelling versioning data parsing'); | ||
@@ -477,0 +481,0 @@ } |
{ | ||
"name": "pm2", | ||
"preferGlobal": true, | ||
"version": "3.4.1", | ||
"version": "3.5.0", | ||
"engines": { | ||
@@ -178,3 +178,2 @@ "node": ">=6.0.0" | ||
"needle": "^2.2.1", | ||
"nssocket": "0.6.0", | ||
"pidusage": "^2.0.14", | ||
@@ -181,0 +180,0 @@ "pm2-axon": "3.3.0", |
@@ -13,7 +13,7 @@ <div align="center"> | ||
<a href="https://badge.fury.io/js/pm2" title="NPM Version Badge"> | ||
<img src="https://badge.fury.io/js/pm2.svg" alt="npm version" height="18"> | ||
<img src="https://badge.fury.io/js/pm2.svg" alt="npm version"> | ||
</a> | ||
<a href="https://img.shields.io/badge/node-%3E%3D4-brightgreen.svg" title="Node Limitation"> | ||
<img src="https://img.shields.io/badge/node-%3E%3D4-brightgreen.svg" alt="npm version" height="18"> | ||
<a href="https://img.shields.io/node/v/pm2.svg" title="Node Limitation"> | ||
<img src="https://img.shields.io/node/v/pm2.svg" alt="node version"> | ||
</a> | ||
@@ -20,0 +20,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 7 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
756063
31
15807
284
- Removednssocket@0.6.0