Comparing version 1.3.0 to 1.4.0
@@ -0,1 +1,37 @@ | ||
2015-06-03, Version 1.4.0 | ||
========================= | ||
* Lint in travis (jigsaw) | ||
* fix iojs version (jigsaw) | ||
* support node 0.12.x and iojs 1.6.x (jigsaw) | ||
* refactor lib/requirements (jigsaw) | ||
* refactor lib/proxy (jigsaw) | ||
* refactor lib/procfile (jigsaw) | ||
* refactor lib/proc (jigsaw) | ||
* refactor lib/forward (jigsaw) | ||
* refactor lib/exporters (jigsaw) | ||
* refactor lib/envs (jigsaw) | ||
* refactor console (jigsaw) | ||
* refactor lib/colors.js (jigsaw) | ||
* refactor forward.js (jigsaw) | ||
* refactor proxy.js and allow snake case (jigsaw) | ||
* refactor nf.js for jshint (jigsaw) | ||
* add jshint configure file (jigsaw) | ||
2015-01-23, Version 1.3.0 | ||
@@ -126,15 +162,12 @@ ========================= | ||
* proxy: Fix regression caused by http-proxy upgrade (Ryan Graham) | ||
2014-03-28, Version 0.2.0 | ||
2014-03-28, Version 0.2.1 | ||
========================= | ||
* proxy: Fix regression caused by http-proxy upgrade (Ryan Graham) | ||
2014-03-28, Version 0.2.1 | ||
2014-03-28, Version 0.2.0 | ||
========================= | ||
* proxy: Fix regression caused by http-proxy upgrade (Ryan Graham) | ||
* Release v0.2.0 (Ryan Graham) | ||
@@ -162,15 +195,12 @@ | ||
* Ignore npm packed tarballs (Ryan Graham) | ||
2014-03-27, Version 0.1.1 | ||
2014-03-27, Version 0.1.2 | ||
========================= | ||
* Ignore npm packed tarballs (Ryan Graham) | ||
2014-03-27, Version 0.1.2 | ||
2014-03-27, Version 0.1.1 | ||
========================= | ||
* Ignore npm packed tarballs (Ryan Graham) | ||
* env: Ignore quoted #'s (Ryan Graham) | ||
@@ -177,0 +207,0 @@ |
@@ -1,47 +0,47 @@ | ||
var url = require('url') | ||
var http = require('http'); | ||
var url = require('url'); | ||
var httpProxy = require('http-proxy'); | ||
function startForward(proxyPort,proxyHost){ | ||
var proxy = httpProxy.createServer(function (req, res, proxy) { | ||
var _url = url.parse(req.url) | ||
var dest = _url.hostname | ||
var port = _url.port || 80 | ||
var host = '127.0.0.1'; | ||
var target | ||
if(proxyHost=='<ANY>' || proxyHost == dest){ | ||
target = { | ||
host: host, | ||
port: port | ||
} | ||
var urlmatch = req.url.match(/http:\/\/[^/]*:?[0-9]*(\/.*)$/); | ||
if(urlmatch){ | ||
req.url = urlmatch[1]; | ||
}else{ | ||
req.url = '/'; | ||
} | ||
}else{ | ||
target = { | ||
host: dest, | ||
port: port | ||
} | ||
} | ||
proxy.proxyRequest(req,res,target); | ||
}); | ||
proxy.listen(proxyPort,function(){ | ||
if(process.getuid()==0) process.setuid( process.env.SUDO_USER ); | ||
}); | ||
}; | ||
function startForward(proxy_port, proxy_host) { | ||
startForward(process.env.PROXY_PORT,process.env.PROXY_HOST); | ||
var proxy = httpProxy.createServer(function (req, res, proxy) { | ||
var _url = url.parse(req.url); | ||
var dest = _url.hostname; | ||
var port = _url.port || 80; | ||
var host = '127.0.0.1'; | ||
var target; | ||
if(proxy_host === '<ANY>' || proxy_host === dest) { | ||
target = { | ||
host: host, | ||
port: port | ||
}; | ||
var urlmatch = req.url.match(/http:\/\/[^/]*:?[0-9]*(\/.*)$/); | ||
if(urlmatch) { | ||
req.url = urlmatch[1]; | ||
} else { | ||
req.url = '/'; | ||
} | ||
} else { | ||
target = { | ||
host: dest, | ||
port: port | ||
}; | ||
} | ||
proxy.proxyRequest(req, res, target); | ||
}); | ||
proxy.listen(proxy_port, function(){ | ||
if(process.getuid() === 0) { | ||
process.setuid(process.env.SUDO_USER); | ||
} | ||
}); | ||
} | ||
startForward(process.env.PROXY_PORT, process.env.PROXY_HOST); |
@@ -19,6 +19,6 @@ var reset = '\x1B[0m'; | ||
bright_white: '\x1B[37m', | ||
} | ||
}; | ||
function identity(self) { | ||
return self | ||
return self; | ||
} | ||
@@ -30,5 +30,5 @@ | ||
return colors[color] + str + reset; | ||
} | ||
}; | ||
} else { | ||
return identity | ||
return identity; | ||
} | ||
@@ -40,6 +40,6 @@ } | ||
[ | ||
"cyan", "yellow","green", | ||
"magenta","red","blue", | ||
"bright_cyan","bright_yellow","bright_green", | ||
"bright_magenta","bright_red","bright_blue" | ||
"cyan", "yellow", "green", | ||
"magenta", "red", "blue", | ||
"bright_cyan", "bright_yellow", "bright_green", | ||
"bright_magenta", "bright_red", "bright_blue" | ||
].forEach(function(name) { | ||
@@ -46,0 +46,0 @@ var colorFn = colorizer(name); |
@@ -1,12 +0,12 @@ | ||
var util = require('util') | ||
var colors = require('./colors') | ||
var util = require('util'); | ||
var colors = require('./colors'); | ||
function wrap(log,length,res){ | ||
if(!res) res=[] | ||
if(log.length <= length){ | ||
res.push(log) | ||
return res | ||
}else{ | ||
res.push(log.substr(0,length)) | ||
return wrap(log.substr(length),length,res) | ||
function wrap(log, length, res) { | ||
if(!res) { res = []; } | ||
if(log.length <= length) { | ||
res.push(log); | ||
return res; | ||
} else { | ||
res.push(log.substr(0, length)); | ||
return wrap(log.substr(length), length, res); | ||
} | ||
@@ -31,3 +31,3 @@ } | ||
} else { | ||
return stripped.substr(0,n) + trimEnd; | ||
return stripped.substr(0, n) + trimEnd; | ||
} | ||
@@ -37,21 +37,20 @@ } | ||
function Console(logger) { | ||
logger = logger || console | ||
this.padding = 25 | ||
logger = logger || console; | ||
this.padding = 25; | ||
this.trimline = 10 | ||
this.wrapline = 500 | ||
this.trimline = 10; | ||
this.wrapline = 500; | ||
this.fmt = function fmt(){ | ||
return util.format.apply(null,arguments); | ||
} | ||
this.fmt = function fmt() { | ||
return util.format.apply(null, arguments); | ||
}; | ||
this.pad = function pad(string,n){ | ||
this.pad = function pad(string, n) { | ||
var l = string.length; | ||
var d = n - l; | ||
var o = string; | ||
for(i=l;i<n;i++){ | ||
o += " " | ||
for(var i = l; i < n; i++) { | ||
o += " "; | ||
} | ||
return o | ||
} | ||
return o; | ||
}; | ||
@@ -61,19 +60,17 @@ this.trim = trim; | ||
// Process Specific Loggers // | ||
this.info = function info(key,proc,string){ | ||
this.info = function info(key, proc, string) { | ||
var stamp = (new Date().toLocaleTimeString()) + " " + key; | ||
logger.log(proc.color(this.pad(stamp,this.padding)), | ||
colors.cyan(string)); | ||
} | ||
logger.log(proc.color(this.pad(stamp,this.padding)), colors.cyan(string)); | ||
}; | ||
this.Info = function info(key,proc,string){ | ||
this.Info = function info(key, proc, string) { | ||
var stamp = (new Date().toLocaleTimeString()) + " " + key; | ||
logger.log(proc.color(this.pad(stamp,this.padding)), | ||
colors.bright_cyan(string)); | ||
} | ||
logger.log(proc.color(this.pad(stamp,this.padding)), colors.bright_cyan(string)); | ||
}; | ||
this.log = function log(key,proc,string){ | ||
this.log = function log(key, proc, string) { | ||
var self = this; | ||
string.split(/\n/).forEach(function(line){ | ||
string.split(/\n/).forEach(function(line) { | ||
if (line.trim().length==0) return; | ||
if (line.trim().length === 0) { return; } | ||
@@ -86,41 +83,40 @@ var stamp = (new Date().toLocaleTimeString()) + " " + key; | ||
var delimiter = " | " | ||
var delimiter = " | "; | ||
var wrapline | ||
if(self.wrapline==0){ | ||
wrapline = line.length | ||
}else{ | ||
wrapline = self.wrapline | ||
var wrapline; | ||
if(self.wrapline === 0) { | ||
wrapline = line.length; | ||
} else { | ||
wrapline = self.wrapline; | ||
} | ||
wrap(line,wrapline).forEach(function(l){ | ||
logger.log(proc.color(self.pad(stamp,self.padding) + delimiter),l); | ||
delimiter = " | > " | ||
}) | ||
wrap(line, wrapline).forEach(function(l) { | ||
logger.log(proc.color(self.pad(stamp,self.padding) + delimiter), l); | ||
delimiter = " | > "; | ||
}); | ||
}); | ||
} | ||
}; | ||
// Foreman Loggers // | ||
this.Alert = function Alert(){ | ||
logger.log( colors.green('[OKAY] '+ this.fmt.apply(null,arguments)) ); | ||
} | ||
this.Alert = function Alert() { | ||
logger.log(colors.green('[OKAY] '+ this.fmt.apply(null, arguments))); | ||
}; | ||
this.Done = function Info(){ | ||
logger.log( colors.cyan('[DONE] ' + this.fmt.apply(null,arguments)) ); | ||
} | ||
this.Done = function Info() { | ||
logger.log(colors.cyan('[DONE] ' + this.fmt.apply(null, arguments))); | ||
}; | ||
this.Warn = function Warn(){ | ||
logger.warn( colors.yellow('[WARN] ' + this.fmt.apply(null,arguments)) ); | ||
} | ||
this.Warn = function Warn() { | ||
logger.warn(colors.yellow('[WARN] ' + this.fmt.apply(null, arguments))); | ||
}; | ||
this.Error = function Error(){ | ||
logger.error( colors.bright_red('[FAIL] ' + this.fmt.apply(null,arguments)) ); | ||
} | ||
this.Error = function Error() { | ||
logger.error(colors.bright_red('[FAIL] ' + this.fmt.apply(null,arguments))); | ||
}; | ||
} | ||
module.exports = Console | ||
Console.Console = new Console() | ||
module.exports = Console; | ||
Console.Console = new Console(); |
@@ -1,24 +0,27 @@ | ||
var fs = require('fs') | ||
var cons = require('./console').Console | ||
var fs = require('fs'); | ||
var cons = require('./console').Console; | ||
function method(name) { | ||
return function(o) { | ||
return o[name].apply(o) | ||
} | ||
return o[name].apply(o); | ||
}; | ||
} | ||
// Parse a Key=Value File Containing Environmental Variables | ||
function KeyValue(data) { | ||
function keyValue(data) { | ||
var env = {}; | ||
data.toString().replace(/^\s*\#.*$/gm,'') | ||
.replace(/^\s*$/gm,'') | ||
.split(/\n/) | ||
.map(method('trim')) | ||
.filter(notBlank) | ||
.forEach(capturePair) | ||
return env | ||
data | ||
.toString() | ||
.replace(/^\s*\#.*$/gm,'') | ||
.replace(/^\s*$/gm,'') | ||
.split(/\n/) | ||
.map(method('trim')) | ||
.filter(notBlank) | ||
.forEach(capturePair); | ||
return env; | ||
function notBlank(str) { | ||
return str.length > 2 | ||
return str.length > 2; | ||
} | ||
@@ -66,19 +69,19 @@ | ||
function flattenJSON(json) { | ||
var flattened = {} | ||
var flattened = {}; | ||
walk(json, function(path, item) { | ||
flattened[path.join('_').toUpperCase()] = item | ||
}) | ||
flattened[path.join('_').toUpperCase()] = item; | ||
}); | ||
return flattened | ||
return flattened; | ||
function walk(obj, visitor, path) { | ||
var item | ||
path = path || [] | ||
for (key in obj) { | ||
item = obj[key] | ||
if (typeof item == 'object') { | ||
walk(item, visitor, path.concat(key)) | ||
var item; | ||
path = path || []; | ||
for (var key in obj) { | ||
item = obj[key]; | ||
if (typeof item === 'object') { | ||
walk(item, visitor, path.concat(key)); | ||
} else { | ||
visitor(path.concat(key), item) | ||
visitor(path.concat(key), item); | ||
} | ||
@@ -109,7 +112,7 @@ } | ||
function dumpEnv(conf) { | ||
var output = [] | ||
for (key in conf) { | ||
output.push(key + '=' + conf[key]) | ||
var output = []; | ||
for (var key in conf) { | ||
output.push(key + '=' + conf[key]); | ||
} | ||
return output.join('\n') + '\n' | ||
return output.join('\n') + '\n'; | ||
} | ||
@@ -119,17 +122,17 @@ | ||
// simplified dictionary | ||
function loadEnvs(path){ | ||
var env, data | ||
function loadEnvs(path) { | ||
var env, data; | ||
if (!fs.existsSync(path)) { | ||
cons.Warn("No ENV file found") | ||
env = {} | ||
if(!fs.existsSync(path)) { | ||
cons.Warn("No ENV file found"); | ||
env = {}; | ||
} else { | ||
data = fs.readFileSync(path); | ||
try { | ||
var envs_json = JSON.parse(data) | ||
env = flattenJSON(envs_json,"",{}); | ||
cons.Alert("Loaded ENV %s File as JSON Format",path); | ||
var envs_json = JSON.parse(data); | ||
env = flattenJSON(envs_json, "", {}); | ||
cons.Alert("Loaded ENV %s File as JSON Format", path); | ||
} catch (e) { | ||
env = KeyValue(data); | ||
cons.Alert("Loaded ENV %s File as KEY=VALUE Format",path); | ||
env = keyValue(data); | ||
cons.Alert("Loaded ENV %s File as KEY=VALUE Format", path); | ||
} | ||
@@ -141,5 +144,5 @@ } | ||
module.exports.loadEnvs = loadEnvs | ||
module.exports.flattenJSON = flattenJSON | ||
module.exports.KeyValue = KeyValue | ||
module.exports.dumpEnv = dumpEnv | ||
module.exports.loadEnvs = loadEnvs; | ||
module.exports.flattenJSON = flattenJSON; | ||
module.exports.keyValue = keyValue; | ||
module.exports.dumpEnv = dumpEnv; |
@@ -6,166 +6,157 @@ var colors = require('./colors'); | ||
var display = require('./console').Console | ||
var display = require('./console').Console; | ||
// Procfile to System Service Export // | ||
mu.root = __dirname | ||
mu.root = __dirname; | ||
function render(filename,conf,callback){ | ||
var out = ""; | ||
var muu = mu.compileAndRender(filename, conf) | ||
muu.on('data', function (data) { | ||
out += data; | ||
}) | ||
muu.on('end',function(){ | ||
callback(out); | ||
}); | ||
function render(filename, conf, callback) { | ||
var out = ""; | ||
var muu = mu.compileAndRender(filename, conf); | ||
muu.on('data', function (data) { | ||
out += data; | ||
}); | ||
muu.on('end', function(){ | ||
callback(out); | ||
}); | ||
} | ||
function templatePath(conf, type, file) { | ||
if (conf.template) | ||
return ppath.resolve(conf.template, file); | ||
else | ||
return ppath.resolve(__dirname, type, file); | ||
if(conf.template) { | ||
return ppath.resolve(conf.template, file); | ||
} else { | ||
return ppath.resolve(__dirname, type, file); | ||
} | ||
} | ||
function writeout(path){ | ||
return function(data){ | ||
if (fs.existsSync(path)) | ||
display.Warn(colors.bright_yellow('Replacing: %s'), path); | ||
fs.writeFileSync(path,data); | ||
display.Alert('Wrote :',ppath.normalize(path)); | ||
function writeout(path) { | ||
return function(data) { | ||
if (fs.existsSync(path)) { | ||
display.Warn(colors.bright_yellow('Replacing: %s'), path); | ||
} | ||
fs.writeFileSync(path,data); | ||
display.Alert('Wrote :',ppath.normalize(path)); | ||
}; | ||
} | ||
function upstart(conf,outdir){ | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
var out = ""; | ||
render(templatePath(conf, 'upstart', 'foreman.conf'), conf, writeout(path) ) | ||
function upstart(conf, outdir) { | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
render(templatePath(conf, 'upstart', 'foreman.conf'), conf, writeout(path)); | ||
} | ||
function upstart_app(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".conf"; | ||
render(templatePath(conf, 'upstart', 'foreman-APP.conf'), conf, writeout(path) ) | ||
function upstart_app(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".conf"; | ||
render(templatePath(conf, 'upstart', 'foreman-APP.conf'), conf, writeout(path)); | ||
} | ||
function upstart_app_n(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".conf"; | ||
render(templatePath(conf, 'upstart','foreman-APP-N.conf'), conf, writeout(path) ) | ||
function upstart_app_n(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".conf"; | ||
render(templatePath(conf, 'upstart','foreman-APP-N.conf'), conf, writeout(path)); | ||
} | ||
function upstart_single(conf,outdir){ | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
var out = ""; | ||
render(templatePath(conf, 'upstart-single', 'foreman.conf'), conf, writeout(path) ) | ||
display.Warn('upstart-single jobs attempt to raise limits and will fail ' + | ||
'to start if the limits cannot be raised to the desired ' + | ||
'levels. Some manual editing may be required.') | ||
function upstart_single(conf, outdir) { | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
render(templatePath(conf, 'upstart-single', 'foreman.conf'), conf, writeout(path)); | ||
display.Warn('upstart-single jobs attempt to raise limits and will fail ' + | ||
'to start if the limits cannot be raised to the desired ' + | ||
'levels. Some manual editing may be required.'); | ||
} | ||
function upstart_single_app(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".conf"; | ||
render(templatePath(conf, 'upstart-single', 'foreman-APP.conf'), conf, writeout(path) ) | ||
function upstart_single_app(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".conf"; | ||
render(templatePath(conf, 'upstart-single', 'foreman-APP.conf'), conf, writeout(path)); | ||
} | ||
function systemd(conf,outdir){ | ||
var path = outdir + "/" + conf.application + ".target"; | ||
var out = ""; | ||
render(templatePath(conf, 'systemd', 'foreman.target'), conf, writeout(path) ) | ||
function systemd(conf, outdir){ | ||
var path = outdir + "/" + conf.application + ".target"; | ||
render(templatePath(conf, 'systemd', 'foreman.target'), conf, writeout(path)); | ||
} | ||
function systemd_app(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".target"; | ||
render(templatePath(conf, 'systemd', 'foreman-APP.target'), conf, writeout(path) ) | ||
function systemd_app(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".target"; | ||
render(templatePath(conf, 'systemd', 'foreman-APP.target'), conf, writeout(path)); | ||
} | ||
function systemd_app_n(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".service"; | ||
render(templatePath(conf, 'systemd', 'foreman-APP-N.service'), conf, writeout(path) ) | ||
function systemd_app_n(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".service"; | ||
render(templatePath(conf, 'systemd', 'foreman-APP-N.service'), conf, writeout(path)); | ||
} | ||
function supervisord(conf,outdir){ | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
var out = ""; | ||
var programs = []; | ||
function supervisord(conf, outdir) { | ||
var path = outdir + "/" + conf.application + ".conf"; | ||
var programs = []; | ||
// Supervisord requires comma separated lists and they are | ||
// quite ugly to handle in Moustache. | ||
for(var i = 0; i < conf.processes.length; i++) { | ||
var process = conf.processes[i].process; | ||
var n = conf.processes[i].n; | ||
// Supervisord requires comma separated lists and they are | ||
// quite ugly to handle in Moustache. | ||
for(var i = 0; i < conf.processes.length; i++) { | ||
var process = conf.processes[i].process; | ||
var n = conf.processes[i].n; | ||
for(var j = 1; j <= n; j++) { | ||
programs.push(conf.application + "-" + process + "-" + j); | ||
} | ||
for(var j = 1; j <= n; j++) { | ||
programs.push(conf.application + "-" + process + "-" + j); | ||
} | ||
} | ||
conf.programs = programs.join(','); | ||
conf.programs = programs.join(','); | ||
render(templatePath(conf, 'supervisord', 'foreman.conf'), conf, writeout(path) ) | ||
render(templatePath(conf, 'supervisord', 'foreman.conf'), conf, writeout(path)); | ||
} | ||
function supervisord_app_n(conf,outdir){ | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".conf"; | ||
var out = ""; | ||
var envs = []; | ||
function supervisord_app_n(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + "-" + conf.number + ".conf"; | ||
var envs = []; | ||
// We have to do the same thing for env variables. | ||
for(var i in conf.envs) { | ||
var key = conf.envs[i].key; | ||
var value = conf.envs[i].value; | ||
// We have to do the same thing for env variables. | ||
for(var i in conf.envs) { | ||
var key = conf.envs[i].key; | ||
var value = conf.envs[i].value; | ||
// Some variables like 'web.1' breaks supervisor confg so we | ||
// escape quotes and wrap values in quotes. | ||
if(typeof value === 'string') { | ||
value = value.replace(/"/, '\\"') | ||
} | ||
envs.push(key + "=" + '"' + value + '"'); | ||
// Some variables like 'web.1' breaks supervisor confg so we | ||
// escape quotes and wrap values in quotes. | ||
if(typeof value === 'string') { | ||
value = value.replace(/"/, '\\"'); | ||
} | ||
conf.envs = envs.join(','); | ||
envs.push(key + "=" + '"' + value + '"'); | ||
} | ||
render(templatePath(conf, 'supervisord', 'foreman-APP-N.conf'), conf, writeout(path) ) | ||
} | ||
conf.envs = envs.join(','); | ||
function smf_app(conf,outdir){ | ||
var out = ""; | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".xml"; | ||
render(templatePath(conf, 'smf', 'foreman-APP.xml'), conf, writeout(path) ) | ||
render(templatePath(conf, 'supervisord', 'foreman-APP-N.conf'), conf, writeout(path)); | ||
} | ||
export_formats = { | ||
"upstart": { | ||
foreman : upstart, | ||
foreman_app : upstart_app, | ||
foreman_app_n : upstart_app_n, | ||
}, | ||
"upstart-single": { | ||
foreman : upstart_single, | ||
foreman_app : upstart_single_app, | ||
foreman_app_n : function noop() {}, | ||
}, | ||
"systemd": { | ||
foreman : systemd, | ||
foreman_app : systemd_app, | ||
foreman_app_n : systemd_app_n, | ||
}, | ||
"supervisord": { | ||
foreman : supervisord, | ||
foreman_app : function noop() {}, | ||
foreman_app_n : supervisord_app_n, | ||
}, | ||
"smf": { | ||
foreman : function noop() {}, | ||
foreman_app : smf_app, | ||
foreman_app_n : function noop() {}, | ||
}, | ||
function smf_app(conf, outdir) { | ||
var path = outdir + "/" + conf.application + "-" + conf.process + ".xml"; | ||
render(templatePath(conf, 'smf', 'foreman-APP.xml'), conf, writeout(path)); | ||
} | ||
module.exports = export_formats | ||
var export_formats = { | ||
"upstart": { | ||
foreman : upstart, | ||
foreman_app : upstart_app, | ||
foreman_app_n : upstart_app_n, | ||
}, | ||
"upstart-single": { | ||
foreman : upstart_single, | ||
foreman_app : upstart_single_app, | ||
foreman_app_n : function noop() {}, | ||
}, | ||
"systemd": { | ||
foreman : systemd, | ||
foreman_app : systemd_app, | ||
foreman_app_n : systemd_app_n, | ||
}, | ||
"supervisord": { | ||
foreman : supervisord, | ||
foreman_app : function noop() {}, | ||
foreman_app_n : supervisord_app_n, | ||
}, | ||
"smf": { | ||
foreman : function noop() {}, | ||
foreman_app : smf_app, | ||
foreman_app_n : function noop() {}, | ||
} | ||
}; | ||
module.exports = export_formats; |
@@ -1,25 +0,25 @@ | ||
var prog = require('child_process') | ||
var prog = require('child_process'); | ||
var cons = require('./console').Console | ||
var cons = require('./console').Console; | ||
function startForward(port,hostname,emitter){ | ||
var proc = prog.fork(__dirname + '/../forward.js',[],{ | ||
env: { | ||
PROXY_PORT: port, | ||
SUDO_USER : process.env.SUDO_USER, | ||
PROXY_HOST: hostname || '<ANY>' | ||
} | ||
}); | ||
cons.Alert('Forward Proxy Started in Port %d',port); | ||
if(hostname){ | ||
cons.Alert('Intercepting requests to %s through forward proxy',hostname) | ||
}else{ | ||
cons.Alert('Intercepting ALL requests through forward proxy') | ||
} | ||
emitter.once('killall',function(signal){ | ||
cons.Done('Killing Forward Proxy Server on Port %d',port); | ||
proc.kill(signal); | ||
}) | ||
function startForward(port, hostname, emitter) { | ||
var proc = prog.fork(__dirname + '/../forward.js', [], { | ||
env: { | ||
PROXY_PORT: port, | ||
SUDO_USER : process.env.SUDO_USER, | ||
PROXY_HOST: hostname || '<ANY>' | ||
} | ||
}); | ||
cons.Alert('Forward Proxy Started in Port %d', port); | ||
if(hostname) { | ||
cons.Alert('Intercepting requests to %s through forward proxy', hostname); | ||
} else { | ||
cons.Alert('Intercepting ALL requests through forward proxy'); | ||
} | ||
emitter.once('killall', function(signal) { | ||
cons.Done('Killing Forward Proxy Server on Port %d',port); | ||
proc.kill(signal); | ||
}); | ||
} | ||
module.exports.startForward = startForward | ||
module.exports.startForward = startForward; |
168
lib/proc.js
@@ -1,11 +0,11 @@ | ||
var prog = require('child_process') | ||
var prog = require('child_process'); | ||
var cons = require('./console').Console | ||
var cons = require('./console').Console; | ||
var _colors = require('./colors') | ||
var colors_max = _colors.colors_max | ||
var colors = _colors.colors | ||
var _colors = require('./colors'); | ||
var colors_max = _colors.colors_max; | ||
var colors = _colors.colors; | ||
var os = require('os') | ||
var platform = os.platform() | ||
var os = require('os'); | ||
var platform = os.platform(); | ||
@@ -17,36 +17,36 @@ // Run a Specific Process | ||
// i.e. web=2 becomes the web.2 key | ||
function run(key,proc,emitter) { | ||
var file, args; | ||
if (platform === 'win32') { | ||
file = process.env.comspec || 'cmd.exe'; | ||
args = ['/s', '/c', proc.command]; | ||
} else { | ||
file = '/bin/sh'; | ||
args = ['-c', proc.command]; | ||
} | ||
var child = prog.spawn(file, args, { env: proc.env }); | ||
function run(key, proc, emitter) { | ||
var file, args; | ||
if (platform === 'win32') { | ||
file = process.env.comspec || 'cmd.exe'; | ||
args = ['/s', '/c', proc.command]; | ||
} else { | ||
file = '/bin/sh'; | ||
args = ['-c', proc.command]; | ||
} | ||
var child = prog.spawn(file, args, { env: proc.env }); | ||
child.stdout.on('data',function(data){ | ||
cons.log(key,proc,data.toString()); | ||
}); | ||
child.stdout.on('data', function(data) { | ||
cons.log(key, proc, data.toString()); | ||
}); | ||
child.stderr.on('data',function(data){ | ||
cons.log(key,proc,data.toString()); | ||
}); | ||
child.stderr.on('data', function(data) { | ||
cons.log(key, proc, data.toString()); | ||
}); | ||
child.on('close',function(code){ | ||
if(code==0){ | ||
cons.info(key,proc,"Exited Successfully"); | ||
}else{ | ||
cons.Info(key,proc,"Exited Abnormally"); | ||
} | ||
}); | ||
child.on('close', function(code) { | ||
if(code === 0) { | ||
cons.info(key,proc,"Exited Successfully"); | ||
} else { | ||
cons.Info(key,proc,"Exited Abnormally"); | ||
} | ||
}); | ||
child.on('exit',function(code, signal){ | ||
emitter.emit('killall', signal); | ||
}); | ||
child.on('exit', function(code, signal) { | ||
emitter.emit('killall', signal); | ||
}); | ||
emitter.on('killall',function(signal){ | ||
child.kill(signal); | ||
}); | ||
emitter.on('killall', function(signal) { | ||
child.kill(signal); | ||
}); | ||
@@ -57,22 +57,22 @@ } | ||
// from the .env file | ||
function once(input,envs,callback) { | ||
var file, args; | ||
var proc = { | ||
command : input, | ||
env : merge(merge({}, process.env), envs) | ||
}; | ||
function once(input, envs, callback) { | ||
var file, args; | ||
var proc = { | ||
command : input, | ||
env : merge(merge({}, process.env), envs) | ||
}; | ||
if (platform === 'win32') { | ||
file = process.env.comspec || 'cmd.exe'; | ||
args = ['/s', '/c', proc.command]; | ||
} else { | ||
file = '/bin/sh'; | ||
args = ['-c', proc.command]; | ||
} | ||
if (platform === 'win32') { | ||
file = process.env.comspec || 'cmd.exe'; | ||
args = ['/s', '/c', proc.command]; | ||
} else { | ||
file = '/bin/sh'; | ||
args = ['-c', proc.command]; | ||
} | ||
var child = prog.spawn(file, args, { env: proc.env, stdio: 'inherit' }); | ||
var child = prog.spawn(file, args, { env: proc.env, stdio: 'inherit' }); | ||
child.on('close', function(code) { | ||
callback(code); | ||
}); | ||
child.on('close', function(code) { | ||
callback(code); | ||
}); | ||
} | ||
@@ -84,41 +84,43 @@ | ||
// e.g. web=2,api=3 are requirements | ||
function start(procs,requirements,envs,portarg,emitter){ | ||
function start(procs, requirements, envs, portarg, emitter){ | ||
var j = 0; | ||
var k = 0; | ||
var port = parseInt(portarg); | ||
var j = 0; | ||
var k = 0; | ||
var port = parseInt(portarg); | ||
if(port<1024) | ||
return cons.Error('Only Proxies Can Bind to Privileged Ports - '+ | ||
'Try \'sudo nf start -x %s\'',port); | ||
if(port < 1024) { | ||
return cons.Error('Only Proxies Can Bind to Privileged Ports - '+ | ||
'Try \'sudo nf start -x %s\'', port); | ||
} | ||
for(key in requirements){ | ||
var n = parseInt(requirements[key]); | ||
for(i=0;i<n;i++){ | ||
for(var key in requirements) { | ||
var n = parseInt(requirements[key]); | ||
var color_val = (j+k) % colors_max; | ||
for(var i = 0; i < n; i++) { | ||
if (!procs[key]){ | ||
cons.Warn("Required Key '%s' Does Not Exist in Procfile Definition",key); | ||
continue; | ||
} | ||
var color_val = (j + k) % colors_max; | ||
var p = { | ||
command : procs[key], | ||
color : colors[color_val], | ||
env : merge(merge({}, process.env), envs) | ||
} | ||
if (!procs[key]) { | ||
cons.Warn("Required Key '%s' Does Not Exist in Procfile Definition", key); | ||
continue; | ||
} | ||
p.env.PORT = port + j + k*100; | ||
p.env.FOREMAN_WORKER_NAME = p.env.FOREMAN_WORKER_NAME || key+"."+(i+1) | ||
var p = { | ||
command : procs[key], | ||
color : colors[color_val], | ||
env : merge(merge({}, process.env), envs) | ||
}; | ||
run(key+"."+(i+1),p,emitter); | ||
p.env.PORT = port + j + k * 100; | ||
p.env.FOREMAN_WORKER_NAME = p.env.FOREMAN_WORKER_NAME || key + "." + (i + 1); | ||
j++; | ||
run(key + "." + (i + 1), p, emitter); | ||
} | ||
j=0; | ||
k++; | ||
j++; | ||
} | ||
j = 0; | ||
k++; | ||
} | ||
} | ||
@@ -136,4 +138,4 @@ | ||
module.exports.start = start | ||
module.exports.run = run | ||
module.exports.once = once | ||
module.exports.start = start; | ||
module.exports.run = run; | ||
module.exports.once = once; |
@@ -1,59 +0,51 @@ | ||
var fs = require('fs') | ||
var cons = require('./console').Console | ||
var _process = process | ||
var fs = require('fs'); | ||
var cons = require('./console').Console; | ||
// Replace a var key with it's value supporting both | ||
// $var and ${var} types | ||
function replaceVar(str, key, value){ | ||
str = str.replace('$' + key, value); | ||
str = str.replace('${' + key + '}', value); | ||
return str; | ||
} | ||
// Parse Procfile | ||
function procs(procdata){ | ||
var processes = {}; | ||
var processes = {}; | ||
procdata.toString().split(/\n/).forEach(function(line){ | ||
if(!line || line[0] === '#') return; | ||
procdata.toString().split(/\n/).forEach(function(line) { | ||
if(!line || line[0] === '#') { return; } | ||
var tuple = /^([A-Za-z0-9_-]+):\s*(.+)$/m.exec(line); | ||
var tuple = /^([A-Za-z0-9_-]+):\s*(.+)$/m.exec(line); | ||
var prockey = tuple[1].trim(); | ||
var command = tuple[2].trim(); | ||
var prockey = tuple[1].trim(); | ||
var command = tuple[2].trim(); | ||
if(!prockey) | ||
return cons.Warn('Syntax Error in Procfile, Line %d: No Prockey Found',i+1); | ||
if(!prockey) { | ||
return cons.Warn('Syntax Error in Procfile, Line %d: No Prockey Found'); | ||
} | ||
if(!command) | ||
return cons.Warn('Syntax Error in Procfile, Line %d: No Command Found',i+1); | ||
if(!command) { | ||
return cons.Warn('Syntax Error in Procfile, Line %d: No Command Found'); | ||
} | ||
processes[prockey]=command; | ||
}); | ||
processes[prockey] = command; | ||
}); | ||
return processes; | ||
return processes; | ||
} | ||
// Look for a Procfile at the Specified Location | ||
function loadProc(path){ | ||
function loadProc(path) { | ||
try{ | ||
var data = fs.readFileSync(path); | ||
return procs(data); | ||
}catch(e){ | ||
cons.Warn('No Procfile Found') | ||
if(fs.existsSync('package.json')){ | ||
cons.Alert("package.json file found - trying 'npm start'") | ||
return procs("web: npm start"); | ||
}else{ | ||
cons.Error("No Procfile found in Current Directory - See nf --help"); | ||
return; | ||
} | ||
try { | ||
var data = fs.readFileSync(path); | ||
return procs(data); | ||
} catch(e) { | ||
cons.Warn('No Procfile Found'); | ||
if(fs.existsSync('package.json')) { | ||
cons.Alert("package.json file found - trying 'npm start'"); | ||
return procs("web: npm start"); | ||
} else { | ||
cons.Error("No Procfile found in Current Directory - See nf --help"); | ||
return; | ||
} | ||
} | ||
} | ||
module.exports.loadProc = loadProc | ||
module.exports.procs = procs | ||
module.exports.loadProc = loadProc; | ||
module.exports.procs = procs; |
126
lib/proxy.js
@@ -1,64 +0,72 @@ | ||
var prog = require('child_process') | ||
var util = require('util') | ||
var prog = require('child_process'); | ||
var util = require('util'); | ||
var cons = require('./console').Console | ||
var cons = require('./console').Console; | ||
function startProxies(reqs,proc,command,emitter,portargs){ | ||
if(command.proxy){ | ||
var localhost = 'localhost'; | ||
var i=0; | ||
var ports = command.proxy.split(','); | ||
for(key in reqs){(function(key){ | ||
var j = i++; | ||
var port = ports[j]; | ||
if(port<1024 && process.getuid()!=0) | ||
return cons.Error('Cannot Bind to Privileged Port %s Without Permission - Try \'sudo\'',port); | ||
if(!port) return cons.Warn('No Downstream Port Defined for \'%s\' Proxy',key); | ||
if(!(key in proc)) return cons.Warn('Proxy Not Started for Undefined Key \'%s\'',key); | ||
var upstream_size = reqs[key]; | ||
var upstream_port = parseInt(portargs) + j*100; | ||
var proxy = prog.fork(__dirname + '/../proxy.js',[],{ | ||
env: { | ||
HOST: localhost, | ||
PORT: port, | ||
UPSTREAM_HOST: localhost, | ||
UPSTREAM_PORT: upstream_port, | ||
UPSTREAM_SIZE: upstream_size, | ||
SUDO_USER: process.env.SUDO_USER | ||
} | ||
}); | ||
var port_targets; | ||
if(upstream_size==1){ | ||
port_targets = util.format('%d', upstream_port); | ||
}else{ | ||
port_targets = util.format('(%d-%d)',upstream_port, upstream_port+upstream_size-1) | ||
} | ||
cons.Alert('Starting Proxy Server [%s] %s -> %s', key, port, port_targets); | ||
emitter.once('killall',function(signal){ | ||
cons.Done('Killing Proxy Server on Port %s',port); | ||
proxy.kill(signal); | ||
}) | ||
proxy.on('exit',function(code, signal){ | ||
emitter.emit('killall', signal); | ||
}) | ||
})(key)} | ||
} | ||
function f(key, i, ports, proc, reqs, portargs, localhost, emitter) { | ||
var j = i++; | ||
var port = ports[j]; | ||
if(port < 1024 && process.getuid() !== 0) { | ||
return cons.Error('Cannot Bind to Privileged Port %s Without Permission - Try \'sudo\'',port); | ||
} | ||
if(!port) { | ||
return cons.Warn('No Downstream Port Defined for \'%s\' Proxy', key); | ||
} | ||
if(!(key in proc)) { | ||
return cons.Warn('Proxy Not Started for Undefined Key \'%s\'', key); | ||
} | ||
var upstream_size = reqs[key]; | ||
var upstream_port = parseInt(portargs) + j * 100; | ||
var proxy = prog.fork(__dirname + '/../proxy.js', [], { | ||
env: { | ||
HOST: localhost, | ||
PORT: port, | ||
UPSTREAM_HOST: localhost, | ||
UPSTREAM_PORT: upstream_port, | ||
UPSTREAM_SIZE: upstream_size, | ||
SUDO_USER: process.env.SUDO_USER | ||
} | ||
}); | ||
var port_targets; | ||
if(upstream_size === 1) { | ||
port_targets = util.format('%d', upstream_port); | ||
} else { | ||
port_targets = util.format('(%d-%d)', upstream_port, upstream_port + upstream_size - 1); | ||
} | ||
cons.Alert('Starting Proxy Server [%s] %s -> %s', key, port, port_targets); | ||
emitter.once('killall', function(signal) { | ||
cons.Done('Killing Proxy Server on Port %s', port); | ||
proxy.kill(signal); | ||
}); | ||
proxy.on('exit', function(code, signal) { | ||
emitter.emit('killall', signal); | ||
}); | ||
} | ||
function startProxies(reqs, proc, command, emitter, portargs) { | ||
if(command.proxy){ | ||
var localhost = 'localhost'; | ||
var i = 0; | ||
var ports = command.proxy.split(','); | ||
for(var key in reqs){ | ||
f(key, i, ports, proc, reqs, portargs, localhost, emitter); | ||
} | ||
} | ||
} | ||
module.exports.startProxies = startProxies; |
@@ -1,44 +0,46 @@ | ||
function parseRequirements(req){ | ||
var requirements = {}; | ||
req.toString().split(',').forEach(function(item){ | ||
var tup = item.trim().split('='); | ||
var key = tup[0]; | ||
var val; | ||
if(tup.length>1){ | ||
val = parseInt(tup[1]); | ||
}else{ | ||
val = 1; | ||
} | ||
requirements[key] = val; | ||
}); | ||
return requirements; | ||
function parseRequirements(req) { | ||
var requirements = {}; | ||
req.toString().split(',').forEach(function(item) { | ||
var tup = item.trim().split('='); | ||
var key = tup[0]; | ||
var val; | ||
if(tup.length > 1) { | ||
val = parseInt(tup[1]); | ||
} else { | ||
val = 1; | ||
} | ||
requirements[key] = val; | ||
}); | ||
return requirements; | ||
} | ||
function getreqs(args,proc){ | ||
var req; | ||
if(args && args.length>0){ | ||
// Run Specific Procs | ||
req = parseRequirements(args); | ||
}else{ | ||
// All | ||
req = {}; | ||
for(key in proc){ | ||
req[key] = 1; | ||
} | ||
function getreqs(args, proc) { | ||
var req; | ||
if(args && args.length > 0) { | ||
// Run Specific Procs | ||
req = parseRequirements(args); | ||
} else { | ||
// All | ||
req = {}; | ||
for(var key in proc){ | ||
req[key] = 1; | ||
} | ||
return req; | ||
} | ||
return req; | ||
} | ||
function calculatePadding(reqs){ | ||
var padding = 0; | ||
for(key in reqs){ | ||
var num = reqs[key]; | ||
var len = key.length + num.toString().length; | ||
if (len>padding) padding=len; | ||
function calculatePadding(reqs) { | ||
var padding = 0; | ||
for(var key in reqs){ | ||
var num = reqs[key]; | ||
var len = key.length + num.toString().length; | ||
if(len > padding) { | ||
padding = len; | ||
} | ||
return padding + 10; | ||
} | ||
return padding + 10; | ||
} | ||
module.exports.calculatePadding = calculatePadding | ||
module.exports.getreqs = getreqs | ||
module.exports.calculatePadding = calculatePadding; | ||
module.exports.getreqs = getreqs; |
316
nf.js
#!/usr/bin/env node | ||
var util = require('util'); | ||
var path = require('path'); | ||
var events = require('events'); | ||
var fs = require('fs'); | ||
var colors = require('./lib/colors') | ||
var colors = require('./lib/colors'); | ||
var quote = require('shell-quote').quote; | ||
var program = require('commander'); | ||
var display = require('./lib/console').Console | ||
var display = require('./lib/console').Console; | ||
@@ -26,44 +25,42 @@ var nf = require('./package.json'); | ||
emitter.once('killall',function(signal){ | ||
display.Done("Killing all processes with signal ", signal); | ||
}) | ||
display.Done("Killing all processes with signal ", signal); | ||
}); | ||
emitter.setMaxListeners(50); | ||
var _proc = require('./lib/proc') | ||
var start = _proc.start | ||
var once = _proc.once | ||
var _proc = require('./lib/proc'); | ||
var start = _proc.start; | ||
var once = _proc.once; | ||
var _procfile = require('./lib/procfile') | ||
var procs = _procfile.procs | ||
var loadProc = _procfile.loadProc | ||
var _procfile = require('./lib/procfile'); | ||
var loadProc = _procfile.loadProc; | ||
var _envs = require('./lib/envs') | ||
var loadEnvs = _envs.loadEnvs | ||
var _envs = require('./lib/envs'); | ||
var loadEnvs = _envs.loadEnvs; | ||
var _requirements = require('./lib/requirements') | ||
var getreqs = _requirements.getreqs | ||
var calculatePadding = _requirements.calculatePadding | ||
var _requirements = require('./lib/requirements'); | ||
var getreqs = _requirements.getreqs; | ||
var calculatePadding = _requirements.calculatePadding; | ||
var startProxies = require('./lib/proxy').startProxies | ||
var startForward = require('./lib/forward').startForward | ||
var startProxies = require('./lib/proxy').startProxies; | ||
var startForward = require('./lib/forward').startForward; | ||
// Kill All Child Processes on SIGINT | ||
process.once('SIGINT',function userkill(){ | ||
console.log(); | ||
display.Warn('Interrupted by User'); | ||
emitter.emit('killall', 'SIGINT'); | ||
process.once('SIGINT', function() { | ||
display.Warn('Interrupted by User'); | ||
emitter.emit('killall', 'SIGINT'); | ||
}); | ||
program | ||
.command('start') | ||
.usage('[Options] [Processes] e.g. web=1,log=2,api') | ||
.option('-s, --showenvs' ,'show ENV variables on start',false) | ||
.option('-x, --proxy <PORT>' ,'start a load balancing proxy on PORT') | ||
.option('-f, --forward <PORT>' ,'start a forward proxy on PORT') | ||
.option('-i, --intercept <HOSTNAME>' ,'set forward proxy to intercept HOSTNAME',null) | ||
.option('-t, --trim <N>' ,'trim logs to N characters',0) | ||
.option('-w, --wrap' ,'wrap logs (negates trim)') | ||
.description('Start the jobs in the Procfile') | ||
.action(function(command_left,command_right){ | ||
.command('start') | ||
.usage('[Options] [Processes] e.g. web=1,log=2,api') | ||
.option('-s, --showenvs' ,'show ENV variables on start',false) | ||
.option('-x, --proxy <PORT>' ,'start a load balancing proxy on PORT') | ||
.option('-f, --forward <PORT>' ,'start a forward proxy on PORT') | ||
.option('-i, --intercept <HOSTNAME>' ,'set forward proxy to intercept HOSTNAME',null) | ||
.option('-t, --trim <N>' ,'trim logs to N characters',0) | ||
.option('-w, --wrap' ,'wrap logs (negates trim)') | ||
.description('Start the jobs in the Procfile') | ||
.action(function(command_left, command_right) { | ||
command = command_right || command_left; | ||
command = command_right || command_left; | ||
@@ -74,9 +71,9 @@ var envs = loadEnvs(program.env); | ||
if(!proc) return; | ||
if(!proc) { return; } | ||
if(command.showenvs){ | ||
for(key in envs){ | ||
display.Alert("env %s=%s",key,envs[key]); | ||
} | ||
} | ||
if(command.showenvs){ | ||
for(var key in envs){ | ||
display.Alert("env %s=%s", key, envs[key]); | ||
} | ||
} | ||
@@ -87,28 +84,32 @@ var reqs = getreqs(program.args[0],proc); | ||
if(command.wrap){ | ||
display.wrapline = process.stdout.columns - display.padding - 7 | ||
display.trimline = 0 | ||
display.Alert('Wrapping display Output to %d Columns',display.wrapline) | ||
}else{ | ||
display.trimline = command.trim || process.stdout.columns - display.padding - 5 | ||
if(display.trimline>0){ | ||
display.Alert('Trimming display Output to %d Columns',display.trimline) | ||
} | ||
} | ||
if(command.wrap) { | ||
display.wrapline = process.stdout.columns - display.padding - 7; | ||
display.trimline = 0; | ||
display.Alert('Wrapping display Output to %d Columns', display.wrapline); | ||
} else { | ||
display.trimline = command.trim || process.stdout.columns - display.padding - 5; | ||
if(display.trimline > 0){ | ||
display.Alert('Trimming display Output to %d Columns', display.trimline); | ||
} | ||
} | ||
if(command.forward) startForward(command.forward,command.intercept,emitter) | ||
if(command.forward) { | ||
startForward(command.forward, command.intercept, emitter); | ||
} | ||
startProxies(reqs,proc,command,emitter,program.port || envs.PORT || process.env.PORT || 5000); | ||
startProxies(reqs, proc, command, emitter, program.port || envs.PORT || process.env.PORT || 5000); | ||
if(process.getuid && process.getuid()==0) process.setuid(process.env.SUDO_USER); | ||
if(process.getuid && process.getuid() === 0) { | ||
process.setuid(process.env.SUDO_USER); | ||
} | ||
start(proc,reqs,envs,program.port || envs.PORT || process.env.PORT || 5000,emitter); | ||
}); | ||
start(proc, reqs, envs, program.port || envs.PORT || process.env.PORT || 5000, emitter); | ||
}); | ||
program | ||
.command('run') | ||
.usage('[Options]') | ||
.option('-s, --showenvs' ,'show ENV variables on start',false) | ||
.description('Run a one off process using the ENV variables') | ||
.action(function(command_left,command_right){ | ||
.command('run') | ||
.usage('[Options]') | ||
.option('-s, --showenvs', 'show ENV variables on start', false) | ||
.description('Run a one off process using the ENV variables') | ||
.action(function(command_left, command_right) { | ||
@@ -118,17 +119,17 @@ command = command_right || command_left; | ||
var envs = loadEnvs(program.env); | ||
var arguments = Array.prototype.slice.apply(this.args); | ||
arguments.pop(); | ||
var args = Array.prototype.slice.apply(this.args); | ||
args.pop(); | ||
var callback = function(code) { | ||
process.exit(code); | ||
} | ||
process.exit(code); | ||
}; | ||
if(!command) return; | ||
if(!command) { return; } | ||
var input = quote(arguments); | ||
var input = quote(args); | ||
if(command.showenvs){ | ||
for(key in envs){ | ||
display.Alert("env %s=%s",key,envs[key]); | ||
} | ||
if(command.showenvs) { | ||
for(var key in envs){ | ||
display.Alert("env %s=%s",key,envs[key]); | ||
} | ||
} | ||
@@ -138,21 +139,21 @@ | ||
once(input,envs,callback); | ||
}); | ||
once(input, envs, callback); | ||
}); | ||
var exporters = require('./lib/exporters') | ||
var exporters = require('./lib/exporters'); | ||
program | ||
.command('export') | ||
.option('-a, --app <NAME>' ,'export upstart application as NAME','foreman') | ||
.option('-u, --user <NAME>' ,'export upstart user as NAME','root') | ||
.option('-o, --out <DIR>' ,'export upstart files to DIR','.') | ||
.option('-c, --cwd <DIR>' ,'change current working directory to DIR') | ||
.option('-g, --gid <GID>' ,'set gid of upstart config to GID') | ||
.option('-l, --log <DIR>' ,'specify upstart log directory','/var/log') | ||
.option('-t, --type <TYPE>' ,'export file to TYPE (default upstart)','upstart') | ||
.option('-m, --template <DIR>' ,'use template folder') | ||
.description('Export to an upstart job independent of foreman') | ||
.action(function(command_left,command_right){ | ||
.command('export') | ||
.option('-a, --app <NAME>' ,'export upstart application as NAME','foreman') | ||
.option('-u, --user <NAME>' ,'export upstart user as NAME','root') | ||
.option('-o, --out <DIR>' ,'export upstart files to DIR','.') | ||
.option('-c, --cwd <DIR>' ,'change current working directory to DIR') | ||
.option('-g, --gid <GID>' ,'set gid of upstart config to GID') | ||
.option('-l, --log <DIR>' ,'specify upstart log directory','/var/log') | ||
.option('-t, --type <TYPE>' ,'export file to TYPE (default upstart)','upstart') | ||
.option('-m, --template <DIR>' ,'use template folder') | ||
.description('Export to an upstart job independent of foreman') | ||
.action(function(command_left, command_right) { | ||
command = command_right || command_left; | ||
command = command_right || command_left; | ||
@@ -163,3 +164,3 @@ var envs = loadEnvs(program.env); | ||
if(!procs) return; | ||
if(!procs) { return; } | ||
@@ -179,10 +180,10 @@ var req = getreqs(program.args[0],procs); | ||
config.envfile = path.resolve(program.env) | ||
config.envfile = path.resolve(program.env); | ||
var writeout | ||
if(exporters[command.type]){ | ||
writeout = exporters[command.type] | ||
}else{ | ||
display.Error("Unknown Export Format",command.type) | ||
process.exit(1); | ||
var writeout; | ||
if(exporters[command.type]) { | ||
writeout = exporters[command.type]; | ||
} else { | ||
display.Error("Unknown Export Format", command.type); | ||
process.exit(1); | ||
} | ||
@@ -192,86 +193,89 @@ | ||
// friendly warning - does not stop export | ||
var user_exists = false; | ||
var userExists = false; | ||
fs.readFileSync('/etc/passwd') | ||
.toString().split(/\n/).forEach(function(line){ | ||
.toString().split(/\n/).forEach(function(line) { | ||
if(line.match(/^[^:]*/)[0] == config.user){ | ||
user_exists = true; | ||
userExists = true; | ||
} | ||
}) | ||
if(!user_exists) display.Warn(display.fmt("User %s Does Not Exist on System",config.user)); | ||
}); | ||
if(!userExists) { | ||
display.Warn(display.fmt("User %s Does Not Exist on System", config.user)); | ||
} | ||
var baseport = parseInt(program.port || envs.PORT || process.env.PORT || 5000); | ||
var baseport_i = 0; | ||
var baseport_j = 0; | ||
var envl = []; | ||
config.processes=[] | ||
config.processes = []; | ||
// This is ugly because of shitty support for array copying | ||
// Cleanup is definitely required | ||
for(key in req){ | ||
for(var key in req) { | ||
var c = {}; | ||
var cmd = procs[key]; | ||
var c = {}; | ||
var cmd = procs[key]; | ||
if (!cmd){ | ||
display.Warn("Required Key '%s' Does Not Exist in Procfile Definition",key); | ||
continue; | ||
} | ||
if (!cmd){ | ||
display.Warn("Required Key '%s' Does Not Exist in Procfile Definition", key); | ||
continue; | ||
} | ||
var n = req[key]; | ||
var n = req[key]; | ||
config.processes.push({process:key, n: n}) | ||
c.process=key; | ||
c.command=cmd; | ||
config.processes.push({process:key, n: n}); | ||
c.process = key; | ||
c.command = cmd; | ||
for(_ in config){ | ||
c[_] = config[_]; | ||
} | ||
for(var _ in config){ | ||
c[_] = config[_]; | ||
} | ||
c.numbers = []; | ||
for(var i=1;i<=n;i++){ | ||
c.numbers = []; | ||
for(var i=1; i <= n; i++) { | ||
var conf = {}; | ||
conf.number = i; | ||
var conf = {}; | ||
conf.number = i; | ||
for(_ in c){ | ||
conf[_] = c[_]; | ||
} | ||
for(_ in c){ | ||
conf[_] = c[_]; | ||
} | ||
conf.port = baseport + baseport_i + baseport_j*100; | ||
conf.port = baseport + baseport_i + baseport_j * 100; | ||
envl = []; | ||
for(key in envs) { | ||
envl.push({ | ||
key: key, | ||
value: envs[key] | ||
}); | ||
} | ||
envl.push({ key: 'PORT', value: conf.port }); | ||
envl.push({ key: 'FOREMAN_WORKER_NAME', value: conf.process + '.' + conf.number }); | ||
var envl = []; | ||
for(key in envs){ | ||
envl.push({ | ||
key: key, | ||
value: envs[key] | ||
}) | ||
} | ||
envl.push({ key: 'PORT', value: conf.port }); | ||
envl.push({ key: 'FOREMAN_WORKER_NAME', value: conf.process+'.'+conf.number }); | ||
conf.envs = envl; | ||
conf.envs = envl; | ||
// Write the APP-PROCESS-N.conf File | ||
writeout.foreman_app_n(conf,command.out); | ||
// Write the APP-PROCESS-N.conf File | ||
writeout.foreman_app_n(conf,command.out); | ||
baseport_i++; | ||
c.numbers.push({number: i}); | ||
} | ||
baseport_i++; | ||
c.numbers.push({number:i}) | ||
} | ||
envl = []; | ||
for(key in envs){ | ||
envl.push({ | ||
key: key, | ||
value: envs[key] | ||
}); | ||
} | ||
var envl = []; | ||
for(key in envs){ | ||
envl.push({ | ||
key: key, | ||
value: envs[key] | ||
}) | ||
} | ||
c.envs = envl; | ||
c.envs = envl; | ||
// Write the APP-Process.conf File | ||
writeout.foreman_app(c,command.out); | ||
// Write the APP-Process.conf File | ||
writeout.foreman_app(c,command.out); | ||
baseport_i=0; | ||
baseport_j++; | ||
baseport_i = 0; | ||
baseport_j++; | ||
} | ||
@@ -282,13 +286,13 @@ | ||
}); | ||
}); | ||
program.parse(process.argv); | ||
if(program.args.length==0) { | ||
console.log(colors.cyan(' _____ ')) | ||
console.log(colors.cyan(' | __|___ ___ ___ _____ ___ ___ ')) | ||
console.log(colors.yellow(' | __| . | _| -_| | | |')) | ||
console.log(colors.magenta(' |__| |___|_| |___|_|_|_|_^_|_|_|')) | ||
program.outputHelp(); | ||
process.exit(1); | ||
if(program.args.length === 0) { | ||
console.log(colors.cyan(' _____ ')); | ||
console.log(colors.cyan(' | __|___ ___ ___ _____ ___ ___ ')); | ||
console.log(colors.yellow(' | __| . | _| -_| | | |')); | ||
console.log(colors.magenta(' |__| |___|_| |___|_|_|_|_^_|_|_|')); | ||
program.outputHelp(); | ||
process.exit(1); | ||
} |
{ | ||
"name": "foreman", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"homepage": "http://strongloop.github.io/node-foreman/", | ||
@@ -19,3 +19,5 @@ "description": "Node Implementation of Foreman", | ||
"scripts": { | ||
"test": "tap test" | ||
"test": "tap test", | ||
"lint": "jshint *.js lib/*.js", | ||
"travis": "npm test && npm run lint" | ||
}, | ||
@@ -41,6 +43,7 @@ "dependencies": { | ||
"devDependencies": { | ||
"tap": "~0.4.8", | ||
"chai": "~1.9.1", | ||
"rimraf": "~2.2.8" | ||
"jshint": "^2.6.3", | ||
"rimraf": "~2.2.8", | ||
"tap": "~0.4.8" | ||
} | ||
} |
42
proxy.js
@@ -5,4 +5,3 @@ var http = require('http'); | ||
var port = parseInt(process.env.PORT); | ||
var host = process.env.HOST; | ||
var upstream_host = process.env.UPSTREAM_HOST; | ||
@@ -13,4 +12,4 @@ var upstream_port = parseInt(process.env.UPSTREAM_PORT); | ||
var addresses = []; | ||
for(i=0;i<upstream_size;i++){ | ||
addresses.push({ | ||
for(var i = 0; i < upstream_size; i++) { | ||
addresses.push({ | ||
host: upstream_host, | ||
@@ -24,24 +23,25 @@ port: upstream_port + i, | ||
var proxy = htproxy.createProxyServer(); | ||
// Hanle Error | ||
proxy.on('proxyError',function(err,req,res){ | ||
console.error("Proxy Error: ",err); | ||
res.writeHead(500); | ||
res.write("Upstream Proxy Error"); | ||
res.end(); | ||
console.error("Proxy Error: ",err); | ||
res.writeHead(500); | ||
res.write("Upstream Proxy Error"); | ||
res.end(); | ||
}); | ||
// Main HTTP Server | ||
http.createServer(function (req, res) { | ||
var target = addresses.shift(); | ||
proxy.web(req, res, {target: target}); | ||
addresses.push(target); | ||
var target = addresses.shift(); | ||
proxy.web(req, res, {target: target}); | ||
addresses.push(target); | ||
}).listen(port,function(){ | ||
if (process.getuid && process.setuid && | ||
process.env.SUDO_USER && process.getuid() == 0) | ||
process.setuid(process.env.SUDO_USER); | ||
}) | ||
if (process.getuid && process.setuid && process.env.SUDO_USER && process.getuid() === 0) { | ||
process.setuid(process.env.SUDO_USER); | ||
} | ||
}); |
@@ -16,7 +16,7 @@ var assert = require('assert') | ||
var loadedEnv = envs.KeyValue(input) | ||
var loadedEnv = envs.keyValue(input) | ||
var dumpedEnv = envs.dumpEnv(loadedEnv) | ||
var loadedFlat = envs.KeyValue(expected) | ||
var loadedFlat = envs.keyValue(expected) | ||
var dumpedFlat = envs.dumpEnv(loadedFlat) | ||
assert.equal(dumpedEnv, expected) | ||
assert.equal(dumpedFlat, expected) |
@@ -7,3 +7,3 @@ var assert = require('assert') | ||
emptyEnvs.forEach(function (env) { | ||
var loaded = envs.KeyValue(env) | ||
var loaded = envs.keyValue(env) | ||
// {} == {} | ||
@@ -10,0 +10,0 @@ assert.equal(Object.keys(loaded).length, 0) |
var assert = require('assert') | ||
, envs = require('../lib/envs') | ||
var parsedHash = envs.KeyValue( | ||
var parsedHash = envs.keyValue( | ||
'#commented heading. \n' + | ||
@@ -6,0 +6,0 @@ 'key = "quoted#hash" \n' + |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance 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
352579
97
27
7
4
1128