feat: use ESLint instead of standard (#630)

This commit is contained in:
Julien Fontanet 2017-12-15 14:18:47 +01:00 committed by GitHub
parent d2f88d0a02
commit 4905a0310a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
98 changed files with 1275 additions and 1430 deletions

15
.eslintrc.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
extends: [
'standard',
],
parser: 'babel-eslint',
rules: {
'comma-dangle': ['error', 'always-multiline'],
'no-var': 'error',
'node/no-extraneous-import': 'error',
'node/no-extraneous-require': 'error',
'node/no-missing-require': 'error',
'node/no-missing-import': 'error',
'prefer-const': 'error',
},
}

View File

@ -2,11 +2,11 @@ Error.stackTraceLimit = 100
// Removes internal modules. // Removes internal modules.
try { try {
var sep = require('path').sep const sep = require('path').sep
require('stack-chain').filter.attach(function (_, frames) { require('stack-chain').filter.attach(function (_, frames) {
var filtered = frames.filter(function (frame) { const filtered = frames.filter(function (frame) {
var name = frame && frame.getFileName() const name = frame && frame.getFileName()
return ( return (
// has a filename // has a filename

View File

@ -2,23 +2,23 @@
// =================================================================== // ===================================================================
var gulp = require('gulp') const gulp = require('gulp')
var babel = require('gulp-babel') const babel = require('gulp-babel')
var coffee = require('gulp-coffee') const coffee = require('gulp-coffee')
var plumber = require('gulp-plumber') const plumber = require('gulp-plumber')
var rimraf = require('rimraf') const rimraf = require('rimraf')
var sourceMaps = require('gulp-sourcemaps') const sourceMaps = require('gulp-sourcemaps')
var watch = require('gulp-watch') const watch = require('gulp-watch')
var join = require('path').join const join = require('path').join
// =================================================================== // ===================================================================
var SRC_DIR = join(__dirname, 'src') const SRC_DIR = join(__dirname, 'src')
var DIST_DIR = join(__dirname, 'dist') const DIST_DIR = join(__dirname, 'dist')
var PRODUCTION = process.argv.indexOf('--production') !== -1 const PRODUCTION = process.argv.indexOf('--production') !== -1
// =================================================================== // ===================================================================
@ -26,13 +26,13 @@ function src (patterns) {
return PRODUCTION return PRODUCTION
? gulp.src(patterns, { ? gulp.src(patterns, {
base: SRC_DIR, base: SRC_DIR,
cwd: SRC_DIR cwd: SRC_DIR,
}) })
: watch(patterns, { : watch(patterns, {
base: SRC_DIR, base: SRC_DIR,
cwd: SRC_DIR, cwd: SRC_DIR,
ignoreInitial: false, ignoreInitial: false,
verbose: true verbose: true,
}) })
.pipe(plumber()) .pipe(plumber())
} }
@ -47,7 +47,7 @@ gulp.task(function buildCoffee () {
return src('**/*.coffee') return src('**/*.coffee')
.pipe(sourceMaps.init()) .pipe(sourceMaps.init())
.pipe(coffee({ .pipe(coffee({
bare: true bare: true,
})) }))
// Necessary to correctly compile generators. // Necessary to correctly compile generators.

View File

@ -8,4 +8,4 @@ if (process.env.DEBUG === undefined) {
} }
// Import the real main module. // Import the real main module.
module.exports = require('./dist').default module.exports = require('./dist').default // eslint-disable-line node/no-missing-require

View File

@ -125,6 +125,12 @@
"babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1", "babel-preset-env": "^1.6.1",
"babel-preset-stage-0": "^6.24.1", "babel-preset-stage-0": "^6.24.1",
"eslint": "^4.13.1",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"gulp": "git://github.com/gulpjs/gulp#4.0", "gulp": "git://github.com/gulpjs/gulp#4.0",
"gulp-babel": "^7.0.0", "gulp-babel": "^7.0.0",
"gulp-coffee": "^2.3.4", "gulp-coffee": "^2.3.4",
@ -134,18 +140,17 @@
"husky": "^0.14.3", "husky": "^0.14.3",
"index-modules": "^0.3.0", "index-modules": "^0.3.0",
"jest": "^21.2.1", "jest": "^21.2.1",
"rimraf": "^2.6.2", "rimraf": "^2.6.2"
"standard": "^10.0.3"
}, },
"scripts": { "scripts": {
"build": "gulp build --production", "build": "gulp build --production",
"commitmsg": "yarn run test", "commitmsg": "yarn run test",
"dev": "gulp build", "dev": "gulp build",
"dev-test": "jest --bail --watch", "dev-test": "jest --bail --watch",
"posttest": "standard",
"prebuild": "index-modules src/api src/xapi/mixins src/xo-mixins", "prebuild": "index-modules src/api src/xapi/mixins src/xo-mixins",
"predev": "yarn run prebuild", "predev": "yarn run prebuild",
"prepublishOnly": "yarn run build", "prepublishOnly": "yarn run build",
"pretest": "eslint --ignore-path .gitignore --fix .",
"start": "node bin/xo-server", "start": "node bin/xo-server",
"test": "jest" "test": "jest"
}, },
@ -172,11 +177,5 @@
"<rootDir>/src" "<rootDir>/src"
], ],
"testRegex": "\\.spec\\.js$" "testRegex": "\\.spec\\.js$"
},
"standard": {
"ignore": [
"dist"
],
"parser": "babel-eslint"
} }
} }

View File

@ -27,7 +27,7 @@ add.permission = 'admin'
add.params = { add.params = {
subject: { type: 'string' }, subject: { type: 'string' },
object: { type: 'string' }, object: { type: 'string' },
action: { type: 'string' } action: { type: 'string' },
} }
add.description = 'add a new ACL entry' add.description = 'add a new ACL entry'
@ -43,7 +43,7 @@ remove.permission = 'admin'
remove.params = { remove.params = {
subject: { type: 'string' }, subject: { type: 'string' },
object: { type: 'string' }, object: { type: 'string' },
action: { type: 'string' } action: { type: 'string' },
} }
remove.description = 'remove an existing ACL entry' remove.description = 'remove an existing ACL entry'

View File

@ -11,7 +11,7 @@ export function list ({ remote }) {
list.permission = 'admin' list.permission = 'admin'
list.params = { list.params = {
remote: { type: 'string' } remote: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -23,7 +23,7 @@ export function scanDisk ({ remote, disk }) {
scanDisk.permission = 'admin' scanDisk.permission = 'admin'
scanDisk.params = { scanDisk.params = {
remote: { type: 'string' }, remote: { type: 'string' },
disk: { type: 'string' } disk: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -37,7 +37,7 @@ scanFiles.params = {
remote: { type: 'string' }, remote: { type: 'string' },
disk: { type: 'string' }, disk: { type: 'string' },
partition: { type: 'string', optional: true }, partition: { type: 'string', optional: true },
path: { type: 'string' } path: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -80,7 +80,7 @@ export async function fetchFiles ({ format = 'zip', ...params }) {
: basename(params.paths[0]) : basename(params.paths[0])
return this.registerHttpRequest(handleFetchFiles, { ...params, format }, { return this.registerHttpRequest(handleFetchFiles, { ...params, format }, {
suffix: encodeURI(`/${fileName}`) suffix: encodeURI(`/${fileName}`),
}).then(url => ({ $getFrom: url })) }).then(url => ({ $getFrom: url }))
} }
@ -93,6 +93,6 @@ fetchFiles.params = {
paths: { paths: {
type: 'array', type: 'array',
items: { type: 'string' }, items: { type: 'string' },
minLength: 1 minLength: 1,
} },
} }

View File

@ -17,14 +17,14 @@ export async function create ({ name, size, sr, vm, bootable, position, mode })
const xapi = this.getXapi(sr) const xapi = this.getXapi(sr)
const vdi = await xapi.createVdi(parseSize(size), { const vdi = await xapi.createVdi(parseSize(size), {
name_label: name, name_label: name,
sr: sr._xapiId sr: sr._xapiId,
}) })
if (attach) { if (attach) {
await xapi.attachVdiToVm(vdi.$id, vm._xapiId, { await xapi.attachVdiToVm(vdi.$id, vm._xapiId, {
bootable, bootable,
position, position,
readOnly: mode === 'RO' readOnly: mode === 'RO',
}) })
} }
@ -40,12 +40,12 @@ create.params = {
vm: { type: 'string', optional: true }, vm: { type: 'string', optional: true },
bootable: { type: 'boolean', optional: true }, bootable: { type: 'boolean', optional: true },
mode: { type: 'string', optional: true }, mode: { type: 'string', optional: true },
position: { type: 'string', optional: true } position: { type: 'string', optional: true },
} }
create.resolve = { create.resolve = {
vm: ['vm', 'VM', 'administrate'], vm: ['vm', 'VM', 'administrate'],
sr: ['sr', 'SR', false] sr: ['sr', 'SR', false],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -58,9 +58,9 @@ resize.description = 'resize an existing VDI'
resize.params = { resize.params = {
id: { type: 'string' }, id: { type: 'string' },
size: { type: ['integer', 'string'] } size: { type: ['integer', 'string'] },
} }
resize.resolve = { resize.resolve = {
vdi: ['id', ['VDI', 'VDI-snapshot'], 'administrate'] vdi: ['id', ['VDI', 'VDI-snapshot'], 'administrate'],
} }

View File

@ -4,11 +4,11 @@ export async function register ({vm}) {
register.description = 'Register the VM for Docker management' register.description = 'Register the VM for Docker management'
register.params = { register.params = {
vm: { type: 'string' } vm: { type: 'string' },
} }
register.resolve = { register.resolve = {
vm: ['vm', 'VM', 'administrate'] vm: ['vm', 'VM', 'administrate'],
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -19,11 +19,11 @@ export async function deregister ({vm}) {
deregister.description = 'Deregister the VM for Docker management' deregister.description = 'Deregister the VM for Docker management'
deregister.params = { deregister.params = {
vm: { type: 'string' } vm: { type: 'string' },
} }
deregister.resolve = { deregister.resolve = {
vm: ['vm', 'VM', 'administrate'] vm: ['vm', 'VM', 'administrate'],
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -48,13 +48,13 @@ export async function unpause ({vm, container}) {
await this.getXapi(vm).unpauseDockerContainer(vm._xapiId, container) await this.getXapi(vm).unpauseDockerContainer(vm._xapiId, container)
} }
for (let fn of [start, stop, restart, pause, unpause]) { for (const fn of [start, stop, restart, pause, unpause]) {
fn.params = { fn.params = {
vm: { type: 'string' }, vm: { type: 'string' },
container: { type: 'string' } container: { type: 'string' },
} }
fn.resolve = { fn.resolve = {
vm: ['vm', 'VM', 'operate'] vm: ['vm', 'VM', 'operate'],
} }
} }

View File

@ -5,7 +5,7 @@ export async function create ({name}) {
create.description = 'creates a new group' create.description = 'creates a new group'
create.permission = 'admin' create.permission = 'admin'
create.params = { create.params = {
name: {type: 'string'} name: {type: 'string'},
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -21,7 +21,7 @@ export {delete_ as delete}
delete_.description = 'deletes an existing group' delete_.description = 'deletes an existing group'
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.params = { delete_.params = {
id: {type: 'string'} id: {type: 'string'},
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -44,7 +44,7 @@ setUsers.description = 'sets the users belonging to a group'
setUsers.permission = 'admin' setUsers.permission = 'admin'
setUsers.params = { setUsers.params = {
id: {type: 'string'}, id: {type: 'string'},
userIds: {} userIds: {},
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -58,7 +58,7 @@ addUser.description = 'adds a user to a group'
addUser.permission = 'admin' addUser.permission = 'admin'
addUser.params = { addUser.params = {
id: {type: 'string'}, id: {type: 'string'},
userId: {type: 'string'} userId: {type: 'string'},
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -74,7 +74,7 @@ removeUser.description = 'removes a user from a group'
removeUser.permission = 'admin' removeUser.permission = 'admin'
removeUser.params = { removeUser.params = {
id: {type: 'string'}, id: {type: 'string'},
userId: {type: 'string'} userId: {type: 'string'},
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -87,5 +87,5 @@ set.description = 'changes the properties of an existing group'
set.permission = 'admin' set.permission = 'admin'
set.params = { set.params = {
id: { type: 'string' }, id: { type: 'string' },
name: { type: 'string', optional: true } name: { type: 'string', optional: true },
} }

View File

@ -14,7 +14,7 @@ export async function get (id) {
get.permission = 'admin' get.permission = 'admin'
get.description = 'Gets an existing job' get.description = 'Gets an existing job'
get.params = { get.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function create ({job}) { export async function create ({job}) {
@ -44,14 +44,14 @@ create.params = {
items: { items: {
type: 'array', type: 'array',
items: { items: {
type: 'object' type: 'object',
} },
} },
}, },
optional: true optional: true,
} },
} },
} },
} }
export async function set ({job}) { export async function set ({job}) {
@ -77,14 +77,14 @@ set.params = {
items: { items: {
type: 'array', type: 'array',
items: { items: {
type: 'object' type: 'object',
} },
} },
}, },
optional: true optional: true,
} },
} },
} },
} }
async function delete_ ({id}) { async function delete_ ({id}) {
@ -94,7 +94,7 @@ async function delete_ ({id}) {
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.description = 'Deletes an existing job' delete_.description = 'Deletes an existing job'
delete_.params = { delete_.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export {delete_ as delete} export {delete_ as delete}
@ -106,5 +106,5 @@ export async function runSequence ({idSequence}) {
runSequence.permission = 'admin' runSequence.permission = 'admin'
runSequence.description = 'Runs jobs sequentially, in the provided order' runSequence.description = 'Runs jobs sequentially, in the provided order'
runSequence.params = { runSequence.params = {
idSequence: {type: 'array', items: {type: 'string'}} idSequence: {type: 'array', items: {type: 'string'}},
} }

View File

@ -17,7 +17,7 @@ export async function get ({namespace}) {
get.description = 'returns logs list for one namespace' get.description = 'returns logs list for one namespace'
get.params = { get.params = {
namespace: { type: 'string' } namespace: { type: 'string' },
} }
get.permission = 'admin' get.permission = 'admin'
@ -31,7 +31,7 @@ async function delete_ ({namespace, id}) {
delete_.description = 'deletes one or several logs from a namespace' delete_.description = 'deletes one or several logs from a namespace'
delete_.params = { delete_.params = {
id: { type: [ 'array', 'string' ] }, id: { type: [ 'array', 'string' ] },
namespace: { type: 'string' } namespace: { type: 'string' },
} }
delete_.permission = 'admin' delete_.permission = 'admin'

View File

@ -4,9 +4,9 @@ async function delete_ ({ message }) {
export {delete_ as delete} export {delete_ as delete}
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
delete_.resolve = { delete_.resolve = {
message: ['id', 'message', 'administrate'] message: ['id', 'message', 'administrate'],
} }

View File

@ -10,7 +10,7 @@ export async function create ({ pool, name, description, pif, mtu = 1500, vlan =
description, description,
pifId: pif && this.getObject(pif, 'PIF')._xapiId, pifId: pif && this.getObject(pif, 'PIF')._xapiId,
mtu: +mtu, mtu: +mtu,
vlan: +vlan vlan: +vlan,
}) })
} }
@ -20,11 +20,11 @@ create.params = {
description: { type: 'string', optional: true }, description: { type: 'string', optional: true },
pif: { type: 'string', optional: true }, pif: { type: 'string', optional: true },
mtu: { type: ['integer', 'string'], optional: true }, mtu: { type: ['integer', 'string'], optional: true },
vlan: { type: ['integer', 'string'], optional: true } vlan: { type: ['integer', 'string'], optional: true },
} }
create.resolve = { create.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
create.permission = 'admin' create.permission = 'admin'
@ -39,7 +39,7 @@ export async function createBonded ({ pool, name, description, pifs, mtu = 1500,
), ),
mtu: +mtu, mtu: +mtu,
mac, mac,
bondMode bondMode,
}) })
} }
@ -50,17 +50,17 @@ createBonded.params = {
pifs: { pifs: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
} },
}, },
mtu: { type: ['integer', 'string'], optional: true }, mtu: { type: ['integer', 'string'], optional: true },
mac: { type: 'string', optional: true }, mac: { type: 'string', optional: true },
// RegExp since schema-inspector does not provide a param check based on an enumeration // RegExp since schema-inspector does not provide a param check based on an enumeration
bondMode: { type: 'string', pattern: new RegExp(`^(${getBondModes().join('|')})$`) } bondMode: { type: 'string', pattern: new RegExp(`^(${getBondModes().join('|')})$`) },
} }
createBonded.resolve = { createBonded.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
createBonded.permission = 'admin' createBonded.permission = 'admin'
createBonded.description = 'Create a bonded network. bondMode can be balance-slb, active-backup or lacp' createBonded.description = 'Create a bonded network. bondMode can be balance-slb, active-backup or lacp'
@ -73,35 +73,35 @@ export async function set ({
name_description: nameDescription, name_description: nameDescription,
name_label: nameLabel, name_label: nameLabel,
defaultIsLocked, defaultIsLocked,
id id,
}) { }) {
await this.getXapi(network).setNetworkProperties(network._xapiId, { await this.getXapi(network).setNetworkProperties(network._xapiId, {
nameDescription, nameDescription,
nameLabel, nameLabel,
defaultIsLocked defaultIsLocked,
}) })
} }
set.params = { set.params = {
id: { id: {
type: 'string' type: 'string',
}, },
name_label: { name_label: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
name_description: { name_description: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
defaultIsLocked: { defaultIsLocked: {
type: 'boolean', type: 'boolean',
optional: true optional: true,
} },
} }
set.resolve = { set.resolve = {
network: ['id', 'network', 'administrate'] network: ['id', 'network', 'administrate'],
} }
// ================================================================= // =================================================================
@ -112,9 +112,9 @@ export async function delete_ ({ network }) {
export {delete_ as delete} export {delete_ as delete}
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
delete_.resolve = { delete_.resolve = {
network: ['id', 'network', 'administrate'] network: ['id', 'network', 'administrate'],
} }

View File

@ -10,11 +10,11 @@ async function delete_ ({PBD}) {
export {delete_ as delete} export {delete_ as delete}
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
delete_.resolve = { delete_.resolve = {
PBD: ['id', 'PBD', 'administrate'] PBD: ['id', 'PBD', 'administrate'],
} }
// =================================================================== // ===================================================================
@ -25,11 +25,11 @@ export async function disconnect ({ pbd }) {
} }
disconnect.params = { disconnect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
disconnect.resolve = { disconnect.resolve = {
pbd: ['id', 'PBD', 'administrate'] pbd: ['id', 'PBD', 'administrate'],
} }
// =================================================================== // ===================================================================
@ -41,9 +41,9 @@ export async function connect ({PBD}) {
} }
connect.params = { connect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
connect.resolve = { connect.resolve = {
PBD: ['id', 'PBD', 'administrate'] PBD: ['id', 'PBD', 'administrate'],
} }

View File

@ -20,11 +20,11 @@ async function delete_ ({pif}) {
export {delete_ as delete} export {delete_ as delete}
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
delete_.resolve = { delete_.resolve = {
pif: ['id', 'PIF', 'administrate'] pif: ['id', 'PIF', 'administrate'],
} }
// =================================================================== // ===================================================================
@ -36,11 +36,11 @@ export async function disconnect ({pif}) {
} }
disconnect.params = { disconnect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
disconnect.resolve = { disconnect.resolve = {
pif: ['id', 'PIF', 'administrate'] pif: ['id', 'PIF', 'administrate'],
} }
// =================================================================== // ===================================================================
// Connect // Connect
@ -51,11 +51,11 @@ export async function connect ({pif}) {
} }
connect.params = { connect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
connect.resolve = { connect.resolve = {
pif: ['id', 'PIF', 'administrate'] pif: ['id', 'PIF', 'administrate'],
} }
// =================================================================== // ===================================================================
// Reconfigure IP // Reconfigure IP
@ -70,11 +70,11 @@ reconfigureIp.params = {
ip: { type: 'string', optional: true }, ip: { type: 'string', optional: true },
netmask: { type: 'string', optional: true }, netmask: { type: 'string', optional: true },
gateway: { type: 'string', optional: true }, gateway: { type: 'string', optional: true },
dns: { type: 'string', optional: true } dns: { type: 'string', optional: true },
} }
reconfigureIp.resolve = { reconfigureIp.resolve = {
pif: ['id', 'PIF', 'administrate'] pif: ['id', 'PIF', 'administrate'],
} }
// =================================================================== // ===================================================================
@ -85,9 +85,9 @@ export async function editPif ({ pif, vlan }) {
editPif.params = { editPif.params = {
id: { type: 'string' }, id: { type: 'string' },
vlan: { type: ['integer', 'string'] } vlan: { type: ['integer', 'string'] },
} }
editPif.resolve = { editPif.resolve = {
pif: ['id', 'PIF', 'administrate'] pif: ['id', 'PIF', 'administrate'],
} }

View File

@ -16,9 +16,9 @@ configure.description = 'sets the configuration of a plugin'
configure.params = { configure.params = {
id: { id: {
type: 'string' type: 'string',
}, },
configuration: {} configuration: {},
} }
configure.permission = 'admin' configure.permission = 'admin'
@ -33,8 +33,8 @@ disableAutoload.description = ''
disableAutoload.params = { disableAutoload.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
disableAutoload.permission = 'admin' disableAutoload.permission = 'admin'
@ -49,8 +49,8 @@ enableAutoload.description = 'enables a plugin, allowing it to be loaded'
enableAutoload.params = { enableAutoload.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
enableAutoload.permission = 'admin' enableAutoload.permission = 'admin'
@ -65,8 +65,8 @@ load.description = 'loads a plugin'
load.params = { load.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
load.permission = 'admin' load.permission = 'admin'
@ -81,8 +81,8 @@ unload.description = 'unloads a plugin'
unload.params = { unload.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
unload.permission = 'admin' unload.permission = 'admin'
@ -97,8 +97,8 @@ purgeConfiguration.description = 'removes a plugin configuration'
purgeConfiguration.params = { purgeConfiguration.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
purgeConfiguration.permission = 'admin' purgeConfiguration.permission = 'admin'
@ -113,11 +113,11 @@ test.description = 'Test a plugin with its current configuration'
test.params = { test.params = {
id: { id: {
type: 'string' type: 'string',
}, },
data: { data: {
optional: true optional: true,
} },
} }
test.permission = 'admin' test.permission = 'admin'

View File

@ -9,30 +9,30 @@ export async function set ({
// TODO: use camel case. // TODO: use camel case.
name_description: nameDescription, name_description: nameDescription,
name_label: nameLabel name_label: nameLabel,
}) { }) {
await this.getXapi(pool).setPoolProperties({ await this.getXapi(pool).setPoolProperties({
nameDescription, nameDescription,
nameLabel nameLabel,
}) })
} }
set.params = { set.params = {
id: { id: {
type: 'string' type: 'string',
}, },
name_label: { name_label: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
name_description: { name_description: {
type: 'string', type: 'string',
optional: true optional: true,
} },
} }
set.resolve = { set.resolve = {
pool: ['id', 'pool', 'administrate'] pool: ['id', 'pool', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -47,12 +47,12 @@ setDefaultSr.permission = '' // signed in
setDefaultSr.params = { setDefaultSr.params = {
sr: { sr: {
type: 'string' type: 'string',
} },
} }
setDefaultSr.resolve = { setDefaultSr.resolve = {
sr: ['sr', 'SR'] sr: ['sr', 'SR'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -65,12 +65,12 @@ export async function setPoolMaster ({ host }) {
setPoolMaster.params = { setPoolMaster.params = {
host: { host: {
type: 'string' type: 'string',
} },
} }
setPoolMaster.resolve = { setPoolMaster.resolve = {
host: ['host', 'host'] host: ['host', 'host'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -81,15 +81,15 @@ export async function installPatch ({pool, patch: patchUuid}) {
installPatch.params = { installPatch.params = {
pool: { pool: {
type: 'string' type: 'string',
}, },
patch: { patch: {
type: 'string' type: 'string',
} },
} }
installPatch.resolve = { installPatch.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -99,12 +99,12 @@ export async function installAllPatches ({ pool }) {
installAllPatches.params = { installAllPatches.params = {
pool: { pool: {
type: 'string' type: 'string',
} },
} }
installAllPatches.resolve = { installAllPatches.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
installAllPatches.description = 'Install automatically all patches for every hosts of a pool' installAllPatches.description = 'Install automatically all patches for every hosts of a pool'
@ -124,16 +124,16 @@ async function handlePatchUpload (req, res, {pool}) {
export async function uploadPatch ({pool}) { export async function uploadPatch ({pool}) {
return { return {
$sendTo: await this.registerHttpRequest(handlePatchUpload, {pool}) $sendTo: await this.registerHttpRequest(handlePatchUpload, {pool}),
} }
} }
uploadPatch.params = { uploadPatch.params = {
pool: { type: 'string' } pool: { type: 'string' },
} }
uploadPatch.resolve = { uploadPatch.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
// Compatibility // Compatibility
@ -167,12 +167,12 @@ export async function mergeInto ({ source, target, force }) {
mergeInto.params = { mergeInto.params = {
force: { type: 'boolean', optional: true }, force: { type: 'boolean', optional: true },
source: { type: 'string' }, source: { type: 'string' },
target: { type: 'string' } target: { type: 'string' },
} }
mergeInto.resolve = { mergeInto.resolve = {
source: ['source', 'pool', 'administrate'], source: ['source', 'pool', 'administrate'],
target: ['target', 'pool', 'administrate'] target: ['target', 'pool', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -186,12 +186,12 @@ export async function getLicenseState ({pool}) {
getLicenseState.params = { getLicenseState.params = {
pool: { pool: {
type: 'string' type: 'string',
} },
} }
getLicenseState.resolve = { getLicenseState.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -215,16 +215,16 @@ async function handleInstallSupplementalPack (req, res, { poolId }) {
export async function installSupplementalPack ({ pool }) { export async function installSupplementalPack ({ pool }) {
return { return {
$sendTo: await this.registerHttpRequest(handleInstallSupplementalPack, { poolId: pool.id }) $sendTo: await this.registerHttpRequest(handleInstallSupplementalPack, { poolId: pool.id }),
} }
} }
installSupplementalPack.description = 'installs supplemental pack from ISO file on all hosts' installSupplementalPack.description = 'installs supplemental pack from ISO file on all hosts'
installSupplementalPack.params = { installSupplementalPack.params = {
pool: { type: 'string' } pool: { type: 'string' },
} }
installSupplementalPack.resolve = { installSupplementalPack.resolve = {
pool: ['pool', 'pool', 'admin'] pool: ['pool', 'pool', 'admin'],
} }

View File

@ -12,7 +12,7 @@ export async function get ({id}) {
get.permission = 'admin' get.permission = 'admin'
get.description = 'Gets an existing fs remote point' get.description = 'Gets an existing fs remote point'
get.params = { get.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function test ({id}) { export async function test ({id}) {
@ -22,7 +22,7 @@ export async function test ({id}) {
test.permission = 'admin' test.permission = 'admin'
test.description = 'Performs a read/write matching test on a remote point' test.description = 'Performs a read/write matching test on a remote point'
test.params = { test.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function list ({id}) { export async function list ({id}) {
@ -32,7 +32,7 @@ export async function list ({id}) {
list.permission = 'admin' list.permission = 'admin'
list.description = 'Lists the files found in a remote point' list.description = 'Lists the files found in a remote point'
list.params = { list.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function create ({name, url}) { export async function create ({name, url}) {
@ -43,7 +43,7 @@ create.permission = 'admin'
create.description = 'Creates a new fs remote point' create.description = 'Creates a new fs remote point'
create.params = { create.params = {
name: {type: 'string'}, name: {type: 'string'},
url: {type: 'string'} url: {type: 'string'},
} }
export async function set ({id, name, url, enabled}) { export async function set ({id, name, url, enabled}) {
@ -56,7 +56,7 @@ set.params = {
id: {type: 'string'}, id: {type: 'string'},
name: {type: 'string', optional: true}, name: {type: 'string', optional: true},
url: {type: 'string', optional: true}, url: {type: 'string', optional: true},
enabled: {type: 'boolean', optional: true} enabled: {type: 'boolean', optional: true},
} }
async function delete_ ({id}) { async function delete_ ({id}) {
@ -66,7 +66,7 @@ async function delete_ ({id}) {
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.description = 'Deletes an existing fs remote point' delete_.description = 'Deletes an existing fs remote point'
delete_.params = { delete_.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export {delete_ as delete} export {delete_ as delete}

View File

@ -1,5 +1,5 @@
import { import {
unauthorized unauthorized,
} from 'xo-common/api-errors' } from 'xo-common/api-errors'
// =================================================================== // ===================================================================
@ -12,26 +12,26 @@ create.permission = 'admin'
create.params = { create.params = {
name: { name: {
type: 'string' type: 'string',
}, },
subjects: { subjects: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
objects: { objects: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
limits: { limits: {
type: 'object', type: 'object',
optional: true optional: true,
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -45,8 +45,8 @@ delete_.permission = 'admin'
delete_.params = { delete_.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -57,7 +57,7 @@ export function set ({ id, name, subjects, objects, ipPools, limits }) {
name, name,
objects, objects,
ipPools, ipPools,
subjects subjects,
}) })
} }
@ -65,37 +65,37 @@ set.permission = 'admin'
set.params = { set.params = {
id: { id: {
type: 'string' type: 'string',
}, },
name: { name: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
subjects: { subjects: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
objects: { objects: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
ipPools: { ipPools: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
limits: { limits: {
type: 'object', type: 'object',
optional: true optional: true,
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -108,8 +108,8 @@ get.permission = 'admin'
get.params = { get.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -135,11 +135,11 @@ addObject.permission = 'admin'
addObject.params = { addObject.params = {
id: { id: {
type: 'string' type: 'string',
}, },
object: { object: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -152,11 +152,11 @@ removeObject.permission = 'admin'
removeObject.params = { removeObject.params = {
id: { id: {
type: 'string' type: 'string',
}, },
object: { object: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -169,11 +169,11 @@ addSubject.permission = 'admin'
addSubject.params = { addSubject.params = {
id: { id: {
type: 'string' type: 'string',
}, },
subject: { subject: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -186,11 +186,11 @@ removeSubject.permission = 'admin'
removeSubject.params = { removeSubject.params = {
id: { id: {
type: 'string' type: 'string',
}, },
subject: { subject: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -203,14 +203,14 @@ addLimit.permission = 'admin'
addLimit.params = { addLimit.params = {
id: { id: {
type: 'string' type: 'string',
}, },
limitId: { limitId: {
type: 'string' type: 'string',
}, },
quantity: { quantity: {
type: 'integer' type: 'integer',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -223,11 +223,11 @@ removeLimit.permission = 'admin'
removeLimit.params = { removeLimit.params = {
id: { id: {
type: 'string' type: 'string',
}, },
limitId: { limitId: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -14,7 +14,7 @@ export async function get (id) {
get.permission = 'admin' get.permission = 'admin'
get.description = 'Gets an existing schedule' get.description = 'Gets an existing schedule'
get.params = { get.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function create ({ jobId, cron, enabled, name, timezone }) { export async function create ({ jobId, cron, enabled, name, timezone }) {
@ -27,7 +27,7 @@ create.params = {
jobId: {type: 'string'}, jobId: {type: 'string'},
cron: {type: 'string'}, cron: {type: 'string'},
enabled: {type: 'boolean', optional: true}, enabled: {type: 'boolean', optional: true},
name: {type: 'string', optional: true} name: {type: 'string', optional: true},
} }
export async function set ({ id, jobId, cron, enabled, name, timezone }) { export async function set ({ id, jobId, cron, enabled, name, timezone }) {
@ -41,7 +41,7 @@ set.params = {
jobId: {type: 'string', optional: true}, jobId: {type: 'string', optional: true},
cron: {type: 'string', optional: true}, cron: {type: 'string', optional: true},
enabled: {type: 'boolean', optional: true}, enabled: {type: 'boolean', optional: true},
name: {type: 'string', optional: true} name: {type: 'string', optional: true},
} }
async function delete_ ({id}) { async function delete_ ({id}) {
@ -51,7 +51,7 @@ async function delete_ ({id}) {
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.description = 'Deletes an existing schedule' delete_.description = 'Deletes an existing schedule'
delete_.params = { delete_.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export {delete_ as delete} export {delete_ as delete}

View File

@ -7,7 +7,7 @@ export async function enable ({id}) {
enable.permission = 'admin' enable.permission = 'admin'
enable.description = 'Enables a schedule to run it\'s job as scheduled' enable.description = 'Enables a schedule to run it\'s job as scheduled'
enable.params = { enable.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export async function disable ({id}) { export async function disable ({id}) {
@ -19,7 +19,7 @@ export async function disable ({id}) {
disable.permission = 'admin' disable.permission = 'admin'
disable.description = 'Disables a schedule' disable.description = 'Disables a schedule'
disable.params = { disable.params = {
id: {type: 'string'} id: {type: 'string'},
} }
export function getScheduleTable () { export function getScheduleTable () {

View File

@ -17,25 +17,25 @@ add.permission = 'admin'
add.params = { add.params = {
label: { label: {
optional: true, optional: true,
type: 'string' type: 'string',
}, },
host: { host: {
type: 'string' type: 'string',
}, },
username: { username: {
type: 'string' type: 'string',
}, },
password: { password: {
type: 'string' type: 'string',
}, },
autoConnect: { autoConnect: {
optional: true, optional: true,
type: 'boolean' type: 'boolean',
}, },
allowUnauthorized: { allowUnauthorized: {
optional: true, optional: true,
type: 'boolean' type: 'boolean',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -50,8 +50,8 @@ remove.permission = 'admin'
remove.params = { remove.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -78,28 +78,28 @@ set.permission = 'admin'
set.params = { set.params = {
id: { id: {
type: 'string' type: 'string',
}, },
label: { label: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
host: { host: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
username: { username: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
password: { password: {
type: 'string', type: 'string',
optional: true optional: true,
}, },
allowUnauthorized: { allowUnauthorized: {
optional: true, optional: true,
type: 'boolean' type: 'boolean',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -115,8 +115,8 @@ connect.permission = 'admin'
connect.params = { connect.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -132,6 +132,6 @@ disconnect.permission = 'admin'
disconnect.params = { disconnect.params = {
id: { id: {
type: 'string' type: 'string',
} },
} }

View File

@ -23,7 +23,7 @@ export const signInWithPassword = deprecate(signIn, 'use session.signIn() instea
signInWithPassword.params = { signInWithPassword.params = {
email: { type: 'string' }, email: { type: 'string' },
password: { type: 'string' } password: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -31,7 +31,7 @@ signInWithPassword.params = {
export const signInWithToken = deprecate(signIn, 'use session.signIn() instead') export const signInWithToken = deprecate(signIn, 'use session.signIn() instead')
signInWithToken.params = { signInWithToken.params = {
token: { type: 'string' } token: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -5,7 +5,7 @@ import {
asyncMap, asyncMap,
ensureArray, ensureArray,
forEach, forEach,
parseXml parseXml,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -15,11 +15,11 @@ export async function set ({
// TODO: use camel case. // TODO: use camel case.
name_description: nameDescription, name_description: nameDescription,
name_label: nameLabel name_label: nameLabel,
}) { }) {
await this.getXapi(sr).setSrProperties(sr._xapiId, { await this.getXapi(sr).setSrProperties(sr._xapiId, {
nameDescription, nameDescription,
nameLabel nameLabel,
}) })
} }
@ -28,11 +28,11 @@ set.params = {
name_label: { type: 'string', optional: true }, name_label: { type: 'string', optional: true },
name_description: { type: 'string', optional: true } name_description: { type: 'string', optional: true },
} }
set.resolve = { set.resolve = {
sr: ['id', 'SR', 'operate'] sr: ['id', 'SR', 'operate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -42,11 +42,11 @@ export async function scan ({ SR }) {
} }
scan.params = { scan.params = {
id: { type: 'string' } id: { type: 'string' },
} }
scan.resolve = { scan.resolve = {
SR: ['id', 'SR', 'operate'] SR: ['id', 'SR', 'operate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -71,11 +71,11 @@ export async function destroy ({sr}) {
} }
destroy.params = { destroy.params = {
id: { type: 'string' } id: { type: 'string' },
} }
destroy.resolve = { destroy.resolve = {
sr: ['id', 'SR', 'administrate'] sr: ['id', 'SR', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -85,11 +85,11 @@ export async function forget ({ SR }) {
} }
forget.params = { forget.params = {
id: { type: 'string' } id: { type: 'string' },
} }
forget.resolve = { forget.resolve = {
SR: ['id', 'SR', 'administrate'] SR: ['id', 'SR', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -99,11 +99,11 @@ export async function connectAllPbds ({ SR }) {
} }
connectAllPbds.params = { connectAllPbds.params = {
id: { type: 'string' } id: { type: 'string' },
} }
connectAllPbds.resolve = { connectAllPbds.resolve = {
SR: ['id', 'SR', 'administrate'] SR: ['id', 'SR', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -113,11 +113,11 @@ export async function disconnectAllPbds ({ SR }) {
} }
disconnectAllPbds.params = { disconnectAllPbds.params = {
id: { type: 'string' } id: { type: 'string' },
} }
disconnectAllPbds.resolve = { disconnectAllPbds.resolve = {
SR: ['id', 'SR', 'administrate'] SR: ['id', 'SR', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -129,7 +129,7 @@ export async function createIso ({
path, path,
type, type,
user, user,
password password,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
@ -169,11 +169,11 @@ createIso.params = {
path: { type: 'string' }, path: { type: 'string' },
type: { type: 'string' }, type: { type: 'string' },
user: { type: 'string', optional: true }, user: { type: 'string', optional: true },
password: { type: 'string', optional: true } password: { type: 'string', optional: true },
} }
createIso.resolve = { createIso.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -187,13 +187,13 @@ export async function createNfs ({
nameDescription, nameDescription,
server, server,
serverPath, serverPath,
nfsVersion nfsVersion,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
server, server,
serverpath: serverPath serverpath: serverPath,
} }
// if NFS version given // if NFS version given
@ -224,11 +224,11 @@ createNfs.params = {
nameDescription: { type: 'string' }, nameDescription: { type: 'string' },
server: { type: 'string' }, server: { type: 'string' },
serverPath: { type: 'string' }, serverPath: { type: 'string' },
nfsVersion: { type: 'string', optional: true } nfsVersion: { type: 'string', optional: true },
} }
createNfs.resolve = { createNfs.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -240,12 +240,12 @@ export async function createHba ({
host, host,
nameLabel, nameLabel,
nameDescription, nameDescription,
scsiId scsiId,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
scsiId scsiId,
} }
const srRef = await xapi.call( const srRef = await xapi.call(
@ -269,11 +269,11 @@ createHba.params = {
host: { type: 'string' }, host: { type: 'string' },
nameLabel: { type: 'string' }, nameLabel: { type: 'string' },
nameDescription: { type: 'string' }, nameDescription: { type: 'string' },
scsiId: { type: 'string' } scsiId: { type: 'string' },
} }
createHba.resolve = { createHba.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -285,12 +285,12 @@ export async function createLvm ({
host, host,
nameLabel, nameLabel,
nameDescription, nameDescription,
device device,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
device device,
} }
const srRef = await xapi.call( const srRef = await xapi.call(
@ -314,11 +314,11 @@ createLvm.params = {
host: { type: 'string' }, host: { type: 'string' },
nameLabel: { type: 'string' }, nameLabel: { type: 'string' },
nameDescription: { type: 'string' }, nameDescription: { type: 'string' },
device: { type: 'string' } device: { type: 'string' },
} }
createLvm.resolve = { createLvm.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -327,12 +327,12 @@ createLvm.resolve = {
export async function probeNfs ({ export async function probeNfs ({
host, host,
server server,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
server server,
} }
let xml let xml
@ -359,7 +359,7 @@ export async function probeNfs ({
forEach(ensureArray(xml['nfs-exports'].Export), nfsExport => { forEach(ensureArray(xml['nfs-exports'].Export), nfsExport => {
nfsExports.push({ nfsExports.push({
path: nfsExport.Path.trim(), path: nfsExport.Path.trim(),
acl: nfsExport.Accesslist.trim() acl: nfsExport.Accesslist.trim(),
}) })
}) })
@ -368,18 +368,18 @@ export async function probeNfs ({
probeNfs.params = { probeNfs.params = {
host: { type: 'string' }, host: { type: 'string' },
server: { type: 'string' } server: { type: 'string' },
} }
probeNfs.resolve = { probeNfs.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// This function helps to detect all HBA devices on the host // This function helps to detect all HBA devices on the host
export async function probeHba ({ export async function probeHba ({
host host,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
@ -409,7 +409,7 @@ export async function probeHba ({
path: hbaDevice.path.trim(), path: hbaDevice.path.trim(),
scsciId: hbaDevice.SCSIid.trim(), scsciId: hbaDevice.SCSIid.trim(),
size: hbaDevice.size.trim(), size: hbaDevice.size.trim(),
vendor: hbaDevice.vendor.trim() vendor: hbaDevice.vendor.trim(),
}) })
}) })
@ -417,11 +417,11 @@ export async function probeHba ({
} }
probeHba.params = { probeHba.params = {
host: { type: 'string' } host: { type: 'string' },
} }
probeHba.resolve = { probeHba.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -439,14 +439,14 @@ export async function createIscsi ({
targetIqn, targetIqn,
scsiId, scsiId,
chapUser, chapUser,
chapPassword chapPassword,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
target, target,
targetIQN: targetIqn, targetIQN: targetIqn,
SCSIid: scsiId SCSIid: scsiId,
} }
// if we give user and password // if we give user and password
@ -486,11 +486,11 @@ createIscsi.params = {
targetIqn: { type: 'string' }, targetIqn: { type: 'string' },
scsiId: { type: 'string' }, scsiId: { type: 'string' },
chapUser: { type: 'string', optional: true }, chapUser: { type: 'string', optional: true },
chapPassword: { type: 'string', optional: true } chapPassword: { type: 'string', optional: true },
} }
createIscsi.resolve = { createIscsi.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -502,12 +502,12 @@ export async function probeIscsiIqns ({
target: targetIp, target: targetIp,
port, port,
chapUser, chapUser,
chapPassword chapPassword,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
target: targetIp target: targetIp,
} }
// if we give user and password // if we give user and password
@ -550,7 +550,7 @@ export async function probeIscsiIqns ({
if (target.IPAddress.trim() === targetIp) { if (target.IPAddress.trim() === targetIp) {
targets.push({ targets.push({
iqn: target.TargetIQN.trim(), iqn: target.TargetIQN.trim(),
ip: target.IPAddress.trim() ip: target.IPAddress.trim(),
}) })
} }
}) })
@ -563,10 +563,10 @@ probeIscsiIqns.params = {
target: { type: 'string' }, target: { type: 'string' },
port: { type: 'integer', optional: true }, port: { type: 'integer', optional: true },
chapUser: { type: 'string', optional: true }, chapUser: { type: 'string', optional: true },
chapPassword: { type: 'string', optional: true } chapPassword: { type: 'string', optional: true },
} }
probeIscsiIqns.resolve = { probeIscsiIqns.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -579,13 +579,13 @@ export async function probeIscsiLuns ({
port, port,
targetIqn, targetIqn,
chapUser, chapUser,
chapPassword chapPassword,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
target: targetIp, target: targetIp,
targetIQN: targetIqn targetIQN: targetIqn,
} }
// if we give user and password // if we give user and password
@ -626,7 +626,7 @@ export async function probeIscsiLuns ({
vendor: lun.vendor.trim(), vendor: lun.vendor.trim(),
serial: lun.serial.trim(), serial: lun.serial.trim(),
size: lun.size.trim(), size: lun.size.trim(),
scsiId: lun.SCSIid.trim() scsiId: lun.SCSIid.trim(),
}) })
}) })
@ -639,11 +639,11 @@ probeIscsiLuns.params = {
port: { type: 'integer', optional: true }, port: { type: 'integer', optional: true },
targetIqn: { type: 'string' }, targetIqn: { type: 'string' },
chapUser: { type: 'string', optional: true }, chapUser: { type: 'string', optional: true },
chapPassword: { type: 'string', optional: true } chapPassword: { type: 'string', optional: true },
} }
probeIscsiLuns.resolve = { probeIscsiLuns.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -657,14 +657,14 @@ export async function probeIscsiExists ({
targetIqn, targetIqn,
scsiId, scsiId,
chapUser, chapUser,
chapPassword chapPassword,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
target: targetIp, target: targetIp,
targetIQN: targetIqn, targetIQN: targetIqn,
SCSIid: scsiId SCSIid: scsiId,
} }
// if we give user and password // if we give user and password
@ -696,11 +696,11 @@ probeIscsiExists.params = {
targetIqn: { type: 'string' }, targetIqn: { type: 'string' },
scsiId: { type: 'string' }, scsiId: { type: 'string' },
chapUser: { type: 'string', optional: true }, chapUser: { type: 'string', optional: true },
chapPassword: { type: 'string', optional: true } chapPassword: { type: 'string', optional: true },
} }
probeIscsiExists.resolve = { probeIscsiExists.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -710,13 +710,13 @@ probeIscsiExists.resolve = {
export async function probeNfsExists ({ export async function probeNfsExists ({
host, host,
server, server,
serverPath serverPath,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
const deviceConfig = { const deviceConfig = {
server, server,
serverpath: serverPath serverpath: serverPath,
} }
const xml = parseXml(await xapi.call('SR.probe', host._xapiRef, deviceConfig, 'nfs', {})) const xml = parseXml(await xapi.call('SR.probe', host._xapiRef, deviceConfig, 'nfs', {}))
@ -734,11 +734,11 @@ export async function probeNfsExists ({
probeNfsExists.params = { probeNfsExists.params = {
host: { type: 'string' }, host: { type: 'string' },
server: { type: 'string' }, server: { type: 'string' },
serverPath: { type: 'string' } serverPath: { type: 'string' },
} }
probeNfsExists.resolve = { probeNfsExists.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -749,7 +749,7 @@ export async function reattach ({
uuid, uuid,
nameLabel, nameLabel,
nameDescription, nameDescription,
type type,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
@ -777,11 +777,11 @@ reattach.params = {
uuid: { type: 'string' }, uuid: { type: 'string' },
nameLabel: { type: 'string' }, nameLabel: { type: 'string' },
nameDescription: { type: 'string' }, nameDescription: { type: 'string' },
type: { type: 'string' } type: { type: 'string' },
} }
reattach.resolve = { reattach.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -792,7 +792,7 @@ export async function reattachIso ({
uuid, uuid,
nameLabel, nameLabel,
nameDescription, nameDescription,
type type,
}) { }) {
const xapi = this.getXapi(host) const xapi = this.getXapi(host)
@ -820,11 +820,11 @@ reattachIso.params = {
uuid: { type: 'string' }, uuid: { type: 'string' },
nameLabel: { type: 'string' }, nameLabel: { type: 'string' },
nameDescription: { type: 'string' }, nameDescription: { type: 'string' },
type: { type: 'string' } type: { type: 'string' },
} }
reattachIso.resolve = { reattachIso.resolve = {
host: ['host', 'host', 'administrate'] host: ['host', 'host', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -834,9 +834,9 @@ export function getUnhealthyVdiChainsLength ({ sr }) {
} }
getUnhealthyVdiChainsLength.params = { getUnhealthyVdiChainsLength.params = {
id: { type: 'string' } id: { type: 'string' },
} }
getUnhealthyVdiChainsLength.resolve = { getUnhealthyVdiChainsLength.resolve = {
sr: ['id', 'SR', 'operate'] sr: ['id', 'SR', 'operate'],
} }

View File

@ -14,7 +14,7 @@ export function getMethodsInfo () {
methods[name] = { methods[name] = {
description: method.description, description: method.description,
params: method.params || {}, params: method.params || {},
permission: method.permission permission: method.permission,
} }
}) })
@ -60,8 +60,8 @@ export function methodSignature ({method: name}) {
name, name,
description: method.description, description: method.description,
params: method.params || {}, params: method.params || {},
permission: method.permission permission: method.permission,
} },
] ]
} }
methodSignature.description = 'returns the signature of an API method' methodSignature.description = 'returns the signature of an API method'

View File

@ -5,12 +5,12 @@ export async function add ({tag, object}) {
add.description = 'add a new tag to an object' add.description = 'add a new tag to an object'
add.resolve = { add.resolve = {
object: ['id', null, 'administrate'] object: ['id', null, 'administrate'],
} }
add.params = { add.params = {
tag: { type: 'string' }, tag: { type: 'string' },
id: { type: 'string' } id: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -22,10 +22,10 @@ export async function remove ({tag, object}) {
remove.description = 'remove an existing tag from an object' remove.description = 'remove an existing tag from an object'
remove.resolve = { remove.resolve = {
object: ['id', null, 'administrate'] object: ['id', null, 'administrate'],
} }
remove.params = { remove.params = {
tag: { type: 'string' }, tag: { type: 'string' },
id: { type: 'string' } id: { type: 'string' },
} }

View File

@ -3,11 +3,11 @@ export async function cancel ({task}) {
} }
cancel.params = { cancel.params = {
id: { type: 'string' } id: { type: 'string' },
} }
cancel.resolve = { cancel.resolve = {
task: ['id', 'task', 'administrate'] task: ['id', 'task', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -17,9 +17,9 @@ export async function destroy ({task}) {
} }
destroy.params = { destroy.params = {
id: { type: 'string' } id: { type: 'string' },
} }
destroy.resolve = { destroy.resolve = {
task: ['id', 'task', 'administrate'] task: ['id', 'task', 'administrate'],
} }

View File

@ -6,15 +6,15 @@ getPermissionsForUser.permission = 'admin'
getPermissionsForUser.params = { getPermissionsForUser.params = {
userId: { userId: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
export function hasPermission ({ userId, objectId, permission }) { export function hasPermission ({ userId, objectId, permission }) {
return this.hasPermissions(userId, [ return this.hasPermissions(userId, [
[ objectId, permission ] [ objectId, permission ],
]) ])
} }
@ -22,14 +22,14 @@ hasPermission.permission = 'admin'
hasPermission.params = { hasPermission.params = {
userId: { userId: {
type: 'string' type: 'string',
}, },
objectId: { objectId: {
type: 'string' type: 'string',
}, },
permission: { permission: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -44,8 +44,8 @@ export function wait ({duration, returnValue}) {
wait.params = { wait.params = {
duration: { duration: {
type: 'string' type: 'string',
} },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -77,10 +77,10 @@ copyVm.permission = 'admin'
copyVm.params = { copyVm.params = {
vm: { type: 'string' }, vm: { type: 'string' },
sr: { type: 'string' } sr: { type: 'string' },
} }
copyVm.resolve = { copyVm.resolve = {
vm: [ 'vm', 'VM' ], vm: [ 'vm', 'VM' ],
sr: [ 'sr', 'SR' ] sr: [ 'sr', 'SR' ],
} }

View File

@ -3,7 +3,7 @@
export async function create ({ expiresIn }) { export async function create ({ expiresIn }) {
return (await this.createAuthenticationToken({ return (await this.createAuthenticationToken({
expiresIn, expiresIn,
userId: this.session.get('user_id') userId: this.session.get('user_id'),
})).id })).id
} }
@ -12,8 +12,8 @@ create.description = 'create a new authentication token'
create.params = { create.params = {
expiresIn: { expiresIn: {
optional: true, optional: true,
type: [ 'number', 'string' ] type: [ 'number', 'string' ],
} },
} }
create.permission = '' // sign in create.permission = '' // sign in
@ -32,5 +32,5 @@ delete_.description = 'delete an existing authentication token'
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.params = { delete_.params = {
token: { type: 'string' } token: { type: 'string' },
} }

View File

@ -14,7 +14,7 @@ create.permission = 'admin'
create.params = { create.params = {
email: { type: 'string' }, email: { type: 'string' },
password: { type: 'string' }, password: { type: 'string' },
permission: { type: 'string', optional: true } permission: { type: 'string', optional: true },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -36,7 +36,7 @@ delete_.description = 'deletes an existing user'
delete_.permission = 'admin' delete_.permission = 'admin'
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -79,7 +79,7 @@ set.params = {
email: { type: 'string', optional: true }, email: { type: 'string', optional: true },
password: { type: 'string', optional: true }, password: { type: 'string', optional: true },
permission: { type: 'string', optional: true }, permission: { type: 'string', optional: true },
preferences: { type: 'object', optional: true } preferences: { type: 'object', optional: true },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -95,5 +95,5 @@ changePassword.permission = ''
changePassword.params = { changePassword.params = {
oldPassword: {type: 'string'}, oldPassword: {type: 'string'},
newPassword: {type: 'string'} newPassword: {type: 'string'},
} }

View File

@ -17,11 +17,11 @@ async function delete_ ({vif}) {
export {delete_ as delete} export {delete_ as delete}
delete_.params = { delete_.params = {
id: { type: 'string' } id: { type: 'string' },
} }
delete_.resolve = { delete_.resolve = {
vif: ['id', 'VIF', 'administrate'] vif: ['id', 'VIF', 'administrate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -33,11 +33,11 @@ export async function disconnect ({vif}) {
} }
disconnect.params = { disconnect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
disconnect.resolve = { disconnect.resolve = {
vif: ['id', 'VIF', 'operate'] vif: ['id', 'VIF', 'operate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -48,11 +48,11 @@ export async function connect ({vif}) {
} }
connect.params = { connect.params = {
id: { type: 'string' } id: { type: 'string' },
} }
connect.resolve = { connect.resolve = {
vif: ['id', 'VIF', 'operate'] vif: ['id', 'VIF', 'operate'],
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -63,7 +63,7 @@ export async function set ({
mac, mac,
allowedIpv4Addresses, allowedIpv4Addresses,
allowedIpv6Addresses, allowedIpv6Addresses,
attached attached,
}) { }) {
const oldIpAddresses = vif.allowedIpv4Addresses.concat(vif.allowedIpv6Addresses) const oldIpAddresses = vif.allowedIpv4Addresses.concat(vif.allowedIpv6Addresses)
const newIpAddresses = [] const newIpAddresses = []
@ -88,7 +88,7 @@ export async function set ({
const newVif = await xapi.createVif(vm.$id, network.$id, { const newVif = await xapi.createVif(vm.$id, network.$id, {
mac, mac,
currently_attached: attached, currently_attached: attached,
ipv4_allowed: newIpAddresses ipv4_allowed: newIpAddresses,
}) })
await this.allocIpAddresses(newVif.$id, newIpAddresses) await this.allocIpAddresses(newVif.$id, newIpAddresses)
@ -108,7 +108,7 @@ export async function set ({
return this.getXapi(vif).editVif(vif._xapiId, { return this.getXapi(vif).editVif(vif._xapiId, {
ipv4Allowed: allowedIpv4Addresses, ipv4Allowed: allowedIpv4Addresses,
ipv6Allowed: allowedIpv6Addresses ipv6Allowed: allowedIpv6Addresses,
}) })
} }
@ -119,21 +119,21 @@ set.params = {
allowedIpv4Addresses: { allowedIpv4Addresses: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
allowedIpv6Addresses: { allowedIpv6Addresses: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
optional: true optional: true,
}, },
attached: { type: 'boolean', optional: true } attached: { type: 'boolean', optional: true },
} }
set.resolve = { set.resolve = {
vif: ['id', 'VIF', 'operate'], vif: ['id', 'VIF', 'operate'],
network: ['network', 'network', 'operate'] network: ['network', 'network', 'operate'],
} }

View File

@ -14,13 +14,13 @@ export async function exportConfig () {
return { return {
$getFrom: await this.registerHttpRequest((req, res) => { $getFrom: await this.registerHttpRequest((req, res) => {
res.writeHead(200, 'OK', { res.writeHead(200, 'OK', {
'content-disposition': 'attachment' 'content-disposition': 'attachment',
}) })
return this.exportConfig() return this.exportConfig()
}, },
undefined, undefined,
{ suffix: '/config.json' }) { suffix: '/config.json' }),
} }
} }
@ -37,7 +37,7 @@ getAllObjects.description = 'Returns all XO objects'
getAllObjects.params = { getAllObjects.params = {
filter: { type: 'object', optional: true }, filter: { type: 'object', optional: true },
limit: { type: 'number', optional: true } limit: { type: 'number', optional: true },
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -48,7 +48,7 @@ export async function importConfig () {
await this.importConfig(JSON.parse(await streamToBuffer(req))) await this.importConfig(JSON.parse(await streamToBuffer(req)))
res.end('config successfully imported') res.end('config successfully imported')
}) }),
} }
} }

View File

@ -12,7 +12,7 @@ import {
remove, remove,
filter, filter,
find, find,
range range,
} from 'lodash' } from 'lodash'
import { asInteger } from '../xapi/utils' import { asInteger } from '../xapi/utils'
@ -67,7 +67,7 @@ function _getGlusterEndpoint (sr) {
xapi, xapi,
data: data, data: data,
hosts: map(data.nodes, node => xapi.getObject(node.host)), hosts: map(data.nodes, node => xapi.getObject(node.host)),
addresses: map(data.nodes, node => node.vm.ip) addresses: map(data.nodes, node => node.vm.ip),
} }
} }
@ -106,7 +106,7 @@ export async function getVolumeInfo ({sr, infoType}) {
}) })
return { return {
commandStatus: true, commandStatus: true,
result: {nodes: brickDictByUuid, tasks: volume['tasks']} result: {nodes: brickDictByUuid, tasks: volume['tasks']},
} }
} }
@ -121,7 +121,7 @@ export async function getVolumeInfo ({sr, infoType}) {
return async () => { return async () => {
const cmdShouldRetry = result => !result['commandStatus'] && result.parsed && result.parsed['cliOutput']['opErrno'] === '30802' const cmdShouldRetry = result => !result['commandStatus'] && result.parsed && result.parsed['cliOutput']['opErrno'] === '30802'
const runCmd = async () => glusterCmd(glusterEndpoint, 'volume ' + command, true) const runCmd = async () => glusterCmd(glusterEndpoint, 'volume ' + command, true)
let commandResult = await rateLimitedRetry(runCmd, cmdShouldRetry) const commandResult = await rateLimitedRetry(runCmd, cmdShouldRetry)
return commandResult['commandStatus'] ? handler(commandResult.parsed['cliOutput']) : commandResult return commandResult['commandStatus'] ? handler(commandResult.parsed['cliOutput']) : commandResult
} }
} }
@ -140,7 +140,7 @@ export async function getVolumeInfo ({sr, infoType}) {
statusDetail: sshInfoType('status xosan detail', parseStatus), statusDetail: sshInfoType('status xosan detail', parseStatus),
statusMem: sshInfoType('status xosan mem', parseStatus), statusMem: sshInfoType('status xosan mem', parseStatus),
info: sshInfoType('info xosan', parseInfo), info: sshInfoType('info xosan', parseInfo),
hosts: this::checkHosts hosts: this::checkHosts,
} }
if (glusterEndpoint == null) { if (glusterEndpoint == null) {
return null return null
@ -157,14 +157,14 @@ getVolumeInfo.permission = 'admin'
getVolumeInfo.params = { getVolumeInfo.params = {
sr: { sr: {
type: 'string' type: 'string',
}, },
infoType: { infoType: {
type: 'string' type: 'string',
} },
} }
getVolumeInfo.resolve = { getVolumeInfo.resolve = {
sr: ['sr', 'SR', 'administrate'] sr: ['sr', 'SR', 'administrate'],
} }
function reconfigurePifIP (xapi, pif, newIP) { function reconfigurePifIP (xapi, pif, newIP) {
@ -190,7 +190,7 @@ export async function fixHostNotInNetwork ({xosanSr, host}) {
await callPlugin(xapi, host, 'receive_ssh_keys', { await callPlugin(xapi, host, 'receive_ssh_keys', {
private_key: sshKey.private, private_key: sshKey.private,
public_key: sshKey.public, public_key: sshKey.public,
force: true force: true,
}) })
} }
} }
@ -200,14 +200,14 @@ fixHostNotInNetwork.permission = 'admin'
fixHostNotInNetwork.params = { fixHostNotInNetwork.params = {
xosanSr: { xosanSr: {
type: 'string' type: 'string',
}, },
host: { host: {
type: 'string' type: 'string',
} },
} }
fixHostNotInNetwork.resolve = { fixHostNotInNetwork.resolve = {
sr: ['sr', 'SR', 'administrate'] sr: ['sr', 'SR', 'administrate'],
} }
function floor2048 (value) { function floor2048 (value) {
@ -315,7 +315,7 @@ const createNetworkAndInsertHosts = defer.onFailure(async function ($onFailure,
description: 'XOSAN network', description: 'XOSAN network',
pifId: pif._xapiId, pifId: pif._xapiId,
mtu: pif.mtu, mtu: pif.mtu,
vlan: +vlan vlan: +vlan,
}) })
$onFailure(() => xapi.deleteNetwork(xosanNetwork)) $onFailure(() => xapi.deleteNetwork(xosanNetwork))
const addresses = xosanNetwork.$PIFs.map(pif => ({pif, address: networkPrefix + (hostIpLastNumber++)})) const addresses = xosanNetwork.$PIFs.map(pif => ({pif, address: networkPrefix + (hostIpLastNumber++)}))
@ -338,7 +338,7 @@ async function getOrCreateSshKey (xapi) {
const readKeys = async () => { const readKeys = async () => {
sshKey = { sshKey = {
private: await fs.readFile(SSH_KEY_FILE, 'ascii'), private: await fs.readFile(SSH_KEY_FILE, 'ascii'),
public: await fs.readFile(SSH_KEY_FILE + '.pub', 'ascii') public: await fs.readFile(SSH_KEY_FILE + '.pub', 'ascii'),
} }
xapi.xo.setData(xapi.pool, 'xosan_ssh_key', sshKey) xapi.xo.setData(xapi.pool, 'xosan_ssh_key', sshKey)
} }
@ -380,18 +380,18 @@ async function configureGluster (redundancy, ipAndHosts, glusterEndpoint, gluste
const configByType = { const configByType = {
replica_arbiter: { replica_arbiter: {
creation: 'replica 3 arbiter 1', creation: 'replica 3 arbiter 1',
extra: [] extra: [],
}, },
replica: { replica: {
creation: 'replica ' + redundancy + ' ', creation: 'replica ' + redundancy + ' ',
extra: ['volume set xosan cluster.data-self-heal on'] extra: ['volume set xosan cluster.data-self-heal on'],
}, },
disperse: { disperse: {
creation: 'disperse ' + ipAndHosts.length + ' redundancy ' + redundancy + ' ', creation: 'disperse ' + ipAndHosts.length + ' redundancy ' + redundancy + ' ',
extra: [] extra: [],
} },
} }
let brickVms = arbiter ? ipAndHosts.concat(arbiter) : ipAndHosts const brickVms = arbiter ? ipAndHosts.concat(arbiter) : ipAndHosts
await _probePoolAndWaitForPresence(glusterEndpoint, map(brickVms.slice(1), bv => bv.address)) await _probePoolAndWaitForPresence(glusterEndpoint, map(brickVms.slice(1), bv => bv.address))
const creation = configByType[glusterType].creation const creation = configByType[glusterType].creation
const volumeCreation = 'volume create xosan ' + creation + ' ' + const volumeCreation = 'volume create xosan ' + creation + ' ' +
@ -418,12 +418,12 @@ async function configureGluster (redundancy, ipAndHosts, glusterEndpoint, gluste
export const createSR = defer.onFailure(async function ($onFailure, { export const createSR = defer.onFailure(async function ($onFailure, {
template, pif, vlan, srs, glusterType, template, pif, vlan, srs, glusterType,
redundancy, brickSize = this::computeBrickSize(srs), memorySize = 2 * GIGABYTE, ipRange = DEFAULT_NETWORK_PREFIX + '.0' redundancy, brickSize = this::computeBrickSize(srs), memorySize = 2 * GIGABYTE, ipRange = DEFAULT_NETWORK_PREFIX + '.0',
}) { }) {
const OPERATION_OBJECT = { const OPERATION_OBJECT = {
operation: 'createSr', operation: 'createSr',
states: ['configuringNetwork', 'importingVm', 'copyingVms', states: ['configuringNetwork', 'importingVm', 'copyingVms',
'configuringVms', 'configuringGluster', 'creatingSr', 'scanningSr'] 'configuringVms', 'configuringGluster', 'creatingSr', 'scanningSr'],
} }
if (!this.requestResource) { if (!this.requestResource) {
throw new Error('requestResource is not a function') throw new Error('requestResource is not a function')
@ -450,7 +450,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
await Promise.all(srsObjects.map(sr => callPlugin(xapi, sr.$PBDs[0].$host, 'receive_ssh_keys', { await Promise.all(srsObjects.map(sr => callPlugin(xapi, sr.$PBDs[0].$host, 'receive_ssh_keys', {
private_key: sshKey.private, private_key: sshKey.private,
public_key: sshKey.public, public_key: sshKey.public,
force: 'true' force: 'true',
}))) })))
const firstSr = srsObjects[0] const firstSr = srsObjects[0]
@ -465,7 +465,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
) )
const vmsAndSrs = [{ const vmsAndSrs = [{
vm: firstVM, vm: firstVM,
sr: firstSr sr: firstSr,
}].concat(copiedVms) }].concat(copiedVms)
let arbiter = null let arbiter = null
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 3} CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 3}
@ -477,7 +477,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
arbiter = await _prepareGlusterVm(xapi, sr, arbiterVm, xosanNetwork, arbiterIP, { arbiter = await _prepareGlusterVm(xapi, sr, arbiterVm, xosanNetwork, arbiterIP, {
labelSuffix: '_arbiter', labelSuffix: '_arbiter',
increaseDataDisk: false, increaseDataDisk: false,
memorySize memorySize,
}) })
arbiter.arbiter = true arbiter.arbiter = true
} }
@ -507,7 +507,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
host: param.host.$id, host: param.host.$id,
vm: {id: param.vm.$id, ip: param.address}, vm: {id: param.vm.$id, ip: param.address},
underlyingSr: param.underlyingSr.$id, underlyingSr: param.underlyingSr.$id,
arbiter: !!param['arbiter'] arbiter: !!param['arbiter'],
})) }))
await xapi.xo.setData(xosanSrRef, 'xosan_config', { await xapi.xo.setData(xosanSrRef, 'xosan_config', {
version: 'beta2', version: 'beta2',
@ -516,7 +516,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
network: xosanNetwork.$id, network: xosanNetwork.$id,
type: glusterType, type: glusterType,
networkPrefix, networkPrefix,
redundancy redundancy,
}) })
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 6} CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 6}
debug('scanning new SR') debug('scanning new SR')
@ -532,32 +532,32 @@ createSR.params = {
srs: { srs: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
} },
}, },
pif: { pif: {
type: 'string' type: 'string',
}, },
vlan: { vlan: {
type: 'string' type: 'string',
}, },
glusterType: { glusterType: {
type: 'string' type: 'string',
}, },
redundancy: { redundancy: {
type: 'number' type: 'number',
}, },
memorySize: { memorySize: {
type: 'number', optional: true type: 'number', optional: true,
}, },
ipRange: { ipRange: {
type: 'string', optional: true type: 'string', optional: true,
} },
} }
createSR.resolve = { createSR.resolve = {
srs: ['sr', 'SR', 'administrate'], srs: ['sr', 'SR', 'administrate'],
pif: ['pif', 'PIF', 'administrate'] pif: ['pif', 'PIF', 'administrate'],
} }
async function umountDisk (localEndpoint, diskMountPoint) { async function umountDisk (localEndpoint, diskMountPoint) {
@ -608,7 +608,7 @@ async function mountNewDisk (localEndpoint, hostname, newDeviceFiledeviceFile) {
async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize) { async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize) {
const OPERATION_OBJECT = { const OPERATION_OBJECT = {
operation: 'replaceBrick', operation: 'replaceBrick',
states: ['creatingNewDisk', 'mountingDisk', 'swappingBrick', 'disconnectingOldDisk', 'scanningSr'] states: ['creatingNewDisk', 'mountingDisk', 'swappingBrick', 'disconnectingOldDisk', 'scanningSr'],
} }
const xapi = this.getXapi(xosansr) const xapi = this.getXapi(xosansr)
const poolId = xapi.pool.$id const poolId = xapi.pool.$id
@ -627,7 +627,7 @@ async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize
const localEndpoint = { const localEndpoint = {
xapi, xapi,
hosts: map(nodes, node => xapi.getObject(node.host)), hosts: map(nodes, node => xapi.getObject(node.host)),
addresses: [previousIp] addresses: [previousIp],
} }
const previousBrickRoot = previousBrick.split(':')[1].split('/').slice(0, 3).join('/') const previousBrickRoot = previousBrick.split(':')[1].split('/').slice(0, 3).join('/')
const previousBrickDevice = (await remoteSsh(localEndpoint, `grep " ${previousBrickRoot} " /proc/mounts | cut -d ' ' -f 1 | sed 's_/dev/__'`)).stdout.trim() const previousBrickDevice = (await remoteSsh(localEndpoint, `grep " ${previousBrickRoot} " /proc/mounts | cut -d ' ' -f 1 | sed 's_/dev/__'`)).stdout.trim()
@ -653,7 +653,7 @@ async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize
export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize, onSameVM = true}) { export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize, onSameVM = true}) {
const OPERATION_OBJECT = { const OPERATION_OBJECT = {
operation: 'replaceBrick', operation: 'replaceBrick',
states: ['insertingNewVm', 'swapingBrick', 'deletingVm', 'scaningSr'] states: ['insertingNewVm', 'swapingBrick', 'deletingVm', 'scaningSr'],
} }
if (onSameVM) { if (onSameVM) {
return this::replaceBrickOnSameVM(xosansr, previousBrick, newLvmSr, brickSize) return this::replaceBrickOnSameVM(xosansr, previousBrick, newLvmSr, brickSize)
@ -672,12 +672,12 @@ export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize
const glusterEndpoint = { const glusterEndpoint = {
xapi, xapi,
hosts: map(stayingNodes, node => xapi.getObject(node.host)), hosts: map(stayingNodes, node => xapi.getObject(node.host)),
addresses: map(stayingNodes, node => node.vm.ip) addresses: map(stayingNodes, node => node.vm.ip),
} }
const previousVMEntry = _getIPToVMDict(xapi, xosansr)[previousBrick] const previousVMEntry = _getIPToVMDict(xapi, xosansr)[previousBrick]
const arbiter = nodes[nodeIndex].arbiter const arbiter = nodes[nodeIndex].arbiter
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 0} CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 0}
let {newVM, addressAndHost} = await this::insertNewGlusterVm(xapi, xosansr, newLvmSr, const {newVM, addressAndHost} = await this::insertNewGlusterVm(xapi, xosansr, newLvmSr,
{labelSuffix: arbiter ? '_arbiter' : '', glusterEndpoint, newIpAddress, increaseDataDisk: !arbiter, brickSize}) {labelSuffix: arbiter ? '_arbiter' : '', glusterEndpoint, newIpAddress, increaseDataDisk: !arbiter, brickSize})
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 1} CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 1}
await glusterCmd(glusterEndpoint, `volume replace-brick xosan ${previousBrick} ${addressAndHost.brickName} commit force`) await glusterCmd(glusterEndpoint, `volume replace-brick xosan ${previousBrick} ${addressAndHost.brickName} commit force`)
@ -687,7 +687,7 @@ export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize
host: addressAndHost.host.$id, host: addressAndHost.host.$id,
arbiter: arbiter, arbiter: arbiter,
vm: {ip: addressAndHost.address, id: newVM.$id}, vm: {ip: addressAndHost.address, id: newVM.$id},
underlyingSr: newLvmSr underlyingSr: newLvmSr,
}) })
await xapi.xo.setData(xosansr, 'xosan_config', data) await xapi.xo.setData(xosansr, 'xosan_config', data)
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 2} CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 2}
@ -707,16 +707,16 @@ replaceBrick.params = {
xosansr: {type: 'string'}, xosansr: {type: 'string'},
previousBrick: {type: 'string'}, previousBrick: {type: 'string'},
newLvmSr: {type: 'string'}, newLvmSr: {type: 'string'},
brickSize: {type: 'number'} brickSize: {type: 'number'},
} }
replaceBrick.resolve = { replaceBrick.resolve = {
xosansr: ['sr', 'SR', 'administrate'] xosansr: ['sr', 'SR', 'administrate'],
} }
async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, { async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
labelSuffix = '', increaseDataDisk = true, labelSuffix = '', increaseDataDisk = true,
maxDiskSize = Infinity, memorySize = 2 * GIGABYTE maxDiskSize = Infinity, memorySize = 2 * GIGABYTE,
}) { }) {
const host = lvmSr.$PBDs[0].$host const host = lvmSr.$PBDs[0].$host
const xenstoreData = { const xenstoreData = {
@ -724,7 +724,7 @@ async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
'vm-data/sshkey': (await getOrCreateSshKey(xapi)).public, 'vm-data/sshkey': (await getOrCreateSshKey(xapi)).public,
'vm-data/ip': ipAddress, 'vm-data/ip': ipAddress,
'vm-data/mtu': String(xosanNetwork.MTU), 'vm-data/mtu': String(xosanNetwork.MTU),
'vm-data/vlan': String(xosanNetwork.$PIFs[0].vlan || 0) 'vm-data/vlan': String(xosanNetwork.$PIFs[0].vlan || 0),
} }
const ip = ipAddress const ip = ipAddress
const sr = xapi.getObject(lvmSr.$id) const sr = xapi.getObject(lvmSr.$id)
@ -750,7 +750,7 @@ async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
memoryMax: memorySize, memoryMax: memorySize,
memoryMin: memorySize, memoryMin: memorySize,
memoryStaticMax: memorySize, memoryStaticMax: memorySize,
memory: memorySize memory: memorySize,
}) })
await xapi.call('VM.set_xenstore_data', newVM.$ref, xenstoreData) await xapi.call('VM.set_xenstore_data', newVM.$ref, xenstoreData)
const rootDisk = newVM.$VBDs.map(vbd => vbd && vbd.$VDI).find(vdi => vdi && vdi.name_label === 'xosan_root') const rootDisk = newVM.$VBDs.map(vbd => vbd && vbd.$VDI).find(vdi => vdi && vdi.name_label === 'xosan_root')
@ -778,7 +778,7 @@ async function _importGlusterVM (xapi, template, lvmsrId) {
await xapi.editVm(newVM, { await xapi.editVm(newVM, {
autoPoweron: true, autoPoweron: true,
name_label: 'XOSAN imported VM', name_label: 'XOSAN imported VM',
name_description: 'freshly imported' name_description: 'freshly imported',
}) })
return xapi.barrier(newVM.$ref) return xapi.barrier(newVM.$ref)
} }
@ -804,7 +804,7 @@ const _median = arr => {
const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xosansr, lvmsrId, { const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xosansr, lvmsrId, {
labelSuffix = '', labelSuffix = '',
glusterEndpoint = null, ipAddress = null, increaseDataDisk = true, brickSize = Infinity glusterEndpoint = null, ipAddress = null, increaseDataDisk = true, brickSize = Infinity,
}) { }) {
const data = getXosanConfig(xosansr, xapi) const data = getXosanConfig(xosansr, xapi)
if (ipAddress === null) { if (ipAddress === null) {
@ -827,7 +827,7 @@ const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xos
labelSuffix, labelSuffix,
increaseDataDisk, increaseDataDisk,
maxDiskSize: brickSize, maxDiskSize: brickSize,
memorySize: vmsMemories.length ? _median(vmsMemories) : 2 * GIGABYTE memorySize: vmsMemories.length ? _median(vmsMemories) : 2 * GIGABYTE,
}) })
if (!glusterEndpoint) { if (!glusterEndpoint) {
glusterEndpoint = this::_getGlusterEndpoint(xosansr) glusterEndpoint = this::_getGlusterEndpoint(xosansr)
@ -839,7 +839,7 @@ const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xos
export const addBricks = defer.onFailure(async function ($onFailure, {xosansr, lvmsrs, brickSize}) { export const addBricks = defer.onFailure(async function ($onFailure, {xosansr, lvmsrs, brickSize}) {
const OPERATION_OBJECT = { const OPERATION_OBJECT = {
operation: 'addBricks', operation: 'addBricks',
states: ['insertingNewVms', 'addingBricks', 'scaningSr'] states: ['insertingNewVms', 'addingBricks', 'scaningSr'],
} }
const xapi = this.getXapi(xosansr) const xapi = this.getXapi(xosansr)
const poolId = xapi.pool.$id const poolId = xapi.pool.$id
@ -890,15 +890,15 @@ addBricks.params = {
lvmsrs: { lvmsrs: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
} },
}, },
brickSize: {type: 'number'} brickSize: {type: 'number'},
} }
addBricks.resolve = { addBricks.resolve = {
xosansr: ['sr', 'SR', 'administrate'], xosansr: ['sr', 'SR', 'administrate'],
lvmsrs: ['sr', 'SR', 'administrate'] lvmsrs: ['sr', 'SR', 'administrate'],
} }
export const removeBricks = defer.onFailure(async function ($onFailure, {xosansr, bricks}) { export const removeBricks = defer.onFailure(async function ($onFailure, {xosansr, bricks}) {
@ -933,8 +933,8 @@ removeBricks.params = {
xosansr: {type: 'string'}, xosansr: {type: 'string'},
bricks: { bricks: {
type: 'array', type: 'array',
items: {type: 'string'} items: {type: 'string'},
} },
} }
export function checkSrCurrentState ({poolId}) { export function checkSrCurrentState ({poolId}) {
@ -1001,12 +1001,12 @@ computeXosanPossibleOptions.params = {
lvmSrs: { lvmSrs: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
} },
}, },
brickSize: { brickSize: {
type: 'number', optional: true type: 'number', optional: true,
} },
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -1021,7 +1021,7 @@ export async function downloadAndInstallXosanPack ({id, version, pool}) {
await xapi.installSupplementalPackOnAllHosts(res) await xapi.installSupplementalPackOnAllHosts(res)
await xapi._updateObjectMapProperty(xapi.pool, 'other_config', { await xapi._updateObjectMapProperty(xapi.pool, 'other_config', {
'xosan_pack_installation_time': String(Math.floor(Date.now() / 1e3)) 'xosan_pack_installation_time': String(Math.floor(Date.now() / 1e3)),
}) })
} }
@ -1030,11 +1030,11 @@ downloadAndInstallXosanPack.description = 'Register a resource via cloud plugin'
downloadAndInstallXosanPack.params = { downloadAndInstallXosanPack.params = {
id: {type: 'string'}, id: {type: 'string'},
version: {type: 'string'}, version: {type: 'string'},
pool: {type: 'string'} pool: {type: 'string'},
} }
downloadAndInstallXosanPack.resolve = { downloadAndInstallXosanPack.resolve = {
pool: ['pool', 'pool', 'administrate'] pool: ['pool', 'pool', 'administrate'],
} }
downloadAndInstallXosanPack.permission = 'admin' downloadAndInstallXosanPack.permission = 'admin'

View File

@ -4,8 +4,8 @@ import {EventEmitter} from 'events'
import { import {
isArray, isArray,
isObject, isObject,
map map,
} from './utils' } from './utils'
// =================================================================== // ===================================================================
@ -29,7 +29,7 @@ export default class Collection extends EventEmitter {
configurable: true, configurable: true,
enumerale: true, enumerale: true,
value: Model, value: Model,
writable: true writable: true,
}) })
} }

View File

@ -32,7 +32,7 @@ export default class Redis extends Collection {
connection, connection,
indexes = [], indexes = [],
prefix, prefix,
uri uri,
}) { }) {
super() super()
@ -145,7 +145,7 @@ export default class Redis extends Collection {
const key = `${prefix}:${id}` const key = `${prefix}:${id}`
const promises = [ const promises = [
redis.del(key), redis.del(key),
redis.hmset(key, ...params) redis.hmset(key, ...params),
] ]
// Update indexes. // Update indexes.

View File

@ -2,14 +2,14 @@ import { getBoundPropertyDescriptor } from 'bind-property-descriptor'
import { import {
isArray, isArray,
isFunction isFunction,
} from './utils' } from './utils'
// =================================================================== // ===================================================================
const { const {
defineProperties, defineProperties,
getOwnPropertyDescriptor getOwnPropertyDescriptor,
} = Object } = Object
// =================================================================== // ===================================================================
@ -29,7 +29,7 @@ export const debounce = duration => (target, name, descriptor) => {
function debounced () { function debounced () {
const data = this[s] || (this[s] = { const data = this[s] || (this[s] = {
lastCall: 0, lastCall: 0,
wrapper: null wrapper: null,
}) })
const now = Date.now() const now = Date.now()
@ -56,7 +56,7 @@ const _ownKeys = (
(typeof Reflect !== 'undefined' && Reflect.ownKeys) || (typeof Reflect !== 'undefined' && Reflect.ownKeys) ||
(({ (({
getOwnPropertyNames: names, getOwnPropertyNames: names,
getOwnPropertySymbols: symbols getOwnPropertySymbols: symbols,
}) => symbols }) => symbols
? obj => names(obj).concat(symbols(obj)) ? obj => names(obj).concat(symbols(obj))
: names : names
@ -75,7 +75,7 @@ const _IGNORED_STATIC_PROPERTIES = {
caller: true, caller: true,
length: true, length: true,
name: true, name: true,
prototype: true prototype: true,
} }
const _isIgnoredStaticProperty = name => _IGNORED_STATIC_PROPERTIES[name] const _isIgnoredStaticProperty = name => _IGNORED_STATIC_PROPERTIES[name]

View File

@ -47,7 +47,7 @@ export function init () {
BootSig: 41, BootSig: 41,
VolID: 895111106, VolID: 895111106,
VolLab: 'NO NAME ', VolLab: 'NO NAME ',
FilSysType: 'FAT16 ' FilSysType: 'FAT16 ',
}, buf) }, buf)
// End of sector. // End of sector.
@ -80,6 +80,6 @@ export default buffer => {
writeSectors: (i, source, cb) => { writeSectors: (i, source, cb) => {
source.copy(buffer, i * SECTOR_SIZE, 0) source.copy(buffer, i * SECTOR_SIZE, 0)
cb() cb()
} },
} }
} }

View File

@ -1,11 +1,11 @@
// See: https://gist.github.com/julien-f/5b9a3537eb82a34b04e2 // See: https://gist.github.com/julien-f/5b9a3537eb82a34b04e2
var matcher = require('micromatch').matcher const matcher = require('micromatch').matcher
module.exports = function globMatcher (patterns, opts) { module.exports = function globMatcher (patterns, opts) {
if (!Array.isArray(patterns)) { if (!Array.isArray(patterns)) {
if (patterns[0] === '!') { if (patterns[0] === '!') {
var m = matcher(patterns.slice(1), opts) const m = matcher(patterns.slice(1), opts)
return function (string) { return function (string) {
return !m(string) return !m(string)
} }
@ -14,12 +14,12 @@ module.exports = function globMatcher (patterns, opts) {
} }
} }
var noneMustMatch = [] const noneMustMatch = []
var anyMustMatch = [] const anyMustMatch = []
// TODO: could probably be optimized by combining all positive patterns (and all negative patterns) as a single matcher. // TODO: could probably be optimized by combining all positive patterns (and all negative patterns) as a single matcher.
for (var i = 0, n = patterns.length; i < n; ++i) { for (let i = 0, n = patterns.length; i < n; ++i) {
var pattern = patterns[i] const pattern = patterns[i]
if (pattern[0] === '!') { if (pattern[0] === '!') {
noneMustMatch.push(matcher(pattern.slice(1), opts)) noneMustMatch.push(matcher(pattern.slice(1), opts))
} else { } else {
@ -27,11 +27,11 @@ module.exports = function globMatcher (patterns, opts) {
} }
} }
var nNone = noneMustMatch.length const nNone = noneMustMatch.length
var nAny = anyMustMatch.length const nAny = anyMustMatch.length
return function (string) { return function (string) {
var i let i
for (i = 0; i < nNone; ++i) { for (i = 0; i < nNone; ++i) {
if (noneMustMatch[i](string)) { if (noneMustMatch[i](string)) {

View File

@ -20,7 +20,7 @@ import { invalidCredentials } from 'xo-common/api-errors'
import { import {
ensureDir, ensureDir,
readdir, readdir,
readFile readFile,
} from 'fs-extra' } from 'fs-extra'
import WebServer from 'http-server-plus' import WebServer from 'http-server-plus'
@ -31,7 +31,7 @@ import {
isArray, isArray,
isFunction, isFunction,
mapToArray, mapToArray,
pFromCallback pFromCallback,
} from './utils' } from './utils'
import bodyParser from 'body-parser' import bodyParser from 'body-parser'
@ -54,12 +54,12 @@ const warn = (...args) => {
const DEPRECATED_ENTRIES = [ const DEPRECATED_ENTRIES = [
'users', 'users',
'servers' 'servers',
] ]
async function loadConfiguration () { async function loadConfiguration () {
const config = await appConf.load('xo-server', { const config = await appConf.load('xo-server', {
ignoreUnknownFormats: true ignoreUnknownFormats: true,
}) })
debug('Configuration loaded.') debug('Configuration loaded.')
@ -89,7 +89,7 @@ function createExpressApp () {
saveUninitialized: false, saveUninitialized: false,
// TODO: should be in the config file. // TODO: should be in the config file.
secret: 'CLWguhRZAZIXZcbrMzHCYmefxgweItKnS' secret: 'CLWguhRZAZIXZcbrMzHCYmefxgweItKnS',
})) }))
// Registers the connect-flash middleware, necessary for Passport to // Registers the connect-flash middleware, necessary for Passport to
@ -124,7 +124,7 @@ async function setUpPassport (express, xo) {
express.get('/signin', (req, res, next) => { express.get('/signin', (req, res, next) => {
res.send(signInPage({ res.send(signInPage({
error: req.flash('error')[0], error: req.flash('error')[0],
strategies strategies,
})) }))
}) })
@ -220,7 +220,7 @@ async function registerPlugin (pluginPath, pluginName) {
default: factory = plugin, default: factory = plugin,
configurationSchema, configurationSchema,
configurationPresets, configurationPresets,
testSchema testSchema,
} = plugin } = plugin
// The default export can be either a factory or directly a plugin // The default export can be either a factory or directly a plugin
@ -231,7 +231,7 @@ async function registerPlugin (pluginPath, pluginName) {
getDataDir: () => { getDataDir: () => {
const dir = `${this._config.datadir}/${pluginName}` const dir = `${this._config.datadir}/${pluginName}`
return ensureDir(dir).then(() => dir) return ensureDir(dir).then(() => dir)
} },
}) })
: factory : factory
@ -287,7 +287,7 @@ async function registerPluginsInPath (path) {
async function registerPlugins (xo) { async function registerPlugins (xo) {
await Promise.all(mapToArray([ await Promise.all(mapToArray([
`${__dirname}/../node_modules/`, `${__dirname}/../node_modules/`,
'/usr/local/lib/node_modules/' '/usr/local/lib/node_modules/',
], xo::registerPluginsInPath)) ], xo::registerPluginsInPath))
} }
@ -305,7 +305,7 @@ async function makeWebServerListen (webServer, {
if (cert && key) { if (cert && key) {
[opts.cert, opts.key] = await Promise.all([ [opts.cert, opts.key] = await Promise.all([
readFile(cert), readFile(cert),
readFile(key) readFile(key),
]) ])
} }
try { try {
@ -346,7 +346,7 @@ const setUpProxies = (express, opts, xo) => {
} }
const proxy = createProxyServer({ const proxy = createProxyServer({
ignorePath: true ignorePath: true,
}).on('error', (error) => console.error(error)) }).on('error', (error) => console.error(error))
// TODO: sort proxies by descending prefix length. // TODO: sort proxies by descending prefix length.
@ -360,7 +360,7 @@ const setUpProxies = (express, opts, xo) => {
const target = opts[prefix] const target = opts[prefix]
proxy.web(req, res, { proxy.web(req, res, {
target: target + url.slice(prefix.length) target: target + url.slice(prefix.length),
}) })
return return
@ -372,7 +372,7 @@ const setUpProxies = (express, opts, xo) => {
// WebSocket proxy. // WebSocket proxy.
const webSocketServer = new WebSocket.Server({ const webSocketServer = new WebSocket.Server({
noServer: true noServer: true,
}) })
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb))) xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
@ -384,7 +384,7 @@ const setUpProxies = (express, opts, xo) => {
const target = opts[prefix] const target = opts[prefix]
proxy.ws(req, socket, head, { proxy.ws(req, socket, head, {
target: target + url.slice(prefix.length) target: target + url.slice(prefix.length),
}) })
return return
@ -413,7 +413,7 @@ const setUpStaticFiles = (express, opts) => {
const setUpApi = (webServer, xo, verboseLogsOnErrors) => { const setUpApi = (webServer, xo, verboseLogsOnErrors) => {
const webSocketServer = new WebSocket.Server({ const webSocketServer = new WebSocket.Server({
noServer: true noServer: true,
}) })
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb))) xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
@ -474,7 +474,7 @@ const CONSOLE_PROXY_PATH_RE = /^\/api\/consoles\/(.*)$/
const setUpConsoleProxy = (webServer, xo) => { const setUpConsoleProxy = (webServer, xo) => {
const webSocketServer = new WebSocket.Server({ const webSocketServer = new WebSocket.Server({
noServer: true noServer: true,
}) })
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb))) xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
@ -519,7 +519,7 @@ const setUpConsoleProxy = (webServer, xo) => {
const USAGE = (({ const USAGE = (({
name, name,
version version,
}) => `Usage: ${name} [--safe-mode] }) => `Usage: ${name} [--safe-mode]
${name} v${version}`)(require('../package.json')) ${name} v${version}`)(require('../package.json'))

View File

@ -12,13 +12,13 @@ import {
map, map,
mapValues, mapValues,
size, size,
some some,
} from 'lodash' } from 'lodash'
import { crossProduct } from './math' import { crossProduct } from './math'
import { import {
serializeError, serializeError,
thunkToArray thunkToArray,
} from './utils' } from './utils'
export class JobExecutorError extends BaseError {} export class JobExecutorError extends BaseError {}
@ -81,11 +81,11 @@ const paramsVectorActionsMap = {
return map(resolveParamsVector.call(this, collection), value => { return map(resolveParamsVector.call(this, collection), value => {
return resolveParamsVector.call(this, { return resolveParamsVector.call(this, {
...iteratee, ...iteratee,
[paramName]: value [paramName]: value,
}) })
}) })
}, },
set: ({ values }) => values set: ({ values }) => values,
} }
export function resolveParamsVector (paramsVector) { export function resolveParamsVector (paramsVector) {
@ -114,7 +114,7 @@ export default class JobExecutor {
event: 'job.start', event: 'job.start',
userId: job.userId, userId: job.userId,
jobId: job.id, jobId: job.id,
key: job.key key: job.key,
}) })
try { try {
@ -128,13 +128,13 @@ export default class JobExecutor {
this._logger.notice(`Execution terminated for ${job.id}.`, { this._logger.notice(`Execution terminated for ${job.id}.`, {
event: 'job.end', event: 'job.end',
runJobId runJobId,
}) })
} catch (error) { } catch (error) {
this._logger.error(`The execution of ${job.id} has failed.`, { this._logger.error(`The execution of ${job.id} has failed.`, {
event: 'job.end', event: 'job.end',
runJobId, runJobId,
error: serializeError(error) error: serializeError(error),
}) })
throw error throw error
@ -157,7 +157,7 @@ export default class JobExecutor {
calls: {}, calls: {},
runJobId, runJobId,
start: Date.now(), start: Date.now(),
timezone: schedule !== undefined ? schedule.timezone : undefined timezone: schedule !== undefined ? schedule.timezone : undefined,
} }
await Bluebird.map(paramsFlatVector, params => { await Bluebird.map(paramsFlatVector, params => {
@ -165,13 +165,13 @@ export default class JobExecutor {
event: 'jobCall.start', event: 'jobCall.start',
runJobId, runJobId,
method: job.method, method: job.method,
params params,
}) })
const call = execStatus.calls[runCallId] = { const call = execStatus.calls[runCallId] = {
method: job.method, method: job.method,
params, params,
start: Date.now() start: Date.now(),
} }
let promise = this.xo.callApiMethod(connection, job.method, assign({}, params)) let promise = this.xo.callApiMethod(connection, job.method, assign({}, params))
if (job.timeout) { if (job.timeout) {
@ -184,7 +184,7 @@ export default class JobExecutor {
event: 'jobCall.end', event: 'jobCall.end',
runJobId, runJobId,
runCallId, runCallId,
returnedValue: value returnedValue: value,
}) })
call.returnedValue = value call.returnedValue = value
@ -195,7 +195,7 @@ export default class JobExecutor {
event: 'jobCall.end', event: 'jobCall.end',
runJobId, runJobId,
runCallId, runCallId,
error: serializeError(reason) error: serializeError(reason),
}) })
call.error = reason call.error = reason
@ -203,7 +203,7 @@ export default class JobExecutor {
} }
) )
}, { }, {
concurrency: 2 concurrency: 2,
}) })
connection.close() connection.close()

View File

@ -18,21 +18,21 @@ describe('resolveParamsVector', function () {
type: 'crossProduct', type: 'crossProduct',
items: [{ items: [{
type: 'set', type: 'set',
values: [ { id: 3 }, { id: 7 }, { id: 10 } ] values: [ { id: 3 }, { id: 7 }, { id: 10 } ],
}, { }, {
type: 'set', type: 'set',
values: [ { value: 'foo' }, { value: 'bar' } ] values: [ { value: 'foo' }, { value: 'bar' } ],
}, { }, {
type: 'set', type: 'set',
values: [ { remote: 'local' } ] values: [ { remote: 'local' } ],
}] }],
} },
], ],
'cross product with `set` and `map`': [ 'cross product with `set` and `map`': [
// Expected result. // Expected result.
[ [
{ remote: 'local', id: 'vm:2' }, { remote: 'local', id: 'vm:2' },
{ remote: 'smb', id: 'vm:2' } { remote: 'smb', id: 'vm:2' },
], ],
// Entry. // Entry.
@ -40,7 +40,7 @@ describe('resolveParamsVector', function () {
type: 'crossProduct', type: 'crossProduct',
items: [{ items: [{
type: 'set', type: 'set',
values: [ { remote: 'local' }, { remote: 'smb' } ] values: [ { remote: 'local' }, { remote: 'smb' } ],
}, { }, {
type: 'map', type: 'map',
collection: { collection: {
@ -49,14 +49,14 @@ describe('resolveParamsVector', function () {
$pool: { __or: [ 'pool:1', 'pool:8', 'pool:12' ] }, $pool: { __or: [ 'pool:1', 'pool:8', 'pool:12' ] },
power_state: 'Running', power_state: 'Running',
tags: [ 'foo' ], tags: [ 'foo' ],
type: 'VM' type: 'VM',
} },
}, },
iteratee: { iteratee: {
type: 'extractProperties', type: 'extractProperties',
mapping: { id: 'id' } mapping: { id: 'id' },
} },
}] }],
}, },
// Context. // Context.
@ -68,28 +68,28 @@ describe('resolveParamsVector', function () {
$pool: 'pool:1', $pool: 'pool:1',
tags: [], tags: [],
type: 'VM', type: 'VM',
power_state: 'Halted' power_state: 'Halted',
}, { }, {
id: 'vm:2', id: 'vm:2',
$pool: 'pool:1', $pool: 'pool:1',
tags: [ 'foo' ], tags: [ 'foo' ],
type: 'VM', type: 'VM',
power_state: 'Running' power_state: 'Running',
}, { }, {
id: 'host:1', id: 'host:1',
type: 'host', type: 'host',
power_state: 'Running' power_state: 'Running',
}, { }, {
id: 'vm:3', id: 'vm:3',
$pool: 'pool:8', $pool: 'pool:8',
tags: [ 'foo' ], tags: [ 'foo' ],
type: 'VM', type: 'VM',
power_state: 'Halted' power_state: 'Halted',
}] }]
} },
} },
} },
] ],
}, ([ expectedResult, entry, context ], name) => { }, ([ expectedResult, entry, context ], name) => {
describe(`with ${name}`, () => { describe(`with ${name}`, () => {
it('Resolves params vector', () => { it('Resolves params vector', () => {

View File

@ -105,12 +105,12 @@ function getArgs () {
default: { default: {
limit: 100, limit: 100,
json: false, json: false,
help: false help: false,
}, },
alias: { alias: {
limit: 'n', limit: 'n',
help: 'h' help: 'h',
} },
}) })
const patterns = {} const patterns = {}
@ -176,7 +176,7 @@ export default async function main () {
} }
const config = await appConf.load('xo-server', { const config = await appConf.load('xo-server', {
ignoreUnknownFormats: true ignoreUnknownFormats: true,
}) })
if (args.repair) { if (args.repair) {

View File

@ -6,7 +6,7 @@ import { isArray, map } from 'lodash'
// =================================================================== // ===================================================================
const parse = createParser({ const parse = createParser({
keyTransform: key => key.slice(5).toLowerCase() keyTransform: key => key.slice(5).toLowerCase(),
}) })
const makeFunction = command => (fields, ...args) => const makeFunction = command => (fields, ...args) =>
execa.stdout(command, [ execa.stdout(command, [
@ -18,7 +18,7 @@ const makeFunction = command => (fields, ...args) =>
'b', 'b',
'-o', '-o',
String(fields), String(fields),
...args ...args,
]).then(stdout => map( ]).then(stdout => map(
splitLines(stdout), splitLines(stdout),
isArray(fields) isArray(fields)

View File

@ -4,32 +4,32 @@ import { forEach } from 'lodash'
import { thunkToArray } from './utils' import { thunkToArray } from './utils'
import { import {
crossProduct, crossProduct,
mergeObjects mergeObjects,
} from './math' } from './math'
describe('mergeObjects', function () { describe('mergeObjects', function () {
forEach({ forEach({
'Two sets of one': [ 'Two sets of one': [
{a: 1, b: 2}, {a: 1}, {b: 2} {a: 1, b: 2}, {a: 1}, {b: 2},
], ],
'Two sets of two': [ 'Two sets of two': [
{a: 1, b: 2, c: 3, d: 4}, {a: 1, b: 2}, {c: 3, d: 4} {a: 1, b: 2, c: 3, d: 4}, {a: 1, b: 2}, {c: 3, d: 4},
], ],
'Three sets': [ 'Three sets': [
{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}, {a: 1}, {b: 2, c: 3}, {d: 4, e: 5, f: 6} {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}, {a: 1}, {b: 2, c: 3}, {d: 4, e: 5, f: 6},
], ],
'One set': [ 'One set': [
{a: 1, b: 2}, {a: 1, b: 2} {a: 1, b: 2}, {a: 1, b: 2},
], ],
'Empty set': [ 'Empty set': [
{a: 1}, {a: 1}, {} {a: 1}, {a: 1}, {},
], ],
'All empty': [ 'All empty': [
{}, {}, {} {}, {}, {},
], ],
'No set': [ 'No set': [
{} {},
] ],
}, ([ resultSet, ...sets ], name) => { }, ([ resultSet, ...sets ], name) => {
describe(`with ${name}`, () => { describe(`with ${name}`, () => {
it('Assembles all given param sets in on set', function () { it('Assembles all given param sets in on set', function () {
@ -47,23 +47,23 @@ describe('crossProduct', function () {
forEach({ forEach({
'2 sets of 2 items to multiply': [ '2 sets of 2 items to multiply': [
[10, 14, 15, 21], [[2, 3], [5, 7]], multiplyTest [10, 14, 15, 21], [[2, 3], [5, 7]], multiplyTest,
], ],
'3 sets of 2 items to multiply': [ '3 sets of 2 items to multiply': [
[110, 130, 154, 182, 165, 195, 231, 273], [[2, 3], [5, 7], [11, 13]], multiplyTest [110, 130, 154, 182, 165, 195, 231, 273], [[2, 3], [5, 7], [11, 13]], multiplyTest,
], ],
'2 sets of 3 items to multiply': [ '2 sets of 3 items to multiply': [
[14, 22, 26, 21, 33, 39, 35, 55, 65], [[2, 3, 5], [7, 11, 13]], multiplyTest [14, 22, 26, 21, 33, 39, 35, 55, 65], [[2, 3, 5], [7, 11, 13]], multiplyTest,
], ],
'2 sets of 2 items to add': [ '2 sets of 2 items to add': [
[7, 9, 8, 10], [[2, 3], [5, 7]], addTest [7, 9, 8, 10], [[2, 3], [5, 7]], addTest,
], ],
'3 sets of 2 items to add': [ '3 sets of 2 items to add': [
[18, 20, 20, 22, 19, 21, 21, 23], [[2, 3], [5, 7], [11, 13]], addTest [18, 20, 20, 22, 19, 21, 21, 23], [[2, 3], [5, 7], [11, 13]], addTest,
], ],
'2 sets of 3 items to add': [ '2 sets of 3 items to add': [
[9, 13, 15, 10, 14, 16, 12, 16, 18], [[2, 3, 5], [7, 11, 13]], addTest [9, 13, 15, 10, 14, 16, 12, 16, 18], [[2, 3, 5], [7, 11, 13]], addTest,
] ],
}, ([ product, items, cb ], name) => { }, ([ product, items, cb ], name) => {
describe(`with ${name}`, () => { describe(`with ${name}`, () => {
it('Crosses sets of values with a crossProduct callback', function () { it('Crosses sets of values with a crossProduct callback', function () {

View File

@ -3,7 +3,7 @@ import {EventEmitter} from 'events'
import { import {
forEach, forEach,
isEmpty, isEmpty,
isString isString,
} from './utils' } from './utils'
// =================================================================== // ===================================================================

View File

@ -3,7 +3,7 @@ import Model from '../model'
import { import {
forEach, forEach,
mapToArray, mapToArray,
multiKeyHash multiKeyHash,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -21,7 +21,7 @@ Acl.create = (subject, object, action) => {
id: hash, id: hash,
subject, subject,
object, object,
action action,
})) }))
} }

View File

@ -17,7 +17,7 @@ export class PluginsMetadata extends Collection {
return /* await */ this.update({ return /* await */ this.update({
id, id,
autoload: autoload ? 'true' : 'false', autoload: autoload ? 'true' : 'false',
configuration: configuration && JSON.stringify(configuration) configuration: configuration && JSON.stringify(configuration),
}) })
} }
@ -29,7 +29,7 @@ export class PluginsMetadata extends Collection {
return /* await */ this.save({ return /* await */ this.save({
...pluginMetadata.properties, ...pluginMetadata.properties,
...data ...data,
}) })
} }

View File

@ -1,7 +1,7 @@
import Collection from '../collection/redis' import Collection from '../collection/redis'
import Model from '../model' import Model from '../model'
import { import {
forEach forEach,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -18,7 +18,7 @@ export class Remotes extends Collection {
name, name,
url, url,
enabled: false, enabled: false,
error: '' error: '',
})) }))
} }

View File

@ -18,7 +18,7 @@ export class Schedules extends Collection {
cron, cron,
enabled, enabled,
name, name,
timezone timezone,
})) }))
} }

View File

@ -11,7 +11,7 @@ import { parseProp } from './utils'
export default class User extends Model {} export default class User extends Model {}
User.prototype.default = { User.prototype.default = {
permission: 'none' permission: 'none',
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -43,8 +43,8 @@ export class Users extends Collection {
? undefined ? undefined
: JSON.stringify(tmp) : JSON.stringify(tmp)
user.preferences = isEmpty(tmp = user.preferences) user.preferences = isEmpty(tmp = user.preferences)
? undefined ? undefined
: JSON.stringify(tmp) : JSON.stringify(tmp)
return /* await */ this.update(user) return /* await */ this.update(user)
} }

View File

@ -13,14 +13,14 @@ export default function proxyConsole (ws, vmConsole, sessionId) {
const socket = connect({ const socket = connect({
host: url.host, host: url.host,
port: url.port || 443, port: url.port || 443,
rejectUnauthorized: false rejectUnauthorized: false,
}, () => { }, () => {
// Write headers. // Write headers.
socket.write([ socket.write([
`CONNECT ${url.path} HTTP/1.0`, `CONNECT ${url.path} HTTP/1.0`,
`Host: ${url.hostname}`, `Host: ${url.hostname}`,
`Cookie: session_id=${sessionId}`, `Cookie: session_id=${sessionId}`,
'', '' '', '',
].join('\r\n')) ].join('\r\n'))
const onSend = (error) => { const onSend = (error) => {

View File

@ -29,7 +29,7 @@ xo-server-recover-account <user name or email>
} }
const xo = new Xo(await appConf.load('xo-server', { const xo = new Xo(await appConf.load('xo-server', {
ignoreUnknownFormats: true ignoreUnknownFormats: true,
})) }))
const user = await xo.getUserByName(name, true) const user = await xo.getUserByName(name, true)

View File

@ -7,7 +7,7 @@ import {
addChecksumToReadStream, addChecksumToReadStream,
getPseudoRandomBytes, getPseudoRandomBytes,
streamToBuffer, streamToBuffer,
validChecksumOfReadStream validChecksumOfReadStream,
} from '../utils' } from '../utils'
export default class RemoteHandlerAbstract { export default class RemoteHandlerAbstract {
@ -56,14 +56,14 @@ export default class RemoteHandlerAbstract {
throw new Error('output and input did not match') throw new Error('output and input did not match')
} }
return { return {
success: true success: true,
} }
} catch (error) { } catch (error) {
return { return {
success: false, success: false,
step, step,
file: testFileName, file: testFileName,
error: error.message || String(error) error: error.message || String(error),
} }
} finally { } finally {
this.unlink(testFileName)::ignoreErrors() this.unlink(testFileName)::ignoreErrors()
@ -73,7 +73,7 @@ export default class RemoteHandlerAbstract {
async outputFile (file, data, options) { async outputFile (file, data, options) {
return this._outputFile(file, data, { return this._outputFile(file, data, {
flags: 'wx', flags: 'wx',
...options ...options,
}) })
} }
@ -127,7 +127,7 @@ export default class RemoteHandlerAbstract {
promise, promise,
this.getSize(file).then(size => { this.getSize(file).then(size => {
stream.length = size stream.length = size
})::ignoreErrors() })::ignoreErrors(),
]) ])
} }
@ -175,7 +175,7 @@ export default class RemoteHandlerAbstract {
} = {}) { } = {}) {
const streamP = this._createOutputStream(file, { const streamP = this._createOutputStream(file, {
flags: 'wx', flags: 'wx',
...options ...options,
}) })
if (!checksum) { if (!checksum) {
@ -202,7 +202,7 @@ export default class RemoteHandlerAbstract {
} }
async unlink (file, { async unlink (file, {
checksum = true checksum = true,
} = {}) { } = {}) {
if (checksum) { if (checksum) {
this._unlink(`${file}.checksum`)::ignoreErrors() this._unlink(`${file}.checksum`)::ignoreErrors()

View File

@ -24,7 +24,7 @@ export default class NfsHandler extends LocalHandler {
const match = regex.exec(m) const match = regex.exec(m)
mounted[match[3]] = { mounted[match[3]] = {
host: match[1], host: match[1],
share: match[2] share: match[2],
} }
} }
}) })

View File

@ -3,7 +3,7 @@ import Smb2 from '@marsaud/smb2-promise'
import RemoteHandlerAbstract from './abstract' import RemoteHandlerAbstract from './abstract'
import { import {
noop, noop,
pFinally pFinally,
} from '../utils' } from '../utils'
// Normalize the error code for file not found. // Normalize the error code for file not found.
@ -19,8 +19,8 @@ const normalizeError = error => {
configurable: true, configurable: true,
readable: true, readable: true,
value: 'ENOENT', value: 'ENOENT',
writable: true writable: true,
} },
}) })
: error : error
} }
@ -41,7 +41,7 @@ export default class SmbHandler extends RemoteHandlerAbstract {
domain: remote.domain, domain: remote.domain,
username: remote.username, username: remote.username,
password: remote.password, password: remote.password,
autoCloseTimeout: 0 autoCloseTimeout: 0,
}) })
} }

View File

@ -4,25 +4,25 @@ export default {
properties: { properties: {
id: { id: {
type: 'string', type: 'string',
description: 'unique identifier for this ACL' description: 'unique identifier for this ACL',
}, },
action: { action: {
type: 'string', type: 'string',
description: 'permission (or role)' description: 'permission (or role)',
}, },
object: { object: {
type: 'string', type: 'string',
description: 'item (or set)' description: 'item (or set)',
}, },
subject: { subject: {
type: 'string', type: 'string',
description: 'user (or group)' description: 'user (or group)',
} },
}, },
required: [ required: [
'id', 'id',
'action', 'action',
'object', 'object',
'subject' 'subject',
] ],
} }

View File

@ -3,41 +3,41 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
type: { type: {
enum: ['call'] enum: ['call'],
}, },
id: { id: {
type: 'string', type: 'string',
description: 'job identifier' description: 'job identifier',
}, },
name: { name: {
type: 'string', type: 'string',
description: 'human readable name' description: 'human readable name',
}, },
userId: { userId: {
type: 'string', type: 'string',
description: 'identifier of the user who have created the job (the permissions of the user are used by the job)' description: 'identifier of the user who have created the job (the permissions of the user are used by the job)',
}, },
key: { key: {
type: 'string' type: 'string',
// TODO description // TODO description
}, },
method: { method: {
type: 'string', type: 'string',
description: 'called method' description: 'called method',
}, },
paramsVector: { paramsVector: {
type: 'object' type: 'object',
}, },
timeout: { timeout: {
type: 'number', type: 'number',
description: 'number of milliseconds after which the job is considered failed' description: 'number of milliseconds after which the job is considered failed',
} },
}, },
required: [ required: [
'type', 'type',
'id', 'id',
'userId', 'userId',
'key', 'key',
'method' 'method',
] ],
} }

View File

@ -4,26 +4,26 @@ export default {
properties: { properties: {
id: { id: {
type: 'string', type: 'string',
description: 'unique identifier for this log' description: 'unique identifier for this log',
}, },
time: { time: {
type: 'string', type: 'string',
description: 'timestamp (in milliseconds) of this log' description: 'timestamp (in milliseconds) of this log',
}, },
message: { message: {
type: 'string', type: 'string',
description: 'human readable (short) description of this log' description: 'human readable (short) description of this log',
}, },
namespace: { namespace: {
type: 'string', type: 'string',
description: 'space to store logs' description: 'space to store logs',
}, },
data: {} data: {},
}, },
required: [ required: [
'id', 'id',
'time', 'time',
'message', 'message',
'namespace' 'namespace',
] ],
} }

View File

@ -3,31 +3,31 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
event: { event: {
enum: ['jobCall.end'] enum: ['jobCall.end'],
}, },
runJobId: { runJobId: {
type: 'string', type: 'string',
description: 'instance id of this job' description: 'instance id of this job',
}, },
runCallId: { runCallId: {
type: 'string', type: 'string',
description: 'instance id of this call' description: 'instance id of this call',
}, },
error: { error: {
type: 'object', type: 'object',
description: 'describe one failure, exists if the call has failed' description: 'describe one failure, exists if the call has failed',
}, },
returnedValue: { returnedValue: {
description: 'call\'s result, exists if the call is a success' description: 'call\'s result, exists if the call is a success',
} },
}, },
required: [ required: [
'event', 'event',
'runJobId', 'runJobId',
'runCallId' 'runCallId',
], ],
oneOf: [ oneOf: [
{ required: ['error'] }, { required: ['error'] },
{ required: ['returnedValue'] } { required: ['returnedValue'] },
] ],
} }

View File

@ -3,25 +3,25 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
event: { event: {
enum: ['jobCall.start'] enum: ['jobCall.start'],
}, },
runJobId: { runJobId: {
type: 'string', type: 'string',
description: 'instance id of this job' description: 'instance id of this job',
}, },
method: { method: {
type: 'string', type: 'string',
description: 'method linked to this call' description: 'method linked to this call',
}, },
params: { params: {
type: 'object', type: 'object',
description: 'params of the called method' description: 'params of the called method',
} },
}, },
required: [ required: [
'event', 'event',
'runJobId', 'runJobId',
'method', 'method',
'params' 'params',
] ],
} }

View File

@ -3,19 +3,19 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
event: { event: {
enum: ['job.end'] enum: ['job.end'],
}, },
runJobId: { runJobId: {
type: 'string', type: 'string',
description: 'instance id of this job' description: 'instance id of this job',
}, },
error: { error: {
type: 'object', type: 'object',
description: 'describe one failure, exists if no call has been made' description: 'describe one failure, exists if no call has been made',
} },
}, },
required: [ required: [
'event', 'event',
'runJobId' 'runJobId',
] ],
} }

View File

@ -3,24 +3,24 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
event: { event: {
enum: ['job.start'] enum: ['job.start'],
}, },
userId: { userId: {
type: 'string', type: 'string',
description: 'user who executes this job' description: 'user who executes this job',
}, },
jobId: { jobId: {
type: 'string', type: 'string',
description: 'identifier of this job' description: 'identifier of this job',
}, },
key: { key: {
type: 'string' type: 'string',
} },
}, },
required: [ required: [
'event', 'event',
'userId', 'userId',
'jobId', 'jobId',
'key' 'key',
] ],
} }

View File

@ -4,46 +4,46 @@ export default {
properties: { properties: {
id: { id: {
type: 'string', type: 'string',
description: 'unique identifier for this plugin' description: 'unique identifier for this plugin',
}, },
name: { name: {
type: 'string', type: 'string',
description: 'unique human readable name for this plugin' description: 'unique human readable name for this plugin',
}, },
autoload: { autoload: {
type: 'boolean', type: 'boolean',
description: 'whether this plugin is loaded on startup' description: 'whether this plugin is loaded on startup',
}, },
loaded: { loaded: {
type: 'boolean', type: 'boolean',
description: 'whether or not this plugin is currently loaded' description: 'whether or not this plugin is currently loaded',
}, },
unloadable: { unloadable: {
type: 'boolean', type: 'boolean',
default: true, default: true,
description: 'whether or not this plugin can be unloaded' description: 'whether or not this plugin can be unloaded',
}, },
configuration: { configuration: {
type: 'object', type: 'object',
description: 'current configuration of this plugin (not present if none)' description: 'current configuration of this plugin (not present if none)',
}, },
configurationSchema: { configurationSchema: {
$ref: 'http://json-schema.org/draft-04/schema#', $ref: 'http://json-schema.org/draft-04/schema#',
description: 'configuration schema for this plugin (not present if not configurable)' description: 'configuration schema for this plugin (not present if not configurable)',
}, },
testable: { testable: {
type: 'boolean', type: 'boolean',
description: 'whether or not this plugin can be tested' description: 'whether or not this plugin can be tested',
}, },
testSchema: { testSchema: {
$ref: 'http://json-schema.org/draft-04/schema#', $ref: 'http://json-schema.org/draft-04/schema#',
description: 'test schema for this plugin' description: 'test schema for this plugin',
} },
}, },
required: [ required: [
'id', 'id',
'name', 'name',
'autoload', 'autoload',
'loaded' 'loaded',
] ],
} }

View File

@ -4,22 +4,22 @@ export default {
properties: { properties: {
id: { id: {
type: 'string', type: 'string',
description: 'unique identifier for this user' description: 'unique identifier for this user',
}, },
email: { email: {
type: 'string', type: 'string',
description: 'email address of this user' description: 'email address of this user',
}, },
groups: { groups: {
type: 'array', type: 'array',
items: { items: {
type: 'string' type: 'string',
}, },
description: 'identifier of groups this user belong to' description: 'identifier of groups this user belong to',
}, },
permission: { permission: {
enum: ['none', 'read', 'write', 'admin'], enum: ['none', 'read', 'write', 'admin'],
description: 'root permission for this user, none and admin are the only significant ones' description: 'root permission for this user, none and admin are the only significant ones',
}, },
preferences: { preferences: {
type: 'object', type: 'object',
@ -31,20 +31,20 @@ export default {
type: 'object', type: 'object',
properties: { properties: {
key: { type: 'string' }, key: { type: 'string' },
title: { type: 'string' } title: { type: 'string' },
}, },
required: [ required: [
'key', 'key',
'title' 'title',
] ],
} },
} },
}, },
description: 'various user preferences' description: 'various user preferences',
} },
}, },
required: [ required: [
'id', 'id',
'email' 'email',
] ],
} }

View File

@ -30,11 +30,11 @@ import {
fromCallback, fromCallback,
isPromise, isPromise,
promisify, promisify,
reflect as pReflect reflect as pReflect,
} from 'promise-toolbox' } from 'promise-toolbox'
import { import {
createHash, createHash,
randomBytes randomBytes,
} from 'crypto' } from 'crypto'
// =================================================================== // ===================================================================
@ -111,7 +111,7 @@ export const diffItems = (coll1, coll2) => {
const ALGORITHM_TO_ID = { const ALGORITHM_TO_ID = {
md5: '1', md5: '1',
sha256: '5', sha256: '5',
sha512: '6' sha512: '6',
} }
const ID_TO_ALGORITHM = invert(ALGORITHM_TO_ID) const ID_TO_ALGORITHM = invert(ALGORITHM_TO_ID)
@ -258,7 +258,7 @@ export const generateToken = (randomBytes => {
export const formatXml = (function () { export const formatXml = (function () {
const builder = new xml2js.Builder({ const builder = new xml2js.Builder({
headless: true headless: true,
}) })
return (...args) => builder.buildObject(...args) return (...args) => builder.buildObject(...args)
@ -267,7 +267,7 @@ export const formatXml = (function () {
export const parseXml = (function () { export const parseXml = (function () {
const opts = { const opts = {
mergeAttrs: true, mergeAttrs: true,
explicitArray: false explicitArray: false,
} }
return (xml) => { return (xml) => {
@ -315,7 +315,7 @@ export const lightSet = collection => {
return set return set
}, },
has: value => data[value], has: value => data[value],
toArray: () => keys(data) toArray: () => keys(data),
} }
return set return set
} }
@ -375,7 +375,7 @@ export {
lastly as pFinally, lastly as pFinally,
promisify, promisify,
promisifyAll, promisifyAll,
reflect as pReflect reflect as pReflect,
} from 'promise-toolbox' } from 'promise-toolbox'
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -489,7 +489,7 @@ export const resolveSubpath = (root, path) =>
export const streamToArray = (stream, { export const streamToArray = (stream, {
filter, filter,
mapper mapper,
} = {}) => new Promise((resolve, reject) => { } = {}) => new Promise((resolve, reject) => {
stream = highland(stream).stopOnError(reject) stream = highland(stream).stopOnError(reject)
if (filter) { if (filter) {
@ -526,7 +526,7 @@ export const scheduleFn = (cronTime, fn, timeZone) => {
} }
}, },
start: true, start: true,
timeZone timeZone,
}) })
return () => { return () => {
@ -540,7 +540,7 @@ export const scheduleFn = (cronTime, fn, timeZone) => {
export const serializeError = error => ({ export const serializeError = error => ({
message: error.message, message: error.message,
stack: error.stack, stack: error.stack,
...error // Copy enumerable properties. ...error, // Copy enumerable properties.
}) })
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -598,7 +598,7 @@ export const splitFirst = (string, separator) => {
const i = string.indexOf(separator) const i = string.indexOf(separator)
return i === -1 ? null : [ return i === -1 ? null : [
string.slice(0, i), string.slice(0, i),
string.slice(i + separator.length) string.slice(i + separator.length),
] ]
} }

View File

@ -9,7 +9,7 @@ import {
formatXml, formatXml,
generateToken, generateToken,
parseSize, parseSize,
pSettle pSettle,
} from './utils' } from './utils'
// =================================================================== // ===================================================================
@ -57,7 +57,7 @@ describe('diffItems', () => {
['baz', 'foo'] ['baz', 'foo']
)).toEqual([ )).toEqual([
['bar'], ['bar'],
['baz'] ['baz'],
]) ])
}) })
}) })
@ -109,9 +109,9 @@ describe('formatXml()', function () {
foo: { foo: {
bar: [ bar: [
{$: {baz: 'plop'}}, {$: {baz: 'plop'}},
{$: {baz: 'plip'}} {$: {baz: 'plip'}},
] ],
} },
})).toBe(`<foo> })).toBe(`<foo>
<bar baz="plop"/> <bar baz="plop"/>
<bar baz="plip"/> <bar baz="plip"/>
@ -157,11 +157,11 @@ describe('pSettle()', () => {
const [ const [
status1, status1,
status2, status2,
status3 status3,
] = await pSettle([ ] = await pSettle([
Promise.resolve(42), Promise.resolve(42),
Math.PI, Math.PI,
Promise.reject(rejection) Promise.reject(rejection),
]) ])
expect(status1.isRejected()).toBe(false) expect(status1.isRejected()).toBe(false)
@ -187,11 +187,11 @@ describe('pSettle()', () => {
const { const {
a: status1, a: status1,
b: status2, b: status2,
c: status3 c: status3,
} = await pSettle({ } = await pSettle({
a: Promise.resolve(42), a: Promise.resolve(42),
b: Math.PI, b: Math.PI,
c: Promise.reject(rejection) c: Promise.reject(rejection),
}) })
expect(status1.isRejected()).toBe(false) expect(status1.isRejected()).toBe(false)

View File

@ -8,7 +8,7 @@ import isEqual from 'lodash/isEqual'
import constantStream from './constant-stream' import constantStream from './constant-stream'
import { import {
noop, noop,
streamToBuffer streamToBuffer,
} from './utils' } from './utils'
const VHD_UTIL_DEBUG = 0 const VHD_UTIL_DEBUG = 0
@ -57,7 +57,7 @@ const fuFooter = fu.struct([
fu.uint32('fileFormatVersion'), // 12 fu.uint32('fileFormatVersion'), // 12
fu.struct('dataOffset', [ fu.struct('dataOffset', [
fu.uint32('high'), // 16 fu.uint32('high'), // 16
fu.uint32('low') // 20 fu.uint32('low'), // 20
]), ]),
fu.uint32('timestamp'), // 24 fu.uint32('timestamp'), // 24
fu.char('creatorApplication', 4), // 28 fu.char('creatorApplication', 4), // 28
@ -65,34 +65,34 @@ const fuFooter = fu.struct([
fu.uint32('creatorHostOs'), // 36 fu.uint32('creatorHostOs'), // 36
fu.struct('originalSize', [ // At the creation, current size of the hard disk. fu.struct('originalSize', [ // At the creation, current size of the hard disk.
fu.uint32('high'), // 40 fu.uint32('high'), // 40
fu.uint32('low') // 44 fu.uint32('low'), // 44
]), ]),
fu.struct('currentSize', [ // Current size of the virtual disk. At the creation: currentSize = originalSize. fu.struct('currentSize', [ // Current size of the virtual disk. At the creation: currentSize = originalSize.
fu.uint32('high'), // 48 fu.uint32('high'), // 48
fu.uint32('low') // 52 fu.uint32('low'), // 52
]), ]),
fu.struct('diskGeometry', [ fu.struct('diskGeometry', [
fu.uint16('cylinders'), // 56 fu.uint16('cylinders'), // 56
fu.uint8('heads'), // 58 fu.uint8('heads'), // 58
fu.uint8('sectorsPerTrackCylinder') // 59 fu.uint8('sectorsPerTrackCylinder'), // 59
]), ]),
fu.uint32('diskType'), // 60 Disk type, must be equal to HARD_DISK_TYPE_DYNAMIC/HARD_DISK_TYPE_DIFFERENCING. fu.uint32('diskType'), // 60 Disk type, must be equal to HARD_DISK_TYPE_DYNAMIC/HARD_DISK_TYPE_DIFFERENCING.
fu.uint32('checksum'), // 64 fu.uint32('checksum'), // 64
fu.uint8('uuid', 16), // 68 fu.uint8('uuid', 16), // 68
fu.char('saved'), // 84 fu.char('saved'), // 84
fu.char('hidden'), // 85 fu.char('hidden'), // 85
fu.char('reserved', 426) // 86 fu.char('reserved', 426), // 86
]) ])
const fuHeader = fu.struct([ const fuHeader = fu.struct([
fu.char('cookie', 8), fu.char('cookie', 8),
fu.struct('dataOffset', [ fu.struct('dataOffset', [
fu.uint32('high'), fu.uint32('high'),
fu.uint32('low') fu.uint32('low'),
]), ]),
fu.struct('tableOffset', [ // Absolute byte offset of the Block Allocation Table. fu.struct('tableOffset', [ // Absolute byte offset of the Block Allocation Table.
fu.uint32('high'), fu.uint32('high'),
fu.uint32('low') fu.uint32('low'),
]), ]),
fu.uint32('headerVersion'), fu.uint32('headerVersion'),
fu.uint32('maxTableEntries'), // Max entries in the Block Allocation Table. fu.uint32('maxTableEntries'), // Max entries in the Block Allocation Table.
@ -109,10 +109,10 @@ const fuHeader = fu.struct([
fu.uint32('reserved'), fu.uint32('reserved'),
fu.struct('platformDataOffset', [ // Absolute byte offset of the locator data. fu.struct('platformDataOffset', [ // Absolute byte offset of the locator data.
fu.uint32('high'), fu.uint32('high'),
fu.uint32('low') fu.uint32('low'),
]) ]),
], VHD_PARENT_LOCATOR_ENTRIES), ], VHD_PARENT_LOCATOR_ENTRIES),
fu.char('reserved2', 256) fu.char('reserved2', 256),
]) ])
// =================================================================== // ===================================================================
@ -191,7 +191,7 @@ class Vhd {
_readStream (start, n) { _readStream (start, n) {
return this._handler.createReadStream(this._path, { return this._handler.createReadStream(this._path, {
start, start,
end: start + n - 1 // end is inclusive end: start + n - 1, // end is inclusive
}) })
} }
@ -313,7 +313,7 @@ class Vhd {
? { bitmap: buf } ? { bitmap: buf }
: { : {
bitmap: buf.slice(0, this.bitmapSize), bitmap: buf.slice(0, this.bitmapSize),
data: buf.slice(this.bitmapSize) data: buf.slice(this.bitmapSize),
} }
) )
} }
@ -370,7 +370,7 @@ class Vhd {
// TODO: could probably be merged in remote handlers. // TODO: could probably be merged in remote handlers.
return this._handler.createOutputStream(this._path, { return this._handler.createOutputStream(this._path, {
flags: 'r+', flags: 'r+',
start: offset start: offset,
}).then( }).then(
Buffer.isBuffer(data) Buffer.isBuffer(data)
? stream => new Promise((resolve, reject) => { ? stream => new Promise((resolve, reject) => {
@ -413,7 +413,7 @@ class Vhd {
if (tableOffset + batSize < sectorsToBytes(firstSector)) { if (tableOffset + batSize < sectorsToBytes(firstSector)) {
return Promise.all([ return Promise.all([
extendBat(), extendBat(),
this.writeHeader() this.writeHeader(),
]) ])
} }
@ -429,7 +429,7 @@ class Vhd {
this._setBatEntry(first, newFirstSector), this._setBatEntry(first, newFirstSector),
this.writeHeader(), this.writeHeader(),
this.writeFooter() this.writeFooter(),
]) ])
} }
@ -460,7 +460,7 @@ class Vhd {
sectorsToBytes(blockAddr) sectorsToBytes(blockAddr)
), ),
this._setBatEntry(blockId, blockAddr) this._setBatEntry(blockId, blockAddr),
]) ])
return blockAddr return blockAddr
@ -585,7 +585,7 @@ export default async function vhdMerge (
// Reading footer and header. // Reading footer and header.
await Promise.all([ await Promise.all([
parentVhd.readHeaderAndFooter(), parentVhd.readHeaderAndFooter(),
childVhd.readHeaderAndFooter() childVhd.readHeaderAndFooter(),
]) ])
assert(childVhd.header.blockSize === parentVhd.header.blockSize) assert(childVhd.header.blockSize === parentVhd.header.blockSize)
@ -611,7 +611,7 @@ export default async function vhdMerge (
// Read allocation table of child/parent. // Read allocation table of child/parent.
await Promise.all([ await Promise.all([
parentVhd.readBlockTable(), parentVhd.readBlockTable(),
childVhd.readBlockTable() childVhd.readBlockTable(),
]) ])
await parentVhd.ensureBatSize(childVhd.header.maxTableEntries) await parentVhd.ensureBatSize(childVhd.header.maxTableEntries)
@ -648,7 +648,7 @@ export async function chainVhd (
const childVhd = new Vhd(childHandler, childPath) const childVhd = new Vhd(childHandler, childPath)
await Promise.all([ await Promise.all([
parentVhd.readHeaderAndFooter(), parentVhd.readHeaderAndFooter(),
childVhd.readHeaderAndFooter() childVhd.readHeaderAndFooter(),
]) ])
const { header } = childVhd const { header } = childVhd

View File

@ -1,5 +1,5 @@
import { import {
startsWith startsWith,
} from 'lodash' } from 'lodash'
import { import {
@ -10,23 +10,23 @@ import {
isEmpty, isEmpty,
mapFilter, mapFilter,
mapToArray, mapToArray,
parseXml parseXml,
} from './utils' } from './utils'
import { import {
isHostRunning, isHostRunning,
isVmHvm, isVmHvm,
isVmRunning, isVmRunning,
parseDateTime parseDateTime,
} from './xapi' } from './xapi'
import { import {
useUpdateSystem useUpdateSystem,
} from './xapi/utils' } from './xapi/utils'
// =================================================================== // ===================================================================
const { const {
defineProperties, defineProperties,
freeze freeze,
} = Object } = Object
function link (obj, prop, idField = '$id') { function link (obj, prop, idField = '$id') {
@ -83,8 +83,8 @@ const TRANSFORMS = {
xosanPackInstallationTime: toTimestamp(obj.other_config.xosan_pack_installation_time), xosanPackInstallationTime: toTimestamp(obj.other_config.xosan_pack_installation_time),
cpus: { cpus: {
cores: cpuInfo && +cpuInfo.cpu_count, cores: cpuInfo && +cpuInfo.cpu_count,
sockets: cpuInfo && +cpuInfo.socket_count sockets: cpuInfo && +cpuInfo.socket_count,
} },
// TODO // TODO
// - ? networks = networksByPool.items[pool.id] (network.$pool.id) // - ? networks = networksByPool.items[pool.id] (network.$pool.id)
@ -104,11 +104,11 @@ const TRANSFORMS = {
host (obj) { host (obj) {
const { const {
$metrics: metrics, $metrics: metrics,
other_config: otherConfig other_config: otherConfig,
software_version: softwareVersion,
} = obj } = obj
const isRunning = isHostRunning(obj) const isRunning = isHostRunning(obj)
const { software_version } = obj
let supplementalPacks, patches let supplementalPacks, patches
if (useUpdateSystem(obj)) { if (useUpdateSystem(obj)) {
@ -124,7 +124,7 @@ const TRANSFORMS = {
guidance: update.after_apply_guidance, guidance: update.after_apply_guidance,
hosts: link(update, 'hosts'), hosts: link(update, 'hosts'),
vdi: link(update, 'vdi'), vdi: link(update, 'vdi'),
size: update.installation_size size: update.installation_size,
} }
if (startsWith(update.name_label, 'XS')) { if (startsWith(update.name_label, 'XS')) {
@ -143,11 +143,11 @@ const TRANSFORMS = {
address: obj.address, address: obj.address,
bios_strings: obj.bios_strings, bios_strings: obj.bios_strings,
build: obj.software_version.build_number, build: softwareVersion.build_number,
enabled: Boolean(obj.enabled), enabled: Boolean(obj.enabled),
cpus: { cpus: {
cores: cpuInfo && +cpuInfo.cpu_count, cores: cpuInfo && +cpuInfo.cpu_count,
sockets: cpuInfo && +cpuInfo.socket_count sockets: cpuInfo && +cpuInfo.socket_count,
}, },
current_operations: obj.current_operations, current_operations: obj.current_operations,
hostname: obj.hostname, hostname: obj.hostname,
@ -164,7 +164,7 @@ const TRANSFORMS = {
return { return {
usage: total - free, usage: total - free,
size: total size: total,
} }
} }
@ -173,7 +173,7 @@ const TRANSFORMS = {
size: 0, size: 0,
// Deprecated // Deprecated
total: 0 total: 0,
} }
})(), })(),
patches: patches || link(obj, 'patches'), patches: patches || link(obj, 'patches'),
@ -183,7 +183,7 @@ const TRANSFORMS = {
: 'Unknown', : 'Unknown',
startTime: toTimestamp(otherConfig.boot_time), startTime: toTimestamp(otherConfig.boot_time),
supplementalPacks: supplementalPacks || supplementalPacks: supplementalPacks ||
mapFilter(software_version, (value, key) => { mapFilter(softwareVersion, (value, key) => {
let author, name let author, name
if (([ author, name ] = key.split(':')).length === 2) { if (([ author, name ] = key.split(':')).length === 2) {
const [ description, version ] = value.split(', ') const [ description, version ] = value.split(', ')
@ -191,14 +191,14 @@ const TRANSFORMS = {
name, name,
description, description,
author, author,
version: version.split(' ')[1] version: version.split(' ')[1],
} }
} }
}), }),
agentStartTime: toTimestamp(otherConfig.agent_start_time), agentStartTime: toTimestamp(otherConfig.agent_start_time),
rebootRequired: !isEmpty(obj.updates_requiring_reboot), rebootRequired: !isEmpty(obj.updates_requiring_reboot),
tags: obj.tags, tags: obj.tags,
version: obj.software_version.product_version, version: softwareVersion.product_version,
// TODO: dedupe. // TODO: dedupe.
PIFs: link(obj, 'PIFs'), PIFs: link(obj, 'PIFs'),
@ -208,7 +208,7 @@ const TRANSFORMS = {
PGPUs: link(obj, 'PGPUs'), PGPUs: link(obj, 'PGPUs'),
$PGPUs: link(obj, 'PGPUs'), $PGPUs: link(obj, 'PGPUs'),
$PBDs: link(obj, 'PBDs') $PBDs: link(obj, 'PBDs'),
// TODO: // TODO:
// - controller = vmControllersByContainer.items[host.id] // - controller = vmControllersByContainer.items[host.id]
@ -226,7 +226,7 @@ const TRANSFORMS = {
const { const {
$guest_metrics: guestMetrics, $guest_metrics: guestMetrics,
$metrics: metrics, $metrics: metrics,
other_config: otherConfig other_config: otherConfig,
} = obj } = obj
const isHvm = isVmHvm(obj) const isHvm = isVmHvm(obj)
@ -276,7 +276,7 @@ const TRANSFORMS = {
isRunning && metrics && xenTools isRunning && metrics && xenTools
? +metrics.VCPUs_number ? +metrics.VCPUs_number
: +obj.VCPUs_at_startup : +obj.VCPUs_at_startup
) ),
}, },
current_operations: obj.current_operations, current_operations: obj.current_operations,
docker: (function () { docker: (function () {
@ -287,14 +287,14 @@ const TRANSFORMS = {
if (monitor === 'False') { if (monitor === 'False') {
return { return {
enabled: false enabled: false,
} }
} }
const { const {
docker_ps: process, docker_ps: process,
docker_info: info, docker_info: info,
docker_version: version docker_version: version,
} = otherConfig } = otherConfig
return { return {
@ -302,7 +302,7 @@ const TRANSFORMS = {
info: info && parseXml(info).docker_info, info: info && parseXml(info).docker_info,
containers: ensureArray(process && parseXml(process).docker_ps.item), containers: ensureArray(process && parseXml(process).docker_ps.item),
process: process && parseXml(process).docker_ps, // deprecated (only used in v4) process: process && parseXml(process).docker_ps, // deprecated (only used in v4)
version: version && parseXml(version).docker_version version: version && parseXml(version).docker_version,
} }
})(), })(),
@ -317,7 +317,7 @@ const TRANSFORMS = {
const memory = { const memory = {
dynamic: [ dynamicMin, dynamicMax ], dynamic: [ dynamicMin, dynamicMax ],
static: [ staticMin, staticMax ] static: [ staticMin, staticMax ],
} }
const gmMemory = guestMetrics && guestMetrics.memory const gmMemory = guestMetrics && guestMetrics.memory
@ -365,13 +365,13 @@ const TRANSFORMS = {
// TODO: dedupe // TODO: dedupe
VGPUs: link(obj, 'VGPUs'), VGPUs: link(obj, 'VGPUs'),
$VGPUs: link(obj, 'VGPUs') $VGPUs: link(obj, 'VGPUs'),
} }
if (isHvm) { if (isHvm) {
({ ({
vga: vm.vga = 'cirrus', vga: vm.vga = 'cirrus',
videoram: vm.videoram = 4 videoram: vm.videoram = 4,
} = obj.platform) } = obj.platform)
} }
@ -418,7 +418,7 @@ const TRANSFORMS = {
return methods ? methods.split(',') : [] return methods ? methods.split(',') : []
})(), })(),
install_repository: otherConfig['install-repository'] install_repository: otherConfig['install-repository'],
} }
} }
@ -462,7 +462,7 @@ const TRANSFORMS = {
? link(obj, 'pool') ? link(obj, 'pool')
: link(obj.$PBDs[0], 'host') : link(obj.$PBDs[0], 'host')
), ),
$PBDs: link(obj, 'PBDs') $PBDs: link(obj, 'PBDs'),
} }
}, },
@ -475,7 +475,7 @@ const TRANSFORMS = {
attached: Boolean(obj.currently_attached), attached: Boolean(obj.currently_attached),
host: link(obj, 'host'), host: link(obj, 'host'),
SR: link(obj, 'SR'), SR: link(obj, 'SR'),
device_config: obj.device_config device_config: obj.device_config,
} }
}, },
@ -506,7 +506,7 @@ const TRANSFORMS = {
physical: Boolean(obj.physical), physical: Boolean(obj.physical),
vlan: +obj.VLAN, vlan: +obj.VLAN,
$host: link(obj, 'host'), $host: link(obj, 'host'),
$network: link(obj, 'network') $network: link(obj, 'network'),
} }
}, },
@ -524,7 +524,7 @@ const TRANSFORMS = {
usage: +obj.physical_utilisation, usage: +obj.physical_utilisation,
$SR: link(obj, 'SR'), $SR: link(obj, 'SR'),
$VBDs: link(obj, 'VBDs') $VBDs: link(obj, 'VBDs'),
} }
if (obj.is_a_snapshot) { if (obj.is_a_snapshot) {
@ -553,7 +553,7 @@ const TRANSFORMS = {
position: obj.userdevice, position: obj.userdevice,
read_only: obj.mode === 'RO', read_only: obj.mode === 'RO',
VDI: link(obj, 'VDI'), VDI: link(obj, 'VDI'),
VM: link(obj, 'VM') VM: link(obj, 'VM'),
} }
}, },
@ -571,7 +571,7 @@ const TRANSFORMS = {
MTU: +obj.MTU, MTU: +obj.MTU,
$network: link(obj, 'network'), $network: link(obj, 'network'),
$VM: link(obj, 'VM') $VM: link(obj, 'VM'),
} }
}, },
@ -587,7 +587,7 @@ const TRANSFORMS = {
other_config: obj.other_config, other_config: obj.other_config,
tags: obj.tags, tags: obj.tags,
PIFs: link(obj, 'PIFs'), PIFs: link(obj, 'PIFs'),
VIFs: link(obj, 'VIFs') VIFs: link(obj, 'VIFs'),
} }
}, },
@ -599,7 +599,7 @@ const TRANSFORMS = {
name: obj.name, name: obj.name,
time: toTimestamp(obj.timestamp), time: toTimestamp(obj.timestamp),
$object: obj.obj_uuid // Special link as it is already an UUID. $object: obj.obj_uuid, // Special link as it is already an UUID.
} }
}, },
@ -616,7 +616,7 @@ const TRANSFORMS = {
result: obj.result, result: obj.result,
status: obj.status, status: obj.status,
$host: link(obj, 'resident_on') $host: link(obj, 'resident_on'),
} }
}, },
@ -628,7 +628,7 @@ const TRANSFORMS = {
time: toTimestamp(obj.timestamp_applied), time: toTimestamp(obj.timestamp_applied),
pool_patch: link(obj, 'pool_patch', '$ref'), pool_patch: link(obj, 'pool_patch', '$ref'),
$host: link(obj, 'host') $host: link(obj, 'host'),
} }
}, },
@ -649,7 +649,7 @@ const TRANSFORMS = {
// version: obj.version, // version: obj.version,
// TODO: host.[$]pool_patches ←→ pool.[$]host_patches // TODO: host.[$]pool_patches ←→ pool.[$]host_patches
$host_patches: link(obj, 'host_patches') $host_patches: link(obj, 'host_patches'),
} }
}, },
@ -663,7 +663,7 @@ const TRANSFORMS = {
device_name: obj.device_name, device_name: obj.device_name,
pci_id: obj.pci_id, pci_id: obj.pci_id,
$host: link(obj, 'host') $host: link(obj, 'host'),
} }
}, },
@ -685,7 +685,7 @@ const TRANSFORMS = {
host: link(obj, 'host'), host: link(obj, 'host'),
$host: link(obj, 'host'), $host: link(obj, 'host'),
vgpus: link(obj, 'resident_VGPUs'), vgpus: link(obj, 'resident_VGPUs'),
$vgpus: link(obj, 'resident_VGPUs') $vgpus: link(obj, 'resident_VGPUs'),
} }
}, },
@ -701,7 +701,7 @@ const TRANSFORMS = {
otherConfig: obj.other_config, otherConfig: obj.other_config,
resident_on: link(obj, 'resident_on'), resident_on: link(obj, 'resident_on'),
vgpuType: link(obj, '$type'), vgpuType: link(obj, '$type'),
vm: link(obj, 'VM') vm: link(obj, 'VM'),
} }
}, },
@ -719,7 +719,7 @@ const TRANSFORMS = {
otherConfig: obj.other_config, otherConfig: obj.other_config,
pgpus: link(obj, 'PGPUs'), pgpus: link(obj, 'PGPUs'),
supportedVgpuTypes: link(obj, 'supported_VGPU_types'), supportedVgpuTypes: link(obj, 'supported_VGPU_types'),
vgpus: link(obj, 'VGPUs') vgpus: link(obj, 'VGPUs'),
} }
}, },
@ -738,9 +738,9 @@ const TRANSFORMS = {
modelName: obj.model_name, modelName: obj.model_name,
pgpus: link(obj, 'enabled_on_PGPUs'), pgpus: link(obj, 'enabled_on_PGPUs'),
vendorName: obj.vendor_name, vendorName: obj.vendor_name,
vgpus: link(obj, 'VGPUs') vgpus: link(obj, 'VGPUs'),
} }
} },
} }
// =================================================================== // ===================================================================
@ -774,11 +774,11 @@ export default xapiObj => {
// Internal properties. // Internal properties.
defineProperties(xoObj, { defineProperties(xoObj, {
_xapiId: { _xapiId: {
value: xapiObj.$id value: xapiObj.$id,
}, },
_xapiRef: { _xapiRef: {
value: xapiObj.$ref value: xapiObj.$ref,
} },
}) })
// Freezes and returns the new object. // Freezes and returns the new object.

View File

@ -14,14 +14,14 @@ const RRD_STEP_FROM_STRING = {
'seconds': RRD_STEP_SECONDS, 'seconds': RRD_STEP_SECONDS,
'minutes': RRD_STEP_MINUTES, 'minutes': RRD_STEP_MINUTES,
'hours': RRD_STEP_HOURS, 'hours': RRD_STEP_HOURS,
'days': RRD_STEP_DAYS 'days': RRD_STEP_DAYS,
} }
const RRD_POINTS_PER_STEP = { const RRD_POINTS_PER_STEP = {
[RRD_STEP_SECONDS]: 120, [RRD_STEP_SECONDS]: 120,
[RRD_STEP_MINUTES]: 120, [RRD_STEP_MINUTES]: 120,
[RRD_STEP_HOURS]: 168, [RRD_STEP_HOURS]: 168,
[RRD_STEP_DAYS]: 366 [RRD_STEP_DAYS]: 366,
} }
export class XapiStatsError extends BaseError {} export class XapiStatsError extends BaseError {}
@ -61,12 +61,12 @@ function getNewHostStats () {
cpus: [], cpus: [],
pifs: { pifs: {
rx: [], rx: [],
tx: [] tx: [],
}, },
load: [], load: [],
memory: [], memory: [],
memoryFree: [], memoryFree: [],
memoryUsed: [] memoryUsed: [],
} }
} }
@ -75,15 +75,15 @@ function getNewVmStats () {
cpus: [], cpus: [],
vifs: { vifs: {
rx: [], rx: [],
tx: [] tx: [],
}, },
xvds: { xvds: {
r: {}, r: {},
w: {} w: {},
}, },
memory: [], memory: [],
memoryFree: [], memoryFree: [],
memoryUsed: [] memoryUsed: [],
} }
} }
@ -96,11 +96,11 @@ function getNewHostLegends () {
cpus: [], cpus: [],
pifs: { pifs: {
rx: [], rx: [],
tx: [] tx: [],
}, },
load: null, load: null,
memoryFree: null, memoryFree: null,
memory: null memory: null,
} }
} }
@ -109,14 +109,14 @@ function getNewVmLegends () {
cpus: [], cpus: [],
vifs: { vifs: {
rx: [], rx: [],
tx: [] tx: [],
}, },
xvds: { xvds: {
r: [], r: [],
w: [] w: [],
}, },
memoryFree: null, memoryFree: null,
memory: null memory: null,
} }
} }
@ -391,8 +391,8 @@ export default class XapiStats {
cf: 'AVERAGE', cf: 'AVERAGE',
host: 'true', host: 'true',
json: 'true', json: 'true',
start: timestamp start: timestamp,
} },
}).then(response => response.readAll().then(JSON5.parse)) }).then(response => response.readAll().then(JSON5.parse))
} }
@ -412,7 +412,7 @@ export default class XapiStats {
if (vmId === undefined) { if (vmId === undefined) {
return { return {
interval: step, interval: step,
...hostStats ...hostStats,
} }
} }
@ -422,14 +422,14 @@ export default class XapiStats {
return { return {
interval: step, interval: step,
endTimestamp: hostStats.endTimestamp, endTimestamp: hostStats.endTimestamp,
stats: (vmsStats && vmsStats[vmId]) || getNewVmStats() stats: (vmsStats && vmsStats[vmId]) || getNewVmStats(),
} }
} }
async _getAndUpdatePoints (xapi, host, vmId, granularity) { async _getAndUpdatePoints (xapi, host, vmId, granularity) {
// Get granularity to use // Get granularity to use
const step = (granularity === undefined || granularity === 0) const step = (granularity === undefined || granularity === 0)
? RRD_STEP_SECONDS : RRD_STEP_FROM_STRING[granularity] ? RRD_STEP_SECONDS : RRD_STEP_FROM_STRING[granularity]
if (step === undefined) { if (step === undefined) {
throw new FaultyGranularity(`Unknown granularity: '${granularity}'. Use 'seconds', 'minutes', 'hours', or 'days'.`) throw new FaultyGranularity(`Unknown granularity: '${granularity}'. Use 'seconds', 'minutes', 'hours', or 'days'.`)
@ -475,7 +475,7 @@ export default class XapiStats {
if (this._hosts[hostname][step] === undefined) { if (this._hosts[hostname][step] === undefined) {
this._hosts[hostname][step] = { this._hosts[hostname][step] = {
endTimestamp: 0, endTimestamp: 0,
localTimestamp: 0 localTimestamp: 0,
} }
} }

View File

@ -17,13 +17,13 @@ import {
isEmpty, isEmpty,
omit, omit,
startsWith, startsWith,
uniq uniq,
} from 'lodash' } from 'lodash'
import { import {
Xapi as XapiBase Xapi as XapiBase,
} from 'xen-api' } from 'xen-api'
import { import {
satisfies as versionSatisfies satisfies as versionSatisfies,
} from 'semver' } from 'semver'
import createSizeStream from '../size-stream' import createSizeStream from '../size-stream'
@ -42,10 +42,10 @@ import {
pDelay, pDelay,
pFinally, pFinally,
promisifyAll, promisifyAll,
pSettle pSettle,
} from '../utils' } from '../utils'
import mixins from './mixins' import mixins from './mixins' // eslint-disable-line node/no-missing-import
import OTHER_CONFIG_TEMPLATE from './other-config-template' import OTHER_CONFIG_TEMPLATE from './other-config-template'
import { import {
asBoolean, asBoolean,
@ -60,7 +60,7 @@ import {
isVmRunning, isVmRunning,
NULL_REF, NULL_REF,
optional, optional,
prepareXapiParam prepareXapiParam,
} from './utils' } from './utils'
// =================================================================== // ===================================================================
@ -104,7 +104,7 @@ export default class Xapi extends XapiBase {
forEach(objects, object => { forEach(objects, object => {
const { const {
$id: id, $id: id,
$ref: ref $ref: ref,
} = object } = object
// Run generic watchers. // Run generic watchers.
@ -131,7 +131,7 @@ export default class Xapi extends XapiBase {
const fn = super.call const fn = super.call
const loop = () => fn.apply(this, args)::pCatch({ const loop = () => fn.apply(this, args)::pCatch({
code: 'TOO_MANY_PENDING_TASKS' code: 'TOO_MANY_PENDING_TASKS',
}, () => pDelay(5e3).then(loop)) }, () => pDelay(5e3).then(loop))
return loop() return loop()
@ -182,7 +182,7 @@ export default class Xapi extends XapiBase {
// Register the watcher. // Register the watcher.
watcher = this._objectWatchers[predicate] = { watcher = this._objectWatchers[predicate] = {
promise, promise,
resolve resolve,
} }
} }
@ -226,7 +226,7 @@ export default class Xapi extends XapiBase {
_setObjectProperties (object, props) { _setObjectProperties (object, props) {
const { const {
$ref: ref, $ref: ref,
$type: type $type: type,
} = object } = object
const namespace = getNamespaceForType(type) const namespace = getNamespaceForType(type)
@ -243,7 +243,7 @@ export default class Xapi extends XapiBase {
async _updateObjectMapProperty (object, prop, values) { async _updateObjectMapProperty (object, prop, values) {
const { const {
$ref: ref, $ref: ref,
$type: type $type: type,
} = object } = object
prop = camelToSnakeCase(prop) prop = camelToSnakeCase(prop)
@ -266,46 +266,46 @@ export default class Xapi extends XapiBase {
async setHostProperties (id, { async setHostProperties (id, {
nameLabel, nameLabel,
nameDescription nameDescription,
}) { }) {
await this._setObjectProperties(this.getObject(id), { await this._setObjectProperties(this.getObject(id), {
nameLabel, nameLabel,
nameDescription nameDescription,
}) })
} }
async setPoolProperties ({ async setPoolProperties ({
autoPoweron, autoPoweron,
nameLabel, nameLabel,
nameDescription nameDescription,
}) { }) {
const { pool } = this const { pool } = this
await Promise.all([ await Promise.all([
this._setObjectProperties(pool, { this._setObjectProperties(pool, {
nameLabel, nameLabel,
nameDescription nameDescription,
}), }),
autoPoweron != null && this._updateObjectMapProperty(pool, 'other_config', { autoPoweron != null && this._updateObjectMapProperty(pool, 'other_config', {
autoPoweron: autoPoweron ? 'true' : null autoPoweron: autoPoweron ? 'true' : null,
}) }),
]) ])
} }
async setSrProperties (id, { async setSrProperties (id, {
nameLabel, nameLabel,
nameDescription nameDescription,
}) { }) {
await this._setObjectProperties(this.getObject(id), { await this._setObjectProperties(this.getObject(id), {
nameLabel, nameLabel,
nameDescription nameDescription,
}) })
} }
async setNetworkProperties (id, { async setNetworkProperties (id, {
nameLabel, nameLabel,
nameDescription, nameDescription,
defaultIsLocked defaultIsLocked,
}) { }) {
let defaultLockingMode let defaultLockingMode
if (defaultIsLocked != null) { if (defaultIsLocked != null) {
@ -314,7 +314,7 @@ export default class Xapi extends XapiBase {
await this._setObjectProperties(this.getObject(id), { await this._setObjectProperties(this.getObject(id), {
nameLabel, nameLabel,
nameDescription, nameDescription,
defaultLockingMode defaultLockingMode,
}) })
} }
@ -323,7 +323,7 @@ export default class Xapi extends XapiBase {
async addTag (id, tag) { async addTag (id, tag) {
const { const {
$ref: ref, $ref: ref,
$type: type $type: type,
} = this.getObject(id) } = this.getObject(id)
const namespace = getNamespaceForType(type) const namespace = getNamespaceForType(type)
@ -333,7 +333,7 @@ export default class Xapi extends XapiBase {
async removeTag (id, tag) { async removeTag (id, tag) {
const { const {
$ref: ref, $ref: ref,
$type: type $type: type,
} = this.getObject(id) } = this.getObject(id)
const namespace = getNamespaceForType(type) const namespace = getNamespaceForType(type)
@ -344,7 +344,7 @@ export default class Xapi extends XapiBase {
async setDefaultSr (srId) { async setDefaultSr (srId) {
this._setObjectProperties(this.pool, { this._setObjectProperties(this.pool, {
default_SR: this.getObject(srId).$ref default_SR: this.getObject(srId).$ref,
}) })
} }
@ -490,7 +490,7 @@ export default class Xapi extends XapiBase {
async cloneVm (vmId, { async cloneVm (vmId, {
nameLabel = undefined, nameLabel = undefined,
fast = true fast = true,
} = {}) { } = {}) {
const vm = this.getObject(vmId) const vm = this.getObject(vmId)
@ -504,7 +504,7 @@ export default class Xapi extends XapiBase {
} }
async copyVm (vmId, srId, { async copyVm (vmId, srId, {
nameLabel = undefined nameLabel = undefined,
} = {}) { } = {}) {
return /* await */ this._getOrWaitObject( return /* await */ this._getOrWaitObject(
await this._copyVm( await this._copyVm(
@ -517,19 +517,19 @@ export default class Xapi extends XapiBase {
async remoteCopyVm (vmId, targetXapi, targetSrId, { async remoteCopyVm (vmId, targetXapi, targetSrId, {
compress = true, compress = true,
nameLabel = undefined nameLabel = undefined,
} = {}) { } = {}) {
// Fall back on local copy if possible. // Fall back on local copy if possible.
if (targetXapi === this) { if (targetXapi === this) {
return { return {
vm: await this.copyVm(vmId, targetSrId, { nameLabel }) vm: await this.copyVm(vmId, targetSrId, { nameLabel }),
} }
} }
const sr = targetXapi.getObject(targetSrId) const sr = targetXapi.getObject(targetSrId)
let stream = await this.exportVm(vmId, { let stream = await this.exportVm(vmId, {
compress, compress,
onlyMetadata: false onlyMetadata: false,
}) })
const sizeStream = createSizeStream() const sizeStream = createSizeStream()
@ -537,7 +537,7 @@ export default class Xapi extends XapiBase {
const onVmCreation = nameLabel !== undefined const onVmCreation = nameLabel !== undefined
? vm => targetXapi._setObjectProperties(vm, { ? vm => targetXapi._setObjectProperties(vm, {
nameLabel nameLabel,
}) })
: null : null
@ -552,7 +552,7 @@ export default class Xapi extends XapiBase {
return { return {
size: sizeStream.size, size: sizeStream.size,
vm vm,
} }
} }
@ -600,7 +600,7 @@ export default class Xapi extends XapiBase {
VCPUs_max, VCPUs_max,
VCPUs_params, VCPUs_params,
version, version,
xenstore_data xenstore_data,
}) { }) {
debug(`Creating VM ${name_label}`) debug(`Creating VM ${name_label}`)
@ -647,7 +647,7 @@ export default class Xapi extends XapiBase {
start_delay: asInteger(start_delay), start_delay: asInteger(start_delay),
tags, tags,
version: asInteger(version), version: asInteger(version),
xenstore_data xenstore_data,
})) }))
} }
@ -699,7 +699,7 @@ export default class Xapi extends XapiBase {
: onFailure(vdi) : onFailure(vdi)
} }
return test() return test()
})::ignoreErrors() })::ignoreErrors(),
]) ])
} }
@ -724,7 +724,7 @@ export default class Xapi extends XapiBase {
// Returns a stream to the exported VM. // Returns a stream to the exported VM.
async exportVm (vmId, { async exportVm (vmId, {
compress = true, compress = true,
onlyMetadata = false onlyMetadata = false,
} = {}) { } = {}) {
const vm = this.getObject(vmId) const vm = this.getObject(vmId)
@ -740,9 +740,9 @@ export default class Xapi extends XapiBase {
host, host,
query: { query: {
ref: snapshotRef || vm.$ref, ref: snapshotRef || vm.$ref,
use_compression: compress ? 'true' : 'false' use_compression: compress ? 'true' : 'false',
}, },
task: this.createTask('VM export', vm.name_label) task: this.createTask('VM export', vm.name_label),
}) })
if (snapshotRef !== undefined) { if (snapshotRef !== undefined) {
@ -800,7 +800,7 @@ export default class Xapi extends XapiBase {
fullVdisRequired = [], fullVdisRequired = [],
disableBaseTags = false, disableBaseTags = false,
snapshotNameLabel = undefined snapshotNameLabel = undefined,
} = {}) { } = {}) {
if (!bypassVdiChainsCheck) { if (!bypassVdiChainsCheck) {
this._assertHealthyVdiChains(this.getObject(vmId)) this._assertHealthyVdiChains(this.getObject(vmId))
@ -810,7 +810,7 @@ export default class Xapi extends XapiBase {
$onFailure(() => this._deleteVm(vm)) $onFailure(() => this._deleteVm(vm))
if (snapshotNameLabel) { if (snapshotNameLabel) {
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
nameLabel: snapshotNameLabel nameLabel: snapshotNameLabel,
})::ignoreErrors() })::ignoreErrors()
} }
@ -869,13 +869,13 @@ export default class Xapi extends XapiBase {
...vdi, ...vdi,
other_config: { other_config: {
...vdi.other_config, ...vdi.other_config,
[TAG_BASE_DELTA]: baseVdi.uuid [TAG_BASE_DELTA]: baseVdi.uuid,
}, },
$SR$uuid: vdi.$SR.uuid $SR$uuid: vdi.$SR.uuid,
} }
: { : {
...vdi, ...vdi,
$SR$uuid: vdi.$SR.uuid $SR$uuid: vdi.$SR.uuid,
} }
const stream = streams[`${vdiRef}.vhd`] = this._exportVdi($cancelToken, vdi, baseVdi, VDI_FORMAT_VHD) const stream = streams[`${vdiRef}.vhd`] = this._exportVdi($cancelToken, vdi, baseVdi, VDI_FORMAT_VHD)
$onFailure(stream.cancel) $onFailure(stream.cancel)
@ -885,7 +885,7 @@ export default class Xapi extends XapiBase {
forEach(vm.$VIFs, vif => { forEach(vm.$VIFs, vif => {
vifs[vif.$ref] = { vifs[vif.$ref] = {
...vif, ...vif,
$network$uuid: vif.$network.uuid $network$uuid: vif.$network.uuid,
} }
}) })
@ -899,12 +899,12 @@ export default class Xapi extends XapiBase {
other_config: baseVm && !disableBaseTags other_config: baseVm && !disableBaseTags
? { ? {
...vm.other_config, ...vm.other_config,
[TAG_BASE_DELTA]: baseVm.uuid [TAG_BASE_DELTA]: baseVm.uuid,
} }
: omit(vm.other_config, TAG_BASE_DELTA) : omit(vm.other_config, TAG_BASE_DELTA),
} },
}, 'streams', { }, 'streams', {
value: await streams::pAll() value: await streams::pAll(),
}) })
} }
@ -914,7 +914,7 @@ export default class Xapi extends XapiBase {
disableStartAfterImport = true, disableStartAfterImport = true,
mapVdisSrs = {}, mapVdisSrs = {},
name_label = delta.vm.name_label, name_label = delta.vm.name_label,
srId = this.pool.default_SR srId = this.pool.default_SR,
} = {}) { } = {}) {
const { version } = delta const { version } = delta
@ -947,21 +947,21 @@ export default class Xapi extends XapiBase {
await this._createVmRecord({ await this._createVmRecord({
...delta.vm, ...delta.vm,
affinity: null, affinity: null,
is_a_template: false is_a_template: false,
}) })
) )
$onFailure(() => this._deleteVm(vm)) $onFailure(() => this._deleteVm(vm))
await Promise.all([ await Promise.all([
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
name_label: `[Importing…] ${name_label}` name_label: `[Importing…] ${name_label}`,
}), }),
this._updateObjectMapProperty(vm, 'blocked_operations', { this._updateObjectMapProperty(vm, 'blocked_operations', {
start: 'Importing…' start: 'Importing…',
}), }),
this._updateObjectMapProperty(vm, 'other_config', { this._updateObjectMapProperty(vm, 'other_config', {
[TAG_COPY_SRC]: delta.vm.uuid [TAG_COPY_SRC]: delta.vm.uuid,
}) }),
]) ])
// 2. Delete all VBDs which may have been created by the import. // 2. Delete all VBDs which may have been created by the import.
@ -979,9 +979,9 @@ export default class Xapi extends XapiBase {
other_config: { other_config: {
...vdi.other_config, ...vdi.other_config,
[TAG_BASE_DELTA]: undefined, [TAG_BASE_DELTA]: undefined,
[TAG_COPY_SRC]: vdi.uuid [TAG_COPY_SRC]: vdi.uuid,
}, },
sr: mapVdisSrs[vdi.uuid] || srId sr: mapVdisSrs[vdi.uuid] || srId,
}) })
$onFailure(() => this._deleteVdi(newVdi)) $onFailure(() => this._deleteVdi(newVdi))
@ -1002,7 +1002,7 @@ export default class Xapi extends XapiBase {
$onFailure(() => this._deleteVdi(newVdi)) $onFailure(() => this._deleteVdi(newVdi))
await this._updateObjectMapProperty(newVdi, 'other_config', { await this._updateObjectMapProperty(newVdi, 'other_config', {
[TAG_COPY_SRC]: vdi.uuid [TAG_COPY_SRC]: vdi.uuid,
}) })
return newVdi return newVdi
@ -1051,7 +1051,7 @@ export default class Xapi extends XapiBase {
vif vif
) )
} }
}) }),
]) ])
if (deleteBase && baseVm) { if (deleteBase && baseVm) {
@ -1060,14 +1060,14 @@ export default class Xapi extends XapiBase {
await Promise.all([ await Promise.all([
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
name_label name_label,
}), }),
// FIXME: move // FIXME: move
this._updateObjectMapProperty(vm, 'blocked_operations', { this._updateObjectMapProperty(vm, 'blocked_operations', {
start: disableStartAfterImport start: disableStartAfterImport
? 'Do not start this VM, clone it if you want to use it.' ? 'Do not start this VM, clone it if you want to use it.'
: null : null,
}) }),
]) ])
return vm return vm
@ -1077,7 +1077,7 @@ export default class Xapi extends XapiBase {
migrationNetwork = find(host.$PIFs, pif => pif.management).$network, // TODO: handle not found migrationNetwork = find(host.$PIFs, pif => pif.management).$network, // TODO: handle not found
sr, sr,
mapVdisSrs, mapVdisSrs,
mapVifsNetworks mapVifsNetworks,
}) { }) {
// VDIs/SRs mapping // VDIs/SRs mapping
const vdis = {} const vdis = {}
@ -1094,7 +1094,7 @@ export default class Xapi extends XapiBase {
} }
// VIFs/Networks mapping // VIFs/Networks mapping
let vifsMap = {} const vifsMap = {}
if (vm.$pool !== host.$pool) { if (vm.$pool !== host.$pool) {
const defaultNetworkRef = find(host.$PIFs, pif => pif.management).$network.$ref const defaultNetworkRef = find(host.$PIFs, pif => pif.management).$network.$ref
for (const vif of vm.$VIFs) { for (const vif of vm.$VIFs) {
@ -1119,7 +1119,7 @@ export default class Xapi extends XapiBase {
vdis, vdis,
vifsMap, vifsMap,
{ {
force: 'true' force: 'true',
} }
)::pCatch( )::pCatch(
{ code: 'TOO_MANY_STORAGE_MIGRATES' }, { code: 'TOO_MANY_STORAGE_MIGRATES' },
@ -1202,7 +1202,7 @@ export default class Xapi extends XapiBase {
async _importVm (stream, sr, onlyMetadata = false, onVmCreation = undefined) { async _importVm (stream, sr, onlyMetadata = false, onVmCreation = undefined) {
const taskRef = await this.createTask('VM import') const taskRef = await this.createTask('VM import')
const query = { const query = {
force: onlyMetadata force: onlyMetadata,
} }
let host let host
@ -1223,7 +1223,7 @@ export default class Xapi extends XapiBase {
{ {
host, host,
query, query,
task: taskRef task: taskRef,
} }
).then(extractOpaqueRef) ).then(extractOpaqueRef)
@ -1245,7 +1245,7 @@ export default class Xapi extends XapiBase {
memory, memory,
nameLabel, nameLabel,
networks, networks,
nCpus nCpus,
}, sr) { }, sr) {
// 1. Create VM. // 1. Create VM.
const vm = await this._getOrWaitObject( const vm = await this._getOrWaitObject(
@ -1257,14 +1257,14 @@ export default class Xapi extends XapiBase {
name_description: descriptionLabel, name_description: descriptionLabel,
name_label: nameLabel, name_label: nameLabel,
VCPUs_at_startup: nCpus, VCPUs_at_startup: nCpus,
VCPUs_max: nCpus VCPUs_max: nCpus,
}) })
) )
$onFailure(() => this._deleteVm(vm)) $onFailure(() => this._deleteVm(vm))
// Disable start and change the VM name label during import. // Disable start and change the VM name label during import.
await Promise.all([ await Promise.all([
this.addForbiddenOperationToVm(vm.$id, 'start', 'OVA import in progress...'), this.addForbiddenOperationToVm(vm.$id, 'start', 'OVA import in progress...'),
this._setObjectProperties(vm, { name_label: `[Importing...] ${nameLabel}` }) this._setObjectProperties(vm, { name_label: `[Importing...] ${nameLabel}` }),
]) ])
// 2. Create VDIs & Vifs. // 2. Create VDIs & Vifs.
@ -1275,14 +1275,14 @@ export default class Xapi extends XapiBase {
const vdi = vdis[disk.path] = await this.createVdi(disk.capacity, { const vdi = vdis[disk.path] = await this.createVdi(disk.capacity, {
name_description: disk.descriptionLabel, name_description: disk.descriptionLabel,
name_label: disk.nameLabel, name_label: disk.nameLabel,
sr: sr.$ref sr: sr.$ref,
}) })
$onFailure(() => this._deleteVdi(vdi)) $onFailure(() => this._deleteVdi(vdi))
return this._createVbd(vm, vdi, { position: disk.position }) return this._createVbd(vm, vdi, { position: disk.position })
}).concat(map(networks, (networkId, i) => ( }).concat(map(networks, (networkId, i) => (
this._createVif(vm, this.getObject(networkId), { this._createVif(vm, this.getObject(networkId), {
device: vifDevices[i] device: vifDevices[i],
}) })
))) )))
) )
@ -1317,7 +1317,7 @@ export default class Xapi extends XapiBase {
// Enable start and restore the VM name label after import. // Enable start and restore the VM name label after import.
await Promise.all([ await Promise.all([
this.removeForbiddenOperationFromVm(vm.$id, 'start'), this.removeForbiddenOperationFromVm(vm.$id, 'start'),
this._setObjectProperties(vm, { name_label: nameLabel }) this._setObjectProperties(vm, { name_label: nameLabel }),
]) ])
return vm return vm
} }
@ -1327,7 +1327,7 @@ export default class Xapi extends XapiBase {
data, data,
onlyMetadata = false, onlyMetadata = false,
srId, srId,
type = 'xva' type = 'xva',
} = {}) { } = {}) {
const sr = srId && this.getObject(srId) const sr = srId && this.getObject(srId)
@ -1350,7 +1350,7 @@ export default class Xapi extends XapiBase {
sr, sr,
migrationNetworkId, migrationNetworkId,
mapVifsNetworks, mapVifsNetworks,
mapVdisSrs mapVdisSrs,
} = {}) { } = {}) {
const vm = this.getObject(vmId) const vm = this.getObject(vmId)
const host = hostXapi.getObject(hostId) const host = hostXapi.getObject(hostId)
@ -1369,7 +1369,7 @@ export default class Xapi extends XapiBase {
migrationNetwork: migrationNetworkId && hostXapi.getObject(migrationNetworkId), migrationNetwork: migrationNetworkId && hostXapi.getObject(migrationNetworkId),
sr, sr,
mapVdisSrs, mapVdisSrs,
mapVifsNetworks mapVifsNetworks,
}) })
} else { } else {
try { try {
@ -1418,7 +1418,7 @@ export default class Xapi extends XapiBase {
// to-date object. // to-date object.
const [ , snapshot ] = await Promise.all([ const [ , snapshot ] = await Promise.all([
this.call('VM.set_is_a_template', ref, false), this.call('VM.set_is_a_template', ref, false),
this._waitObjectState(ref, snapshot => !snapshot.is_a_template) this._waitObjectState(ref, snapshot => !snapshot.is_a_template),
]) ])
return snapshot return snapshot
@ -1442,7 +1442,7 @@ export default class Xapi extends XapiBase {
if (force) { if (force) {
await this._updateObjectMapProperty(vm, 'blocked_operations', { await this._updateObjectMapProperty(vm, 'blocked_operations', {
start: null start: null,
}) })
} }
@ -1473,14 +1473,14 @@ export default class Xapi extends XapiBase {
const { order } = vm.HVM_boot_params const { order } = vm.HVM_boot_params
await this._updateObjectMapProperty(vm, 'HVM_boot_params', { await this._updateObjectMapProperty(vm, 'HVM_boot_params', {
order: 'd' order: 'd',
}) })
try { try {
await this._startVm(vm) await this._startVm(vm)
} finally { } finally {
await this._updateObjectMapProperty(vm, 'HVM_boot_params', { await this._updateObjectMapProperty(vm, 'HVM_boot_params', {
order order,
}) })
} }
} else { } else {
@ -1502,7 +1502,7 @@ export default class Xapi extends XapiBase {
forEach(vm.$VBDs, vbd => { forEach(vm.$VBDs, vbd => {
promises.push( promises.push(
this._setObjectProperties(vbd, { this._setObjectProperties(vbd, {
bootable: vbd === cdDrive bootable: vbd === cdDrive,
}) })
) )
@ -1511,11 +1511,11 @@ export default class Xapi extends XapiBase {
promises.push( promises.push(
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
PV_bootloader: 'eliloader' PV_bootloader: 'eliloader',
}), }),
this._updateObjectMapProperty(vm, 'other_config', { this._updateObjectMapProperty(vm, 'other_config', {
'install-distro': template && template.other_config['install-distro'], 'install-distro': template && template.other_config['install-distro'],
'install-repository': 'cdrom' 'install-repository': 'cdrom',
}) })
) )
@ -1524,7 +1524,7 @@ export default class Xapi extends XapiBase {
await this._startVm(vm) await this._startVm(vm)
} finally { } finally {
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
PV_bootloader: bootloader PV_bootloader: bootloader,
})::ignoreErrors() })::ignoreErrors()
forEach(bootables, ([ vbd, bootable ]) => { forEach(bootables, ([ vbd, bootable ]) => {
@ -1555,7 +1555,7 @@ export default class Xapi extends XapiBase {
mode = (type === 'Disk') ? 'RW' : 'RO', mode = (type === 'Disk') ? 'RW' : 'RO',
position = userdevice, position = userdevice,
readOnly = (mode === 'RO') readOnly = (mode === 'RO'),
} = {}) { } = {}) {
debug(`Creating VBD for VDI ${vdi.name_label} on VM ${vm.name_label}`) debug(`Creating VBD for VDI ${vdi.name_label} on VM ${vm.name_label}`)
@ -1593,7 +1593,7 @@ export default class Xapi extends XapiBase {
unpluggable: Boolean(unpluggable), unpluggable: Boolean(unpluggable),
userdevice: String(position), userdevice: String(position),
VDI: vdi.$ref, VDI: vdi.$ref,
VM: vm.$ref VM: vm.$ref,
}) })
if (isVmRunning(vm)) { if (isVmRunning(vm)) {
@ -1621,7 +1621,7 @@ export default class Xapi extends XapiBase {
tags = [], tags = [],
type = 'user', type = 'user',
xenstore_data = undefined xenstore_data = undefined,
} = {}) { } = {}) {
if (sr === NULL_REF) { if (sr === NULL_REF) {
throw new Error('SR required to create VDI') throw new Error('SR required to create VDI')
@ -1642,7 +1642,7 @@ export default class Xapi extends XapiBase {
tags, tags,
type, type,
virtual_size: String(size), virtual_size: String(size),
SR: sr.$ref SR: sr.$ref,
} }
if (xenstore_data) { if (xenstore_data) {
@ -1677,7 +1677,7 @@ export default class Xapi extends XapiBase {
bootable: vbd.bootable, bootable: vbd.bootable,
position: vbd.userdevice, position: vbd.userdevice,
type: vbd.type, type: vbd.type,
readOnly: vbd.mode === 'RO' readOnly: vbd.mode === 'RO',
}) })
// Remove the old VDI // Remove the old VDI
await this._deleteVdi(vdi) await this._deleteVdi(vdi)
@ -1722,7 +1722,7 @@ export default class Xapi extends XapiBase {
async _insertCdIntoVm (cd, vm, { async _insertCdIntoVm (cd, vm, {
bootable = false, bootable = false,
force = false force = false,
} = {}) { } = {}) {
const cdDrive = await this._getVmCdDrive(vm) const cdDrive = await this._getVmCdDrive(vm)
if (cdDrive) { if (cdDrive) {
@ -1745,7 +1745,7 @@ export default class Xapi extends XapiBase {
} else { } else {
await this._createVbd(vm, cd, { await this._createVbd(vm, cd, {
bootable, bootable,
type: 'CD' type: 'CD',
}) })
} }
} }
@ -1845,7 +1845,7 @@ export default class Xapi extends XapiBase {
const query = { const query = {
format, format,
vdi: vdi.$ref vdi: vdi.$ref,
} }
if (base) { if (base) {
query.base = base.$ref query.base = base.$ref
@ -1859,14 +1859,14 @@ export default class Xapi extends XapiBase {
return this.getResource($cancelToken, '/export_raw_vdi/', { return this.getResource($cancelToken, '/export_raw_vdi/', {
host, host,
query, query,
task: this.createTask('VDI Export', vdi.name_label) task: this.createTask('VDI Export', vdi.name_label),
}) })
} }
// Returns a stream to the exported VDI. // Returns a stream to the exported VDI.
exportVdi (vdiId, { exportVdi (vdiId, {
baseId, baseId,
format format,
} = {}) { } = {}) {
return this._exportVdi( return this._exportVdi(
this.getObject(vdiId), this.getObject(vdiId),
@ -1890,15 +1890,15 @@ export default class Xapi extends XapiBase {
host: pbd.host, host: pbd.host,
query: { query: {
format, format,
vdi: vdi.$ref vdi: vdi.$ref,
}, },
task: this.createTask('VDI Content Import', vdi.name_label) task: this.createTask('VDI Content Import', vdi.name_label),
}) }),
]) ])
} }
importVdiContent (vdiId, body, { importVdiContent (vdiId, body, {
format format,
} = {}) { } = {}) {
return this._importVdiContent( return this._importVdiContent(
this.getObject(vdiId), this.getObject(vdiId),
@ -1921,7 +1921,7 @@ export default class Xapi extends XapiBase {
MAC = mac, MAC = mac,
other_config = {}, other_config = {},
qos_algorithm_params = {}, qos_algorithm_params = {},
qos_algorithm_type = '' qos_algorithm_type = '',
} = {}) { } = {}) {
debug(`Creating VIF for VM ${vm.name_label} on network ${network.name_label}`) debug(`Creating VIF for VM ${vm.name_label} on network ${network.name_label}`)
@ -1940,7 +1940,7 @@ export default class Xapi extends XapiBase {
other_config, other_config,
qos_algorithm_params, qos_algorithm_params,
qos_algorithm_type, qos_algorithm_type,
VM: vm.$ref VM: vm.$ref,
})) }))
if (currently_attached && isVmRunning(vm)) { if (currently_attached && isVmRunning(vm)) {
@ -1965,13 +1965,13 @@ export default class Xapi extends XapiBase {
description = 'Created with Xen Orchestra', description = 'Created with Xen Orchestra',
pifId, pifId,
mtu, mtu,
vlan vlan,
}) { }) {
const networkRef = await this.call('network.create', { const networkRef = await this.call('network.create', {
name_label: name, name_label: name,
name_description: description, name_description: description,
MTU: asInteger(mtu), MTU: asInteger(mtu),
other_config: {} other_config: {},
}) })
$onFailure(() => this.call('network.destroy', networkRef)) $onFailure(() => this.call('network.destroy', networkRef))
if (pifId) { if (pifId) {
@ -2059,7 +2059,7 @@ export default class Xapi extends XapiBase {
return /* await */ this.call('host.call_plugin', host.$ref, 'xscontainer', action, { return /* await */ this.call('host.call_plugin', host.$ref, 'xscontainer', action, {
vmuuid: vm.uuid, vmuuid: vm.uuid,
container: containerId container: containerId,
}) })
} }
@ -2095,8 +2095,8 @@ export default class Xapi extends XapiBase {
const template = this.getObject(templateId) const template = this.getObject(templateId)
const host = this.pool.$master const host = this.pool.$master
let config = await this.call('host.call_plugin', host.$ref, 'xscontainer', 'get_config_drive_default', { const config = await this.call('host.call_plugin', host.$ref, 'xscontainer', 'get_config_drive_default', {
templateuuid: template.uuid templateuuid: template.uuid,
}) })
return config.slice(4) // FIXME remove the "True" string on the begining return config.slice(4) // FIXME remove the "True" string on the begining
} }
@ -2110,7 +2110,7 @@ export default class Xapi extends XapiBase {
await this.call('host.call_plugin', host.$ref, 'xscontainer', 'create_config_drive', { await this.call('host.call_plugin', host.$ref, 'xscontainer', 'create_config_drive', {
vmuuid: vm.uuid, vmuuid: vm.uuid,
sruuid: sr.uuid, sruuid: sr.uuid,
configuration: config configuration: config,
}) })
await this.registerDockerContainer(vmId) await this.registerDockerContainer(vmId)
} }
@ -2136,7 +2136,7 @@ export default class Xapi extends XapiBase {
'openstack/latest/meta_data.json', 'openstack/latest/meta_data.json',
'{\n "uuid": "' + vm.uuid + '"\n}\n' '{\n "uuid": "' + vm.uuid + '"\n}\n'
), ),
fs.writeFile('openstack/latest/user_data', config) fs.writeFile('openstack/latest/user_data', config),
]) ])
// ignore errors, I (JFT) don't understand why they are emitted // ignore errors, I (JFT) don't understand why they are emitted
@ -2151,7 +2151,7 @@ export default class Xapi extends XapiBase {
const vdi = await this.createVdi(stream.length, { const vdi = await this.createVdi(stream.length, {
sr: sr.$ref, sr: sr.$ref,
name_label, name_label,
name_description name_description,
}) })
$onFailure(() => this._deleteVdi(vdi)) $onFailure(() => this._deleteVdi(vdi))

View File

@ -5,5 +5,5 @@ export default {
}, },
deleteVgpu (vgpu) { deleteVgpu (vgpu) {
return this.call('VGPU.destroy', this.getObject(vgpu).$ref) return this.call('VGPU.destroy', this.getObject(vgpu).$ref)
} },
} }

