From 9ce292e020e32020a76a546c62b7faa96a8f70d4 Mon Sep 17 00:00:00 2001 From: wmantly Date: Fri, 29 Jan 2016 14:49:03 -0500 Subject: [PATCH] first --- app.js | 60 ++++++++++++++ bin/www | 90 +++++++++++++++++++++ lxc.js | 125 +++++++++++++++++++++++++++++ package.json | 17 ++++ public/images/gears.gif | Bin 0 -> 22928 bytes public/images/load.gif | 24 ++++++ public/stylesheets/style.css | 8 ++ routes/index.js | 81 +++++++++++++++++++ routes/users.js | 9 +++ stuff.md | 5 ++ views/error.ejs | 3 + views/index.ejs | 151 +++++++++++++++++++++++++++++++++++ 12 files changed, 573 insertions(+) create mode 100644 app.js create mode 100755 bin/www create mode 100644 lxc.js create mode 100644 package.json create mode 100644 public/images/gears.gif create mode 100644 public/images/load.gif create mode 100644 public/stylesheets/style.css create mode 100644 routes/index.js create mode 100644 routes/users.js create mode 100644 stuff.md create mode 100644 views/error.ejs create mode 100644 views/index.ejs diff --git a/app.js b/app.js new file mode 100644 index 0000000..83fefb3 --- /dev/null +++ b/app.js @@ -0,0 +1,60 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); + +var routes = require('./routes/index'); +var users = require('./routes/users'); + +var app = express(); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'ejs'); + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', users); +app.use('/api', routes); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handlers + +// development error handler +// will print stacktrace +if (app.get('env') === 'development') { + app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err + }); + }); +} + +// production error handler +// no stacktraces leaked to user +app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {} + }); +}); + + +module.exports = app; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..eafbd45 --- /dev/null +++ b/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('manager:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '2000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/lxc.js b/lxc.js new file mode 100644 index 0000000..73098a5 --- /dev/null +++ b/lxc.js @@ -0,0 +1,125 @@ +module.exports = function(config){ + + var obj = {}; + var child = require('child'), + sshBind = config.sshBind || false; + + //http://stackoverflow.com/questions/10530532/ + function textToArgs(s){ + var words = []; + s.replace(/"([^"]*)"|'([^']*)'|(\S+)/g,function(g0,g1,g2,g3){ words.push(g1 || g2 || g3 || '')}); + return words; + } + + var sysExec = function(command, onData, onClose){ + + onData = onData || function(){}; + onClose = onClose || function(){}; + + if (sshBind != false) + { + var runCommand = sshBind.slice(); + runCommand.push(command); + } else { + var runCommand = textToArgs(command); + } + + var errors = ''; + + child({ + command: runCommand.slice(0,1)[0], + args: runCommand.slice(1), + cbStdout: function(data){ onData(''+data) }, + cbStderr: function(data){ errors+=data; onData(''+data) }, + cbClose: function(exitCode){ onClose(exitCode == 0 ? null:exitCode, errors) } + }).start(); + }; + + + obj.create = function(name, template, config, cbComplete, cbData){ + sysExec('lxc-create -n '+name+' -t '+template, cbComplete, cbData); + }; + + obj.clone = function(name, base_name, cbComplete, cbData){ + sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', cbComplete, cbData); + }; + + obj.destroy = function(name, cbComplete, cbData){ + sysExec('lxc-destroy -n '+ name, cbComplete, cbData); + }; + + + obj.start = function(name, cbComplete, cbData){ + var cmd = 'lxc-start --name '+name+' --daemon'; + console.log('start cmd\n', cmd, '\n'); + sysExec(cmd, cbComplete, cbData); + }; + + obj.startEphemeral = function(name, base_name, cbComplete, cbData){ + + var output = ''; + sysExec('lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d', function(data){output+=data}, function(error){ + if(output.match("doesn't exist.")) return cbData({status: 500, error: "doesn't exist."}); + if(output.match("already exists.")) return cbData({status: 500, error: "already exists"}); + if(output.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)) return cbData({status: 200, state:'RUNNING', ip: output.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]}); + cbData({'?': '?', data: output, name: name, base_name: base_name}); + }); + }; + + obj.stop = function(name, cbComplete, cbData){ + sysExec('lxc-stop -n '+ name, cbComplete, cbData); + }; + + + obj.freeze = function(name, cbComplete, cbData){ + sysExec('lxc-freeze -n '+name, cbComplete, cbData); + }; + + obj.unfreeze = function(name, cbComplete, cbData){ + sysExec('lxc-unfreeze -n '+name, cbComplete, cbData); + }; + + obj.info = function(name, cbComplete, cbData){ + + var output = ''; + sysExec('lxc-info -n'+name, function(data){output+=data}, function(error){ + if(output.match("doesn't exist")) return cbData({state: 'NULL'}); + var info = {}; + output = output.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1); + for(var i in output){ + var temp = output[i].split(/\:\s+/); + info[temp[0].toLowerCase().trim()] = temp[1].trim(); + } + cbData(info); + }); + }; + + obj.list = function(cbData){ + + var output = ''; + sysExec('lxc-ls --fancy', function(data){output+=data}, function(error){ + + output = output.split("\n"); + var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1); + keys = keys.map(function(v){return v.toLowerCase()}); + output = output.slice(0).splice(1).slice(0,-1); + + var info = []; + + for (var i in output) + { + + var aIn = output[i].split(/\s+/).slice(0,-1), + mapOut = {}; + aIn.map( function(v,i){ mapOut[keys[i]] = v; } ); + info.push(mapOut); + + } + + cbData(info); + }); + }; + + + return obj; +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..dde6f7f --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "manager", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.13.2", + "cookie-parser": "~1.3.5", + "debug": "~2.2.0", + "ejs": "~2.3.3", + "express": "~4.13.1", + "morgan": "~1.6.1", + "serve-favicon": "~2.3.0" + } +} \ No newline at end of file diff --git a/public/images/gears.gif b/public/images/gears.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c51c2fac3420021ad59ffbba62635de8516c322 GIT binary patch literal 22928 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 literal 0 HcmV?d00001 diff --git a/public/images/load.gif b/public/images/load.gif new file mode 100644 index 0000000..ab67ac0 --- /dev/null +++ b/public/images/load.gif @@ -0,0 +1,24 @@ +loading.io - Your SVG + GIF Ajax Loading Icons
LOADING.IO
Login With Facebook

