Merge remote-tracking branch 'xo-cli/master'
This commit is contained in:
commit
a703ecc7e1
12
packages/xo-cli/.editorconfig
Normal file
12
packages/xo-cli/.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespaces = true
|
1
packages/xo-cli/.gitignore
vendored
Normal file
1
packages/xo-cli/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/node_modules/
|
90
packages/xo-cli/.jshintrc
Normal file
90
packages/xo-cli/.jshintrc
Normal file
@ -0,0 +1,90 @@
|
||||
{
|
||||
// Julien Fontanet JSHint configuration
|
||||
//
|
||||
// Changes from defaults:
|
||||
// - all enforcing options (except `++` & `--`) enabled
|
||||
// - single quotes
|
||||
// - indentation set to 2 instead of 4
|
||||
// - almost all relaxing options disabled
|
||||
// - allow expression statements (necessary for chai.expect())
|
||||
// - allow global strict (most of my devs are in Node.js or Browserify)
|
||||
// - environments are set to Browserify, mocha & Node.js
|
||||
//
|
||||
// See http://jshint.com/docs/ for more details
|
||||
|
||||
"maxerr" : 50, // {int} Maximum error before stopping
|
||||
|
||||
// Enforcing
|
||||
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
|
||||
"camelcase" : true, // true: Identifiers must be in camelCase
|
||||
"curly" : true, // true: Require {} for every new block or scope
|
||||
"eqeqeq" : true, // true: Require triple equals (===) for comparison
|
||||
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
|
||||
"immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||
"indent" : 2, // {int} Number of spaces to use for indentation
|
||||
"latedef" : true, // true: Require variables/functions to be defined before being used
|
||||
"newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||
"noempty" : true, // true: Prohibit use of empty blocks
|
||||
"nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment)
|
||||
"plusplus" : false, // true: Prohibit use of `++` & `--`
|
||||
"quotmark" : "single", // Quotation mark consistency:
|
||||
// false : do nothing (default)
|
||||
// true : ensure whatever is used is consistent
|
||||
// "single" : require single quotes
|
||||
// "double" : require double quotes
|
||||
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||
"unused" : true, // true: Require all defined variables be used
|
||||
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
|
||||
"maxparams" : 4, // {int} Max number of formal params allowed per function
|
||||
"maxdepth" : 3, // {int} Max depth of nested blocks (within functions)
|
||||
"maxstatements" : 20, // {int} Max number statements per function
|
||||
"maxcomplexity" : 7, // {int} Max cyclomatic complexity per function
|
||||
"maxlen" : 80, // {int} Max number of characters per line
|
||||
|
||||
// Relaxing
|
||||
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
|
||||
"boss" : false, // true: Tolerate assignments where comparisons would be expected
|
||||
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
|
||||
"eqnull" : false, // true: Tolerate use of `== null`
|
||||
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
|
||||
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
|
||||
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
|
||||
// (ex: `for each`, multiple try/catch, function expression…)
|
||||
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
|
||||
"expr" : true, // true: Tolerate `ExpressionStatement` as Programs
|
||||
"funcscope" : false, // true: Tolerate defining variables inside control statements
|
||||
"globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
|
||||
"iterator" : false, // true: Tolerate using the `__iterator__` property
|
||||
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
|
||||
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
|
||||
"laxcomma" : false, // true: Tolerate comma-first style coding
|
||||
"loopfunc" : false, // true: Tolerate functions being defined in loops
|
||||
"multistr" : false, // true: Tolerate multi-line strings
|
||||
"proto" : false, // true: Tolerate using the `__proto__` property
|
||||
"scripturl" : false, // true: Tolerate script-targeted URLs
|
||||
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
|
||||
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
|
||||
"validthis" : false, // true: Tolerate using this in a non-constructor function
|
||||
|
||||
// Environments
|
||||
"browser" : false, // Web Browser (window, document, etc)
|
||||
"browserify" : true, // Browserify (node.js code in the browser)
|
||||
"couch" : false, // CouchDB
|
||||
"devel" : true, // Development/debugging (alert, confirm, etc)
|
||||
"dojo" : false, // Dojo Toolkit
|
||||
"jquery" : false, // jQuery
|
||||
"mocha" : true, // mocha
|
||||
"mootools" : false, // MooTools
|
||||
"node" : true, // Node.js
|
||||
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
|
||||
"prototypejs" : false, // Prototype and Scriptaculous
|
||||
"rhino" : false, // Rhino
|
||||
"worker" : false, // Web Workers
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
|
||||
// Custom Globals
|
||||
"globals" : {} // additional predefined global variables
|
||||
}
|
9
packages/xo-cli/.travis.yml
Normal file
9
packages/xo-cli/.travis.yml
Normal file
@ -0,0 +1,9 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 'stable'
|
||||
- '6'
|
||||
- '4'
|
||||
|
||||
# Use containers.
|
||||
# http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||
sudo: false
|
130
packages/xo-cli/README.md
Normal file
130
packages/xo-cli/README.md
Normal file
@ -0,0 +1,130 @@
|
||||
# XO-CLI
|
||||
[](http://travis-ci.org/vatesfr/xo-cli)
|
||||
[](https://david-dm.org/vatesfr/xo-cli)
|
||||
[](https://david-dm.org/vatesfr/xo-cli#info=devDependencies)
|
||||
|
||||
> Basic CLI for Xen-Orchestra
|
||||
|
||||
## Installation
|
||||
|
||||
#### [npm](https://npmjs.org/package/xo-cli)
|
||||
|
||||
```
|
||||
npm install -g xo-cli
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
> xo-cli --help
|
||||
Usage:
|
||||
|
||||
xo-cli --register [<XO-Server URL>] [<username>] [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
xo-cli --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
xo-cli --list-commands [--json] [<pattern>]...
|
||||
Returns the list of available commands on the current XO instance.
|
||||
|
||||
The patterns can be used to filter on command names.
|
||||
|
||||
xo-cli --list-objects [--<property>]… [<property>=<value>]...
|
||||
Returns a list of XO objects.
|
||||
|
||||
--<property>
|
||||
Restricts displayed properties to those listed.
|
||||
|
||||
<property>=<value>
|
||||
Restricted displayed objects to those matching the patterns.
|
||||
|
||||
xo-cli <command> [<name>=<value>]...
|
||||
Executes a command on the current XO instance.
|
||||
```
|
||||
|
||||
#### Register your XO instance
|
||||
|
||||
```
|
||||
> xo-cli --register http://xo.my-company.net admin@admin.net admin
|
||||
Successfully logged with admin@admin.net
|
||||
```
|
||||
|
||||
Note: only a token will be saved in the configuration file.
|
||||
|
||||
#### List available objects
|
||||
|
||||
Prints all objects:
|
||||
|
||||
```
|
||||
> xo-cli --list-objects
|
||||
```
|
||||
|
||||
It is possible to filter on object properties, for instance to prints
|
||||
all VM templates:
|
||||
|
||||
```
|
||||
> xo-cli --list-objects type=VM-template
|
||||
```
|
||||
|
||||
#### List available commands
|
||||
|
||||
```
|
||||
> xo-cli --list-commands
|
||||
```
|
||||
|
||||
Commands can be filtered using patterns:
|
||||
|
||||
```
|
||||
> xo-cli --list-commands '{user,group}.*'
|
||||
```
|
||||
|
||||
#### Execute a command
|
||||
|
||||
The same syntax is used for all commands: `xo-cli <command> <param
|
||||
name>=<value>...`
|
||||
|
||||
E.g., adding a new server:
|
||||
|
||||
```
|
||||
> xo-cli server.add host=my.server.net username=root password=secret-password
|
||||
42
|
||||
```
|
||||
|
||||
The return value is the identifier of this new server in XO.
|
||||
|
||||
Parameters (except `true` and `false` which are correctly parsed as
|
||||
booleans) are assumed to be strings, for other types, you may use JSON
|
||||
encoding by prefixing with `json:`:
|
||||
|
||||
```
|
||||
> xo-cli foo.bar baz='json:[1, 2, 3]'
|
||||
```
|
||||
|
||||
##### VM export
|
||||
|
||||
```
|
||||
> xo-cli vm.export vm=a01667e0-8e29-49fc-a550-17be4226783c @=vm.xva
|
||||
```
|
||||
|
||||
##### VM import
|
||||
|
||||
```
|
||||
> xo-cli vm.import host=60a6939e-8b0a-4352-9954-5bde44bcdf7d @=vm.xva
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are *very* welcome, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xo-cli/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
XO-CLI is released under the [AGPL
|
||||
v3](http://www.gnu.org/licenses/agpl-3.0-standalone.html).
|
54
packages/xo-cli/config.js
Normal file
54
packages/xo-cli/config.js
Normal file
@ -0,0 +1,54 @@
|
||||
'use strict'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var promisify = require('bluebird').promisify
|
||||
|
||||
var readFile = promisify(require('fs').readFile)
|
||||
var writeFile = promisify(require('fs').writeFile)
|
||||
|
||||
var assign = require('lodash/assign')
|
||||
var l33t = require('l33teral')
|
||||
var mkdirp = promisify(require('mkdirp'))
|
||||
var xdgBasedir = require('xdg-basedir')
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var configPath = xdgBasedir.config + '/xo-cli'
|
||||
var configFile = configPath + '/config.json'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var load = exports.load = function () {
|
||||
return readFile(configFile).then(JSON.parse).catch(function () {
|
||||
return {}
|
||||
})
|
||||
}
|
||||
|
||||
exports.get = function (path) {
|
||||
return load().then(function (config) {
|
||||
return l33t(config).tap(path)
|
||||
})
|
||||
}
|
||||
|
||||
var save = exports.save = function (config) {
|
||||
return mkdirp(configPath).then(function () {
|
||||
return writeFile(configFile, JSON.stringify(config))
|
||||
})
|
||||
}
|
||||
|
||||
exports.set = function (data) {
|
||||
return load().then(function (config) {
|
||||
return save(assign(config, data))
|
||||
})
|
||||
}
|
||||
|
||||
exports.unset = function (paths) {
|
||||
return load().then(function (config) {
|
||||
var l33tConfig = l33t(config)
|
||||
;[].concat(paths).forEach(function (path) {
|
||||
l33tConfig.purge(path, true)
|
||||
})
|
||||
return save(config)
|
||||
})
|
||||
}
|
397
packages/xo-cli/index.js
Executable file
397
packages/xo-cli/index.js
Executable file
@ -0,0 +1,397 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
var Bluebird = require('bluebird')
|
||||
Bluebird.longStackTraces()
|
||||
|
||||
var createReadStream = require('fs').createReadStream
|
||||
var createWriteStream = require('fs').createWriteStream
|
||||
var resolveUrl = require('url').resolve
|
||||
var stat = require('fs-promise').stat
|
||||
|
||||
var chalk = require('chalk')
|
||||
var eventToPromise = require('event-to-promise')
|
||||
var filter = require('lodash/filter')
|
||||
var forEach = require('lodash/forEach')
|
||||
var getKeys = require('lodash/keys')
|
||||
var got = require('got')
|
||||
var humanFormat = require('human-format')
|
||||
var identity = require('lodash/identity')
|
||||
var isObject = require('lodash/isObject')
|
||||
var micromatch = require('micromatch')
|
||||
var multiline = require('multiline')
|
||||
var nicePipe = require('nice-pipe')
|
||||
var pairs = require('lodash/toPairs')
|
||||
var pick = require('lodash/pick')
|
||||
var prettyMs = require('pretty-ms')
|
||||
var progressStream = require('progress-stream')
|
||||
var Xo = require('xo-lib').default
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
var config = require('./config')
|
||||
|
||||
// ===================================================================
|
||||
|
||||
function connect () {
|
||||
return config.load().bind({}).then(function (config) {
|
||||
if (!config.server) {
|
||||
throw new Error('no server to connect to!')
|
||||
}
|
||||
|
||||
if (!config.token) {
|
||||
throw new Error('no token available')
|
||||
}
|
||||
|
||||
var xo = new Xo({ url: config.server })
|
||||
|
||||
return xo.open().then(function () {
|
||||
return xo.signIn({ token: config.token })
|
||||
}).then(function () {
|
||||
return xo
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function _startsWith (string, search) {
|
||||
return string.lastIndexOf(search, 0) === 0
|
||||
}
|
||||
|
||||
var FLAG_RE = /^--([^=]+)(?:=([^]*))?$/
|
||||
function extractFlags (args) {
|
||||
var flags = {}
|
||||
|
||||
var i = 0
|
||||
var n = args.length
|
||||
var matches
|
||||
while (i < n && (matches = args[i].match(FLAG_RE))) {
|
||||
var value = matches[2]
|
||||
|
||||
flags[matches[1]] = value === undefined ? true : value
|
||||
++i
|
||||
}
|
||||
args.splice(0, i)
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
var PARAM_RE = /^([^=]+)=([^]*)$/
|
||||
function parseParameters (args) {
|
||||
var params = {}
|
||||
forEach(args, function (arg) {
|
||||
var matches
|
||||
if (!(matches = arg.match(PARAM_RE))) {
|
||||
throw new Error('invalid arg: ' + arg)
|
||||
}
|
||||
var name = matches[1]
|
||||
var value = matches[2]
|
||||
|
||||
if (_startsWith(value, 'json:')) {
|
||||
value = JSON.parse(value.slice(5))
|
||||
}
|
||||
|
||||
if (name === '@') {
|
||||
params['@'] = value
|
||||
return
|
||||
}
|
||||
|
||||
if (value === 'true') {
|
||||
value = true
|
||||
} else if (value === 'false') {
|
||||
value = false
|
||||
}
|
||||
|
||||
params[name] = value
|
||||
})
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
var humanFormatOpts = {
|
||||
unit: 'B',
|
||||
scale: 'binary'
|
||||
}
|
||||
|
||||
function printProgress (progress) {
|
||||
if (progress.length) {
|
||||
console.warn('%s% of %s @ %s/s - ETA %s',
|
||||
Math.round(progress.percentage),
|
||||
humanFormat(progress.length, humanFormatOpts),
|
||||
humanFormat(progress.speed, humanFormatOpts),
|
||||
prettyMs(progress.eta * 1e3)
|
||||
)
|
||||
} else {
|
||||
console.warn('%s @ %s/s',
|
||||
humanFormat(progress.transferred, humanFormatOpts),
|
||||
humanFormat(progress.speed, humanFormatOpts)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function wrap (val) {
|
||||
return function wrappedValue () {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var help = wrap((function (pkg) {
|
||||
return multiline.stripIndent(function () { /*
|
||||
Usage:
|
||||
|
||||
$name --register [<XO-Server URL>] [<username>] [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
$name --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
$name --list-commands [--json] [<pattern>]...
|
||||
Returns the list of available commands on the current XO instance.
|
||||
|
||||
The patterns can be used to filter on command names.
|
||||
|
||||
$name --list-objects [--<property>]… [<property>=<value>]...
|
||||
Returns a list of XO objects.
|
||||
|
||||
--<property>
|
||||
Restricts displayed properties to those listed.
|
||||
|
||||
<property>=<value>
|
||||
Restricted displayed objects to those matching the patterns.
|
||||
|
||||
$name <command> [<name>=<value>]...
|
||||
Executes a command on the current XO instance.
|
||||
|
||||
$name v$version
|
||||
*/ }).replace(/<([^>]+)>|\$(\w+)/g, function (_, arg, key) {
|
||||
if (arg) {
|
||||
return '<' + chalk.yellow(arg) + '>'
|
||||
}
|
||||
|
||||
if (key === 'name') {
|
||||
return chalk.bold(pkg[key])
|
||||
}
|
||||
|
||||
return pkg[key]
|
||||
})
|
||||
})(require('./package')))
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function main (args) {
|
||||
if (!args || !args.length || args[0] === '-h') {
|
||||
return help()
|
||||
}
|
||||
|
||||
var fnName = args[0].replace(/^--|-\w/g, function (match) {
|
||||
if (match === '--') {
|
||||
return ''
|
||||
}
|
||||
|
||||
return match[1].toUpperCase()
|
||||
})
|
||||
if (fnName in exports) {
|
||||
return exports[fnName](args.slice(1))
|
||||
}
|
||||
|
||||
return exports.call(args)
|
||||
}
|
||||
exports = module.exports = main
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
exports.help = help
|
||||
|
||||
function register (args) {
|
||||
var xo = new Xo({ url: args[0] })
|
||||
return xo.open().then(function () {
|
||||
return xo.signIn({
|
||||
email: args[1],
|
||||
password: args[2]
|
||||
})
|
||||
}).then(function () {
|
||||
console.log('Successfully logged with', xo.user.email)
|
||||
|
||||
return xo.call('token.create')
|
||||
}).then(function (token) {
|
||||
return config.set({
|
||||
server: args[0],
|
||||
token: token
|
||||
})
|
||||
})
|
||||
}
|
||||
exports.register = register
|
||||
|
||||
function unregister () {
|
||||
return config.unset([
|
||||
'server',
|
||||
'token'
|
||||
])
|
||||
}
|
||||
exports.unregister = unregister
|
||||
|
||||
function listCommands (args) {
|
||||
return connect().then(function getMethodsInfo (xo) {
|
||||
return xo.call('system.getMethodsInfo')
|
||||
}).then(function formatMethodsInfo (methods) {
|
||||
var json = false
|
||||
var patterns = []
|
||||
forEach(args, function (arg) {
|
||||
if (arg === '--json') {
|
||||
json = true
|
||||
} else {
|
||||
patterns.push(arg)
|
||||
}
|
||||
})
|
||||
|
||||
if (patterns.length) {
|
||||
methods = pick(methods, micromatch(Object.keys(methods), patterns))
|
||||
}
|
||||
|
||||
if (json) {
|
||||
return methods
|
||||
}
|
||||
|
||||
methods = pairs(methods)
|
||||
methods.sort(function (a, b) {
|
||||
a = a[0]
|
||||
b = b[0]
|
||||
if (a < b) {
|
||||
return -1
|
||||
}
|
||||
return +(a > b)
|
||||
})
|
||||
|
||||
var str = []
|
||||
forEach(methods, function (method) {
|
||||
var name = method[0]
|
||||
var info = method[1]
|
||||
str.push(chalk.bold.blue(name))
|
||||
forEach(info.params || [], function (info, name) {
|
||||
str.push(' ')
|
||||
if (info.optional) {
|
||||
str.push('[')
|
||||
}
|
||||
str.push(name, '=<', info.type || 'unknown', '>')
|
||||
if (info.optional) {
|
||||
str.push(']')
|
||||
}
|
||||
})
|
||||
str.push('\n')
|
||||
if (info.description) {
|
||||
str.push(' ', info.description, '\n')
|
||||
}
|
||||
})
|
||||
return str.join('')
|
||||
})
|
||||
}
|
||||
exports.listCommands = listCommands
|
||||
|
||||
function listObjects (args) {
|
||||
var properties = getKeys(extractFlags(args))
|
||||
var filterProperties = properties.length
|
||||
? function (object) {
|
||||
return pick(object, properties)
|
||||
}
|
||||
: identity
|
||||
|
||||
var sieve = args.length ? parseParameters(args) : null
|
||||
|
||||
return connect().then(function getXoObjects (xo) {
|
||||
return xo.call('xo.getAllObjects')
|
||||
}).then(function filterObjects (objects) {
|
||||
objects = filter(objects, sieve)
|
||||
|
||||
const stdout = process.stdout
|
||||
stdout.write('[\n')
|
||||
for (var i = 0, n = objects.length; i < n;) {
|
||||
stdout.write(JSON.stringify(filterProperties(objects[i]), null, 2))
|
||||
stdout.write(++i < n ? ',\n' : '\n')
|
||||
}
|
||||
stdout.write(']')
|
||||
})
|
||||
}
|
||||
exports.listObjects = listObjects
|
||||
|
||||
function call (args) {
|
||||
if (!args.length) {
|
||||
throw new Error('missing command name')
|
||||
}
|
||||
|
||||
var method = args.shift()
|
||||
var params = parseParameters(args)
|
||||
|
||||
var file = params['@']
|
||||
delete params['@']
|
||||
|
||||
var baseUrl
|
||||
return connect().then(function (xo) {
|
||||
// FIXME: do not use private properties.
|
||||
baseUrl = xo._url.replace(/^ws/, 'http')
|
||||
|
||||
return xo.call(method, params)
|
||||
}).then(function handleResult (result) {
|
||||
var keys, key, url
|
||||
if (
|
||||
isObject(result) &&
|
||||
(keys = getKeys(result)).length === 1
|
||||
) {
|
||||
key = keys[0]
|
||||
|
||||
if (key === '$getFrom') {
|
||||
url = resolveUrl(baseUrl, result[key])
|
||||
var output = createWriteStream(file)
|
||||
|
||||
var progress = progressStream({ time: 1e3 }, printProgress)
|
||||
|
||||
return eventToPromise(nicePipe([
|
||||
got.stream(url).on('response', function (response) {
|
||||
var length = response.headers['content-length']
|
||||
if (length) {
|
||||
progress.length(length)
|
||||
}
|
||||
}),
|
||||
progress,
|
||||
output
|
||||
]), 'finish')
|
||||
}
|
||||
|
||||
if (key === '$sendTo') {
|
||||
url = resolveUrl(baseUrl, result[key])
|
||||
|
||||
return stat(file).then(function (stats) {
|
||||
var length = stats.size
|
||||
|
||||
var input = nicePipe([
|
||||
createReadStream(file),
|
||||
progressStream({
|
||||
length: length,
|
||||
time: 1e3
|
||||
}, printProgress)
|
||||
])
|
||||
|
||||
return got.post(url, {
|
||||
body: input,
|
||||
headers: {
|
||||
'content-length': length
|
||||
},
|
||||
method: 'POST'
|
||||
}).then(function (response) {
|
||||
return response.body
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
}
|
||||
exports.call = call
|
||||
|
||||
// ===================================================================
|
||||
|
||||
if (!module.parent) {
|
||||
require('exec-promise')(exports)
|
||||
}
|
57
packages/xo-cli/package.json
Normal file
57
packages/xo-cli/package.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "xo-cli",
|
||||
"version": "0.8.2",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Basic CLI for Xen-Orchestra",
|
||||
"keywords": [
|
||||
"xo",
|
||||
"xen-orchestra",
|
||||
"xen",
|
||||
"orchestra"
|
||||
],
|
||||
"homepage": "https://github.com/vatesfr/xo-cli",
|
||||
"bugs": "https://github.com/vatesfr/xo-cli/issues",
|
||||
"author": "Julien Fontanet <julien.fontanet@vates.fr>",
|
||||
"preferGlobal": true,
|
||||
"bin": {
|
||||
"xo-cli": "index.js"
|
||||
},
|
||||
"files": [
|
||||
"*.js"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xo-cli"
|
||||
},
|
||||
"dependencies": {
|
||||
"bluebird": "^3.4.6",
|
||||
"chalk": "^1.1.1",
|
||||
"event-to-promise": "^0.7.0",
|
||||
"exec-promise": "^0.6.1",
|
||||
"fs-promise": "^1.0.0",
|
||||
"got": "^6.5.0",
|
||||
"human-format": "^0.7.0",
|
||||
"l33teral": "^3.0.2",
|
||||
"lodash": "^4.16.4",
|
||||
"micromatch": "^2.2.0",
|
||||
"mkdirp": "^0.5.0",
|
||||
"multiline": "^1.0.2",
|
||||
"nice-pipe": "0.0.0",
|
||||
"pretty-ms": "^2.1.0",
|
||||
"progress-stream": "^1.1.1",
|
||||
"xdg-basedir": "^2.0.0",
|
||||
"xo-lib": "^0.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^8.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard",
|
||||
"posttest": "npm run lint"
|
||||
},
|
||||
"greenkeeper": {
|
||||
"ignore": [
|
||||
"nice-pipe"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user