View File

@ -38,8 +38,8 @@ export default {
if (lockingMode !== vif.locking_mode) { if (lockingMode !== vif.locking_mode) {
return this._set('locking_mode', lockingMode) return this._set('locking_mode', lockingMode)
} }
} },
] ],
}, },
ipv6Allowed: { ipv6Allowed: {
get: true, get: true,
@ -53,8 +53,8 @@ export default {
if (lockingMode !== vif.locking_mode) { if (lockingMode !== vif.locking_mode) {
return this._set('locking_mode', lockingMode) return this._set('locking_mode', lockingMode)
} }
} },
] ],
} },
}) }),
} }

View File

@ -16,13 +16,13 @@ import {
forEach, forEach,
mapFilter, mapFilter,
mapToArray, mapToArray,
parseXml parseXml,
} from '../../utils' } from '../../utils'
import { import {
debug, debug,
extractOpaqueRef, extractOpaqueRef,
useUpdateSystem useUpdateSystem,
} from '../utils' } from '../utils'
export default { export default {
@ -55,7 +55,7 @@ export default {
requirements: mapToArray(ensureArray(patch.requiredpatches), patch => { requirements: mapToArray(ensureArray(patch.requiredpatches), patch => {
return patch.requiredpatch.uuid return patch.requiredpatch.uuid
}), }),
paid: patch['update-stream'] === 'premium' paid: patch['update-stream'] === 'premium',
// TODO: what does it mean, should we handle it? // TODO: what does it mean, should we handle it?
// version: patch.version, // version: patch.version,
} }
@ -85,7 +85,7 @@ export default {
name: version.name, name: version.name,
id: version.value, id: version.value,
documentationUrl: version.url, documentationUrl: version.url,
patches: resolveVersionPatches(version.patch) patches: resolveVersionPatches(version.patch),
} }
if (version.latest) { if (version.latest) {
@ -96,7 +96,7 @@ export default {
return { return {
patches, patches,
latestVersion, latestVersion,
versions versions,
} }
}, },
@ -219,7 +219,7 @@ export default {
stream, stream,
'/pool_patch_upload', '/pool_patch_upload',
{ {
task: this.createTask('Patch upload', patchName) task: this.createTask('Patch upload', patchName),
} }
).then(extractOpaqueRef) ).then(extractOpaqueRef)
@ -303,7 +303,7 @@ export default {
_installPatchUpdateOnHost: deferrable(async function ($defer, patchUuid, host) { _installPatchUpdateOnHost: deferrable(async function ($defer, patchUuid, host) {
const [ vdi ] = await Promise.all([ const [ vdi ] = await Promise.all([
this._getUpdateVdi($defer, patchUuid, host.$id), this._getUpdateVdi($defer, patchUuid, host.$id),
this._ejectToolsIsos(host.$ref) this._ejectToolsIsos(host.$ref),
]) ])
const updateRef = await this.call('pool_update.introduce', vdi.$ref) const updateRef = await this.call('pool_update.introduce', vdi.$ref)
@ -334,7 +334,7 @@ export default {
async _installPoolPatchOnAllHosts (patchUuid) { async _installPoolPatchOnAllHosts (patchUuid) {
const [ patch ] = await Promise.all([ const [ patch ] = await Promise.all([
this._getOrUploadPoolPatch(patchUuid), this._getOrUploadPoolPatch(patchUuid),
this._ejectToolsIsos() this._ejectToolsIsos(),
]) ])
await this.call('pool_patch.pool_apply', patch.$ref) await this.call('pool_patch.pool_apply', patch.$ref)
@ -344,7 +344,7 @@ export default {
_installPatchUpdateOnAllHosts: deferrable(async function ($defer, patchUuid) { _installPatchUpdateOnAllHosts: deferrable(async function ($defer, patchUuid) {
let [ vdi ] = await Promise.all([ let [ vdi ] = await Promise.all([
this._getUpdateVdi($defer, patchUuid), this._getUpdateVdi($defer, patchUuid),
this._ejectToolsIsos() this._ejectToolsIsos(),
]) ])
if (vdi == null) { if (vdi == null) {
vdi = await this._getUpdateVdi($defer, patchUuid, this.pool.master) vdi = await this._getUpdateVdi($defer, patchUuid, this.pool.master)
@ -473,5 +473,5 @@ export default {
} }
}) })
} }
} },
} }

View File

@ -1,11 +1,11 @@
import { import {
forEach, forEach,
groupBy groupBy,
} from 'lodash' } from 'lodash'
import { import {
createRawObject, createRawObject,
mapToArray mapToArray,
} from '../../utils' } from '../../utils'
export default { export default {
@ -92,5 +92,5 @@ export default {
} }
}) })
return unhealthyVdis return unhealthyVdis
} },
} }

