Skip to content
Browse files

Add 'env' to the apps database, which is a String-to-String Object ma…

…p that represents the environment variables that an app is to be run with. Add NODE_ENV="production" as a default env variable, but allow it to be overridden. Add RESTful /env API for managing environment variables.
  • Loading branch information...
1 parent b6a1098 commit 4a62ff5d3d58c18fe6b40877c015da500646a06f @ckknight ckknight committed Apr 21, 2011
Showing with 109 additions and 5 deletions.
  1. +12 −0 app.js
  2. +84 −2 lib/app.js
  3. +13 −3 scripts/launch_chrooted_app.js
View
12 app.js
@@ -105,6 +105,18 @@ myapp.delete('/gitreset', middle.authenticate, middle.authenticate_app, app.gitr
// curl -u "testuser:123" -d "appname=test" http://localhost:4001/applogs
myapp.get('/applogs/:appname', middle.authenticate, middle.authenticate_app, app.logs);
+// Retrieve information about or update a node app's ENV variables
+// This fulfills all four RESTful verbs.
+// GET will retrieve the list of all keys.
+// PUT will either create or update.
+// DELETE will delete the key if it exists.
+// curl -u GET -u "testuser:123" -d "appname=test" http://localhost:4001/env
+// curl -u PUT -u "testuser:123" -d "appname=test&key=NODE_ENV&value=production" http://localhost:4001/env
+// curl -u DELETE -u "testuser:123" -d "appname=test&key=NODE_ENV" http://localhost:4001/env
+myapp.get('/env', middle.authenticate, middle.authenticate_app, app.env_get);
+myapp.put('/env', middle.authenticate, middle.authenticate_app, app.env_put);
+myapp.delete('/env', middle.authenticate, middle.authenticate_app, app.env_delete);
+
// APP NPM Handlers
var npm = require('./lib/npm');
// curl -X POST -u "testuser:123" -d "appname=test&package=express" http://localhost:4001/appnpm
View
86 lib/app.js
@@ -304,7 +304,8 @@ module.exports = {
username: user._id,
repo_id: repo_id,
running: false,
- pid: 'unknown'
+ pid: 'unknown',
+ env: {}
}, function (err, resp) {
if (err) {
res.writeHead(500, { 'Content-Type': 'application/json' });
@@ -353,9 +354,89 @@ module.exports = {
res.send({status: "failure", message: "app exists"});
}
});
+ },
+ env_get: function(req, res, next) {
+ var appname = req.body.appname.toLowerCase();
+ var db = lib.get_couchdb_database('apps');
+ db.get(appname, function (err, appdoc) {
+ if (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify({status: "failure", message: err.error + ' - ' + err.reason}) + '\n');
+ } else {
+ var start = req.body.start;
+ db.get(appname, function (err, doc) {
+ if (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify({status: "failure", message: err.error + ' - ' + err.reason}) + '\n');
+ } else {
+ res.send({status: "success", message: doc.env || {}});
+ }
+ });
+ }
+ });
+ },
+ env_put: function(req, res, next) {
+ var appname = req.body.appname.toLowerCase();
+ var db = lib.get_couchdb_database('apps');
+ var key = req.body.key,
+ value = req.body.value;
+ if (!key || !value) {
+ res.writeHead(400, { 'Content-Type': 'application/json' });
+ res.write(JSON.stringify({status: "false", message: "Must specify both key and value."}) + "\n");
+ res.end();
+ return;
+ }
+ db.get(appname, function (err, appdoc) {
+ if (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify({status: "failure", message: err.error + ' - ' + err.reason}) + '\n');
+ } else {
+ env_update(res, db, appname, appdoc, key, value);
+ }
+ });
+ },
+ env_delete: function(req, res, next) {
+ var appname = req.body.appname.toLowerCase();
+ var db = lib.get_couchdb_database('apps');
+ var key = req.body.key;
+ if (!key) {
+ res.writeHead(400, { 'Content-Type': 'application/json' });
+ res.write(JSON.stringify({status: "false", message: "Must specify key."}) + "\n");
+ res.end();
+ return;
+ }
+ db.get(appname, function (err, appdoc) {
+ if (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify({status: "failure", message: err.error + ' - ' + err.reason}) + '\n');
+ } else {
+ env_update(res, db, appname, appdoc, key, undefined);
+ }
+ });
}
}
+var env_update = function(res, db, appname, appdoc, key, value) {
+ var env = {};
+ if (appdoc.env) {
+ Object.keys(appdoc.env).forEach(function (k) {
+ env[k] = appdoc.env[k];
+ });
+ }
+ if (value !== undefined) {
+ env[key] = value;
+ } else {
+ delete env[key];
+ }
+ db.merge(appname, {env: env}, function(err, resp) {
+ if (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify({status: "failure", message: err.error + ' - ' + err.reason}) + '\n');
+ } else {
+ res.send({status: "success", message: value === undefined ? ("DELETE " + key) : (key + "=" + value)});
+ }
+ });
+};
var force_stop = function(repo_id, callback) {
console.log('Forcing stop for: ', repo_id);
@@ -433,7 +514,8 @@ var app_start = function (repo_id, callback) {
start: app.start,
port: app.port,
ip: '127.0.0.1',
- name: doc.appname
+ name: doc.appname,
+ env: app.env || {}
};
console.log('Checking: ', app_home);
if (!path.existsSync(app_home)) {
View
16 scripts/launch_chrooted_app.js
@@ -82,10 +82,20 @@ daemon.daemonize(path.join('.nodester', 'logs', 'daemon.log'), path.join('.nodes
sandbox.process.installPrefix = '/';
sandbox.process.ARGV = ['node', config.start];
sandbox.process.argv = sandbox.process.ARGV;
- sandbox.process.env = sandbox.process.ENV = {
- 'app_port': app_port,
- 'app_host': app_host
+ var env = sandbox.process.env = sandbox.process.ENV = {
+ // defaults which can be overriden
+ NODE_ENV: "production"
};
+
+ if (config.env) {
+ Object.keys(config.env).forEach(function (key) {
+ env[key] = String(config.env[key]);
+ });
+ }
+
+ // environment variables which cannot be overriden by config.
+ env.app_port = app_port;
+ env.app_host = app_host;
sandbox.process.mainModule = sandbox.module;
sandbox.process.kill = function () { return 'process.kill is disabled' };
sandbox.process.stdout.write = sandbox.console.warn = sandbox.console.error = function (args) {

0 comments on commit 4a62ff5

Please sign in to comment.
Something went wrong with that request. Please try again.