From a4a1cf314aac7a6b1ec22f3c2ed371d149efa029 Mon Sep 17 00:00:00 2001 From: william Date: Sun, 7 Feb 2016 00:34:42 -0500 Subject: [PATCH] runner --- lxc.js | 309 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 215 insertions(+), 94 deletions(-) diff --git a/lxc.js b/lxc.js index a54a942..c6f7752 100644 --- a/lxc.js +++ b/lxc.js @@ -1,5 +1,28 @@ 'use strict'; var exec = require('child_process').exec; +var extend = require('node.extend'); + + +var parseArgs = function(required, takes, config){ + var all = Object.keys(config); + // console.log(all) + for(var i=required.length; i--;){ + if(all.indexOf(required[i]) !== -1){ + required.splice(i, 1); + } + } + + if(required.length !== 0) return false; + + var out = ''; + for(var i=0; i< takes.length; i++){ + if(all.indexOf(takes[i]) !== -1){ + out += '--'+takes[i]+' '+config[takes[i]]+' '; + } + } + + return out; +}; function sysExec(command, callback){ command = 'unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; ' + command; @@ -13,126 +36,224 @@ function sysExec(command, callback){ })(callback)); }; + var Container = function(config){ this.name = config.name; - this.state = config.state; + this.state = config.state || 'STOPPED'; this.ip = config.ip || (config.ipv4 || '').replace('-', '') || null ; + this.overlayfs = null } -Container.prototype.autoShutDown = function(time) { - time = time || 600000; - - // this.__shutDownTimeout = setTimeout(function(){}, this.autoShutDown): +Container.prototype.clone = function(callback){ + var overlayfs = this.overlayfs : ' -B overlayfs -s ' ? ''; + + return sysExec('lxc-clone -o '+this.orig+ ' -n '+this.name + overlayfs, callback); }; -var lxcORM = function(){ - var orm = {} - lxc.list(function(data){ - for(var idx = data.length; idx--;){ - orm[data[idx].name] = new Container(data[idx]); - } +Container.prototype.start = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name'], + defaults: extend({}, this); + }); - return orm + return sysExec('lxc-start --daemon '+args, callback); }; -var lxc = { - create: function(name, template, config, callback){ - return sysExec('lxc-create -n '+name+' -t '+template, callback); - }, +Container.prototype.startEphemeral = function(callback){ + args = parseArgs({ + required: ['orig'], + takes: ['orig', 'name', 'key', 'union-type', 'keep-data'], + defaults: extend({}, this) + + }); - clone: function(name, base_name, callback){ - return sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', callback); - }, + var command = 'lxc-start-ephemeral --daemon '+args; + return sysExec(command, function(data){ + console.log('startEphemeral', arguments); + if(data.match("doesn't exist.")){ + return callback({status: 500, error: "doesn't exist."}); + } + if(data.match('already exists.')){ + return callback({status: 500, error: 'already exists'}); + } + if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)){ + return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]}); + } - destroy: function(name, callback){ - return sysExec('lxc-destroy -n '+ name, function(data){ - var info = data.match(/Destroyed container/); - console.log('destroy info:', info); - var args = [true].concat(Array.prototype.slice.call(arguments, 1)); - return callback.apply(this, args); - }); - }, + callback({'?': '?', data: data, name: name, base_name: base_name}); + }); +}; - start: function(name, callback){ - return sysExec('lxc-start --name '+name+' --daemon', callback); - }, +Container.prototype.destroy = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name', 'force'], + defaults: extend({}, this) + }); - startEphemeral: function(name, base_name, callback){ - var command = 'lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d'; - return sysExec(command, function(data){ - console.log('startEphemeral', arguments); - if(data.match("doesn't exist.")){ - return callback({status: 500, error: "doesn't exist."}); - } - if(data.match('already exists.')){ - return callback({status: 500, error: 'already exists'}); - } - if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)){ - return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]}); - } + return sysExec('lxc-destroy '+ args, function(data){ + var info = data.match(/Destroyed container/); + console.log('destroy info:', info); + var args = [true].concat(Array.prototype.slice.call(arguments, 1)); + return callback.apply(this, args); + }); +}, - callback({'?': '?', data: data, name: name, base_name: base_name}); - }); - }, +Container.prototype.stop = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name', 'reboot', 'nowait', 'timeout', 'kill'], + defaults: extend({}, this) + + }); + return sysExec('lxc-stop '+args, callback); +}; - stop: function(name, callback){ - return sysExec('lxc-stop -n '+ name, callback); - }, +Container.prototype.freeze = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name', 'force'], + defaults: extend({}, this) + }); + return sysExec('lxc-freeze -n '+name, callback); +}; - freeze: function(name, callback){ - return sysExec('lxc-freeze -n '+name, callback); - }, +Container.prototype.unfreeze = function(callback){ - unfreeze: function(name, callback){ - return sysExec('lxc-unfreeze -n '+name, callback); - }, + return sysExec('lxc-unfreeze --name '+this.name, callback); +}; - info: function(name, callback){ - return sysExec('lxc-info -n '+name, function(data){ - console.log('info', arguments); - if(data.match("doesn't exist")){ - return callback({state: 'NULL'}); - } +Container.prototype.info = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name', 'reboot', 'nowait', 'timeout', 'kill'], + defaults: extend({}, this) + + }); + return sysExec('lxc-stop '+args, callback); +}; - var info = {}; - data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1); - for(var i in data){ - var temp = data[i].split(/\:\s+/); - info[temp[0].toLowerCase().trim()] = temp[1].trim(); - } - var args = [info].concat(Array.prototype.slice.call(arguments, 1)); - callback.apply(this, args); - }); - }, +Container.prototype.freeze = function(callback){ + args = parseArgs({ + required: ['name'], + takes: ['name', 'force'], + defaults: extend({}, this) + }); + return sysExec('lxc-freeze -n '+name, callback); +}; - list: function(callback){ - sysExec('lxc-ls --fancy', function(data){ - var output = data.split("\n"); - var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1); - var info = []; +Container.prototype.unfreeze = function(callback){ - keys = keys.map(function(v){return v.toLowerCase()}); - output = output.slice(0).slice(0,-1); + return sysExec('lxc-unfreeze --name '+this.name, callback); +}; - for(var i in output){ - if(output[i].match(/^-/)) continue; // compatibility with 1.x and 2.x output +Container.prototype.info = function(callback){ + return sysExec('lxc-info --name '+this.name, function(data){ + console.log('info', arguments); + if(data.match("doesn't exist")){ + return callback({state: 'NULL'}); + } - var aIn = output[i].split(/\s+/).slice(0,-1); - var mapOut = {}; - aIn.map(function(value,idx){ - mapOut[keys[idx]] = value; - }); - info.push(mapOut); - - } - var args = [info].concat(Array.prototype.slice.call(arguments, 1)); - callback.apply(this, args); - }); + var info = {}; + data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1); + for(var i in data){ + var temp = data[i].split(/\:\s+/); + info[temp[0].toLowerCase().trim()] = temp[1].trim(); + } + var args = [info].concat(Array.prototype.slice.call(arguments, 1)); + return callback.apply(this, args); + }); +}; + +Container.prototype.UpdateFromInfo = function(data){ + for(var key in Object.keys(data)){ + this[key] = data[key]; } + + return this; +} + + + + + + + + + + +var lxcORM = function(){ + this.containers = {} + lxc.list(function(data){ + for(var idx = data.length; idx--;){ + container[data[idx].name] = new Container(data[idx]); + } + }); + this.isReady = false; + this.whenReady = []; + }; -module.exports = lxc; +lxc.prototype.callReady = function(){ + for(var idx=0; idx