View File

@ -5,20 +5,20 @@ import {
gte, gte,
includes, includes,
isEmpty, isEmpty,
lte lte,
} from 'lodash' } from 'lodash'
import { import {
forEach, forEach,
mapToArray, mapToArray,
parseSize parseSize,
} from '../../utils' } from '../../utils'
import { import {
isVmHvm, isVmHvm,
isVmRunning, isVmRunning,
makeEditObject, makeEditObject,
NULL_REF NULL_REF,
} from '../utils' } from '../utils'
// According to: https://xenserver.org/blog/entry/vga-over-cirrus-in-xenserver-6-2.html. // According to: https://xenserver.org/blog/entry/vga-over-cirrus-in-xenserver-6-2.html.
@ -29,7 +29,7 @@ export default {
// TODO: clean up on error. // TODO: clean up on error.
@deferrable.onFailure @deferrable.onFailure
async createVm ($onFailure, templateId, { async createVm ($onFailure, templateId, {
name_label, // deprecated name_label, // eslint-disable-line camelcase
nameLabel = name_label, // eslint-disable-line camelcase nameLabel = name_label, // eslint-disable-line camelcase
clone = true, clone = true,
@ -94,7 +94,7 @@ export default {
} }
this._setObjectProperties(vm, { this._setObjectProperties(vm, {
HVM_boot_params: { ...bootParams, order } HVM_boot_params: { ...bootParams, order },
}) })
} }
} else { // PV } else { // PV
@ -103,11 +103,11 @@ export default {
// TODO: normalize RHEL URL? // TODO: normalize RHEL URL?
await this._updateObjectMapProperty(vm, 'other_config', { await this._updateObjectMapProperty(vm, 'other_config', {
'install-repository': installRepository 'install-repository': installRepository,
}) })
} else if (installMethod === 'cd') { } else if (installMethod === 'cd') {
await this._updateObjectMapProperty(vm, 'other_config', { await this._updateObjectMapProperty(vm, 'other_config', {
'install-repository': 'cdrom' 'install-repository': 'cdrom',
}) })
} }
} }
@ -121,7 +121,7 @@ export default {
// When the VM is started, if PV, the CD drive will become not // When the VM is started, if PV, the CD drive will become not
// bootable and the first disk bootable. // bootable and the first disk bootable.
await this._insertCdIntoVm(installRepository, vm, { await this._insertCdIntoVm(installRepository, vm, {
bootable: true bootable: true,
}) })
hasBootableDisk = true hasBootableDisk = true
} }
@ -158,14 +158,14 @@ export default {
{ {
name_label: vdiDescription.name_label, name_label: vdiDescription.name_label,
name_description: vdiDescription.name_description, name_description: vdiDescription.name_description,
sr: vdiDescription.sr || vdiDescription.SR sr: vdiDescription.sr || vdiDescription.SR,
} }
) )
.then(ref => this._getOrWaitObject(ref)) .then(ref => this._getOrWaitObject(ref))
.then(vdi => this._createVbd(vm, vdi, { .then(vdi => this._createVbd(vm, vdi, {
// Either the CD or the 1st disk is bootable (only useful for PV VMs) // Either the CD or the 1st disk is bootable (only useful for PV VMs)
bootable: !(hasBootableDisk || i), bootable: !(hasBootableDisk || i),
userdevice: devices[i] userdevice: devices[i],
})) }))
)) ))
} }
@ -185,7 +185,7 @@ export default {
device: devices[index], device: devices[index],
locking_mode: isEmpty(vif.ipv4_allowed) && isEmpty(vif.ipv6_allowed) ? 'network_default' : 'locked', locking_mode: isEmpty(vif.ipv4_allowed) && isEmpty(vif.ipv6_allowed) ? 'network_default' : 'locked',
mac: vif.mac, mac: vif.mac,
mtu: vif.mtu mtu: vif.mtu,
} }
))) )))
} }
@ -234,26 +234,26 @@ export default {
'affinity', 'affinity',
value ? this.getObject(value).$ref : NULL_REF value ? this.getObject(value).$ref : NULL_REF
) )
} },
}, },
autoPoweron: { autoPoweron: {
set (value, vm) { set (value, vm) {
return Promise.all([ return Promise.all([
this._updateObjectMapProperty(vm, 'other_config', { this._updateObjectMapProperty(vm, 'other_config', {
autoPoweron: value ? 'true' : null autoPoweron: value ? 'true' : null,
}), }),
value && this.setPoolProperties({ value && this.setPoolProperties({
autoPoweron: true autoPoweron: true,
}) }),
]) ])
} },
}, },
coresPerSocket: { coresPerSocket: {
set (coresPerSocket, vm) { set (coresPerSocket, vm) {
return this._updateObjectMapProperty(vm, 'platform', {'cores-per-socket': coresPerSocket}) return this._updateObjectMapProperty(vm, 'platform', {'cores-per-socket': coresPerSocket})
} },
}, },
CPUs: 'cpus', CPUs: 'cpus',
@ -265,7 +265,7 @@ export default {
// If the other value is not set and the constraint is not // If the other value is not set and the constraint is not
// respected, the other value is changed first. // respected, the other value is changed first.
constraints: { constraints: {
cpusStaticMax: gte cpusStaticMax: gte,
}, },
get: vm => +vm.VCPUs_at_startup, get: vm => +vm.VCPUs_at_startup,
@ -273,46 +273,46 @@ export default {
'VCPUs_at_startup', 'VCPUs_at_startup',
function (value, vm) { function (value, vm) {
return isVmRunning(vm) && this._set('VCPUs_number_live', value) return isVmRunning(vm) && this._set('VCPUs_number_live', value)
} },
] ],
}, },
cpuCap: { cpuCap: {
get: vm => vm.VCPUs_params.cap && +vm.VCPUs_params.cap, get: vm => vm.VCPUs_params.cap && +vm.VCPUs_params.cap,
set (cap, vm) { set (cap, vm) {
return this._updateObjectMapProperty(vm, 'VCPUs_params', { cap }) return this._updateObjectMapProperty(vm, 'VCPUs_params', { cap })
} },
}, },
cpusMax: 'cpusStaticMax', cpusMax: 'cpusStaticMax',
cpusStaticMax: { cpusStaticMax: {
constraints: { constraints: {
cpus: lte cpus: lte,
}, },
get: vm => +vm.VCPUs_max, get: vm => +vm.VCPUs_max,
set: 'VCPUs_max' set: 'VCPUs_max',
}, },
cpuWeight: { cpuWeight: {
get: vm => vm.VCPUs_params.weight && +vm.VCPUs_params.weight, get: vm => vm.VCPUs_params.weight && +vm.VCPUs_params.weight,
set (weight, vm) { set (weight, vm) {
return this._updateObjectMapProperty(vm, 'VCPUs_params', { weight }) return this._updateObjectMapProperty(vm, 'VCPUs_params', { weight })
} },
}, },
highAvailability: { highAvailability: {
set (ha, vm) { set (ha, vm) {
return this.call('VM.set_ha_restart_priority', vm.$ref, ha ? 'restart' : '') return this.call('VM.set_ha_restart_priority', vm.$ref, ha ? 'restart' : '')
} },
}, },
memoryMin: { memoryMin: {
constraints: { constraints: {
memoryMax: gte memoryMax: gte,
}, },
get: vm => +vm.memory_dynamic_min, get: vm => +vm.memory_dynamic_min,
preprocess: parseSize, preprocess: parseSize,
set: 'memory_dynamic_min' set: 'memory_dynamic_min',
}, },
memory: 'memoryMax', memory: 'memoryMax',
@ -321,20 +321,20 @@ export default {
limitName: 'memory', limitName: 'memory',
constraints: { constraints: {
memoryMin: lte, memoryMin: lte,
memoryStaticMax: gte memoryStaticMax: gte,
}, },
get: vm => +vm.memory_dynamic_max, get: vm => +vm.memory_dynamic_max,
preprocess: parseSize, preprocess: parseSize,
set: 'memory_dynamic_max' set: 'memory_dynamic_max',
}, },
memoryStaticMax: { memoryStaticMax: {
constraints: { constraints: {
memoryMax: lte memoryMax: lte,
}, },
get: vm => +vm.memory_static_max, get: vm => +vm.memory_static_max,
preprocess: parseSize, preprocess: parseSize,
set: 'memory_static_max' set: 'memory_static_max',
}, },
nameDescription: true, nameDescription: true,
@ -351,7 +351,7 @@ export default {
throw new Error(`The different values that the VGA can take are: ${XEN_VGA_VALUES}`) throw new Error(`The different values that the VGA can take are: ${XEN_VGA_VALUES}`)
} }
return this._updateObjectMapProperty(vm, 'platform', { vga }) return this._updateObjectMapProperty(vm, 'platform', { vga })
} },
}, },
videoram: { videoram: {
@ -360,8 +360,8 @@ export default {
throw new Error(`The different values that the video RAM can take are: ${XEN_VIDEORAM_VALUES}`) throw new Error(`The different values that the video RAM can take are: ${XEN_VIDEORAM_VALUES}`)
} }
return this._updateObjectMapProperty(vm, 'platform', { videoram }) return this._updateObjectMapProperty(vm, 'platform', { videoram })
} },
} },
}), }),
async editVm (id, props, checkLimits) { async editVm (id, props, checkLimits) {
@ -387,5 +387,5 @@ export default {
async resumeVm (vmId) { async resumeVm (vmId) {
// the force parameter is always true // the force parameter is always true
return this.call('VM.resume', this.getObject(vmId).$ref, false, true) return this.call('VM.resume', this.getObject(vmId).$ref, false, true)
} },
} }

View File

@ -8,7 +8,7 @@ const OTHER_CONFIG_TEMPLATE = {
blocked_operations: {}, blocked_operations: {},
ha_always_run: false, ha_always_run: false,
HVM_boot_params: { HVM_boot_params: {
order: 'cdn' order: 'cdn',
}, },
HVM_boot_policy: 'BIOS order', HVM_boot_policy: 'BIOS order',
HVM_shadow_multiplier: 1, HVM_shadow_multiplier: 1,
@ -22,7 +22,7 @@ const OTHER_CONFIG_TEMPLATE = {
vgpu_pci: '', vgpu_pci: '',
base_template_name: 'Other install media', base_template_name: 'Other install media',
mac_seed: '5e88eb6a-d680-c47f-a94a-028886971ba4', mac_seed: '5e88eb6a-d680-c47f-a94a-028886971ba4',
'install-methods': 'cdrom' 'install-methods': 'cdrom',
}, },
PCI_bus: '', PCI_bus: '',
platform: { platform: {
@ -32,7 +32,7 @@ const OTHER_CONFIG_TEMPLATE = {
apic: 'true', apic: 'true',
pae: 'true', pae: 'true',
hpet: 'true', hpet: 'true',
viridian: 'true' viridian: 'true',
}, },
protection_policy: NULL_REF, protection_policy: NULL_REF,
PV_args: '', PV_args: '',
@ -48,6 +48,6 @@ const OTHER_CONFIG_TEMPLATE = {
VCPUs_at_startup: 1, VCPUs_at_startup: 1,
VCPUs_max: 1, VCPUs_max: 1,
VCPUs_params: {}, VCPUs_params: {},
version: 0 version: 0,
} }
export { OTHER_CONFIG_TEMPLATE as default } export { OTHER_CONFIG_TEMPLATE as default }

View File

@ -19,7 +19,7 @@ import {
map, map,
mapFilter, mapFilter,
mapToArray, mapToArray,
noop noop,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -102,7 +102,7 @@ forEach([
'VM_guest_metrics', 'VM_guest_metrics',
'VM_metrics', 'VM_metrics',
'VMPP', 'VMPP',
'VTPM' 'VTPM',
], namespace => { ], namespace => {
TYPE_TO_NAMESPACE[namespace.toLowerCase()] = namespace TYPE_TO_NAMESPACE[namespace.toLowerCase()] = namespace
}) })
@ -152,7 +152,7 @@ export const isVmHvm = vm => Boolean(vm.HVM_boot_policy)
const VM_RUNNING_POWER_STATES = { const VM_RUNNING_POWER_STATES = {
Running: true, Running: true,
Paused: true Paused: true,
} }
export const isVmRunning = vm => VM_RUNNING_POWER_STATES[vm.power_state] export const isVmRunning = vm => VM_RUNNING_POWER_STATES[vm.power_state]
@ -226,7 +226,7 @@ export const makeEditObject = specs => {
if (spec === true) { if (spec === true) {
spec = { spec = {
get: true, get: true,
set: true set: true,
} }
} }
@ -287,7 +287,7 @@ export const makeEditObject = specs => {
// Context used to execute functions. // Context used to execute functions.
const context = { const context = {
__proto__: this, __proto__: this,
_set: (prop, value) => this.call(_setMethodPrefix + prop, _objectRef, prepareXapiParam(value)) _set: (prop, value) => this.call(_setMethodPrefix + prop, _objectRef, prepareXapiParam(value)),
} }
const set = (value, name) => { const set = (value, name) => {

View File

@ -1,16 +1,16 @@
import checkAuthorization from 'xo-acl-resolver' import checkAuthorization from 'xo-acl-resolver'
import { import {
ModelAlreadyExists ModelAlreadyExists,
} from '../collection' } from '../collection'
import { import {
Acls Acls,
} from '../models/acl' } from '../models/acl'
import { import {
createRawObject, createRawObject,
forEach, forEach,
includes, includes,
mapToArray mapToArray,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -22,7 +22,7 @@ export default class {
const aclsDb = this._acls = new Acls({ const aclsDb = this._acls = new Acls({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:acl', prefix: 'xo:acl',
indexes: ['subject', 'object'] indexes: ['subject', 'object'],
}) })
xo.on('start', () => { xo.on('start', () => {
@ -93,10 +93,10 @@ export default class {
async getPermissionsForUser (userId) { async getPermissionsForUser (userId) {
const [ const [
acls, acls,
permissionsByRole permissionsByRole,
] = await Promise.all([ ] = await Promise.all([
this._getAclsForUser(userId), this._getAclsForUser(userId),
this._getPermissionsByRole() this._getPermissionsByRole(),
]) ])
const permissions = createRawObject() const permissions = createRawObject()
@ -152,16 +152,16 @@ export default class {
id: 'viewer', id: 'viewer',
name: 'Viewer', name: 'Viewer',
permissions: [ permissions: [
'view' 'view',
] ],
}, },
{ {
id: 'operator', id: 'operator',
name: 'Operator', name: 'Operator',
permissions: [ permissions: [
'view', 'view',
'operate' 'operate',
] ],
}, },
{ {
id: 'admin', id: 'admin',
@ -169,9 +169,9 @@ export default class {
permissions: [ permissions: [
'view', 'view',
'operate', 'operate',
'administrate' 'administrate',
] ],
} },
] ]
} }

View File

@ -7,17 +7,17 @@ import {
isArray, isArray,
isFunction, isFunction,
map, map,
mapValues mapValues,
} from 'lodash' } from 'lodash'
import * as methods from '../api' import * as methods from '../api' // eslint-disable-line node/no-missing-import
import { import {
MethodNotFound MethodNotFound,
} from 'json-rpc-peer' } from 'json-rpc-peer'
import { import {
createRawObject, createRawObject,
noop, noop,
serializeError serializeError,
} from '../utils' } from '../utils'
import * as errors from 'xo-common/api-errors' import * as errors from 'xo-common/api-errors'
@ -30,7 +30,7 @@ const PERMISSIONS = {
none: 0, none: 0,
read: 1, read: 1,
write: 2, write: 2,
admin: 3 admin: 3,
} }
// TODO: // TODO:
@ -50,7 +50,7 @@ const XAPI_ERROR_TO_XO_ERROR = {
VM_IS_TEMPLATE: errors.vmIsTemplate, VM_IS_TEMPLATE: errors.vmIsTemplate,
VM_LACKS_FEATURE: ([ vm ], getId) => errors.vmLacksFeature({ vm: getId(vm) }), VM_LACKS_FEATURE: ([ vm ], getId) => errors.vmLacksFeature({ vm: getId(vm) }),
VM_LACKS_FEATURE_SHUTDOWN: ([ vm ], getId) => errors.vmLacksFeature({ vm: getId(vm), feature: 'shutdown' }), VM_LACKS_FEATURE_SHUTDOWN: ([ vm ], getId) => errors.vmLacksFeature({ vm: getId(vm), feature: 'shutdown' }),
VM_MISSING_PV_DRIVERS: ([ vm ], getId) => errors.vmMissingPvDrivers({ vm: getId(vm) }) VM_MISSING_PV_DRIVERS: ([ vm ], getId) => errors.vmMissingPvDrivers({ vm: getId(vm) }),
} }
const hasPermission = (user, permission) => ( const hasPermission = (user, permission) => (
@ -65,7 +65,7 @@ function checkParams (method, params) {
const result = schemaInspector.validate({ const result = schemaInspector.validate({
type: 'object', type: 'object',
properties: schema properties: schema,
}, params) }, params)
if (!result.valid) { if (!result.valid) {
@ -243,11 +243,11 @@ export default class Api {
// XO methods called from the API. // XO methods called from the API.
const context = Object.create(this._xo, { const context = Object.create(this._xo, {
api: { // Used by system.*(). api: { // Used by system.*().
value: this value: this,
}, },
session: { session: {
value: session value: session,
} },
}) })
// Fetch and inject the current user. // Fetch and inject the current user.
@ -303,7 +303,7 @@ export default class Api {
method: name, method: name,
params: removeSensitiveParams(params), params: removeSensitiveParams(params),
duration: Date.now() - startTime, duration: Date.now() - startTime,
error: serializeError(error) error: serializeError(error),
} }
const message = `${userName} | ${name}(${JSON.stringify(params)}) [${ms(Date.now() - startTime)}] =!> ${error}` const message = `${userName} | ${name}(${JSON.stringify(params)}) [${ms(Date.now() - startTime)}] =!> ${error}`

View File

@ -6,7 +6,7 @@ import Token, { Tokens } from '../models/token'
import { import {
createRawObject, createRawObject,
forEach, forEach,
generateToken generateToken,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -30,13 +30,13 @@ export default class {
const tokensDb = this._tokens = new Tokens({ const tokensDb = this._tokens = new Tokens({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:token', prefix: 'xo:token',
indexes: ['user_id'] indexes: ['user_id'],
}) })
// Password authentication provider. // Password authentication provider.
this.registerAuthenticationProvider(async ({ this.registerAuthenticationProvider(async ({
username, username,
password password,
}) => { }) => {
if (username === undefined || password === undefined) { if (username === undefined || password === undefined) {
return return
@ -50,7 +50,7 @@ export default class {
// Token authentication provider. // Token authentication provider.
this.registerAuthenticationProvider(async ({ this.registerAuthenticationProvider(async ({
token: tokenId token: tokenId,
}) => { }) => {
if (!tokenId) { if (!tokenId) {
return return
@ -154,7 +154,7 @@ export default class {
async createAuthenticationToken ({ async createAuthenticationToken ({
expiresIn = ONE_MONTH, expiresIn = ONE_MONTH,
userId userId,
}) { }) {
const token = new Token({ const token = new Token({
id: await generateToken(), id: await generateToken(),
@ -163,7 +163,7 @@ export default class {
typeof expiresIn === 'string' typeof expiresIn === 'string'
? ms(expiresIn) ? ms(expiresIn)
: expiresIn : expiresIn
) ),
}) })
await this._tokens.add(token) await this._tokens.add(token)

View File

@ -10,7 +10,7 @@ import { satisfies as versionSatisfies } from 'semver'
import { utcFormat } from 'd3-time-format' import { utcFormat } from 'd3-time-format'
import { import {
basename, basename,
dirname dirname,
} from 'path' } from 'path'
import { import {
endsWith, endsWith,
@ -22,7 +22,7 @@ import {
range, range,
sortBy, sortBy,
startsWith, startsWith,
trim trim,
} from 'lodash' } from 'lodash'
import createSizeStream from '../size-stream' import createSizeStream from '../size-stream'
@ -41,10 +41,10 @@ import {
resolveSubpath, resolveSubpath,
safeDateFormat, safeDateFormat,
safeDateParse, safeDateParse,
tmpDir tmpDir,
} from '../utils' } from '../utils'
import { import {
VDI_FORMAT_VHD VDI_FORMAT_VHD,
} from '../xapi' } from '../xapi'
// =================================================================== // ===================================================================
@ -76,7 +76,7 @@ const parseVmBackupPath = name => {
id: name, id: name,
name: baseMatches[3], name: baseMatches[3],
tag: baseMatches[2], tag: baseMatches[2],
type: 'xva' type: 'xva',
} }
} }
@ -91,7 +91,7 @@ const parseVmBackupPath = name => {
name: baseMatches[2], name: baseMatches[2],
tag: dirMatches[1], tag: dirMatches[1],
type: 'delta', type: 'delta',
uuid: dirMatches[2] uuid: dirMatches[2],
} }
} }
@ -139,7 +139,7 @@ const listPartitions = (() => {
// https://github.com/jhermsmeier/node-mbr/blob/master/lib/partition.js#L38 // https://github.com/jhermsmeier/node-mbr/blob/master/lib/partition.js#L38
0x05, 0x0F, 0x85, 0x15, 0x91, 0x9B, 0x5E, 0x5F, 0xCF, 0xD5, 0xC5, 0x05, 0x0F, 0x85, 0x15, 0x91, 0x9B, 0x5E, 0x5F, 0xCF, 0xD5, 0xC5,
0x82 // swap 0x82, // swap
], type => { ], type => {
IGNORED[type] = true IGNORED[type] = true
}) })
@ -147,7 +147,7 @@ const listPartitions = (() => {
const TYPES = { const TYPES = {
0x7: 'NTFS', 0x7: 'NTFS',
0x83: 'linux', 0x83: 'linux',
0xc: 'FAT' 0xc: 'FAT',
} }
const parseLine = createPairsParser({ const parseLine = createPairsParser({
@ -158,14 +158,14 @@ const listPartitions = (() => {
? +value ? +value
: key === 'type' : key === 'type'
? TYPES[+value] || value ? TYPES[+value] || value
: value : value,
}) })
return device => execa.stdout('partx', [ return device => execa.stdout('partx', [
'--bytes', '--bytes',
'--output=NR,START,SIZE,NAME,UUID,TYPE', '--output=NR,START,SIZE,NAME,UUID,TYPE',
'--pairs', '--pairs',
device.path device.path,
]).then(stdout => mapFilter(splitLines(stdout), line => { ]).then(stdout => mapFilter(splitLines(stdout), line => {
const partition = parseLine(line) const partition = parseLine(line)
const { type } = partition const { type } = partition
@ -187,7 +187,7 @@ const listPartitions2 = device => listPartitions(device).then(partitions => {
partitions2.push({ partitions2.push({
name: lv.lv_name, name: lv.lv_name,
size: +lv.lv_size, size: +lv.lv_size,
id: `${partition.id}/${lv.vg_name}/${lv.lv_name}` id: `${partition.id}/${lv.vg_name}/${lv.lv_name}`,
}) })
}) })
}) })
@ -203,11 +203,11 @@ const listPartitions2 = device => listPartitions(device).then(partitions => {
const mountPartition = (device, partitionId) => Promise.all([ const mountPartition = (device, partitionId) => Promise.all([
partitionId != null && listPartitions(device), partitionId != null && listPartitions(device),
tmpDir() tmpDir(),
]).then(([ partitions, path ]) => { ]).then(([ partitions, path ]) => {
const options = [ const options = [
'loop', 'loop',
'ro' 'ro',
] ]
if (partitions) { if (partitions) {
@ -222,7 +222,7 @@ const mountPartition = (device, partitionId) => Promise.all([
const mount = options => execa('mount', [ const mount = options => execa('mount', [
`--options=${options.join(',')}`, `--options=${options.join(',')}`,
`--source=${device.path}`, `--source=${device.path}`,
`--target=${path}` `--target=${path}`,
]) ])
// `norecovery` option is used for ext3/ext4/xfs, if it fails it // `norecovery` option is used for ext3/ext4/xfs, if it fails it
@ -231,7 +231,7 @@ const mountPartition = (device, partitionId) => Promise.all([
mount(options) mount(options)
).then(() => ({ ).then(() => ({
path, path,
unmount: once(() => execa('umount', [ '--lazy', path ])) unmount: once(() => execa('umount', [ '--lazy', path ])),
}), error => { }), error => {
console.log(error) console.log(error)
@ -260,7 +260,7 @@ const mountPartition2 = (device, partitionId) => {
).then(path => ).then(path =>
mountPartition({ path }).then(device2 => ({ mountPartition({ path }).then(device2 => ({
...device2, ...device2,
unmount: () => device2.unmount().then(device1.unmount) unmount: () => device2.unmount().then(device1.unmount),
})) }))
).catch(error => device1.unmount().then(() => { ).catch(error => device1.unmount().then(() => {
throw error throw error
@ -274,7 +274,7 @@ const listLvmLvs = device => pvs([
'lv_name', 'lv_name',
'lv_path', 'lv_path',
'lv_size', 'lv_size',
'vg_name' 'vg_name',
], device.path).then(pvs => filter(pvs, 'lv_name')) ], device.path).then(pvs => filter(pvs, 'lv_name'))
const mountLvmPv = (device, partition) => { const mountLvmPv = (device, partition) => {
@ -296,9 +296,9 @@ const mountLvmPv = (device, partition) => {
execa('losetup', [ '-d', path ]), execa('losetup', [ '-d', path ]),
pvs('vg_name', path).then(vgNames => execa('vgchange', [ pvs('vg_name', path).then(vgNames => execa('vgchange', [
'-an', '-an',
...vgNames ...vgNames,
])) ])),
])) ])),
} }
}) })
} }
@ -313,7 +313,7 @@ export default class {
// unmounted // unmounted
xo.on('start', () => Promise.all([ xo.on('start', () => Promise.all([
execa('losetup', [ '-D' ]), execa('losetup', [ '-D' ]),
execa('vgchange', [ '-an' ]) execa('vgchange', [ '-an' ]),
]).then(() => ]).then(() =>
execa('pvscan', [ '--cache' ]) execa('pvscan', [ '--cache' ])
)) ))
@ -367,7 +367,7 @@ export default class {
record.disks = mapToArray(JSON.parse(data).vdis, vdi => ({ record.disks = mapToArray(JSON.parse(data).vdis, vdi => ({
id: `${entry}/${vdi.xoPath}`, id: `${entry}/${vdi.xoPath}`,
name: vdi.name_label, name: vdi.name_label,
uuid: vdi.uuid uuid: vdi.uuid,
})) }))
}) })
} }
@ -390,8 +390,8 @@ export default class {
await Promise.all([ await Promise.all([
xapi.addTag(vm.$id, 'restored from backup'), xapi.addTag(vm.$id, 'restored from backup'),
xapi.editVm(vm.$id, { xapi.editVm(vm.$id, {
name_label: `${vm.name_label} (${shortDate(datetime * 1e3)})` name_label: `${vm.name_label} (${shortDate(datetime * 1e3)})`,
}) }),
]) ])
return xapiObjectToXo(vm).id return xapiObjectToXo(vm).id
@ -424,7 +424,7 @@ export default class {
const { cancel, token } = CancelToken.source() const { cancel, token } = CancelToken.source()
const delta = await srcXapi.exportDeltaVm(token, srcVm.$id, localBaseUuid, { const delta = await srcXapi.exportDeltaVm(token, srcVm.$id, localBaseUuid, {
bypassVdiChainsCheck: force, bypassVdiChainsCheck: force,
snapshotNameLabel: `XO_DELTA_EXPORT: ${targetSr.name_label} (${targetSr.uuid})` snapshotNameLabel: `XO_DELTA_EXPORT: ${targetSr.name_label} (${targetSr.uuid})`,
}) })
$onFailure(() => srcXapi.deleteVm(delta.vm.uuid)) $onFailure(() => srcXapi.deleteVm(delta.vm.uuid))
$onFailure(cancel) $onFailure(cancel)
@ -461,7 +461,7 @@ export default class {
delta, delta,
{ {
deleteBase, deleteBase,
srId: targetSr.$id srId: targetSr.$id,
} }
) )
@ -480,7 +480,7 @@ export default class {
// (Asynchronously) Identify snapshot as future base. // (Asynchronously) Identify snapshot as future base.
promise.then(() => { promise.then(() => {
return srcXapi._updateObjectMapProperty(srcVm, 'other_config', { return srcXapi._updateObjectMapProperty(srcVm, 'other_config', {
[TAG_LAST_BASE_DELTA]: delta.vm.uuid [TAG_LAST_BASE_DELTA]: delta.vm.uuid,
}) })
})::ignoreErrors() })::ignoreErrors()
@ -491,7 +491,7 @@ export default class {
// 5. Return the identifier of the new XO VM object. // 5. Return the identifier of the new XO VM object.
id: xapiObjectToXo(dstVm).id, id: xapiObjectToXo(dstVm).id,
transferDuration: Date.now() - transferStart, transferDuration: Date.now() - transferStart,
transferSize: size transferSize: size,
} }
} }
@ -530,7 +530,7 @@ export default class {
const stream = await handler.createReadStream(`${dir}/${vdiDir}/${backup}`) const stream = await handler.createReadStream(`${dir}/${vdiDir}/${backup}`)
await xapi.importVdiContent(vdiId, stream, { await xapi.importVdiContent(vdiId, stream, {
format: VDI_FORMAT_VHD format: VDI_FORMAT_VHD,
}) })
} }
@ -550,7 +550,7 @@ export default class {
// Disable start and change the VM name label during import. // Disable start and change the VM name label during import.
await Promise.all([ await Promise.all([
xapi.addForbiddenOperationToVm(vm.$id, 'start', 'Delta backup import...'), xapi.addForbiddenOperationToVm(vm.$id, 'start', 'Delta backup import...'),
xapi._setObjectProperties(vm, { name_label: `[Importing...] ${vmName}` }) xapi._setObjectProperties(vm, { name_label: `[Importing...] ${vmName}` }),
]) ])
// Destroy vbds if necessary. Why ? // Destroy vbds if necessary. Why ?
@ -583,7 +583,7 @@ export default class {
// Import done, reenable start and set real vm name. // Import done, reenable start and set real vm name.
await Promise.all([ await Promise.all([
xapi.removeForbiddenOperationFromVm(vm.$id, 'start'), xapi.removeForbiddenOperationFromVm(vm.$id, 'start'),
xapi._setObjectProperties(vm, { name_label: vmName }) xapi._setObjectProperties(vm, { name_label: vmName }),
]) ])
return vm return vm
@ -628,7 +628,7 @@ export default class {
async _mergeDeltaVdiBackups ({handler, dir, retention}) { async _mergeDeltaVdiBackups ({handler, dir, retention}) {
const backups = await this._listVdiBackups(handler, dir) const backups = await this._listVdiBackups(handler, dir)
let i = backups.length - retention const i = backups.length - retention
// No merge. // No merge.
if (i <= 0) { if (i <= 0) {
@ -730,7 +730,7 @@ export default class {
// The problem is in the merge case, a delta merged in a full vdi // The problem is in the merge case, a delta merged in a full vdi
// backup forces us to browse the resulting file => // backup forces us to browse the resulting file =>
// Significant transfer time on the network ! // Significant transfer time on the network !
checksum: !isFull checksum: !isFull,
}) })
stream.on('error', error => targetStream.emit('error', error)) stream.on('error', error => targetStream.emit('error', error))
@ -742,7 +742,7 @@ export default class {
.pipe(targetStream), .pipe(targetStream),
'finish' 'finish'
), ),
stream.task stream.task,
]) ])
} catch (error) { } catch (error) {
// Remove new backup. (corrupt). // Remove new backup. (corrupt).
@ -754,7 +754,7 @@ export default class {
return { return {
// Returns relative path. // Returns relative path.
path: `${backupDirectory}/${vdiFilename}`, path: `${backupDirectory}/${vdiFilename}`,
size: sizeStream.size size: sizeStream.size,
} }
} }
@ -769,7 +769,7 @@ export default class {
// Remove xva file. // Remove xva file.
// Version 0.0.0 (Legacy) Delta Backup. // Version 0.0.0 (Legacy) Delta Backup.
handler.unlink(`${dir}/${getDeltaBackupNameWithoutExt(backup)}.xva`)::ignoreErrors() handler.unlink(`${dir}/${getDeltaBackupNameWithoutExt(backup)}.xva`)::ignoreErrors(),
])) ]))
} }
} }
@ -815,7 +815,7 @@ export default class {
const delta = await xapi.exportDeltaVm(token, vm.$id, baseVm && baseVm.$id, { const delta = await xapi.exportDeltaVm(token, vm.$id, baseVm && baseVm.$id, {
snapshotNameLabel: `XO_DELTA_BASE_VM_SNAPSHOT_${tag}`, snapshotNameLabel: `XO_DELTA_BASE_VM_SNAPSHOT_${tag}`,
fullVdisRequired, fullVdisRequired,
disableBaseTags: true disableBaseTags: true,
}) })
$onFailure(() => xapi.deleteVm(delta.vm.uuid)) $onFailure(() => xapi.deleteVm(delta.vm.uuid))
$onFailure(cancel) $onFailure(cancel)
@ -831,12 +831,12 @@ export default class {
handler, handler,
stream: delta.streams[`${key}.vhd`], stream: delta.streams[`${key}.vhd`],
dir, dir,
retention retention,
}) })
.then(data => { .then(data => {
delta.vdis[key] = { delta.vdis[key] = {
...delta.vdis[key], ...delta.vdis[key],
xoPath: data.path xoPath: data.path,
} }
return data return data
@ -912,7 +912,7 @@ export default class {
mergeDuration: mergedDataSize !== 0 ? mergeDuration : undefined, mergeDuration: mergedDataSize !== 0 ? mergeDuration : undefined,
mergeSize: mergedDataSize !== 0 ? mergedDataSize : undefined, mergeSize: mergedDataSize !== 0 ? mergedDataSize : undefined,
transferDuration: Date.now() - transferStart - mergeDuration, transferDuration: Date.now() - transferStart - mergeDuration,
transferSize: dataSize transferSize: dataSize,
} }
} }
@ -930,7 +930,7 @@ export default class {
if (!version) { if (!version) {
// Legacy import. (Version 0.0.0) // Legacy import. (Version 0.0.0)
vm = await this._legacyImportDeltaVmBackup(xapi, { vm = await this._legacyImportDeltaVmBackup(xapi, {
remoteId, handler, filePath, info: delta, sr, mapVdisSrs remoteId, handler, filePath, info: delta, sr, mapVdisSrs,
}) })
} else if (versionSatisfies(delta.version, '^1')) { } else if (versionSatisfies(delta.version, '^1')) {
const basePath = dirname(filePath) const basePath = dirname(filePath)
@ -956,7 +956,7 @@ export default class {
vm = await xapi.importDeltaVm(delta, { vm = await xapi.importDeltaVm(delta, {
disableStartAfterImport: false, disableStartAfterImport: false,
srId: sr !== undefined && sr._xapiId, srId: sr !== undefined && sr._xapiId,
mapVdisSrs mapVdisSrs,
}) })
} else { } else {
throw new Error(`Unsupported delta backup version: ${version}`) throw new Error(`Unsupported delta backup version: ${version}`)
@ -982,7 +982,7 @@ export default class {
const sourceStream = await this._xo.getXapi(vm).exportVm(vm._xapiId, { const sourceStream = await this._xo.getXapi(vm).exportVm(vm._xapiId, {
compress, compress,
onlyMetadata: onlyMetadata || false onlyMetadata: onlyMetadata || false,
}) })
const sizeStream = createSizeStream() const sizeStream = createSizeStream()
@ -994,7 +994,7 @@ export default class {
await promise await promise
return { return {
transferSize: sizeStream.size transferSize: sizeStream.size,
} }
} }
@ -1073,11 +1073,11 @@ export default class {
const copyName = `${vm.name_label}_${tag}_${safeDateFormat(new Date())}` const copyName = `${vm.name_label}_${tag}_${safeDateFormat(new Date())}`
const data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, { const data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, {
nameLabel: copyName nameLabel: copyName,
}) })
targetXapi._updateObjectMapProperty(data.vm, 'blocked_operations', { targetXapi._updateObjectMapProperty(data.vm, 'blocked_operations', {
start: 'Start operation for this vm is blocked, clone it if you want to use it.' start: 'Start operation for this vm is blocked, clone it if you want to use it.',
}) })
await targetXapi.addTag(data.vm.$id, 'Disaster Recovery') await targetXapi.addTag(data.vm.$id, 'Disaster Recovery')
@ -1088,7 +1088,7 @@ export default class {
return { return {
transferDuration: Date.now() - transferStart, transferDuration: Date.now() - transferStart,
transferSize: data.size transferSize: data.size,
} }
} }
@ -1097,7 +1097,7 @@ export default class {
_mountVhd (remoteId, vhdPath) { _mountVhd (remoteId, vhdPath) {
return Promise.all([ return Promise.all([
this._xo.getRemoteHandler(remoteId), this._xo.getRemoteHandler(remoteId),
tmpDir() tmpDir(),
]).then(([ handler, mountDir ]) => { ]).then(([ handler, mountDir ]) => {
if (!handler._getRealPath) { if (!handler._getRealPath) {
throw new Error(`this remote is not supported`) throw new Error(`this remote is not supported`)
@ -1141,7 +1141,7 @@ export default class {
return { return {
path: `${mountDir}/vhdi${max}`, path: `${mountDir}/vhdi${max}`,
unmount: once(() => execa('fusermount', [ '-uz', mountDir ])) unmount: once(() => execa('fusermount', [ '-uz', mountDir ])),
} }
}) })
) )
@ -1152,7 +1152,7 @@ export default class {
return this._mountVhd(remoteId, vhdPath).then(device => return this._mountVhd(remoteId, vhdPath).then(device =>
mountPartition2(device, partitionId).then(partition => ({ mountPartition2(device, partitionId).then(partition => ({
...partition, ...partition,
unmount: () => partition.unmount().then(device.unmount) unmount: () => partition.unmount().then(device.unmount),
})).catch(error => device.unmount().then(() => { })).catch(error => device.unmount().then(() => {
throw error throw error
})) }))
@ -1165,7 +1165,7 @@ export default class {
$defer(device.unmount) $defer(device.unmount)
return { return {
partitions: await listPartitions2(device) partitions: await listPartitions2(device),
} }
} }

View File

@ -48,7 +48,7 @@ const runHook = (app, hook) => {
onError: error => console.error( onError: error => console.error(
`[WARN] hook ${hook} failure:`, `[WARN] hook ${hook} failure:`,
(error != null && error.stack) || error (error != null && error.stack) || error
) ),
}, hook) }, hook)
promise.then(() => { promise.then(() => {
debug(`${hook} finished`) debug(`${hook} finished`)
@ -72,5 +72,5 @@ export default {
// Run *stop* async listeners. // Run *stop* async listeners.
// //
// They close connections, unmount file systems, save states, etc. // They close connections, unmount file systems, save states, etc.
stop: makeSingletonHook('stop', 'stopped') stop: makeSingletonHook('stop', 'stopped'),
} }

View File

@ -2,7 +2,7 @@ import hrp from 'http-request-plus'
import ProxyAgent from 'proxy-agent' import ProxyAgent from 'proxy-agent'
import { import {
firstDefined firstDefined,
} from '../utils' } from '../utils'
export default class Http { export default class Http {
@ -10,14 +10,14 @@ export default class Http {
httpProxy = firstDefined( httpProxy = firstDefined(
process.env.http_proxy, process.env.http_proxy,
process.env.HTTP_PROXY process.env.HTTP_PROXY
) ),
}) { }) {
this._proxy = httpProxy && new ProxyAgent(httpProxy) this._proxy = httpProxy && new ProxyAgent(httpProxy)
} }
httpRequest (...args) { httpRequest (...args) {
return hrp({ return hrp({
agent: this._proxy agent: this._proxy,
}, ...args) }, ...args)
} }
} }

View File

@ -21,7 +21,7 @@ import {
lightSet, lightSet,
mapToArray, mapToArray,
streamToArray, streamToArray,
throwFn throwFn,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -31,13 +31,13 @@ const normalize = ({
id = throwFn('id is a required field'), id = throwFn('id is a required field'),
name = '', name = '',
networks, networks,
resourceSets resourceSets,
}) => ({ }) => ({
addresses, addresses,
id, id,
name, name,
networks, networks,
resourceSets resourceSets,
}) })
const _isAddressInIpPool = (address, network, ipPool) => ( const _isAddressInIpPool = (address, network, ipPool) => (
@ -71,7 +71,7 @@ export default class IpPools {
addresses, addresses,
id, id,
name, name,
networks networks,
}) })
return id return id
@ -98,7 +98,7 @@ export default class IpPools {
_getAllIpPools (filter) { _getAllIpPools (filter) {
return streamToArray(this._store.createValueStream(), { return streamToArray(this._store.createValueStream(), {
filter, filter,
mapper: normalize mapper: normalize,
}) })
} }
@ -161,8 +161,8 @@ export default class IpPools {
const saveIpPools = () => Promise.all(mapToArray(updatedIpPools, ipPool => this._save(ipPool))) const saveIpPools = () => Promise.all(mapToArray(updatedIpPools, ipPool => this._save(ipPool)))
return resourseSetId return resourseSetId
? this._xo.allocateLimitsInResourceSet(limits, resourseSetId).then( ? this._xo.allocateLimitsInResourceSet(limits, resourseSetId).then(
saveIpPools saveIpPools
) )
: saveIpPools() : saveIpPools()
} }
})() })()
@ -243,7 +243,7 @@ export default class IpPools {
return getXapi(vif).editVif(vif._xapiId, { return getXapi(vif).editVif(vif._xapiId, {
ipv4Allowed: allowedIpv4Addresses, ipv4Allowed: allowedIpv4Addresses,
ipv6Allowed: allowedIpv6Addresses ipv6Allowed: allowedIpv6Addresses,
}) })
})) }))
} }
@ -252,7 +252,7 @@ export default class IpPools {
addresses, addresses,
name, name,
networks, networks,
resourceSets resourceSets,
}) { }) {
const ipPool = await this.getIpPool(id) const ipPool = await this.getIpPool(id)
const previousAddresses = { ...ipPool.addresses } const previousAddresses = { ...ipPool.addresses }

View File

@ -14,7 +14,7 @@ export default class Jobs {
const jobsDb = this._jobs = new JobsDb({ const jobsDb = this._jobs = new JobsDb({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:job', prefix: 'xo:job',
indexes: ['user_id', 'key'] indexes: ['user_id', 'key'],
}) })
this._runningJobs = Object.create(null) this._runningJobs = Object.create(null)

View File

@ -21,7 +21,7 @@ export default class Logs {
} }
} }
const stream = db.createKeyStream({ const stream = db.createKeyStream({
reverse: true reverse: true,
}) })
const deleteEntry = key => { const deleteEntry = key => {

View File

@ -9,7 +9,7 @@ const LEVELS = [
'warning', 'warning',
'notice', 'notice',
'informational', 'informational',
'debug' 'debug',
] ]
// Create high level log methods. // Create high level log methods.
@ -17,6 +17,6 @@ for (const level of LEVELS) {
Object.defineProperty(AbstractLogger.prototype, level, { Object.defineProperty(AbstractLogger.prototype, level, {
value (message, data) { value (message, data) {
return this._add(level, message, data) return this._add(level, message, data)
} },
}) })
} }

View File

@ -32,7 +32,7 @@ export default class LevelDbLogger extends AbstractLogger {
message, message,
data, data,
namespace: this._namespace, namespace: this._namespace,
time time,
} }
const key = generateUniqueKey(time) const key = generateUniqueKey(time)

View File

@ -3,12 +3,12 @@ import Ajv from 'ajv'
import { PluginsMetadata } from '../models/plugin-metadata' import { PluginsMetadata } from '../models/plugin-metadata'
import { import {
invalidParameters, invalidParameters,
noSuchObject noSuchObject,
} from 'xo-common/api-errors' } from 'xo-common/api-errors'
import { import {
createRawObject, createRawObject,
isFunction, isFunction,
mapToArray mapToArray,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -16,13 +16,13 @@ import {
export default class { export default class {
constructor (xo) { constructor (xo) {
this._ajv = new Ajv({ this._ajv = new Ajv({
useDefaults: true useDefaults: true,
}) })
this._plugins = createRawObject() this._plugins = createRawObject()
this._pluginsMetadata = new PluginsMetadata({ this._pluginsMetadata = new PluginsMetadata({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:plugin-metadata' prefix: 'xo:plugin-metadata',
}) })
xo.on('start', () => { xo.on('start', () => {
@ -71,7 +71,7 @@ export default class {
testable: isFunction(instance.test), testable: isFunction(instance.test),
testSchema, testSchema,
unloadable: isFunction(instance.unload), unloadable: isFunction(instance.unload),
version version,
} }
const metadata = await this._getPluginMetadata(id) const metadata = await this._getPluginMetadata(id)
@ -80,13 +80,13 @@ export default class {
if (metadata) { if (metadata) {
({ ({
autoload, autoload,
configuration configuration,
} = metadata) } = metadata)
} else { } else {
console.log(`[NOTICE] register plugin ${name} for the first time`) console.log(`[NOTICE] register plugin ${name} for the first time`)
await this._pluginsMetadata.save({ await this._pluginsMetadata.save({
id, id,
autoload autoload,
}) })
} }
@ -113,11 +113,11 @@ export default class {
testable, testable,
testSchema, testSchema,
unloadable, unloadable,
version version,
} = this._getRawPlugin(id) } = this._getRawPlugin(id)
const { const {
autoload, autoload,
configuration configuration,
} = (await this._getPluginMetadata(id)) || {} } = (await this._getPluginMetadata(id)) || {}
return { return {
@ -132,7 +132,7 @@ export default class {
configurationPresets, configurationPresets,
configurationSchema, configurationSchema,
testable, testable,
testSchema testSchema,
} }
} }
@ -160,7 +160,7 @@ export default class {
// Shallow copy of the configuration object to avoid most of the // Shallow copy of the configuration object to avoid most of the
// errors when the plugin is altering the configuration object // errors when the plugin is altering the configuration object
// which is handed over to it. // which is handed over to it.
...configuration ...configuration,
}) })
plugin.configured = true plugin.configured = true
} }
@ -234,7 +234,7 @@ export default class {
if (data == null) { if (data == null) {
throw invalidParameters([{ throw invalidParameters([{
field: 'data', field: 'data',
message: 'is the wrong type' message: 'is the wrong type',
}]) }])
} }

View File

@ -5,10 +5,10 @@ import RemoteHandlerNfs from '../remote-handlers/nfs'
import RemoteHandlerSmb from '../remote-handlers/smb' import RemoteHandlerSmb from '../remote-handlers/smb'
import { import {
forEach, forEach,
mapToArray mapToArray,
} from '../utils' } from '../utils'
import { import {
Remotes Remotes,
} from '../models/remote' } from '../models/remote'
// =================================================================== // ===================================================================
@ -18,7 +18,7 @@ export default class {
this._remotes = new Remotes({ this._remotes = new Remotes({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:remote', prefix: 'xo:remote',
indexes: ['enabled'] indexes: ['enabled'],
}) })
xo.on('clean', () => this._remotes.rebuildIndexes()) xo.on('clean', () => this._remotes.rebuildIndexes())
@ -48,7 +48,7 @@ export default class {
const HANDLERS = { const HANDLERS = {
file: RemoteHandlerLocal, file: RemoteHandlerLocal,
smb: RemoteHandlerSmb, smb: RemoteHandlerSmb,
nfs: RemoteHandlerNfs nfs: RemoteHandlerNfs,
} }
// FIXME: should be done in xo-remote-parser. // FIXME: should be done in xo-remote-parser.
@ -84,7 +84,7 @@ export default class {
} }
async createRemote ({name, url}) { async createRemote ({name, url}) {
let remote = await this._remotes.create(name, url) const remote = await this._remotes.create(name, url)
return /* await */ this.updateRemote(remote.get('id'), {enabled: true}) return /* await */ this.updateRemote(remote.get('id'), {enabled: true})
} }
@ -125,7 +125,7 @@ export default class {
// TODO: Should it be private? // TODO: Should it be private?
async forgetAllRemotes () { async forgetAllRemotes () {
const remotes = await this.getAllRemotes() const remotes = await this.getAllRemotes()
for (let remote of remotes) { for (const remote of remotes) {
try { try {
(await this.getRemoteHandler(remote, true)).forget() (await this.getRemoteHandler(remote, true)).forget()
} catch (_) {} } catch (_) {}

View File

@ -5,7 +5,7 @@ import some from 'lodash/some'
import synchronized from 'decorator-synchronized' import synchronized from 'decorator-synchronized'
import { import {
noSuchObject, noSuchObject,
unauthorized unauthorized,
} from 'xo-common/api-errors' } from 'xo-common/api-errors'
import { import {
@ -15,7 +15,7 @@ import {
lightSet, lightSet,
map, map,
mapToArray, mapToArray,
streamToArray streamToArray,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -25,7 +25,7 @@ const VM_RESOURCES = {
disk: true, disk: true,
disks: true, disks: true,
memory: true, memory: true,
vms: true vms: true,
} }
const computeVmResourcesUsage = vm => { const computeVmResourcesUsage = vm => {
@ -51,7 +51,7 @@ const computeVmResourcesUsage = vm => {
disk, disk,
disks, disks,
memory: vm.memory_dynamic_max, memory: vm.memory_dynamic_max,
vms: 1 vms: 1,
} }
} }
@ -63,13 +63,13 @@ const normalize = set => ({
? limit ? limit
: { : {
available: limit, available: limit,
total: limit total: limit,
} }
) )
: {}, : {},
name: set.name || '', name: set.name || '',
objects: set.objects || [], objects: set.objects || [],
subjects: set.subjects || [] subjects: set.subjects || [],
}) })
// =================================================================== // ===================================================================
@ -115,11 +115,11 @@ export default class {
// (itself or its groups). // (itself or its groups).
!some(set.subjects, lightSet(user.groups).add(user.id).has) !some(set.subjects, lightSet(user.groups).add(user.id).has)
) || ( ) || (
objectIds && objectIds &&
// The set does not contains ALL objects. // The set does not contains ALL objects.
!every(objectIds, lightSet(set.objects).has) !every(objectIds, lightSet(set.objects).has)
)) { )) {
throw unauthorized() throw unauthorized()
} }
} }
@ -137,7 +137,7 @@ export default class {
name, name,
objects, objects,
subjects, subjects,
limits limits,
}) })
await this._store.put(id, set) await this._store.put(id, set)
@ -160,7 +160,7 @@ export default class {
subjects = undefined, subjects = undefined,
objects = undefined, objects = undefined,
limits = undefined, limits = undefined,
ipPools = undefined ipPools = undefined,
}) { }) {
const set = await this.getResourceSet(id) const set = await this.getResourceSet(id)
if (name) { if (name) {
@ -179,7 +179,7 @@ export default class {
if (!previous) { if (!previous) {
return { return {
available: quantity, available: quantity,
total: quantity total: quantity,
} }
} }
@ -187,7 +187,7 @@ export default class {
return { return {
available: available - total + quantity, available: available - total + quantity,
total: quantity total: quantity,
} }
}) })
} }
@ -212,7 +212,7 @@ export default class {
return streamToArray(this._store.createValueStream(), { return streamToArray(this._store.createValueStream(), {
filter, filter,
mapper: normalize mapper: normalize,
}) })
} }

