feat: use ESLint instead of standard (#630)
This commit is contained in:
parent
d2f88d0a02
commit
4905a0310a
15
.eslintrc.js
Normal file
15
.eslintrc.js
Normal 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',
|
||||
},
|
||||
}
|
@ -2,11 +2,11 @@ Error.stackTraceLimit = 100
|
||||
|
||||
// Removes internal modules.
|
||||
try {
|
||||
var sep = require('path').sep
|
||||
const sep = require('path').sep
|
||||
|
||||
require('stack-chain').filter.attach(function (_, frames) {
|
||||
var filtered = frames.filter(function (frame) {
|
||||
var name = frame && frame.getFileName()
|
||||
const filtered = frames.filter(function (frame) {
|
||||
const name = frame && frame.getFileName()
|
||||
|
||||
return (
|
||||
// has a filename
|
||||
|
28
gulpfile.js
28
gulpfile.js
@ -2,23 +2,23 @@
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var gulp = require('gulp')
|
||||
const gulp = require('gulp')
|
||||
|
||||
var babel = require('gulp-babel')
|
||||
var coffee = require('gulp-coffee')
|
||||
var plumber = require('gulp-plumber')
|
||||
var rimraf = require('rimraf')
|
||||
var sourceMaps = require('gulp-sourcemaps')
|
||||
var watch = require('gulp-watch')
|
||||
const babel = require('gulp-babel')
|
||||
const coffee = require('gulp-coffee')
|
||||
const plumber = require('gulp-plumber')
|
||||
const rimraf = require('rimraf')
|
||||
const sourceMaps = require('gulp-sourcemaps')
|
||||
const watch = require('gulp-watch')
|
||||
|
||||
var join = require('path').join
|
||||
const join = require('path').join
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var SRC_DIR = join(__dirname, 'src')
|
||||
var DIST_DIR = join(__dirname, 'dist')
|
||||
const SRC_DIR = join(__dirname, 'src')
|
||||
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
|
||||
? gulp.src(patterns, {
|
||||
base: SRC_DIR,
|
||||
cwd: SRC_DIR
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
: watch(patterns, {
|
||||
base: SRC_DIR,
|
||||
cwd: SRC_DIR,
|
||||
ignoreInitial: false,
|
||||
verbose: true
|
||||
verbose: true,
|
||||
})
|
||||
.pipe(plumber())
|
||||
}
|
||||
@ -47,7 +47,7 @@ gulp.task(function buildCoffee () {
|
||||
return src('**/*.coffee')
|
||||
.pipe(sourceMaps.init())
|
||||
.pipe(coffee({
|
||||
bare: true
|
||||
bare: true,
|
||||
}))
|
||||
|
||||
// Necessary to correctly compile generators.
|
||||
|
2
index.js
2
index.js
@ -8,4 +8,4 @@ if (process.env.DEBUG === undefined) {
|
||||
}
|
||||
|
||||
// Import the real main module.
|
||||
module.exports = require('./dist').default
|
||||
module.exports = require('./dist').default // eslint-disable-line node/no-missing-require
|
||||
|
17
package.json
17
package.json
@ -125,6 +125,12 @@
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.6.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-babel": "^7.0.0",
|
||||
"gulp-coffee": "^2.3.4",
|
||||
@ -134,18 +140,17 @@
|
||||
"husky": "^0.14.3",
|
||||
"index-modules": "^0.3.0",
|
||||
"jest": "^21.2.1",
|
||||
"rimraf": "^2.6.2",
|
||||
"standard": "^10.0.3"
|
||||
"rimraf": "^2.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build --production",
|
||||
"commitmsg": "yarn run test",
|
||||
"dev": "gulp build",
|
||||
"dev-test": "jest --bail --watch",
|
||||
"posttest": "standard",
|
||||
"prebuild": "index-modules src/api src/xapi/mixins src/xo-mixins",
|
||||
"predev": "yarn run prebuild",
|
||||
"prepublishOnly": "yarn run build",
|
||||
"pretest": "eslint --ignore-path .gitignore --fix .",
|
||||
"start": "node bin/xo-server",
|
||||
"test": "jest"
|
||||
},
|
||||
@ -172,11 +177,5 @@
|
||||
"<rootDir>/src"
|
||||
],
|
||||
"testRegex": "\\.spec\\.js$"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"dist"
|
||||
],
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ add.permission = 'admin'
|
||||
add.params = {
|
||||
subject: { type: 'string' },
|
||||
object: { type: 'string' },
|
||||
action: { type: 'string' }
|
||||
action: { type: 'string' },
|
||||
}
|
||||
|
||||
add.description = 'add a new ACL entry'
|
||||
@ -43,7 +43,7 @@ remove.permission = 'admin'
|
||||
remove.params = {
|
||||
subject: { type: 'string' },
|
||||
object: { type: 'string' },
|
||||
action: { type: 'string' }
|
||||
action: { type: 'string' },
|
||||
}
|
||||
|
||||
remove.description = 'remove an existing ACL entry'
|
||||
|
@ -11,7 +11,7 @@ export function list ({ remote }) {
|
||||
|
||||
list.permission = 'admin'
|
||||
list.params = {
|
||||
remote: { type: 'string' }
|
||||
remote: { type: 'string' },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -23,7 +23,7 @@ export function scanDisk ({ remote, disk }) {
|
||||
scanDisk.permission = 'admin'
|
||||
scanDisk.params = {
|
||||
remote: { type: 'string' },
|
||||
disk: { type: 'string' }
|
||||
disk: { type: 'string' },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -37,7 +37,7 @@ scanFiles.params = {
|
||||
remote: { type: 'string' },
|
||||
disk: { type: 'string' },
|
||||
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])
|
||||
|
||||
return this.registerHttpRequest(handleFetchFiles, { ...params, format }, {
|
||||
suffix: encodeURI(`/${fileName}`)
|
||||
suffix: encodeURI(`/${fileName}`),
|
||||
}).then(url => ({ $getFrom: url }))
|
||||
}
|
||||
|
||||
@ -93,6 +93,6 @@ fetchFiles.params = {
|
||||
paths: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
minLength: 1
|
||||
}
|
||||
minLength: 1,
|
||||
},
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ export async function create ({ name, size, sr, vm, bootable, position, mode })
|
||||
const xapi = this.getXapi(sr)
|
||||
const vdi = await xapi.createVdi(parseSize(size), {
|
||||
name_label: name,
|
||||
sr: sr._xapiId
|
||||
sr: sr._xapiId,
|
||||
})
|
||||
|
||||
if (attach) {
|
||||
await xapi.attachVdiToVm(vdi.$id, vm._xapiId, {
|
||||
bootable,
|
||||
position,
|
||||
readOnly: mode === 'RO'
|
||||
readOnly: mode === 'RO',
|
||||
})
|
||||
}
|
||||
|
||||
@ -40,12 +40,12 @@ create.params = {
|
||||
vm: { type: 'string', optional: true },
|
||||
bootable: { type: 'boolean', optional: true },
|
||||
mode: { type: 'string', optional: true },
|
||||
position: { type: 'string', optional: true }
|
||||
position: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
create.resolve = {
|
||||
vm: ['vm', 'VM', 'administrate'],
|
||||
sr: ['sr', 'SR', false]
|
||||
sr: ['sr', 'SR', false],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -58,9 +58,9 @@ resize.description = 'resize an existing VDI'
|
||||
|
||||
resize.params = {
|
||||
id: { type: 'string' },
|
||||
size: { type: ['integer', 'string'] }
|
||||
size: { type: ['integer', 'string'] },
|
||||
}
|
||||
|
||||
resize.resolve = {
|
||||
vdi: ['id', ['VDI', 'VDI-snapshot'], 'administrate']
|
||||
vdi: ['id', ['VDI', 'VDI-snapshot'], 'administrate'],
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ export async function register ({vm}) {
|
||||
register.description = 'Register the VM for Docker management'
|
||||
|
||||
register.params = {
|
||||
vm: { type: 'string' }
|
||||
vm: { type: 'string' },
|
||||
}
|
||||
|
||||
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.params = {
|
||||
vm: { type: 'string' }
|
||||
vm: { type: 'string' },
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
for (let fn of [start, stop, restart, pause, unpause]) {
|
||||
for (const fn of [start, stop, restart, pause, unpause]) {
|
||||
fn.params = {
|
||||
vm: { type: 'string' },
|
||||
container: { type: 'string' }
|
||||
container: { type: 'string' },
|
||||
}
|
||||
|
||||
fn.resolve = {
|
||||
vm: ['vm', 'VM', 'operate']
|
||||
vm: ['vm', 'VM', 'operate'],
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ export async function create ({name}) {
|
||||
create.description = 'creates a new group'
|
||||
create.permission = 'admin'
|
||||
create.params = {
|
||||
name: {type: 'string'}
|
||||
name: {type: 'string'},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -21,7 +21,7 @@ export {delete_ as delete}
|
||||
delete_.description = 'deletes an existing group'
|
||||
delete_.permission = 'admin'
|
||||
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.params = {
|
||||
id: {type: 'string'},
|
||||
userIds: {}
|
||||
userIds: {},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -58,7 +58,7 @@ addUser.description = 'adds a user to a group'
|
||||
addUser.permission = 'admin'
|
||||
addUser.params = {
|
||||
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.params = {
|
||||
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.params = {
|
||||
id: { type: 'string' },
|
||||
name: { type: 'string', optional: true }
|
||||
name: { type: 'string', optional: true },
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export async function get (id) {
|
||||
get.permission = 'admin'
|
||||
get.description = 'Gets an existing job'
|
||||
get.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function create ({job}) {
|
||||
@ -44,14 +44,14 @@ create.params = {
|
||||
items: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
},
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
optional: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function set ({job}) {
|
||||
@ -77,14 +77,14 @@ set.params = {
|
||||
items: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
},
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
optional: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function delete_ ({id}) {
|
||||
@ -94,7 +94,7 @@ async function delete_ ({id}) {
|
||||
delete_.permission = 'admin'
|
||||
delete_.description = 'Deletes an existing job'
|
||||
delete_.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export {delete_ as delete}
|
||||
@ -106,5 +106,5 @@ export async function runSequence ({idSequence}) {
|
||||
runSequence.permission = 'admin'
|
||||
runSequence.description = 'Runs jobs sequentially, in the provided order'
|
||||
runSequence.params = {
|
||||
idSequence: {type: 'array', items: {type: 'string'}}
|
||||
idSequence: {type: 'array', items: {type: 'string'}},
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export async function get ({namespace}) {
|
||||
|
||||
get.description = 'returns logs list for one namespace'
|
||||
get.params = {
|
||||
namespace: { type: 'string' }
|
||||
namespace: { type: 'string' },
|
||||
}
|
||||
get.permission = 'admin'
|
||||
|
||||
@ -31,7 +31,7 @@ async function delete_ ({namespace, id}) {
|
||||
delete_.description = 'deletes one or several logs from a namespace'
|
||||
delete_.params = {
|
||||
id: { type: [ 'array', 'string' ] },
|
||||
namespace: { type: 'string' }
|
||||
namespace: { type: 'string' },
|
||||
}
|
||||
delete_.permission = 'admin'
|
||||
|
||||
|
@ -4,9 +4,9 @@ async function delete_ ({ message }) {
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
message: ['id', 'message', 'administrate']
|
||||
message: ['id', 'message', 'administrate'],
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ export async function create ({ pool, name, description, pif, mtu = 1500, vlan =
|
||||
description,
|
||||
pifId: pif && this.getObject(pif, 'PIF')._xapiId,
|
||||
mtu: +mtu,
|
||||
vlan: +vlan
|
||||
vlan: +vlan,
|
||||
})
|
||||
}
|
||||
|
||||
@ -20,11 +20,11 @@ create.params = {
|
||||
description: { type: 'string', optional: true },
|
||||
pif: { type: 'string', optional: true },
|
||||
mtu: { type: ['integer', 'string'], optional: true },
|
||||
vlan: { type: ['integer', 'string'], optional: true }
|
||||
vlan: { type: ['integer', 'string'], optional: true },
|
||||
}
|
||||
|
||||
create.resolve = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
create.permission = 'admin'
|
||||
|
||||
@ -39,7 +39,7 @@ export async function createBonded ({ pool, name, description, pifs, mtu = 1500,
|
||||
),
|
||||
mtu: +mtu,
|
||||
mac,
|
||||
bondMode
|
||||
bondMode,
|
||||
})
|
||||
}
|
||||
|
||||
@ -50,17 +50,17 @@ createBonded.params = {
|
||||
pifs: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
mtu: { type: ['integer', 'string'], optional: true },
|
||||
mac: { type: 'string', optional: true },
|
||||
// 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 = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
createBonded.permission = 'admin'
|
||||
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_label: nameLabel,
|
||||
defaultIsLocked,
|
||||
id
|
||||
id,
|
||||
}) {
|
||||
await this.getXapi(network).setNetworkProperties(network._xapiId, {
|
||||
nameDescription,
|
||||
nameLabel,
|
||||
defaultIsLocked
|
||||
defaultIsLocked,
|
||||
})
|
||||
}
|
||||
|
||||
set.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
name_label: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
name_description: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
defaultIsLocked: {
|
||||
type: 'boolean',
|
||||
optional: true
|
||||
}
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
set.resolve = {
|
||||
network: ['id', 'network', 'administrate']
|
||||
network: ['id', 'network', 'administrate'],
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
@ -112,9 +112,9 @@ export async function delete_ ({ network }) {
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
network: ['id', 'network', 'administrate']
|
||||
network: ['id', 'network', 'administrate'],
|
||||
}
|
||||
|
@ -10,11 +10,11 @@ async function delete_ ({PBD}) {
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
PBD: ['id', 'PBD', 'administrate'],
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -25,11 +25,11 @@ export async function disconnect ({ pbd }) {
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
pbd: ['id', 'PBD', 'administrate']
|
||||
pbd: ['id', 'PBD', 'administrate'],
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -41,9 +41,9 @@ export async function connect ({PBD}) {
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
PBD: ['id', 'PBD', 'administrate']
|
||||
PBD: ['id', 'PBD', 'administrate'],
|
||||
}
|
||||
|
@ -20,11 +20,11 @@ async function delete_ ({pif}) {
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
pif: ['id', 'PIF', 'administrate']
|
||||
pif: ['id', 'PIF', 'administrate'],
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -36,11 +36,11 @@ export async function disconnect ({pif}) {
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
pif: ['id', 'PIF', 'administrate']
|
||||
pif: ['id', 'PIF', 'administrate'],
|
||||
}
|
||||
// ===================================================================
|
||||
// Connect
|
||||
@ -51,11 +51,11 @@ export async function connect ({pif}) {
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
pif: ['id', 'PIF', 'administrate']
|
||||
pif: ['id', 'PIF', 'administrate'],
|
||||
}
|
||||
// ===================================================================
|
||||
// Reconfigure IP
|
||||
@ -70,11 +70,11 @@ reconfigureIp.params = {
|
||||
ip: { type: 'string', optional: true },
|
||||
netmask: { type: 'string', optional: true },
|
||||
gateway: { type: 'string', optional: true },
|
||||
dns: { type: 'string', optional: true }
|
||||
dns: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
reconfigureIp.resolve = {
|
||||
pif: ['id', 'PIF', 'administrate']
|
||||
pif: ['id', 'PIF', 'administrate'],
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -85,9 +85,9 @@ export async function editPif ({ pif, vlan }) {
|
||||
|
||||
editPif.params = {
|
||||
id: { type: 'string' },
|
||||
vlan: { type: ['integer', 'string'] }
|
||||
vlan: { type: ['integer', 'string'] },
|
||||
}
|
||||
|
||||
editPif.resolve = {
|
||||
pif: ['id', 'PIF', 'administrate']
|
||||
pif: ['id', 'PIF', 'administrate'],
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ configure.description = 'sets the configuration of a plugin'
|
||||
|
||||
configure.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
configuration: {}
|
||||
configuration: {},
|
||||
}
|
||||
|
||||
configure.permission = 'admin'
|
||||
@ -33,8 +33,8 @@ disableAutoload.description = ''
|
||||
|
||||
disableAutoload.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
disableAutoload.permission = 'admin'
|
||||
@ -49,8 +49,8 @@ enableAutoload.description = 'enables a plugin, allowing it to be loaded'
|
||||
|
||||
enableAutoload.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
enableAutoload.permission = 'admin'
|
||||
@ -65,8 +65,8 @@ load.description = 'loads a plugin'
|
||||
|
||||
load.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
load.permission = 'admin'
|
||||
@ -81,8 +81,8 @@ unload.description = 'unloads a plugin'
|
||||
|
||||
unload.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
unload.permission = 'admin'
|
||||
@ -97,8 +97,8 @@ purgeConfiguration.description = 'removes a plugin configuration'
|
||||
|
||||
purgeConfiguration.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
purgeConfiguration.permission = 'admin'
|
||||
@ -113,11 +113,11 @@ test.description = 'Test a plugin with its current configuration'
|
||||
|
||||
test.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
data: {
|
||||
optional: true
|
||||
}
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
test.permission = 'admin'
|
||||
|
@ -9,30 +9,30 @@ export async function set ({
|
||||
|
||||
// TODO: use camel case.
|
||||
name_description: nameDescription,
|
||||
name_label: nameLabel
|
||||
name_label: nameLabel,
|
||||
}) {
|
||||
await this.getXapi(pool).setPoolProperties({
|
||||
nameDescription,
|
||||
nameLabel
|
||||
nameLabel,
|
||||
})
|
||||
}
|
||||
|
||||
set.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
name_label: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
name_description: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
}
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
set.resolve = {
|
||||
pool: ['id', 'pool', 'administrate']
|
||||
pool: ['id', 'pool', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -47,12 +47,12 @@ setDefaultSr.permission = '' // signed in
|
||||
|
||||
setDefaultSr.params = {
|
||||
sr: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
setDefaultSr.resolve = {
|
||||
sr: ['sr', 'SR']
|
||||
sr: ['sr', 'SR'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -65,12 +65,12 @@ export async function setPoolMaster ({ host }) {
|
||||
|
||||
setPoolMaster.params = {
|
||||
host: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
setPoolMaster.resolve = {
|
||||
host: ['host', 'host']
|
||||
host: ['host', 'host'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -81,15 +81,15 @@ export async function installPatch ({pool, patch: patchUuid}) {
|
||||
|
||||
installPatch.params = {
|
||||
pool: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
patch: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
installPatch.resolve = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@ -99,12 +99,12 @@ export async function installAllPatches ({ pool }) {
|
||||
|
||||
installAllPatches.params = {
|
||||
pool: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
installAllPatches.resolve = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
|
||||
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}) {
|
||||
return {
|
||||
$sendTo: await this.registerHttpRequest(handlePatchUpload, {pool})
|
||||
$sendTo: await this.registerHttpRequest(handlePatchUpload, {pool}),
|
||||
}
|
||||
}
|
||||
|
||||
uploadPatch.params = {
|
||||
pool: { type: 'string' }
|
||||
pool: { type: 'string' },
|
||||
}
|
||||
|
||||
uploadPatch.resolve = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
|
||||
// Compatibility
|
||||
@ -167,12 +167,12 @@ export async function mergeInto ({ source, target, force }) {
|
||||
mergeInto.params = {
|
||||
force: { type: 'boolean', optional: true },
|
||||
source: { type: 'string' },
|
||||
target: { type: 'string' }
|
||||
target: { type: 'string' },
|
||||
}
|
||||
|
||||
mergeInto.resolve = {
|
||||
source: ['source', 'pool', 'administrate'],
|
||||
target: ['target', 'pool', 'administrate']
|
||||
target: ['target', 'pool', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -186,12 +186,12 @@ export async function getLicenseState ({pool}) {
|
||||
|
||||
getLicenseState.params = {
|
||||
pool: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
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 }) {
|
||||
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.params = {
|
||||
pool: { type: 'string' }
|
||||
pool: { type: 'string' },
|
||||
}
|
||||
|
||||
installSupplementalPack.resolve = {
|
||||
pool: ['pool', 'pool', 'admin']
|
||||
pool: ['pool', 'pool', 'admin'],
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export async function get ({id}) {
|
||||
get.permission = 'admin'
|
||||
get.description = 'Gets an existing fs remote point'
|
||||
get.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function test ({id}) {
|
||||
@ -22,7 +22,7 @@ export async function test ({id}) {
|
||||
test.permission = 'admin'
|
||||
test.description = 'Performs a read/write matching test on a remote point'
|
||||
test.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function list ({id}) {
|
||||
@ -32,7 +32,7 @@ export async function list ({id}) {
|
||||
list.permission = 'admin'
|
||||
list.description = 'Lists the files found in a remote point'
|
||||
list.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function create ({name, url}) {
|
||||
@ -43,7 +43,7 @@ create.permission = 'admin'
|
||||
create.description = 'Creates a new fs remote point'
|
||||
create.params = {
|
||||
name: {type: 'string'},
|
||||
url: {type: 'string'}
|
||||
url: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function set ({id, name, url, enabled}) {
|
||||
@ -56,7 +56,7 @@ set.params = {
|
||||
id: {type: 'string'},
|
||||
name: {type: 'string', optional: true},
|
||||
url: {type: 'string', optional: true},
|
||||
enabled: {type: 'boolean', optional: true}
|
||||
enabled: {type: 'boolean', optional: true},
|
||||
}
|
||||
|
||||
async function delete_ ({id}) {
|
||||
@ -66,7 +66,7 @@ async function delete_ ({id}) {
|
||||
delete_.permission = 'admin'
|
||||
delete_.description = 'Deletes an existing fs remote point'
|
||||
delete_.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export {delete_ as delete}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {
|
||||
unauthorized
|
||||
unauthorized,
|
||||
} from 'xo-common/api-errors'
|
||||
|
||||
// ===================================================================
|
||||
@ -12,26 +12,26 @@ create.permission = 'admin'
|
||||
|
||||
create.params = {
|
||||
name: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
subjects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
objects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
limits: {
|
||||
type: 'object',
|
||||
optional: true
|
||||
}
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -45,8 +45,8 @@ delete_.permission = 'admin'
|
||||
|
||||
delete_.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -57,7 +57,7 @@ export function set ({ id, name, subjects, objects, ipPools, limits }) {
|
||||
name,
|
||||
objects,
|
||||
ipPools,
|
||||
subjects
|
||||
subjects,
|
||||
})
|
||||
}
|
||||
|
||||
@ -65,37 +65,37 @@ set.permission = 'admin'
|
||||
|
||||
set.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
subjects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
objects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
ipPools: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
limits: {
|
||||
type: 'object',
|
||||
optional: true
|
||||
}
|
||||
optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -108,8 +108,8 @@ get.permission = 'admin'
|
||||
|
||||
get.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -135,11 +135,11 @@ addObject.permission = 'admin'
|
||||
|
||||
addObject.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
object: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -152,11 +152,11 @@ removeObject.permission = 'admin'
|
||||
|
||||
removeObject.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
object: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -169,11 +169,11 @@ addSubject.permission = 'admin'
|
||||
|
||||
addSubject.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
subject: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -186,11 +186,11 @@ removeSubject.permission = 'admin'
|
||||
|
||||
removeSubject.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
subject: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -203,14 +203,14 @@ addLimit.permission = 'admin'
|
||||
|
||||
addLimit.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
limitId: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
quantity: {
|
||||
type: 'integer'
|
||||
}
|
||||
type: 'integer',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -223,11 +223,11 @@ removeLimit.permission = 'admin'
|
||||
|
||||
removeLimit.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
limitId: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -14,7 +14,7 @@ export async function get (id) {
|
||||
get.permission = 'admin'
|
||||
get.description = 'Gets an existing schedule'
|
||||
get.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function create ({ jobId, cron, enabled, name, timezone }) {
|
||||
@ -27,7 +27,7 @@ create.params = {
|
||||
jobId: {type: 'string'},
|
||||
cron: {type: 'string'},
|
||||
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 }) {
|
||||
@ -41,7 +41,7 @@ set.params = {
|
||||
jobId: {type: 'string', optional: true},
|
||||
cron: {type: 'string', optional: true},
|
||||
enabled: {type: 'boolean', optional: true},
|
||||
name: {type: 'string', optional: true}
|
||||
name: {type: 'string', optional: true},
|
||||
}
|
||||
|
||||
async function delete_ ({id}) {
|
||||
@ -51,7 +51,7 @@ async function delete_ ({id}) {
|
||||
delete_.permission = 'admin'
|
||||
delete_.description = 'Deletes an existing schedule'
|
||||
delete_.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export {delete_ as delete}
|
||||
|
@ -7,7 +7,7 @@ export async function enable ({id}) {
|
||||
enable.permission = 'admin'
|
||||
enable.description = 'Enables a schedule to run it\'s job as scheduled'
|
||||
enable.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export async function disable ({id}) {
|
||||
@ -19,7 +19,7 @@ export async function disable ({id}) {
|
||||
disable.permission = 'admin'
|
||||
disable.description = 'Disables a schedule'
|
||||
disable.params = {
|
||||
id: {type: 'string'}
|
||||
id: {type: 'string'},
|
||||
}
|
||||
|
||||
export function getScheduleTable () {
|
||||
|
@ -17,25 +17,25 @@ add.permission = 'admin'
|
||||
add.params = {
|
||||
label: {
|
||||
optional: true,
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
host: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
username: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
password: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
autoConnect: {
|
||||
optional: true,
|
||||
type: 'boolean'
|
||||
type: 'boolean',
|
||||
},
|
||||
allowUnauthorized: {
|
||||
optional: true,
|
||||
type: 'boolean'
|
||||
}
|
||||
type: 'boolean',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -50,8 +50,8 @@ remove.permission = 'admin'
|
||||
|
||||
remove.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -78,28 +78,28 @@ set.permission = 'admin'
|
||||
|
||||
set.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
label: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
host: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
allowUnauthorized: {
|
||||
optional: true,
|
||||
type: 'boolean'
|
||||
}
|
||||
type: 'boolean',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -115,8 +115,8 @@ connect.permission = 'admin'
|
||||
|
||||
connect.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -132,6 +132,6 @@ disconnect.permission = 'admin'
|
||||
|
||||
disconnect.params = {
|
||||
id: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export const signInWithPassword = deprecate(signIn, 'use session.signIn() instea
|
||||
|
||||
signInWithPassword.params = {
|
||||
email: { type: 'string' },
|
||||
password: { type: 'string' }
|
||||
password: { type: 'string' },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -31,7 +31,7 @@ signInWithPassword.params = {
|
||||
export const signInWithToken = deprecate(signIn, 'use session.signIn() instead')
|
||||
|
||||
signInWithToken.params = {
|
||||
token: { type: 'string' }
|
||||
token: { type: 'string' },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
138
src/api/sr.js
138
src/api/sr.js
@ -5,7 +5,7 @@ import {
|
||||
asyncMap,
|
||||
ensureArray,
|
||||
forEach,
|
||||
parseXml
|
||||
parseXml,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -15,11 +15,11 @@ export async function set ({
|
||||
|
||||
// TODO: use camel case.
|
||||
name_description: nameDescription,
|
||||
name_label: nameLabel
|
||||
name_label: nameLabel,
|
||||
}) {
|
||||
await this.getXapi(sr).setSrProperties(sr._xapiId, {
|
||||
nameDescription,
|
||||
nameLabel
|
||||
nameLabel,
|
||||
})
|
||||
}
|
||||
|
||||
@ -28,11 +28,11 @@ set.params = {
|
||||
|
||||
name_label: { type: 'string', optional: true },
|
||||
|
||||
name_description: { type: 'string', optional: true }
|
||||
name_description: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
set.resolve = {
|
||||
sr: ['id', 'SR', 'operate']
|
||||
sr: ['id', 'SR', 'operate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -42,11 +42,11 @@ export async function scan ({ SR }) {
|
||||
}
|
||||
|
||||
scan.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
scan.resolve = {
|
||||
SR: ['id', 'SR', 'operate']
|
||||
SR: ['id', 'SR', 'operate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -71,11 +71,11 @@ export async function destroy ({sr}) {
|
||||
}
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
destroy.resolve = {
|
||||
sr: ['id', 'SR', 'administrate']
|
||||
sr: ['id', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -85,11 +85,11 @@ export async function forget ({ SR }) {
|
||||
}
|
||||
|
||||
forget.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
forget.resolve = {
|
||||
SR: ['id', 'SR', 'administrate']
|
||||
SR: ['id', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -99,11 +99,11 @@ export async function connectAllPbds ({ SR }) {
|
||||
}
|
||||
|
||||
connectAllPbds.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
connectAllPbds.resolve = {
|
||||
SR: ['id', 'SR', 'administrate']
|
||||
SR: ['id', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -113,11 +113,11 @@ export async function disconnectAllPbds ({ SR }) {
|
||||
}
|
||||
|
||||
disconnectAllPbds.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
disconnectAllPbds.resolve = {
|
||||
SR: ['id', 'SR', 'administrate']
|
||||
SR: ['id', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -129,7 +129,7 @@ export async function createIso ({
|
||||
path,
|
||||
type,
|
||||
user,
|
||||
password
|
||||
password,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
@ -169,11 +169,11 @@ createIso.params = {
|
||||
path: { type: 'string' },
|
||||
type: { type: 'string' },
|
||||
user: { type: 'string', optional: true },
|
||||
password: { type: 'string', optional: true }
|
||||
password: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
createIso.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -187,13 +187,13 @@ export async function createNfs ({
|
||||
nameDescription,
|
||||
server,
|
||||
serverPath,
|
||||
nfsVersion
|
||||
nfsVersion,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
server,
|
||||
serverpath: serverPath
|
||||
serverpath: serverPath,
|
||||
}
|
||||
|
||||
// if NFS version given
|
||||
@ -224,11 +224,11 @@ createNfs.params = {
|
||||
nameDescription: { type: 'string' },
|
||||
server: { type: 'string' },
|
||||
serverPath: { type: 'string' },
|
||||
nfsVersion: { type: 'string', optional: true }
|
||||
nfsVersion: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
createNfs.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -240,12 +240,12 @@ export async function createHba ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
scsiId
|
||||
scsiId,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
scsiId
|
||||
scsiId,
|
||||
}
|
||||
|
||||
const srRef = await xapi.call(
|
||||
@ -269,11 +269,11 @@ createHba.params = {
|
||||
host: { type: 'string' },
|
||||
nameLabel: { type: 'string' },
|
||||
nameDescription: { type: 'string' },
|
||||
scsiId: { type: 'string' }
|
||||
scsiId: { type: 'string' },
|
||||
}
|
||||
|
||||
createHba.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -285,12 +285,12 @@ export async function createLvm ({
|
||||
host,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
device
|
||||
device,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
device
|
||||
device,
|
||||
}
|
||||
|
||||
const srRef = await xapi.call(
|
||||
@ -314,11 +314,11 @@ createLvm.params = {
|
||||
host: { type: 'string' },
|
||||
nameLabel: { type: 'string' },
|
||||
nameDescription: { type: 'string' },
|
||||
device: { type: 'string' }
|
||||
device: { type: 'string' },
|
||||
}
|
||||
|
||||
createLvm.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -327,12 +327,12 @@ createLvm.resolve = {
|
||||
|
||||
export async function probeNfs ({
|
||||
host,
|
||||
server
|
||||
server,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
server
|
||||
server,
|
||||
}
|
||||
|
||||
let xml
|
||||
@ -359,7 +359,7 @@ export async function probeNfs ({
|
||||
forEach(ensureArray(xml['nfs-exports'].Export), nfsExport => {
|
||||
nfsExports.push({
|
||||
path: nfsExport.Path.trim(),
|
||||
acl: nfsExport.Accesslist.trim()
|
||||
acl: nfsExport.Accesslist.trim(),
|
||||
})
|
||||
})
|
||||
|
||||
@ -368,18 +368,18 @@ export async function probeNfs ({
|
||||
|
||||
probeNfs.params = {
|
||||
host: { type: 'string' },
|
||||
server: { type: 'string' }
|
||||
server: { type: 'string' },
|
||||
}
|
||||
|
||||
probeNfs.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// This function helps to detect all HBA devices on the host
|
||||
|
||||
export async function probeHba ({
|
||||
host
|
||||
host,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
@ -409,7 +409,7 @@ export async function probeHba ({
|
||||
path: hbaDevice.path.trim(),
|
||||
scsciId: hbaDevice.SCSIid.trim(),
|
||||
size: hbaDevice.size.trim(),
|
||||
vendor: hbaDevice.vendor.trim()
|
||||
vendor: hbaDevice.vendor.trim(),
|
||||
})
|
||||
})
|
||||
|
||||
@ -417,11 +417,11 @@ export async function probeHba ({
|
||||
}
|
||||
|
||||
probeHba.params = {
|
||||
host: { type: 'string' }
|
||||
host: { type: 'string' },
|
||||
}
|
||||
|
||||
probeHba.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -439,14 +439,14 @@ export async function createIscsi ({
|
||||
targetIqn,
|
||||
scsiId,
|
||||
chapUser,
|
||||
chapPassword
|
||||
chapPassword,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
target,
|
||||
targetIQN: targetIqn,
|
||||
SCSIid: scsiId
|
||||
SCSIid: scsiId,
|
||||
}
|
||||
|
||||
// if we give user and password
|
||||
@ -486,11 +486,11 @@ createIscsi.params = {
|
||||
targetIqn: { type: 'string' },
|
||||
scsiId: { type: 'string' },
|
||||
chapUser: { type: 'string', optional: true },
|
||||
chapPassword: { type: 'string', optional: true }
|
||||
chapPassword: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
createIscsi.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -502,12 +502,12 @@ export async function probeIscsiIqns ({
|
||||
target: targetIp,
|
||||
port,
|
||||
chapUser,
|
||||
chapPassword
|
||||
chapPassword,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
target: targetIp
|
||||
target: targetIp,
|
||||
}
|
||||
|
||||
// if we give user and password
|
||||
@ -550,7 +550,7 @@ export async function probeIscsiIqns ({
|
||||
if (target.IPAddress.trim() === targetIp) {
|
||||
targets.push({
|
||||
iqn: target.TargetIQN.trim(),
|
||||
ip: target.IPAddress.trim()
|
||||
ip: target.IPAddress.trim(),
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -563,10 +563,10 @@ probeIscsiIqns.params = {
|
||||
target: { type: 'string' },
|
||||
port: { type: 'integer', optional: true },
|
||||
chapUser: { type: 'string', optional: true },
|
||||
chapPassword: { type: 'string', optional: true }
|
||||
chapPassword: { type: 'string', optional: true },
|
||||
}
|
||||
probeIscsiIqns.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -579,13 +579,13 @@ export async function probeIscsiLuns ({
|
||||
port,
|
||||
targetIqn,
|
||||
chapUser,
|
||||
chapPassword
|
||||
chapPassword,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
target: targetIp,
|
||||
targetIQN: targetIqn
|
||||
targetIQN: targetIqn,
|
||||
}
|
||||
|
||||
// if we give user and password
|
||||
@ -626,7 +626,7 @@ export async function probeIscsiLuns ({
|
||||
vendor: lun.vendor.trim(),
|
||||
serial: lun.serial.trim(),
|
||||
size: lun.size.trim(),
|
||||
scsiId: lun.SCSIid.trim()
|
||||
scsiId: lun.SCSIid.trim(),
|
||||
})
|
||||
})
|
||||
|
||||
@ -639,11 +639,11 @@ probeIscsiLuns.params = {
|
||||
port: { type: 'integer', optional: true },
|
||||
targetIqn: { type: 'string' },
|
||||
chapUser: { type: 'string', optional: true },
|
||||
chapPassword: { type: 'string', optional: true }
|
||||
chapPassword: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
probeIscsiLuns.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -657,14 +657,14 @@ export async function probeIscsiExists ({
|
||||
targetIqn,
|
||||
scsiId,
|
||||
chapUser,
|
||||
chapPassword
|
||||
chapPassword,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
target: targetIp,
|
||||
targetIQN: targetIqn,
|
||||
SCSIid: scsiId
|
||||
SCSIid: scsiId,
|
||||
}
|
||||
|
||||
// if we give user and password
|
||||
@ -696,11 +696,11 @@ probeIscsiExists.params = {
|
||||
targetIqn: { type: 'string' },
|
||||
scsiId: { type: 'string' },
|
||||
chapUser: { type: 'string', optional: true },
|
||||
chapPassword: { type: 'string', optional: true }
|
||||
chapPassword: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
probeIscsiExists.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -710,13 +710,13 @@ probeIscsiExists.resolve = {
|
||||
export async function probeNfsExists ({
|
||||
host,
|
||||
server,
|
||||
serverPath
|
||||
serverPath,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
const deviceConfig = {
|
||||
server,
|
||||
serverpath: serverPath
|
||||
serverpath: serverPath,
|
||||
}
|
||||
|
||||
const xml = parseXml(await xapi.call('SR.probe', host._xapiRef, deviceConfig, 'nfs', {}))
|
||||
@ -734,11 +734,11 @@ export async function probeNfsExists ({
|
||||
probeNfsExists.params = {
|
||||
host: { type: 'string' },
|
||||
server: { type: 'string' },
|
||||
serverPath: { type: 'string' }
|
||||
serverPath: { type: 'string' },
|
||||
}
|
||||
|
||||
probeNfsExists.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -749,7 +749,7 @@ export async function reattach ({
|
||||
uuid,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
type
|
||||
type,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
@ -777,11 +777,11 @@ reattach.params = {
|
||||
uuid: { type: 'string' },
|
||||
nameLabel: { type: 'string' },
|
||||
nameDescription: { type: 'string' },
|
||||
type: { type: 'string' }
|
||||
type: { type: 'string' },
|
||||
}
|
||||
|
||||
reattach.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -792,7 +792,7 @@ export async function reattachIso ({
|
||||
uuid,
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
type
|
||||
type,
|
||||
}) {
|
||||
const xapi = this.getXapi(host)
|
||||
|
||||
@ -820,11 +820,11 @@ reattachIso.params = {
|
||||
uuid: { type: 'string' },
|
||||
nameLabel: { type: 'string' },
|
||||
nameDescription: { type: 'string' },
|
||||
type: { type: 'string' }
|
||||
type: { type: 'string' },
|
||||
}
|
||||
|
||||
reattachIso.resolve = {
|
||||
host: ['host', 'host', 'administrate']
|
||||
host: ['host', 'host', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -834,9 +834,9 @@ export function getUnhealthyVdiChainsLength ({ sr }) {
|
||||
}
|
||||
|
||||
getUnhealthyVdiChainsLength.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
getUnhealthyVdiChainsLength.resolve = {
|
||||
sr: ['id', 'SR', 'operate']
|
||||
sr: ['id', 'SR', 'operate'],
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export function getMethodsInfo () {
|
||||
methods[name] = {
|
||||
description: method.description,
|
||||
params: method.params || {},
|
||||
permission: method.permission
|
||||
permission: method.permission,
|
||||
}
|
||||
})
|
||||
|
||||
@ -60,8 +60,8 @@ export function methodSignature ({method: name}) {
|
||||
name,
|
||||
description: method.description,
|
||||
params: method.params || {},
|
||||
permission: method.permission
|
||||
}
|
||||
permission: method.permission,
|
||||
},
|
||||
]
|
||||
}
|
||||
methodSignature.description = 'returns the signature of an API method'
|
||||
|
@ -5,12 +5,12 @@ export async function add ({tag, object}) {
|
||||
add.description = 'add a new tag to an object'
|
||||
|
||||
add.resolve = {
|
||||
object: ['id', null, 'administrate']
|
||||
object: ['id', null, 'administrate'],
|
||||
}
|
||||
|
||||
add.params = {
|
||||
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.resolve = {
|
||||
object: ['id', null, 'administrate']
|
||||
object: ['id', null, 'administrate'],
|
||||
}
|
||||
|
||||
remove.params = {
|
||||
tag: { type: 'string' },
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
@ -3,11 +3,11 @@ export async function cancel ({task}) {
|
||||
}
|
||||
|
||||
cancel.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
cancel.resolve = {
|
||||
task: ['id', 'task', 'administrate']
|
||||
task: ['id', 'task', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -17,9 +17,9 @@ export async function destroy ({task}) {
|
||||
}
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
destroy.resolve = {
|
||||
task: ['id', 'task', 'administrate']
|
||||
task: ['id', 'task', 'administrate'],
|
||||
}
|
||||
|
@ -6,15 +6,15 @@ getPermissionsForUser.permission = 'admin'
|
||||
|
||||
getPermissionsForUser.params = {
|
||||
userId: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export function hasPermission ({ userId, objectId, permission }) {
|
||||
return this.hasPermissions(userId, [
|
||||
[ objectId, permission ]
|
||||
[ objectId, permission ],
|
||||
])
|
||||
}
|
||||
|
||||
@ -22,14 +22,14 @@ hasPermission.permission = 'admin'
|
||||
|
||||
hasPermission.params = {
|
||||
userId: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
objectId: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
permission: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -44,8 +44,8 @@ export function wait ({duration, returnValue}) {
|
||||
|
||||
wait.params = {
|
||||
duration: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -77,10 +77,10 @@ copyVm.permission = 'admin'
|
||||
|
||||
copyVm.params = {
|
||||
vm: { type: 'string' },
|
||||
sr: { type: 'string' }
|
||||
sr: { type: 'string' },
|
||||
}
|
||||
|
||||
copyVm.resolve = {
|
||||
vm: [ 'vm', 'VM' ],
|
||||
sr: [ 'sr', 'SR' ]
|
||||
sr: [ 'sr', 'SR' ],
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
export async function create ({ expiresIn }) {
|
||||
return (await this.createAuthenticationToken({
|
||||
expiresIn,
|
||||
userId: this.session.get('user_id')
|
||||
userId: this.session.get('user_id'),
|
||||
})).id
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ create.description = 'create a new authentication token'
|
||||
create.params = {
|
||||
expiresIn: {
|
||||
optional: true,
|
||||
type: [ 'number', 'string' ]
|
||||
}
|
||||
type: [ 'number', 'string' ],
|
||||
},
|
||||
}
|
||||
|
||||
create.permission = '' // sign in
|
||||
@ -32,5 +32,5 @@ delete_.description = 'delete an existing authentication token'
|
||||
delete_.permission = 'admin'
|
||||
|
||||
delete_.params = {
|
||||
token: { type: 'string' }
|
||||
token: { type: 'string' },
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ create.permission = 'admin'
|
||||
create.params = {
|
||||
email: { 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_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -79,7 +79,7 @@ set.params = {
|
||||
email: { type: 'string', optional: true },
|
||||
password: { 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 = {
|
||||
oldPassword: {type: 'string'},
|
||||
newPassword: {type: 'string'}
|
||||
newPassword: {type: 'string'},
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ async function delete_ ({vif}) {
|
||||
export {delete_ as delete}
|
||||
|
||||
delete_.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
delete_.resolve = {
|
||||
vif: ['id', 'VIF', 'administrate']
|
||||
vif: ['id', 'VIF', 'administrate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -33,11 +33,11 @@ export async function disconnect ({vif}) {
|
||||
}
|
||||
|
||||
disconnect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
disconnect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
vif: ['id', 'VIF', 'operate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -48,11 +48,11 @@ export async function connect ({vif}) {
|
||||
}
|
||||
|
||||
connect.params = {
|
||||
id: { type: 'string' }
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
connect.resolve = {
|
||||
vif: ['id', 'VIF', 'operate']
|
||||
vif: ['id', 'VIF', 'operate'],
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -63,7 +63,7 @@ export async function set ({
|
||||
mac,
|
||||
allowedIpv4Addresses,
|
||||
allowedIpv6Addresses,
|
||||
attached
|
||||
attached,
|
||||
}) {
|
||||
const oldIpAddresses = vif.allowedIpv4Addresses.concat(vif.allowedIpv6Addresses)
|
||||
const newIpAddresses = []
|
||||
@ -88,7 +88,7 @@ export async function set ({
|
||||
const newVif = await xapi.createVif(vm.$id, network.$id, {
|
||||
mac,
|
||||
currently_attached: attached,
|
||||
ipv4_allowed: newIpAddresses
|
||||
ipv4_allowed: newIpAddresses,
|
||||
})
|
||||
|
||||
await this.allocIpAddresses(newVif.$id, newIpAddresses)
|
||||
@ -108,7 +108,7 @@ export async function set ({
|
||||
|
||||
return this.getXapi(vif).editVif(vif._xapiId, {
|
||||
ipv4Allowed: allowedIpv4Addresses,
|
||||
ipv6Allowed: allowedIpv6Addresses
|
||||
ipv6Allowed: allowedIpv6Addresses,
|
||||
})
|
||||
}
|
||||
|
||||
@ -119,21 +119,21 @@ set.params = {
|
||||
allowedIpv4Addresses: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
allowedIpv6Addresses: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
optional: true
|
||||
optional: true,
|
||||
},
|
||||
attached: { type: 'boolean', optional: true }
|
||||
attached: { type: 'boolean', optional: true },
|
||||
}
|
||||
|
||||
set.resolve = {
|
||||
vif: ['id', 'VIF', 'operate'],
|
||||
network: ['network', 'network', 'operate']
|
||||
network: ['network', 'network', 'operate'],
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ export async function exportConfig () {
|
||||
return {
|
||||
$getFrom: await this.registerHttpRequest((req, res) => {
|
||||
res.writeHead(200, 'OK', {
|
||||
'content-disposition': 'attachment'
|
||||
'content-disposition': 'attachment',
|
||||
})
|
||||
|
||||
return this.exportConfig()
|
||||
},
|
||||
undefined,
|
||||
{ suffix: '/config.json' })
|
||||
{ suffix: '/config.json' }),
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ getAllObjects.description = 'Returns all XO objects'
|
||||
|
||||
getAllObjects.params = {
|
||||
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)))
|
||||
|
||||
res.end('config successfully imported')
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
132
src/api/xosan.js
132
src/api/xosan.js
@ -12,7 +12,7 @@ import {
|
||||
remove,
|
||||
filter,
|
||||
find,
|
||||
range
|
||||
range,
|
||||
} from 'lodash'
|
||||
|
||||
import { asInteger } from '../xapi/utils'
|
||||
@ -67,7 +67,7 @@ function _getGlusterEndpoint (sr) {
|
||||
xapi,
|
||||
data: data,
|
||||
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 {
|
||||
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 () => {
|
||||
const cmdShouldRetry = result => !result['commandStatus'] && result.parsed && result.parsed['cliOutput']['opErrno'] === '30802'
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ export async function getVolumeInfo ({sr, infoType}) {
|
||||
statusDetail: sshInfoType('status xosan detail', parseStatus),
|
||||
statusMem: sshInfoType('status xosan mem', parseStatus),
|
||||
info: sshInfoType('info xosan', parseInfo),
|
||||
hosts: this::checkHosts
|
||||
hosts: this::checkHosts,
|
||||
}
|
||||
if (glusterEndpoint == null) {
|
||||
return null
|
||||
@ -157,14 +157,14 @@ getVolumeInfo.permission = 'admin'
|
||||
|
||||
getVolumeInfo.params = {
|
||||
sr: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
infoType: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
getVolumeInfo.resolve = {
|
||||
sr: ['sr', 'SR', 'administrate']
|
||||
sr: ['sr', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
function reconfigurePifIP (xapi, pif, newIP) {
|
||||
@ -190,7 +190,7 @@ export async function fixHostNotInNetwork ({xosanSr, host}) {
|
||||
await callPlugin(xapi, host, 'receive_ssh_keys', {
|
||||
private_key: sshKey.private,
|
||||
public_key: sshKey.public,
|
||||
force: true
|
||||
force: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -200,14 +200,14 @@ fixHostNotInNetwork.permission = 'admin'
|
||||
|
||||
fixHostNotInNetwork.params = {
|
||||
xosanSr: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
host: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
fixHostNotInNetwork.resolve = {
|
||||
sr: ['sr', 'SR', 'administrate']
|
||||
sr: ['sr', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
function floor2048 (value) {
|
||||
@ -315,7 +315,7 @@ const createNetworkAndInsertHosts = defer.onFailure(async function ($onFailure,
|
||||
description: 'XOSAN network',
|
||||
pifId: pif._xapiId,
|
||||
mtu: pif.mtu,
|
||||
vlan: +vlan
|
||||
vlan: +vlan,
|
||||
})
|
||||
$onFailure(() => xapi.deleteNetwork(xosanNetwork))
|
||||
const addresses = xosanNetwork.$PIFs.map(pif => ({pif, address: networkPrefix + (hostIpLastNumber++)}))
|
||||
@ -338,7 +338,7 @@ async function getOrCreateSshKey (xapi) {
|
||||
const readKeys = async () => {
|
||||
sshKey = {
|
||||
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)
|
||||
}
|
||||
@ -380,18 +380,18 @@ async function configureGluster (redundancy, ipAndHosts, glusterEndpoint, gluste
|
||||
const configByType = {
|
||||
replica_arbiter: {
|
||||
creation: 'replica 3 arbiter 1',
|
||||
extra: []
|
||||
extra: [],
|
||||
},
|
||||
replica: {
|
||||
creation: 'replica ' + redundancy + ' ',
|
||||
extra: ['volume set xosan cluster.data-self-heal on']
|
||||
extra: ['volume set xosan cluster.data-self-heal on'],
|
||||
},
|
||||
disperse: {
|
||||
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))
|
||||
const creation = configByType[glusterType].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, {
|
||||
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 = {
|
||||
operation: 'createSr',
|
||||
states: ['configuringNetwork', 'importingVm', 'copyingVms',
|
||||
'configuringVms', 'configuringGluster', 'creatingSr', 'scanningSr']
|
||||
'configuringVms', 'configuringGluster', 'creatingSr', 'scanningSr'],
|
||||
}
|
||||
if (!this.requestResource) {
|
||||
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', {
|
||||
private_key: sshKey.private,
|
||||
public_key: sshKey.public,
|
||||
force: 'true'
|
||||
force: 'true',
|
||||
})))
|
||||
|
||||
const firstSr = srsObjects[0]
|
||||
@ -465,7 +465,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
|
||||
)
|
||||
const vmsAndSrs = [{
|
||||
vm: firstVM,
|
||||
sr: firstSr
|
||||
sr: firstSr,
|
||||
}].concat(copiedVms)
|
||||
let arbiter = null
|
||||
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, {
|
||||
labelSuffix: '_arbiter',
|
||||
increaseDataDisk: false,
|
||||
memorySize
|
||||
memorySize,
|
||||
})
|
||||
arbiter.arbiter = true
|
||||
}
|
||||
@ -507,7 +507,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
|
||||
host: param.host.$id,
|
||||
vm: {id: param.vm.$id, ip: param.address},
|
||||
underlyingSr: param.underlyingSr.$id,
|
||||
arbiter: !!param['arbiter']
|
||||
arbiter: !!param['arbiter'],
|
||||
}))
|
||||
await xapi.xo.setData(xosanSrRef, 'xosan_config', {
|
||||
version: 'beta2',
|
||||
@ -516,7 +516,7 @@ export const createSR = defer.onFailure(async function ($onFailure, {
|
||||
network: xosanNetwork.$id,
|
||||
type: glusterType,
|
||||
networkPrefix,
|
||||
redundancy
|
||||
redundancy,
|
||||
})
|
||||
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 6}
|
||||
debug('scanning new SR')
|
||||
@ -532,32 +532,32 @@ createSR.params = {
|
||||
srs: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
pif: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
vlan: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
glusterType: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
redundancy: {
|
||||
type: 'number'
|
||||
type: 'number',
|
||||
},
|
||||
memorySize: {
|
||||
type: 'number', optional: true
|
||||
type: 'number', optional: true,
|
||||
},
|
||||
ipRange: {
|
||||
type: 'string', optional: true
|
||||
}
|
||||
type: 'string', optional: true,
|
||||
},
|
||||
}
|
||||
|
||||
createSR.resolve = {
|
||||
srs: ['sr', 'SR', 'administrate'],
|
||||
pif: ['pif', 'PIF', 'administrate']
|
||||
pif: ['pif', 'PIF', 'administrate'],
|
||||
}
|
||||
|
||||
async function umountDisk (localEndpoint, diskMountPoint) {
|
||||
@ -608,7 +608,7 @@ async function mountNewDisk (localEndpoint, hostname, newDeviceFiledeviceFile) {
|
||||
async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize) {
|
||||
const OPERATION_OBJECT = {
|
||||
operation: 'replaceBrick',
|
||||
states: ['creatingNewDisk', 'mountingDisk', 'swappingBrick', 'disconnectingOldDisk', 'scanningSr']
|
||||
states: ['creatingNewDisk', 'mountingDisk', 'swappingBrick', 'disconnectingOldDisk', 'scanningSr'],
|
||||
}
|
||||
const xapi = this.getXapi(xosansr)
|
||||
const poolId = xapi.pool.$id
|
||||
@ -627,7 +627,7 @@ async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize
|
||||
const localEndpoint = {
|
||||
xapi,
|
||||
hosts: map(nodes, node => xapi.getObject(node.host)),
|
||||
addresses: [previousIp]
|
||||
addresses: [previousIp],
|
||||
}
|
||||
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()
|
||||
@ -653,7 +653,7 @@ async function replaceBrickOnSameVM (xosansr, previousBrick, newLvmSr, brickSize
|
||||
export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize, onSameVM = true}) {
|
||||
const OPERATION_OBJECT = {
|
||||
operation: 'replaceBrick',
|
||||
states: ['insertingNewVm', 'swapingBrick', 'deletingVm', 'scaningSr']
|
||||
states: ['insertingNewVm', 'swapingBrick', 'deletingVm', 'scaningSr'],
|
||||
}
|
||||
if (onSameVM) {
|
||||
return this::replaceBrickOnSameVM(xosansr, previousBrick, newLvmSr, brickSize)
|
||||
@ -672,12 +672,12 @@ export async function replaceBrick ({xosansr, previousBrick, newLvmSr, brickSize
|
||||
const glusterEndpoint = {
|
||||
xapi,
|
||||
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 arbiter = nodes[nodeIndex].arbiter
|
||||
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})
|
||||
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 1}
|
||||
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,
|
||||
arbiter: arbiter,
|
||||
vm: {ip: addressAndHost.address, id: newVM.$id},
|
||||
underlyingSr: newLvmSr
|
||||
underlyingSr: newLvmSr,
|
||||
})
|
||||
await xapi.xo.setData(xosansr, 'xosan_config', data)
|
||||
CURRENT_POOL_OPERATIONS[poolId] = {...OPERATION_OBJECT, state: 2}
|
||||
@ -707,16 +707,16 @@ replaceBrick.params = {
|
||||
xosansr: {type: 'string'},
|
||||
previousBrick: {type: 'string'},
|
||||
newLvmSr: {type: 'string'},
|
||||
brickSize: {type: 'number'}
|
||||
brickSize: {type: 'number'},
|
||||
}
|
||||
|
||||
replaceBrick.resolve = {
|
||||
xosansr: ['sr', 'SR', 'administrate']
|
||||
xosansr: ['sr', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
|
||||
labelSuffix = '', increaseDataDisk = true,
|
||||
maxDiskSize = Infinity, memorySize = 2 * GIGABYTE
|
||||
maxDiskSize = Infinity, memorySize = 2 * GIGABYTE,
|
||||
}) {
|
||||
const host = lvmSr.$PBDs[0].$host
|
||||
const xenstoreData = {
|
||||
@ -724,7 +724,7 @@ async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
|
||||
'vm-data/sshkey': (await getOrCreateSshKey(xapi)).public,
|
||||
'vm-data/ip': ipAddress,
|
||||
'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 sr = xapi.getObject(lvmSr.$id)
|
||||
@ -750,7 +750,7 @@ async function _prepareGlusterVm (xapi, lvmSr, newVM, xosanNetwork, ipAddress, {
|
||||
memoryMax: memorySize,
|
||||
memoryMin: memorySize,
|
||||
memoryStaticMax: memorySize,
|
||||
memory: memorySize
|
||||
memory: memorySize,
|
||||
})
|
||||
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')
|
||||
@ -778,7 +778,7 @@ async function _importGlusterVM (xapi, template, lvmsrId) {
|
||||
await xapi.editVm(newVM, {
|
||||
autoPoweron: true,
|
||||
name_label: 'XOSAN imported VM',
|
||||
name_description: 'freshly imported'
|
||||
name_description: 'freshly imported',
|
||||
})
|
||||
return xapi.barrier(newVM.$ref)
|
||||
}
|
||||
@ -804,7 +804,7 @@ const _median = arr => {
|
||||
|
||||
const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xosansr, lvmsrId, {
|
||||
labelSuffix = '',
|
||||
glusterEndpoint = null, ipAddress = null, increaseDataDisk = true, brickSize = Infinity
|
||||
glusterEndpoint = null, ipAddress = null, increaseDataDisk = true, brickSize = Infinity,
|
||||
}) {
|
||||
const data = getXosanConfig(xosansr, xapi)
|
||||
if (ipAddress === null) {
|
||||
@ -827,7 +827,7 @@ const insertNewGlusterVm = defer.onFailure(async function ($onFailure, xapi, xos
|
||||
labelSuffix,
|
||||
increaseDataDisk,
|
||||
maxDiskSize: brickSize,
|
||||
memorySize: vmsMemories.length ? _median(vmsMemories) : 2 * GIGABYTE
|
||||
memorySize: vmsMemories.length ? _median(vmsMemories) : 2 * GIGABYTE,
|
||||
})
|
||||
if (!glusterEndpoint) {
|
||||
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}) {
|
||||
const OPERATION_OBJECT = {
|
||||
operation: 'addBricks',
|
||||
states: ['insertingNewVms', 'addingBricks', 'scaningSr']
|
||||
states: ['insertingNewVms', 'addingBricks', 'scaningSr'],
|
||||
}
|
||||
const xapi = this.getXapi(xosansr)
|
||||
const poolId = xapi.pool.$id
|
||||
@ -890,15 +890,15 @@ addBricks.params = {
|
||||
lvmsrs: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
brickSize: {type: 'number'}
|
||||
},
|
||||
brickSize: {type: 'number'},
|
||||
}
|
||||
|
||||
addBricks.resolve = {
|
||||
xosansr: ['sr', 'SR', 'administrate'],
|
||||
lvmsrs: ['sr', 'SR', 'administrate']
|
||||
lvmsrs: ['sr', 'SR', 'administrate'],
|
||||
}
|
||||
|
||||
export const removeBricks = defer.onFailure(async function ($onFailure, {xosansr, bricks}) {
|
||||
@ -933,8 +933,8 @@ removeBricks.params = {
|
||||
xosansr: {type: 'string'},
|
||||
bricks: {
|
||||
type: 'array',
|
||||
items: {type: 'string'}
|
||||
}
|
||||
items: {type: 'string'},
|
||||
},
|
||||
}
|
||||
|
||||
export function checkSrCurrentState ({poolId}) {
|
||||
@ -1001,12 +1001,12 @@ computeXosanPossibleOptions.params = {
|
||||
lvmSrs: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
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._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 = {
|
||||
id: {type: 'string'},
|
||||
version: {type: 'string'},
|
||||
pool: {type: 'string'}
|
||||
pool: {type: 'string'},
|
||||
}
|
||||
|
||||
downloadAndInstallXosanPack.resolve = {
|
||||
pool: ['pool', 'pool', 'administrate']
|
||||
pool: ['pool', 'pool', 'administrate'],
|
||||
}
|
||||
|
||||
downloadAndInstallXosanPack.permission = 'admin'
|
||||
|
@ -4,8 +4,8 @@ import {EventEmitter} from 'events'
|
||||
import {
|
||||
isArray,
|
||||
isObject,
|
||||
map
|
||||
} from './utils'
|
||||
map,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@ -29,7 +29,7 @@ export default class Collection extends EventEmitter {
|
||||
configurable: true,
|
||||
enumerale: true,
|
||||
value: Model,
|
||||
writable: true
|
||||
writable: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ export default class Redis extends Collection {
|
||||
connection,
|
||||
indexes = [],
|
||||
prefix,
|
||||
uri
|
||||
uri,
|
||||
}) {
|
||||
super()
|
||||
|
||||
@ -145,7 +145,7 @@ export default class Redis extends Collection {
|
||||
const key = `${prefix}:${id}`
|
||||
const promises = [
|
||||
redis.del(key),
|
||||
redis.hmset(key, ...params)
|
||||
redis.hmset(key, ...params),
|
||||
]
|
||||
|
||||
// Update indexes.
|
||||
|
@ -2,14 +2,14 @@ import { getBoundPropertyDescriptor } from 'bind-property-descriptor'
|
||||
|
||||
import {
|
||||
isArray,
|
||||
isFunction
|
||||
isFunction,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const {
|
||||
defineProperties,
|
||||
getOwnPropertyDescriptor
|
||||
getOwnPropertyDescriptor,
|
||||
} = Object
|
||||
|
||||
// ===================================================================
|
||||
@ -29,7 +29,7 @@ export const debounce = duration => (target, name, descriptor) => {
|
||||
function debounced () {
|
||||
const data = this[s] || (this[s] = {
|
||||
lastCall: 0,
|
||||
wrapper: null
|
||||
wrapper: null,
|
||||
})
|
||||
|
||||
const now = Date.now()
|
||||
@ -56,7 +56,7 @@ const _ownKeys = (
|
||||
(typeof Reflect !== 'undefined' && Reflect.ownKeys) ||
|
||||
(({
|
||||
getOwnPropertyNames: names,
|
||||
getOwnPropertySymbols: symbols
|
||||
getOwnPropertySymbols: symbols,
|
||||
}) => symbols
|
||||
? obj => names(obj).concat(symbols(obj))
|
||||
: names
|
||||
@ -75,7 +75,7 @@ const _IGNORED_STATIC_PROPERTIES = {
|
||||
caller: true,
|
||||
length: true,
|
||||
name: true,
|
||||
prototype: true
|
||||
prototype: true,
|
||||
}
|
||||
const _isIgnoredStaticProperty = name => _IGNORED_STATIC_PROPERTIES[name]
|
||||
|
||||
|
@ -47,7 +47,7 @@ export function init () {
|
||||
BootSig: 41,
|
||||
VolID: 895111106,
|
||||
VolLab: 'NO NAME ',
|
||||
FilSysType: 'FAT16 '
|
||||
FilSysType: 'FAT16 ',
|
||||
}, buf)
|
||||
|
||||
// End of sector.
|
||||
@ -80,6 +80,6 @@ export default buffer => {
|
||||
writeSectors: (i, source, cb) => {
|
||||
source.copy(buffer, i * SECTOR_SIZE, 0)
|
||||
cb()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
// See: https://gist.github.com/julien-f/5b9a3537eb82a34b04e2
|
||||
|
||||
var matcher = require('micromatch').matcher
|
||||
const matcher = require('micromatch').matcher
|
||||
|
||||
module.exports = function globMatcher (patterns, opts) {
|
||||
if (!Array.isArray(patterns)) {
|
||||
if (patterns[0] === '!') {
|
||||
var m = matcher(patterns.slice(1), opts)
|
||||
const m = matcher(patterns.slice(1), opts)
|
||||
return function (string) {
|
||||
return !m(string)
|
||||
}
|
||||
@ -14,12 +14,12 @@ module.exports = function globMatcher (patterns, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
var noneMustMatch = []
|
||||
var anyMustMatch = []
|
||||
const noneMustMatch = []
|
||||
const anyMustMatch = []
|
||||
|
||||
// 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) {
|
||||
var pattern = patterns[i]
|
||||
for (let i = 0, n = patterns.length; i < n; ++i) {
|
||||
const pattern = patterns[i]
|
||||
if (pattern[0] === '!') {
|
||||
noneMustMatch.push(matcher(pattern.slice(1), opts))
|
||||
} else {
|
||||
@ -27,11 +27,11 @@ module.exports = function globMatcher (patterns, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
var nNone = noneMustMatch.length
|
||||
var nAny = anyMustMatch.length
|
||||
const nNone = noneMustMatch.length
|
||||
const nAny = anyMustMatch.length
|
||||
|
||||
return function (string) {
|
||||
var i
|
||||
let i
|
||||
|
||||
for (i = 0; i < nNone; ++i) {
|
||||
if (noneMustMatch[i](string)) {
|
||||
|
34
src/index.js
34
src/index.js
@ -20,7 +20,7 @@ import { invalidCredentials } from 'xo-common/api-errors'
|
||||
import {
|
||||
ensureDir,
|
||||
readdir,
|
||||
readFile
|
||||
readFile,
|
||||
} from 'fs-extra'
|
||||
|
||||
import WebServer from 'http-server-plus'
|
||||
@ -31,7 +31,7 @@ import {
|
||||
isArray,
|
||||
isFunction,
|
||||
mapToArray,
|
||||
pFromCallback
|
||||
pFromCallback,
|
||||
} from './utils'
|
||||
|
||||
import bodyParser from 'body-parser'
|
||||
@ -54,12 +54,12 @@ const warn = (...args) => {
|
||||
|
||||
const DEPRECATED_ENTRIES = [
|
||||
'users',
|
||||
'servers'
|
||||
'servers',
|
||||
]
|
||||
|
||||
async function loadConfiguration () {
|
||||
const config = await appConf.load('xo-server', {
|
||||
ignoreUnknownFormats: true
|
||||
ignoreUnknownFormats: true,
|
||||
})
|
||||
|
||||
debug('Configuration loaded.')
|
||||
@ -89,7 +89,7 @@ function createExpressApp () {
|
||||
saveUninitialized: false,
|
||||
|
||||
// TODO: should be in the config file.
|
||||
secret: 'CLWguhRZAZIXZcbrMzHCYmefxgweItKnS'
|
||||
secret: 'CLWguhRZAZIXZcbrMzHCYmefxgweItKnS',
|
||||
}))
|
||||
|
||||
// Registers the connect-flash middleware, necessary for Passport to
|
||||
@ -124,7 +124,7 @@ async function setUpPassport (express, xo) {
|
||||
express.get('/signin', (req, res, next) => {
|
||||
res.send(signInPage({
|
||||
error: req.flash('error')[0],
|
||||
strategies
|
||||
strategies,
|
||||
}))
|
||||
})
|
||||
|
||||
@ -220,7 +220,7 @@ async function registerPlugin (pluginPath, pluginName) {
|
||||
default: factory = plugin,
|
||||
configurationSchema,
|
||||
configurationPresets,
|
||||
testSchema
|
||||
testSchema,
|
||||
} = plugin
|
||||
|
||||
// The default export can be either a factory or directly a plugin
|
||||
@ -231,7 +231,7 @@ async function registerPlugin (pluginPath, pluginName) {
|
||||
getDataDir: () => {
|
||||
const dir = `${this._config.datadir}/${pluginName}`
|
||||
return ensureDir(dir).then(() => dir)
|
||||
}
|
||||
},
|
||||
})
|
||||
: factory
|
||||
|
||||
@ -287,7 +287,7 @@ async function registerPluginsInPath (path) {
|
||||
async function registerPlugins (xo) {
|
||||
await Promise.all(mapToArray([
|
||||
`${__dirname}/../node_modules/`,
|
||||
'/usr/local/lib/node_modules/'
|
||||
'/usr/local/lib/node_modules/',
|
||||
], xo::registerPluginsInPath))
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ async function makeWebServerListen (webServer, {
|
||||
if (cert && key) {
|
||||
[opts.cert, opts.key] = await Promise.all([
|
||||
readFile(cert),
|
||||
readFile(key)
|
||||
readFile(key),
|
||||
])
|
||||
}
|
||||
try {
|
||||
@ -346,7 +346,7 @@ const setUpProxies = (express, opts, xo) => {
|
||||
}
|
||||
|
||||
const proxy = createProxyServer({
|
||||
ignorePath: true
|
||||
ignorePath: true,
|
||||
}).on('error', (error) => console.error(error))
|
||||
|
||||
// TODO: sort proxies by descending prefix length.
|
||||
@ -360,7 +360,7 @@ const setUpProxies = (express, opts, xo) => {
|
||||
const target = opts[prefix]
|
||||
|
||||
proxy.web(req, res, {
|
||||
target: target + url.slice(prefix.length)
|
||||
target: target + url.slice(prefix.length),
|
||||
})
|
||||
|
||||
return
|
||||
@ -372,7 +372,7 @@ const setUpProxies = (express, opts, xo) => {
|
||||
|
||||
// WebSocket proxy.
|
||||
const webSocketServer = new WebSocket.Server({
|
||||
noServer: true
|
||||
noServer: true,
|
||||
})
|
||||
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
|
||||
|
||||
@ -384,7 +384,7 @@ const setUpProxies = (express, opts, xo) => {
|
||||
const target = opts[prefix]
|
||||
|
||||
proxy.ws(req, socket, head, {
|
||||
target: target + url.slice(prefix.length)
|
||||
target: target + url.slice(prefix.length),
|
||||
})
|
||||
|
||||
return
|
||||
@ -413,7 +413,7 @@ const setUpStaticFiles = (express, opts) => {
|
||||
|
||||
const setUpApi = (webServer, xo, verboseLogsOnErrors) => {
|
||||
const webSocketServer = new WebSocket.Server({
|
||||
noServer: true
|
||||
noServer: true,
|
||||
})
|
||||
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
|
||||
|
||||
@ -474,7 +474,7 @@ const CONSOLE_PROXY_PATH_RE = /^\/api\/consoles\/(.*)$/
|
||||
|
||||
const setUpConsoleProxy = (webServer, xo) => {
|
||||
const webSocketServer = new WebSocket.Server({
|
||||
noServer: true
|
||||
noServer: true,
|
||||
})
|
||||
xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb)))
|
||||
|
||||
@ -519,7 +519,7 @@ const setUpConsoleProxy = (webServer, xo) => {
|
||||
|
||||
const USAGE = (({
|
||||
name,
|
||||
version
|
||||
version,
|
||||
}) => `Usage: ${name} [--safe-mode]
|
||||
|
||||
${name} v${version}`)(require('../package.json'))
|
||||
|
@ -12,13 +12,13 @@ import {
|
||||
map,
|
||||
mapValues,
|
||||
size,
|
||||
some
|
||||
some,
|
||||
} from 'lodash'
|
||||
|
||||
import { crossProduct } from './math'
|
||||
import {
|
||||
serializeError,
|
||||
thunkToArray
|
||||
thunkToArray,
|
||||
} from './utils'
|
||||
|
||||
export class JobExecutorError extends BaseError {}
|
||||
@ -81,11 +81,11 @@ const paramsVectorActionsMap = {
|
||||
return map(resolveParamsVector.call(this, collection), value => {
|
||||
return resolveParamsVector.call(this, {
|
||||
...iteratee,
|
||||
[paramName]: value
|
||||
[paramName]: value,
|
||||
})
|
||||
})
|
||||
},
|
||||
set: ({ values }) => values
|
||||
set: ({ values }) => values,
|
||||
}
|
||||
|
||||
export function resolveParamsVector (paramsVector) {
|
||||
@ -114,7 +114,7 @@ export default class JobExecutor {
|
||||
event: 'job.start',
|
||||
userId: job.userId,
|
||||
jobId: job.id,
|
||||
key: job.key
|
||||
key: job.key,
|
||||
})
|
||||
|
||||
try {
|
||||
@ -128,13 +128,13 @@ export default class JobExecutor {
|
||||
|
||||
this._logger.notice(`Execution terminated for ${job.id}.`, {
|
||||
event: 'job.end',
|
||||
runJobId
|
||||
runJobId,
|
||||
})
|
||||
} catch (error) {
|
||||
this._logger.error(`The execution of ${job.id} has failed.`, {
|
||||
event: 'job.end',
|
||||
runJobId,
|
||||
error: serializeError(error)
|
||||
error: serializeError(error),
|
||||
})
|
||||
|
||||
throw error
|
||||
@ -157,7 +157,7 @@ export default class JobExecutor {
|
||||
calls: {},
|
||||
runJobId,
|
||||
start: Date.now(),
|
||||
timezone: schedule !== undefined ? schedule.timezone : undefined
|
||||
timezone: schedule !== undefined ? schedule.timezone : undefined,
|
||||
}
|
||||
|
||||
await Bluebird.map(paramsFlatVector, params => {
|
||||
@ -165,13 +165,13 @@ export default class JobExecutor {
|
||||
event: 'jobCall.start',
|
||||
runJobId,
|
||||
method: job.method,
|
||||
params
|
||||
params,
|
||||
})
|
||||
|
||||
const call = execStatus.calls[runCallId] = {
|
||||
method: job.method,
|
||||
params,
|
||||
start: Date.now()
|
||||
start: Date.now(),
|
||||
}
|
||||
let promise = this.xo.callApiMethod(connection, job.method, assign({}, params))
|
||||
if (job.timeout) {
|
||||
@ -184,7 +184,7 @@ export default class JobExecutor {
|
||||
event: 'jobCall.end',
|
||||
runJobId,
|
||||
runCallId,
|
||||
returnedValue: value
|
||||
returnedValue: value,
|
||||
})
|
||||
|
||||
call.returnedValue = value
|
||||
@ -195,7 +195,7 @@ export default class JobExecutor {
|
||||
event: 'jobCall.end',
|
||||
runJobId,
|
||||
runCallId,
|
||||
error: serializeError(reason)
|
||||
error: serializeError(reason),
|
||||
})
|
||||
|
||||
call.error = reason
|
||||
@ -203,7 +203,7 @@ export default class JobExecutor {
|
||||
}
|
||||
)
|
||||
}, {
|
||||
concurrency: 2
|
||||
concurrency: 2,
|
||||
})
|
||||
|
||||
connection.close()
|
||||
|
@ -18,21 +18,21 @@ describe('resolveParamsVector', function () {
|
||||
type: 'crossProduct',
|
||||
items: [{
|
||||
type: 'set',
|
||||
values: [ { id: 3 }, { id: 7 }, { id: 10 } ]
|
||||
values: [ { id: 3 }, { id: 7 }, { id: 10 } ],
|
||||
}, {
|
||||
type: 'set',
|
||||
values: [ { value: 'foo' }, { value: 'bar' } ]
|
||||
values: [ { value: 'foo' }, { value: 'bar' } ],
|
||||
}, {
|
||||
type: 'set',
|
||||
values: [ { remote: 'local' } ]
|
||||
}]
|
||||
}
|
||||
values: [ { remote: 'local' } ],
|
||||
}],
|
||||
},
|
||||
],
|
||||
'cross product with `set` and `map`': [
|
||||
// Expected result.
|
||||
[
|
||||
{ remote: 'local', id: 'vm:2' },
|
||||
{ remote: 'smb', id: 'vm:2' }
|
||||
{ remote: 'smb', id: 'vm:2' },
|
||||
],
|
||||
|
||||
// Entry.
|
||||
@ -40,7 +40,7 @@ describe('resolveParamsVector', function () {
|
||||
type: 'crossProduct',
|
||||
items: [{
|
||||
type: 'set',
|
||||
values: [ { remote: 'local' }, { remote: 'smb' } ]
|
||||
values: [ { remote: 'local' }, { remote: 'smb' } ],
|
||||
}, {
|
||||
type: 'map',
|
||||
collection: {
|
||||
@ -49,14 +49,14 @@ describe('resolveParamsVector', function () {
|
||||
$pool: { __or: [ 'pool:1', 'pool:8', 'pool:12' ] },
|
||||
power_state: 'Running',
|
||||
tags: [ 'foo' ],
|
||||
type: 'VM'
|
||||
}
|
||||
type: 'VM',
|
||||
},
|
||||
},
|
||||
iteratee: {
|
||||
type: 'extractProperties',
|
||||
mapping: { id: 'id' }
|
||||
}
|
||||
}]
|
||||
mapping: { id: 'id' },
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
// Context.
|
||||
@ -68,28 +68,28 @@ describe('resolveParamsVector', function () {
|
||||
$pool: 'pool:1',
|
||||
tags: [],
|
||||
type: 'VM',
|
||||
power_state: 'Halted'
|
||||
power_state: 'Halted',
|
||||
}, {
|
||||
id: 'vm:2',
|
||||
$pool: 'pool:1',
|
||||
tags: [ 'foo' ],
|
||||
type: 'VM',
|
||||
power_state: 'Running'
|
||||
power_state: 'Running',
|
||||
}, {
|
||||
id: 'host:1',
|
||||
type: 'host',
|
||||
power_state: 'Running'
|
||||
power_state: 'Running',
|
||||
}, {
|
||||
id: 'vm:3',
|
||||
$pool: 'pool:8',
|
||||
tags: [ 'foo' ],
|
||||
type: 'VM',
|
||||
power_state: 'Halted'
|
||||
power_state: 'Halted',
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}, ([ expectedResult, entry, context ], name) => {
|
||||
describe(`with ${name}`, () => {
|
||||
it('Resolves params vector', () => {
|
||||
|
@ -105,12 +105,12 @@ function getArgs () {
|
||||
default: {
|
||||
limit: 100,
|
||||
json: false,
|
||||
help: false
|
||||
help: false,
|
||||
},
|
||||
alias: {
|
||||
limit: 'n',
|
||||
help: 'h'
|
||||
}
|
||||
help: 'h',
|
||||
},
|
||||
})
|
||||
|
||||
const patterns = {}
|
||||
@ -176,7 +176,7 @@ export default async function main () {
|
||||
}
|
||||
|
||||
const config = await appConf.load('xo-server', {
|
||||
ignoreUnknownFormats: true
|
||||
ignoreUnknownFormats: true,
|
||||
})
|
||||
|
||||
if (args.repair) {
|
||||
|
@ -6,7 +6,7 @@ import { isArray, map } from 'lodash'
|
||||
// ===================================================================
|
||||
|
||||
const parse = createParser({
|
||||
keyTransform: key => key.slice(5).toLowerCase()
|
||||
keyTransform: key => key.slice(5).toLowerCase(),
|
||||
})
|
||||
const makeFunction = command => (fields, ...args) =>
|
||||
execa.stdout(command, [
|
||||
@ -18,7 +18,7 @@ const makeFunction = command => (fields, ...args) =>
|
||||
'b',
|
||||
'-o',
|
||||
String(fields),
|
||||
...args
|
||||
...args,
|
||||
]).then(stdout => map(
|
||||
splitLines(stdout),
|
||||
isArray(fields)
|
||||
|
@ -4,32 +4,32 @@ import { forEach } from 'lodash'
|
||||
import { thunkToArray } from './utils'
|
||||
import {
|
||||
crossProduct,
|
||||
mergeObjects
|
||||
mergeObjects,
|
||||
} from './math'
|
||||
|
||||
describe('mergeObjects', function () {
|
||||
forEach({
|
||||
'Two sets of one': [
|
||||
{a: 1, b: 2}, {a: 1}, {b: 2}
|
||||
{a: 1, b: 2}, {a: 1}, {b: 2},
|
||||
],
|
||||
'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': [
|
||||
{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': [
|
||||
{a: 1, b: 2}, {a: 1, b: 2}
|
||||
{a: 1, b: 2}, {a: 1, b: 2},
|
||||
],
|
||||
'Empty set': [
|
||||
{a: 1}, {a: 1}, {}
|
||||
{a: 1}, {a: 1}, {},
|
||||
],
|
||||
'All empty': [
|
||||
{}, {}, {}
|
||||
{}, {}, {},
|
||||
],
|
||||
'No set': [
|
||||
{}
|
||||
]
|
||||
{},
|
||||
],
|
||||
}, ([ resultSet, ...sets ], name) => {
|
||||
describe(`with ${name}`, () => {
|
||||
it('Assembles all given param sets in on set', function () {
|
||||
@ -47,23 +47,23 @@ describe('crossProduct', function () {
|
||||
|
||||
forEach({
|
||||
'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': [
|
||||
[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': [
|
||||
[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': [
|
||||
[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': [
|
||||
[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': [
|
||||
[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) => {
|
||||
describe(`with ${name}`, () => {
|
||||
it('Crosses sets of values with a crossProduct callback', function () {
|
||||
|
@ -3,7 +3,7 @@ import {EventEmitter} from 'events'
|
||||
import {
|
||||
forEach,
|
||||
isEmpty,
|
||||
isString
|
||||
isString,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
|
@ -3,7 +3,7 @@ import Model from '../model'
|
||||
import {
|
||||
forEach,
|
||||
mapToArray,
|
||||
multiKeyHash
|
||||
multiKeyHash,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -21,7 +21,7 @@ Acl.create = (subject, object, action) => {
|
||||
id: hash,
|
||||
subject,
|
||||
object,
|
||||
action
|
||||
action,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ export class PluginsMetadata extends Collection {
|
||||
return /* await */ this.update({
|
||||
id,
|
||||
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({
|
||||
...pluginMetadata.properties,
|
||||
...data
|
||||
...data,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Collection from '../collection/redis'
|
||||
import Model from '../model'
|
||||
import {
|
||||
forEach
|
||||
forEach,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -18,7 +18,7 @@ export class Remotes extends Collection {
|
||||
name,
|
||||
url,
|
||||
enabled: false,
|
||||
error: ''
|
||||
error: '',
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ export class Schedules extends Collection {
|
||||
cron,
|
||||
enabled,
|
||||
name,
|
||||
timezone
|
||||
timezone,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { parseProp } from './utils'
|
||||
export default class User extends Model {}
|
||||
|
||||
User.prototype.default = {
|
||||
permission: 'none'
|
||||
permission: 'none',
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -13,14 +13,14 @@ export default function proxyConsole (ws, vmConsole, sessionId) {
|
||||
const socket = connect({
|
||||
host: url.host,
|
||||
port: url.port || 443,
|
||||
rejectUnauthorized: false
|
||||
rejectUnauthorized: false,
|
||||
}, () => {
|
||||
// Write headers.
|
||||
socket.write([
|
||||
`CONNECT ${url.path} HTTP/1.0`,
|
||||
`Host: ${url.hostname}`,
|
||||
`Cookie: session_id=${sessionId}`,
|
||||
'', ''
|
||||
'', '',
|
||||
].join('\r\n'))
|
||||
|
||||
const onSend = (error) => {
|
||||
|
@ -29,7 +29,7 @@ xo-server-recover-account <user name or email>
|
||||
}
|
||||
|
||||
const xo = new Xo(await appConf.load('xo-server', {
|
||||
ignoreUnknownFormats: true
|
||||
ignoreUnknownFormats: true,
|
||||
}))
|
||||
|
||||
const user = await xo.getUserByName(name, true)
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
addChecksumToReadStream,
|
||||
getPseudoRandomBytes,
|
||||
streamToBuffer,
|
||||
validChecksumOfReadStream
|
||||
validChecksumOfReadStream,
|
||||
} from '../utils'
|
||||
|
||||
export default class RemoteHandlerAbstract {
|
||||
@ -56,14 +56,14 @@ export default class RemoteHandlerAbstract {
|
||||
throw new Error('output and input did not match')
|
||||
}
|
||||
return {
|
||||
success: true
|
||||
success: true,
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
step,
|
||||
file: testFileName,
|
||||
error: error.message || String(error)
|
||||
error: error.message || String(error),
|
||||
}
|
||||
} finally {
|
||||
this.unlink(testFileName)::ignoreErrors()
|
||||
@ -73,7 +73,7 @@ export default class RemoteHandlerAbstract {
|
||||
async outputFile (file, data, options) {
|
||||
return this._outputFile(file, data, {
|
||||
flags: 'wx',
|
||||
...options
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ export default class RemoteHandlerAbstract {
|
||||
promise,
|
||||
this.getSize(file).then(size => {
|
||||
stream.length = size
|
||||
})::ignoreErrors()
|
||||
})::ignoreErrors(),
|
||||
])
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ export default class RemoteHandlerAbstract {
|
||||
} = {}) {
|
||||
const streamP = this._createOutputStream(file, {
|
||||
flags: 'wx',
|
||||
...options
|
||||
...options,
|
||||
})
|
||||
|
||||
if (!checksum) {
|
||||
@ -202,7 +202,7 @@ export default class RemoteHandlerAbstract {
|
||||
}
|
||||
|
||||
async unlink (file, {
|
||||
checksum = true
|
||||
checksum = true,
|
||||
} = {}) {
|
||||
if (checksum) {
|
||||
this._unlink(`${file}.checksum`)::ignoreErrors()
|
||||
|
@ -24,7 +24,7 @@ export default class NfsHandler extends LocalHandler {
|
||||
const match = regex.exec(m)
|
||||
mounted[match[3]] = {
|
||||
host: match[1],
|
||||
share: match[2]
|
||||
share: match[2],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -3,7 +3,7 @@ import Smb2 from '@marsaud/smb2-promise'
|
||||
import RemoteHandlerAbstract from './abstract'
|
||||
import {
|
||||
noop,
|
||||
pFinally
|
||||
pFinally,
|
||||
} from '../utils'
|
||||
|
||||
// Normalize the error code for file not found.
|
||||
@ -19,8 +19,8 @@ const normalizeError = error => {
|
||||
configurable: true,
|
||||
readable: true,
|
||||
value: 'ENOENT',
|
||||
writable: true
|
||||
}
|
||||
writable: true,
|
||||
},
|
||||
})
|
||||
: error
|
||||
}
|
||||
@ -41,7 +41,7 @@ export default class SmbHandler extends RemoteHandlerAbstract {
|
||||
domain: remote.domain,
|
||||
username: remote.username,
|
||||
password: remote.password,
|
||||
autoCloseTimeout: 0
|
||||
autoCloseTimeout: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -4,25 +4,25 @@ export default {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'unique identifier for this ACL'
|
||||
description: 'unique identifier for this ACL',
|
||||
},
|
||||
action: {
|
||||
type: 'string',
|
||||
description: 'permission (or role)'
|
||||
description: 'permission (or role)',
|
||||
},
|
||||
object: {
|
||||
type: 'string',
|
||||
description: 'item (or set)'
|
||||
description: 'item (or set)',
|
||||
},
|
||||
subject: {
|
||||
type: 'string',
|
||||
description: 'user (or group)'
|
||||
}
|
||||
description: 'user (or group)',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'action',
|
||||
'object',
|
||||
'subject'
|
||||
]
|
||||
'subject',
|
||||
],
|
||||
}
|
||||
|
@ -3,41 +3,41 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
type: {
|
||||
enum: ['call']
|
||||
enum: ['call'],
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'job identifier'
|
||||
description: 'job identifier',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'human readable name'
|
||||
description: 'human readable name',
|
||||
},
|
||||
userId: {
|
||||
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: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
// TODO description
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
description: 'called method'
|
||||
description: 'called method',
|
||||
},
|
||||
paramsVector: {
|
||||
type: 'object'
|
||||
type: 'object',
|
||||
},
|
||||
timeout: {
|
||||
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: [
|
||||
'type',
|
||||
'id',
|
||||
'userId',
|
||||
'key',
|
||||
'method'
|
||||
]
|
||||
'method',
|
||||
],
|
||||
}
|
||||
|
@ -4,26 +4,26 @@ export default {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'unique identifier for this log'
|
||||
description: 'unique identifier for this log',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
description: 'timestamp (in milliseconds) of this log'
|
||||
description: 'timestamp (in milliseconds) of this log',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'human readable (short) description of this log'
|
||||
description: 'human readable (short) description of this log',
|
||||
},
|
||||
namespace: {
|
||||
type: 'string',
|
||||
description: 'space to store logs'
|
||||
description: 'space to store logs',
|
||||
},
|
||||
data: {}
|
||||
data: {},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'time',
|
||||
'message',
|
||||
'namespace'
|
||||
]
|
||||
'namespace',
|
||||
],
|
||||
}
|
||||
|
@ -3,31 +3,31 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
event: {
|
||||
enum: ['jobCall.end']
|
||||
enum: ['jobCall.end'],
|
||||
},
|
||||
runJobId: {
|
||||
type: 'string',
|
||||
description: 'instance id of this job'
|
||||
description: 'instance id of this job',
|
||||
},
|
||||
runCallId: {
|
||||
type: 'string',
|
||||
description: 'instance id of this call'
|
||||
description: 'instance id of this call',
|
||||
},
|
||||
error: {
|
||||
type: 'object',
|
||||
description: 'describe one failure, exists if the call has failed'
|
||||
description: 'describe one failure, exists if the call has failed',
|
||||
},
|
||||
returnedValue: {
|
||||
description: 'call\'s result, exists if the call is a success'
|
||||
}
|
||||
description: 'call\'s result, exists if the call is a success',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'event',
|
||||
'runJobId',
|
||||
'runCallId'
|
||||
'runCallId',
|
||||
],
|
||||
oneOf: [
|
||||
{ required: ['error'] },
|
||||
{ required: ['returnedValue'] }
|
||||
]
|
||||
{ required: ['returnedValue'] },
|
||||
],
|
||||
}
|
||||
|
@ -3,25 +3,25 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
event: {
|
||||
enum: ['jobCall.start']
|
||||
enum: ['jobCall.start'],
|
||||
},
|
||||
runJobId: {
|
||||
type: 'string',
|
||||
description: 'instance id of this job'
|
||||
description: 'instance id of this job',
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
description: 'method linked to this call'
|
||||
description: 'method linked to this call',
|
||||
},
|
||||
params: {
|
||||
type: 'object',
|
||||
description: 'params of the called method'
|
||||
}
|
||||
description: 'params of the called method',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'event',
|
||||
'runJobId',
|
||||
'method',
|
||||
'params'
|
||||
]
|
||||
'params',
|
||||
],
|
||||
}
|
||||
|
@ -3,19 +3,19 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
event: {
|
||||
enum: ['job.end']
|
||||
enum: ['job.end'],
|
||||
},
|
||||
runJobId: {
|
||||
type: 'string',
|
||||
description: 'instance id of this job'
|
||||
description: 'instance id of this job',
|
||||
},
|
||||
error: {
|
||||
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: [
|
||||
'event',
|
||||
'runJobId'
|
||||
]
|
||||
'runJobId',
|
||||
],
|
||||
}
|
||||
|
@ -3,24 +3,24 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
event: {
|
||||
enum: ['job.start']
|
||||
enum: ['job.start'],
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
description: 'user who executes this job'
|
||||
description: 'user who executes this job',
|
||||
},
|
||||
jobId: {
|
||||
type: 'string',
|
||||
description: 'identifier of this job'
|
||||
description: 'identifier of this job',
|
||||
},
|
||||
key: {
|
||||
type: 'string'
|
||||
}
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'event',
|
||||
'userId',
|
||||
'jobId',
|
||||
'key'
|
||||
]
|
||||
'key',
|
||||
],
|
||||
}
|
||||
|
@ -4,46 +4,46 @@ export default {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'unique identifier for this plugin'
|
||||
description: 'unique identifier for this plugin',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'unique human readable name for this plugin'
|
||||
description: 'unique human readable name for this plugin',
|
||||
},
|
||||
autoload: {
|
||||
type: 'boolean',
|
||||
description: 'whether this plugin is loaded on startup'
|
||||
description: 'whether this plugin is loaded on startup',
|
||||
},
|
||||
loaded: {
|
||||
type: 'boolean',
|
||||
description: 'whether or not this plugin is currently loaded'
|
||||
description: 'whether or not this plugin is currently loaded',
|
||||
},
|
||||
unloadable: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'whether or not this plugin can be unloaded'
|
||||
description: 'whether or not this plugin can be unloaded',
|
||||
},
|
||||
configuration: {
|
||||
type: 'object',
|
||||
description: 'current configuration of this plugin (not present if none)'
|
||||
description: 'current configuration of this plugin (not present if none)',
|
||||
},
|
||||
configurationSchema: {
|
||||
$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: {
|
||||
type: 'boolean',
|
||||
description: 'whether or not this plugin can be tested'
|
||||
description: 'whether or not this plugin can be tested',
|
||||
},
|
||||
testSchema: {
|
||||
$ref: 'http://json-schema.org/draft-04/schema#',
|
||||
description: 'test schema for this plugin'
|
||||
}
|
||||
description: 'test schema for this plugin',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'name',
|
||||
'autoload',
|
||||
'loaded'
|
||||
]
|
||||
'loaded',
|
||||
],
|
||||
}
|
||||
|
@ -4,22 +4,22 @@ export default {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'unique identifier for this user'
|
||||
description: 'unique identifier for this user',
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
description: 'email address of this user'
|
||||
description: 'email address of this user',
|
||||
},
|
||||
groups: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'string',
|
||||
},
|
||||
description: 'identifier of groups this user belong to'
|
||||
description: 'identifier of groups this user belong to',
|
||||
},
|
||||
permission: {
|
||||
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: {
|
||||
type: 'object',
|
||||
@ -31,20 +31,20 @@ export default {
|
||||
type: 'object',
|
||||
properties: {
|
||||
key: { type: 'string' },
|
||||
title: { type: 'string' }
|
||||
title: { type: 'string' },
|
||||
},
|
||||
required: [
|
||||
'key',
|
||||
'title'
|
||||
]
|
||||
}
|
||||
}
|
||||
'title',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
description: 'various user preferences',
|
||||
},
|
||||
description: 'various user preferences'
|
||||
}
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'email'
|
||||
]
|
||||
'email',
|
||||
],
|
||||
}
|
||||
|
22
src/utils.js
22
src/utils.js
@ -30,11 +30,11 @@ import {
|
||||
fromCallback,
|
||||
isPromise,
|
||||
promisify,
|
||||
reflect as pReflect
|
||||
reflect as pReflect,
|
||||
} from 'promise-toolbox'
|
||||
import {
|
||||
createHash,
|
||||
randomBytes
|
||||
randomBytes,
|
||||
} from 'crypto'
|
||||
|
||||
// ===================================================================
|
||||
@ -111,7 +111,7 @@ export const diffItems = (coll1, coll2) => {
|
||||
const ALGORITHM_TO_ID = {
|
||||
md5: '1',
|
||||
sha256: '5',
|
||||
sha512: '6'
|
||||
sha512: '6',
|
||||
}
|
||||
|
||||
const ID_TO_ALGORITHM = invert(ALGORITHM_TO_ID)
|
||||
@ -258,7 +258,7 @@ export const generateToken = (randomBytes => {
|
||||
|
||||
export const formatXml = (function () {
|
||||
const builder = new xml2js.Builder({
|
||||
headless: true
|
||||
headless: true,
|
||||
})
|
||||
|
||||
return (...args) => builder.buildObject(...args)
|
||||
@ -267,7 +267,7 @@ export const formatXml = (function () {
|
||||
export const parseXml = (function () {
|
||||
const opts = {
|
||||
mergeAttrs: true,
|
||||
explicitArray: false
|
||||
explicitArray: false,
|
||||
}
|
||||
|
||||
return (xml) => {
|
||||
@ -315,7 +315,7 @@ export const lightSet = collection => {
|
||||
return set
|
||||
},
|
||||
has: value => data[value],
|
||||
toArray: () => keys(data)
|
||||
toArray: () => keys(data),
|
||||
}
|
||||
return set
|
||||
}
|
||||
@ -375,7 +375,7 @@ export {
|
||||
lastly as pFinally,
|
||||
promisify,
|
||||
promisifyAll,
|
||||
reflect as pReflect
|
||||
reflect as pReflect,
|
||||
} from 'promise-toolbox'
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -489,7 +489,7 @@ export const resolveSubpath = (root, path) =>
|
||||
|
||||
export const streamToArray = (stream, {
|
||||
filter,
|
||||
mapper
|
||||
mapper,
|
||||
} = {}) => new Promise((resolve, reject) => {
|
||||
stream = highland(stream).stopOnError(reject)
|
||||
if (filter) {
|
||||
@ -526,7 +526,7 @@ export const scheduleFn = (cronTime, fn, timeZone) => {
|
||||
}
|
||||
},
|
||||
start: true,
|
||||
timeZone
|
||||
timeZone,
|
||||
})
|
||||
|
||||
return () => {
|
||||
@ -540,7 +540,7 @@ export const scheduleFn = (cronTime, fn, timeZone) => {
|
||||
export const serializeError = error => ({
|
||||
message: error.message,
|
||||
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)
|
||||
return i === -1 ? null : [
|
||||
string.slice(0, i),
|
||||
string.slice(i + separator.length)
|
||||
string.slice(i + separator.length),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
formatXml,
|
||||
generateToken,
|
||||
parseSize,
|
||||
pSettle
|
||||
pSettle,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -57,7 +57,7 @@ describe('diffItems', () => {
|
||||
['baz', 'foo']
|
||||
)).toEqual([
|
||||
['bar'],
|
||||
['baz']
|
||||
['baz'],
|
||||
])
|
||||
})
|
||||
})
|
||||
@ -109,9 +109,9 @@ describe('formatXml()', function () {
|
||||
foo: {
|
||||
bar: [
|
||||
{$: {baz: 'plop'}},
|
||||
{$: {baz: 'plip'}}
|
||||
]
|
||||
}
|
||||
{$: {baz: 'plip'}},
|
||||
],
|
||||
},
|
||||
})).toBe(`<foo>
|
||||
<bar baz="plop"/>
|
||||
<bar baz="plip"/>
|
||||
@ -157,11 +157,11 @@ describe('pSettle()', () => {
|
||||
const [
|
||||
status1,
|
||||
status2,
|
||||
status3
|
||||
status3,
|
||||
] = await pSettle([
|
||||
Promise.resolve(42),
|
||||
Math.PI,
|
||||
Promise.reject(rejection)
|
||||
Promise.reject(rejection),
|
||||
])
|
||||
|
||||
expect(status1.isRejected()).toBe(false)
|
||||
@ -187,11 +187,11 @@ describe('pSettle()', () => {
|
||||
const {
|
||||
a: status1,
|
||||
b: status2,
|
||||
c: status3
|
||||
c: status3,
|
||||
} = await pSettle({
|
||||
a: Promise.resolve(42),
|
||||
b: Math.PI,
|
||||
c: Promise.reject(rejection)
|
||||
c: Promise.reject(rejection),
|
||||
})
|
||||
|
||||
expect(status1.isRejected()).toBe(false)
|
||||
|
@ -8,7 +8,7 @@ import isEqual from 'lodash/isEqual'
|
||||
import constantStream from './constant-stream'
|
||||
import {
|
||||
noop,
|
||||
streamToBuffer
|
||||
streamToBuffer,
|
||||
} from './utils'
|
||||
|
||||
const VHD_UTIL_DEBUG = 0
|
||||
@ -57,7 +57,7 @@ const fuFooter = fu.struct([
|
||||
fu.uint32('fileFormatVersion'), // 12
|
||||
fu.struct('dataOffset', [
|
||||
fu.uint32('high'), // 16
|
||||
fu.uint32('low') // 20
|
||||
fu.uint32('low'), // 20
|
||||
]),
|
||||
fu.uint32('timestamp'), // 24
|
||||
fu.char('creatorApplication', 4), // 28
|
||||
@ -65,34 +65,34 @@ const fuFooter = fu.struct([
|
||||
fu.uint32('creatorHostOs'), // 36
|
||||
fu.struct('originalSize', [ // At the creation, current size of the hard disk.
|
||||
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.uint32('high'), // 48
|
||||
fu.uint32('low') // 52
|
||||
fu.uint32('low'), // 52
|
||||
]),
|
||||
fu.struct('diskGeometry', [
|
||||
fu.uint16('cylinders'), // 56
|
||||
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('checksum'), // 64
|
||||
fu.uint8('uuid', 16), // 68
|
||||
fu.char('saved'), // 84
|
||||
fu.char('hidden'), // 85
|
||||
fu.char('reserved', 426) // 86
|
||||
fu.char('reserved', 426), // 86
|
||||
])
|
||||
|
||||
const fuHeader = fu.struct([
|
||||
fu.char('cookie', 8),
|
||||
fu.struct('dataOffset', [
|
||||
fu.uint32('high'),
|
||||
fu.uint32('low')
|
||||
fu.uint32('low'),
|
||||
]),
|
||||
fu.struct('tableOffset', [ // Absolute byte offset of the Block Allocation Table.
|
||||
fu.uint32('high'),
|
||||
fu.uint32('low')
|
||||
fu.uint32('low'),
|
||||
]),
|
||||
fu.uint32('headerVersion'),
|
||||
fu.uint32('maxTableEntries'), // Max entries in the Block Allocation Table.
|
||||
@ -109,10 +109,10 @@ const fuHeader = fu.struct([
|
||||
fu.uint32('reserved'),
|
||||
fu.struct('platformDataOffset', [ // Absolute byte offset of the locator data.
|
||||
fu.uint32('high'),
|
||||
fu.uint32('low')
|
||||
])
|
||||
fu.uint32('low'),
|
||||
]),
|
||||
], VHD_PARENT_LOCATOR_ENTRIES),
|
||||
fu.char('reserved2', 256)
|
||||
fu.char('reserved2', 256),
|
||||
])
|
||||
|
||||
// ===================================================================
|
||||
@ -191,7 +191,7 @@ class Vhd {
|
||||
_readStream (start, n) {
|
||||
return this._handler.createReadStream(this._path, {
|
||||
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.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.
|
||||
return this._handler.createOutputStream(this._path, {
|
||||
flags: 'r+',
|
||||
start: offset
|
||||
start: offset,
|
||||
}).then(
|
||||
Buffer.isBuffer(data)
|
||||
? stream => new Promise((resolve, reject) => {
|
||||
@ -413,7 +413,7 @@ class Vhd {
|
||||
if (tableOffset + batSize < sectorsToBytes(firstSector)) {
|
||||
return Promise.all([
|
||||
extendBat(),
|
||||
this.writeHeader()
|
||||
this.writeHeader(),
|
||||
])
|
||||
}
|
||||
|
||||
@ -429,7 +429,7 @@ class Vhd {
|
||||
|
||||
this._setBatEntry(first, newFirstSector),
|
||||
this.writeHeader(),
|
||||
this.writeFooter()
|
||||
this.writeFooter(),
|
||||
])
|
||||
}
|
||||
|
||||
@ -460,7 +460,7 @@ class Vhd {
|
||||
sectorsToBytes(blockAddr)
|
||||
),
|
||||
|
||||
this._setBatEntry(blockId, blockAddr)
|
||||
this._setBatEntry(blockId, blockAddr),
|
||||
])
|
||||
|
||||
return blockAddr
|
||||
@ -585,7 +585,7 @@ export default async function vhdMerge (
|
||||
// Reading footer and header.
|
||||
await Promise.all([
|
||||
parentVhd.readHeaderAndFooter(),
|
||||
childVhd.readHeaderAndFooter()
|
||||
childVhd.readHeaderAndFooter(),
|
||||
])
|
||||
|
||||
assert(childVhd.header.blockSize === parentVhd.header.blockSize)
|
||||
@ -611,7 +611,7 @@ export default async function vhdMerge (
|
||||
// Read allocation table of child/parent.
|
||||
await Promise.all([
|
||||
parentVhd.readBlockTable(),
|
||||
childVhd.readBlockTable()
|
||||
childVhd.readBlockTable(),
|
||||
])
|
||||
|
||||
await parentVhd.ensureBatSize(childVhd.header.maxTableEntries)
|
||||
@ -648,7 +648,7 @@ export async function chainVhd (
|
||||
const childVhd = new Vhd(childHandler, childPath)
|
||||
await Promise.all([
|
||||
parentVhd.readHeaderAndFooter(),
|
||||
childVhd.readHeaderAndFooter()
|
||||
childVhd.readHeaderAndFooter(),
|
||||
])
|
||||
|
||||
const { header } = childVhd
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {
|
||||
startsWith
|
||||
startsWith,
|
||||
} from 'lodash'
|
||||
|
||||
import {
|
||||
@ -10,23 +10,23 @@ import {
|
||||
isEmpty,
|
||||
mapFilter,
|
||||
mapToArray,
|
||||
parseXml
|
||||
parseXml,
|
||||
} from './utils'
|
||||
import {
|
||||
isHostRunning,
|
||||
isVmHvm,
|
||||
isVmRunning,
|
||||
parseDateTime
|
||||
parseDateTime,
|
||||
} from './xapi'
|
||||
import {
|
||||
useUpdateSystem
|
||||
useUpdateSystem,
|
||||
} from './xapi/utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const {
|
||||
defineProperties,
|
||||
freeze
|
||||
freeze,
|
||||
} = Object
|
||||
|
||||
function link (obj, prop, idField = '$id') {
|
||||
@ -83,8 +83,8 @@ const TRANSFORMS = {
|
||||
xosanPackInstallationTime: toTimestamp(obj.other_config.xosan_pack_installation_time),
|
||||
cpus: {
|
||||
cores: cpuInfo && +cpuInfo.cpu_count,
|
||||
sockets: cpuInfo && +cpuInfo.socket_count
|
||||
}
|
||||
sockets: cpuInfo && +cpuInfo.socket_count,
|
||||
},
|
||||
|
||||
// TODO
|
||||
// - ? networks = networksByPool.items[pool.id] (network.$pool.id)
|
||||
@ -104,11 +104,11 @@ const TRANSFORMS = {
|
||||
host (obj) {
|
||||
const {
|
||||
$metrics: metrics,
|
||||
other_config: otherConfig
|
||||
other_config: otherConfig,
|
||||
software_version: softwareVersion,
|
||||
} = obj
|
||||
|
||||
const isRunning = isHostRunning(obj)
|
||||
const { software_version } = obj
|
||||
let supplementalPacks, patches
|
||||
|
||||
if (useUpdateSystem(obj)) {
|
||||
@ -124,7 +124,7 @@ const TRANSFORMS = {
|
||||
guidance: update.after_apply_guidance,
|
||||
hosts: link(update, 'hosts'),
|
||||
vdi: link(update, 'vdi'),
|
||||
size: update.installation_size
|
||||
size: update.installation_size,
|
||||
}
|
||||
|
||||
if (startsWith(update.name_label, 'XS')) {
|
||||
@ -143,11 +143,11 @@ const TRANSFORMS = {
|
||||
|
||||
address: obj.address,
|
||||
bios_strings: obj.bios_strings,
|
||||
build: obj.software_version.build_number,
|
||||
build: softwareVersion.build_number,
|
||||
enabled: Boolean(obj.enabled),
|
||||
cpus: {
|
||||
cores: cpuInfo && +cpuInfo.cpu_count,
|
||||
sockets: cpuInfo && +cpuInfo.socket_count
|
||||
sockets: cpuInfo && +cpuInfo.socket_count,
|
||||
},
|
||||
current_operations: obj.current_operations,
|
||||
hostname: obj.hostname,
|
||||
@ -164,7 +164,7 @@ const TRANSFORMS = {
|
||||
|
||||
return {
|
||||
usage: total - free,
|
||||
size: total
|
||||
size: total,
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ const TRANSFORMS = {
|
||||
size: 0,
|
||||
|
||||
// Deprecated
|
||||
total: 0
|
||||
total: 0,
|
||||
}
|
||||
})(),
|
||||
patches: patches || link(obj, 'patches'),
|
||||
@ -183,7 +183,7 @@ const TRANSFORMS = {
|
||||
: 'Unknown',
|
||||
startTime: toTimestamp(otherConfig.boot_time),
|
||||
supplementalPacks: supplementalPacks ||
|
||||
mapFilter(software_version, (value, key) => {
|
||||
mapFilter(softwareVersion, (value, key) => {
|
||||
let author, name
|
||||
if (([ author, name ] = key.split(':')).length === 2) {
|
||||
const [ description, version ] = value.split(', ')
|
||||
@ -191,14 +191,14 @@ const TRANSFORMS = {
|
||||
name,
|
||||
description,
|
||||
author,
|
||||
version: version.split(' ')[1]
|
||||
version: version.split(' ')[1],
|
||||
}
|
||||
}
|
||||
}),
|
||||
agentStartTime: toTimestamp(otherConfig.agent_start_time),
|
||||
rebootRequired: !isEmpty(obj.updates_requiring_reboot),
|
||||
tags: obj.tags,
|
||||
version: obj.software_version.product_version,
|
||||
version: softwareVersion.product_version,
|
||||
|
||||
// TODO: dedupe.
|
||||
PIFs: link(obj, 'PIFs'),
|
||||
@ -208,7 +208,7 @@ const TRANSFORMS = {
|
||||
PGPUs: link(obj, 'PGPUs'),
|
||||
$PGPUs: link(obj, 'PGPUs'),
|
||||
|
||||
$PBDs: link(obj, 'PBDs')
|
||||
$PBDs: link(obj, 'PBDs'),
|
||||
|
||||
// TODO:
|
||||
// - controller = vmControllersByContainer.items[host.id]
|
||||
@ -226,7 +226,7 @@ const TRANSFORMS = {
|
||||
const {
|
||||
$guest_metrics: guestMetrics,
|
||||
$metrics: metrics,
|
||||
other_config: otherConfig
|
||||
other_config: otherConfig,
|
||||
} = obj
|
||||
|
||||
const isHvm = isVmHvm(obj)
|
||||
@ -276,7 +276,7 @@ const TRANSFORMS = {
|
||||
isRunning && metrics && xenTools
|
||||
? +metrics.VCPUs_number
|
||||
: +obj.VCPUs_at_startup
|
||||
)
|
||||
),
|
||||
},
|
||||
current_operations: obj.current_operations,
|
||||
docker: (function () {
|
||||
@ -287,14 +287,14 @@ const TRANSFORMS = {
|
||||
|
||||
if (monitor === 'False') {
|
||||
return {
|
||||
enabled: false
|
||||
enabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
docker_ps: process,
|
||||
docker_info: info,
|
||||
docker_version: version
|
||||
docker_version: version,
|
||||
} = otherConfig
|
||||
|
||||
return {
|
||||
@ -302,7 +302,7 @@ const TRANSFORMS = {
|
||||
info: info && parseXml(info).docker_info,
|
||||
containers: ensureArray(process && parseXml(process).docker_ps.item),
|
||||
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 = {
|
||||
dynamic: [ dynamicMin, dynamicMax ],
|
||||
static: [ staticMin, staticMax ]
|
||||
static: [ staticMin, staticMax ],
|
||||
}
|
||||
|
||||
const gmMemory = guestMetrics && guestMetrics.memory
|
||||
@ -365,13 +365,13 @@ const TRANSFORMS = {
|
||||
|
||||
// TODO: dedupe
|
||||
VGPUs: link(obj, 'VGPUs'),
|
||||
$VGPUs: link(obj, 'VGPUs')
|
||||
$VGPUs: link(obj, 'VGPUs'),
|
||||
}
|
||||
|
||||
if (isHvm) {
|
||||
({
|
||||
vga: vm.vga = 'cirrus',
|
||||
videoram: vm.videoram = 4
|
||||
videoram: vm.videoram = 4,
|
||||
} = obj.platform)
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ const TRANSFORMS = {
|
||||
|
||||
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.$PBDs[0], 'host')
|
||||
),
|
||||
$PBDs: link(obj, 'PBDs')
|
||||
$PBDs: link(obj, 'PBDs'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -475,7 +475,7 @@ const TRANSFORMS = {
|
||||
attached: Boolean(obj.currently_attached),
|
||||
host: link(obj, 'host'),
|
||||
SR: link(obj, 'SR'),
|
||||
device_config: obj.device_config
|
||||
device_config: obj.device_config,
|
||||
}
|
||||
},
|
||||
|
||||
@ -506,7 +506,7 @@ const TRANSFORMS = {
|
||||
physical: Boolean(obj.physical),
|
||||
vlan: +obj.VLAN,
|
||||
$host: link(obj, 'host'),
|
||||
$network: link(obj, 'network')
|
||||
$network: link(obj, 'network'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -524,7 +524,7 @@ const TRANSFORMS = {
|
||||
usage: +obj.physical_utilisation,
|
||||
|
||||
$SR: link(obj, 'SR'),
|
||||
$VBDs: link(obj, 'VBDs')
|
||||
$VBDs: link(obj, 'VBDs'),
|
||||
}
|
||||
|
||||
if (obj.is_a_snapshot) {
|
||||
@ -553,7 +553,7 @@ const TRANSFORMS = {
|
||||
position: obj.userdevice,
|
||||
read_only: obj.mode === 'RO',
|
||||
VDI: link(obj, 'VDI'),
|
||||
VM: link(obj, 'VM')
|
||||
VM: link(obj, 'VM'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -571,7 +571,7 @@ const TRANSFORMS = {
|
||||
MTU: +obj.MTU,
|
||||
|
||||
$network: link(obj, 'network'),
|
||||
$VM: link(obj, 'VM')
|
||||
$VM: link(obj, 'VM'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -587,7 +587,7 @@ const TRANSFORMS = {
|
||||
other_config: obj.other_config,
|
||||
tags: obj.tags,
|
||||
PIFs: link(obj, 'PIFs'),
|
||||
VIFs: link(obj, 'VIFs')
|
||||
VIFs: link(obj, 'VIFs'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -599,7 +599,7 @@ const TRANSFORMS = {
|
||||
name: obj.name,
|
||||
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,
|
||||
status: obj.status,
|
||||
|
||||
$host: link(obj, 'resident_on')
|
||||
$host: link(obj, 'resident_on'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -628,7 +628,7 @@ const TRANSFORMS = {
|
||||
time: toTimestamp(obj.timestamp_applied),
|
||||
pool_patch: link(obj, 'pool_patch', '$ref'),
|
||||
|
||||
$host: link(obj, 'host')
|
||||
$host: link(obj, 'host'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -649,7 +649,7 @@ const TRANSFORMS = {
|
||||
// version: obj.version,
|
||||
|
||||
// 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,
|
||||
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'),
|
||||
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,
|
||||
resident_on: link(obj, 'resident_on'),
|
||||
vgpuType: link(obj, '$type'),
|
||||
vm: link(obj, 'VM')
|
||||
vm: link(obj, 'VM'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -719,7 +719,7 @@ const TRANSFORMS = {
|
||||
otherConfig: obj.other_config,
|
||||
pgpus: link(obj, 'PGPUs'),
|
||||
supportedVgpuTypes: link(obj, 'supported_VGPU_types'),
|
||||
vgpus: link(obj, 'VGPUs')
|
||||
vgpus: link(obj, 'VGPUs'),
|
||||
}
|
||||
},
|
||||
|
||||
@ -738,9 +738,9 @@ const TRANSFORMS = {
|
||||
modelName: obj.model_name,
|
||||
pgpus: link(obj, 'enabled_on_PGPUs'),
|
||||
vendorName: obj.vendor_name,
|
||||
vgpus: link(obj, 'VGPUs')
|
||||
}
|
||||
vgpus: link(obj, 'VGPUs'),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -774,11 +774,11 @@ export default xapiObj => {
|
||||
// Internal properties.
|
||||
defineProperties(xoObj, {
|
||||
_xapiId: {
|
||||
value: xapiObj.$id
|
||||
value: xapiObj.$id,
|
||||
},
|
||||
_xapiRef: {
|
||||
value: xapiObj.$ref
|
||||
}
|
||||
value: xapiObj.$ref,
|
||||
},
|
||||
})
|
||||
|
||||
// Freezes and returns the new object.
|
||||
|
@ -14,14 +14,14 @@ const RRD_STEP_FROM_STRING = {
|
||||
'seconds': RRD_STEP_SECONDS,
|
||||
'minutes': RRD_STEP_MINUTES,
|
||||
'hours': RRD_STEP_HOURS,
|
||||
'days': RRD_STEP_DAYS
|
||||
'days': RRD_STEP_DAYS,
|
||||
}
|
||||
|
||||
const RRD_POINTS_PER_STEP = {
|
||||
[RRD_STEP_SECONDS]: 120,
|
||||
[RRD_STEP_MINUTES]: 120,
|
||||
[RRD_STEP_HOURS]: 168,
|
||||
[RRD_STEP_DAYS]: 366
|
||||
[RRD_STEP_DAYS]: 366,
|
||||
}
|
||||
|
||||
export class XapiStatsError extends BaseError {}
|
||||
@ -61,12 +61,12 @@ function getNewHostStats () {
|
||||
cpus: [],
|
||||
pifs: {
|
||||
rx: [],
|
||||
tx: []
|
||||
tx: [],
|
||||
},
|
||||
load: [],
|
||||
memory: [],
|
||||
memoryFree: [],
|
||||
memoryUsed: []
|
||||
memoryUsed: [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,15 +75,15 @@ function getNewVmStats () {
|
||||
cpus: [],
|
||||
vifs: {
|
||||
rx: [],
|
||||
tx: []
|
||||
tx: [],
|
||||
},
|
||||
xvds: {
|
||||
r: {},
|
||||
w: {}
|
||||
w: {},
|
||||
},
|
||||
memory: [],
|
||||
memoryFree: [],
|
||||
memoryUsed: []
|
||||
memoryUsed: [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,11 +96,11 @@ function getNewHostLegends () {
|
||||
cpus: [],
|
||||
pifs: {
|
||||
rx: [],
|
||||
tx: []
|
||||
tx: [],
|
||||
},
|
||||
load: null,
|
||||
memoryFree: null,
|
||||
memory: null
|
||||
memory: null,
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,14 +109,14 @@ function getNewVmLegends () {
|
||||
cpus: [],
|
||||
vifs: {
|
||||
rx: [],
|
||||
tx: []
|
||||
tx: [],
|
||||
},
|
||||
xvds: {
|
||||
r: [],
|
||||
w: []
|
||||
w: [],
|
||||
},
|
||||
memoryFree: null,
|
||||
memory: null
|
||||
memory: null,
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,8 +391,8 @@ export default class XapiStats {
|
||||
cf: 'AVERAGE',
|
||||
host: 'true',
|
||||
json: 'true',
|
||||
start: timestamp
|
||||
}
|
||||
start: timestamp,
|
||||
},
|
||||
}).then(response => response.readAll().then(JSON5.parse))
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ export default class XapiStats {
|
||||
if (vmId === undefined) {
|
||||
return {
|
||||
interval: step,
|
||||
...hostStats
|
||||
...hostStats,
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,7 +422,7 @@ export default class XapiStats {
|
||||
return {
|
||||
interval: step,
|
||||
endTimestamp: hostStats.endTimestamp,
|
||||
stats: (vmsStats && vmsStats[vmId]) || getNewVmStats()
|
||||
stats: (vmsStats && vmsStats[vmId]) || getNewVmStats(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,7 +475,7 @@ export default class XapiStats {
|
||||
if (this._hosts[hostname][step] === undefined) {
|
||||
this._hosts[hostname][step] = {
|
||||
endTimestamp: 0,
|
||||
localTimestamp: 0
|
||||
localTimestamp: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,13 @@ import {
|
||||
isEmpty,
|
||||
omit,
|
||||
startsWith,
|
||||
uniq
|
||||
uniq,
|
||||
} from 'lodash'
|
||||
import {
|
||||
Xapi as XapiBase
|
||||
Xapi as XapiBase,
|
||||
} from 'xen-api'
|
||||
import {
|
||||
satisfies as versionSatisfies
|
||||
satisfies as versionSatisfies,
|
||||
} from 'semver'
|
||||
|
||||
import createSizeStream from '../size-stream'
|
||||
@ -42,10 +42,10 @@ import {
|
||||
pDelay,
|
||||
pFinally,
|
||||
promisifyAll,
|
||||
pSettle
|
||||
pSettle,
|
||||
} 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 {
|
||||
asBoolean,
|
||||
@ -60,7 +60,7 @@ import {
|
||||
isVmRunning,
|
||||
NULL_REF,
|
||||
optional,
|
||||
prepareXapiParam
|
||||
prepareXapiParam,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -104,7 +104,7 @@ export default class Xapi extends XapiBase {
|
||||
forEach(objects, object => {
|
||||
const {
|
||||
$id: id,
|
||||
$ref: ref
|
||||
$ref: ref,
|
||||
} = object
|
||||
|
||||
// Run generic watchers.
|
||||
@ -131,7 +131,7 @@ export default class Xapi extends XapiBase {
|
||||
const fn = super.call
|
||||
|
||||
const loop = () => fn.apply(this, args)::pCatch({
|
||||
code: 'TOO_MANY_PENDING_TASKS'
|
||||
code: 'TOO_MANY_PENDING_TASKS',
|
||||
}, () => pDelay(5e3).then(loop))
|
||||
|
||||
return loop()
|
||||
@ -182,7 +182,7 @@ export default class Xapi extends XapiBase {
|
||||
// Register the watcher.
|
||||
watcher = this._objectWatchers[predicate] = {
|
||||
promise,
|
||||
resolve
|
||||
resolve,
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ export default class Xapi extends XapiBase {
|
||||
_setObjectProperties (object, props) {
|
||||
const {
|
||||
$ref: ref,
|
||||
$type: type
|
||||
$type: type,
|
||||
} = object
|
||||
|
||||
const namespace = getNamespaceForType(type)
|
||||
@ -243,7 +243,7 @@ export default class Xapi extends XapiBase {
|
||||
async _updateObjectMapProperty (object, prop, values) {
|
||||
const {
|
||||
$ref: ref,
|
||||
$type: type
|
||||
$type: type,
|
||||
} = object
|
||||
|
||||
prop = camelToSnakeCase(prop)
|
||||
@ -266,46 +266,46 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
async setHostProperties (id, {
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
}) {
|
||||
await this._setObjectProperties(this.getObject(id), {
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
})
|
||||
}
|
||||
|
||||
async setPoolProperties ({
|
||||
autoPoweron,
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
}) {
|
||||
const { pool } = this
|
||||
|
||||
await Promise.all([
|
||||
this._setObjectProperties(pool, {
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
}),
|
||||
autoPoweron != null && this._updateObjectMapProperty(pool, 'other_config', {
|
||||
autoPoweron: autoPoweron ? 'true' : null
|
||||
})
|
||||
autoPoweron: autoPoweron ? 'true' : null,
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
async setSrProperties (id, {
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
}) {
|
||||
await this._setObjectProperties(this.getObject(id), {
|
||||
nameLabel,
|
||||
nameDescription
|
||||
nameDescription,
|
||||
})
|
||||
}
|
||||
|
||||
async setNetworkProperties (id, {
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
defaultIsLocked
|
||||
defaultIsLocked,
|
||||
}) {
|
||||
let defaultLockingMode
|
||||
if (defaultIsLocked != null) {
|
||||
@ -314,7 +314,7 @@ export default class Xapi extends XapiBase {
|
||||
await this._setObjectProperties(this.getObject(id), {
|
||||
nameLabel,
|
||||
nameDescription,
|
||||
defaultLockingMode
|
||||
defaultLockingMode,
|
||||
})
|
||||
}
|
||||
|
||||
@ -323,7 +323,7 @@ export default class Xapi extends XapiBase {
|
||||
async addTag (id, tag) {
|
||||
const {
|
||||
$ref: ref,
|
||||
$type: type
|
||||
$type: type,
|
||||
} = this.getObject(id)
|
||||
|
||||
const namespace = getNamespaceForType(type)
|
||||
@ -333,7 +333,7 @@ export default class Xapi extends XapiBase {
|
||||
async removeTag (id, tag) {
|
||||
const {
|
||||
$ref: ref,
|
||||
$type: type
|
||||
$type: type,
|
||||
} = this.getObject(id)
|
||||
|
||||
const namespace = getNamespaceForType(type)
|
||||
@ -344,7 +344,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
async setDefaultSr (srId) {
|
||||
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, {
|
||||
nameLabel = undefined,
|
||||
fast = true
|
||||
fast = true,
|
||||
} = {}) {
|
||||
const vm = this.getObject(vmId)
|
||||
|
||||
@ -504,7 +504,7 @@ export default class Xapi extends XapiBase {
|
||||
}
|
||||
|
||||
async copyVm (vmId, srId, {
|
||||
nameLabel = undefined
|
||||
nameLabel = undefined,
|
||||
} = {}) {
|
||||
return /* await */ this._getOrWaitObject(
|
||||
await this._copyVm(
|
||||
@ -517,19 +517,19 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
async remoteCopyVm (vmId, targetXapi, targetSrId, {
|
||||
compress = true,
|
||||
nameLabel = undefined
|
||||
nameLabel = undefined,
|
||||
} = {}) {
|
||||
// Fall back on local copy if possible.
|
||||
if (targetXapi === this) {
|
||||
return {
|
||||
vm: await this.copyVm(vmId, targetSrId, { nameLabel })
|
||||
vm: await this.copyVm(vmId, targetSrId, { nameLabel }),
|
||||
}
|
||||
}
|
||||
|
||||
const sr = targetXapi.getObject(targetSrId)
|
||||
let stream = await this.exportVm(vmId, {
|
||||
compress,
|
||||
onlyMetadata: false
|
||||
onlyMetadata: false,
|
||||
})
|
||||
|
||||
const sizeStream = createSizeStream()
|
||||
@ -537,7 +537,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
const onVmCreation = nameLabel !== undefined
|
||||
? vm => targetXapi._setObjectProperties(vm, {
|
||||
nameLabel
|
||||
nameLabel,
|
||||
})
|
||||
: null
|
||||
|
||||
@ -552,7 +552,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
return {
|
||||
size: sizeStream.size,
|
||||
vm
|
||||
vm,
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,7 +600,7 @@ export default class Xapi extends XapiBase {
|
||||
VCPUs_max,
|
||||
VCPUs_params,
|
||||
version,
|
||||
xenstore_data
|
||||
xenstore_data,
|
||||
}) {
|
||||
debug(`Creating VM ${name_label}`)
|
||||
|
||||
@ -647,7 +647,7 @@ export default class Xapi extends XapiBase {
|
||||
start_delay: asInteger(start_delay),
|
||||
tags,
|
||||
version: asInteger(version),
|
||||
xenstore_data
|
||||
xenstore_data,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -699,7 +699,7 @@ export default class Xapi extends XapiBase {
|
||||
: onFailure(vdi)
|
||||
}
|
||||
return test()
|
||||
})::ignoreErrors()
|
||||
})::ignoreErrors(),
|
||||
])
|
||||
}
|
||||
|
||||
@ -724,7 +724,7 @@ export default class Xapi extends XapiBase {
|
||||
// Returns a stream to the exported VM.
|
||||
async exportVm (vmId, {
|
||||
compress = true,
|
||||
onlyMetadata = false
|
||||
onlyMetadata = false,
|
||||
} = {}) {
|
||||
const vm = this.getObject(vmId)
|
||||
|
||||
@ -740,9 +740,9 @@ export default class Xapi extends XapiBase {
|
||||
host,
|
||||
query: {
|
||||
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) {
|
||||
@ -800,7 +800,7 @@ export default class Xapi extends XapiBase {
|
||||
fullVdisRequired = [],
|
||||
|
||||
disableBaseTags = false,
|
||||
snapshotNameLabel = undefined
|
||||
snapshotNameLabel = undefined,
|
||||
} = {}) {
|
||||
if (!bypassVdiChainsCheck) {
|
||||
this._assertHealthyVdiChains(this.getObject(vmId))
|
||||
@ -810,7 +810,7 @@ export default class Xapi extends XapiBase {
|
||||
$onFailure(() => this._deleteVm(vm))
|
||||
if (snapshotNameLabel) {
|
||||
this._setObjectProperties(vm, {
|
||||
nameLabel: snapshotNameLabel
|
||||
nameLabel: snapshotNameLabel,
|
||||
})::ignoreErrors()
|
||||
}
|
||||
|
||||
@ -869,13 +869,13 @@ export default class Xapi extends XapiBase {
|
||||
...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,
|
||||
$SR$uuid: vdi.$SR.uuid
|
||||
$SR$uuid: vdi.$SR.uuid,
|
||||
}
|
||||
const stream = streams[`${vdiRef}.vhd`] = this._exportVdi($cancelToken, vdi, baseVdi, VDI_FORMAT_VHD)
|
||||
$onFailure(stream.cancel)
|
||||
@ -885,7 +885,7 @@ export default class Xapi extends XapiBase {
|
||||
forEach(vm.$VIFs, vif => {
|
||||
vifs[vif.$ref] = {
|
||||
...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
|
||||
? {
|
||||
...vm.other_config,
|
||||
[TAG_BASE_DELTA]: baseVm.uuid
|
||||
}
|
||||
: omit(vm.other_config, TAG_BASE_DELTA)
|
||||
[TAG_BASE_DELTA]: baseVm.uuid,
|
||||
}
|
||||
: omit(vm.other_config, TAG_BASE_DELTA),
|
||||
},
|
||||
}, 'streams', {
|
||||
value: await streams::pAll()
|
||||
value: await streams::pAll(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -914,7 +914,7 @@ export default class Xapi extends XapiBase {
|
||||
disableStartAfterImport = true,
|
||||
mapVdisSrs = {},
|
||||
name_label = delta.vm.name_label,
|
||||
srId = this.pool.default_SR
|
||||
srId = this.pool.default_SR,
|
||||
} = {}) {
|
||||
const { version } = delta
|
||||
|
||||
@ -947,21 +947,21 @@ export default class Xapi extends XapiBase {
|
||||
await this._createVmRecord({
|
||||
...delta.vm,
|
||||
affinity: null,
|
||||
is_a_template: false
|
||||
is_a_template: false,
|
||||
})
|
||||
)
|
||||
$onFailure(() => this._deleteVm(vm))
|
||||
|
||||
await Promise.all([
|
||||
this._setObjectProperties(vm, {
|
||||
name_label: `[Importing…] ${name_label}`
|
||||
name_label: `[Importing…] ${name_label}`,
|
||||
}),
|
||||
this._updateObjectMapProperty(vm, 'blocked_operations', {
|
||||
start: 'Importing…'
|
||||
start: 'Importing…',
|
||||
}),
|
||||
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.
|
||||
@ -979,9 +979,9 @@ export default class Xapi extends XapiBase {
|
||||
other_config: {
|
||||
...vdi.other_config,
|
||||
[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))
|
||||
|
||||
@ -1002,7 +1002,7 @@ export default class Xapi extends XapiBase {
|
||||
$onFailure(() => this._deleteVdi(newVdi))
|
||||
|
||||
await this._updateObjectMapProperty(newVdi, 'other_config', {
|
||||
[TAG_COPY_SRC]: vdi.uuid
|
||||
[TAG_COPY_SRC]: vdi.uuid,
|
||||
})
|
||||
|
||||
return newVdi
|
||||
@ -1051,7 +1051,7 @@ export default class Xapi extends XapiBase {
|
||||
vif
|
||||
)
|
||||
}
|
||||
})
|
||||
}),
|
||||
])
|
||||
|
||||
if (deleteBase && baseVm) {
|
||||
@ -1060,14 +1060,14 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
await Promise.all([
|
||||
this._setObjectProperties(vm, {
|
||||
name_label
|
||||
name_label,
|
||||
}),
|
||||
// FIXME: move
|
||||
this._updateObjectMapProperty(vm, 'blocked_operations', {
|
||||
start: disableStartAfterImport
|
||||
? 'Do not start this VM, clone it if you want to use it.'
|
||||
: null
|
||||
})
|
||||
: null,
|
||||
}),
|
||||
])
|
||||
|
||||
return vm
|
||||
@ -1077,7 +1077,7 @@ export default class Xapi extends XapiBase {
|
||||
migrationNetwork = find(host.$PIFs, pif => pif.management).$network, // TODO: handle not found
|
||||
sr,
|
||||
mapVdisSrs,
|
||||
mapVifsNetworks
|
||||
mapVifsNetworks,
|
||||
}) {
|
||||
// VDIs/SRs mapping
|
||||
const vdis = {}
|
||||
@ -1094,7 +1094,7 @@ export default class Xapi extends XapiBase {
|
||||
}
|
||||
|
||||
// VIFs/Networks mapping
|
||||
let vifsMap = {}
|
||||
const vifsMap = {}
|
||||
if (vm.$pool !== host.$pool) {
|
||||
const defaultNetworkRef = find(host.$PIFs, pif => pif.management).$network.$ref
|
||||
for (const vif of vm.$VIFs) {
|
||||
@ -1119,7 +1119,7 @@ export default class Xapi extends XapiBase {
|
||||
vdis,
|
||||
vifsMap,
|
||||
{
|
||||
force: 'true'
|
||||
force: 'true',
|
||||
}
|
||||
)::pCatch(
|
||||
{ code: 'TOO_MANY_STORAGE_MIGRATES' },
|
||||
@ -1202,7 +1202,7 @@ export default class Xapi extends XapiBase {
|
||||
async _importVm (stream, sr, onlyMetadata = false, onVmCreation = undefined) {
|
||||
const taskRef = await this.createTask('VM import')
|
||||
const query = {
|
||||
force: onlyMetadata
|
||||
force: onlyMetadata,
|
||||
}
|
||||
|
||||
let host
|
||||
@ -1223,7 +1223,7 @@ export default class Xapi extends XapiBase {
|
||||
{
|
||||
host,
|
||||
query,
|
||||
task: taskRef
|
||||
task: taskRef,
|
||||
}
|
||||
).then(extractOpaqueRef)
|
||||
|
||||
@ -1245,7 +1245,7 @@ export default class Xapi extends XapiBase {
|
||||
memory,
|
||||
nameLabel,
|
||||
networks,
|
||||
nCpus
|
||||
nCpus,
|
||||
}, sr) {
|
||||
// 1. Create VM.
|
||||
const vm = await this._getOrWaitObject(
|
||||
@ -1257,14 +1257,14 @@ export default class Xapi extends XapiBase {
|
||||
name_description: descriptionLabel,
|
||||
name_label: nameLabel,
|
||||
VCPUs_at_startup: nCpus,
|
||||
VCPUs_max: nCpus
|
||||
VCPUs_max: nCpus,
|
||||
})
|
||||
)
|
||||
$onFailure(() => this._deleteVm(vm))
|
||||
// Disable start and change the VM name label during import.
|
||||
await Promise.all([
|
||||
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.
|
||||
@ -1275,14 +1275,14 @@ export default class Xapi extends XapiBase {
|
||||
const vdi = vdis[disk.path] = await this.createVdi(disk.capacity, {
|
||||
name_description: disk.descriptionLabel,
|
||||
name_label: disk.nameLabel,
|
||||
sr: sr.$ref
|
||||
sr: sr.$ref,
|
||||
})
|
||||
$onFailure(() => this._deleteVdi(vdi))
|
||||
|
||||
return this._createVbd(vm, vdi, { position: disk.position })
|
||||
}).concat(map(networks, (networkId, i) => (
|
||||
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.
|
||||
await Promise.all([
|
||||
this.removeForbiddenOperationFromVm(vm.$id, 'start'),
|
||||
this._setObjectProperties(vm, { name_label: nameLabel })
|
||||
this._setObjectProperties(vm, { name_label: nameLabel }),
|
||||
])
|
||||
return vm
|
||||
}
|
||||
@ -1327,7 +1327,7 @@ export default class Xapi extends XapiBase {
|
||||
data,
|
||||
onlyMetadata = false,
|
||||
srId,
|
||||
type = 'xva'
|
||||
type = 'xva',
|
||||
} = {}) {
|
||||
const sr = srId && this.getObject(srId)
|
||||
|
||||
@ -1350,7 +1350,7 @@ export default class Xapi extends XapiBase {
|
||||
sr,
|
||||
migrationNetworkId,
|
||||
mapVifsNetworks,
|
||||
mapVdisSrs
|
||||
mapVdisSrs,
|
||||
} = {}) {
|
||||
const vm = this.getObject(vmId)
|
||||
const host = hostXapi.getObject(hostId)
|
||||
@ -1369,7 +1369,7 @@ export default class Xapi extends XapiBase {
|
||||
migrationNetwork: migrationNetworkId && hostXapi.getObject(migrationNetworkId),
|
||||
sr,
|
||||
mapVdisSrs,
|
||||
mapVifsNetworks
|
||||
mapVifsNetworks,
|
||||
})
|
||||
} else {
|
||||
try {
|
||||
@ -1418,7 +1418,7 @@ export default class Xapi extends XapiBase {
|
||||
// to-date object.
|
||||
const [ , snapshot ] = await Promise.all([
|
||||
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
|
||||
@ -1442,7 +1442,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
if (force) {
|
||||
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
|
||||
|
||||
await this._updateObjectMapProperty(vm, 'HVM_boot_params', {
|
||||
order: 'd'
|
||||
order: 'd',
|
||||
})
|
||||
|
||||
try {
|
||||
await this._startVm(vm)
|
||||
} finally {
|
||||
await this._updateObjectMapProperty(vm, 'HVM_boot_params', {
|
||||
order
|
||||
order,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@ -1502,7 +1502,7 @@ export default class Xapi extends XapiBase {
|
||||
forEach(vm.$VBDs, vbd => {
|
||||
promises.push(
|
||||
this._setObjectProperties(vbd, {
|
||||
bootable: vbd === cdDrive
|
||||
bootable: vbd === cdDrive,
|
||||
})
|
||||
)
|
||||
|
||||
@ -1511,11 +1511,11 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
promises.push(
|
||||
this._setObjectProperties(vm, {
|
||||
PV_bootloader: 'eliloader'
|
||||
PV_bootloader: 'eliloader',
|
||||
}),
|
||||
this._updateObjectMapProperty(vm, 'other_config', {
|
||||
'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)
|
||||
} finally {
|
||||
this._setObjectProperties(vm, {
|
||||
PV_bootloader: bootloader
|
||||
PV_bootloader: bootloader,
|
||||
})::ignoreErrors()
|
||||
|
||||
forEach(bootables, ([ vbd, bootable ]) => {
|
||||
@ -1555,7 +1555,7 @@ export default class Xapi extends XapiBase {
|
||||
mode = (type === 'Disk') ? 'RW' : 'RO',
|
||||
position = userdevice,
|
||||
|
||||
readOnly = (mode === 'RO')
|
||||
readOnly = (mode === 'RO'),
|
||||
} = {}) {
|
||||
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),
|
||||
userdevice: String(position),
|
||||
VDI: vdi.$ref,
|
||||
VM: vm.$ref
|
||||
VM: vm.$ref,
|
||||
})
|
||||
|
||||
if (isVmRunning(vm)) {
|
||||
@ -1621,7 +1621,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
tags = [],
|
||||
type = 'user',
|
||||
xenstore_data = undefined
|
||||
xenstore_data = undefined,
|
||||
} = {}) {
|
||||
if (sr === NULL_REF) {
|
||||
throw new Error('SR required to create VDI')
|
||||
@ -1642,7 +1642,7 @@ export default class Xapi extends XapiBase {
|
||||
tags,
|
||||
type,
|
||||
virtual_size: String(size),
|
||||
SR: sr.$ref
|
||||
SR: sr.$ref,
|
||||
}
|
||||
|
||||
if (xenstore_data) {
|
||||
@ -1677,7 +1677,7 @@ export default class Xapi extends XapiBase {
|
||||
bootable: vbd.bootable,
|
||||
position: vbd.userdevice,
|
||||
type: vbd.type,
|
||||
readOnly: vbd.mode === 'RO'
|
||||
readOnly: vbd.mode === 'RO',
|
||||
})
|
||||
// Remove the old VDI
|
||||
await this._deleteVdi(vdi)
|
||||
@ -1722,7 +1722,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
async _insertCdIntoVm (cd, vm, {
|
||||
bootable = false,
|
||||
force = false
|
||||
force = false,
|
||||
} = {}) {
|
||||
const cdDrive = await this._getVmCdDrive(vm)
|
||||
if (cdDrive) {
|
||||
@ -1745,7 +1745,7 @@ export default class Xapi extends XapiBase {
|
||||
} else {
|
||||
await this._createVbd(vm, cd, {
|
||||
bootable,
|
||||
type: 'CD'
|
||||
type: 'CD',
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1845,7 +1845,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
const query = {
|
||||
format,
|
||||
vdi: vdi.$ref
|
||||
vdi: vdi.$ref,
|
||||
}
|
||||
if (base) {
|
||||
query.base = base.$ref
|
||||
@ -1859,14 +1859,14 @@ export default class Xapi extends XapiBase {
|
||||
return this.getResource($cancelToken, '/export_raw_vdi/', {
|
||||
host,
|
||||
query,
|
||||
task: this.createTask('VDI Export', vdi.name_label)
|
||||
task: this.createTask('VDI Export', vdi.name_label),
|
||||
})
|
||||
}
|
||||
|
||||
// Returns a stream to the exported VDI.
|
||||
exportVdi (vdiId, {
|
||||
baseId,
|
||||
format
|
||||
format,
|
||||
} = {}) {
|
||||
return this._exportVdi(
|
||||
this.getObject(vdiId),
|
||||
@ -1890,15 +1890,15 @@ export default class Xapi extends XapiBase {
|
||||
host: pbd.host,
|
||||
query: {
|
||||
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, {
|
||||
format
|
||||
format,
|
||||
} = {}) {
|
||||
return this._importVdiContent(
|
||||
this.getObject(vdiId),
|
||||
@ -1921,7 +1921,7 @@ export default class Xapi extends XapiBase {
|
||||
MAC = mac,
|
||||
other_config = {},
|
||||
qos_algorithm_params = {},
|
||||
qos_algorithm_type = ''
|
||||
qos_algorithm_type = '',
|
||||
} = {}) {
|
||||
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,
|
||||
qos_algorithm_params,
|
||||
qos_algorithm_type,
|
||||
VM: vm.$ref
|
||||
VM: vm.$ref,
|
||||
}))
|
||||
|
||||
if (currently_attached && isVmRunning(vm)) {
|
||||
@ -1965,13 +1965,13 @@ export default class Xapi extends XapiBase {
|
||||
description = 'Created with Xen Orchestra',
|
||||
pifId,
|
||||
mtu,
|
||||
vlan
|
||||
vlan,
|
||||
}) {
|
||||
const networkRef = await this.call('network.create', {
|
||||
name_label: name,
|
||||
name_description: description,
|
||||
MTU: asInteger(mtu),
|
||||
other_config: {}
|
||||
other_config: {},
|
||||
})
|
||||
$onFailure(() => this.call('network.destroy', networkRef))
|
||||
if (pifId) {
|
||||
@ -2059,7 +2059,7 @@ export default class Xapi extends XapiBase {
|
||||
|
||||
return /* await */ this.call('host.call_plugin', host.$ref, 'xscontainer', action, {
|
||||
vmuuid: vm.uuid,
|
||||
container: containerId
|
||||
container: containerId,
|
||||
})
|
||||
}
|
||||
|
||||
@ -2095,8 +2095,8 @@ export default class Xapi extends XapiBase {
|
||||
const template = this.getObject(templateId)
|
||||
const host = this.pool.$master
|
||||
|
||||
let config = await this.call('host.call_plugin', host.$ref, 'xscontainer', 'get_config_drive_default', {
|
||||
templateuuid: template.uuid
|
||||
const config = await this.call('host.call_plugin', host.$ref, 'xscontainer', 'get_config_drive_default', {
|
||||
templateuuid: template.uuid,
|
||||
})
|
||||
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', {
|
||||
vmuuid: vm.uuid,
|
||||
sruuid: sr.uuid,
|
||||
configuration: config
|
||||
configuration: config,
|
||||
})
|
||||
await this.registerDockerContainer(vmId)
|
||||
}
|
||||
@ -2136,7 +2136,7 @@ export default class Xapi extends XapiBase {
|
||||
'openstack/latest/meta_data.json',
|
||||
'{\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
|
||||
@ -2151,7 +2151,7 @@ export default class Xapi extends XapiBase {
|
||||
const vdi = await this.createVdi(stream.length, {
|
||||
sr: sr.$ref,
|
||||
name_label,
|
||||
name_description
|
||||
name_description,
|
||||
})
|
||||
$onFailure(() => this._deleteVdi(vdi))
|
||||
|
||||
|
@ -5,5 +5,5 @@ export default {
|
||||
},
|
||||
deleteVgpu (vgpu) {
|
||||
return this.call('VGPU.destroy', this.getObject(vgpu).$ref)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ export default {
|
||||
if (lockingMode !== vif.locking_mode) {
|
||||
return this._set('locking_mode', lockingMode)
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
ipv6Allowed: {
|
||||
get: true,
|
||||
@ -53,8 +53,8 @@ export default {
|
||||
if (lockingMode !== vif.locking_mode) {
|
||||
return this._set('locking_mode', lockingMode)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
@ -16,13 +16,13 @@ import {
|
||||
forEach,
|
||||
mapFilter,
|
||||
mapToArray,
|
||||
parseXml
|
||||
parseXml,
|
||||
} from '../../utils'
|
||||
|
||||
import {
|
||||
debug,
|
||||
extractOpaqueRef,
|
||||
useUpdateSystem
|
||||
useUpdateSystem,
|
||||
} from '../utils'
|
||||
|
||||
export default {
|
||||
@ -55,7 +55,7 @@ export default {
|
||||
requirements: mapToArray(ensureArray(patch.requiredpatches), patch => {
|
||||
return patch.requiredpatch.uuid
|
||||
}),
|
||||
paid: patch['update-stream'] === 'premium'
|
||||
paid: patch['update-stream'] === 'premium',
|
||||
// TODO: what does it mean, should we handle it?
|
||||
// version: patch.version,
|
||||
}
|
||||
@ -85,7 +85,7 @@ export default {
|
||||
name: version.name,
|
||||
id: version.value,
|
||||
documentationUrl: version.url,
|
||||
patches: resolveVersionPatches(version.patch)
|
||||
patches: resolveVersionPatches(version.patch),
|
||||
}
|
||||
|
||||
if (version.latest) {
|
||||
@ -96,7 +96,7 @@ export default {
|
||||
return {
|
||||
patches,
|
||||
latestVersion,
|
||||
versions
|
||||
versions,
|
||||
}
|
||||
},
|
||||
|
||||
@ -219,7 +219,7 @@ export default {
|
||||
stream,
|
||||
'/pool_patch_upload',
|
||||
{
|
||||
task: this.createTask('Patch upload', patchName)
|
||||
task: this.createTask('Patch upload', patchName),
|
||||
}
|
||||
).then(extractOpaqueRef)
|
||||
|
||||
@ -303,7 +303,7 @@ export default {
|
||||
_installPatchUpdateOnHost: deferrable(async function ($defer, patchUuid, host) {
|
||||
const [ vdi ] = await Promise.all([
|
||||
this._getUpdateVdi($defer, patchUuid, host.$id),
|
||||
this._ejectToolsIsos(host.$ref)
|
||||
this._ejectToolsIsos(host.$ref),
|
||||
])
|
||||
|
||||
const updateRef = await this.call('pool_update.introduce', vdi.$ref)
|
||||
@ -334,7 +334,7 @@ export default {
|
||||
async _installPoolPatchOnAllHosts (patchUuid) {
|
||||
const [ patch ] = await Promise.all([
|
||||
this._getOrUploadPoolPatch(patchUuid),
|
||||
this._ejectToolsIsos()
|
||||
this._ejectToolsIsos(),
|
||||
])
|
||||
|
||||
await this.call('pool_patch.pool_apply', patch.$ref)
|
||||
@ -344,7 +344,7 @@ export default {
|
||||
_installPatchUpdateOnAllHosts: deferrable(async function ($defer, patchUuid) {
|
||||
let [ vdi ] = await Promise.all([
|
||||
this._getUpdateVdi($defer, patchUuid),
|
||||
this._ejectToolsIsos()
|
||||
this._ejectToolsIsos(),
|
||||
])
|
||||
if (vdi == null) {
|
||||
vdi = await this._getUpdateVdi($defer, patchUuid, this.pool.master)
|
||||
@ -473,5 +473,5 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
forEach,
|
||||
groupBy
|
||||
groupBy,
|
||||
} from 'lodash'
|
||||
|
||||
import {
|
||||
createRawObject,
|
||||
mapToArray
|
||||
mapToArray,
|
||||
} from '../../utils'
|
||||
|
||||
export default {
|
||||
@ -92,5 +92,5 @@ export default {
|
||||
}
|
||||
})
|
||||
return unhealthyVdis
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -5,20 +5,20 @@ import {
|
||||
gte,
|
||||
includes,
|
||||
isEmpty,
|
||||
lte
|
||||
lte,
|
||||
} from 'lodash'
|
||||
|
||||
import {
|
||||
forEach,
|
||||
mapToArray,
|
||||
parseSize
|
||||
parseSize,
|
||||
} from '../../utils'
|
||||
|
||||
import {
|
||||
isVmHvm,
|
||||
isVmRunning,
|
||||
makeEditObject,
|
||||
NULL_REF
|
||||
NULL_REF,
|
||||
} from '../utils'
|
||||
|
||||
// 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.
|
||||
@deferrable.onFailure
|
||||
async createVm ($onFailure, templateId, {
|
||||
name_label, // deprecated
|
||||
name_label, // eslint-disable-line camelcase
|
||||
nameLabel = name_label, // eslint-disable-line camelcase
|
||||
|
||||
clone = true,
|
||||
@ -94,7 +94,7 @@ export default {
|
||||
}
|
||||
|
||||
this._setObjectProperties(vm, {
|
||||
HVM_boot_params: { ...bootParams, order }
|
||||
HVM_boot_params: { ...bootParams, order },
|
||||
})
|
||||
}
|
||||
} else { // PV
|
||||
@ -103,11 +103,11 @@ export default {
|
||||
// TODO: normalize RHEL URL?
|
||||
|
||||
await this._updateObjectMapProperty(vm, 'other_config', {
|
||||
'install-repository': installRepository
|
||||
'install-repository': installRepository,
|
||||
})
|
||||
} else if (installMethod === 'cd') {
|
||||
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
|
||||
// bootable and the first disk bootable.
|
||||
await this._insertCdIntoVm(installRepository, vm, {
|
||||
bootable: true
|
||||
bootable: true,
|
||||
})
|
||||
hasBootableDisk = true
|
||||
}
|
||||
@ -158,14 +158,14 @@ export default {
|
||||
{
|
||||
name_label: vdiDescription.name_label,
|
||||
name_description: vdiDescription.name_description,
|
||||
sr: vdiDescription.sr || vdiDescription.SR
|
||||
sr: vdiDescription.sr || vdiDescription.SR,
|
||||
}
|
||||
)
|
||||
.then(ref => this._getOrWaitObject(ref))
|
||||
.then(vdi => this._createVbd(vm, vdi, {
|
||||
// Either the CD or the 1st disk is bootable (only useful for PV VMs)
|
||||
bootable: !(hasBootableDisk || i),
|
||||
userdevice: devices[i]
|
||||
userdevice: devices[i],
|
||||
}))
|
||||
))
|
||||
}
|
||||
@ -185,7 +185,7 @@ export default {
|
||||
device: devices[index],
|
||||
locking_mode: isEmpty(vif.ipv4_allowed) && isEmpty(vif.ipv6_allowed) ? 'network_default' : 'locked',
|
||||
mac: vif.mac,
|
||||
mtu: vif.mtu
|
||||
mtu: vif.mtu,
|
||||
}
|
||||
)))
|
||||
}
|
||||
@ -234,26 +234,26 @@ export default {
|
||||
'affinity',
|
||||
value ? this.getObject(value).$ref : NULL_REF
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
autoPoweron: {
|
||||
set (value, vm) {
|
||||
return Promise.all([
|
||||
this._updateObjectMapProperty(vm, 'other_config', {
|
||||
autoPoweron: value ? 'true' : null
|
||||
autoPoweron: value ? 'true' : null,
|
||||
}),
|
||||
value && this.setPoolProperties({
|
||||
autoPoweron: true
|
||||
})
|
||||
autoPoweron: true,
|
||||
}),
|
||||
])
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
coresPerSocket: {
|
||||
set (coresPerSocket, vm) {
|
||||
return this._updateObjectMapProperty(vm, 'platform', {'cores-per-socket': coresPerSocket})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
CPUs: 'cpus',
|
||||
@ -265,7 +265,7 @@ export default {
|
||||
// If the other value is not set and the constraint is not
|
||||
// respected, the other value is changed first.
|
||||
constraints: {
|
||||
cpusStaticMax: gte
|
||||
cpusStaticMax: gte,
|
||||
},
|
||||
|
||||
get: vm => +vm.VCPUs_at_startup,
|
||||
@ -273,46 +273,46 @@ export default {
|
||||
'VCPUs_at_startup',
|
||||
function (value, vm) {
|
||||
return isVmRunning(vm) && this._set('VCPUs_number_live', value)
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
cpuCap: {
|
||||
get: vm => vm.VCPUs_params.cap && +vm.VCPUs_params.cap,
|
||||
set (cap, vm) {
|
||||
return this._updateObjectMapProperty(vm, 'VCPUs_params', { cap })
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
cpusMax: 'cpusStaticMax',
|
||||
cpusStaticMax: {
|
||||
constraints: {
|
||||
cpus: lte
|
||||
cpus: lte,
|
||||
},
|
||||
get: vm => +vm.VCPUs_max,
|
||||
set: 'VCPUs_max'
|
||||
set: 'VCPUs_max',
|
||||
},
|
||||
|
||||
cpuWeight: {
|
||||
get: vm => vm.VCPUs_params.weight && +vm.VCPUs_params.weight,
|
||||
set (weight, vm) {
|
||||
return this._updateObjectMapProperty(vm, 'VCPUs_params', { weight })
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
highAvailability: {
|
||||
set (ha, vm) {
|
||||
return this.call('VM.set_ha_restart_priority', vm.$ref, ha ? 'restart' : '')
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
memoryMin: {
|
||||
constraints: {
|
||||
memoryMax: gte
|
||||
memoryMax: gte,
|
||||
},
|
||||
get: vm => +vm.memory_dynamic_min,
|
||||
preprocess: parseSize,
|
||||
set: 'memory_dynamic_min'
|
||||
set: 'memory_dynamic_min',
|
||||
},
|
||||
|
||||
memory: 'memoryMax',
|
||||
@ -321,20 +321,20 @@ export default {
|
||||
limitName: 'memory',
|
||||
constraints: {
|
||||
memoryMin: lte,
|
||||
memoryStaticMax: gte
|
||||
memoryStaticMax: gte,
|
||||
},
|
||||
get: vm => +vm.memory_dynamic_max,
|
||||
preprocess: parseSize,
|
||||
set: 'memory_dynamic_max'
|
||||
set: 'memory_dynamic_max',
|
||||
},
|
||||
|
||||
memoryStaticMax: {
|
||||
constraints: {
|
||||
memoryMax: lte
|
||||
memoryMax: lte,
|
||||
},
|
||||
get: vm => +vm.memory_static_max,
|
||||
preprocess: parseSize,
|
||||
set: 'memory_static_max'
|
||||
set: 'memory_static_max',
|
||||
},
|
||||
|
||||
nameDescription: true,
|
||||
@ -351,7 +351,7 @@ export default {
|
||||
throw new Error(`The different values that the VGA can take are: ${XEN_VGA_VALUES}`)
|
||||
}
|
||||
return this._updateObjectMapProperty(vm, 'platform', { vga })
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
videoram: {
|
||||
@ -360,8 +360,8 @@ export default {
|
||||
throw new Error(`The different values that the video RAM can take are: ${XEN_VIDEORAM_VALUES}`)
|
||||
}
|
||||
return this._updateObjectMapProperty(vm, 'platform', { videoram })
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
async editVm (id, props, checkLimits) {
|
||||
@ -387,5 +387,5 @@ export default {
|
||||
async resumeVm (vmId) {
|
||||
// the force parameter is always true
|
||||
return this.call('VM.resume', this.getObject(vmId).$ref, false, true)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ const OTHER_CONFIG_TEMPLATE = {
|
||||
blocked_operations: {},
|
||||
ha_always_run: false,
|
||||
HVM_boot_params: {
|
||||
order: 'cdn'
|
||||
order: 'cdn',
|
||||
},
|
||||
HVM_boot_policy: 'BIOS order',
|
||||
HVM_shadow_multiplier: 1,
|
||||
@ -22,7 +22,7 @@ const OTHER_CONFIG_TEMPLATE = {
|
||||
vgpu_pci: '',
|
||||
base_template_name: 'Other install media',
|
||||
mac_seed: '5e88eb6a-d680-c47f-a94a-028886971ba4',
|
||||
'install-methods': 'cdrom'
|
||||
'install-methods': 'cdrom',
|
||||
},
|
||||
PCI_bus: '',
|
||||
platform: {
|
||||
@ -32,7 +32,7 @@ const OTHER_CONFIG_TEMPLATE = {
|
||||
apic: 'true',
|
||||
pae: 'true',
|
||||
hpet: 'true',
|
||||
viridian: 'true'
|
||||
viridian: 'true',
|
||||
},
|
||||
protection_policy: NULL_REF,
|
||||
PV_args: '',
|
||||
@ -48,6 +48,6 @@ const OTHER_CONFIG_TEMPLATE = {
|
||||
VCPUs_at_startup: 1,
|
||||
VCPUs_max: 1,
|
||||
VCPUs_params: {},
|
||||
version: 0
|
||||
version: 0,
|
||||
}
|
||||
export { OTHER_CONFIG_TEMPLATE as default }
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
map,
|
||||
mapFilter,
|
||||
mapToArray,
|
||||
noop
|
||||
noop,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -102,7 +102,7 @@ forEach([
|
||||
'VM_guest_metrics',
|
||||
'VM_metrics',
|
||||
'VMPP',
|
||||
'VTPM'
|
||||
'VTPM',
|
||||
], 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 = {
|
||||
Running: true,
|
||||
Paused: true
|
||||
Paused: true,
|
||||
}
|
||||
export const isVmRunning = vm => VM_RUNNING_POWER_STATES[vm.power_state]
|
||||
|
||||
@ -226,7 +226,7 @@ export const makeEditObject = specs => {
|
||||
if (spec === true) {
|
||||
spec = {
|
||||
get: true,
|
||||
set: true
|
||||
set: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ export const makeEditObject = specs => {
|
||||
// Context used to execute functions.
|
||||
const context = {
|
||||
__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) => {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import checkAuthorization from 'xo-acl-resolver'
|
||||
|
||||
import {
|
||||
ModelAlreadyExists
|
||||
ModelAlreadyExists,
|
||||
} from '../collection'
|
||||
import {
|
||||
Acls
|
||||
Acls,
|
||||
} from '../models/acl'
|
||||
import {
|
||||
createRawObject,
|
||||
forEach,
|
||||
includes,
|
||||
mapToArray
|
||||
mapToArray,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -22,7 +22,7 @@ export default class {
|
||||
const aclsDb = this._acls = new Acls({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:acl',
|
||||
indexes: ['subject', 'object']
|
||||
indexes: ['subject', 'object'],
|
||||
})
|
||||
|
||||
xo.on('start', () => {
|
||||
@ -93,10 +93,10 @@ export default class {
|
||||
async getPermissionsForUser (userId) {
|
||||
const [
|
||||
acls,
|
||||
permissionsByRole
|
||||
permissionsByRole,
|
||||
] = await Promise.all([
|
||||
this._getAclsForUser(userId),
|
||||
this._getPermissionsByRole()
|
||||
this._getPermissionsByRole(),
|
||||
])
|
||||
|
||||
const permissions = createRawObject()
|
||||
@ -152,16 +152,16 @@ export default class {
|
||||
id: 'viewer',
|
||||
name: 'Viewer',
|
||||
permissions: [
|
||||
'view'
|
||||
]
|
||||
'view',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'operator',
|
||||
name: 'Operator',
|
||||
permissions: [
|
||||
'view',
|
||||
'operate'
|
||||
]
|
||||
'operate',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'admin',
|
||||
@ -169,9 +169,9 @@ export default class {
|
||||
permissions: [
|
||||
'view',
|
||||
'operate',
|
||||
'administrate'
|
||||
]
|
||||
}
|
||||
'administrate',
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -7,17 +7,17 @@ import {
|
||||
isArray,
|
||||
isFunction,
|
||||
map,
|
||||
mapValues
|
||||
mapValues,
|
||||
} from 'lodash'
|
||||
|
||||
import * as methods from '../api'
|
||||
import * as methods from '../api' // eslint-disable-line node/no-missing-import
|
||||
import {
|
||||
MethodNotFound
|
||||
MethodNotFound,
|
||||
} from 'json-rpc-peer'
|
||||
import {
|
||||
createRawObject,
|
||||
noop,
|
||||
serializeError
|
||||
serializeError,
|
||||
} from '../utils'
|
||||
|
||||
import * as errors from 'xo-common/api-errors'
|
||||
@ -30,7 +30,7 @@ const PERMISSIONS = {
|
||||
none: 0,
|
||||
read: 1,
|
||||
write: 2,
|
||||
admin: 3
|
||||
admin: 3,
|
||||
}
|
||||
|
||||
// TODO:
|
||||
@ -50,7 +50,7 @@ const XAPI_ERROR_TO_XO_ERROR = {
|
||||
VM_IS_TEMPLATE: errors.vmIsTemplate,
|
||||
VM_LACKS_FEATURE: ([ vm ], getId) => errors.vmLacksFeature({ vm: getId(vm) }),
|
||||
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) => (
|
||||
@ -65,7 +65,7 @@ function checkParams (method, params) {
|
||||
|
||||
const result = schemaInspector.validate({
|
||||
type: 'object',
|
||||
properties: schema
|
||||
properties: schema,
|
||||
}, params)
|
||||
|
||||
if (!result.valid) {
|
||||
@ -243,11 +243,11 @@ export default class Api {
|
||||
// XO methods called from the API.
|
||||
const context = Object.create(this._xo, {
|
||||
api: { // Used by system.*().
|
||||
value: this
|
||||
value: this,
|
||||
},
|
||||
session: {
|
||||
value: session
|
||||
}
|
||||
value: session,
|
||||
},
|
||||
})
|
||||
|
||||
// Fetch and inject the current user.
|
||||
@ -303,7 +303,7 @@ export default class Api {
|
||||
method: name,
|
||||
params: removeSensitiveParams(params),
|
||||
duration: Date.now() - startTime,
|
||||
error: serializeError(error)
|
||||
error: serializeError(error),
|
||||
}
|
||||
const message = `${userName} | ${name}(${JSON.stringify(params)}) [${ms(Date.now() - startTime)}] =!> ${error}`
|
||||
|
||||
|
@ -6,7 +6,7 @@ import Token, { Tokens } from '../models/token'
|
||||
import {
|
||||
createRawObject,
|
||||
forEach,
|
||||
generateToken
|
||||
generateToken,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -30,13 +30,13 @@ export default class {
|
||||
const tokensDb = this._tokens = new Tokens({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:token',
|
||||
indexes: ['user_id']
|
||||
indexes: ['user_id'],
|
||||
})
|
||||
|
||||
// Password authentication provider.
|
||||
this.registerAuthenticationProvider(async ({
|
||||
username,
|
||||
password
|
||||
password,
|
||||
}) => {
|
||||
if (username === undefined || password === undefined) {
|
||||
return
|
||||
@ -50,7 +50,7 @@ export default class {
|
||||
|
||||
// Token authentication provider.
|
||||
this.registerAuthenticationProvider(async ({
|
||||
token: tokenId
|
||||
token: tokenId,
|
||||
}) => {
|
||||
if (!tokenId) {
|
||||
return
|
||||
@ -154,7 +154,7 @@ export default class {
|
||||
|
||||
async createAuthenticationToken ({
|
||||
expiresIn = ONE_MONTH,
|
||||
userId
|
||||
userId,
|
||||
}) {
|
||||
const token = new Token({
|
||||
id: await generateToken(),
|
||||
@ -163,7 +163,7 @@ export default class {
|
||||
typeof expiresIn === 'string'
|
||||
? ms(expiresIn)
|
||||
: expiresIn
|
||||
)
|
||||
),
|
||||
})
|
||||
|
||||
await this._tokens.add(token)
|
||||
|
@ -10,7 +10,7 @@ import { satisfies as versionSatisfies } from 'semver'
|
||||
import { utcFormat } from 'd3-time-format'
|
||||
import {
|
||||
basename,
|
||||
dirname
|
||||
dirname,
|
||||
} from 'path'
|
||||
import {
|
||||
endsWith,
|
||||
@ -22,7 +22,7 @@ import {
|
||||
range,
|
||||
sortBy,
|
||||
startsWith,
|
||||
trim
|
||||
trim,
|
||||
} from 'lodash'
|
||||
|
||||
import createSizeStream from '../size-stream'
|
||||
@ -41,10 +41,10 @@ import {
|
||||
resolveSubpath,
|
||||
safeDateFormat,
|
||||
safeDateParse,
|
||||
tmpDir
|
||||
tmpDir,
|
||||
} from '../utils'
|
||||
import {
|
||||
VDI_FORMAT_VHD
|
||||
VDI_FORMAT_VHD,
|
||||
} from '../xapi'
|
||||
|
||||
// ===================================================================
|
||||
@ -76,7 +76,7 @@ const parseVmBackupPath = name => {
|
||||
id: name,
|
||||
name: baseMatches[3],
|
||||
tag: baseMatches[2],
|
||||
type: 'xva'
|
||||
type: 'xva',
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ const parseVmBackupPath = name => {
|
||||
name: baseMatches[2],
|
||||
tag: dirMatches[1],
|
||||
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
|
||||
0x05, 0x0F, 0x85, 0x15, 0x91, 0x9B, 0x5E, 0x5F, 0xCF, 0xD5, 0xC5,
|
||||
|
||||
0x82 // swap
|
||||
0x82, // swap
|
||||
], type => {
|
||||
IGNORED[type] = true
|
||||
})
|
||||
@ -147,7 +147,7 @@ const listPartitions = (() => {
|
||||
const TYPES = {
|
||||
0x7: 'NTFS',
|
||||
0x83: 'linux',
|
||||
0xc: 'FAT'
|
||||
0xc: 'FAT',
|
||||
}
|
||||
|
||||
const parseLine = createPairsParser({
|
||||
@ -158,14 +158,14 @@ const listPartitions = (() => {
|
||||
? +value
|
||||
: key === 'type'
|
||||
? TYPES[+value] || value
|
||||
: value
|
||||
: value,
|
||||
})
|
||||
|
||||
return device => execa.stdout('partx', [
|
||||
'--bytes',
|
||||
'--output=NR,START,SIZE,NAME,UUID,TYPE',
|
||||
'--pairs',
|
||||
device.path
|
||||
device.path,
|
||||
]).then(stdout => mapFilter(splitLines(stdout), line => {
|
||||
const partition = parseLine(line)
|
||||
const { type } = partition
|
||||
@ -187,7 +187,7 @@ const listPartitions2 = device => listPartitions(device).then(partitions => {
|
||||
partitions2.push({
|
||||
name: lv.lv_name,
|
||||
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([
|
||||
partitionId != null && listPartitions(device),
|
||||
tmpDir()
|
||||
tmpDir(),
|
||||
]).then(([ partitions, path ]) => {
|
||||
const options = [
|
||||
'loop',
|
||||
'ro'
|
||||
'ro',
|
||||
]
|
||||
|
||||
if (partitions) {
|
||||
@ -222,7 +222,7 @@ const mountPartition = (device, partitionId) => Promise.all([
|
||||
const mount = options => execa('mount', [
|
||||
`--options=${options.join(',')}`,
|
||||
`--source=${device.path}`,
|
||||
`--target=${path}`
|
||||
`--target=${path}`,
|
||||
])
|
||||
|
||||
// `norecovery` option is used for ext3/ext4/xfs, if it fails it
|
||||
@ -231,7 +231,7 @@ const mountPartition = (device, partitionId) => Promise.all([
|
||||
mount(options)
|
||||
).then(() => ({
|
||||
path,
|
||||
unmount: once(() => execa('umount', [ '--lazy', path ]))
|
||||
unmount: once(() => execa('umount', [ '--lazy', path ])),
|
||||
}), error => {
|
||||
console.log(error)
|
||||
|
||||
@ -260,7 +260,7 @@ const mountPartition2 = (device, partitionId) => {
|
||||
).then(path =>
|
||||
mountPartition({ path }).then(device2 => ({
|
||||
...device2,
|
||||
unmount: () => device2.unmount().then(device1.unmount)
|
||||
unmount: () => device2.unmount().then(device1.unmount),
|
||||
}))
|
||||
).catch(error => device1.unmount().then(() => {
|
||||
throw error
|
||||
@ -274,7 +274,7 @@ const listLvmLvs = device => pvs([
|
||||
'lv_name',
|
||||
'lv_path',
|
||||
'lv_size',
|
||||
'vg_name'
|
||||
'vg_name',
|
||||
], device.path).then(pvs => filter(pvs, 'lv_name'))
|
||||
|
||||
const mountLvmPv = (device, partition) => {
|
||||
@ -296,9 +296,9 @@ const mountLvmPv = (device, partition) => {
|
||||
execa('losetup', [ '-d', path ]),
|
||||
pvs('vg_name', path).then(vgNames => execa('vgchange', [
|
||||
'-an',
|
||||
...vgNames
|
||||
]))
|
||||
]))
|
||||
...vgNames,
|
||||
])),
|
||||
])),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -313,7 +313,7 @@ export default class {
|
||||
// unmounted
|
||||
xo.on('start', () => Promise.all([
|
||||
execa('losetup', [ '-D' ]),
|
||||
execa('vgchange', [ '-an' ])
|
||||
execa('vgchange', [ '-an' ]),
|
||||
]).then(() =>
|
||||
execa('pvscan', [ '--cache' ])
|
||||
))
|
||||
@ -367,7 +367,7 @@ export default class {
|
||||
record.disks = mapToArray(JSON.parse(data).vdis, vdi => ({
|
||||
id: `${entry}/${vdi.xoPath}`,
|
||||
name: vdi.name_label,
|
||||
uuid: vdi.uuid
|
||||
uuid: vdi.uuid,
|
||||
}))
|
||||
})
|
||||
}
|
||||
@ -390,8 +390,8 @@ export default class {
|
||||
await Promise.all([
|
||||
xapi.addTag(vm.$id, 'restored from backup'),
|
||||
xapi.editVm(vm.$id, {
|
||||
name_label: `${vm.name_label} (${shortDate(datetime * 1e3)})`
|
||||
})
|
||||
name_label: `${vm.name_label} (${shortDate(datetime * 1e3)})`,
|
||||
}),
|
||||
])
|
||||
|
||||
return xapiObjectToXo(vm).id
|
||||
@ -424,7 +424,7 @@ export default class {
|
||||
const { cancel, token } = CancelToken.source()
|
||||
const delta = await srcXapi.exportDeltaVm(token, srcVm.$id, localBaseUuid, {
|
||||
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(cancel)
|
||||
@ -461,7 +461,7 @@ export default class {
|
||||
delta,
|
||||
{
|
||||
deleteBase,
|
||||
srId: targetSr.$id
|
||||
srId: targetSr.$id,
|
||||
}
|
||||
)
|
||||
|
||||
@ -480,7 +480,7 @@ export default class {
|
||||
// (Asynchronously) Identify snapshot as future base.
|
||||
promise.then(() => {
|
||||
return srcXapi._updateObjectMapProperty(srcVm, 'other_config', {
|
||||
[TAG_LAST_BASE_DELTA]: delta.vm.uuid
|
||||
[TAG_LAST_BASE_DELTA]: delta.vm.uuid,
|
||||
})
|
||||
})::ignoreErrors()
|
||||
|
||||
@ -491,7 +491,7 @@ export default class {
|
||||
// 5. Return the identifier of the new XO VM object.
|
||||
id: xapiObjectToXo(dstVm).id,
|
||||
transferDuration: Date.now() - transferStart,
|
||||
transferSize: size
|
||||
transferSize: size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +530,7 @@ export default class {
|
||||
const stream = await handler.createReadStream(`${dir}/${vdiDir}/${backup}`)
|
||||
|
||||
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.
|
||||
await Promise.all([
|
||||
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 ?
|
||||
@ -583,7 +583,7 @@ export default class {
|
||||
// Import done, reenable start and set real vm name.
|
||||
await Promise.all([
|
||||
xapi.removeForbiddenOperationFromVm(vm.$id, 'start'),
|
||||
xapi._setObjectProperties(vm, { name_label: vmName })
|
||||
xapi._setObjectProperties(vm, { name_label: vmName }),
|
||||
])
|
||||
|
||||
return vm
|
||||
@ -628,7 +628,7 @@ export default class {
|
||||
|
||||
async _mergeDeltaVdiBackups ({handler, dir, retention}) {
|
||||
const backups = await this._listVdiBackups(handler, dir)
|
||||
let i = backups.length - retention
|
||||
const i = backups.length - retention
|
||||
|
||||
// No merge.
|
||||
if (i <= 0) {
|
||||
@ -730,7 +730,7 @@ export default class {
|
||||
// The problem is in the merge case, a delta merged in a full vdi
|
||||
// backup forces us to browse the resulting file =>
|
||||
// Significant transfer time on the network !
|
||||
checksum: !isFull
|
||||
checksum: !isFull,
|
||||
})
|
||||
|
||||
stream.on('error', error => targetStream.emit('error', error))
|
||||
@ -742,7 +742,7 @@ export default class {
|
||||
.pipe(targetStream),
|
||||
'finish'
|
||||
),
|
||||
stream.task
|
||||
stream.task,
|
||||
])
|
||||
} catch (error) {
|
||||
// Remove new backup. (corrupt).
|
||||
@ -754,7 +754,7 @@ export default class {
|
||||
return {
|
||||
// Returns relative path.
|
||||
path: `${backupDirectory}/${vdiFilename}`,
|
||||
size: sizeStream.size
|
||||
size: sizeStream.size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -769,7 +769,7 @@ export default class {
|
||||
|
||||
// Remove xva file.
|
||||
// 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, {
|
||||
snapshotNameLabel: `XO_DELTA_BASE_VM_SNAPSHOT_${tag}`,
|
||||
fullVdisRequired,
|
||||
disableBaseTags: true
|
||||
disableBaseTags: true,
|
||||
})
|
||||
$onFailure(() => xapi.deleteVm(delta.vm.uuid))
|
||||
$onFailure(cancel)
|
||||
@ -831,12 +831,12 @@ export default class {
|
||||
handler,
|
||||
stream: delta.streams[`${key}.vhd`],
|
||||
dir,
|
||||
retention
|
||||
retention,
|
||||
})
|
||||
.then(data => {
|
||||
delta.vdis[key] = {
|
||||
...delta.vdis[key],
|
||||
xoPath: data.path
|
||||
xoPath: data.path,
|
||||
}
|
||||
|
||||
return data
|
||||
@ -912,7 +912,7 @@ export default class {
|
||||
mergeDuration: mergedDataSize !== 0 ? mergeDuration : undefined,
|
||||
mergeSize: mergedDataSize !== 0 ? mergedDataSize : undefined,
|
||||
transferDuration: Date.now() - transferStart - mergeDuration,
|
||||
transferSize: dataSize
|
||||
transferSize: dataSize,
|
||||
}
|
||||
}
|
||||
|
||||
@ -930,7 +930,7 @@ export default class {
|
||||
if (!version) {
|
||||
// Legacy import. (Version 0.0.0)
|
||||
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')) {
|
||||
const basePath = dirname(filePath)
|
||||
@ -956,7 +956,7 @@ export default class {
|
||||
vm = await xapi.importDeltaVm(delta, {
|
||||
disableStartAfterImport: false,
|
||||
srId: sr !== undefined && sr._xapiId,
|
||||
mapVdisSrs
|
||||
mapVdisSrs,
|
||||
})
|
||||
} else {
|
||||
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, {
|
||||
compress,
|
||||
onlyMetadata: onlyMetadata || false
|
||||
onlyMetadata: onlyMetadata || false,
|
||||
})
|
||||
|
||||
const sizeStream = createSizeStream()
|
||||
@ -994,7 +994,7 @@ export default class {
|
||||
await promise
|
||||
|
||||
return {
|
||||
transferSize: sizeStream.size
|
||||
transferSize: sizeStream.size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,11 +1073,11 @@ export default class {
|
||||
|
||||
const copyName = `${vm.name_label}_${tag}_${safeDateFormat(new Date())}`
|
||||
const data = await sourceXapi.remoteCopyVm(vm.$id, targetXapi, sr.$id, {
|
||||
nameLabel: copyName
|
||||
nameLabel: copyName,
|
||||
})
|
||||
|
||||
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')
|
||||
@ -1088,7 +1088,7 @@ export default class {
|
||||
|
||||
return {
|
||||
transferDuration: Date.now() - transferStart,
|
||||
transferSize: data.size
|
||||
transferSize: data.size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1097,7 +1097,7 @@ export default class {
|
||||
_mountVhd (remoteId, vhdPath) {
|
||||
return Promise.all([
|
||||
this._xo.getRemoteHandler(remoteId),
|
||||
tmpDir()
|
||||
tmpDir(),
|
||||
]).then(([ handler, mountDir ]) => {
|
||||
if (!handler._getRealPath) {
|
||||
throw new Error(`this remote is not supported`)
|
||||
@ -1141,7 +1141,7 @@ export default class {
|
||||
|
||||
return {
|
||||
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 =>
|
||||
mountPartition2(device, partitionId).then(partition => ({
|
||||
...partition,
|
||||
unmount: () => partition.unmount().then(device.unmount)
|
||||
unmount: () => partition.unmount().then(device.unmount),
|
||||
})).catch(error => device.unmount().then(() => {
|
||||
throw error
|
||||
}))
|
||||
@ -1165,7 +1165,7 @@ export default class {
|
||||
$defer(device.unmount)
|
||||
|
||||
return {
|
||||
partitions: await listPartitions2(device)
|
||||
partitions: await listPartitions2(device),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ const runHook = (app, hook) => {
|
||||
onError: error => console.error(
|
||||
`[WARN] hook ${hook} failure:`,
|
||||
(error != null && error.stack) || error
|
||||
)
|
||||
),
|
||||
}, hook)
|
||||
promise.then(() => {
|
||||
debug(`${hook} finished`)
|
||||
@ -72,5 +72,5 @@ export default {
|
||||
// Run *stop* async listeners.
|
||||
//
|
||||
// They close connections, unmount file systems, save states, etc.
|
||||
stop: makeSingletonHook('stop', 'stopped')
|
||||
stop: makeSingletonHook('stop', 'stopped'),
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import hrp from 'http-request-plus'
|
||||
import ProxyAgent from 'proxy-agent'
|
||||
|
||||
import {
|
||||
firstDefined
|
||||
firstDefined,
|
||||
} from '../utils'
|
||||
|
||||
export default class Http {
|
||||
@ -10,14 +10,14 @@ export default class Http {
|
||||
httpProxy = firstDefined(
|
||||
process.env.http_proxy,
|
||||
process.env.HTTP_PROXY
|
||||
)
|
||||
),
|
||||
}) {
|
||||
this._proxy = httpProxy && new ProxyAgent(httpProxy)
|
||||
}
|
||||
|
||||
httpRequest (...args) {
|
||||
return hrp({
|
||||
agent: this._proxy
|
||||
agent: this._proxy,
|
||||
}, ...args)
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
lightSet,
|
||||
mapToArray,
|
||||
streamToArray,
|
||||
throwFn
|
||||
throwFn,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -31,13 +31,13 @@ const normalize = ({
|
||||
id = throwFn('id is a required field'),
|
||||
name = '',
|
||||
networks,
|
||||
resourceSets
|
||||
resourceSets,
|
||||
}) => ({
|
||||
addresses,
|
||||
id,
|
||||
name,
|
||||
networks,
|
||||
resourceSets
|
||||
resourceSets,
|
||||
})
|
||||
|
||||
const _isAddressInIpPool = (address, network, ipPool) => (
|
||||
@ -71,7 +71,7 @@ export default class IpPools {
|
||||
addresses,
|
||||
id,
|
||||
name,
|
||||
networks
|
||||
networks,
|
||||
})
|
||||
|
||||
return id
|
||||
@ -98,7 +98,7 @@ export default class IpPools {
|
||||
_getAllIpPools (filter) {
|
||||
return streamToArray(this._store.createValueStream(), {
|
||||
filter,
|
||||
mapper: normalize
|
||||
mapper: normalize,
|
||||
})
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ export default class IpPools {
|
||||
|
||||
return getXapi(vif).editVif(vif._xapiId, {
|
||||
ipv4Allowed: allowedIpv4Addresses,
|
||||
ipv6Allowed: allowedIpv6Addresses
|
||||
ipv6Allowed: allowedIpv6Addresses,
|
||||
})
|
||||
}))
|
||||
}
|
||||
@ -252,7 +252,7 @@ export default class IpPools {
|
||||
addresses,
|
||||
name,
|
||||
networks,
|
||||
resourceSets
|
||||
resourceSets,
|
||||
}) {
|
||||
const ipPool = await this.getIpPool(id)
|
||||
const previousAddresses = { ...ipPool.addresses }
|
||||
|
@ -14,7 +14,7 @@ export default class Jobs {
|
||||
const jobsDb = this._jobs = new JobsDb({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:job',
|
||||
indexes: ['user_id', 'key']
|
||||
indexes: ['user_id', 'key'],
|
||||
})
|
||||
this._runningJobs = Object.create(null)
|
||||
|
||||
|
@ -21,7 +21,7 @@ export default class Logs {
|
||||
}
|
||||
}
|
||||
const stream = db.createKeyStream({
|
||||
reverse: true
|
||||
reverse: true,
|
||||
})
|
||||
|
||||
const deleteEntry = key => {
|
||||
|
@ -9,7 +9,7 @@ const LEVELS = [
|
||||
'warning',
|
||||
'notice',
|
||||
'informational',
|
||||
'debug'
|
||||
'debug',
|
||||
]
|
||||
|
||||
// Create high level log methods.
|
||||
@ -17,6 +17,6 @@ for (const level of LEVELS) {
|
||||
Object.defineProperty(AbstractLogger.prototype, level, {
|
||||
value (message, data) {
|
||||
return this._add(level, message, data)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export default class LevelDbLogger extends AbstractLogger {
|
||||
message,
|
||||
data,
|
||||
namespace: this._namespace,
|
||||
time
|
||||
time,
|
||||
}
|
||||
|
||||
const key = generateUniqueKey(time)
|
||||
|
@ -3,12 +3,12 @@ import Ajv from 'ajv'
|
||||
import { PluginsMetadata } from '../models/plugin-metadata'
|
||||
import {
|
||||
invalidParameters,
|
||||
noSuchObject
|
||||
noSuchObject,
|
||||
} from 'xo-common/api-errors'
|
||||
import {
|
||||
createRawObject,
|
||||
isFunction,
|
||||
mapToArray
|
||||
mapToArray,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -16,13 +16,13 @@ import {
|
||||
export default class {
|
||||
constructor (xo) {
|
||||
this._ajv = new Ajv({
|
||||
useDefaults: true
|
||||
useDefaults: true,
|
||||
})
|
||||
this._plugins = createRawObject()
|
||||
|
||||
this._pluginsMetadata = new PluginsMetadata({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:plugin-metadata'
|
||||
prefix: 'xo:plugin-metadata',
|
||||
})
|
||||
|
||||
xo.on('start', () => {
|
||||
@ -71,7 +71,7 @@ export default class {
|
||||
testable: isFunction(instance.test),
|
||||
testSchema,
|
||||
unloadable: isFunction(instance.unload),
|
||||
version
|
||||
version,
|
||||
}
|
||||
|
||||
const metadata = await this._getPluginMetadata(id)
|
||||
@ -80,13 +80,13 @@ export default class {
|
||||
if (metadata) {
|
||||
({
|
||||
autoload,
|
||||
configuration
|
||||
configuration,
|
||||
} = metadata)
|
||||
} else {
|
||||
console.log(`[NOTICE] register plugin ${name} for the first time`)
|
||||
await this._pluginsMetadata.save({
|
||||
id,
|
||||
autoload
|
||||
autoload,
|
||||
})
|
||||
}
|
||||
|
||||
@ -113,11 +113,11 @@ export default class {
|
||||
testable,
|
||||
testSchema,
|
||||
unloadable,
|
||||
version
|
||||
version,
|
||||
} = this._getRawPlugin(id)
|
||||
const {
|
||||
autoload,
|
||||
configuration
|
||||
configuration,
|
||||
} = (await this._getPluginMetadata(id)) || {}
|
||||
|
||||
return {
|
||||
@ -132,7 +132,7 @@ export default class {
|
||||
configurationPresets,
|
||||
configurationSchema,
|
||||
testable,
|
||||
testSchema
|
||||
testSchema,
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ export default class {
|
||||
// Shallow copy of the configuration object to avoid most of the
|
||||
// errors when the plugin is altering the configuration object
|
||||
// which is handed over to it.
|
||||
...configuration
|
||||
...configuration,
|
||||
})
|
||||
plugin.configured = true
|
||||
}
|
||||
@ -234,7 +234,7 @@ export default class {
|
||||
if (data == null) {
|
||||
throw invalidParameters([{
|
||||
field: 'data',
|
||||
message: 'is the wrong type'
|
||||
message: 'is the wrong type',
|
||||
}])
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,10 @@ import RemoteHandlerNfs from '../remote-handlers/nfs'
|
||||
import RemoteHandlerSmb from '../remote-handlers/smb'
|
||||
import {
|
||||
forEach,
|
||||
mapToArray
|
||||
mapToArray,
|
||||
} from '../utils'
|
||||
import {
|
||||
Remotes
|
||||
Remotes,
|
||||
} from '../models/remote'
|
||||
|
||||
// ===================================================================
|
||||
@ -18,7 +18,7 @@ export default class {
|
||||
this._remotes = new Remotes({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:remote',
|
||||
indexes: ['enabled']
|
||||
indexes: ['enabled'],
|
||||
})
|
||||
|
||||
xo.on('clean', () => this._remotes.rebuildIndexes())
|
||||
@ -48,7 +48,7 @@ export default class {
|
||||
const HANDLERS = {
|
||||
file: RemoteHandlerLocal,
|
||||
smb: RemoteHandlerSmb,
|
||||
nfs: RemoteHandlerNfs
|
||||
nfs: RemoteHandlerNfs,
|
||||
}
|
||||
|
||||
// FIXME: should be done in xo-remote-parser.
|
||||
@ -84,7 +84,7 @@ export default class {
|
||||
}
|
||||
|
||||
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})
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ export default class {
|
||||
// TODO: Should it be private?
|
||||
async forgetAllRemotes () {
|
||||
const remotes = await this.getAllRemotes()
|
||||
for (let remote of remotes) {
|
||||
for (const remote of remotes) {
|
||||
try {
|
||||
(await this.getRemoteHandler(remote, true)).forget()
|
||||
} catch (_) {}
|
||||
|
@ -5,7 +5,7 @@ import some from 'lodash/some'
|
||||
import synchronized from 'decorator-synchronized'
|
||||
import {
|
||||
noSuchObject,
|
||||
unauthorized
|
||||
unauthorized,
|
||||
} from 'xo-common/api-errors'
|
||||
|
||||
import {
|
||||
@ -15,7 +15,7 @@ import {
|
||||
lightSet,
|
||||
map,
|
||||
mapToArray,
|
||||
streamToArray
|
||||
streamToArray,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -25,7 +25,7 @@ const VM_RESOURCES = {
|
||||
disk: true,
|
||||
disks: true,
|
||||
memory: true,
|
||||
vms: true
|
||||
vms: true,
|
||||
}
|
||||
|
||||
const computeVmResourcesUsage = vm => {
|
||||
@ -51,7 +51,7 @@ const computeVmResourcesUsage = vm => {
|
||||
disk,
|
||||
disks,
|
||||
memory: vm.memory_dynamic_max,
|
||||
vms: 1
|
||||
vms: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,13 +63,13 @@ const normalize = set => ({
|
||||
? limit
|
||||
: {
|
||||
available: limit,
|
||||
total: limit
|
||||
total: limit,
|
||||
}
|
||||
)
|
||||
: {},
|
||||
name: set.name || '',
|
||||
objects: set.objects || [],
|
||||
subjects: set.subjects || []
|
||||
subjects: set.subjects || [],
|
||||
})
|
||||
|
||||
// ===================================================================
|
||||
@ -137,7 +137,7 @@ export default class {
|
||||
name,
|
||||
objects,
|
||||
subjects,
|
||||
limits
|
||||
limits,
|
||||
})
|
||||
|
||||
await this._store.put(id, set)
|
||||
@ -160,7 +160,7 @@ export default class {
|
||||
subjects = undefined,
|
||||
objects = undefined,
|
||||
limits = undefined,
|
||||
ipPools = undefined
|
||||
ipPools = undefined,
|
||||
}) {
|
||||
const set = await this.getResourceSet(id)
|
||||
if (name) {
|
||||
@ -179,7 +179,7 @@ export default class {
|
||||
if (!previous) {
|
||||
return {
|
||||
available: quantity,
|
||||
total: quantity
|
||||
total: quantity,
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ export default class {
|
||||
|
||||
return {
|
||||
available: available - total + quantity,
|
||||
total: quantity
|
||||
total: quantity,
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -212,7 +212,7 @@ export default class {
|
||||
|
||||
return streamToArray(this._store.createValueStream(), {
|
||||
filter,
|
||||
mapper: normalize
|
||||
mapper: normalize,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { Schedules } from '../models/schedule'
|
||||
import {
|
||||
forEach,
|
||||
mapToArray,
|
||||
scheduleFn
|
||||
scheduleFn,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -40,7 +40,7 @@ export default class {
|
||||
const schedules = this._redisSchedules = new Schedules({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:schedule',
|
||||
indexes: ['user_id', 'job']
|
||||
indexes: ['user_id', 'job'],
|
||||
})
|
||||
this._scheduleTable = undefined
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { ensureDir } from 'fs-extra'
|
||||
import {
|
||||
forEach,
|
||||
isFunction,
|
||||
promisify
|
||||
promisify,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -68,7 +68,7 @@ export default class {
|
||||
const dir = `${xo._config.datadir}/leveldb`
|
||||
this._db = ensureDir(dir).then(() => {
|
||||
return sublevel(levelup(dir, {
|
||||
valueEncoding: 'json'
|
||||
valueEncoding: 'json',
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
@ -3,24 +3,24 @@ import { ignoreErrors } from 'promise-toolbox'
|
||||
import {
|
||||
hash,
|
||||
needsRehash,
|
||||
verify
|
||||
verify,
|
||||
} from 'hashy'
|
||||
import {
|
||||
invalidCredentials,
|
||||
noSuchObject
|
||||
noSuchObject,
|
||||
} from 'xo-common/api-errors'
|
||||
|
||||
import {
|
||||
Groups
|
||||
Groups,
|
||||
} from '../models/group'
|
||||
import {
|
||||
Users
|
||||
Users,
|
||||
} from '../models/user'
|
||||
import {
|
||||
forEach,
|
||||
isEmpty,
|
||||
lightSet,
|
||||
mapToArray
|
||||
mapToArray,
|
||||
} from '../utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -40,17 +40,17 @@ export default class {
|
||||
|
||||
const groupsDb = this._groups = new Groups({
|
||||
connection: redis,
|
||||
prefix: 'xo:group'
|
||||
prefix: 'xo:group',
|
||||
})
|
||||
const usersDb = this._users = new Users({
|
||||
connection: redis,
|
||||
prefix: 'xo:user',
|
||||
indexes: ['email']
|
||||
indexes: ['email'],
|
||||
})
|
||||
|
||||
xo.on('clean', () => Promise.all([
|
||||
groupsDb.rebuildIndexes(),
|
||||
usersDb.rebuildIndexes()
|
||||
usersDb.rebuildIndexes(),
|
||||
]))
|
||||
xo.on('start', async () => {
|
||||
xo.addConfigManager('groups',
|
||||
@ -135,7 +135,7 @@ export default class {
|
||||
name = email,
|
||||
password,
|
||||
permission,
|
||||
preferences
|
||||
preferences,
|
||||
}) {
|
||||
const user = await this.getUser(id)
|
||||
|
||||
@ -210,7 +210,7 @@ export default class {
|
||||
|
||||
// Get or create a user associated with an auth provider.
|
||||
async registerUser (provider, name) {
|
||||
let user = await this.getUserByName(name, true)
|
||||
const user = await this.getUserByName(name, true)
|
||||
if (user) {
|
||||
if (user._provider !== provider) {
|
||||
throw new Error(`the name ${name} is already taken`)
|
||||
@ -225,7 +225,7 @@ export default class {
|
||||
|
||||
return /* await */ this.createUser({
|
||||
name,
|
||||
_provider: provider
|
||||
_provider: provider,
|
||||
})
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ export default class {
|
||||
async addUserToGroup (userId, groupId) {
|
||||
const [user, group] = await Promise.all([
|
||||
this.getUser(userId),
|
||||
this.getGroup(groupId)
|
||||
this.getGroup(groupId),
|
||||
])
|
||||
|
||||
user.groups = addToArraySet(user.groups, groupId)
|
||||
@ -314,7 +314,7 @@ export default class {
|
||||
|
||||
await Promise.all([
|
||||
this._users.save(user),
|
||||
this._groups.save(group)
|
||||
this._groups.save(group),
|
||||
])
|
||||
}
|
||||
|
||||
@ -331,12 +331,12 @@ export default class {
|
||||
async removeUserFromGroup (userId, groupId) {
|
||||
const [user, group] = await Promise.all([
|
||||
this.getUser(userId),
|
||||
this.getGroup(groupId)
|
||||
this.getGroup(groupId),
|
||||
])
|
||||
|
||||
await Promise.all([
|
||||
this._removeUserFromGroup(userId, group),
|
||||
this._removeGroupFromUser(groupId, user)
|
||||
this._removeGroupFromUser(groupId, user),
|
||||
])
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ export default class {
|
||||
const getUser = ::this.getUser
|
||||
const [newUsers, oldUsers] = await Promise.all([
|
||||
Promise.all(newUsersIds.map(getUser)),
|
||||
Promise.all(oldUsersIds.map(getUser))
|
||||
Promise.all(oldUsersIds.map(getUser)),
|
||||
])
|
||||
|
||||
forEach(newUsers, user => {
|
||||
@ -373,7 +373,7 @@ export default class {
|
||||
await Promise.all([
|
||||
Promise.all(mapToArray(newUsers, saveUser)),
|
||||
Promise.all(mapToArray(oldUsers, saveUser)),
|
||||
this._groups.save(group)
|
||||
this._groups.save(group),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ import {
|
||||
isEmpty,
|
||||
isString,
|
||||
popProperty,
|
||||
serializeError
|
||||
serializeError,
|
||||
} from '../utils'
|
||||
import {
|
||||
Servers
|
||||
Servers,
|
||||
} from '../models/server'
|
||||
|
||||
// ===================================================================
|
||||
@ -25,7 +25,7 @@ export default class {
|
||||
const serversDb = this._servers = new Servers({
|
||||
connection: xo._redis,
|
||||
prefix: 'xo:server',
|
||||
indexes: ['host']
|
||||
indexes: ['host'],
|
||||
})
|
||||
this._stats = new XapiStats()
|
||||
this._xapis = createRawObject()
|
||||
@ -41,7 +41,7 @@ export default class {
|
||||
|
||||
// Connects to existing servers.
|
||||
const servers = await serversDb.get()
|
||||
for (let server of servers) {
|
||||
for (const server of servers) {
|
||||
if (server.enabled) {
|
||||
this.connectXenServer(server.id).catch(error => {
|
||||
console.error(
|
||||
@ -62,7 +62,7 @@ export default class {
|
||||
label,
|
||||
password,
|
||||
readOnly,
|
||||
username
|
||||
username,
|
||||
}) {
|
||||
// FIXME: We are storing passwords which is bad!
|
||||
// Could we use tokens instead?
|
||||
@ -74,7 +74,7 @@ export default class {
|
||||
label: label || undefined,
|
||||
password,
|
||||
readOnly: readOnly ? 'true' : undefined,
|
||||
username
|
||||
username,
|
||||
})
|
||||
|
||||
return server.properties
|
||||
@ -96,7 +96,7 @@ export default class {
|
||||
label,
|
||||
password,
|
||||
readOnly,
|
||||
username
|
||||
username,
|
||||
}) {
|
||||
const server = await this._getXenServer(id)
|
||||
const xapi = this._xapis[id]
|
||||
@ -225,10 +225,10 @@ export default class {
|
||||
allowUnauthorized: Boolean(server.allowUnauthorized),
|
||||
auth: {
|
||||
user: server.username,
|
||||
password: server.password
|
||||
password: server.password,
|
||||
},
|
||||
readOnly: Boolean(server.readOnly),
|
||||
url: server.host
|
||||
url: server.host,
|
||||
})
|
||||
|
||||
xapi.xo = (() => {
|
||||
@ -316,7 +316,7 @@ export default class {
|
||||
|
||||
// Register the updated object.
|
||||
addObject(await xapi._waitObject(id))
|
||||
}
|
||||
},
|
||||
}
|
||||
})()
|
||||
|
||||
@ -410,7 +410,7 @@ export default class {
|
||||
const sourceXapi = this.getXapi(sourceId)
|
||||
const {
|
||||
_auth: { user, password },
|
||||
_url: { hostname }
|
||||
_url: { hostname },
|
||||
} = this.getXapi(targetId)
|
||||
|
||||
// We don't want the events of the source XAPI to interfere with
|
||||
|
32
src/xo.js
32
src/xo.js
@ -11,18 +11,18 @@ import {
|
||||
isString,
|
||||
iteratee,
|
||||
map as mapToArray,
|
||||
stubTrue
|
||||
stubTrue,
|
||||
} from 'lodash'
|
||||
|
||||
import mixins from './xo-mixins'
|
||||
import mixins from './xo-mixins' // eslint-disable-line node/no-missing-import
|
||||
import Connection from './connection'
|
||||
import {
|
||||
mixin
|
||||
mixin,
|
||||
} from './decorators'
|
||||
import {
|
||||
createRawObject,
|
||||
generateToken,
|
||||
noop
|
||||
noop,
|
||||
} from './utils'
|
||||
|
||||
// ===================================================================
|
||||
@ -49,12 +49,12 @@ export default class Xo extends EventEmitter {
|
||||
// Connects to Redis.
|
||||
{
|
||||
const {
|
||||
renameCommands: rename_commands,
|
||||
renameCommands,
|
||||
socket: path,
|
||||
uri: url
|
||||
uri: url,
|
||||
} = config.redis || {}
|
||||
|
||||
this._redis = createRedisClient({ path, rename_commands, url })
|
||||
this._redis = createRedisClient({ path, rename_commands: renameCommands, url })
|
||||
}
|
||||
|
||||
this.on('start', () => this._watchObjects())
|
||||
@ -67,8 +67,8 @@ export default class Xo extends EventEmitter {
|
||||
const {
|
||||
all,
|
||||
indexes: {
|
||||
byRef
|
||||
}
|
||||
byRef,
|
||||
},
|
||||
} = this._objects
|
||||
|
||||
const obj = all[key] || byRef[key]
|
||||
@ -180,7 +180,7 @@ export default class Xo extends EventEmitter {
|
||||
|
||||
watchers[url] = {
|
||||
data,
|
||||
fn
|
||||
fn,
|
||||
}
|
||||
|
||||
return url
|
||||
@ -188,7 +188,7 @@ export default class Xo extends EventEmitter {
|
||||
|
||||
async registerHttpRequestHandler (url, fn, {
|
||||
data = undefined,
|
||||
persistent = true
|
||||
persistent = true,
|
||||
} = {}) {
|
||||
const {_httpRequestWatchers: watchers} = this
|
||||
|
||||
@ -199,7 +199,7 @@ export default class Xo extends EventEmitter {
|
||||
watchers[url] = {
|
||||
data,
|
||||
fn,
|
||||
persistent
|
||||
persistent,
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ export default class Xo extends EventEmitter {
|
||||
|
||||
Object.defineProperty(this, name, {
|
||||
configurable: true,
|
||||
value
|
||||
value,
|
||||
})
|
||||
|
||||
let unset = () => {
|
||||
@ -260,7 +260,7 @@ export default class Xo extends EventEmitter {
|
||||
_watchObjects () {
|
||||
const {
|
||||
_connections: connections,
|
||||
_objects: objects
|
||||
_objects: objects,
|
||||
} = this
|
||||
|
||||
let entered, exited
|
||||
@ -289,11 +289,11 @@ export default class Xo extends EventEmitter {
|
||||
objects.on('finish', () => {
|
||||
const enteredMessage = !isEmpty(entered) && {
|
||||
type: 'enter',
|
||||
items: entered
|
||||
items: entered,
|
||||
}
|
||||
const exitedMessage = !isEmpty(exited) && {
|
||||
type: 'exit',
|
||||
items: exited
|
||||
items: exited,
|
||||
}
|
||||
|
||||
if (!enteredMessage && !exitedMessage) {
|
||||
|
553
yarn.lock
553
yarn.lock
@ -168,11 +168,11 @@ agent-base@^4.1.0:
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
ajv-keywords@^1.0.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
|
||||
ajv-keywords@^2.1.0:
|
||||
version "2.1.1"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
|
||||
dependencies:
|
||||
@ -188,6 +188,15 @@ ajv@^5.1.0, ajv@^5.3.0:
|
||||
fast-json-stable-stringify "^2.0.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:
|
||||
version "0.1.4"
|
||||
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"
|
||||
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:
|
||||
version "3.0.0"
|
||||
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"
|
||||
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:
|
||||
version "1.0.1"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
|
||||
dependencies:
|
||||
@ -1509,6 +1507,10 @@ character-parser@^2.1.1:
|
||||
dependencies:
|
||||
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:
|
||||
version "2.2.1"
|
||||
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"
|
||||
source-map "0.4.x"
|
||||
|
||||
cli-cursor@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
|
||||
cli-cursor@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
|
||||
dependencies:
|
||||
restore-cursor "^1.0.1"
|
||||
restore-cursor "^2.0.0"
|
||||
|
||||
cli-width@^2.0.0:
|
||||
version "2.2.0"
|
||||
@ -1661,7 +1663,7 @@ concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
|
||||
dependencies:
|
||||
@ -1776,7 +1778,7 @@ cross-spawn@^4.0.2:
|
||||
lru-cache "^4.0.1"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^5.0.1:
|
||||
cross-spawn@^5.0.1, cross-spawn@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
|
||||
dependencies:
|
||||
@ -1861,11 +1863,7 @@ debug-fabulous@>=0.1.1:
|
||||
memoizee "0.4.X"
|
||||
object-assign "4.X"
|
||||
|
||||
debug-log@^1.0.0:
|
||||
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:
|
||||
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
dependencies:
|
||||
@ -1925,13 +1923,6 @@ deferred-leveldown@~2.0.2:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.2.5"
|
||||
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"
|
||||
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:
|
||||
version "2.2.2"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
doctrine@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
|
||||
doctrine@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
doctypes@^1.1.0:
|
||||
version "1.1.0"
|
||||
@ -2119,24 +2098,6 @@ error-ex@^1.2.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.10.35"
|
||||
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"
|
||||
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:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
|
||||
@ -2173,17 +2123,7 @@ es6-promisify@^5.0.0:
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
es6-set@~0.1.5:
|
||||
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:
|
||||
es6-symbol@^3.1.1, es6-symbol@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
|
||||
dependencies:
|
||||
@ -2237,122 +2177,106 @@ escodegen@~1.3.2:
|
||||
optionalDependencies:
|
||||
source-map "~0.1.33"
|
||||
|
||||
escope@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
|
||||
eslint-config-standard@^11.0.0-beta.0:
|
||||
version "11.0.0-beta.0"
|
||||
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:
|
||||
es6-map "^0.1.3"
|
||||
es6-weak-map "^2.0.1"
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
debug "^2.6.8"
|
||||
resolve "^1.2.0"
|
||||
|
||||
eslint-config-standard-jsx@4.0.2:
|
||||
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:
|
||||
eslint-module-utils@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
pkg-dir "^1.0.0"
|
||||
|
||||
eslint-plugin-import@~2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e"
|
||||
eslint-plugin-import@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894"
|
||||
dependencies:
|
||||
builtin-modules "^1.1.1"
|
||||
contains-path "^0.1.0"
|
||||
debug "^2.2.0"
|
||||
debug "^2.6.8"
|
||||
doctrine "1.5.0"
|
||||
eslint-import-resolver-node "^0.2.0"
|
||||
eslint-module-utils "^2.0.0"
|
||||
eslint-import-resolver-node "^0.3.1"
|
||||
eslint-module-utils "^2.1.1"
|
||||
has "^1.0.1"
|
||||
lodash.cond "^4.3.0"
|
||||
minimatch "^3.0.3"
|
||||
pkg-up "^1.0.0"
|
||||
read-pkg-up "^2.0.0"
|
||||
|
||||
eslint-plugin-node@~4.2.2:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz#c04390ab8dbcbb6887174023d6f3a72769e63b97"
|
||||
eslint-plugin-node@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz#80df3253c4d7901045ec87fa660a284e32bdca29"
|
||||
dependencies:
|
||||
ignore "^3.0.11"
|
||||
minimatch "^3.0.2"
|
||||
object-assign "^4.0.1"
|
||||
resolve "^1.1.7"
|
||||
ignore "^3.3.6"
|
||||
minimatch "^3.0.4"
|
||||
resolve "^1.3.3"
|
||||
semver "5.3.0"
|
||||
|
||||
eslint-plugin-promise@~3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz#78fbb6ffe047201627569e85a6c5373af2a68fca"
|
||||
eslint-plugin-promise@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz#54b7658c8f454813dc2a870aff8152ec4969ba75"
|
||||
|
||||
eslint-plugin-react@~6.10.0:
|
||||
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:
|
||||
eslint-plugin-standard@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2"
|
||||
|
||||
eslint@~3.19.0:
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
|
||||
eslint-scope@^3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
|
||||
dependencies:
|
||||
babel-code-frame "^6.16.0"
|
||||
chalk "^1.1.3"
|
||||
concat-stream "^1.5.2"
|
||||
debug "^2.1.1"
|
||||
doctrine "^2.0.0"
|
||||
escope "^3.6.0"
|
||||
espree "^3.4.0"
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint@^4.13.1:
|
||||
version "4.13.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f"
|
||||
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"
|
||||
estraverse "^4.2.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^2.0.0"
|
||||
glob "^7.0.3"
|
||||
globals "^9.14.0"
|
||||
ignore "^3.2.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob "^7.1.2"
|
||||
globals "^11.0.1"
|
||||
ignore "^3.3.3"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^0.12.0"
|
||||
is-my-json-valid "^2.10.0"
|
||||
inquirer "^3.0.6"
|
||||
is-resolvable "^1.0.0"
|
||||
js-yaml "^3.5.1"
|
||||
json-stable-stringify "^1.0.0"
|
||||
js-yaml "^3.9.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.0.0"
|
||||
mkdirp "^0.5.0"
|
||||
lodash "^4.17.4"
|
||||
minimatch "^3.0.2"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.2"
|
||||
path-is-inside "^1.0.1"
|
||||
pluralize "^1.2.1"
|
||||
progress "^1.1.8"
|
||||
require-uncached "^1.0.2"
|
||||
shelljs "^0.7.5"
|
||||
strip-bom "^3.0.0"
|
||||
path-is-inside "^1.0.2"
|
||||
pluralize "^7.0.0"
|
||||
progress "^2.0.0"
|
||||
require-uncached "^1.0.3"
|
||||
semver "^5.3.0"
|
||||
strip-ansi "^4.0.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
table "^3.7.8"
|
||||
table "^4.0.1"
|
||||
text-table "~0.2.0"
|
||||
user-home "^2.0.0"
|
||||
|
||||
espree@^3.4.0:
|
||||
espree@^3.5.2:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca"
|
||||
dependencies:
|
||||
@ -2412,7 +2336,7 @@ etag@~1.8.1:
|
||||
version "1.8.1"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
dependencies:
|
||||
@ -2473,10 +2397,6 @@ execa@^0.8.0:
|
||||
signal-exit "^3.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:
|
||||
version "0.1.5"
|
||||
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"
|
||||
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:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
|
||||
@ -2664,12 +2592,11 @@ fifolock@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fifolock/-/fifolock-1.0.0.tgz#a37e54f3ebe69d13480d95a82abc42b7a5c1792d"
|
||||
|
||||
figures@^1.3.5:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
|
||||
figures@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
file-entry-cache@^2.0.0:
|
||||
version "2.0.0"
|
||||
@ -2724,10 +2651,6 @@ finalhandler@1.1.0:
|
||||
statuses "~1.3.1"
|
||||
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:
|
||||
version "1.1.2"
|
||||
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"
|
||||
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"
|
||||
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:
|
||||
version "2.7.4"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
|
||||
dependencies:
|
||||
@ -2947,10 +2874,6 @@ get-caller-file@^1.0.1:
|
||||
version "1.0.2"
|
||||
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:
|
||||
version "3.0.0"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
strip-indent "^2.0.0"
|
||||
|
||||
iconv-lite@0.4.19:
|
||||
iconv-lite@0.4.19, iconv-lite@^0.4.17:
|
||||
version "0.4.19"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
|
||||
|
||||
inquirer@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
|
||||
inquirer@^3.0.6:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
|
||||
dependencies:
|
||||
ansi-escapes "^1.1.0"
|
||||
ansi-regex "^2.0.0"
|
||||
chalk "^1.0.0"
|
||||
cli-cursor "^1.0.1"
|
||||
ansi-escapes "^3.0.0"
|
||||
chalk "^2.0.0"
|
||||
cli-cursor "^2.1.0"
|
||||
cli-width "^2.0.0"
|
||||
figures "^1.3.5"
|
||||
external-editor "^2.0.4"
|
||||
figures "^2.0.0"
|
||||
lodash "^4.3.0"
|
||||
readline2 "^1.0.1"
|
||||
run-async "^0.1.0"
|
||||
rx-lite "^3.1.2"
|
||||
string-width "^1.0.1"
|
||||
strip-ansi "^3.0.0"
|
||||
mute-stream "0.0.7"
|
||||
run-async "^2.2.0"
|
||||
rx-lite "^4.0.8"
|
||||
rx-lite-aggregates "^4.0.8"
|
||||
string-width "^2.1.0"
|
||||
strip-ansi "^4.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
interpret@^1.0.0:
|
||||
@ -3616,10 +3544,6 @@ is-builtin-module@^1.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.10"
|
||||
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:
|
||||
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:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
|
||||
@ -3716,15 +3636,6 @@ is-glob@^3.1.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "2.1.0"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
|
||||
dependencies:
|
||||
@ -3807,10 +3718,6 @@ is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
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:
|
||||
version "1.0.0"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
|
||||
dependencies:
|
||||
@ -4225,6 +4132,10 @@ json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
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:
|
||||
version "1.0.1"
|
||||
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"
|
||||
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:
|
||||
version "1.4.1"
|
||||
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"
|
||||
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:
|
||||
version "0.1.0"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.0.tgz#5b32ea07eb43c9ded6130434cf926f46b2a7fd4d"
|
||||
|
||||
mute-stream@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
||||
nan@2.6.2, nan@~2.6.1:
|
||||
version "2.6.2"
|
||||
@ -5170,7 +5073,7 @@ object-inspect@~0.4.0:
|
||||
version "0.4.0"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
|
||||
|
||||
@ -5184,14 +5087,6 @@ object-visit@^1.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.1.0"
|
||||
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:
|
||||
wrappy "1"
|
||||
|
||||
onetime@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
|
||||
onetime@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
|
||||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
optimist@^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"
|
||||
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"
|
||||
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:
|
||||
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:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
|
||||
dependencies:
|
||||
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:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd"
|
||||
|
||||
pluralize@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
|
||||
pluralize@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
||||
|
||||
posix-character-classes@^0.1.0:
|
||||
version "0.1.1"
|
||||
@ -5586,9 +5462,9 @@ process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
|
||||
progress@^1.1.8:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
|
||||
progress@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
|
||||
|
||||
promise-polyfill@^6.0.1:
|
||||
version "6.0.2"
|
||||
@ -5938,14 +5814,6 @@ readdirp@^2.0.0:
|
||||
readable-stream "^2.0.2"
|
||||
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:
|
||||
version "0.6.2"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
|
||||
dependencies:
|
||||
@ -6140,18 +6008,18 @@ resolve@1.1.7, resolve@~1.1.6:
|
||||
version "1.1.7"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
restore-cursor@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
dependencies:
|
||||
exit-hook "^1.0.0"
|
||||
onetime "^1.0.0"
|
||||
onetime "^2.0.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
right-align@^0.1.1:
|
||||
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:
|
||||
glob "^7.0.5"
|
||||
|
||||
run-async@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
is-promise "^2.1.0"
|
||||
|
||||
run-parallel@^1.1.2:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039"
|
||||
rx-lite-aggregates@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
|
||||
dependencies:
|
||||
rx-lite "*"
|
||||
|
||||
rx-lite@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
|
||||
rx-lite@*, rx-lite@^4.0.8:
|
||||
version "4.0.8"
|
||||
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:
|
||||
version "5.1.1"
|
||||
@ -6314,14 +6184,6 @@ shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
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:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
@ -6352,9 +6214,11 @@ slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
||||
slice-ansi@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||
slice-ansi@1.0.0:
|
||||
version "1.0.0"
|
||||
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":
|
||||
version "1.0.0"
|
||||
@ -6540,29 +6404,6 @@ stack-trace@0.0.9:
|
||||
version "0.0.9"
|
||||
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:
|
||||
version "0.2.4"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||
dependencies:
|
||||
@ -6734,16 +6575,16 @@ symbol-tree@^3.2.1:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
|
||||
|
||||
table@^3.7.8:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
|
||||
table@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
|
||||
dependencies:
|
||||
ajv "^4.7.0"
|
||||
ajv-keywords "^1.0.0"
|
||||
chalk "^1.1.1"
|
||||
lodash "^4.0.0"
|
||||
slice-ansi "0.0.4"
|
||||
string-width "^2.0.0"
|
||||
ajv "^5.2.3"
|
||||
ajv-keywords "^2.1.0"
|
||||
chalk "^2.1.0"
|
||||
lodash "^4.17.4"
|
||||
slice-ansi "1.0.0"
|
||||
string-width "^2.1.1"
|
||||
|
||||
tar-fs@^1.13.0:
|
||||
version "1.16.0"
|
||||
@ -7029,10 +6870,6 @@ union-value@^1.0.0:
|
||||
is-extendable "^0.1.1"
|
||||
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:
|
||||
version "2.2.1"
|
||||
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"
|
||||
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:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
Loading…
Reference in New Issue
Block a user