{{auth.failed}}
LoginSign up
Sign up
Log In
{{n.message}}
Build Your Ajax
Loading
Icons with

SVG / CSS / GIF !
{{t[0]}}
want more? share it!

Examples

SVG Loader

You can use SVG loader just like using an image. For example, with <img> tag:

<img src="triangle.svg">

or as background image:



CSS Loader

CSS loader has two parts: stylesheet and HTML part. Stylesheet is embraced in <style> tag so you can copy the file content into the place you want the icon to show.

To increase reusability, you can separate stylesheet from html part into a standalone css file. For example:

<link rel="stylesheet" type="text/css" href="examples/battery.css"> +<div class='uil-battery-demo-css' style='-webkit-transform:scale(0.6)'> + <outer></outer> + <inner></inner> + <inner></inner> + <inner></inner> + <inner></inner> +</div>

will look like this:


GIF Loader

Use GIF loader in an <img> tag or as background of another element:

<img src="spinner.gif"> +<div style="background:url(spinner.gif) no-repeat center center;width:32px;height:32px;"></div>

+For example:



Browser Compatibility

tl;dr

+Use GIF loader if you need compatibility in Internet Explorer.


SVG Loader ( not for IE )

All SVG loaders use SMIL to animate elements. Modern browsers support SVG and SMIL except Internet Explorer:

  • SVG: IE ≥ 9.0
  • SMIL: IE doesn't Support