View File

@ -5,7 +5,7 @@ import { Schedules } from '../models/schedule'
import { import {
forEach, forEach,
mapToArray, mapToArray,
scheduleFn scheduleFn,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -40,7 +40,7 @@ export default class {
const schedules = this._redisSchedules = new Schedules({ const schedules = this._redisSchedules = new Schedules({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:schedule', prefix: 'xo:schedule',
indexes: ['user_id', 'job'] indexes: ['user_id', 'job'],
}) })
this._scheduleTable = undefined this._scheduleTable = undefined

View File

@ -7,7 +7,7 @@ import { ensureDir } from 'fs-extra'
import { import {
forEach, forEach,
isFunction, isFunction,
promisify promisify,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -19,7 +19,7 @@ const _levelHas = function has (key, cb) {
error.notFound error.notFound
? cb(null, false) ? cb(null, false)
: cb(error) : cb(error)
) )
: cb(null, true) : cb(null, true)
) )
} }
@ -68,7 +68,7 @@ export default class {
const dir = `${xo._config.datadir}/leveldb` const dir = `${xo._config.datadir}/leveldb`
this._db = ensureDir(dir).then(() => { this._db = ensureDir(dir).then(() => {
return sublevel(levelup(dir, { return sublevel(levelup(dir, {
valueEncoding: 'json' valueEncoding: 'json',
})) }))
}) })
} }

