Compare commits
16 Commits
xo-server/
...
xo-server/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07d91b8f50 | ||
|
|
5645921a8e | ||
|
|
9c17ac1c33 | ||
|
|
a80968aaa7 | ||
|
|
2589a15e0a | ||
|
|
950efde3b8 | ||
|
|
de8d5e4489 | ||
|
|
d6eefa5185 | ||
|
|
5ad0cffbb3 | ||
|
|
89bd00c65e | ||
|
|
b7e7a0df94 | ||
|
|
e3f02fc4d6 | ||
|
|
81bece9dc4 | ||
|
|
db4b05e9d2 | ||
|
|
0b9029c7b5 | ||
|
|
7fd9a65ce5 |
7
bin/xo-server
Executable file
7
bin/xo-server
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
//====================================================================
|
||||
|
||||
require('exec-promise')(require('../'));
|
||||
6
index.js
Normal file
6
index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
//====================================================================
|
||||
|
||||
require('coffee-script/register');
|
||||
module.exports = require('./src/main');
|
||||
537
npm-shrinkwrap.json
generated
537
npm-shrinkwrap.json
generated
@@ -1,537 +0,0 @@
|
||||
{
|
||||
"name": "XO-Server",
|
||||
"version": "3.3.1",
|
||||
"dependencies": {
|
||||
"backoff": {
|
||||
"version": "2.3.0",
|
||||
"from": "backoff@~2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/backoff/-/backoff-2.3.0.tgz"
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "1.2.4",
|
||||
"from": "bluebird@^1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-1.2.4.tgz"
|
||||
},
|
||||
"coffee-script": {
|
||||
"version": "1.7.1",
|
||||
"from": "coffee-script@~1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz",
|
||||
"dependencies": {
|
||||
"mkdirp": {
|
||||
"version": "0.3.5",
|
||||
"from": "mkdirp@~0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"connect": {
|
||||
"version": "2.17.1",
|
||||
"from": "connect@^2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/connect/-/connect-2.17.1.tgz",
|
||||
"dependencies": {
|
||||
"basic-auth-connect": {
|
||||
"version": "1.0.0",
|
||||
"from": "basic-auth-connect@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz"
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.2.0",
|
||||
"from": "body-parser@1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"raw-body": {
|
||||
"version": "1.1.4",
|
||||
"from": "raw-body@1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.4.tgz",
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "0.3.0",
|
||||
"from": "bytes@~0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-0.3.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "1.0.0",
|
||||
"from": "bytes@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz"
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.1.2",
|
||||
"from": "cookie@0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz"
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.1.0",
|
||||
"from": "cookie-parser@1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.1.0.tgz"
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.3",
|
||||
"from": "cookie-signature@1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz"
|
||||
},
|
||||
"compression": {
|
||||
"version": "1.0.2",
|
||||
"from": "compression@1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.0.2.tgz",
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "0.3.0",
|
||||
"from": "bytes@0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-0.3.0.tgz"
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.4.3",
|
||||
"from": "negotiator@0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.3.tgz"
|
||||
},
|
||||
"compressible": {
|
||||
"version": "1.0.1",
|
||||
"from": "compressible@1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"connect-timeout": {
|
||||
"version": "1.1.0",
|
||||
"from": "connect-timeout@1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/connect-timeout/-/connect-timeout-1.1.0.tgz"
|
||||
},
|
||||
"csurf": {
|
||||
"version": "1.2.0",
|
||||
"from": "csurf@1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/csurf/-/csurf-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"uid2": {
|
||||
"version": "0.0.3",
|
||||
"from": "uid2@~0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz"
|
||||
},
|
||||
"scmp": {
|
||||
"version": "0.0.3",
|
||||
"from": "scmp@~0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/scmp/-/scmp-0.0.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"errorhandler": {
|
||||
"version": "1.0.1",
|
||||
"from": "errorhandler@1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.0.1.tgz"
|
||||
},
|
||||
"express-session": {
|
||||
"version": "1.2.0",
|
||||
"from": "express-session@1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"utils-merge": {
|
||||
"version": "1.0.0",
|
||||
"from": "utils-merge@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz"
|
||||
},
|
||||
"uid2": {
|
||||
"version": "0.0.3",
|
||||
"from": "uid2@~0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz"
|
||||
},
|
||||
"buffer-crc32": {
|
||||
"version": "0.2.1",
|
||||
"from": "buffer-crc32@0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.2.2",
|
||||
"from": "fresh@0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz"
|
||||
},
|
||||
"method-override": {
|
||||
"version": "1.0.1",
|
||||
"from": "method-override@1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/method-override/-/method-override-1.0.1.tgz",
|
||||
"dependencies": {
|
||||
"methods": {
|
||||
"version": "1.0.0",
|
||||
"from": "methods@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"morgan": {
|
||||
"version": "1.1.1",
|
||||
"from": "morgan@1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.1.1.tgz"
|
||||
},
|
||||
"on-headers": {
|
||||
"version": "0.0.0",
|
||||
"from": "on-headers@0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-0.0.0.tgz"
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.0.1",
|
||||
"from": "parseurl@1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz"
|
||||
},
|
||||
"qs": {
|
||||
"version": "0.6.6",
|
||||
"from": "qs@0.6.6",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz"
|
||||
},
|
||||
"response-time": {
|
||||
"version": "1.0.0",
|
||||
"from": "response-time@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/response-time/-/response-time-1.0.0.tgz"
|
||||
},
|
||||
"serve-favicon": {
|
||||
"version": "2.0.0",
|
||||
"from": "serve-favicon@2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.0.0.tgz"
|
||||
},
|
||||
"serve-index": {
|
||||
"version": "1.0.3",
|
||||
"from": "serve-index@1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"batch": {
|
||||
"version": "0.5.0",
|
||||
"from": "batch@0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.5.0.tgz"
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.4.3",
|
||||
"from": "negotiator@0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.1.0",
|
||||
"from": "serve-static@1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"send": {
|
||||
"version": "0.3.0",
|
||||
"from": "send@0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz",
|
||||
"dependencies": {
|
||||
"buffer-crc32": {
|
||||
"version": "0.2.1",
|
||||
"from": "buffer-crc32@0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz"
|
||||
},
|
||||
"debug": {
|
||||
"version": "0.8.0",
|
||||
"from": "debug@0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz"
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.2.11",
|
||||
"from": "mime@1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.0.0",
|
||||
"from": "range-parser@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.2.0",
|
||||
"from": "type-is@1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"mime": {
|
||||
"version": "1.2.11",
|
||||
"from": "mime@1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vhost": {
|
||||
"version": "1.0.0",
|
||||
"from": "vhost@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vhost/-/vhost-1.0.0.tgz"
|
||||
},
|
||||
"pause": {
|
||||
"version": "0.0.1",
|
||||
"from": "pause@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz"
|
||||
},
|
||||
"debug": {
|
||||
"version": "0.8.1",
|
||||
"from": "debug@*",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
|
||||
},
|
||||
"multiparty": {
|
||||
"version": "2.2.0",
|
||||
"from": "multiparty@2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz",
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.1.13-1",
|
||||
"from": "readable-stream@~1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz",
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.1",
|
||||
"from": "core-util-is@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"from": "isarray@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.25-1",
|
||||
"from": "string_decoder@~0.10.x",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"stream-counter": {
|
||||
"version": "0.2.0",
|
||||
"from": "stream-counter@~0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"extendable": {
|
||||
"version": "0.0.6",
|
||||
"from": "extendable@~0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/extendable/-/extendable-0.0.6.tgz"
|
||||
},
|
||||
"fibers": {
|
||||
"version": "1.0.1",
|
||||
"from": "fibers@~1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fibers/-/fibers-1.0.1.tgz"
|
||||
},
|
||||
"hashy": {
|
||||
"version": "0.3.1",
|
||||
"from": "hashy@~0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/hashy/-/hashy-0.3.1.tgz",
|
||||
"dependencies": {
|
||||
"bcrypt": {
|
||||
"version": "0.7.8",
|
||||
"from": "bcrypt@~0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.0.0",
|
||||
"from": "bindings@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "1.2.2",
|
||||
"from": "yargs@^1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.2.tgz",
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"from": "minimist@~0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"hiredis": {
|
||||
"version": "0.1.16",
|
||||
"from": "hiredis@~0.1.16",
|
||||
"resolved": "https://registry.npmjs.org/hiredis/-/hiredis-0.1.16.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.0",
|
||||
"from": "bindings@*",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.0.2",
|
||||
"from": "js-yaml@~3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.2.tgz",
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "0.1.15",
|
||||
"from": "argparse@~ 0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz",
|
||||
"dependencies": {
|
||||
"underscore": {
|
||||
"version": "1.4.4",
|
||||
"from": "underscore@~1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz"
|
||||
},
|
||||
"underscore.string": {
|
||||
"version": "2.3.3",
|
||||
"from": "underscore.string@~2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"esprima": {
|
||||
"version": "1.0.4",
|
||||
"from": "esprima@~ 1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nconf": {
|
||||
"version": "0.6.9",
|
||||
"from": "nconf@~0.6.9",
|
||||
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.6.9.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.2.9",
|
||||
"from": "async@0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz"
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.2.0",
|
||||
"from": "ini@1.x.x",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.2.0.tgz"
|
||||
},
|
||||
"optimist": {
|
||||
"version": "0.6.0",
|
||||
"from": "optimist@0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz",
|
||||
"dependencies": {
|
||||
"wordwrap": {
|
||||
"version": "0.0.2",
|
||||
"from": "wordwrap@~0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"from": "minimist@~0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"version": "0.10.2",
|
||||
"from": "redis@~0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-0.10.2.tgz"
|
||||
},
|
||||
"require-tree": {
|
||||
"version": "0.3.3",
|
||||
"from": "require-tree@~0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/require-tree/-/require-tree-0.3.3.tgz"
|
||||
},
|
||||
"schema-inspector": {
|
||||
"version": "1.4.2",
|
||||
"from": "schema-inspector@^1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/schema-inspector/-/schema-inspector-1.4.2.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
"from": "async@*",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"then-redis": {
|
||||
"version": "0.3.12",
|
||||
"from": "then-redis@~0.3.12",
|
||||
"resolved": "https://registry.npmjs.org/then-redis/-/then-redis-0.3.12.tgz",
|
||||
"dependencies": {
|
||||
"rsvp": {
|
||||
"version": "3.0.6",
|
||||
"from": "rsvp@~3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.0.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.6.0",
|
||||
"from": "underscore@~1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
|
||||
},
|
||||
"ws": {
|
||||
"version": "0.4.31",
|
||||
"from": "ws@~0.4.31",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-0.4.31.tgz",
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "0.6.1",
|
||||
"from": "commander@~0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "0.3.2",
|
||||
"from": "nan@~0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-0.3.2.tgz"
|
||||
},
|
||||
"tinycolor": {
|
||||
"version": "0.0.1",
|
||||
"from": "tinycolor@0.x",
|
||||
"resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz"
|
||||
},
|
||||
"options": {
|
||||
"version": "0.0.5",
|
||||
"from": "options@>=0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/options/-/options-0.0.5.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.3",
|
||||
"from": "xml2js@~0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.3.tgz",
|
||||
"dependencies": {
|
||||
"sax": {
|
||||
"version": "0.6.0",
|
||||
"from": "sax@0.6.x",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-0.6.0.tgz"
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "2.2.1",
|
||||
"from": "xmlbuilder@>=1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.2.1.tgz",
|
||||
"dependencies": {
|
||||
"lodash-node": {
|
||||
"version": "2.4.1",
|
||||
"from": "lodash-node@~2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"xmlrpc": {
|
||||
"version": "1.2.0",
|
||||
"from": "xmlrpc@~1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlrpc/-/xmlrpc-1.2.0.tgz",
|
||||
"dependencies": {
|
||||
"sax": {
|
||||
"version": "0.4.3",
|
||||
"from": "sax@0.4.x",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-0.4.3.tgz"
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "0.4.2",
|
||||
"from": "xmlbuilder@0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.2.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
package.json
63
package.json
@@ -1,50 +1,59 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr",
|
||||
"url": "http://vates.fr/"
|
||||
},
|
||||
"name": "XO-Server",
|
||||
"version": "3.4.0",
|
||||
"name": "xo-server",
|
||||
"version": "3.5.0-alpha0",
|
||||
"license": "AGPL3",
|
||||
"description": "Server part of Xen-Orchestra",
|
||||
"keywords": [
|
||||
"xen",
|
||||
"orchestra",
|
||||
"xen-orchestra",
|
||||
"server"
|
||||
],
|
||||
"homepage": "http://github.com/vatesfr/xo-server/",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vatesfr/xo-server/issues"
|
||||
},
|
||||
"author": "Julien Fontanet <julien.fontanet@vates.fr>",
|
||||
"preferGlobal": true,
|
||||
"directories": {
|
||||
"bin": "bin"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/vatesfr/xo-server.git"
|
||||
},
|
||||
"main": "src/main.coffee",
|
||||
"dependencies": {
|
||||
"backoff": "~2.3.0",
|
||||
"bluebird": "^1.2.4",
|
||||
"backoff": "~2.4.0",
|
||||
"bluebird": "^2.2.2",
|
||||
"coffee-script": "~1.7.1",
|
||||
"connect": "^2.17.1",
|
||||
"connect": "^3.1.0",
|
||||
"event-to-promise": "^0.3.0",
|
||||
"exec-promise": "^0.3.0",
|
||||
"extendable": "~0.0.6",
|
||||
"fibers": "~1.0.1",
|
||||
"hashy": "~0.3.1",
|
||||
"hiredis": "~0.1.16",
|
||||
"js-yaml": "~3.0.2",
|
||||
"hashy": "~0.3.6",
|
||||
"hiredis": "~0.1.17",
|
||||
"http-server-plus": "^0.2.3",
|
||||
"js-yaml": "~3.1.0",
|
||||
"nconf": "~0.6.9",
|
||||
"redis": "~0.10.2",
|
||||
"redis": "~0.11.0",
|
||||
"require-tree": "~0.3.3",
|
||||
"schema-inspector": "^1.4.2",
|
||||
"schema-inspector": "^1.4.5",
|
||||
"serve-static": "^1.4.0",
|
||||
"then-redis": "~0.3.12",
|
||||
"underscore": "~1.6.0",
|
||||
"ws": "~0.4.31",
|
||||
"xml2js": "~0.4.3",
|
||||
"xml2js": "~0.4.4",
|
||||
"xmlrpc": "~1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "~1.9.1",
|
||||
"glob": "~4.0.0",
|
||||
"mocha": "^1.19.0",
|
||||
"node-inspector": "^0.7.3",
|
||||
"sinon": "^1.10.0"
|
||||
},
|
||||
"description": "XO-Server is part of Xen-Orchestra, a web interface for XenServer or XAPI enabled hosts.",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vatesfr/xo-server/issues"
|
||||
"glob": "~4.0.4",
|
||||
"mocha": "^1.21.0",
|
||||
"node-inspector": "^0.7.4",
|
||||
"sinon": "^1.10.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./run-tests"
|
||||
},
|
||||
"license": "AGPL3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ class $MappedCollection extends $EventEmitter
|
||||
return if $_.isEmpty items
|
||||
|
||||
# An update is similar to an exit followed by an enter.
|
||||
@_emitEvent 'exit', items unless areNew
|
||||
@_removeItems items unless areNew
|
||||
|
||||
$each items, (item) =>
|
||||
return unless @_runHook 'beforeUpdate', item
|
||||
@@ -426,15 +426,14 @@ class $MappedCollection extends $EventEmitter
|
||||
updateValue item, 'data', @_rules[ruleName].data
|
||||
updateValue item, 'val', @_rules[ruleName].val
|
||||
|
||||
return unless @_runHook 'beforeSave', item
|
||||
|
||||
# Registers the new item.
|
||||
@_byKey[item.key] = item
|
||||
unless @_runHook 'beforeSave', item
|
||||
# FIXME: should not be removed, only not saved.
|
||||
delete @_byKey[item.key]
|
||||
|
||||
# Really inserts the items and trigger events.
|
||||
$each items, (item) => @_byKey[item.key] = item
|
||||
@_emitEvent 'enter', items
|
||||
|
||||
# TODO: checks for loops.
|
||||
|
||||
#=====================================================================
|
||||
|
||||
module.exports = {$MappedCollection}
|
||||
|
||||
41
src/api.js
41
src/api.js
@@ -23,6 +23,12 @@ function $deprecated(fn)
|
||||
};
|
||||
}
|
||||
|
||||
var wrap = function (val) {
|
||||
return function () {
|
||||
return val;
|
||||
};
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: Helper functions that could be written:
|
||||
@@ -132,6 +138,11 @@ Api.prototype.exec = function (session, request) {
|
||||
throw Api.err.INVALID_METHOD;
|
||||
}
|
||||
|
||||
if ('permission' in method)
|
||||
{
|
||||
helpers.checkPermission.call(ctx, method.permission)
|
||||
}
|
||||
|
||||
if (method.params)
|
||||
{
|
||||
helpers.getParams.call(ctx, method.params);
|
||||
@@ -262,10 +273,7 @@ var $register = function (path, fn, params) {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap this value in a function.
|
||||
current[path[n]] = function () {
|
||||
return fn;
|
||||
};
|
||||
current[path[n]] = wrap(fn);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -273,7 +281,7 @@ Api.fn = $requireTree('./api');
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
$register('api.getVersion', '0.1');
|
||||
$register('system.getVersion', wrap('0.1'));
|
||||
|
||||
$register('xo.getAllObjects', function () {
|
||||
return this.getObjects();
|
||||
@@ -290,7 +298,11 @@ $register('xo.getAllObjects', function () {
|
||||
path[n] = key;
|
||||
if ($_.isFunction(content))
|
||||
{
|
||||
methods[path.join('.')] = content;
|
||||
methods[path.join('.')] = {
|
||||
description: content.description,
|
||||
params: content.params || {},
|
||||
permission: content.permission,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -300,25 +312,26 @@ $register('xo.getAllObjects', function () {
|
||||
path.pop();
|
||||
})(Api.fn, []);
|
||||
|
||||
$register('system.listMethods', $_.keys(methods));
|
||||
|
||||
$register('system.listMethods', wrap($_.keys(methods)));
|
||||
$register('system.methodSignature', function (params) {
|
||||
var method = methods[params.name];
|
||||
|
||||
if (!method)
|
||||
{
|
||||
throw Api.err.NO_SUCH_OBJECT;
|
||||
this.throw('NO_SUCH_OBJECT');
|
||||
}
|
||||
|
||||
return {
|
||||
name: params.name,
|
||||
description: method.description || null,
|
||||
params: method.params || null,
|
||||
};
|
||||
// XML-RPC can have multiple signatures per method.
|
||||
return [
|
||||
// XML-RPC requires the method name.
|
||||
$_.extend({name: name}, method)
|
||||
];
|
||||
}, {
|
||||
name: {
|
||||
description: 'method to describe',
|
||||
type: 'string',
|
||||
},
|
||||
});
|
||||
|
||||
$register('system.getMethodsInfo', wrap(methods));
|
||||
})();
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#=====================================================================
|
||||
|
||||
exports.set = (params) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
host = @getObject params.id
|
||||
catch
|
||||
@@ -22,16 +19,19 @@ exports.set = (params) ->
|
||||
|
||||
$wait xapi.call "host.set_#{field}", host.ref, params[param]
|
||||
|
||||
return
|
||||
exports.set.params = {
|
||||
id: { type: 'string' }
|
||||
|
||||
name_label: { type: 'string', optional: true }
|
||||
|
||||
name_description: { type: 'string', optional: true }
|
||||
|
||||
enabled: { type: 'boolean', optional: true }
|
||||
}
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params =
|
||||
id: type: 'string'
|
||||
name_label:
|
||||
type: 'string'
|
||||
optional: true
|
||||
name_description:
|
||||
type: 'string'
|
||||
optional: true
|
||||
enabled:
|
||||
type: 'boolean'
|
||||
optional: true
|
||||
|
||||
exports.restart = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
@@ -47,13 +47,12 @@ exports.restart = ({id}) ->
|
||||
$wait xapi.call 'host.reboot', host.ref
|
||||
|
||||
return true
|
||||
exports.restart.permission = 'admin'
|
||||
exports.restart.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.restart_agent = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
host = @getObject id
|
||||
catch
|
||||
@@ -64,13 +63,12 @@ exports.restart_agent = ({id}) ->
|
||||
$wait xapi.call 'host.restart_agent', host.ref
|
||||
|
||||
return true
|
||||
exports.restart_agent.permission = 'admin'
|
||||
exports.restart_agent.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.stop = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
host = @getObject id
|
||||
catch
|
||||
@@ -82,13 +80,12 @@ exports.stop = ({id}) ->
|
||||
$wait xapi.call 'host.shutdown', host.ref
|
||||
|
||||
return true
|
||||
exports.stop.permission = 'admin'
|
||||
exports.stop.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.detach = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
host = @getObject id
|
||||
catch
|
||||
@@ -99,6 +96,7 @@ exports.detach = ({id}) ->
|
||||
$wait xapi.call 'pool.eject', host.ref
|
||||
|
||||
return true
|
||||
exports.detach.permission = 'admin'
|
||||
exports.detach.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
@@ -2,16 +2,7 @@
|
||||
|
||||
#=====================================================================
|
||||
|
||||
exports.delete = ->
|
||||
{
|
||||
id
|
||||
} = @getParams {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
exports.delete = ({id}) ->
|
||||
try
|
||||
message = @getObject id
|
||||
catch
|
||||
@@ -21,4 +12,8 @@ exports.delete = ->
|
||||
|
||||
$wait xapi.call 'message.destroy', message.ref
|
||||
|
||||
return true
|
||||
return true
|
||||
exports.delete.permission = 'admin'
|
||||
exports.delete.params =
|
||||
id:
|
||||
type: 'string'
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
#=====================================================================
|
||||
|
||||
exports.set = ->
|
||||
params = @getParams {
|
||||
id: { type: 'string' }
|
||||
|
||||
name_label: { type: 'string', optional: true }
|
||||
|
||||
name_description: { type: 'string', optional: true }
|
||||
}
|
||||
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
pool = @getObject params.id
|
||||
catch
|
||||
@@ -29,4 +18,14 @@ exports.set = ->
|
||||
|
||||
$wait xapi.call "pool.set_#{field}", pool.ref, params[param]
|
||||
|
||||
return
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params =
|
||||
id:
|
||||
type: 'string'
|
||||
name_label:
|
||||
type: 'string'
|
||||
optional: true
|
||||
name_description:
|
||||
type: 'string'
|
||||
optional: true
|
||||
|
||||
@@ -6,17 +6,7 @@
|
||||
# Could we use tokens instead?
|
||||
|
||||
# Adds a new server.
|
||||
exports.add = ->
|
||||
{host, username, password} = @getParams {
|
||||
host: { type: 'string' }
|
||||
username: { type: 'string' }
|
||||
password: { type: 'string' }
|
||||
}
|
||||
|
||||
# Current user must be administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Adds the server.
|
||||
exports.add = ({host, username, password}) ->
|
||||
server = $wait @servers.add {
|
||||
host
|
||||
username
|
||||
@@ -24,26 +14,29 @@ exports.add = ->
|
||||
}
|
||||
|
||||
return server.id
|
||||
exports.add.description = 'Add a new Xen server to XO'
|
||||
exports.add.permission = 'admin'
|
||||
exports.add.params =
|
||||
host:
|
||||
type: 'string'
|
||||
username:
|
||||
type: 'string'
|
||||
password:
|
||||
type: 'string'
|
||||
|
||||
# Removes an existing server.
|
||||
exports.remove = ->
|
||||
{id} = @getParams {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# Current user must be administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
exports.remove = ({id}) ->
|
||||
# Throws an error if the server did not exist.
|
||||
@throw 'NO_SUCH_OBJECT' unless $wait @servers.remove id
|
||||
|
||||
return true
|
||||
exports.remove.permission = 'admin'
|
||||
exports.remove.params =
|
||||
id:
|
||||
type: 'string'
|
||||
|
||||
# Returns all servers.
|
||||
exports.getAll = ->
|
||||
# Only an administrator can see all servers.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Retrieves the servers.
|
||||
servers = $wait @servers.get()
|
||||
|
||||
@@ -52,19 +45,10 @@ exports.getAll = ->
|
||||
servers[i] = @getServerPublicProperties server
|
||||
|
||||
return servers
|
||||
exports.getAll.permission = 'admin'
|
||||
|
||||
# Changes the properties of an existing server.
|
||||
exports.set = ->
|
||||
{id, host, username, password} = @getParams {
|
||||
id: { type: 'string' }
|
||||
host: { type: 'string', optional: true }
|
||||
username: { type: 'string', optional: true }
|
||||
password: { type: 'string', optional: true }
|
||||
}
|
||||
|
||||
# Only an administrator can modify an server.
|
||||
@checkPermission 'admin'
|
||||
|
||||
exports.set = ({id, host, username, password}) ->
|
||||
# Retrieves the server.
|
||||
server = $wait @servers.first id
|
||||
|
||||
@@ -80,6 +64,20 @@ exports.set = ->
|
||||
$wait @servers.update server
|
||||
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params =
|
||||
id:
|
||||
type: 'string'
|
||||
host:
|
||||
type: 'string'
|
||||
optional: true
|
||||
username:
|
||||
type: 'string'
|
||||
optional: true
|
||||
password:
|
||||
type: 'string'
|
||||
optional: true
|
||||
|
||||
|
||||
# Connects to an existing server.
|
||||
exports.connect = ->
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.signInWithPassword = ({email, password}) ->
|
||||
@session.set 'user_id', user.get 'id'
|
||||
|
||||
# Returns the user.
|
||||
@getUserPublicProperties user
|
||||
return @getUserPublicProperties user
|
||||
exports.signInWithPassword.params = {
|
||||
email: { type: 'string' }
|
||||
password: { type: 'string' }
|
||||
@@ -38,7 +38,7 @@ exports.signInWithToken = ({token}) ->
|
||||
|
||||
# Returns the user.
|
||||
user = $wait @users.first user_id
|
||||
@getUserPublicProperties user
|
||||
return @getUserPublicProperties user
|
||||
exports.signInWithToken.params = {
|
||||
token: { type: 'string' }
|
||||
}
|
||||
@@ -47,7 +47,7 @@ exports.signOut = ->
|
||||
@session.unset 'token_id'
|
||||
@session.unset 'user_id'
|
||||
|
||||
true
|
||||
return true
|
||||
|
||||
# Gets the the currently signed in user.
|
||||
exports.getUser = ->
|
||||
@@ -58,4 +58,4 @@ exports.getUser = ->
|
||||
|
||||
# Returns the user.
|
||||
user = $wait @users.first id
|
||||
@getUserPublicProperties user
|
||||
return @getUserPublicProperties user
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#=====================================================================
|
||||
|
||||
exports.set = (params) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
SR = @getObject params.id
|
||||
catch
|
||||
@@ -21,7 +18,8 @@ exports.set = (params) ->
|
||||
|
||||
$wait xapi.call "SR.set_#{field}", SR.ref, params[param]
|
||||
|
||||
return
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params = {
|
||||
id: { type: 'string' }
|
||||
|
||||
@@ -31,12 +29,9 @@ exports.set.params = {
|
||||
}
|
||||
|
||||
|
||||
exports.scan = (params) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
exports.scan = ({id}) ->
|
||||
try
|
||||
SR = @getObject params.id
|
||||
SR = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
@@ -44,7 +39,8 @@ exports.scan = (params) ->
|
||||
|
||||
$wait xapi.call 'SR.scan', SR.ref
|
||||
|
||||
return
|
||||
return true
|
||||
exports.scan.permission = 'admin'
|
||||
exports.scan.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
|
||||
# Creates a new user.
|
||||
exports.create = ({email, password, permission}) ->
|
||||
# Current user must be administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Creates the user.
|
||||
user = $wait @users.create email, password, permission
|
||||
|
||||
return user.id
|
||||
exports.create.permission = 'admin'
|
||||
exports.create.params = {
|
||||
email: { type: 'string' }
|
||||
password: { type: 'string' }
|
||||
@@ -21,22 +19,20 @@ exports.create.params = {
|
||||
#
|
||||
# FIXME: a user should not be able to delete itself.
|
||||
exports.delete = ({id}) ->
|
||||
# Current user must be administrator.
|
||||
@checkPermission 'admin'
|
||||
# The user cannot delete himself.
|
||||
@throw 'INVALID_PARAMS' if id is @session.get 'user_id'
|
||||
|
||||
# Throws an error if the user did not exist.
|
||||
@throw 'NO_SUCH_OBJECT' unless $wait @users.remove id
|
||||
|
||||
return true
|
||||
exports.delete.permission = 'admin'
|
||||
exports.delete.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# Changes the password of the current user.
|
||||
exports.changePassword = ({old, new: newP}) ->
|
||||
# Current user must be signed in.
|
||||
@checkPermission()
|
||||
|
||||
# Gets the current user (which MUST exist).
|
||||
user = $wait @users.first @session.get 'user_id'
|
||||
|
||||
@@ -50,6 +46,7 @@ exports.changePassword = ({old, new: newP}) ->
|
||||
$wait @users.update user
|
||||
|
||||
return true
|
||||
exports.changePassword.permission = '' # Signed in.
|
||||
exports.changePassword.params = {
|
||||
old: { type: 'string' }
|
||||
new: { type: 'string' }
|
||||
@@ -73,9 +70,6 @@ exports.get.params = {
|
||||
|
||||
# Returns all users.
|
||||
exports.getAll = ->
|
||||
# Only an administrator can see all users.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Retrieves the users.
|
||||
users = $wait @users.get()
|
||||
|
||||
@@ -84,12 +78,10 @@ exports.getAll = ->
|
||||
users[i] = @getUserPublicProperties user
|
||||
|
||||
return users
|
||||
exports.getAll.permission = 'admin'
|
||||
|
||||
# Changes the properties of an existing user.
|
||||
exports.set = ({id, email, password, permission}) ->
|
||||
# Only an administrator can modify an user.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Retrieves the user.
|
||||
user = $wait @users.first id
|
||||
|
||||
@@ -105,6 +97,7 @@ exports.set = ({id, email, password, permission}) ->
|
||||
$wait @users.update user
|
||||
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params = {
|
||||
id: { type: 'string' }
|
||||
email: { type: 'string', optional: true }
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#=====================================================================
|
||||
|
||||
exports.delete = ({id}) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VBD = @getObject params.id
|
||||
catch
|
||||
@@ -14,17 +11,15 @@ exports.delete = ({id}) ->
|
||||
xapi = @getXAPI VBD
|
||||
|
||||
# TODO: check if VBD is attached before
|
||||
$wait xapi.call "VBD.destroy", VBD.ref
|
||||
$wait xapi.call 'VBD.destroy', VBD.ref
|
||||
|
||||
return
|
||||
return true
|
||||
exports.delete.permission = 'admin'
|
||||
exports.delete.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.disconnect = ({id}) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VBD = @getObject params.id
|
||||
catch
|
||||
@@ -33,9 +28,10 @@ exports.disconnect = ({id}) ->
|
||||
xapi = @getXAPI VBD
|
||||
|
||||
# TODO: check if VBD is attached before
|
||||
$wait xapi.call "VBD.unplug_force", VBD.ref
|
||||
$wait xapi.call 'VBD.unplug_force', VBD.ref
|
||||
|
||||
return
|
||||
return true
|
||||
exports.disconnect.permission = 'admin'
|
||||
exports.disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
{isArray: $isArray} = require 'underscore'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
{$wait} = require '../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
exports.delete = ({id}) ->
|
||||
params = @getParams {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VDI = @getObject params.id
|
||||
VDI = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
xapi = @getXAPI VDI
|
||||
|
||||
# TODO: check if VDI is attached before
|
||||
$wait xapi.call "VDI.destroy", VDI.ref
|
||||
$wait xapi.call 'VDI.destroy', VDI.ref
|
||||
|
||||
return
|
||||
return true
|
||||
exports.delete.permission = 'admin'
|
||||
exports.delete.params =
|
||||
id:
|
||||
type: 'string'
|
||||
|
||||
exports.set = (params) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VDI = @getObject params.id
|
||||
catch
|
||||
@@ -57,7 +55,8 @@ exports.set = (params) ->
|
||||
for field in (if $isArray fields then fields else [fields])
|
||||
$wait xapi.call "VDI.set_#{field}", ref, "#{params[param]}"
|
||||
|
||||
return
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params = {
|
||||
# Identifier of the VDI to update.
|
||||
id: { type: 'string' }
|
||||
@@ -67,5 +66,5 @@ exports.set.params = {
|
||||
name_description: { type: 'string', optional: true }
|
||||
|
||||
# size of VDI
|
||||
size: { type: 'integer' }
|
||||
size: { type: 'integer', optional: true }
|
||||
}
|
||||
|
||||
@@ -43,9 +43,6 @@ exports.create = ({
|
||||
VDIs
|
||||
VIFs
|
||||
}) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Gets the template.
|
||||
template = @getObject template
|
||||
@throw 'NO_SUCH_OBJECT' unless template
|
||||
@@ -186,6 +183,7 @@ exports.create = ({
|
||||
|
||||
# The VM should be properly created.
|
||||
return VM.uuid
|
||||
exports.create.permission = 'admin'
|
||||
exports.create.params = {
|
||||
installation: {
|
||||
type: 'object'
|
||||
@@ -241,9 +239,6 @@ exports.create.params = {
|
||||
}
|
||||
|
||||
exports.delete = ({id, delete_disks: deleteDisks}) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -268,6 +263,7 @@ exports.delete = ({id, delete_disks: deleteDisks}) ->
|
||||
$wait xapi.call 'VM.destroy', VM.ref
|
||||
|
||||
return true
|
||||
exports.delete.permission = 'admin'
|
||||
exports.delete.params = {
|
||||
id: { type: 'string' }
|
||||
|
||||
@@ -297,6 +293,7 @@ exports.ejectCd = ({id}) ->
|
||||
$wait xapi.call 'VBD.destroy', cdDriveRef
|
||||
|
||||
return true
|
||||
exports.ejectCd.permission = 'admin'
|
||||
exports.ejectCd.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
@@ -342,6 +339,7 @@ exports.insertCd = ({id, cd_id, force}) ->
|
||||
$wait xapi.call 'VBD.insert', cdDriveRef, VDI.ref
|
||||
|
||||
return true
|
||||
exports.insertCd.permission = 'admin'
|
||||
exports.insertCd.params = {
|
||||
id: { type: 'string' }
|
||||
cd_id: { type: 'string' }
|
||||
@@ -349,9 +347,6 @@ exports.insertCd.params = {
|
||||
}
|
||||
|
||||
exports.migrate = ({id, host_id}) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
host = @getObject host_id
|
||||
@@ -366,6 +361,7 @@ exports.migrate = ({id, host_id}) ->
|
||||
$wait xapi.call 'VM.pool_migrate', VM.ref, host.ref, {}
|
||||
|
||||
return true
|
||||
exports.migrate.permission = 'admin'
|
||||
exports.migrate.params = {
|
||||
# Identifier of the VM to migrate.
|
||||
id: { type: 'string' }
|
||||
@@ -375,9 +371,6 @@ exports.migrate.params = {
|
||||
}
|
||||
|
||||
exports.set = (params) ->
|
||||
# Current user must be an administrator.
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject params.id
|
||||
catch
|
||||
@@ -438,6 +431,7 @@ exports.set = (params) ->
|
||||
$wait xapi.call "VM.set_#{field}", ref, "#{params[param]}"
|
||||
|
||||
return true
|
||||
exports.set.permission = 'admin'
|
||||
exports.set.params = {
|
||||
# Identifier of the VM to update.
|
||||
id: { type: 'string' }
|
||||
@@ -456,8 +450,6 @@ exports.set.params = {
|
||||
}
|
||||
|
||||
exports.restart = ({id, force}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -476,14 +468,13 @@ exports.restart = ({id, force}) ->
|
||||
$wait xapi.call 'VM.hard_reboot', VM.ref
|
||||
|
||||
return true
|
||||
exports.restart.permission = 'admin'
|
||||
exports.restart.params = {
|
||||
id: { type: 'string' }
|
||||
force: { type: 'boolean' }
|
||||
}
|
||||
|
||||
exports.clone = ({id, name, full_copy}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -496,6 +487,7 @@ exports.clone = ({id, name, full_copy}) ->
|
||||
$wait xapi.call 'VM.clone', VM.ref, name
|
||||
|
||||
return true
|
||||
exports.clone.permission = 'admin'
|
||||
exports.clone.params = {
|
||||
id: { type: 'string' }
|
||||
name: { type: 'string' }
|
||||
@@ -504,8 +496,6 @@ exports.clone.params = {
|
||||
|
||||
# TODO: rename convertToTemplate()
|
||||
exports.convert = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -515,13 +505,12 @@ exports.convert = ({id}) ->
|
||||
$wait xapi.call 'VM.set_is_a_template', VM.ref, true
|
||||
|
||||
return true
|
||||
exports.convert.permission = 'admin'
|
||||
exports.convert.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.snapshot = ({id, name}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -532,33 +521,31 @@ exports.snapshot = ({id, name}) ->
|
||||
$wait xapi.call 'VM.snapshot', VM.ref, name
|
||||
|
||||
return true
|
||||
exports.snapshot.permission = 'admin'
|
||||
exports.snapshot.params = {
|
||||
id: { type: 'string' }
|
||||
name: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.start = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
(@getXAPI VM).call(
|
||||
$wait (@getXAPI VM).call(
|
||||
'VM.start', VM.ref
|
||||
false # Start paused?
|
||||
false # Skips the pre-boot checks?
|
||||
)
|
||||
|
||||
return true
|
||||
exports.start.permission = 'admin'
|
||||
exports.start.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
exports.stop = ({id, force}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -577,6 +564,7 @@ exports.stop = ({id, force}) ->
|
||||
$wait xapi.call 'VM.hard_shutdown', VM.ref
|
||||
|
||||
return true
|
||||
exports.stop.permission = 'admin'
|
||||
exports.stop.params = {
|
||||
id: { type: 'string' }
|
||||
force: { type: 'boolean' }
|
||||
@@ -584,8 +572,6 @@ exports.stop.params = {
|
||||
|
||||
# revert a snapshot to its parent VM
|
||||
exports.revert = ({id}) ->
|
||||
@checkPermission 'admin'
|
||||
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@@ -597,6 +583,57 @@ exports.revert = ({id}) ->
|
||||
$wait xapi.call 'VM.revert', VM.ref
|
||||
|
||||
return true
|
||||
exports.revert.permission = 'admin'
|
||||
exports.revert.params = {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# export a VM
|
||||
exports.export = ({id, compress}) ->
|
||||
@throw 'NOT_IMPLEMENTED'
|
||||
compress ?= true
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
xapi = @getXAPI VM
|
||||
|
||||
# get the session ID
|
||||
sessionId = xapi.sessionId
|
||||
# HTTP object connected to the pool master
|
||||
http.put "/export/?session_id=#{sessionId}&ref=#{VM.ref}&use_compression=#{compress}"
|
||||
|
||||
# @TODO: we need to get the file somehow
|
||||
|
||||
return true
|
||||
exports.export.permission = 'admin'
|
||||
exports.export.params = {
|
||||
id: { type: 'string' }
|
||||
compress: { type: 'boolean', optional:true }
|
||||
}
|
||||
|
||||
# import a VM
|
||||
exports.import = ({id, file}) ->
|
||||
@throw 'NOT_IMPLEMENTED'
|
||||
try
|
||||
VM = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
xapi = @getXAPI VM
|
||||
|
||||
# get the session ID
|
||||
sessionId = xapi.sessionId
|
||||
|
||||
# HTTP object connected to the pool master
|
||||
http.put "/import/?session_id=#{sessionId}"
|
||||
|
||||
# @TODO: we need to put the file somehow
|
||||
|
||||
return true
|
||||
exports.import.permission = 'admin'
|
||||
exports.import.params = {
|
||||
id: { type: 'string' }
|
||||
file: { type: 'string' }
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
$_ = require 'underscore'
|
||||
|
||||
{$wait} = require '../../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Generates method to delete objects.
|
||||
do ->
|
||||
types = [
|
||||
'message'
|
||||
'task'
|
||||
]
|
||||
$_.each types, (type) ->
|
||||
exports[type] ?= {}
|
||||
exports[type].destroy = ->
|
||||
{id} = @getParams {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# FIXME: For now, the current user must be an administrator, but
|
||||
# eventually, the user only need to have the “write” permission
|
||||
# over the object linked to the message or task.
|
||||
@checkPermission 'admin'
|
||||
|
||||
# Retrieves the object.
|
||||
object = @xobjs.get id
|
||||
@throw 'NO_SUCH_OBJECT' unless object?
|
||||
|
||||
# Gets the corresponding connection.
|
||||
xapi = @xapis[object.$pool]
|
||||
$wait xapi.call "#{type}.destroy", object.$ref
|
||||
|
||||
return true
|
||||
@@ -1,49 +0,0 @@
|
||||
$_ = require 'underscore'
|
||||
|
||||
{$wait} = require '../../fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Definitions of the methods to generate.
|
||||
defs = {
|
||||
pause: {}
|
||||
|
||||
unpause: {}
|
||||
}
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Generates methods.
|
||||
$_.each defs, (def, name) ->
|
||||
method = name
|
||||
params = []
|
||||
|
||||
if $_.isString def
|
||||
method = def
|
||||
else if $_.isArray def
|
||||
params = def
|
||||
else if $_.isObject def
|
||||
method = def.method if def.method?
|
||||
params = def.params if def.params?
|
||||
|
||||
exports[name] = ->
|
||||
# This method expect to the VM's UUID.
|
||||
{id} = @getParams {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
|
||||
# The current session MUST have the `write`
|
||||
# permission.
|
||||
@checkPermission 'write'
|
||||
|
||||
# Retrieves the VM with this UUID.
|
||||
try
|
||||
vm = @getObject id
|
||||
catch
|
||||
@throw 'NO_SUCH_OBJECT'
|
||||
|
||||
# Gets the corresponding connection.
|
||||
xapi = @getXAPI vm
|
||||
$wait xapi.call.apply xapi, ["VM.#{method}", vm.ref].concat params
|
||||
|
||||
return true
|
||||
@@ -73,8 +73,6 @@ $fiberize = (fn) ->
|
||||
).run()
|
||||
|
||||
# Makes a function run in its own fiber and returns a promise.
|
||||
#
|
||||
# TODO: should we keep it?
|
||||
$promisify = (fn) ->
|
||||
(args...) ->
|
||||
new $Promise (resolve, reject) ->
|
||||
|
||||
@@ -8,12 +8,18 @@ $_ = require 'underscore'
|
||||
|
||||
# HTTP(s) middleware framework.
|
||||
$connect = require 'connect'
|
||||
$serveStatic = require 'serve-static'
|
||||
|
||||
$eventToPromise = require 'event-to-promise'
|
||||
|
||||
# Configuration handling.
|
||||
$nconf = require 'nconf'
|
||||
|
||||
$Promise = require 'bluebird'
|
||||
$Promise.longStackTraces()
|
||||
|
||||
# WebSocket server.
|
||||
$WSServer = (require 'ws').Server
|
||||
{Server: $WSServer} = require 'ws'
|
||||
|
||||
# YAML formatting and parsing.
|
||||
$YAML = require 'js-yaml'
|
||||
@@ -25,13 +31,15 @@ $Connection = require './connection'
|
||||
$XO = require './xo'
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$fiberize, $waitEvent, $wait} = require './fibers-utils'
|
||||
{$fiberize, $promisify, $waitEvent, $wait} = require './fibers-utils'
|
||||
|
||||
# HTTP/HTTPS server which can listen on multiple ports.
|
||||
$WebServer = require './web-server'
|
||||
$WebServer = require 'http-server-plus'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
$readFile = $Promise.promisify $fs.readFile
|
||||
|
||||
$handleJsonRpcCall = (api, session, encodedRequest) ->
|
||||
request = {
|
||||
id: null
|
||||
@@ -81,7 +89,11 @@ $handleJsonRpcCall = (api, session, encodedRequest) ->
|
||||
#=====================================================================
|
||||
|
||||
# Main.
|
||||
do $fiberize ->
|
||||
module.exports = $promisify (args) ->
|
||||
|
||||
# Relative paths in the configuration are relative to this
|
||||
# directory's parent.
|
||||
process.chdir "#{__dirname}/.."
|
||||
|
||||
# Loads the environment.
|
||||
$nconf.env()
|
||||
@@ -89,13 +101,13 @@ do $fiberize ->
|
||||
# Parses process' arguments.
|
||||
$nconf.argv()
|
||||
|
||||
# Loads the configuration file.
|
||||
# Loads the configuration files.
|
||||
format =
|
||||
stringify: $YAML.safeDump
|
||||
parse: $YAML.safeLoad
|
||||
$nconf.use 'file', {
|
||||
file: "#{__dirname}/../config/local.yaml"
|
||||
format: {
|
||||
stringify: (obj) -> $YAML.safeDump obj
|
||||
parse: (string) -> $YAML.safeLoad string
|
||||
}
|
||||
format
|
||||
}
|
||||
|
||||
# Defines defaults configuration.
|
||||
@@ -118,10 +130,26 @@ do $fiberize ->
|
||||
|
||||
# Creates the web server according to the configuration.
|
||||
webServer = new $WebServer()
|
||||
webServer.listen options for options in $nconf.get 'http:listen'
|
||||
$wait $Promise.map ($nconf.get 'http:listen'), (options) ->
|
||||
# Reads certificate and key if necessary.
|
||||
if options.certificate? and options.key?
|
||||
options.certificate = $wait $readFile options.certificate
|
||||
options.key = $wait $readFile options.key
|
||||
|
||||
# Waits for the web server to start listening to drop privileges.
|
||||
$waitEvent webServer, 'listening'
|
||||
# Starts listening
|
||||
webServer.listen options
|
||||
.then ->
|
||||
console.log "WebServer listening on #{@niceAddress()}"
|
||||
.catch (error) ->
|
||||
console.warn "[WARN] WebServer could not listen on #{@niceAddress()}"
|
||||
switch error.code
|
||||
when 'EACCES'
|
||||
console.warn ' Access denied.'
|
||||
console.warn ' Ports < 1024 are often reserved to privileges users.'
|
||||
when 'EADDRINUSE'
|
||||
console.warn ' Address already in use.'
|
||||
|
||||
# Now the web server is listening, drop privileges.
|
||||
try
|
||||
if (group = $nconf.get 'group')?
|
||||
process.setgid group
|
||||
@@ -151,7 +179,7 @@ do $fiberize ->
|
||||
for urlPath, filePaths of $nconf.get 'http:mounts'
|
||||
filePaths = [filePaths] unless $_.isArray filePaths
|
||||
for filePath in filePaths
|
||||
connect.use urlPath, $connect.static filePath
|
||||
connect.use urlPath, $serveStatic filePath
|
||||
webServer.on 'request', connect
|
||||
|
||||
# Creates the API.
|
||||
@@ -198,3 +226,5 @@ do $fiberize ->
|
||||
password = 'admin' # TODO: Should be generated.
|
||||
xo.users.create email, password, 'admin'
|
||||
console.log "[INFO] Default user: “#{email}” with password “#{password}”"
|
||||
|
||||
return $eventToPromise webServer, 'close'
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
var Model = require('./model');
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Session = Model.extend({
|
||||
'constructor': function (xo) {
|
||||
Model.call(this);
|
||||
|
||||
|
||||
var self = this;
|
||||
var close = function () {
|
||||
self.close();
|
||||
};
|
||||
|
||||
// If the user associated to this session is deleted or
|
||||
// disabled, the session must close.
|
||||
this.on('change:user_id', function () {
|
||||
var event = 'user.revoked:'+ this.get('user_id');
|
||||
|
||||
xo.on(event, close);
|
||||
|
||||
// Prevents a memory leak.
|
||||
self.on('close', function () {
|
||||
xo.removeListener(event, close);
|
||||
});
|
||||
});
|
||||
|
||||
// If the token associated to this session is deleted, the
|
||||
// session must close.
|
||||
this.on('change:token_id', function () {
|
||||
var event = 'token.revoked:'+ this.get('token_id');
|
||||
|
||||
xo.on(event, close);
|
||||
|
||||
// Prevents a memory leak.
|
||||
self.on('close', function () {
|
||||
xo.removeListener(event, close);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'close': function () {
|
||||
// This function can be called multiple times but will only
|
||||
// emit an event once.
|
||||
this.close = function () {};
|
||||
|
||||
this.emit('close');
|
||||
},
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module.exports = Session;
|
||||
@@ -11,7 +11,7 @@ $helpers = require './helpers'
|
||||
#=====================================================================
|
||||
|
||||
$isVMRunning = ->
|
||||
switch @genval.power_state
|
||||
switch @val.power_state
|
||||
when 'Paused', 'Running'
|
||||
true
|
||||
else
|
||||
@@ -21,7 +21,7 @@ $isHostRunning = ->
|
||||
@val.power_state is 'Running'
|
||||
|
||||
$isTaskLive = ->
|
||||
@genval.status is 'pending' or @genval.status is 'cancelling'
|
||||
@val.status is 'pending' or @val.status is 'cancelling'
|
||||
|
||||
# $xml2js.parseString() uses callback for synchronous code.
|
||||
$parseXML = (XML) ->
|
||||
@@ -254,12 +254,12 @@ module.exports = ->
|
||||
$memory: {
|
||||
usage: $sum {
|
||||
rule: 'host'
|
||||
if: -> @val?.memory?.usage?
|
||||
if: $isHostRunning
|
||||
val: -> @val.memory.usage
|
||||
}
|
||||
size: $sum {
|
||||
rule: 'host'
|
||||
if: -> @val?.memory?.size?
|
||||
if: $isHostRunning
|
||||
val: -> @val.memory.size
|
||||
}
|
||||
}
|
||||
@@ -451,6 +451,8 @@ module.exports = ->
|
||||
else
|
||||
null
|
||||
|
||||
power_state: -> @genval.power_state
|
||||
|
||||
memory: ->
|
||||
{metrics, guest_metrics} = @data
|
||||
|
||||
@@ -477,8 +479,6 @@ module.exports = ->
|
||||
|
||||
memory
|
||||
|
||||
power_state: -> @genval.power_state
|
||||
|
||||
PV_drivers: ->
|
||||
{guest_metrics} = @data
|
||||
if guest_metrics
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
# Events handling.
|
||||
{EventEmitter: $EventEmitter} = require 'events'
|
||||
|
||||
# File handling.
|
||||
$fs = require 'fs'
|
||||
|
||||
# HTTP(S) handling.
|
||||
$http = require 'http'
|
||||
$https = require 'https'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Low level tools.
|
||||
$_ = require 'underscore'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$wait} = require './fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Events which may be emitted by a `http(s).Server`
|
||||
$events = [
|
||||
'checkContinue'
|
||||
'clientError'
|
||||
'close'
|
||||
'connect'
|
||||
'connection'
|
||||
'error'
|
||||
'request'
|
||||
'upgrade'
|
||||
]
|
||||
|
||||
# Thunk version of `$fs.readFile()`.
|
||||
$readFile = (args...) ->
|
||||
(cb) ->
|
||||
$fs.readFile args..., cb
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# HTTP/HTTPS server which can listen on multiple address/ports or
|
||||
# sockets.
|
||||
class $WebServer extends $EventEmitter
|
||||
|
||||
constructor: ->
|
||||
@_servers = []
|
||||
@_notYetListening = 0
|
||||
|
||||
close: ->
|
||||
server.close() for server in @_servers
|
||||
|
||||
# Does not return anything.
|
||||
undefined
|
||||
|
||||
listen: ({host, port, socket, certificate, key}) ->
|
||||
server = if certificate? and key?
|
||||
$https.createServer {
|
||||
cert: $wait $readFile certificate
|
||||
key: $wait $readFile key
|
||||
}
|
||||
else
|
||||
$http.createServer()
|
||||
@_servers.push server
|
||||
|
||||
# Makes it start listening.
|
||||
if socket?
|
||||
server.listen socket
|
||||
else
|
||||
host ?= '0.0.0.0'
|
||||
server.listen port, host
|
||||
|
||||
++@_notYetListening
|
||||
|
||||
errorHandler = (error) =>
|
||||
# `address()` can only be used once listening.
|
||||
address = if socket?
|
||||
socket
|
||||
else
|
||||
"#{host}:#{port}"
|
||||
|
||||
# Prints a (hopefully) helpful message if the server could not
|
||||
# listen.
|
||||
console.log "[WARN] WebServer could not listen on #{address}"
|
||||
switch error.code
|
||||
when 'EACCES'
|
||||
console.log ' Access denied.'
|
||||
if port < 1024
|
||||
console.log ' Ports < 1024 are often reserved to privileges users.'
|
||||
when 'EADDRINUSE'
|
||||
console.log ' Address already in use.'
|
||||
|
||||
# This server will never start listening.
|
||||
--@_notYetListening
|
||||
|
||||
# Registers the error handler.
|
||||
server.on 'error', errorHandler
|
||||
|
||||
server.once 'listening', =>
|
||||
# Removes the error handler.
|
||||
server.removeListener 'error', errorHandler
|
||||
|
||||
# Prints a helpful message.
|
||||
address = server.address()
|
||||
if $_.isObject address
|
||||
{address, port} = address
|
||||
address = "#{address}:#{port}"
|
||||
console.log "WebServer listening on #{address}"
|
||||
|
||||
# If the web server is listening on all addresses, fire the
|
||||
# `listening` event.
|
||||
@emit 'listening' unless --@_notYetListening
|
||||
|
||||
# Forwards events to this object.
|
||||
$_.each $events, (event) =>
|
||||
server.on event, (args...) => @emit event, args...
|
||||
|
||||
# Does not return anything.
|
||||
undefined
|
||||
|
||||
#=====================================================================
|
||||
|
||||
module.exports = $WebServer
|
||||
46
xo-server
46
xo-server
@@ -1,46 +0,0 @@
|
||||
#/bin/sh -eu
|
||||
|
||||
# This file is a part of Xen Orchestra Server.
|
||||
#
|
||||
# Xen Orchestra Server is free software: you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Xen Orchestra Server is distributed in the hope that it will be
|
||||
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Xen Orchestra Server. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
# @license http://www.gnu.org/licenses/gpl-3.0-standalone.html GPLv3
|
||||
#
|
||||
# @package Xen Orchestra Server
|
||||
|
||||
MAIN='src/main.coffee'
|
||||
|
||||
COFFEE='./node_modules/.bin/coffee'
|
||||
|
||||
#######################################
|
||||
|
||||
cd -P "$(dirname "$(which "$0")")"
|
||||
|
||||
########################################
|
||||
|
||||
if [ "${1:-}" = '--debug' ]
|
||||
then
|
||||
shift
|
||||
|
||||
# Launch XO-Server in debug mode.
|
||||
"$COFFEE" --nodejs --debug-brk "$MAIN" "$@" > /dev/null &
|
||||
|
||||
# Runs Node Inspector (avoids the recommended alternate HTTP port
|
||||
# for XO-Server).
|
||||
exec ./node_modules/.bin/node-inspector --web-port 64985
|
||||
else
|
||||
exec "$COFFEE" "$MAIN" "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user