CSS Loader ( IE ≥ 10.0 )

All CSS loaders use CSS3 Animation to animate elements. Modern browsers support CSS3 except Internet Explorer:

  • CSS3 Animation: IE ≥ 10.0
  • CSS3 Transform: IE ≥ 10.0 (partially)


+GIF Loader ( cross-platform )

All modern browsers support GIF loader. Use GIF loader to ensure optimized browser compatibility.



This Tool

This tool is tested against following browsers:

  • Google Chrome 34.0.
  • Firefox 28.0
  • Safari 7.03
  • Opera 18.0.
  • Internet Explorer 11.0

It's built upon bootstrap, angularjs, canvg, gif.js and web workers. It's known that some browsers ( e.g., IE10 ) are not supported, so please upgrade your browser if you want to use this tool.


Comments

\ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..1c75508 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,81 @@ +var express = require('express'); +var router = express.Router(); +var extend = require('node.extend'); +var redis = require("redis"); +var client = redis.createClient(); +var lxc = require('../lxc')({sshBind: ['/usr/bin/ssh', 'virt@127.0.0.1']}); +//lxc.startEphemeral('ubuntu_template', 'ue0', function(){console.log('cb1', arguments)}, function(){console.log('cb2', arguments)}) + +router.get('/start/:name', function(req, res, next){ + lxc.start(req.params.name, null, function(status, message){ + if(status){ + res.json({status: 500, name: req.params.name, message: message}); + }else{ + setTimeout(function() { + lxc.info(req.params.name, null, function(data){ + var domain = req.query.domain || 'vm42.us'; + domain = req.params.name+'.'+domain; + client.SADD("hosts", domain, function(){}); + + var ip = data.ip + ':5000'; + client.HSET(domain, "ip", ip, redis.print); + client.HSET(domain, "updated", (new Date).getTime(), redis.print); + client.hset(domain, "include", "proxy.include"); + res.json({status: 200, info: data}); + }); + }, 5000); + + } + }); +}); + +router.get('/live/:template/:name', function(req, res, next){ + lxc.startEphemeral(req.params.name, req.params.template, null, function (data) { + res.json(data); + }); +}); + +router.get('/stop/:name', function(req, res, next){ + lxc.stop(req.params.name, null, function(data, message){ + if(data){ + res.json({status: 500, name: req.params.name, message: message}); + }else{ + res.json({status: 200}); + } + }); +}); + +router.get('/clone/:template/:name', function(req, res, next){ + lxc.clone(req.params.name, req.params.template, function(message){ + if( message.match(/Created container/) ){ + res.json({status: 200}); + }else{ + res.json({status: 500, message: message}); + } + }); +}); + +router.get('/destroy/:name', function(req, res, next){ + lxc.destroy(req.params.name, null, function(data, message){ + if(data){ + res.json({status: 500, message: message}); + }else{ + res.json({status: 200}); + } + }); +}); + +router.get('/info/:name', function(req, res, next){ + lxc.info(req.params.name, null, function(data){ + res.json(data); + }); +}); + +router.get('/list', function(req, res, next) { + lxc.list(function(data){ + res.json(data); + }); +}); + +module.exports = router; +// {"changed":true,"filter":false,"title":"index.js","tooltip":"/routes/index.js","value":"var express = require('express');\nvar router = express.Router();\nvar extend = require('node.extend');\nvar redis = require(\"redis\");\nvar client = redis.createClient();\nvar lxc = require('../lxc')({sshBind: ['/usr/bin/ssh', 'virt@127.0.0.1']});\n//lxc.startEphemeral('ubuntu_template', 'ue0', function(){console.log('cb1', arguments)}, function(){console.log('cb2', arguments)})\n\nrouter.get('/start/:name', function(req, res, next){\n lxc.start(req.params.name, null, function(status, message){\n if(status){\n res.json({status: 500, name: req.params.name, message: message});\n }else{\n setTimeout(function() {\n lxc.info(req.params.name, null, function(data){\n var domain = req.query.domain || 'vm42.us';\n domain = req.params.name+'.'+domain;\n client.SADD(\"hosts\", domain, function(){});\n \n var ip = data.ip + ':5000';\n client.HSET(domain, \"ip\", ip, redis.print);\n client.HSET(domain, \"updated\", (new Date).getTime(), redis.print);\n client.hset(domain, \"include\", \"proxy.include\");\n res.json({status: 200, info: data});\n });\n }, 5000);\n\n }\n });\n});\n\nrouter.get('/live/:template/:name', function(req, res, next){\n lxc.startEphemeral(req.params.name, req.params.template, null, function (data) {\n res.json(data);\n });\n});\n\nrouter.get('/stop/:name', function(req, res, next){\n lxc.stop(req.params.name, null, function(data, message){\n if(data){\n res.json({status: 500, name: req.params.name, message: message});\n }else{\n res.json({status: 200});\n }\n });\n});\n\nrouter.get('/clone/:template/:name', function(req, res, next){\n lxc.clone(req.params.name, req.params.template, function(message){\n if( message.match(/Created container/) ){\n res.json({status: 200});\n }else{\n res.json({status: 500, message: message});\n }\n });\n});\n\nrouter.get('/destroy/:name', function(req, res, next){\n lxc.destroy(req.params.name, null, function(data, message){\n if(data){\n res.json({status: 500, message: message});\n }else{\n res.json({status: 200});\n }\n });\n});\n\nrouter.get('/info/:name', function(req, res, next){\n lxc.info(req.params.name, null, function(data){\n res.json(data);\n });\n});\n\nrouter.get('/list', function(req, res, next) {\n lxc.list(function(data){\n res.json(data); \n });\n});\n\nmodule.exports = router;","undoManager":{"mark":90,"position":100,"stack":[[{"start":{"row":32,"column":27},"end":{"row":32,"column":30},"action":"remove","lines":["par"],"id":37},{"start":{"row":32,"column":27},"end":{"row":32,"column":33},"action":"insert","lines":["params"]}],[{"start":{"row":32,"column":33},"end":{"row":32,"column":34},"action":"insert","lines":["."],"id":38}],[{"start":{"row":32,"column":34},"end":{"row":32,"column":35},"action":"insert","lines":["n"],"id":39}],[{"start":{"row":32,"column":35},"end":{"row":32,"column":36},"action":"insert","lines":["a"],"id":40}],[{"start":{"row":32,"column":36},"end":{"row":32,"column":37},"action":"insert","lines":["m"],"id":41}],[{"start":{"row":32,"column":37},"end":{"row":32,"column":38},"action":"insert","lines":["e"],"id":42}],[{"start":{"row":32,"column":38},"end":{"row":32,"column":39},"action":"insert","lines":[","],"id":43}],[{"start":{"row":32,"column":39},"end":{"row":32,"column":40},"action":"insert","lines":[" "],"id":44}],[{"start":{"row":32,"column":40},"end":{"row":32,"column":41},"action":"insert","lines":["p"],"id":45}],[{"start":{"row":32,"column":41},"end":{"row":32,"column":42},"action":"insert","lines":["a"],"id":46}],[{"start":{"row":32,"column":42},"end":{"row":32,"column":43},"action":"insert","lines":["q"],"id":47}],[{"start":{"row":32,"column":42},"end":{"row":32,"column":43},"action":"remove","lines":["q"],"id":48}],[{"start":{"row":32,"column":41},"end":{"row":32,"column":42},"action":"remove","lines":["a"],"id":49}],[{"start":{"row":32,"column":40},"end":{"row":32,"column":41},"action":"remove","lines":["p"],"id":50}],[{"start":{"row":32,"column":40},"end":{"row":32,"column":41},"action":"insert","lines":["r"],"id":51}],[{"start":{"row":32,"column":41},"end":{"row":32,"column":42},"action":"insert","lines":["e"],"id":52}],[{"start":{"row":32,"column":42},"end":{"row":32,"column":43},"action":"insert","lines":["q"],"id":53}],[{"start":{"row":32,"column":43},"end":{"row":32,"column":44},"action":"insert","lines":[","],"id":54}],[{"start":{"row":32,"column":43},"end":{"row":32,"column":44},"action":"remove","lines":[","],"id":55}],[{"start":{"row":32,"column":43},"end":{"row":32,"column":44},"action":"insert","lines":["."],"id":56}],[{"start":{"row":32,"column":44},"end":{"row":32,"column":45},"action":"insert","lines":["p"],"id":57}],[{"start":{"row":32,"column":44},"end":{"row":32,"column":45},"action":"remove","lines":["p"],"id":58},{"start":{"row":32,"column":44},"end":{"row":32,"column":50},"action":"insert","lines":["params"]}],[{"start":{"row":32,"column":50},"end":{"row":32,"column":51},"action":"insert","lines":[","],"id":59}],[{"start":{"row":32,"column":50},"end":{"row":32,"column":51},"action":"remove","lines":[","],"id":60}],[{"start":{"row":32,"column":50},"end":{"row":32,"column":51},"action":"insert","lines":["."],"id":61}],[{"start":{"row":32,"column":51},"end":{"row":32,"column":52},"action":"insert","lines":["t"],"id":62}],[{"start":{"row":32,"column":52},"end":{"row":32,"column":53},"action":"insert","lines":["e"],"id":63}],[{"start":{"row":32,"column":51},"end":{"row":32,"column":53},"action":"remove","lines":["te"],"id":64},{"start":{"row":32,"column":51},"end":{"row":32,"column":59},"action":"insert","lines":["template"]}],[{"start":{"row":32,"column":59},"end":{"row":32,"column":60},"action":"insert","lines":[","],"id":65}],[{"start":{"row":32,"column":60},"end":{"row":32,"column":61},"action":"insert","lines":[" "],"id":66}],[{"start":{"row":32,"column":61},"end":{"row":32,"column":62},"action":"insert","lines":["n"],"id":67}],[{"start":{"row":32,"column":62},"end":{"row":32,"column":63},"action":"insert","lines":["u"],"id":68}],[{"start":{"row":32,"column":63},"end":{"row":32,"column":64},"action":"insert","lines":["k"],"id":69}],[{"start":{"row":32,"column":64},"end":{"row":32,"column":65},"action":"insert","lines":["k"],"id":70}],[{"start":{"row":32,"column":64},"end":{"row":32,"column":65},"action":"remove","lines":["k"],"id":71}],[{"start":{"row":32,"column":63},"end":{"row":32,"column":64},"action":"remove","lines":["k"],"id":72}],[{"start":{"row":32,"column":63},"end":{"row":32,"column":64},"action":"insert","lines":["l"],"id":73}],[{"start":{"row":32,"column":64},"end":{"row":32,"column":65},"action":"insert","lines":["l"],"id":74}],[{"start":{"row":32,"column":65},"end":{"row":32,"column":66},"action":"insert","lines":["m"],"id":75}],[{"start":{"row":32,"column":65},"end":{"row":32,"column":66},"action":"remove","lines":["m"],"id":76}],[{"start":{"row":32,"column":64},"end":{"row":32,"column":65},"action":"remove","lines":["l"],"id":77}],[{"start":{"row":32,"column":63},"end":{"row":32,"column":64},"action":"remove","lines":["l"],"id":78}],[{"start":{"row":32,"column":62},"end":{"row":32,"column":63},"action":"remove","lines":["u"],"id":79}],[{"start":{"row":32,"column":61},"end":{"row":32,"column":62},"action":"remove","lines":["n"],"id":80}],[{"start":{"row":32,"column":60},"end":{"row":32,"column":61},"action":"remove","lines":[" "],"id":81}],[{"start":{"row":32,"column":60},"end":{"row":32,"column":61},"action":"insert","lines":[" "],"id":82}],[{"start":{"row":32,"column":61},"end":{"row":32,"column":62},"action":"insert","lines":["n"],"id":83}],[{"start":{"row":32,"column":62},"end":{"row":32,"column":63},"action":"insert","lines":["u"],"id":84}],[{"start":{"row":32,"column":63},"end":{"row":32,"column":64},"action":"insert","lines":["l"],"id":85}],[{"start":{"row":32,"column":64},"end":{"row":32,"column":65},"action":"insert","lines":["l"],"id":86}],[{"start":{"row":32,"column":65},"end":{"row":32,"column":66},"action":"insert","lines":[","],"id":87}],[{"start":{"row":32,"column":66},"end":{"row":32,"column":67},"action":"insert","lines":[" "],"id":88}],[{"start":{"row":32,"column":67},"end":{"row":32,"column":68},"action":"insert","lines":["f"],"id":89}],[{"start":{"row":32,"column":68},"end":{"row":32,"column":69},"action":"insert","lines":["i"],"id":90}],[{"start":{"row":32,"column":68},"end":{"row":32,"column":69},"action":"remove","lines":["i"],"id":91}],[{"start":{"row":32,"column":68},"end":{"row":32,"column":69},"action":"insert","lines":["u"],"id":92}],[{"start":{"row":32,"column":69},"end":{"row":32,"column":70},"action":"insert","lines":["n"],"id":93}],[{"start":{"row":32,"column":67},"end":{"row":32,"column":70},"action":"remove","lines":["fun"],"id":94},{"start":{"row":32,"column":67},"end":{"row":34,"column":5},"action":"insert","lines":["function function_name(argument) {"," // body..."," }"]}],[{"start":{"row":32,"column":76},"end":{"row":32,"column":89},"action":"remove","lines":["function_name"],"id":95}],[{"start":{"row":32,"column":77},"end":{"row":32,"column":85},"action":"remove","lines":["argument"],"id":96},{"start":{"row":32,"column":77},"end":{"row":32,"column":78},"action":"insert","lines":["d"]}],[{"start":{"row":32,"column":78},"end":{"row":32,"column":79},"action":"insert","lines":["a"],"id":97}],[{"start":{"row":32,"column":79},"end":{"row":32,"column":80},"action":"insert","lines":["t"],"id":98}],[{"start":{"row":32,"column":80},"end":{"row":32,"column":81},"action":"insert","lines":["a"],"id":99}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":18},"action":"remove","lines":["/ body..."],"id":100}],[{"start":{"row":33,"column":8},"end":{"row":33,"column":9},"action":"remove","lines":["/"],"id":101}],[{"start":{"row":33,"column":8},"end":{"row":33,"column":9},"action":"insert","lines":["r"],"id":102}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":10},"action":"insert","lines":["e"],"id":103}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":10},"action":"remove","lines":["e"],"id":104}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":10},"action":"insert","lines":["s"],"id":105}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":10},"action":"remove","lines":["s"],"id":106}],[{"start":{"row":33,"column":8},"end":{"row":33,"column":9},"action":"remove","lines":["r"],"id":107}],[{"start":{"row":33,"column":8},"end":{"row":33,"column":9},"action":"insert","lines":["r"],"id":108}],[{"start":{"row":33,"column":9},"end":{"row":33,"column":10},"action":"insert","lines":["e"],"id":109}],[{"start":{"row":33,"column":10},"end":{"row":33,"column":11},"action":"insert","lines":["s"],"id":110}],[{"start":{"row":33,"column":11},"end":{"row":33,"column":12},"action":"insert","lines":["."],"id":111}],[{"start":{"row":33,"column":12},"end":{"row":33,"column":13},"action":"insert","lines":["j"],"id":112}],[{"start":{"row":33,"column":13},"end":{"row":33,"column":14},"action":"insert","lines":["s"],"id":113}],[{"start":{"row":33,"column":12},"end":{"row":33,"column":14},"action":"remove","lines":["js"],"id":114},{"start":{"row":33,"column":12},"end":{"row":33,"column":16},"action":"insert","lines":["json"]}],[{"start":{"row":33,"column":16},"end":{"row":33,"column":18},"action":"insert","lines":["()"],"id":115}],[{"start":{"row":33,"column":17},"end":{"row":33,"column":18},"action":"insert","lines":["d"],"id":116}],[{"start":{"row":33,"column":18},"end":{"row":33,"column":19},"action":"insert","lines":["a"],"id":117}],[{"start":{"row":33,"column":19},"end":{"row":33,"column":20},"action":"insert","lines":["t"],"id":118}],[{"start":{"row":33,"column":20},"end":{"row":33,"column":21},"action":"insert","lines":["a"],"id":119}],[{"start":{"row":33,"column":22},"end":{"row":33,"column":23},"action":"insert","lines":["l"],"id":120}],[{"start":{"row":33,"column":22},"end":{"row":33,"column":23},"action":"remove","lines":["l"],"id":121}],[{"start":{"row":33,"column":22},"end":{"row":33,"column":23},"action":"insert","lines":[";"],"id":122}],[{"start":{"row":34,"column":6},"end":{"row":34,"column":7},"action":"insert","lines":[";"],"id":123}],[{"start":{"row":52,"column":53},"end":{"row":52,"column":54},"action":"insert","lines":[";"],"id":124}],[{"start":{"row":62,"column":35},"end":{"row":62,"column":36},"action":"insert","lines":[";"],"id":125}],[{"start":{"row":22,"column":67},"end":{"row":22,"column":68},"action":"insert","lines":[";"],"id":126}],[{"start":{"row":5,"column":19},"end":{"row":5,"column":20},"action":"insert","lines":["."],"id":127}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":4},"action":"remove","lines":[" "],"id":128}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":4},"action":"remove","lines":[" "],"id":129}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":4},"action":"remove","lines":[" "],"id":130}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":4},"action":"remove","lines":[" "],"id":131}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":3},"action":"remove","lines":[" "],"id":132}],[{"start":{"row":23,"column":0},"end":{"row":23,"column":4},"action":"insert","lines":[" "],"id":133}],[{"start":{"row":23,"column":4},"end":{"row":23,"column":8},"action":"insert","lines":[" "],"id":134}],[{"start":{"row":23,"column":8},"end":{"row":23,"column":12},"action":"insert","lines":[" "],"id":135}],[{"start":{"row":23,"column":12},"end":{"row":23,"column":16},"action":"insert","lines":[" "],"id":136}],[{"start":{"row":23,"column":16},"end":{"row":23,"column":20},"action":"insert","lines":[" "],"id":137}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":23,"column":20},"end":{"row":23,"column":20},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":92,"mode":"ace/mode/javascript"}},"timestamp":1448259407910} \ No newline at end of file diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..d30f494 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.render('index') +}); + +module.exports = router; diff --git a/stuff.md b/stuff.md new file mode 100644 index 0000000..92a1987 --- /dev/null +++ b/stuff.md @@ -0,0 +1,5 @@ +## Auto start +`@reboot /usr/local/bin/forever start -o /var/log/forver.out.log -e /var/log/sorver.err.log -c "/usr/local/bin/codebox run -p 5000" /workspace/` +http://stackoverflow.com/a/13388741/3140931 + + diff --git a/views/error.ejs b/views/error.ejs new file mode 100644 index 0000000..7cf94ed --- /dev/null +++ b/views/error.ejs @@ -0,0 +1,3 @@ +

<%= message %>

+

<%= error.status %>

+
<%= error.stack %>
diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 0000000..2ff58d5 --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + +

Start will take atlest 5 seconds!

+ +
    +
  1. + {{ name }} | {{ state }} | {{ ip }} + +
    + + + +
    + {{{ url }}} + {{{ clone }}} + {{{ message }}} +
    +
  2. +
+ +