View File

@ -3,24 +3,24 @@ import { ignoreErrors } from 'promise-toolbox'
import { import {
hash, hash,
needsRehash, needsRehash,
verify verify,
} from 'hashy' } from 'hashy'
import { import {
invalidCredentials, invalidCredentials,
noSuchObject noSuchObject,
} from 'xo-common/api-errors' } from 'xo-common/api-errors'
import { import {
Groups Groups,
} from '../models/group' } from '../models/group'
import { import {
Users Users,
} from '../models/user' } from '../models/user'
import { import {
forEach, forEach,
isEmpty, isEmpty,
lightSet, lightSet,
mapToArray mapToArray,
} from '../utils' } from '../utils'
// =================================================================== // ===================================================================
@ -40,17 +40,17 @@ export default class {
const groupsDb = this._groups = new Groups({ const groupsDb = this._groups = new Groups({
connection: redis, connection: redis,
prefix: 'xo:group' prefix: 'xo:group',
}) })
const usersDb = this._users = new Users({ const usersDb = this._users = new Users({
connection: redis, connection: redis,
prefix: 'xo:user', prefix: 'xo:user',
indexes: ['email'] indexes: ['email'],
}) })
xo.on('clean', () => Promise.all([ xo.on('clean', () => Promise.all([
groupsDb.rebuildIndexes(), groupsDb.rebuildIndexes(),
usersDb.rebuildIndexes() usersDb.rebuildIndexes(),
])) ]))
xo.on('start', async () => { xo.on('start', async () => {
xo.addConfigManager('groups', xo.addConfigManager('groups',
@ -135,7 +135,7 @@ export default class {
name = email, name = email,
password, password,
permission, permission,
preferences preferences,
}) { }) {
const user = await this.getUser(id) const user = await this.getUser(id)
@ -210,7 +210,7 @@ export default class {
// Get or create a user associated with an auth provider. // Get or create a user associated with an auth provider.
async registerUser (provider, name) { async registerUser (provider, name) {
let user = await this.getUserByName(name, true) const user = await this.getUserByName(name, true)
if (user) { if (user) {
if (user._provider !== provider) { if (user._provider !== provider) {
throw new Error(`the name ${name} is already taken`) throw new Error(`the name ${name} is already taken`)
@ -225,7 +225,7 @@ export default class {
return /* await */ this.createUser({ return /* await */ this.createUser({
name, name,
_provider: provider _provider: provider,
}) })
} }
@ -306,7 +306,7 @@ export default class {
async addUserToGroup (userId, groupId) { async addUserToGroup (userId, groupId) {
const [user, group] = await Promise.all([ const [user, group] = await Promise.all([
this.getUser(userId), this.getUser(userId),
this.getGroup(groupId) this.getGroup(groupId),
]) ])
user.groups = addToArraySet(user.groups, groupId) user.groups = addToArraySet(user.groups, groupId)
@ -314,7 +314,7 @@ export default class {
await Promise.all([ await Promise.all([
this._users.save(user), this._users.save(user),
this._groups.save(group) this._groups.save(group),
]) ])
} }
@ -331,12 +331,12 @@ export default class {
async removeUserFromGroup (userId, groupId) { async removeUserFromGroup (userId, groupId) {
const [user, group] = await Promise.all([ const [user, group] = await Promise.all([
this.getUser(userId), this.getUser(userId),
this.getGroup(groupId) this.getGroup(groupId),
]) ])
await Promise.all([ await Promise.all([
this._removeUserFromGroup(userId, group), this._removeUserFromGroup(userId, group),
this._removeGroupFromUser(groupId, user) this._removeGroupFromUser(groupId, user),
]) ])
} }
@ -357,7 +357,7 @@ export default class {
const getUser = ::this.getUser const getUser = ::this.getUser
const [newUsers, oldUsers] = await Promise.all([ const [newUsers, oldUsers] = await Promise.all([
Promise.all(newUsersIds.map(getUser)), Promise.all(newUsersIds.map(getUser)),
Promise.all(oldUsersIds.map(getUser)) Promise.all(oldUsersIds.map(getUser)),
]) ])
forEach(newUsers, user => { forEach(newUsers, user => {
@ -373,7 +373,7 @@ export default class {
await Promise.all([ await Promise.all([
Promise.all(mapToArray(newUsers, saveUser)), Promise.all(mapToArray(newUsers, saveUser)),
Promise.all(mapToArray(oldUsers, saveUser)), Promise.all(mapToArray(oldUsers, saveUser)),
this._groups.save(group) this._groups.save(group),
]) ])
} }
} }

View File

@ -11,10 +11,10 @@ import {
isEmpty, isEmpty,
isString, isString,
popProperty, popProperty,
serializeError serializeError,
} from '../utils' } from '../utils'
import { import {
Servers Servers,
} from '../models/server' } from '../models/server'
// =================================================================== // ===================================================================
@ -25,7 +25,7 @@ export default class {
const serversDb = this._servers = new Servers({ const serversDb = this._servers = new Servers({
connection: xo._redis, connection: xo._redis,
prefix: 'xo:server', prefix: 'xo:server',
indexes: ['host'] indexes: ['host'],
}) })
this._stats = new XapiStats() this._stats = new XapiStats()
this._xapis = createRawObject() this._xapis = createRawObject()
@ -41,7 +41,7 @@ export default class {
// Connects to existing servers. // Connects to existing servers.
const servers = await serversDb.get() const servers = await serversDb.get()
for (let server of servers) { for (const server of servers) {
if (server.enabled) { if (server.enabled) {
this.connectXenServer(server.id).catch(error => { this.connectXenServer(server.id).catch(error => {
console.error( console.error(
@ -62,7 +62,7 @@ export default class {
label, label,
password, password,
readOnly, readOnly,
username username,
}) { }) {
// FIXME: We are storing passwords which is bad! // FIXME: We are storing passwords which is bad!
// Could we use tokens instead? // Could we use tokens instead?
@ -74,7 +74,7 @@ export default class {
label: label || undefined, label: label || undefined,
password, password,
readOnly: readOnly ? 'true' : undefined, readOnly: readOnly ? 'true' : undefined,
username username,
}) })
return server.properties return server.properties
@ -96,7 +96,7 @@ export default class {
label, label,
password, password,
readOnly, readOnly,
username username,
}) { }) {
const server = await this._getXenServer(id) const server = await this._getXenServer(id)
const xapi = this._xapis[id] const xapi = this._xapis[id]
@ -225,10 +225,10 @@ export default class {
allowUnauthorized: Boolean(server.allowUnauthorized), allowUnauthorized: Boolean(server.allowUnauthorized),
auth: { auth: {
user: server.username, user: server.username,
password: server.password password: server.password,
}, },
readOnly: Boolean(server.readOnly), readOnly: Boolean(server.readOnly),
url: server.host url: server.host,
}) })
xapi.xo = (() => { xapi.xo = (() => {
@ -316,7 +316,7 @@ export default class {
// Register the updated object. // Register the updated object.
addObject(await xapi._waitObject(id)) addObject(await xapi._waitObject(id))
} },
} }
})() })()
@ -410,7 +410,7 @@ export default class {
const sourceXapi = this.getXapi(sourceId) const sourceXapi = this.getXapi(sourceId)
const { const {
_auth: { user, password }, _auth: { user, password },
_url: { hostname } _url: { hostname },
} = this.getXapi(targetId) } = this.getXapi(targetId)
// We don't want the events of the source XAPI to interfere with // We don't want the events of the source XAPI to interfere with

View File

@ -11,18 +11,18 @@ import {
isString, isString,
iteratee, iteratee,
map as mapToArray, map as mapToArray,
stubTrue stubTrue,
} from 'lodash' } from 'lodash'
import mixins from './xo-mixins' import mixins from './xo-mixins' // eslint-disable-line node/no-missing-import
import Connection from './connection' import Connection from './connection'
import { import {
mixin mixin,
} from './decorators' } from './decorators'
import { import {
createRawObject, createRawObject,
generateToken, generateToken,
noop noop,
} from './utils' } from './utils'
// =================================================================== // ===================================================================
@ -49,12 +49,12 @@ export default class Xo extends EventEmitter {
// Connects to Redis. // Connects to Redis.
{ {
const { const {
renameCommands: rename_commands, renameCommands,
socket: path, socket: path,
uri: url uri: url,
} = config.redis || {} } = config.redis || {}
this._redis = createRedisClient({ path, rename_commands, url }) this._redis = createRedisClient({ path, rename_commands: renameCommands, url })
} }
this.on('start', () => this._watchObjects()) this.on('start', () => this._watchObjects())
@ -67,8 +67,8 @@ export default class Xo extends EventEmitter {
const { const {
all, all,
indexes: { indexes: {
byRef byRef,
} },
} = this._objects } = this._objects
const obj = all[key] || byRef[key] const obj = all[key] || byRef[key]
@ -180,7 +180,7 @@ export default class Xo extends EventEmitter {
watchers[url] = { watchers[url] = {
data, data,
fn fn,
} }
return url return url
@ -188,7 +188,7 @@ export default class Xo extends EventEmitter {
async registerHttpRequestHandler (url, fn, { async registerHttpRequestHandler (url, fn, {
data = undefined, data = undefined,
persistent = true persistent = true,
} = {}) { } = {}) {
const {_httpRequestWatchers: watchers} = this const {_httpRequestWatchers: watchers} = this
@ -199,7 +199,7 @@ export default class Xo extends EventEmitter {
watchers[url] = { watchers[url] = {
data, data,
fn, fn,
persistent persistent,
} }
} }
@ -224,7 +224,7 @@ export default class Xo extends EventEmitter {
Object.defineProperty(this, name, { Object.defineProperty(this, name, {
configurable: true, configurable: true,
value value,
}) })
let unset = () => { let unset = () => {
@ -260,7 +260,7 @@ export default class Xo extends EventEmitter {
_watchObjects () { _watchObjects () {
const { const {
_connections: connections, _connections: connections,
_objects: objects _objects: objects,
} = this } = this
let entered, exited let entered, exited
@ -289,11 +289,11 @@ export default class Xo extends EventEmitter {
objects.on('finish', () => { objects.on('finish', () => {
const enteredMessage = !isEmpty(entered) && { const enteredMessage = !isEmpty(entered) && {
type: 'enter', type: 'enter',
items: entered items: entered,
} }
const exitedMessage = !isEmpty(exited) && { const exitedMessage = !isEmpty(exited) && {
type: 'exit', type: 'exit',
items: exited items: exited,
} }
if (!enteredMessage && !exitedMessage) { if (!enteredMessage && !exitedMessage) {

553
yarn.lock
View File

@ -168,11 +168,11 @@ agent-base@^4.1.0:
dependencies: dependencies:
es6-promisify "^5.0.0" es6-promisify "^5.0.0"
ajv-keywords@^1.0.0: ajv-keywords@^2.1.0:
version "1.5.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
ajv@^4.7.0, ajv@^4.9.1: ajv@^4.9.1:
version "4.11.8" version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies: dependencies:
@ -188,6 +188,15 @@ ajv@^5.1.0, ajv@^5.3.0:
fast-json-stable-stringify "^2.0.0" fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0" json-schema-traverse "^0.3.0"
ajv@^5.2.3:
version "5.5.1"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
align-text@^0.1.1, align-text@^0.1.3: align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@ -200,10 +209,6 @@ amdefine@>=0.0.4:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
ansi-escapes@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
ansi-escapes@^3.0.0: ansi-escapes@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
@ -388,13 +393,6 @@ array-unique@^0.3.2:
version "0.3.2" version "0.3.2"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
array.prototype.find@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.7.0"
arrify@^1.0.0, arrify@^1.0.1: arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@ -480,7 +478,7 @@ aws4@^1.2.1, aws4@^1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0" version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
dependencies: dependencies:
@ -1495,7 +1493,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0" strip-ansi "^3.0.0"
supports-color "^2.0.0" supports-color "^2.0.0"
chalk@^2.0.0, chalk@^2.0.1: chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
dependencies: dependencies:
@ -1509,6 +1507,10 @@ character-parser@^2.1.1:
dependencies: dependencies:
is-regex "^1.0.3" is-regex "^1.0.3"
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
child-process-promise@^2.0.3: child-process-promise@^2.0.3:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074"
@ -1561,11 +1563,11 @@ clean-css@^3.3.0:
commander "2.8.x" commander "2.8.x"
source-map "0.4.x" source-map "0.4.x"
cli-cursor@^1.0.1: cli-cursor@^2.1.0:
version "1.0.2" version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies: dependencies:
restore-cursor "^1.0.1" restore-cursor "^2.0.0"
cli-width@^2.0.0: cli-width@^2.0.0:
version "2.2.0" version "2.2.0"
@ -1661,7 +1663,7 @@ concat-map@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concat-stream@^1.5.2, concat-stream@~1.6.0: concat-stream@^1.6.0, concat-stream@~1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
dependencies: dependencies:
@ -1776,7 +1778,7 @@ cross-spawn@^4.0.2:
lru-cache "^4.0.1" lru-cache "^4.0.1"
which "^1.2.9" which "^1.2.9"
cross-spawn@^5.0.1: cross-spawn@^5.0.1, cross-spawn@^5.1.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies: dependencies:
@ -1861,11 +1863,7 @@ debug-fabulous@>=0.1.1:
memoizee "0.4.X" memoizee "0.4.X"
object-assign "4.X" object-assign "4.X"
debug-log@^1.0.0: debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"
debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies: dependencies:
@ -1925,13 +1923,6 @@ deferred-leveldown@~2.0.2:
dependencies: dependencies:
abstract-leveldown "~3.0.0" abstract-leveldown "~3.0.0"
define-properties@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
dependencies:
foreach "^2.0.5"
object-keys "^1.0.8"
define-property@^0.2.5: define-property@^0.2.5:
version "0.2.5" version "0.2.5"
resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
@ -1956,17 +1947,6 @@ degenerator@^1.0.4:
escodegen "1.x.x" escodegen "1.x.x"
esprima "3.x.x" esprima "3.x.x"
deglob@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/deglob/-/deglob-2.1.0.tgz#4d44abe16ef32c779b4972bd141a80325029a14a"
dependencies:
find-root "^1.0.0"
glob "^7.0.5"
ignore "^3.0.9"
pkg-config "^1.1.0"
run-parallel "^1.1.2"
uniq "^1.0.1"
del@^2.0.2: del@^2.0.2:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
@ -2027,19 +2007,18 @@ dns-prefetch-control@0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2" resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2"
doctrine@1.5.0, doctrine@^1.2.2: doctrine@1.5.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
isarray "^1.0.0" isarray "^1.0.0"
doctrine@^2.0.0: doctrine@^2.0.2:
version "2.0.0" version "2.0.2"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
isarray "^1.0.0"
doctypes@^1.1.0: doctypes@^1.1.0:
version "1.1.0" version "1.1.0"
@ -2119,24 +2098,6 @@ error-ex@^1.2.0:
dependencies: dependencies:
is-arrayish "^0.2.1" is-arrayish "^0.2.1"
es-abstract@^1.7.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
dependencies:
es-to-primitive "^1.1.1"
function-bind "^1.1.1"
has "^1.0.1"
is-callable "^1.1.3"
is-regex "^1.0.4"
es-to-primitive@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
dependencies:
is-callable "^1.1.1"
is-date-object "^1.0.1"
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2: es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
version "0.10.35" version "0.10.35"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f"
@ -2152,17 +2113,6 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1:
es5-ext "^0.10.35" es5-ext "^0.10.35"
es6-symbol "^3.1.1" es6-symbol "^3.1.1"
es6-map@^0.1.3:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-set "~0.1.5"
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-promise@^4.0.3: es6-promise@^4.0.3:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
@ -2173,17 +2123,7 @@ es6-promisify@^5.0.0:
dependencies: dependencies:
es6-promise "^4.0.3" es6-promise "^4.0.3"
es6-set@~0.1.5: es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-symbol "3.1.1"
event-emitter "~0.3.5"
es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies: dependencies:
@ -2237,122 +2177,106 @@ escodegen@~1.3.2:
optionalDependencies: optionalDependencies:
source-map "~0.1.33" source-map "~0.1.33"
escope@^3.6.0: eslint-config-standard@^11.0.0-beta.0:
version "3.6.0" version "11.0.0-beta.0"
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-11.0.0-beta.0.tgz#f8afe69803d95c685a4b8392b8793188eb03cbb3"
eslint-import-resolver-node@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc"
dependencies: dependencies:
es6-map "^0.1.3" debug "^2.6.8"
es6-weak-map "^2.0.1" resolve "^1.2.0"
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-config-standard-jsx@4.0.2: eslint-module-utils@^2.1.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz#009e53c4ddb1e9ee70b4650ffe63a7f39f8836e1"
eslint-config-standard@10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591"
eslint-import-resolver-node@^0.2.0:
version "0.2.3"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c"
dependencies:
debug "^2.2.0"
object-assign "^4.0.1"
resolve "^1.1.6"
eslint-module-utils@^2.0.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
dependencies: dependencies:
debug "^2.6.8" debug "^2.6.8"
pkg-dir "^1.0.0" pkg-dir "^1.0.0"
eslint-plugin-import@~2.2.0: eslint-plugin-import@^2.8.0:
version "2.2.0" version "2.8.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894"
dependencies: dependencies:
builtin-modules "^1.1.1" builtin-modules "^1.1.1"
contains-path "^0.1.0" contains-path "^0.1.0"
debug "^2.2.0" debug "^2.6.8"
doctrine "1.5.0" doctrine "1.5.0"
eslint-import-resolver-node "^0.2.0" eslint-import-resolver-node "^0.3.1"
eslint-module-utils "^2.0.0" eslint-module-utils "^2.1.1"
has "^1.0.1" has "^1.0.1"
lodash.cond "^4.3.0" lodash.cond "^4.3.0"
minimatch "^3.0.3" minimatch "^3.0.3"
pkg-up "^1.0.0" read-pkg-up "^2.0.0"
eslint-plugin-node@~4.2.2: eslint-plugin-node@^5.2.1:
version "4.2.3" version "5.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz#c04390ab8dbcbb6887174023d6f3a72769e63b97" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz#80df3253c4d7901045ec87fa660a284e32bdca29"
dependencies: dependencies:
ignore "^3.0.11" ignore "^3.3.6"
minimatch "^3.0.2" minimatch "^3.0.4"
object-assign "^4.0.1" resolve "^1.3.3"
resolve "^1.1.7"
semver "5.3.0" semver "5.3.0"
eslint-plugin-promise@~3.5.0: eslint-plugin-promise@^3.6.0:
version "3.5.0" version "3.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz#78fbb6ffe047201627569e85a6c5373af2a68fca" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz#54b7658c8f454813dc2a870aff8152ec4969ba75"
eslint-plugin-react@~6.10.0: eslint-plugin-standard@^3.0.1:
version "6.10.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78"
dependencies:
array.prototype.find "^2.0.1"
doctrine "^1.2.2"
has "^1.0.1"
jsx-ast-utils "^1.3.4"
object.assign "^4.0.4"
eslint-plugin-standard@~3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2"
eslint@~3.19.0: eslint-scope@^3.7.1:
version "3.19.0" version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
dependencies: dependencies:
babel-code-frame "^6.16.0" esrecurse "^4.1.0"
chalk "^1.1.3" estraverse "^4.1.1"
concat-stream "^1.5.2"
debug "^2.1.1" eslint@^4.13.1:
doctrine "^2.0.0" version "4.13.1"
escope "^3.6.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f"
espree "^3.4.0" dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
chalk "^2.1.0"
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.0.1"
doctrine "^2.0.2"
eslint-scope "^3.7.1"
espree "^3.5.2"
esquery "^1.0.0" esquery "^1.0.0"
estraverse "^4.2.0" estraverse "^4.2.0"
esutils "^2.0.2" esutils "^2.0.2"
file-entry-cache "^2.0.0" file-entry-cache "^2.0.0"
glob "^7.0.3" functional-red-black-tree "^1.0.1"
globals "^9.14.0" glob "^7.1.2"
ignore "^3.2.0" globals "^11.0.1"
ignore "^3.3.3"
imurmurhash "^0.1.4" imurmurhash "^0.1.4"
inquirer "^0.12.0" inquirer "^3.0.6"
is-my-json-valid "^2.10.0"
is-resolvable "^1.0.0" is-resolvable "^1.0.0"
js-yaml "^3.5.1" js-yaml "^3.9.1"
json-stable-stringify "^1.0.0" json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0" levn "^0.3.0"
lodash "^4.0.0" lodash "^4.17.4"
mkdirp "^0.5.0" minimatch "^3.0.2"
mkdirp "^0.5.1"
natural-compare "^1.4.0" natural-compare "^1.4.0"
optionator "^0.8.2" optionator "^0.8.2"
path-is-inside "^1.0.1" path-is-inside "^1.0.2"
pluralize "^1.2.1" pluralize "^7.0.0"
progress "^1.1.8" progress "^2.0.0"
require-uncached "^1.0.2" require-uncached "^1.0.3"
shelljs "^0.7.5" semver "^5.3.0"
strip-bom "^3.0.0" strip-ansi "^4.0.0"
strip-json-comments "~2.0.1" strip-json-comments "~2.0.1"
table "^3.7.8" table "^4.0.1"
text-table "~0.2.0" text-table "~0.2.0"
user-home "^2.0.0"
espree@^3.4.0: espree@^3.5.2:
version "3.5.2" version "3.5.2"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca"
dependencies: dependencies:
@ -2412,7 +2336,7 @@ etag@~1.8.1:
version "1.8.1" version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
event-emitter@^0.3.5, event-emitter@~0.3.5: event-emitter@^0.3.5:
version "0.3.5" version "0.3.5"
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
dependencies: dependencies:
@ -2473,10 +2397,6 @@ execa@^0.8.0:
signal-exit "^3.0.0" signal-exit "^3.0.0"
strip-eof "^1.0.0" strip-eof "^1.0.0"
exit-hook@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
expand-brackets@^0.1.4: expand-brackets@^0.1.4:
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
@ -2591,6 +2511,14 @@ extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
external-editor@^2.0.4:
version "2.1.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
dependencies:
chardet "^0.4.0"
iconv-lite "^0.4.17"
tmp "^0.0.33"
extglob@^0.3.1: extglob@^0.3.1:
version "0.3.2" version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
@ -2664,12 +2592,11 @@ fifolock@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fifolock/-/fifolock-1.0.0.tgz#a37e54f3ebe69d13480d95a82abc42b7a5c1792d" resolved "https://registry.yarnpkg.com/fifolock/-/fifolock-1.0.0.tgz#a37e54f3ebe69d13480d95a82abc42b7a5c1792d"
figures@^1.3.5: figures@^2.0.0:
version "1.7.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
dependencies: dependencies:
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
object-assign "^4.1.0"
file-entry-cache@^2.0.0: file-entry-cache@^2.0.0:
version "2.0.0" version "2.0.0"
@ -2724,10 +2651,6 @@ finalhandler@1.1.0:
statuses "~1.3.1" statuses "~1.3.1"
unpipe "~1.0.0" unpipe "~1.0.0"
find-root@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
find-up@^1.0.0: find-up@^1.0.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@ -2916,10 +2839,14 @@ ftp@~0.3.10:
readable-stream "1.1.x" readable-stream "1.1.x"
xregexp "2.0.0" xregexp "2.0.0"
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: function-bind@^1.0.2:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
gauge@~2.7.3: gauge@~2.7.3:
version "2.7.4" version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@ -2937,7 +2864,7 @@ generate-function@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
generate-object-property@^1.1.0, generate-object-property@^1.2.0: generate-object-property@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
dependencies: dependencies:
@ -2947,10 +2874,6 @@ get-caller-file@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
get-stdin@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
get-stream@^3.0.0: get-stream@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@ -3063,7 +2986,11 @@ globals@^10.0.0:
version "10.3.0" version "10.3.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-10.3.0.tgz#716aba93657b56630b5a0e77de5ea8ac6215afaa" resolved "https://registry.yarnpkg.com/globals/-/globals-10.3.0.tgz#716aba93657b56630b5a0e77de5ea8ac6215afaa"
globals@^9.14.0, globals@^9.18.0: globals@^11.0.1:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
globals@^9.18.0:
version "9.18.0" version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@ -3505,7 +3432,7 @@ husky@^0.14.3:
normalize-path "^1.0.0" normalize-path "^1.0.0"
strip-indent "^2.0.0" strip-indent "^2.0.0"
iconv-lite@0.4.19: iconv-lite@0.4.19, iconv-lite@^0.4.17:
version "0.4.19" version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@ -3513,7 +3440,7 @@ ienoopen@1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b" resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b"
ignore@^3.0.11, ignore@^3.0.9, ignore@^3.2.0: ignore@^3.3.3, ignore@^3.3.6:
version "3.3.7" version "3.3.7"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
@ -3543,22 +3470,23 @@ ini@^1.3.4, ini@~1.3.0:
version "1.3.4" version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
inquirer@^0.12.0: inquirer@^3.0.6:
version "0.12.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
dependencies: dependencies:
ansi-escapes "^1.1.0" ansi-escapes "^3.0.0"
ansi-regex "^2.0.0" chalk "^2.0.0"
chalk "^1.0.0" cli-cursor "^2.1.0"
cli-cursor "^1.0.1"
cli-width "^2.0.0" cli-width "^2.0.0"
figures "^1.3.5" external-editor "^2.0.4"
figures "^2.0.0"
lodash "^4.3.0" lodash "^4.3.0"
readline2 "^1.0.1" mute-stream "0.0.7"
run-async "^0.1.0" run-async "^2.2.0"
rx-lite "^3.1.2" rx-lite "^4.0.8"
string-width "^1.0.1" rx-lite-aggregates "^4.0.8"
strip-ansi "^3.0.0" string-width "^2.1.0"
strip-ansi "^4.0.0"
through "^2.3.6" through "^2.3.6"
interpret@^1.0.0: interpret@^1.0.0:
@ -3616,10 +3544,6 @@ is-builtin-module@^1.0.0:
dependencies: dependencies:
builtin-modules "^1.0.0" builtin-modules "^1.0.0"
is-callable@^1.1.1, is-callable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
is-ci@^1.0.10: is-ci@^1.0.10:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
@ -3632,10 +3556,6 @@ is-data-descriptor@^0.1.4:
dependencies: dependencies:
kind-of "^3.0.2" kind-of "^3.0.2"
is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
is-descriptor@^0.1.0: is-descriptor@^0.1.0:
version "0.1.6" version "0.1.6"
resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
@ -3716,15 +3636,6 @@ is-glob@^3.1.0:
dependencies: dependencies:
is-extglob "^2.1.0" is-extglob "^2.1.0"
is-my-json-valid@^2.10.0:
version "2.16.1"
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
is-number@^2.1.0: is-number@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
@ -3773,7 +3684,7 @@ is-primitive@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
is-promise@^2.0.0, is-promise@^2.1: is-promise@^2.0.0, is-promise@^2.1, is-promise@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
@ -3785,7 +3696,7 @@ is-redirect@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
is-regex@^1.0.3, is-regex@^1.0.4: is-regex@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
dependencies: dependencies:
@ -3807,10 +3718,6 @@ is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
is-typedarray@~1.0.0: is-typedarray@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@ -4159,7 +4066,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
js-yaml@^3.10.0, js-yaml@^3.5.1, js-yaml@^3.7.0: js-yaml@^3.10.0, js-yaml@^3.7.0, js-yaml@^3.9.1:
version "3.10.0" version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies: dependencies:
@ -4225,6 +4132,10 @@ json-schema@0.2.3:
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
@ -4249,10 +4160,6 @@ jsonify@~0.0.0:
version "0.0.0" version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jsonpointer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
jsprim@^1.2.2: jsprim@^1.2.2:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -4269,10 +4176,6 @@ jstransformer@1.0.0:
is-promise "^2.0.0" is-promise "^2.0.0"
promise "^7.0.1" promise "^7.0.1"
jsx-ast-utils@^1.3.4:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1"
julien-f-source-map-support@0.1.0: julien-f-source-map-support@0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/julien-f-source-map-support/-/julien-f-source-map-support-0.1.0.tgz#174152c8509538cf666d813eff77cb261711f0af" resolved "https://registry.yarnpkg.com/julien-f-source-map-support/-/julien-f-source-map-support-0.1.0.tgz#174152c8509538cf666d813eff77cb261711f0af"
@ -4696,7 +4599,7 @@ lodash@^3.10.1:
version "3.10.1" version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.0, lodash@^4.16.6, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0: lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.0, lodash@^4.16.6, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0:
version "4.17.4" version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@ -4965,9 +4868,9 @@ mute-stdout@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.0.tgz#5b32ea07eb43c9ded6130434cf926f46b2a7fd4d" resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.0.tgz#5b32ea07eb43c9ded6130434cf926f46b2a7fd4d"
mute-stream@0.0.5: mute-stream@0.0.7:
version "0.0.5" version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
nan@2.6.2, nan@~2.6.1: nan@2.6.2, nan@~2.6.1:
version "2.6.2" version "2.6.2"
@ -5170,7 +5073,7 @@ object-inspect@~0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec"
object-keys@^1.0.10, object-keys@^1.0.6, object-keys@^1.0.8: object-keys@^1.0.6:
version "1.0.11" version "1.0.11"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
@ -5184,14 +5087,6 @@ object-visit@^1.0.0:
dependencies: dependencies:
isobject "^3.0.0" isobject "^3.0.0"
object.assign@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc"
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.0"
object-keys "^1.0.10"
object.defaults@^1.0.0, object.defaults@^1.1.0: object.defaults@^1.0.0, object.defaults@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
@ -5237,9 +5132,11 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0:
dependencies: dependencies:
wrappy "1" wrappy "1"
onetime@^1.0.0: onetime@^2.0.0:
version "1.1.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
dependencies:
mimic-fn "^1.0.0"
optimist@^0.6.1: optimist@^0.6.1:
version "0.6.1" version "0.6.1"
@ -5425,7 +5322,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-is-inside@^1.0.1: path-is-inside@^1.0.1, path-is-inside@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
@ -5501,40 +5398,19 @@ pipette@^0.9.3:
dependencies: dependencies:
typ "~0.6.1" typ "~0.6.1"
pkg-conf@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279"
dependencies:
find-up "^2.0.0"
load-json-file "^2.0.0"
pkg-config@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pkg-config/-/pkg-config-1.1.1.tgz#557ef22d73da3c8837107766c52eadabde298fe4"
dependencies:
debug-log "^1.0.0"
find-root "^1.0.0"
xtend "^4.0.1"
pkg-dir@^1.0.0: pkg-dir@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
dependencies: dependencies:
find-up "^1.0.0" find-up "^1.0.0"
pkg-up@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
dependencies:
find-up "^1.0.0"
platform@1.3.4: platform@1.3.4:
version "1.3.4" version "1.3.4"
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd" resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd"
pluralize@^1.2.1: pluralize@^7.0.0:
version "1.2.1" version "7.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
posix-character-classes@^0.1.0: posix-character-classes@^0.1.0:
version "0.1.1" version "0.1.1"
@ -5586,9 +5462,9 @@ process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
progress@^1.1.8: progress@^2.0.0:
version "1.1.8" version "2.0.0"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
promise-polyfill@^6.0.1: promise-polyfill@^6.0.1:
version "6.0.2" version "6.0.2"
@ -5938,14 +5814,6 @@ readdirp@^2.0.0:
readable-stream "^2.0.2" readable-stream "^2.0.2"
set-immediate-shim "^1.0.1" set-immediate-shim "^1.0.1"
readline2@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
mute-stream "0.0.5"
rechoir@^0.6.2: rechoir@^0.6.2:
version "0.6.2" version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@ -6110,7 +5978,7 @@ require-package-name@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
require-uncached@^1.0.2: require-uncached@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
dependencies: dependencies:
@ -6140,18 +6008,18 @@ resolve@1.1.7, resolve@~1.1.6:
version "1.1.7" version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7: resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.3:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies: dependencies:
path-parse "^1.0.5" path-parse "^1.0.5"
restore-cursor@^1.0.1: restore-cursor@^2.0.0:
version "1.0.1" version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
dependencies: dependencies:
exit-hook "^1.0.0" onetime "^2.0.0"
onetime "^1.0.0" signal-exit "^3.0.2"
right-align@^0.1.1: right-align@^0.1.1:
version "0.1.3" version "0.1.3"
@ -6165,19 +6033,21 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.6.2:
dependencies: dependencies:
glob "^7.0.5" glob "^7.0.5"
run-async@^0.1.0: run-async@^2.2.0:
version "0.1.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
dependencies: dependencies:
once "^1.3.0" is-promise "^2.1.0"
run-parallel@^1.1.2: rx-lite-aggregates@^4.0.8:
version "1.1.6" version "4.0.8"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
dependencies:
rx-lite "*"
rx-lite@^3.1.2: rx-lite@*, rx-lite@^4.0.8:
version "3.1.2" version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1" version "5.1.1"
@ -6314,14 +6184,6 @@ shebang-regex@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
shelljs@^0.7.5:
version "0.7.8"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
shellwords@^0.1.0: shellwords@^0.1.0:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@ -6352,9 +6214,11 @@ slash@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
slice-ansi@0.0.4: slice-ansi@1.0.0:
version "0.0.4" version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
dependencies:
is-fullwidth-code-point "^2.0.0"
"slice-stream@>= 1.0.0 < 2": "slice-stream@>= 1.0.0 < 2":
version "1.0.0" version "1.0.0"
@ -6540,29 +6404,6 @@ stack-trace@0.0.9:
version "0.0.9" version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
standard-engine@~7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-7.0.0.tgz#ebb77b9c8fc2c8165ffa353bd91ba0dff41af690"
dependencies:
deglob "^2.1.0"
get-stdin "^5.0.1"
minimist "^1.1.0"
pkg-conf "^2.0.0"
standard@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/standard/-/standard-10.0.3.tgz#7869bcbf422bdeeaab689a1ffb1fea9677dd50ea"
dependencies:
eslint "~3.19.0"
eslint-config-standard "10.2.1"
eslint-config-standard-jsx "4.0.2"
eslint-plugin-import "~2.2.0"
eslint-plugin-node "~4.2.2"
eslint-plugin-promise "~3.5.0"
eslint-plugin-react "~6.10.0"
eslint-plugin-standard "~3.0.1"
standard-engine "~7.0.0"
static-eval@~0.2.0: static-eval@~0.2.0:
version "0.2.4" version "0.2.4"
resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b" resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b"
@ -6630,7 +6471,7 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0" is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0" strip-ansi "^3.0.0"
string-width@^2.0.0: string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
dependencies: dependencies:
@ -6734,16 +6575,16 @@ symbol-tree@^3.2.1:
version "3.2.2" version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
table@^3.7.8: table@^4.0.1:
version "3.8.3" version "4.0.2"
resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
dependencies: dependencies:
ajv "^4.7.0" ajv "^5.2.3"
ajv-keywords "^1.0.0" ajv-keywords "^2.1.0"
chalk "^1.1.1" chalk "^2.1.0"
lodash "^4.0.0" lodash "^4.17.4"
slice-ansi "0.0.4" slice-ansi "1.0.0"
string-width "^2.0.0" string-width "^2.1.1"
tar-fs@^1.13.0: tar-fs@^1.13.0:
version "1.16.0" version "1.16.0"
@ -7029,10 +6870,6 @@ union-value@^1.0.0:
is-extendable "^0.1.1" is-extendable "^0.1.1"
set-value "^0.4.3" set-value "^0.4.3"
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
unique-stream@^2.0.2: unique-stream@^2.0.2:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369"
@ -7075,12 +6912,6 @@ user-home@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
user-home@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
dependencies:
os-homedir "^1.0.0"
util-deprecate@^1.0.2, util-deprecate@~1.0.1: util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"