Compare commits
315 Commits
Author | SHA1 | Date | |
---|---|---|---|
6e034f26c3 | |||
f01049df74 | |||
0a45462205 | |||
9dc7b76d11 | |||
10e5c885f6 | |||
ceb08124f0 | |||
81c14dbc80 | |||
b81a5a9c2f | |||
0f0033a646 | |||
127a2caac1 | |||
47027fdf39 | |||
cfd6c373ad | |||
128320f80e | |||
5711070d92 | |||
8e89c986bb | |||
14a628a8ff | |||
b45f45153f | |||
8c64959482 | |||
e74f24b2b9 | |||
5533187636 | |||
4a0e16f5f6 | |||
21ad051a4d | |||
3b36642ff8 | |||
84a51ca0db | |||
8779c5c6ca | |||
3a948df9f1 | |||
c2f7dc72aa | |||
70091ddbdb | |||
ef2e953366 | |||
e01794edbc | |||
00f68ef649 | |||
bfa3e689b3 | |||
ec565c2803 | |||
f525c4d98f | |||
7f04135505 | |||
8e82a7f47a | |||
40b6b6ffdc | |||
3a5c110aec | |||
e412dd3f1f | |||
68e7c48bc7 | |||
bbc1025c7d | |||
08f3b1fce6 | |||
432b056609 | |||
7c49a0c623 | |||
841b7d1b35 | |||
1f4f9686bb | |||
bc1c56f37c | |||
992a891aee | |||
78658a5c9f | |||
ae8c58bfda | |||
cba7ba7dbe | |||
8723a7b97a | |||
8533950663 | |||
4dd67ea2f6 | |||
640fb30c8a | |||
d4b45739f1 | |||
ab317dc791 | |||
9bf4055923 | |||
f836ece931 | |||
2aa0257502 | |||
714ff75cb6 | |||
6b662f131d | |||
e27bb6deba | |||
de4ce8553e | |||
e9bd665cc1 | |||
d90e0aaa25 | |||
d204f29526 | |||
0c46420715 | |||
93bf4b2577 | |||
11c7b1907d | |||
b808d23965 | |||
2a21be1825 | |||
9c69033756 | |||
00bca4ff34 | |||
29ad409649 | |||
aee63de478 | |||
67b717ace1 | |||
4d78659654 | |||
5467209d25 | |||
a432df7879 | |||
ded9cff1dc | |||
9bb9809f51 | |||
9072167e65 | |||
7c97bed5b0 | |||
fd4405bca5 | |||
2237d3cac3 | |||
3e0d34a2f5 | |||
4b4ab75aaa | |||
cfc6d406a1 | |||
1624d9f7ff | |||
e8c26abd52 | |||
5a5c453ea3 | |||
71ab12c64e | |||
be7f518778 | |||
b8dfaff861 | |||
eec89027a4 | |||
421a8ec78b | |||
a77d00aab4 | |||
c971b609ee | |||
b8f72ef13c | |||
f9482b3483 | |||
136bf04825 | |||
6c2a8d48bf | |||
d22a79c81e | |||
4c2a4b7657 | |||
d1a87a033b | |||
18ff2ee3be | |||
651f3835e2 | |||
232e9b72bb | |||
f714a6e179 | |||
9b7936ee3a | |||
ce96c7cb87 | |||
23f7cf1f68 | |||
b1e3e23d91 | |||
f63b6c3acd | |||
05b6a477f4 | |||
848f439122 | |||
f0d6016a63 | |||
37fae2e413 | |||
42ea77720a | |||
4079ee8208 | |||
cd37c680f0 | |||
7d12414d74 | |||
a7e1478697 | |||
571e81ace5 | |||
02c0c85417 | |||
0b9b5c0627 | |||
e6dee5bde3 | |||
586c8cc32f | |||
2ba7fa58e2 | |||
b84c87d55d | |||
f86a74a589 | |||
a51f4c203c | |||
ccd128100a | |||
191851e2bb | |||
b5baacf668 | |||
3e592887d1 | |||
18897cd4e6 | |||
b5737a0470 | |||
732d15cc54 | |||
424b5c68c8 | |||
f6f5b81b49 | |||
eb9b8b2556 | |||
d5bd5d2c39 | |||
71bd4ffc4a | |||
101160e887 | |||
371a40a3d3 | |||
8a5001aee7 | |||
9991e7eb36 | |||
7fcbcecb6a | |||
6b72ddcdd4 | |||
a4f01f8062 | |||
5a0ab51c32 | |||
dd68a29208 | |||
bf21a8b966 | |||
99043948db | |||
ee3091ae3c | |||
ac524a1c76 | |||
d7b32996b3 | |||
7ba58ee8d6 | |||
9a58acdfa2 | |||
28596a0b4d | |||
1086baf65a | |||
8c32b2e246 | |||
c319487141 | |||
a301ad88e5 | |||
d4da910040 | |||
62fcae727a | |||
1ddda799d3 | |||
9a0ad761b9 | |||
26f06c0aa8 | |||
b8f23077da | |||
7d4965b21e | |||
1af8aed161 | |||
5fc47fbbcc | |||
129cd54812 | |||
c6e9ec62ba | |||
caf32c3809 | |||
19293fdaff | |||
f32d6f70a9 | |||
66f6c3b92a | |||
ed2b37d696 | |||
61dedb013d | |||
0e7ccf2637 | |||
b74a71efb4 | |||
4651a2f49c | |||
eff29a9922 | |||
baa8fe6730 | |||
16f91f01a7 | |||
b53c3e6808 | |||
a1338c5792 | |||
f875bf101a | |||
f503f370b2 | |||
32e70d4be4 | |||
15cac181c3 | |||
63b7a3b481 | |||
360f2c591d | |||
d4214cbf1d | |||
d23f1b91d1 | |||
4ca49a9632 | |||
b8ce1fdcfc | |||
4257644d4e | |||
dd759efd8a | |||
ae2a4984e4 | |||
152b206f9c | |||
e6c45352c9 | |||
d00b325625 | |||
f5ea0966dc | |||
405569a0c9 | |||
3b356a48f8 | |||
30525c984c | |||
998063268f | |||
22905cf056 | |||
923b6fdd78 | |||
8f9a43c743 | |||
8962181782 | |||
82ce62a678 | |||
8b0556b545 | |||
2b8ef1d39e | |||
f80988a929 | |||
7834e892bf | |||
1db5cbb600 | |||
18cbb5536b | |||
2e21a7d91b | |||
3a1276db67 | |||
fcb4612e1c | |||
a158d05b9d | |||
7e5fae983b | |||
d10c699145 | |||
c97100c9a7 | |||
2a6cce6296 | |||
2fc8276634 | |||
651a4d82a5 | |||
19395652c4 | |||
7f0489cfa9 | |||
1db7bd8f3c | |||
a65c87017a | |||
70bd796bc6 | |||
a5afd8469c | |||
c742c8fb7a | |||
c42cf797e7 | |||
280a90a7eb | |||
f82968fbbe | |||
ceadfcb24f | |||
f809e57ba5 | |||
d93b43d37f | |||
109db64634 | |||
2f8cf5c120 | |||
d452250126 | |||
6acc3fba21 | |||
5c94ea4c29 | |||
0b1b1fd5c9 | |||
049972b278 | |||
5c91414521 | |||
299040be6f | |||
1dce0358cc | |||
7e2c575a06 | |||
96c931ba5c | |||
c9b66b1bd6 | |||
2ea36dc963 | |||
77d8f2b743 | |||
3a313a21d1 | |||
491f6c57e8 | |||
96b032f816 | |||
fbc9a308b9 | |||
56cebedf04 | |||
b7c8335a82 | |||
57cfc24e92 | |||
9c2fbaab99 | |||
d57058b59c | |||
147d7ab41f | |||
39b64a4ecd | |||
aa5dd97694 | |||
e481f1c071 | |||
2dba8c9c4f | |||
81bda27acd | |||
3b89660ef1 | |||
a74d7130d7 | |||
1ee46f6d2c | |||
99dcc47e00 | |||
8ce30f1e60 | |||
1e3f9a7302 | |||
517690a454 | |||
469d4deb7e | |||
64af338a6c | |||
cf05db1c91 | |||
ee7ff554e7 | |||
c77ee3a007 | |||
46ad5ae25d | |||
8c0d3bd6da | |||
c8d32de96d | |||
f19c673764 | |||
238cfd94b3 | |||
e7987d8035 | |||
f8ff072690 | |||
b0ab1a5313 | |||
a1a0ec8d02 | |||
d438cdd249 | |||
708c5ea5d3 | |||
7c37aa2e8b | |||
025205e349 | |||
85e0dcf729 | |||
45bf9c67f6 | |||
d34a482a60 | |||
0c891f62ef | |||
5df3ecd5af | |||
55813dc422 | |||
ee57ab01e1 | |||
b27f0d6bd9 | |||
303c80f601 | |||
1cafd74cc4 | |||
a8d53d5bc5 | |||
c8a3d5c60d | |||
cb68bc4eec | |||
a4a1cf314a |
3
.gitignore
vendored
3
.gitignore
vendored
@ -29,3 +29,6 @@ node_modules
|
||||
# Debug log from npm
|
||||
npm-debug.log
|
||||
.c9
|
||||
|
||||
# keys
|
||||
secrets.js
|
56
README.md
56
README.md
@ -1,5 +1,5 @@
|
||||
# lxc_manager_node
|
||||
This has been tested on **clean** install of ubuntu 14.04 64bit.
|
||||
This has been tested on **clean** install of ubuntu 16.04 64bit.
|
||||
|
||||
## install
|
||||
Update you system to the newest packages and reboot. You may need to do this several times:
|
||||
@ -18,9 +18,13 @@ Now you can install the packages we need:
|
||||
sudo add-apt-repository ppa:ubuntu-lxc/stable
|
||||
sudo add-apt-repository ppa:ubuntu-lxc/cgmanager-stable
|
||||
sudo apt-get update && sudo apt-get upgrade
|
||||
sudo apt-get install git nodejs npm lxc redis-server btrfs-tools
|
||||
sudo apt-get install git nodejs npm lxc btrfs-tools lxctl lxc-templates uidmap libpam-cgfs
|
||||
```
|
||||
|
||||
### may need this
|
||||
https://discuss.linuxcontainers.org/t/failed-creating-cgroups/272/10 looking more into it.
|
||||
|
||||
|
||||
remap `nodejs` to `node`:
|
||||
```bash
|
||||
sudo ln -s /usr/bin/nodejs /usr/bin/node
|
||||
@ -53,10 +57,11 @@ Clone the repo and set it up:
|
||||
git clone https://github.com/wmantly/lxc_manager_node.git
|
||||
cd lxc_manager_node
|
||||
npm install
|
||||
```
|
||||
|
||||
Its safer at this point to reboot the system, `exit` back to the privlaged user and `reboot`
|
||||
|
||||
**SSH or log dercily into the `virt` user!!!** this will not if you use su!
|
||||
**SSH or log dercily into the `virt` user!!!** this will not work if you use su to get into the user!
|
||||
|
||||
Now you can can create a test container:
|
||||
```bash
|
||||
@ -72,7 +77,52 @@ If everything worked you can stop and delete the container
|
||||
lxc-stop -n test-ubuntu
|
||||
lxc-destroy -n test-ubuntu
|
||||
```
|
||||
## Open resty config file
|
||||
```lua
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
resolver 10.0.3.1; # use LXC dns
|
||||
|
||||
set $target '';
|
||||
access_by_lua '
|
||||
function mysplit(inputstr, sep)
|
||||
-- http://stackoverflow.com/a/7615129/3140931
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local t={} ; i=0
|
||||
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
||||
t[i] = str
|
||||
i = i + 1
|
||||
end
|
||||
return t,i
|
||||
end
|
||||
|
||||
host, hostLen = mysplit(ngx.var.host, ".")
|
||||
|
||||
if hostLen == 1 then
|
||||
ngx.var.target = host[0]..":15000"
|
||||
elseif hostLen == 6 then
|
||||
ngx.var.target = host[1]..":"..host[0]
|
||||
elseif hostLen == 5 then
|
||||
ngx.var.target = host[0]..":15000"
|
||||
else
|
||||
return ngx.exit(599)
|
||||
end
|
||||
';
|
||||
|
||||
proxy_pass http://$target;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# auto start
|
||||
## crontab
|
||||
|
6
app.js
6
app.js
@ -18,6 +18,12 @@ app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
next();
|
||||
});
|
||||
|
||||
app.use('/', require('./routes/index'));
|
||||
app.use('/api', require('./routes/api'));
|
||||
|
||||
|
178
doapi.js
Normal file
178
doapi.js
Normal file
@ -0,0 +1,178 @@
|
||||
var request = require('request');
|
||||
|
||||
api = function(key){
|
||||
key = key || require('./secrets.js').doAPI;
|
||||
this.BASEURL = 'https://api.digitalocean.com/v2/';
|
||||
this.headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer '+key
|
||||
}
|
||||
this.calls = 0;
|
||||
|
||||
this.account = function(callback){
|
||||
var options = {
|
||||
url: this.BASEURL+'account',
|
||||
headers: this.headers
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.get(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.dropletsByTag = function(tag, callback){
|
||||
var options = {
|
||||
url: this.BASEURL+'droplets?tag_name='+tag,
|
||||
headers: this.headers
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.get(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.dropletSetTag = function(tag, dropletID, callback) {
|
||||
callback = callback || function(){};
|
||||
var data = {
|
||||
resources: [
|
||||
{
|
||||
resource_id: dropletID,
|
||||
resource_type: 'droplet'
|
||||
}
|
||||
]
|
||||
};
|
||||
var options = {
|
||||
url: this.BASEURL+'tags/'+tag+'/resources',
|
||||
headers: this.headers,
|
||||
body: JSON.stringify(data)
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.post(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.dropletCreate = function(args, callback){
|
||||
callback = callback || function(){};
|
||||
|
||||
var data = {
|
||||
name: args.name, // || return false,
|
||||
region: args.region || 'nyc3',
|
||||
size: args.size || '512mb',
|
||||
image: args.image || 'ubuntu-14-04-x64',
|
||||
ssh_keys: args.ssh_key || null,
|
||||
backups: args.backup || false,
|
||||
private_networking: args.private_networking || true,
|
||||
user_data: args.user_data || null
|
||||
};
|
||||
var options = {
|
||||
url: this.BASEURL+'droplets',
|
||||
headers: this.headers,
|
||||
body: JSON.stringify(data)
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.post(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
}
|
||||
|
||||
this.dropletToActive = function(args){
|
||||
args.__doapi = this; // hold the DO api in the agrs scope
|
||||
args.onCreated = args.onCreate || function(){};
|
||||
|
||||
this.dropletCreate(args, function(data){
|
||||
data = JSON.parse(data);
|
||||
args.onCreate(data, args);
|
||||
|
||||
// check if the server is ready, giving time to allow
|
||||
// digital ocean to do its thing
|
||||
setTimeout(function check(id, args){
|
||||
time = args.time || 10000;
|
||||
args.__doapi.dropletInfo(id, function (data){
|
||||
var droplet = JSON.parse(data)['droplet'];
|
||||
if(droplet.status == 'active'){
|
||||
|
||||
return args.onActive(droplet, args);
|
||||
}else{
|
||||
setTimeout(function(check, id){
|
||||
check(id, args);
|
||||
}, time, check, droplet.id);
|
||||
}
|
||||
});
|
||||
}, 70000, data.droplet.id, args);
|
||||
});
|
||||
};
|
||||
|
||||
this.dropletDestroy = function(dropletID, callback){
|
||||
callback = callback || function(){};
|
||||
var options = {
|
||||
url: this.BASEURL+'droplets/'+dropletID,
|
||||
headers: this.headers
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.del(options, function(error, response, body){
|
||||
callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.dropletInfo = function(dropletID, callback){
|
||||
var options = {
|
||||
url: this.BASEURL+'droplets/'+dropletID,
|
||||
headers: this.headers
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.get(options, function(error, response, body){
|
||||
callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.tagCreate = function(tag, callback){
|
||||
callback = callback || function(){};
|
||||
var options = {
|
||||
url: this.BASEURL+'tags',
|
||||
headers: this.headers,
|
||||
body: JSON.stringify({name: tag})
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.post(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
};
|
||||
|
||||
this.tagsList = function(callback){
|
||||
var options = {
|
||||
url: this.BASEURL+'tags',
|
||||
headers: this.headers
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.get(options, function(e,r,b){
|
||||
callback(b,r,e);
|
||||
});
|
||||
};
|
||||
|
||||
this.domianAddRecord = function(args, callback){
|
||||
callback = callback || function(){};
|
||||
var options = {
|
||||
url: this.BASEURL+'domains/'+ args.domain +'/records',
|
||||
headers: this.headers,
|
||||
body: JSON.stringify(args)
|
||||
};
|
||||
this.calls++;
|
||||
|
||||
return request.post(options, function(error, response, body){
|
||||
return callback(body, response, error);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
module.exports = api;
|
18
guest_setup.sh
Normal file
18
guest_setup.sh
Normal file
@ -0,0 +1,18 @@
|
||||
apt update;
|
||||
apt upgrade -y;
|
||||
|
||||
wget https://github.com/wmantly/crunner/blob/master/crunner?raw=true -O /usr/local/bin/crunner;
|
||||
chmod +x /usr/local/bin/crunner;
|
||||
|
||||
apt install git nano wget python3-dev python3-pip;
|
||||
|
||||
echo "
|
||||
#!/bin/bash;
|
||||
export NODE_PATH='/usr/local/lib/node_modules:$NODE_PATH';
|
||||
export TERM=xterm-256color;
|
||||
cd ~;
|
||||
crunner &;
|
||||
exit 0;
|
||||
" > /opt/bytedev.sh
|
||||
|
||||
|
41
host_setup.sh
Normal file
41
host_setup.sh
Normal file
@ -0,0 +1,41 @@
|
||||
echo "Update the base system\n";
|
||||
apt update;
|
||||
apt upgrade -y;
|
||||
|
||||
echo "\n\n\nInstall stuff\n";
|
||||
|
||||
add-apt-repository -y ppa:ubuntu-lxc/stable;
|
||||
apt update;
|
||||
apt upgrade -y;
|
||||
apt install -y git lxc btrfs-tools lxctl lxc-templates uidmap libpam-cgfs libpcre3-dev libssl-dev perl make build-essential curl;
|
||||
|
||||
echo "\n\n\ninstalling open resty\n";
|
||||
|
||||
# import our GPG key:
|
||||
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -;
|
||||
|
||||
# for installing the add-apt-repository command
|
||||
# (you can remove this package and its dependencies later):
|
||||
apt-get -y install software-properties-common;
|
||||
|
||||
# add the our official APT repository:
|
||||
add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main";
|
||||
|
||||
# to update the APT index:
|
||||
apt-get update;
|
||||
|
||||
apt-get install -y openresty;
|
||||
|
||||
# TODO!
|
||||
# Add the proxy config file
|
||||
|
||||
echo "\n\n\nSet up virt user\n";
|
||||
|
||||
|
||||
adduser virt --gecos "" --disabled-password;
|
||||
echo "virt:1lovebyte" | chpasswd;
|
||||
|
||||
echo "virt veth lxcbr0 1024" | tee -a /etc/lxc/lxc-usernet;
|
||||
|
||||
# TODO!
|
||||
# added default base config for LXC runners.
|
50
lxc.js
50
lxc.js
@ -1,8 +1,12 @@
|
||||
'use strict';
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
function sysExec(command, callback){
|
||||
command = 'unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; ' + command;
|
||||
|
||||
function sysExec(command, ip, callback){
|
||||
ip = ip || '104.236.77.157';
|
||||
command = new Buffer(command).toString('base64')
|
||||
command = 'ssh -i ~/.ssh/clw_rsa -o StrictHostKeyChecking=no virt@'+ ip + ' "echo ' + command + '|base64 --decode|bash"';
|
||||
// command = 'unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; ' + command;
|
||||
|
||||
return exec(command, (function(callback){
|
||||
return function(err,data,stderr){
|
||||
@ -13,30 +17,9 @@ function sysExec(command, callback){
|
||||
})(callback));
|
||||
};
|
||||
|
||||
var Container = function(config){
|
||||
this.name = config.name;
|
||||
this.state = config.state;
|
||||
this.ip = config.ip || (config.ipv4 || '').replace('-', '') || null ;
|
||||
}
|
||||
|
||||
Container.prototype.autoShutDown = function(time) {
|
||||
time = time || 600000;
|
||||
|
||||
// this.__shutDownTimeout = setTimeout(function(){}, this.autoShutDown):
|
||||
};
|
||||
|
||||
var lxcORM = function(){
|
||||
var orm = {}
|
||||
lxc.list(function(data){
|
||||
for(var idx = data.length; idx--;){
|
||||
orm[data[idx].name] = new Container(data[idx]);
|
||||
}
|
||||
});
|
||||
|
||||
return orm
|
||||
};
|
||||
|
||||
var lxc = {
|
||||
exec: sysExec,
|
||||
|
||||
create: function(name, template, config, callback){
|
||||
return sysExec('lxc-create -n '+name+' -t '+template, callback);
|
||||
},
|
||||
@ -48,7 +31,7 @@ var lxc = {
|
||||
destroy: function(name, callback){
|
||||
return sysExec('lxc-destroy -n '+ name, function(data){
|
||||
var info = data.match(/Destroyed container/);
|
||||
console.log('destroy info:', info);
|
||||
// console.log('destroy info:', info);
|
||||
var args = [true].concat(Array.prototype.slice.call(arguments, 1));
|
||||
return callback.apply(this, args);
|
||||
});
|
||||
@ -58,10 +41,10 @@ var lxc = {
|
||||
return sysExec('lxc-start --name '+name+' --daemon', callback);
|
||||
},
|
||||
|
||||
startEphemeral: function(name, base_name, callback){
|
||||
startEphemeral: function(name, base_name, ip, callback){
|
||||
var command = 'lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d';
|
||||
return sysExec(command, function(data){
|
||||
console.log('startEphemeral', arguments);
|
||||
return sysExec(command, ip, function(data){
|
||||
// console.log('startEphemeral', arguments);
|
||||
if(data.match("doesn't exist.")){
|
||||
return callback({status: 500, error: "doesn't exist."});
|
||||
}
|
||||
@ -76,8 +59,8 @@ var lxc = {
|
||||
});
|
||||
},
|
||||
|
||||
stop: function(name, callback){
|
||||
return sysExec('lxc-stop -n '+ name, callback);
|
||||
stop: function(name, ip, callback){
|
||||
return sysExec('lxc-stop -n '+ name, ip, callback);
|
||||
},
|
||||
|
||||
freeze: function(name, callback){
|
||||
@ -90,7 +73,7 @@ var lxc = {
|
||||
|
||||
info: function(name, callback){
|
||||
return sysExec('lxc-info -n '+name, function(data){
|
||||
console.log('info', arguments);
|
||||
// console.log('info', arguments);
|
||||
if(data.match("doesn't exist")){
|
||||
return callback({state: 'NULL'});
|
||||
}
|
||||
@ -133,6 +116,3 @@ var lxc = {
|
||||
};
|
||||
|
||||
module.exports = lxc;
|
||||
|
||||
var orm = lxcORM()
|
||||
setTimeout(function(){console.log(orm)}, 5000)
|
||||
|
974
package-lock.json
generated
Normal file
974
package-lock.json
generated
Normal file
@ -0,0 +1,974 @@
|
||||
{
|
||||
"name": "manager",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz",
|
||||
"integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=",
|
||||
"requires": {
|
||||
"mime-types": "2.1.17",
|
||||
"negotiator": "0.5.3"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
||||
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
||||
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
|
||||
},
|
||||
"async": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
|
||||
"integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
|
||||
"requires": {
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
||||
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
||||
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
|
||||
},
|
||||
"basic-auth": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz",
|
||||
"integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
||||
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz",
|
||||
"integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=",
|
||||
"requires": {
|
||||
"readable-stream": "2.0.6"
|
||||
}
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.13.3.tgz",
|
||||
"integrity": "sha1-wIzzMMM1jhUQFqBXRvE/ApyX+pc=",
|
||||
"requires": {
|
||||
"bytes": "2.1.0",
|
||||
"content-type": "1.0.4",
|
||||
"debug": "2.2.0",
|
||||
"depd": "1.0.1",
|
||||
"http-errors": "1.3.1",
|
||||
"iconv-lite": "0.4.11",
|
||||
"on-finished": "2.3.0",
|
||||
"qs": "4.0.0",
|
||||
"raw-body": "2.1.7",
|
||||
"type-is": "1.6.15"
|
||||
}
|
||||
},
|
||||
"boom": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz",
|
||||
"integrity": "sha1-rJPEEOL/ycx89LRks4KJBn9eR7Q="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
|
||||
"integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"requires": {
|
||||
"ansi-styles": "2.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"has-ansi": "2.0.0",
|
||||
"strip-ansi": "3.0.1",
|
||||
"supports-color": "2.0.0"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
||||
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
|
||||
"requires": {
|
||||
"delayed-stream": "1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
|
||||
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.1.tgz",
|
||||
"integrity": "sha1-h0dsamfI2qh+Muh2Ft+IO6f7Bxs="
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz",
|
||||
"integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
|
||||
"integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=",
|
||||
"requires": {
|
||||
"cookie": "0.1.3",
|
||||
"cookie-signature": "1.0.6"
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
||||
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
||||
"requires": {
|
||||
"boom": "2.10.1"
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
||||
"requires": {
|
||||
"ms": "0.7.1"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz",
|
||||
"integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"double-ended-queue": {
|
||||
"version": "2.1.0-0",
|
||||
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
|
||||
"integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsbn": "0.1.1"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"ejs": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.3.4.tgz",
|
||||
"integrity": "sha1-PHbKoJZks1g7ADevncE2557Gi5g="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz",
|
||||
"integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.13.4",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.13.4.tgz",
|
||||
"integrity": "sha1-PAt288d1kMg0VzkGHsC9O6Bn7CQ=",
|
||||
"requires": {
|
||||
"accepts": "1.2.13",
|
||||
"array-flatten": "1.1.1",
|
||||
"content-disposition": "0.5.1",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.1.5",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.2.0",
|
||||
"depd": "1.1.1",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.7.0",
|
||||
"finalhandler": "0.4.1",
|
||||
"fresh": "0.3.0",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "1.1.2",
|
||||
"on-finished": "2.3.0",
|
||||
"parseurl": "1.3.2",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "1.0.10",
|
||||
"qs": "4.0.0",
|
||||
"range-parser": "1.0.3",
|
||||
"send": "0.13.1",
|
||||
"serve-static": "1.10.3",
|
||||
"type-is": "1.6.15",
|
||||
"utils-merge": "1.0.0",
|
||||
"vary": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.5.tgz",
|
||||
"integrity": "sha1-armUiksa4hlSzSWIUwpHItQETXw="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.1.tgz",
|
||||
"integrity": "sha1-haF8bFmpRxfSYtYSMNSw6+PUoU0=",
|
||||
"requires": {
|
||||
"debug": "2.2.0",
|
||||
"escape-html": "1.0.3",
|
||||
"on-finished": "2.3.0",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz",
|
||||
"integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=",
|
||||
"requires": {
|
||||
"async": "2.5.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"mime-types": "2.1.17"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz",
|
||||
"integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8="
|
||||
},
|
||||
"generate-function": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
|
||||
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ="
|
||||
},
|
||||
"generate-object-property": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
|
||||
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
|
||||
"requires": {
|
||||
"is-property": "1.0.2"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||
"optional": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
||||
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
"commander": "2.11.0",
|
||||
"is-my-json-valid": "2.16.1",
|
||||
"pinkie-promise": "2.0.1"
|
||||
}
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"hawk": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
||||
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
||||
"requires": {
|
||||
"boom": "2.10.1",
|
||||
"cryptiles": "2.0.5",
|
||||
"hoek": "2.16.3",
|
||||
"sntp": "1.0.9"
|
||||
}
|
||||
},
|
||||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
|
||||
"integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=",
|
||||
"requires": {
|
||||
"inherits": "2.0.3",
|
||||
"statuses": "1.3.1"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
|
||||
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
|
||||
"requires": {
|
||||
"assert-plus": "0.2.0",
|
||||
"jsprim": "1.4.1",
|
||||
"sshpk": "1.13.1"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.11",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz",
|
||||
"integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz",
|
||||
"integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c="
|
||||
},
|
||||
"is": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz",
|
||||
"integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU="
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
|
||||
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
|
||||
"requires": {
|
||||
"generate-function": "2.0.0",
|
||||
"generate-object-property": "1.2.0",
|
||||
"jsonpointer": "4.0.1",
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
"is-property": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"optional": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
|
||||
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11"
|
||||
}
|
||||
},
|
||||
"jsonpointer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
|
||||
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
|
||||
"integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
|
||||
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.17",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
|
||||
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
|
||||
"requires": {
|
||||
"mime-db": "1.30.0"
|
||||
}
|
||||
},
|
||||
"morgan": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz",
|
||||
"integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=",
|
||||
"requires": {
|
||||
"basic-auth": "1.0.4",
|
||||
"debug": "2.2.0",
|
||||
"depd": "1.0.1",
|
||||
"on-finished": "2.3.0",
|
||||
"on-headers": "1.0.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
||||
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz",
|
||||
"integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g="
|
||||
},
|
||||
"node-uuid": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
|
||||
"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
|
||||
},
|
||||
"node.extend": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz",
|
||||
"integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=",
|
||||
"requires": {
|
||||
"is": "3.2.1"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
|
||||
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"on-headers": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
|
||||
"integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
||||
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
|
||||
},
|
||||
"pinkie-promise": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
|
||||
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
|
||||
"requires": {
|
||||
"pinkie": "2.0.4"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz",
|
||||
"integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=",
|
||||
"requires": {
|
||||
"forwarded": "0.1.2",
|
||||
"ipaddr.js": "1.0.5"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz",
|
||||
"integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz",
|
||||
"integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
|
||||
"integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=",
|
||||
"requires": {
|
||||
"bytes": "2.4.0",
|
||||
"iconv-lite": "0.4.13",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
|
||||
"integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
|
||||
"integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
|
||||
"integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"string_decoder": "0.10.31",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-2.4.2.tgz",
|
||||
"integrity": "sha1-L5FgJVompsrSt5vwhH4GcoChRuo=",
|
||||
"requires": {
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"redis-commands": "1.3.1"
|
||||
}
|
||||
},
|
||||
"redis-commands": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
|
||||
"integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs="
|
||||
},
|
||||
"request": {
|
||||
"version": "2.69.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.69.0.tgz",
|
||||
"integrity": "sha1-z5HS4AB1KxIXFVwAUkGRGZGiNGo=",
|
||||
"requires": {
|
||||
"aws-sign2": "0.6.0",
|
||||
"aws4": "1.6.0",
|
||||
"bl": "1.0.3",
|
||||
"caseless": "0.11.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"extend": "3.0.1",
|
||||
"forever-agent": "0.6.1",
|
||||
"form-data": "1.0.1",
|
||||
"har-validator": "2.0.6",
|
||||
"hawk": "3.1.3",
|
||||
"http-signature": "1.1.1",
|
||||
"is-typedarray": "1.0.0",
|
||||
"isstream": "0.1.2",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"mime-types": "2.1.17",
|
||||
"node-uuid": "1.4.8",
|
||||
"oauth-sign": "0.8.2",
|
||||
"qs": "6.0.4",
|
||||
"stringstream": "0.0.5",
|
||||
"tough-cookie": "2.2.2",
|
||||
"tunnel-agent": "0.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"qs": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.0.4.tgz",
|
||||
"integrity": "sha1-UQGdhHIMk5uCc36EVWp4Izjs6ns="
|
||||
}
|
||||
}
|
||||
},
|
||||
"send": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.13.1.tgz",
|
||||
"integrity": "sha1-ow1fTILIqbrprQCh2bG9vm8Zntc=",
|
||||
"requires": {
|
||||
"debug": "2.2.0",
|
||||
"depd": "1.1.1",
|
||||
"destroy": "1.0.4",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.7.0",
|
||||
"fresh": "0.3.0",
|
||||
"http-errors": "1.3.1",
|
||||
"mime": "1.3.4",
|
||||
"ms": "0.7.1",
|
||||
"on-finished": "2.3.0",
|
||||
"range-parser": "1.0.3",
|
||||
"statuses": "1.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz",
|
||||
"integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-favicon": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz",
|
||||
"integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=",
|
||||
"requires": {
|
||||
"etag": "1.7.0",
|
||||
"fresh": "0.3.0",
|
||||
"ms": "0.7.2",
|
||||
"parseurl": "1.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz",
|
||||
"integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=",
|
||||
"requires": {
|
||||
"escape-html": "1.0.3",
|
||||
"parseurl": "1.3.2",
|
||||
"send": "0.13.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.13.2",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz",
|
||||
"integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=",
|
||||
"requires": {
|
||||
"debug": "2.2.0",
|
||||
"depd": "1.1.1",
|
||||
"destroy": "1.0.4",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.7.0",
|
||||
"fresh": "0.3.0",
|
||||
"http-errors": "1.3.1",
|
||||
"mime": "1.3.4",
|
||||
"ms": "0.7.1",
|
||||
"on-finished": "2.3.0",
|
||||
"range-parser": "1.0.3",
|
||||
"statuses": "1.2.1"
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz",
|
||||
"integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sntp": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
||||
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
|
||||
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
|
||||
"requires": {
|
||||
"asn1": "0.2.3",
|
||||
"assert-plus": "1.0.0",
|
||||
"bcrypt-pbkdf": "1.0.1",
|
||||
"dashdash": "1.14.1",
|
||||
"ecc-jsbn": "0.1.1",
|
||||
"getpass": "0.1.7",
|
||||
"jsbn": "0.1.1",
|
||||
"tweetnacl": "0.14.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
|
||||
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz",
|
||||
"integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc="
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
|
||||
"integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us="
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"optional": true
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.15",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
|
||||
"integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "2.1.17"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
|
||||
"integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz",
|
||||
"integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA="
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
}
|
||||
}
|
||||
}
|
@ -11,10 +11,11 @@
|
||||
"debug": "~2.2.0",
|
||||
"ejs": "~2.3.3",
|
||||
"express": "~4.13.1",
|
||||
"jsonfile": "^2.3.1",
|
||||
"morgan": "~1.6.1",
|
||||
"serve-favicon": "~2.3.0",
|
||||
"node.extend": "~1.1.5",
|
||||
"redis": "~2.4.2",
|
||||
"request": "~2.69.0"
|
||||
"request": "~2.69.0",
|
||||
"serve-favicon": "~2.3.0"
|
||||
}
|
||||
}
|
||||
|
535
routes/api.js
535
routes/api.js
@ -2,51 +2,376 @@
|
||||
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
var extend = require('node.extend');
|
||||
var redis = require("redis");
|
||||
var client = redis.createClient();
|
||||
var util = require('util');
|
||||
var request = require('request');
|
||||
var jsonfile = require('jsonfile');
|
||||
var lxc = require('../lxc');
|
||||
var doapi = require('../doapi')();
|
||||
var settings = require('./workers.json');
|
||||
|
||||
var runner = function(req, res, ip){
|
||||
return request.post({url:'http://'+ip, form: req.body}, function(error, response, body){
|
||||
body = JSON.parse(body);
|
||||
body['ip'] = ip.replace('10.0.', '');
|
||||
return res.json(body);
|
||||
});
|
||||
};
|
||||
// mapping of current used runners for quick loop up based on runner label
|
||||
var label2runner = {};
|
||||
|
||||
var addToRedis = 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");
|
||||
return res.json({status: 200, info: data});
|
||||
});
|
||||
};
|
||||
//
|
||||
var tagPrefix = settings.tagPrefix || 'clwV';
|
||||
|
||||
router.get('/start/:name', function(req, res, next){
|
||||
return lxc.start(req.params.name, function(data){
|
||||
console.log('start', arguments);
|
||||
if(!data){
|
||||
return res.json({status: 500, name: req.params.name, message: data});
|
||||
}else{
|
||||
res.json({});
|
||||
var workers = (function(){
|
||||
// works array constructor. This will hold the works(order by creation) and all
|
||||
// the methods interacting with the workers.
|
||||
|
||||
// base array that will be the workers objects.
|
||||
var workers = [];
|
||||
|
||||
// persistent settings object
|
||||
// .image is the currently used Digital Ocean snap shot ID
|
||||
// .lastSnapShotId is the previous ID used Digital Ocean snap shot
|
||||
// .version is the current worker version
|
||||
// .size is the base Droplet size for worker creation
|
||||
// .min is the minimum amount of workers that should exist
|
||||
// .max is the maximum amount of works that ca exist
|
||||
// .minAvail is the amount of empty workers there should be
|
||||
workers.settings = settings;
|
||||
|
||||
// How many droplets are currently in the process of being created. It takes
|
||||
// about 3 minutes to create a worker.
|
||||
workers.currentCreating = 0;
|
||||
|
||||
workers.create = function(){
|
||||
// manages the creation of a work from first call to all runners seeded
|
||||
|
||||
// dont create more workers then the settings file allows
|
||||
if(workers.currentCreating > workers.settings.max ) return false;
|
||||
workers.currentCreating++;
|
||||
|
||||
doapi.dropletToActive({
|
||||
name: 'clw'+workers.settings.version+'-'+(Math.random()*100).toString().slice(-4),
|
||||
image: workers.settings.image,
|
||||
size: workers.settings.size,
|
||||
onCreate: function(data){
|
||||
doapi.dropletSetTag(tagPrefix+workers.settings.version, data.droplet.id);
|
||||
},
|
||||
onActive: function(worker, args){
|
||||
workers.startRunners({
|
||||
worker: workers.makeWorkerObj(worker),
|
||||
onStart: function(runner, args){
|
||||
workers.push(args.worker);
|
||||
doapi.domianAddRecord({
|
||||
domain: "codeland.us",
|
||||
type: "A",
|
||||
name: "*."+worker.name+".workers",
|
||||
data: worker.publicIP
|
||||
});
|
||||
args.onStart = function(){};
|
||||
},
|
||||
onDone: function(args){
|
||||
console.log("Seeded runners on", worker.name);
|
||||
workers.currentCreating--;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
workers.makeWorkerObj = function(worker){
|
||||
// Create object for each worker.
|
||||
|
||||
worker.networks.v4.forEach(function(value){
|
||||
worker[value.type+'IP'] = value.ip_address;
|
||||
});
|
||||
|
||||
worker.availrunners = [];
|
||||
worker.ip = worker.publicIP;
|
||||
worker.usedrunners = 0;
|
||||
worker.index = workers.length;
|
||||
|
||||
worker.getRunner = function(){
|
||||
if(this.availrunners.length === 0) return false;
|
||||
// console.log('getting runner from ', worker.name, ' avail length ', this.availrunners.length);
|
||||
var runner = this.availrunners.pop();
|
||||
this.usedrunners++;
|
||||
runnerTimeout(runner);
|
||||
|
||||
return runner;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/live/:template/:name', function(req, res, next){
|
||||
return lxc.startEphemeral(req.params.name, req.params.template, function (data) {
|
||||
console.log('live', arguments);
|
||||
return res.json(data);
|
||||
return worker;
|
||||
};
|
||||
|
||||
workers.__workersId = function(argument){
|
||||
// create array of all current worker Digital Ocean ID
|
||||
return workers.map(function(item){
|
||||
return item.id;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
workers.destroy = function(worker){
|
||||
// todo: If worker is passed, check for it in the workers array and
|
||||
// remove it if found.
|
||||
|
||||
var worker = worker || workers.pop();
|
||||
return doapi.dropletDestroy(worker.id, function(body) {
|
||||
console.log('Deleted worker', worker.name);
|
||||
});
|
||||
};
|
||||
|
||||
workers.destroyByTag = function(tag){
|
||||
// Delete works that with
|
||||
|
||||
tag = tag || tagPrefix + workers.settings.version;
|
||||
let currentIDs = workers.__workersId();
|
||||
|
||||
let deleteDroplets = function(droplets){
|
||||
if(droplets.length === 0) return true;
|
||||
let droplet = droplets.pop();
|
||||
if(~currentIDs.indexOf(droplet.id)) return deleteDroplets(droplets);
|
||||
|
||||
doapi.dropletDestroy(droplet.id, function(body){
|
||||
setTimeout(deleteDroplets, 1000, droplets);
|
||||
if(!droplets.length) console.log(`Finished deleting workers tagged ${tag}.`);
|
||||
});
|
||||
}
|
||||
|
||||
doapi.dropletsByTag(tag, function(data){
|
||||
data = JSON.parse(data);
|
||||
console.log(`Deleting ${data['droplets'].length} workers tagged ${tag}. Workers`,
|
||||
data['droplets'].map(function(item){
|
||||
return item.name+' | '+item.id;
|
||||
})
|
||||
);
|
||||
|
||||
deleteDroplets(data['droplets']);
|
||||
});
|
||||
};
|
||||
|
||||
workers.startRunners = function(args){
|
||||
// console.log('starting runners on', args.worker.name, args.worker.ip)
|
||||
|
||||
// dont make runners on out dated workers
|
||||
if(!args.worker || workers.settings.image > args.worker.image.id){
|
||||
console.log(`Blocked outdated worker(${args.worker.image.id}), current image ${workers.settings.image}.`)
|
||||
return ;
|
||||
}
|
||||
|
||||
// percent of used RAM to stop runner creation
|
||||
args.stopPercent = args.stopPercent || 80;
|
||||
args.onStart = args.onStart || function(){};
|
||||
args.onDone = args.onDone || function(){};
|
||||
|
||||
ramPercentUsed(args.worker.ip, function(usedMemPercent){
|
||||
if(usedMemPercent > args.stopPercent ){
|
||||
console.log('using', String(usedMemPercent).trim(),
|
||||
'percent memory, stopping runner creation!', args.worker.availrunners.length,
|
||||
'created on ', args.worker.name
|
||||
);
|
||||
args.onDone(args);
|
||||
return ;
|
||||
}
|
||||
|
||||
var name = 'crunner-'+(Math.random()*100).toString().slice(-4);
|
||||
// console.log('Free ram check passed!')
|
||||
lxc.startEphemeral(name, 'crunner0', args.worker.ip, function(data){
|
||||
if(!data.ip) return setTimeout(workers.startRunners, 0, args);
|
||||
// console.log('started runner on', args.worker.name)
|
||||
|
||||
var runner = {
|
||||
ip: data.ip,
|
||||
name: name,
|
||||
worker: args.worker,
|
||||
label: args.worker.name + ':' + name
|
||||
};
|
||||
args.onStart(runner, args);
|
||||
|
||||
args.worker.availrunners.push(runner);
|
||||
|
||||
setTimeout(workers.startRunners, 0, args);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
workers.checkForZombies = function(){
|
||||
// check to make sure all works are used or usable.
|
||||
|
||||
let zombies = 0;
|
||||
|
||||
for(let worker of workers){
|
||||
console.log(`Checking if ${worker.name} is a zombie worker.`);
|
||||
// if a runner has no available runners and no used runners, its a
|
||||
// zombie. This should happen when a newer image ID has been added
|
||||
// and old workers slowly lose there usefulness.
|
||||
if(worker.availrunners.length === 0 && worker.usedrunners === 0){
|
||||
workers.splice(workers.indexOf(worker), 1);
|
||||
console.log(`Zombie! Worker ${worker.name}, destroying.`);
|
||||
workers.destroy(worker);
|
||||
zombies++;
|
||||
}
|
||||
}
|
||||
|
||||
return zombies;
|
||||
};
|
||||
|
||||
workers.checkBalance = function(){
|
||||
console.log(`Checking balance.`);
|
||||
|
||||
workers.checkForZombies();
|
||||
|
||||
// if there are workers being created, stop scale up and down check
|
||||
if(workers.currentCreating+workers.length < workers.settings.min) null;
|
||||
else if(workers.currentCreating)
|
||||
return console.log(`Killing balance, workers are being created.`);
|
||||
|
||||
// hold amount of workers with no used runners
|
||||
var lastMinAval = 0;
|
||||
|
||||
// check to make sure the `workers.settings.minAvail` have free runners
|
||||
for(let worker of workers.slice(-workers.settings.minAvail)){
|
||||
if(worker.usedrunners === 0){
|
||||
lastMinAval++;
|
||||
}else{
|
||||
// no need to keep counting, workers need to be created
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(lastMinAval > workers.settings.minAvail){
|
||||
// Remove workers if there are more then the settings states
|
||||
console.log(
|
||||
`Last ${workers.settings.minAvail} workers not used, killing last worker`,
|
||||
'lastMinAval:', lastMinAval,
|
||||
'minAvail:', workers.settings.minAvail,
|
||||
'workers:', workers.length
|
||||
);
|
||||
|
||||
return workers.destroy();
|
||||
|
||||
} else if(lastMinAval < workers.settings.minAvail){
|
||||
// creates workers if the settings file demands it
|
||||
console.log(
|
||||
'last 3 workers have no free runners, starting worker',
|
||||
'lastMinAval:', lastMinAval,
|
||||
'minAvail:', workers.settings.minAvail,
|
||||
'workers:', workers.length
|
||||
);
|
||||
|
||||
return workers.create();
|
||||
}
|
||||
|
||||
};
|
||||
workers.settingsSave = function(){
|
||||
// save the live settings file to disk
|
||||
|
||||
jsonfile.writeFile('./workers.json', workers.settings, {spaces: 2}, function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
workers.add = function(newWorkers){
|
||||
newWorkers.forEach(function(worker){
|
||||
workers.push(worker);
|
||||
});
|
||||
};
|
||||
|
||||
// make sure Digital Ocean has a tag for the current worker version
|
||||
doapi.tagCreate(tagPrefix+workers.settings.version);
|
||||
|
||||
return workers;
|
||||
|
||||
})();
|
||||
|
||||
var ramPercentUsed = function(ip, callback){
|
||||
// checks the percent of ram used on a worker.
|
||||
|
||||
return lxc.exec(
|
||||
"python3 -c \"a=`head /proc/meminfo|grep MemAvail|grep -Po '\\d+'`;t=`head /proc/meminfo|grep MemTotal|grep -Po '\\d+'`;print(round(((t-a)/t)*100, 2))\"",
|
||||
ip,
|
||||
callback
|
||||
);
|
||||
};
|
||||
|
||||
var runnerTimeout = function(runner, time){
|
||||
time = time || 60000; // 1 minutes
|
||||
|
||||
if(runner.hasOwnProperty('timeout')){
|
||||
clearTimeout(runner.timeout);
|
||||
}
|
||||
|
||||
return runner.timeout = setTimeout(runnerFree, time, runner);
|
||||
};
|
||||
|
||||
var runnerFree = function(runner){
|
||||
lxc.stop(runner.name, runner.worker.ip);
|
||||
runner.worker.usedrunners--;
|
||||
if(runner.hasOwnProperty('timeout')){
|
||||
clearTimeout(runner.timeout);
|
||||
}
|
||||
delete label2runner[runner.label];
|
||||
|
||||
console.log(`Runner freed ${runner.label}.`, runner.worker);
|
||||
workers.startRunners({worker: runner.worker});
|
||||
};
|
||||
|
||||
var getAvailrunner = function(runner){
|
||||
for(let worker of workers){
|
||||
if(worker.availrunners.length === 0) continue;
|
||||
if(runner && runner.worker.index <= worker.index) break;
|
||||
if(runner) runnerFree(runner);
|
||||
|
||||
return worker.getRunner();
|
||||
}
|
||||
|
||||
if(runner) return runner;
|
||||
};
|
||||
|
||||
var run = function(req, res, runner, count){
|
||||
count = count || 0;
|
||||
console.log(`Runner starting attempt ${count}.`);
|
||||
|
||||
if(!runner){
|
||||
console.log(`No runner available!`);
|
||||
res.status(503);
|
||||
return res.json({error: 'No runners, try again soon.'});
|
||||
}
|
||||
|
||||
if(count > 2){
|
||||
console.log(`Runner attempt failed, to many requests!`);
|
||||
return res.status(400).json({error: 'Runner restarted to many times'});
|
||||
}
|
||||
|
||||
var httpOptions = {
|
||||
url: 'http://' + runner.worker.ip,
|
||||
headers: {
|
||||
Host: runner.name
|
||||
},
|
||||
body: JSON.stringify({
|
||||
code: req.body.code
|
||||
})
|
||||
};
|
||||
|
||||
return request.post(httpOptions, function(error, response, body){
|
||||
// console.log('runner response:', arguments)
|
||||
if(error || response.statusCode !== 200) return run(req, res, getAvailrunner(), ++count);
|
||||
body = JSON.parse(body);
|
||||
|
||||
if(req.query.once){
|
||||
res.json(body);
|
||||
return runnerFree(runner, 0);
|
||||
}
|
||||
|
||||
label2runner[runner.label] = runner;
|
||||
body['ip'] = runner.label;
|
||||
body['rname'] = runner.name;
|
||||
body['wname'] = runner.worker.name;
|
||||
res.json(body);
|
||||
|
||||
runnerTimeout(runner);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
console.log('========STARTING===========')
|
||||
setInterval(workers.checkBalance, 15000);
|
||||
workers.destroyByTag();
|
||||
|
||||
|
||||
router.get('/stop/:name', function(req, res, next){
|
||||
return lxc.stop(req.params.name, function(data){
|
||||
@ -58,66 +383,102 @@ router.get('/stop/:name', function(req, res, next){
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/clone/:template/:name', function(req, res, next){
|
||||
return lxc.clone(req.params.name, req.params.template, function(data){
|
||||
console.log('clone', arguments);
|
||||
if( data.match(/Created container/) ){
|
||||
return res.json({status: 200});
|
||||
}else{
|
||||
return res.json({status: 500, message: data});
|
||||
}
|
||||
});
|
||||
router.get('/destroyByTag', function(req, res, next) {
|
||||
workers.destroyByTag();
|
||||
res.send('?');
|
||||
});
|
||||
|
||||
router.get('/destroy/:name', function(req, res, next){
|
||||
return lxc.destroy(req.params.name, function(data){
|
||||
console.log('destroy', arguments);
|
||||
if(data){
|
||||
return res.json({status: 500, message: data});
|
||||
}else{
|
||||
return res.json({status: 200});
|
||||
}
|
||||
});
|
||||
});
|
||||
router.post('/updateID', function(req, res, next){
|
||||
var newWorkers = {
|
||||
workers: [],
|
||||
image: req.query.image,
|
||||
target: req.query.target || workers.length,
|
||||
size: req.query.size || workers.settings.size,
|
||||
version: workers.settings.version+1,
|
||||
min: req.query.min || workers.settings,
|
||||
minAvail: req.query.minAvail || workers.settings
|
||||
};
|
||||
|
||||
router.get('/info/:name', function(req, res, next){
|
||||
return lxc.info(req.params.name, function(data){
|
||||
return res.json(data);
|
||||
});
|
||||
});
|
||||
doapi.tagCreate(tagPrefix+newWorkers.version);
|
||||
workers.destroyByTag(tagPrefix+newWorkers.version);
|
||||
|
||||
router.get('/list', function(req, res, next) {
|
||||
return lxc.list(function(data){
|
||||
return res.json(data);
|
||||
});
|
||||
});
|
||||
for(var i=0; i<newWorkers.target; i++){
|
||||
|
||||
router.post('/run/:ip?', function doRun(req, res, next){
|
||||
// check if server is
|
||||
doapi.dropletToActive({
|
||||
name: 'clw'+newWorkers.version+'-'+(Math.random()*100).toString().slice(-4),
|
||||
newWorkers: newWorkers,
|
||||
image: newWorkers.image,
|
||||
size: newWorkers.size,
|
||||
onCreate: function(data, args){
|
||||
doapi.dropletSetTag(tagPrefix+args.newWorkers.version, data.droplet.id);
|
||||
},
|
||||
onActive: function(droplet, args){
|
||||
workers.startRunners({
|
||||
worker: workers.makeWorkerObj(droplet),
|
||||
newWorkers: args.newWorkers,
|
||||
onStart: function(runner, args){
|
||||
args.newWorkers.workers.push(args.worker);
|
||||
console.log('onStart', args.worker.name);
|
||||
args.onStart = function(){};
|
||||
},
|
||||
onDone: function(args){
|
||||
console.log('new workers:', args.newWorkers.workers.length);
|
||||
doapi.domianAddRecord({
|
||||
domain: "codeland.us",
|
||||
type: "A",
|
||||
name: "*."+args.worker.name+".workers",
|
||||
data: args.worker.publicIP
|
||||
});
|
||||
|
||||
if(args.newWorkers.workers.length >= args.newWorkers.target){
|
||||
console.log('upgrade complete!')
|
||||
workers.settings.image = args.newWorkers.image;
|
||||
workers.settings.size = args.newWorkers.size;
|
||||
workers.settings.min = args.newWorkers.min;
|
||||
workers.settings.minAvail = args.newWorkers.minAvail;
|
||||
|
||||
return lxc.list(function(data){
|
||||
if(!req.params.ip) data = [];
|
||||
var ip = '10.0.'+ req.params.ip;
|
||||
var found = false;
|
||||
workers.forEach(function(worker){
|
||||
worker.availrunners.forEach(function(runner){
|
||||
lxc.stop(runner.name, runner.worker.ip);
|
||||
});
|
||||
worker.availrunners = [];
|
||||
});
|
||||
|
||||
for(var idx=data.length; idx--;){
|
||||
if( data[idx]['ipv4'] === ip ){
|
||||
found = true;
|
||||
break;
|
||||
workers.add(args.newWorkers.workers);
|
||||
workers.settingsSave();
|
||||
workers.checkBalance();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
res.json({status: "maybe?"});
|
||||
});
|
||||
|
||||
if(found){
|
||||
return runner(req, res, ip)
|
||||
}else{
|
||||
var name = 'u1-'+(Math.random()*100).toString().replace('.','');
|
||||
return lxc.startEphemeral(name, 'u1', function(data){
|
||||
return runner(req, res, data.ip);
|
||||
});
|
||||
}
|
||||
});
|
||||
router.get('/liststuff', function(req, res, next){
|
||||
var obj = util.inspect(workers, {depth: 4});
|
||||
res.send(`
|
||||
<h1>Workers</h1>
|
||||
<pre>${obj}</pre>
|
||||
<h1>label2runner</h1>
|
||||
<pre>${util.inspect(label2runner)}</pre>
|
||||
<h1>DO calls</h1>
|
||||
${doapi.calls}
|
||||
`);
|
||||
});
|
||||
|
||||
router.get('/ping/:runner', function(req, res, next){
|
||||
var runner = label2runner[req.params.runner];
|
||||
runnerTimeout(runner);
|
||||
res.json({res:''});
|
||||
});
|
||||
|
||||
router.post('/run/:runner?', function (req, res, next){
|
||||
console.log(`Request runner route!`);
|
||||
var runner = getAvailrunner(label2runner[req.params.runner]);
|
||||
return run(req, res, runner);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
9
routes/workers.json
Normal file
9
routes/workers.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"image":"25092187",
|
||||
"version":10,
|
||||
"lastSnapShotId":"23505298",
|
||||
"size":"512mb",
|
||||
"max":100,
|
||||
"min":3,
|
||||
"minAvail":3
|
||||
}
|
3
rx.sh
3
rx.sh
@ -1,3 +0,0 @@
|
||||
sudo cgm create all virt
|
||||
sudo cgm chown all virt $(id -u virt) $(id -g virt)
|
||||
|
13
stuff.md
13
stuff.md
@ -1,5 +1,14 @@
|
||||
# Random things not to lose
|
||||
|
||||
## 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
|
||||
|
||||
```crontab
|
||||
@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/`
|
||||
```
|
||||
|
||||
## LXC permission issue
|
||||
|
||||
```bash
|
||||
sudo cgm create all virt
|
||||
sudo cgm chown all virt $(id -u virt) $(id -g virt)
|
||||
```
|
||||
|
61
testAPI.js
Normal file
61
testAPI.js
Normal file
@ -0,0 +1,61 @@
|
||||
const request = require('request');
|
||||
|
||||
var callRunner = (function(){
|
||||
let started = 0;
|
||||
let completed = 0;
|
||||
let errors = 0;
|
||||
let noRunner = 0;
|
||||
|
||||
let func = function(code, callback) {
|
||||
// code | `string` block of code to send runner or
|
||||
// `number` sleep timeout in seconds
|
||||
let sleepTime = 0;
|
||||
let id = started++;
|
||||
callback = callback || function(){};
|
||||
|
||||
if(/^\+?(0|[1-9]\d*)$/.test(code)){
|
||||
sleepTime = code;
|
||||
code = null;
|
||||
}
|
||||
console.log(id, ': Running...');
|
||||
|
||||
|
||||
let httpOptions = {
|
||||
url: 'http://codeland.bytedev.co:2000/api/run?once=true',
|
||||
form: {
|
||||
code: code || `python3 -c "
|
||||
from time import sleep
|
||||
sleep(${sleepTime})
|
||||
"`,
|
||||
}
|
||||
};
|
||||
|
||||
return request.post(httpOptions, function(error, response, body){
|
||||
completed++;
|
||||
let res = ``;
|
||||
if(response.statusCode == 503){
|
||||
noRunner++;
|
||||
}else if(error || response.statusCode !== 200){
|
||||
errors++;
|
||||
body = JSON.parse(body);
|
||||
res = (Buffer.from(body.res, 'base64').toString('ascii'));
|
||||
}
|
||||
console.log(`${id} with results ${res}. Errors ${errors}. No runner ${noRunner}. Completed ${completed}`);
|
||||
|
||||
callback()
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
return func;
|
||||
})();
|
||||
|
||||
|
||||
let __do = function(till){
|
||||
if(!till) return ;
|
||||
|
||||
callRunner(String(Math.random())[3]);
|
||||
setTimeout(__do, 1500, --till);
|
||||
};
|
||||
|
||||
__do(30)
|
Reference in New Issue
Block a user