Compare commits

..

1 Commits

Author SHA1 Message Date
Julien Fontanet
7174499228 WiP 2021-05-25 16:25:39 +02:00
78 changed files with 611 additions and 393 deletions

View File

@@ -16,9 +16,7 @@ Installation of the [npm package](https://npmjs.org/package/@vates/decorate-with
## Usage
### `decorateWith(fn, ...args)`
Creates a new ([legacy](https://babeljs.io/docs/en/babel-plugin-syntax-decorators#legacy)) method decorator from a function decorator, for instance, allows using Lodash's functions as decorators:
For instance, allows using Lodash's functions as decorators:
```js
import { decorateWith } from '@vates/decorate-with'
@@ -31,34 +29,6 @@ class Foo {
}
```
### `decorateMethodsWith(class, map)`
Decorates a number of methods directly, without using the decorator syntax:
```js
import { decorateMethodsWith } from '@vates/decorate-with'
class Foo {
bar() {
// body
}
baz() {
// body
}
}
decorateMethodsWith(Foo, {
// without arguments
bar: lodash.curry,
// with arguments
baz: [lodash.debounce, 150],
})
```
The decorated class is returned, so you can export it directly.
## Contributions
Contributions are _very_ welcomed, either on the documentation or on

View File

@@ -1,6 +1,4 @@
### `decorateWith(fn, ...args)`
Creates a new ([legacy](https://babeljs.io/docs/en/babel-plugin-syntax-decorators#legacy)) method decorator from a function decorator, for instance, allows using Lodash's functions as decorators:
For instance, allows using Lodash's functions as decorators:
```js
import { decorateWith } from '@vates/decorate-with'
@@ -12,31 +10,3 @@ class Foo {
}
}
```
### `decorateMethodsWith(class, map)`
Decorates a number of methods directly, without using the decorator syntax:
```js
import { decorateMethodsWith } from '@vates/decorate-with'
class Foo {
bar() {
// body
}
baz() {
// body
}
}
decorateMethodsWith(Foo, {
// without arguments
bar: lodash.curry,
// with arguments
baz: [lodash.debounce, 150],
})
```
The decorated class is returned, so you can export it directly.

View File

@@ -1,21 +1,4 @@
exports.decorateWith = function decorateWith(fn, ...args) {
return (target, name, descriptor) => ({
...descriptor,
value: fn(descriptor.value, ...args),
})
}
const { getOwnPropertyDescriptor, defineProperty } = Object
exports.decorateMethodsWith = function decorateMethodsWith(klass, map) {
const { prototype } = klass
for (const name of Object.keys(map)) {
const descriptor = getOwnPropertyDescriptor(prototype, name)
const { value } = descriptor
const decorator = map[name]
descriptor.value = typeof decorator === 'function' ? decorator(value) : decorator[0](value, ...decorator.slice(1))
defineProperty(prototype, name, descriptor)
}
return klass
}
exports.decorateWith = (fn, ...args) => (target, name, descriptor) => ({
...descriptor,
value: fn(descriptor.value, ...args),
})

View File

@@ -20,7 +20,7 @@
"url": "https://vates.fr"
},
"license": "ISC",
"version": "0.1.0",
"version": "0.0.1",
"engines": {
"node": ">=8.10"
},

View File

@@ -24,7 +24,7 @@
"dependencies": {
"@vates/multi-key-map": "^0.1.0",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"ensure-array": "^1.0.0"
}
}

View File

@@ -18,6 +18,17 @@ const wrapCall = (fn, arg, thisArg) => {
* @returns {Promise<Item[]>}
*/
exports.asyncMap = function asyncMap(iterable, mapFn, thisArg = iterable) {
let onError
if (onError !== undefined) {
const original = mapFn
mapFn = async function () {
try {
return await original.apply(this, arguments)
} catch (error) {
return onError.call(this, error, ...arguments)
}
}
}
return Promise.all(Array.from(iterable, mapFn, thisArg))
}

View File

@@ -9,7 +9,7 @@
},
"version": "0.2.0",
"engines": {
"node": ">=10"
"node": ">=8.10"
},
"main": "dist/",
"scripts": {
@@ -30,8 +30,9 @@
"rimraf": "^3.0.0"
},
"dependencies": {
"@vates/decorate-with": "^0.1.0",
"@xen-orchestra/log": "^0.2.1",
"@vates/decorate-with": "^0.0.1",
"@xen-orchestra/log": "^0.2.0",
"core-js": "^3.6.4",
"golike-defer": "^0.5.1",
"object-hash": "^2.0.1"
},

View File

@@ -1,3 +1,6 @@
// see https://github.com/babel/babel/issues/8450
import 'core-js/features/symbol/async-iterator'
import assert from 'assert'
import hash from 'object-hash'
import { createLogger } from '@xen-orchestra/log'

View File

@@ -543,6 +543,40 @@ class RemoteAdapter {
async readVmBackupMetadata(path) {
return Object.defineProperty(JSON.parse(await this._handler.readFile(path)), '_filename', { value: path })
}
async writeFullVmBackup({ jobId, mode, scheduleId, timestamp, vm, vmSnapshot, xva }, sizeContainer, stream) {
const basename = formatFilenameDate(timestamp)
const dataBasename = basename + '.xva'
const dataFilename = backupDir + '/' + dataBasename
const metadataFilename = `${backupDir}/${basename}.json`
const metadata = {
jobId: job.id,
mode: job.mode,
scheduleId,
timestamp,
version: '2.0.0',
vm,
vmSnapshot: this._backup.exportedVm,
xva: './' + dataBasename,
}
const { deleteFirst } = settings
if (deleteFirst) {
await deleteOldBackups()
}
await adapter.outputStream(stream, dataFilename, {
validator: tmpPath => {
if (handler._getFilePath !== undefined) {
return isValidXva(handler._getFilePath('/' + tmpPath))
}
},
})
metadata.size = sizeContainer.size
await handler.outputFile(metadataFilename, JSON.stringify(metadata))
}
}
Object.assign(RemoteAdapter.prototype, {

View File

@@ -1,8 +1,11 @@
const CancelToken = require('promise-toolbox/CancelToken.js')
const Zone = require('node-zone')
const logAfterEnd = () => {
throw new Error('task has already ended')
const logAfterEnd = function (log) {
const error = new Error('task has already ended:' + this.id)
error.result = log.result
error.log = log
throw error
}
const noop = Function.prototype
@@ -44,11 +47,19 @@ class Task {
}
}
get id() {
return this.#id
}
#cancelToken
#id = Math.random().toString(36).slice(2)
#onLog
#zone
get id() {
return this.#id
}
constructor({ name, data, onLog }) {
let parentCancelToken, parentId
if (onLog === undefined) {
@@ -100,6 +111,8 @@ class Task {
run(fn, last = false) {
return this.#zone.run(() => {
try {
this.#cancelToken.throwIfRequested()
const result = fn()
let then
if (result != null && typeof (then = result.then) === 'function') {

View File

@@ -1,4 +1,5 @@
const assert = require('assert')
// const asyncFn = require('promise-toolbox/asyncFn')
const findLast = require('lodash/findLast.js')
const ignoreErrors = require('promise-toolbox/ignoreErrors.js')
const keyBy = require('lodash/keyBy.js')
@@ -143,6 +144,7 @@ exports.VmBackup = class VmBackup {
const doSnapshot =
this._isDelta || (!settings.offlineBackup && vm.power_state === 'Running') || settings.snapshotRetention !== 0
console.log({ doSnapshot })
if (doSnapshot) {
await Task.run({ name: 'snapshot' }, async () => {
if (!settings.bypassVdiChainsCheck) {
@@ -181,6 +183,7 @@ exports.VmBackup = class VmBackup {
await this._callWriters(writer => writer.prepare({ isFull }), 'writer.prepare()')
const deltaExport = await exportDeltaVm(exportedVm, baseVm, {
cancelToken: Task.cancelToken,
fullVdisRequired,
})
const sizeContainers = mapValues(deltaExport.streams, stream => watchStreamSize(stream))
@@ -226,6 +229,7 @@ exports.VmBackup = class VmBackup {
async _copyFull() {
const { compression } = this.job
const stream = await this._xapi.VM_export(this.exportedVm.$ref, {
cancelToken: Task.cancelToken,
compress: Boolean(compression) && (compression === 'native' ? 'gzip' : 'zstd'),
useSnapshot: false,
})
@@ -330,10 +334,22 @@ exports.VmBackup = class VmBackup {
this._baseVm = baseVm
this._fullVdisRequired = fullVdisRequired
Task.info('base data', {
vm: baseVm.uuid,
fullVdisRequired: Array.from(fullVdisRequired),
})
}
run = defer(this.run)
async run($defer) {
this.exportedVm = this.vm
this.timestamp = Date.now()
const doSnapshot = this._isDelta || vm.power_state === 'Running' || settings.snapshotRetention !== 0
if (!this._isDelta) {
}
const settings = this._settings
assert(
!settings.offlineBackup || settings.snapshotRetention === 0,
@@ -380,3 +396,6 @@ exports.VmBackup = class VmBackup {
}
}
}
// const { prototype } = exports.VmBackup
// prototype.run = asyncFn.cancelable(prototype.run)

View File

@@ -21,7 +21,7 @@
"@vates/parse-duration": "^0.1.1",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/fs": "^0.17.0",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"@xen-orchestra/template": "^0.1.0",
"compare-versions": "^3.6.0",
"d3-time-format": "^3.0.0",
@@ -38,7 +38,7 @@
"yazl": "^2.5.1"
},
"peerDependencies": {
"@xen-orchestra/xapi": "^0.6.3"
"@xen-orchestra/xapi": "^0.6.2"
},
"license": "AGPL-3.0-or-later",
"author": {

View File

@@ -128,7 +128,7 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
})
}
async _transfer({ timestamp, deltaExport, sizeContainers }) {
async transfer({ timestamp, deltaExport, sizeContainers }) {
const adapter = this._adapter
const backup = this._backup

View File

@@ -77,7 +77,7 @@ exports.DeltaReplicationWriter = class DeltaReplicationWriter extends MixinRepli
return asyncMapSettled(this._oldEntries, vm => vm.$destroy())
}
async _transfer({ timestamp, deltaExport, sizeContainers }) {
async transfer({ timestamp, deltaExport, sizeContainers }) {
const sr = this._sr
const { job, scheduleId, vm } = this._backup

View File

@@ -25,7 +25,7 @@ exports.FullBackupWriter = class FullBackupWriter extends MixinBackupWriter(Abst
)
}
async _run({ timestamp, sizeContainer, stream }) {
async run({ timestamp, sizeContainer, stream }) {
const backup = this._backup
const settings = this._settings

View File

@@ -29,7 +29,7 @@ exports.FullReplicationWriter = class FullReplicationWriter extends MixinReplica
)
}
async _run({ timestamp, sizeContainer, stream }) {
async run({ timestamp, sizeContainer, stream }) {
const sr = this._sr
const settings = this._settings
const { job, scheduleId, vm } = this._backup

View File

@@ -13,14 +13,7 @@ exports.AbstractDeltaWriter = class AbstractDeltaWriter extends AbstractWriter {
throw new Error('Not implemented')
}
async transfer({ timestamp, deltaExport, sizeContainers }) {
try {
return await this._transfer({ timestamp, deltaExport, sizeContainers })
} finally {
// ensure all streams are properly closed
for (const stream of Object.values(deltaExport.streams)) {
stream.destroy()
}
}
transfer({ timestamp, deltaExport, sizeContainers }) {
throw new Error('Not implemented')
}
}

View File

@@ -1,12 +1,7 @@
const { AbstractWriter } = require('./_AbstractWriter.js')
exports.AbstractFullWriter = class AbstractFullWriter extends AbstractWriter {
async run({ timestamp, sizeContainer, stream }) {
try {
return await this._run({ timestamp, sizeContainer, stream })
} finally {
// ensure stream is properly closed
stream.destroy()
}
run({ timestamp, sizeContainer, stream }) {
throw new Error('Not implemented')
}
}

View File

@@ -18,7 +18,7 @@
"preferGlobal": true,
"dependencies": {
"golike-defer": "^0.5.1",
"xen-api": "^0.33.0"
"xen-api": "^0.32.0"
},
"scripts": {
"postversion": "npm publish"

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "@xen-orchestra/defined",
"version": "0.0.1",
"version": "0.0.0",
"license": "ISC",
"description": "Utilities to help handling (possibly) undefined values",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/defined",

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "@xen-orchestra/emit-async",
"version": "0.1.0",
"version": "0.0.0",
"license": "ISC",
"description": "Emit an event for async listeners to settle",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/emit-async",

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "@xen-orchestra/log",
"version": "0.2.1",
"version": "0.2.0",
"license": "ISC",
"description": "Logging system with decoupled producers/consumer",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/log",

View File

@@ -20,8 +20,8 @@
},
"dependencies": {
"@vates/parse-duration": "^0.1.1",
"@xen-orchestra/emit-async": "^0.1.0",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/emit-async": "^0.0.0",
"@xen-orchestra/log": "^0.2.0",
"app-conf": "^0.9.0",
"lodash": "^4.17.21"
},

View File

@@ -140,6 +140,16 @@ ${pkg.name} v${pkg.version}`
}
}
const $import = ({ $import: path }) => {
const data = fs.readFileSync(path, 'utf8')
const ext = extname(path).slice(1).toLowerCase()
const parse = FORMATS[ext]
if (parse === undefined) {
throw new Error(`unsupported file: ${path}`)
}
return visit(parse(data))
}
const seq = async seq => {
const j = callPath.length
for (let i = 0, n = seq.length; i < n; ++i) {
@@ -153,17 +163,13 @@ ${pkg.name} v${pkg.version}`
if (Array.isArray(node)) {
return seq(node)
}
return call(node)
const keys = Object.keys(node)
return keys.length === 1 && keys[0] === '$import' ? $import(node) : call(node)
}
let node
if (file !== '') {
const data = fs.readFileSync(file, 'utf8')
const ext = extname(file).slice(1).toLowerCase()
const parse = FORMATS[ext]
if (parse === undefined) {
throw new Error(`unsupported file: ${file}`)
}
await visit(parse(data))
node = { $import: file }
} else {
const method = args[0]
const params = {}
@@ -176,8 +182,9 @@ ${pkg.name} v${pkg.version}`
params[param.slice(0, j)] = parseValue(param.slice(j + 1))
}
await call({ method, params })
node = { method, params }
}
await visit(node)
}
main(process.argv.slice(2)).then(
() => {

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@xen-orchestra/proxy",
"version": "0.14.1",
"version": "0.13.1",
"license": "AGPL-3.0-or-later",
"description": "XO Proxy used to remotely execute backup jobs",
"keywords": [
@@ -18,8 +18,9 @@
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"preferGlobal": true,
"main": "dist/",
"bin": {
"xo-proxy": "dist/index.mjs"
"xo-proxy": "dist/index.js"
},
"engines": {
"node": ">=14.13"
@@ -28,16 +29,16 @@
"@iarna/toml": "^2.2.0",
"@koa/router": "^10.0.0",
"@vates/compose": "^2.0.0",
"@vates/decorate-with": "^0.1.0",
"@vates/decorate-with": "^0.0.1",
"@vates/disposable": "^0.1.1",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.11.0",
"@xen-orchestra/fs": "^0.17.0",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"@xen-orchestra/mixin": "^0.1.0",
"@xen-orchestra/mixins": "^0.1.0",
"@xen-orchestra/self-signed": "^0.1.0",
"@xen-orchestra/xapi": "^0.6.3",
"@xen-orchestra/xapi": "^0.6.2",
"ajv": "^8.0.3",
"app-conf": "^0.9.0",
"async-iterator-to-stream": "^1.1.0",
@@ -58,7 +59,7 @@
"source-map-support": "^0.5.16",
"stoppable": "^1.0.6",
"xdg-basedir": "^4.0.0",
"xen-api": "^0.33.0",
"xen-api": "^0.32.0",
"xo-common": "^0.7.0"
},
"devDependencies": {
@@ -83,7 +84,7 @@
"prepack": "toggle-scripts +postinstall +preuninstall",
"prepublishOnly": "yarn run build",
"_preuninstall": "./scripts/systemd-service-installer",
"start": "./dist/index.mjs"
"start": "./dist/index.js"
},
"author": {
"name": "Vates SAS",

View File

@@ -1,3 +1,5 @@
import Cancel from 'promise-toolbox/Cancel'
import CancelToken from 'promise-toolbox/CancelToken'
import Disposable from 'promise-toolbox/Disposable.js'
import fromCallback from 'promise-toolbox/fromCallback.js'
import { asyncMap } from '@xen-orchestra/async-map'
@@ -95,7 +97,8 @@ export default class Backups {
error.jobId = jobId
throw error
}
runningJobs[jobId] = true
const source = CancelToken.source()
runningJobs[jobId] = source.cancel
try {
return await run.apply(this, arguments)
} finally {

View File

@@ -0,0 +1,38 @@
import { asyncMapSettled } from '@xen-orchestra/async-map'
export default class Task {
#tasks = new Map()
constructor(app) {
const tasks = new Map()
this.#tasks = tasks
app.api.addMethods({
task: {
*list() {
for (const id of tasks.keys()) {
yield { id }
}
},
cancel: [
({ taskId }) => this.cancel(taskId),
{
params: {
taskId: { type: 'string' },
},
},
],
},
})
app.hooks.on('stop', () => asyncMapSettled(tasks.values(), task => task.cancel()))
}
async cancel(taskId) {
await this.tasks.get(taskId).cancel()
}
register(task) {
this.#tasks.set(task.id, task)
}
}

View File

@@ -27,18 +27,20 @@
"xo-upload-ova": "dist/index.js"
},
"engines": {
"node": ">=10"
"node": ">=8.10"
},
"dependencies": {
"chalk": "^4.1.0",
"exec-promise": "^0.7.0",
"form-data": "^4.0.0",
"fs-extra": "^9.0.0",
"fs-promise": "^2.0.3",
"get-stream": "^6.0.0",
"http-request-plus": "^0.10.0",
"human-format": "^0.11.0",
"l33teral": "^3.0.3",
"lodash": "^4.17.4",
"nice-pipe": "0.0.0",
"pretty-ms": "^7.0.0",
"progress-stream": "^2.0.0",
"pw": "^0.0.4",

View File

@@ -6,7 +6,7 @@ import chalk from 'chalk'
import execPromise from 'exec-promise'
import FormData from 'form-data'
import { createReadStream } from 'fs'
import { stat } from 'fs-extra'
import { stat } from 'fs-promise'
import getStream from 'get-stream'
import hrp from 'http-request-plus'
import humanFormat from 'human-format'
@@ -14,6 +14,7 @@ import l33t from 'l33teral'
import isObject from 'lodash/isObject'
import getKeys from 'lodash/keys'
import startsWith from 'lodash/startsWith'
import nicePipe from 'nice-pipe'
import prettyMs from 'pretty-ms'
import progressStream from 'progress-stream'
import pw from 'pw'
@@ -21,13 +22,10 @@ import stripIndent from 'strip-indent'
import { URL } from 'url'
import Xo from 'xo-lib'
import { parseOVAFile } from 'xo-vmdk-to-vhd'
import { pipeline } from 'stream'
import pkg from '../package'
import { load as loadConfig, set as setConfig, unset as unsetConfig } from './config'
const noop = Function.prototype
function help() {
return stripIndent(
`
@@ -208,7 +206,7 @@ export async function upload(args) {
url = new URL(result[key], baseUrl)
const { size: length } = await stat(file)
const input = pipeline(
const input = nicePipe([
createReadStream(file),
progressStream(
{
@@ -217,8 +215,7 @@ export async function upload(args) {
},
printProgress
),
noop
)
])
formData.append('file', input, { filename: 'file', knownLength: length })
try {
return await hrp.post(url.toString(), { body: formData, headers: formData.getHeaders() }).readAll('utf-8')

View File

@@ -1,6 +1,6 @@
{
"name": "@xen-orchestra/xapi",
"version": "0.6.3",
"version": "0.6.2",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/xapi",
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"repository": {
@@ -25,7 +25,7 @@
"xo-common": "^0.7.0"
},
"peerDependencies": {
"xen-api": "^0.33.0"
"xen-api": "^0.32.0"
},
"scripts": {
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
@@ -38,9 +38,9 @@
"prepublishOnly": "yarn run build"
},
"dependencies": {
"@vates/decorate-with": "^0.1.0",
"@vates/decorate-with": "^0.0.1",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"d3-time-format": "^3.0.0",
"golike-defer": "^0.5.1",
"lodash": "^4.17.15",

View File

@@ -4,44 +4,11 @@
### Released packages
- @vates/decorate-with 0.1.0
## **5.59.0** (2021-05-31)
<img id="latest" src="https://badgen.net/badge/channel/latest/yellow" alt="Channel: latest" />
### Highlights
- [Smart backup] Report missing pools [#2844](https://github.com/vatesfr/xen-orchestra/issues/2844) (PR [#5768](https://github.com/vatesfr/xen-orchestra/pull/5768))
- [Metadata Backup] Add a warning on restoring a metadata backup (PR [#5769](https://github.com/vatesfr/xen-orchestra/pull/5769))
- [Netbox] [Plugin](https://xen-orchestra.com/docs/advanced.html#netbox) to synchronize pools, VMs and IPs with [Netbox](https://netbox.readthedocs.io/en/stable/) (PR [#5783](https://github.com/vatesfr/xen-orchestra/pull/5783))
### Enhancements
- [SAML] Compatible with users created with other authentication providers (PR [#5781](https://github.com/vatesfr/xen-orchestra/pull/5781))
### Bug fixes
- [SDN Controller] Private network creation failure when the tunnels were created on different devices [Forum #4620](https://xcp-ng.org/forum/topic/4620/no-pif-found-in-center) (PR [#5793](https://github.com/vatesfr/xen-orchestra/pull/5793))
### Released packages
- @xen-orchestra/emit-async 0.1.0
- @xen-orchestra/defined 0.0.1
- xo-collection 0.5.0
- @xen-orchestra/log 0.2.1
- xen-api 0.33.0
- @xen-orchestra/xapi 0.6.3
- xo-server-auth-saml 0.9.0
- xo-server-backup-reports 0.16.10
- xo-server-netbox 0.1.1
- xo-server-sdn-controller 1.0.5
- xo-web 5.82.0
- xo-server 5.79.5
- xen-api 0.32
## **5.58.1** (2021-05-06)
<img id="stable" src="https://badgen.net/badge/channel/stable/green" alt="Channel: stable" />
<img id="latest" src="https://badgen.net/badge/channel/latest/yellow" alt="Channel: latest" />
### Bug fixes
@@ -97,6 +64,8 @@
## **5.57.1** (2021-04-13)
<img id="stable" src="https://badgen.net/badge/channel/stable/green" alt="Channel: stable" />
### Enhancements
- [Host/Load-balancer] Add option to disable migration (PR [#5706](https://github.com/vatesfr/xen-orchestra/pull/5706))

View File

@@ -7,18 +7,28 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [OVA import] improve OVA import error reporting (PR [#5797](https://github.com/vatesfr/xen-orchestra/pull/5797))
- [Metadata Backup] Add a warning on restoring a metadata backup (PR [#5769](https://github.com/vatesfr/xen-orchestra/pull/5769))
- [SAML] Compatible with users created with other authentication providers (PR [#5781](https://github.com/vatesfr/xen-orchestra/pull/5781))
- [Netbox] [Plugin](https://xen-orchestra.com/docs/advanced.html#netbox) to synchronize pools, VMs and IPs with [Netbox](https://netbox.readthedocs.io/en/stable/) (PR [#5783](https://github.com/vatesfr/xen-orchestra/pull/5783))
### Bug fixes
> Users must be able to say: “I had this issue, happy to know it's fixed”
- [Smart backup] Report missing pools [#2844](https://github.com/vatesfr/xen-orchestra/issues/2844) (PR [#5768](https://github.com/vatesfr/xen-orchestra/pull/5768))
### Packages to release
> Packages will be released in the order they are here, therefore, they should
> be listed by inverse order of dependency.
>
> Rule of thumb: add packages on top.
> Global order:
>
> - @vates/...
> - @xen-orchestra/...
> - xo-server-...
> - xo-server
> - xo-web
>
> The format is the following: - `$packageName` `$version`
>
@@ -30,5 +40,13 @@
>
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- @xen-orchestra/emit-async minor
- @xen-orchestra/defined patch
- xo-collection minor
- @xen-orchestra/log patch
- xen-api minor
- xo-server-auth-saml minor
- xo-server-backup-reports patch
- xo-server-netbox minor
- xo-web minor
- xo-server patch
- xo-web patch

View File

@@ -14,13 +14,13 @@ As you may have seen in other parts of the documentation, XO is composed of two
### NodeJS
XO needs Node.js. **Please always use latest Node LTS**.
XO needs Node.js. **Please use Node LTS version 14**.
We'll consider at this point that you've got a working node on your box. E.g:
```
$ node -v
v14.17.0
v14.16.0
```
If not, see [this page](https://nodejs.org/en/download/package-manager/) for instructions on how to install Node.

View File

@@ -83,13 +83,13 @@ As you may have seen in other parts of the documentation, XO is composed of two
#### NodeJS
XO needs Node.js. **Please always use latest Node LTS**.
XO needs Node.js. **Please use Node LTS 14**.
We'll consider at this point that you've got a working node on your box. E.g:
```
$ node -v
v14.17.0
v14.16.0
```
If not, see [this page](https://nodejs.org/en/download/package-manager/) for instructions on how to install Node.

View File

@@ -13,12 +13,13 @@
},
"main": "dist/",
"engines": {
"node": ">=10"
"node": ">=8.10"
},
"dependencies": {
"@vates/read-chunk": "^0.1.2",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"async-iterator-to-stream": "^1.0.2",
"core-js": "^3.0.0",
"fs-extra": "^9.0.0",
"limit-concurrency-decorator": "^0.5.0",
"lodash": "^4.17.4",
@@ -34,6 +35,7 @@
"babel-plugin-lodash": "^3.3.2",
"cross-env": "^7.0.2",
"execa": "^5.0.0",
"fs-promise": "^2.0.0",
"get-stream": "^6.0.0",
"readable-stream": "^3.0.6",
"rimraf": "^3.0.0",

View File

@@ -1,3 +1,6 @@
// see https://github.com/babel/babel/issues/8450
import 'core-js/features/symbol/async-iterator'
export { default } from './vhd'
export { default as chainVhd } from './chain'
export { default as checkVhdChain } from './checkChain'

View File

@@ -2,7 +2,7 @@
import execa from 'execa'
import rimraf from 'rimraf'
import tmp from 'tmp'
import { createWriteStream, readFile } from 'fs-extra'
import { createWriteStream, readFile } from 'fs-promise'
import { fromEvent, pFromCallback } from 'promise-toolbox'
import { pipeline } from 'readable-stream'

View File

@@ -39,7 +39,7 @@
"human-format": "^0.11.0",
"lodash": "^4.17.4",
"pw": "^0.0.4",
"xen-api": "^0.33.0"
"xen-api": "^0.32.0"
},
"devDependencies": {
"@babel/cli": "^7.1.5",

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "xen-api",
"version": "0.33.0",
"version": "0.32.0",
"license": "ISC",
"description": "Connector to the Xen API",
"keywords": [
@@ -45,7 +45,7 @@
"promise-toolbox": "^0.19.2",
"pw": "0.0.4",
"xmlrpc": "^1.3.2",
"xo-collection": "^0.5.0"
"xo-collection": "^0.4.1"
},
"devDependencies": {
"@babel/cli": "^7.0.0",

View File

@@ -291,6 +291,16 @@ export class Xapi extends EventEmitter {
return this._roCall(`${type}.get_${field}`, [ref])
}
async getFields(type, ref, fields) {
const values = {}
await Promise.all(
fields.map(async field => {
values[field] = await this._sessionCall(`${type}.get_${field}`, [ref])
})
)
return this._wrapRecord(type, ref, values)
}
setField(type, ref, field, value) {
return this.call(`${type}.set_${field}`, ref, value).then(noop)
}

View File

@@ -27,19 +27,20 @@
"xo-cli": "dist/index.js"
},
"engines": {
"node": ">=10"
"node": ">=8.10"
},
"dependencies": {
"bluebird": "^3.5.1",
"chalk": "^4.1.0",
"exec-promise": "^0.7.0",
"fs-extra": "^9.0.0",
"fs-promise": "^2.0.3",
"http-request-plus": "^0.10.0",
"human-format": "^0.11.0",
"l33teral": "^3.0.3",
"lodash": "^4.17.4",
"micromatch": "^4.0.2",
"mkdirp": "^1.0.4",
"nice-pipe": "0.0.0",
"pretty-ms": "^7.0.0",
"progress-stream": "^2.0.0",
"promise-toolbox": "^0.19.2",

View File

@@ -8,7 +8,7 @@ Bluebird.longStackTraces()
const createReadStream = require('fs').createReadStream
const createWriteStream = require('fs').createWriteStream
const resolveUrl = require('url').resolve
const stat = require('fs-extra').stat
const stat = require('fs-promise').stat
const chalk = require('chalk')
const forEach = require('lodash/forEach')
@@ -19,6 +19,7 @@ const humanFormat = require('human-format')
const identity = require('lodash/identity')
const isObject = require('lodash/isObject')
const micromatch = require('micromatch')
const nicePipe = require('nice-pipe')
const pairs = require('lodash/toPairs')
const pick = require('lodash/pick')
const pump = require('pump')
@@ -26,7 +27,7 @@ const prettyMs = require('pretty-ms')
const progressStream = require('progress-stream')
const pw = require('pw')
const Xo = require('xo-lib').default
const { PassThrough, pipeline } = require('stream')
const { PassThrough } = require('stream')
// -------------------------------------------------------------------
@@ -79,8 +80,6 @@ function extractFlags(args) {
return flags
}
const noop = Function.prototype
const PARAM_RE = /^([^=]+)=([^]*)$/
function parseParameters(args) {
const params = {}
@@ -396,7 +395,7 @@ async function call(args) {
url = resolveUrl(baseUrl, result[key])
const { size: length } = await stat(file)
const input = pipeline(
const input = nicePipe([
createReadStream(file),
progressStream(
{
@@ -405,8 +404,7 @@ async function call(args) {
},
printProgress
),
noop
)
])
return hrp
.post(url, {

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "xo-collection",
"version": "0.5.0",
"version": "0.4.1",
"license": "AGPL-3.0-or-later",
"description": "Generic in-memory collection with events",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-collection",

View File

@@ -42,11 +42,15 @@
"devDependencies": {
"@types/node": "^14.0.9",
"@types/through2": "^2.0.31",
"tslint": "^5.9.1",
"tslint-config-standard": "^9.0.0",
"typescript": "^3.1.6"
},
"scripts": {
"build": "tsc",
"dev": "tsc -w",
"lint": "tslint 'src/*.ts'",
"posttest": "yarn run lint",
"prepublishOnly": "yarn run build",
"start": "node dist/index.js",
"postversion": "npm publish"

View File

@@ -0,0 +1,3 @@
{
"extends": "tslint-config-standard"
}

View File

@@ -47,7 +47,7 @@
"dependencies": {
"@xen-orchestra/audit-core": "^0.2.0",
"@xen-orchestra/cron": "^1.0.6",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"async-iterator-to-stream": "^1.1.0",
"promise-toolbox": "^0.19.2",
"readable-stream": "^3.5.0",

View File

@@ -1,6 +1,6 @@
{
"name": "xo-server-auth-saml",
"version": "0.9.0",
"version": "0.8.0",
"license": "AGPL-3.0-or-later",
"description": "SAML authentication plugin for XO-Server",
"keywords": [

View File

@@ -1,6 +1,6 @@
{
"name": "xo-server-backup-reports",
"version": "0.16.10",
"version": "0.16.9",
"license": "AGPL-3.0-or-later",
"description": "Backup reports plugin for XO-Server",
"keywords": [
@@ -32,8 +32,8 @@
"node": ">=6"
},
"dependencies": {
"@xen-orchestra/defined": "^0.0.1",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/defined": "^0.0.0",
"@xen-orchestra/log": "^0.2.0",
"human-format": "^0.11.0",
"lodash": "^4.13.1",
"moment-timezone": "^0.5.13"

View File

@@ -1,6 +1,6 @@
{
"name": "xo-server-netbox",
"version": "0.1.1",
"version": "0.0.0",
"license": "AGPL-3.0-or-later",
"description": "Synchronizes pools managed by Xen Orchestra with Netbox",
"keywords": [
@@ -28,18 +28,17 @@
"engines": {
"node": ">=14.6"
},
"dependencies": {
"@xen-orchestra/log": "^0.2.1",
"is-in-subnet": "^4.0.1",
"lodash": "^4.17.21"
},
"devDependencies": {
"@babel/cli": "^7.13.16",
"@babel/core": "^7.14.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
"@babel/preset-env": "^7.14.1",
"cross-env": "^7.0.3"
"@xen-orchestra/log": "^0.2.0",
"assert": "^2.0.0",
"cross-env": "^7.0.3",
"is-in-subnet": "^4.0.1",
"lodash": "^4.17.21"
},
"scripts": {
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",

View File

@@ -16,7 +16,7 @@
"predev": "yarn run prebuild",
"prepublishOnly": "yarn run build"
},
"version": "1.0.5",
"version": "1.0.4",
"engines": {
"node": ">=8.10"
},
@@ -29,7 +29,7 @@
"cross-env": "^7.0.2"
},
"dependencies": {
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"@xen-orchestra/openflow": "^0.1.1",
"@vates/coalesce-calls": "^0.1.0",
"ipaddr.js": "^1.9.1",

View File

@@ -62,10 +62,8 @@ export class PrivateNetwork {
const hostPif = hostClient.host.$PIFs.find(
pif => pif?.device === pifDevice && pif.VLAN === pifVlan && pif.ip_configuration_mode !== 'None'
)
const centerDevice = centerNetwork.other_config['xo:sdn-controller:pif-device']
const centerVlan = +centerNetwork.other_config['xo:sdn-controller:vlan']
const centerPif = centerClient.host.$PIFs.find(
pif => pif?.device === centerDevice && pif.VLAN === centerVlan && pif.ip_configuration_mode !== 'None'
pif => pif?.device === pifDevice && pif.VLAN === pifVlan && pif.ip_configuration_mode !== 'None'
)
assert(hostPif !== undefined, 'No PIF found', {
privateNetwork: this.uuid,

View File

@@ -26,7 +26,7 @@
"@babel/plugin-proposal-decorators": "^7.4.0",
"@babel/preset-env": "^7.1.6",
"@iarna/toml": "^2.2.1",
"@vates/decorate-with": "^0.1.0",
"@vates/decorate-with": "^0.0.1",
"@vates/parse-duration": "^0.1.1",
"app-conf": "^0.9.0",
"babel-plugin-lodash": "^3.2.11",
@@ -34,7 +34,7 @@
"jest": "^26.6.3",
"lodash": "^4.17.11",
"promise-toolbox": "^0.19.2",
"xo-collection": "^0.5.0",
"xo-collection": "^0.4.1",
"xo-common": "^0.7.0",
"xo-lib": "^0.10.1"
},

View File

@@ -5,9 +5,9 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { getConfig, getMainConnection, getSrId, waitObjectState } from './util'
import { map } from 'lodash'
import eventToPromise from 'event-to-promise'
// ===================================================================
@@ -27,7 +27,7 @@ describe('disk', () => {
const config = await getConfig()
serverId = await xo.call('server.add', Object.assign({ autoConnect: false }, config.xenServer1))
await xo.call('server.connect', { id: serverId })
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
srId = await getSrId(xo)
})

View File

@@ -3,7 +3,7 @@
// Doc: https://github.com/moll/js-must/blob/master/doc/API.md#must
import expect from 'must'
import fromEvent from 'promise-toolbox/fromEvent'
import eventToPromise from 'event-to-promise'
import { getAllHosts, getConfig, getMainConnection, getVmToMigrateId, waitObjectState } from './util'
import { find, forEach } from 'lodash'
@@ -21,7 +21,7 @@ describe('host', () => {
let config
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer2).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
hostId = getHost(config.host1)
})

View File

@@ -5,8 +5,8 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { getConfig, getMainConnection, waitObjectState } from './util'
import eventToPromise from 'event-to-promise'
import { find } from 'lodash'
// ===================================================================
@@ -21,7 +21,7 @@ describe('pool', () => {
jest.setTimeout(10e3)
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer1).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
poolId = getPoolId()
})

View File

@@ -5,8 +5,8 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { getConfig, getMainConnection, getSchedule, jobTest, scheduleTest } from './util'
import eventToPromise from 'event-to-promise'
import { map } from 'lodash'
// ===================================================================
@@ -23,7 +23,7 @@ describe('schedule', () => {
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer1).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
jobId = await jobTest(xo)
})

View File

@@ -5,8 +5,8 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { jobTest, scheduleTest, getConfig, getMainConnection, getSchedule } from './util'
import eventToPromise from 'event-to-promise'
// ===================================================================
@@ -22,7 +22,7 @@ describe('scheduler', () => {
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer1).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
jobId = await jobTest(xo)
scheduleId = (await scheduleTest(xo, jobId)).id

View File

@@ -5,9 +5,9 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { getConfig, getMainConnection, getVmXoTestPvId, getOneHost, waitObjectState } from './util'
import { map } from 'lodash'
import eventToPromise from 'event-to-promise'
// ===================================================================
@@ -27,7 +27,7 @@ describe('vbd', () => {
serverId = await xo.call('server.add', Object.assign({ autoConnect: false }, config.xenServer1))
await xo.call('server.connect', { id: serverId })
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
vmId = await getVmXoTestPvId(xo)
try {

View File

@@ -5,8 +5,8 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import { getConfig, getMainConnection, getNetworkId, waitObjectState, getVmXoTestPvId } from './util'
import eventToPromise from 'event-to-promise'
import { map } from 'lodash'
// ===================================================================
@@ -24,7 +24,7 @@ describe('vif', () => {
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer1).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
vmId = await getVmXoTestPvId(xo)
try {

View File

@@ -5,7 +5,6 @@ import expect from 'must'
// ===================================================================
import fromEvent from 'promise-toolbox/fromEvent'
import {
almostEqual,
getAllHosts,
@@ -19,6 +18,7 @@ import {
waitObjectState,
} from './util'
import { map, find } from 'lodash'
import eventToPromise from 'event-to-promise'
// ===================================================================
@@ -35,7 +35,7 @@ describe('vm', () => {
jest.setTimeout(10e3)
;[xo, config] = await Promise.all([getMainConnection(), getConfig()])
serverId = await xo.call('server.add', config.xenServer1).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
})
// ----------------------------------------------------------------------
@@ -347,7 +347,7 @@ describe('vm', () => {
beforeAll(async () => {
secondServerId = await xo.call('server.add', config.xenServer2).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
vmId = await getVmToMigrateId(xo)
@@ -393,7 +393,7 @@ describe('vm', () => {
beforeAll(async () => {
secondServerId = await xo.call('server.add', config.xenServer2).catch(() => {})
await fromEvent(xo.objects, 'finish')
await eventToPromise(xo.objects, 'finish')
vmId = await getVmToMigrateId(xo)

View File

@@ -29,8 +29,8 @@
"node": ">=6"
},
"dependencies": {
"node-xmpp-client": "^3.0.0",
"promise-toolbox": "^0.19.2"
"event-to-promise": "^0.8.0",
"node-xmpp-client": "^3.0.0"
},
"devDependencies": {
"@babel/cli": "^7.0.0",

View File

@@ -1,4 +1,4 @@
import fromEvent from 'promise-toolbox/fromEvent'
import eventToPromise from 'event-to-promise'
import XmppClient from 'node-xmpp-client'
// ===================================================================
@@ -55,8 +55,8 @@ class TransportXmppPlugin {
this._client = new XmppClient(this._conf)
this._client.on('error', () => {})
await fromEvent(this._client.connection.socket, 'data')
await fromEvent(this._client, 'online')
await eventToPromise(this._client.connection.socket, 'data')
await eventToPromise(this._client, 'online')
this._unset = this._set('sendToXmppClient', this._sendToXmppClient)
}

View File

@@ -31,7 +31,7 @@
"dependencies": {
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/cron": "^1.0.6",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"csv-stringify": "^5.5.0",
"handlebars": "^4.0.6",
"html-minifier": "^4.0.0",

View File

@@ -29,7 +29,7 @@
"node": ">=8.10"
},
"dependencies": {
"@xen-orchestra/log": "^0.2.1"
"@xen-orchestra/log": "^0.2.0"
},
"devDependencies": {
"@babel/cli": "^7.7.0",

View File

@@ -162,7 +162,7 @@ vdiExportConcurrency = 12
vmExportConcurrency = 2
vmSnapshotConcurrency = 2
[xo-proxy]
["xo-proxy"]
callTimeout = '1 min'
channel = 'xo-proxy-appliance'

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "xo-server",
"version": "5.79.5",
"version": "5.79.3",
"license": "AGPL-3.0-or-later",
"description": "Server part of Xen-Orchestra",
"keywords": [
@@ -24,12 +24,12 @@
"xo-server-recover-account": "dist/recover-account-cli.mjs"
},
"engines": {
"node": ">=14.17"
"node": ">=14.13"
},
"dependencies": {
"@iarna/toml": "^2.2.1",
"@vates/compose": "^2.0.0",
"@vates/decorate-with": "^0.1.0",
"@vates/decorate-with": "^0.0.1",
"@vates/disposable": "^0.1.1",
"@vates/multi-key-map": "^0.1.0",
"@vates/parse-duration": "^0.1.1",
@@ -37,15 +37,15 @@
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.11.0",
"@xen-orchestra/cron": "^1.0.6",
"@xen-orchestra/defined": "^0.0.1",
"@xen-orchestra/emit-async": "^0.1.0",
"@xen-orchestra/defined": "^0.0.0",
"@xen-orchestra/emit-async": "^0.0.0",
"@xen-orchestra/fs": "^0.17.0",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/log": "^0.2.0",
"@xen-orchestra/mixin": "^0.1.0",
"@xen-orchestra/mixins": "^0.1.0",
"@xen-orchestra/self-signed": "^0.1.0",
"@xen-orchestra/template": "^0.1.0",
"@xen-orchestra/xapi": "^0.6.3",
"@xen-orchestra/xapi": "^0.6.2",
"ajv": "^8.0.3",
"app-conf": "^0.9.0",
"async-iterator-to-stream": "^1.0.1",
@@ -125,9 +125,9 @@
"vhd-lib": "^1.0.0",
"ws": "^7.1.2",
"xdg-basedir": "^4.0.0",
"xen-api": "^0.33.0",
"xen-api": "^0.32.0",
"xo-acl-resolver": "^0.4.1",
"xo-collection": "^0.5.0",
"xo-collection": "^0.4.1",
"xo-common": "^0.7.0",
"xo-remote-parser": "^0.7.0",
"xo-vmdk-to-vhd": "^2.0.0"

View File

@@ -1256,42 +1256,38 @@ async function handleVmImport(req, res, { data, srId, type, xapi }) {
// Timeout seems to be broken in Node 4.
// See https://github.com/nodejs/node/issues/3319
req.setTimeout(43200000) // 12 hours
const vm = await new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
const form = new multiparty.Form()
const promises = []
const tables = {}
form.on('error', reject)
form.on('part', async part => {
try {
if (part.name !== 'file') {
promises.push(
(async () => {
if (!(part.filename in tables)) {
tables[part.filename] = {}
}
const view = new DataView((await getStream.buffer(part)).buffer)
const result = new Uint32Array(view.byteLength / 4)
for (const i in result) {
result[i] = view.getUint32(i * 4, true)
}
tables[part.filename][part.name] = result
data.tables = tables
})()
)
} else {
await Promise.all(promises)
// XVA files are directly sent to xcp-ng who wants a content-length
part.length = part.byteCount
resolve(xapi.importVm(part, { data, srId, type }))
}
} catch (e) {
// multiparty is not promise-aware, we have to chain errors ourselves.
reject(e)
if (part.name !== 'file') {
promises.push(
(async () => {
if (!(part.filename in tables)) {
tables[part.filename] = {}
}
const view = new DataView((await getStream.buffer(part)).buffer)
const result = new Uint32Array(view.byteLength / 4)
for (const i in result) {
result[i] = view.getUint32(i * 4, true)
}
tables[part.filename][part.name] = result
data.tables = tables
})()
)
} else {
await Promise.all(promises)
// XVA files are directly sent to xcp-ng who wants a content-length
part.length = part.byteCount
const vm = await xapi.importVm(part, { data, srId, type })
res.end(format.response(0, vm.$id))
resolve()
}
})
form.parse(req)
})
res.end(format.response(0, vm.$id))
}
// TODO: "sr_id" can be passed in URL to target a specific SR
@@ -1301,18 +1297,12 @@ async function import_({ data, sr, type }) {
}
return {
$sendTo: await this.registerApiHttpRequest(
'vm.import',
this.session,
handleVmImport,
{
data,
srId: sr._xapiId,
type,
xapi: this.getXapi(sr),
},
{ exposeAllErrors: true }
),
$sendTo: await this.registerHttpRequest(handleVmImport, {
data,
srId: sr._xapiId,
type,
xapi: this.getXapi(sr),
}),
}
}

View File

@@ -1102,9 +1102,6 @@ export default class Xapi extends XapiBase {
const vdis = {}
const compression = {}
const vifDevices = await this.call('VM.get_allowed_VIF_devices', vm.$ref)
if (networks.length > vifDevices.length) {
throw operationFailed({ objectId: vm.id, code: 'TOO_MANY_VIFs' })
}
await Promise.all(
map(disks, async disk => {
const vdi = (vdis[disk.path] = await this.createVdi({

View File

@@ -6,7 +6,7 @@ import kindOf from 'kindof'
import ms from 'ms'
import schemaInspector from 'schema-inspector'
import { getBoundPropertyDescriptor } from 'bind-property-descriptor'
import { format, JsonRpcError, MethodNotFound } from 'json-rpc-peer'
import { MethodNotFound } from 'json-rpc-peer'
import * as methods from '../api/index.mjs'
import * as sensitiveValues from '../sensitive-values.mjs'
@@ -376,47 +376,4 @@ export default class Api {
throw error
}
}
registerApiHttpRequest(method, session, fn, data, { exposeAllErrors = false, ...opts } = {}) {
const app = this._app
const logger = this._logger
return app.registerHttpRequest(
async function (req, res) {
const timestamp = Date.now()
try {
return await fn.apply(this, arguments)
} catch (error) {
const userId = session.get('user_id', undefined)
const user = userId && (await app.getUser(userId))
logger.error(`handleVmImport =!> ${error}`, {
callId: Math.random().toString(36).slice(2),
// userId,
userName: user?.email ?? '(unknown user)',
userIp: session.get('user_ip', undefined),
method: `HTTP handler of ${method}`,
timestamp,
duration: Date.now() - timestamp,
error: serializeError(error),
})
if (!res.headersSent) {
res.statusCode = 500
res.setHeader('Content-Type', 'application/json')
res.write(
format.error(
0,
exposeAllErrors && error != null && typeof error.toJsonRpcError !== 'function'
? new JsonRpcError(error.message, error.code, error.data)
: error
)
)
}
res.end()
}
},
data,
opts
)
}
}

View File

@@ -18,10 +18,11 @@
"preferGlobal": false,
"main": "dist/",
"engines": {
"node": ">=10"
"node": ">=6"
},
"dependencies": {
"child-process-promise": "^2.0.3",
"core-js": "^3.0.0",
"lodash": "^4.17.15",
"pako": "^1.0.11",
"promise-toolbox": "^0.19.2",
@@ -34,10 +35,10 @@
"@babel/preset-env": "^7.0.0",
"babel-plugin-lodash": "^3.3.2",
"cross-env": "^7.0.2",
"event-to-promise": "^0.8.0",
"execa": "^5.0.0",
"fs-extra": "^9.0.0",
"get-stream": "^6.0.0",
"promise-toolbox": "^0.19.2",
"rimraf": "^3.0.0",
"tmp": "^0.2.1"
},

View File

@@ -1,3 +1,6 @@
// see https://github.com/babel/babel/issues/8450
import 'core-js/features/symbol/async-iterator'
import assert from 'assert'
import zlib from 'zlib'

View File

@@ -1,7 +1,7 @@
/* eslint-env jest */
import execa from 'execa'
import fromEvent from 'promise-toolbox/fromEvent'
import eventToPromise from 'event-to-promise'
import getStream from 'get-stream'
import rimraf from 'rimraf'
import tmp from 'tmp'
@@ -54,7 +54,7 @@ test('VMDK to VHD can convert a random data file with VMDKDirectParser', async (
const pipe = (
await vmdkToVhd(createReadStream(vmdkFileName), result.grainLogicalAddressList, result.grainFileOffsetList)
).pipe(createWriteStream(vhdFileName))
await fromEvent(pipe, 'finish')
await eventToPromise(pipe, 'finish')
await execa('vhd-util', ['check', '-p', '-b', '-t', '-n', vhdFileName])
await execa('qemu-img', ['convert', '-fvmdk', '-Oraw', vmdkFileName, reconvertedFromVmdk])
await execa('qemu-img', ['convert', '-fvpc', '-Oraw', vhdFileName, reconvertedFromVhd])

View File

@@ -261,7 +261,11 @@ gulp.task(function buildScripts() {
],
}),
require('gulp-sourcemaps').init({ loadMaps: true }),
PRODUCTION && require('gulp-terser')(),
PRODUCTION &&
require('gulp-uglify/composer')(require('uglify-es'))({
// 2019-09-04 Disabling inline optimization until https://github.com/mishoo/UglifyJS2/issues/2842 is fixed
compress: { inline: false },
}),
dest()
)
})

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "xo-web",
"version": "5.82.0",
"version": "5.81.0",
"license": "AGPL-3.0-or-later",
"description": "Web interface client for Xen-Orchestra",
"keywords": [
@@ -39,8 +39,8 @@
"@babel/register": "^7.13.8",
"@nraynaud/novnc": "0.6.1",
"@xen-orchestra/cron": "^1.0.6",
"@xen-orchestra/defined": "^0.0.1",
"@xen-orchestra/log": "^0.2.1",
"@xen-orchestra/defined": "^0.0.0",
"@xen-orchestra/log": "^0.2.0",
"@xen-orchestra/template": "^0.1.0",
"ansi_up": "^4.0.3",
"asap": "^2.0.6",
@@ -61,6 +61,7 @@
"enzyme": "^3.3.0",
"enzyme-adapter-react-15": "^1.0.5",
"enzyme-to-json": "^3.3.0",
"event-to-promise": "^0.8.0",
"font-awesome": "^4.7.0",
"font-mfizz": "^2.4.1",
"get-stream": "^4.0.0",
@@ -73,7 +74,7 @@
"gulp-refresh": "^1.1.0",
"gulp-sass": "^4.0.1",
"gulp-sourcemaps": "^2.6.2",
"gulp-terser": "^2.0.1",
"gulp-uglify": "^3.0.0",
"gulp-watch": "^5.0.0",
"human-format": "^0.11.0",
"immutable": "^4.0.0-rc.9",
@@ -126,6 +127,7 @@
"semver": "^6.0.0",
"strip-ansi": "^5.2.0",
"styled-components": "^3.1.5",
"uglify-es": "^3.3.4",
"uncontrollable-input": "^0.1.1",
"url-parse": "^1.2.0",
"value-matcher": "^0.2.0",

View File

@@ -1465,16 +1465,21 @@ export const importVm = async (file, type = 'xva', data = undefined, sr) => {
}
}
}
const result = await _call('vm.import', { type, data, sr: resolveId(sr) })
formData.append('file', file)
const res = await post(result.$sendTo, formData)
const json = await res.json()
if (res.status !== 200) {
error(_('vmImportFailed'), name)
throw json.error
}
success(_('vmImportSuccess'), name)
return json.result
return _call('vm.import', { type, data, sr: resolveId(sr) }).then(async ({ $sendTo }) => {
formData.append('file', file)
return post($sendTo, formData)
.then(res => {
if (res.status !== 200) {
throw res.status
}
success(_('vmImportSuccess'), name)
return res.json().then(body => body.result)
})
.catch(err => {
error(_('vmImportFailed'), name)
throw err
})
})
}
import ImportVdiModalBody from './import-vdi-modal' // eslint-disable-line import/first

View File

@@ -1,5 +1,5 @@
import eventToPromise from 'event-to-promise'
import forEach from 'lodash/forEach'
import fromEvents from 'promise-toolbox/fromEvents'
import makeError from 'make-error'
import map from 'lodash/map'
import { AbortedConnection, ConnectionError, JsonRpcWebSocketClient as Client } from 'jsonrpc-websocket-client'
@@ -191,7 +191,7 @@ class XoaUpdater extends EventEmitter {
if (c.status === 'open') {
return c
} else {
return fromEvents(c, ['open'], ['closed', 'error']).then(() => c)
return eventToPromise.multi(c, ['open'], ['closed', 'error']).then(() => c)
}
}

View File

@@ -1,4 +1,5 @@
.*
gitignore-
/benchmark/
/benchmarks/

267
yarn.lock
View File

@@ -2398,7 +2398,7 @@ ansi_up@^4.0.3:
resolved "https://registry.yarnpkg.com/ansi_up/-/ansi_up-4.0.4.tgz#5b8c35f0b02e4476f3f18cf89c3bf48d15d054f6"
integrity sha512-vRxC8q6QY918MbehO869biJW4tiunJdjOhi5fpY6NLOliBQlZhOkKgABJKJqH+JZfb/WfjvjN1chLWI6tODerw==
any-promise@^1.1.0:
any-promise@^1.0.0, any-promise@^1.1.0, any-promise@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
@@ -2706,6 +2706,16 @@ assert@^1.1.1, assert@^1.4.0:
object-assign "^4.1.1"
util "0.10.3"
assert@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32"
integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==
dependencies:
es6-object-assign "^1.1.0"
is-nan "^1.2.1"
object-is "^1.0.1"
util "^0.12.0"
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
@@ -2811,6 +2821,13 @@ autoprefixer@^9.5.1, autoprefixer@^9.6.1:
postcss "^7.0.32"
postcss-value-parser "^4.1.0"
available-typed-arrays@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.3.tgz#fb7d02445bfedefad79fad1fe47931163a227198"
integrity sha512-CuPhFULixV/d89POo1UG4GqGbR7dmrefY2ZdmsYakeR4gOSJXoF7tfeaiqMHGOMrlTiJoeEs87fpLsBYmE2BMw==
dependencies:
array.prototype.filter "^1.0.0"
aws-sdk@^2.686.0:
version "2.913.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.913.0.tgz#633623dce1cf219ee333a0c1a0040988f67e0e5c"
@@ -3547,6 +3564,11 @@ buffers@~0.1.1:
resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb"
integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s=
builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@@ -4269,7 +4291,7 @@ combokeys@^3.0.1:
resolved "https://registry.yarnpkg.com/combokeys/-/combokeys-3.0.1.tgz#fc8ca5c3f5f2d2b03a458544cb88b14ab5f53f86"
integrity sha512-5nAfaLZ3oO3kA+/xdoL7t197UJTz2WWidyH3BBeU6hqHtvyFERICd0y3DQFrQkJFTKBrtUDck/xCLLoFpnjaCw==
commander@2, commander@^2.19.0, commander@^2.20.0:
commander@2, commander@^2.12.1, commander@^2.19.0, commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -4289,6 +4311,11 @@ commander@^6.2.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==
commander@~2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
@@ -4539,7 +4566,7 @@ core-js@^2.4.0, core-js@^2.5.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.6.4, core-js@^3.6.5:
core-js@^3.0.0, core-js@^3.6.4, core-js@^3.6.5:
version "3.12.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112"
integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==
@@ -5591,6 +5618,11 @@ diff-sequences@^26.6.2:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@@ -5672,6 +5704,14 @@ docsearch.js@^2.5.2:
to-factory "^1.0.0"
zepto "^1.2.0"
doctrine@0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523"
integrity sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=
dependencies:
esutils "^1.1.6"
isarray "0.0.1"
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -6128,6 +6168,11 @@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3:
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-object-assign@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
es6-promise@^4.1.0:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@@ -6424,6 +6469,11 @@ estraverse@^5.1.0, estraverse@^5.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
esutils@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375"
integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@@ -7231,6 +7281,14 @@ fs-constants@^1.0.0:
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35"
integrity sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
@@ -7274,6 +7332,16 @@ fs-mkdirp-stream@^1.0.0:
graceful-fs "^4.1.11"
through2 "^2.0.3"
fs-promise@^2.0.0, fs-promise@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854"
integrity sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=
dependencies:
any-promise "^1.3.0"
fs-extra "^2.0.0"
mz "^2.6.0"
thenify-all "^1.6.0"
fs-readdir-recursive@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
@@ -7824,15 +7892,21 @@ gulp-sourcemaps@^2.6.2:
strip-bom-string "1.X"
through2 "2.X"
gulp-terser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/gulp-terser/-/gulp-terser-2.0.1.tgz#5f8f4fc54588b79519243809cc8eef4936286d0d"
integrity sha512-XCrnCXP8ovNpgLK9McJIXlgm0j3W2TsiWu7K9y3m+Sn5XZgUzi6U8MPHtS3NdLMic9poCj695N0ARJ2B6atypw==
gulp-uglify@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.2.tgz#5f5b2e8337f879ca9dec971feb1b82a5a87850b0"
integrity sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==
dependencies:
plugin-error "^1.0.1"
terser "5.4.0"
through2 "^4.0.2"
vinyl-sourcemaps-apply "^0.2.1"
array-each "^1.0.1"
extend-shallow "^3.0.2"
gulplog "^1.0.0"
has-gulplog "^0.1.0"
isobject "^3.0.1"
make-error-cause "^1.1.1"
safe-buffer "^5.1.2"
through2 "^2.0.0"
uglify-js "^3.0.5"
vinyl-sourcemaps-apply "^0.2.0"
gulp-util@^3.0.2:
version "3.0.8"
@@ -9063,6 +9137,14 @@ is-ip@^3.1.0:
dependencies:
ip-regex "^4.0.0"
is-nan@^1.2.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==
dependencies:
call-bind "^1.0.0"
define-properties "^1.1.3"
is-negated-glob@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2"
@@ -9235,6 +9317,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
is-typed-array@^1.1.3:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e"
integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==
dependencies:
available-typed-arrays "^1.0.2"
call-bind "^1.0.2"
es-abstract "^1.18.0-next.2"
foreach "^2.0.5"
has-symbols "^1.0.1"
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -9936,6 +10029,13 @@ json5@^2.0.1, json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -10841,7 +10941,14 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
dependencies:
semver "^6.0.0"
make-error@^1, make-error@^1.0.2, make-error@^1.0.4, make-error@^1.2.1, make-error@^1.2.3, make-error@^1.3.0, make-error@^1.3.2, make-error@^1.3.5:
make-error-cause@^1.1.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
integrity sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=
dependencies:
make-error "^1.2.0"
make-error@^1, make-error@^1.0.2, make-error@^1.0.4, make-error@^1.2.0, make-error@^1.2.1, make-error@^1.2.3, make-error@^1.3.0, make-error@^1.3.2, make-error@^1.3.5:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
@@ -11433,6 +11540,15 @@ mute-stream@0.0.8:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
mz@^2.6.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@^2.12.1, nan@^2.13.2:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
@@ -11511,6 +11627,11 @@ next-tick@~1.0.0:
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
nice-pipe@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/nice-pipe/-/nice-pipe-0.0.0.tgz#0e2069551244d64ce686a716511892fe4fb1d63a"
integrity sha1-DiBpVRJE1kzmhqcWURiS/k+x1jo=
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
@@ -14611,7 +14732,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.2.0, resolve@^1.20.0, resolve@^1.4.0:
resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.2.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.4.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@@ -14886,7 +15007,7 @@ semver-regex@^3.1.2:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807"
integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -15280,7 +15401,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
source-map-url "^0.4.0"
urix "^0.1.0"
source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19:
source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@@ -15315,7 +15436,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3, source-map@~0.7.2:
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
@@ -16042,15 +16163,6 @@ terser-webpack-plugin@^1.4.3:
webpack-sources "^1.4.0"
worker-farm "^1.7.0"
terser@5.4.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.4.0.tgz#9815c0839072d5c894e22c6fc508fbe9f5e7d7e8"
integrity sha512-3dZunFLbCJis9TAF2VnX+VrQLctRUmt1p3W2kCsJuZE4ZgWqh//+1MZ62EanewrqKoUf4zIaDGZAvml4UDc0OQ==
dependencies:
commander "^2.20.0"
source-map "~0.7.2"
source-map-support "~0.5.19"
terser@^4.1.2:
version "4.8.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
@@ -16079,6 +16191,20 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
thenify-all@^1.0.0, thenify-all@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.1"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
thirty-two@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a"
@@ -16354,7 +16480,12 @@ tsconfig-paths@^3.9.0:
minimist "^1.2.0"
strip-bom "^3.0.0"
tslib@^1.9.0:
tslib@1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@@ -16364,11 +16495,60 @@ tslib@^2.0.1, tslib@^2.2.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
tslint-config-standard@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/tslint-config-standard/-/tslint-config-standard-9.0.0.tgz#349a94819d93d5f8d803e3c71cb58ef38eff88e0"
integrity sha512-CAw9J743RnPMemQV/XQ4YyNreC+A1NItACfkm+cBedrOkz6CQfwlnbKn8anUXBfoa4Zo4tjAhblRbsMNcSLfSw==
dependencies:
tslint-eslint-rules "^5.3.1"
tslint-eslint-rules@^5.3.1:
version "5.4.0"
resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5"
integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==
dependencies:
doctrine "0.7.2"
tslib "1.9.0"
tsutils "^3.0.0"
tslint@^5.9.1:
version "5.20.1"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d"
integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==
dependencies:
"@babel/code-frame" "^7.0.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^4.0.1"
glob "^7.1.1"
js-yaml "^3.13.1"
minimatch "^3.0.4"
mkdirp "^0.5.1"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.29.0"
tsscmp@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
tsutils@^2.29.0:
version "2.29.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"
tsutils@^3.0.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@@ -16475,6 +16655,14 @@ uc.micro@^1.0.1, uc.micro@^1.0.5:
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
uglify-es@^3.3.4:
version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
uglify-js@3.4.x:
version "3.4.10"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
@@ -16493,7 +16681,7 @@ uglify-js@^2.6.1:
optionalDependencies:
uglify-to-browserify "~1.0.0"
uglify-js@^3.1.4, uglify-js@^3.5.1:
uglify-js@^3.0.5, uglify-js@^3.1.4, uglify-js@^3.5.1:
version "3.13.7"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.7.tgz#25468a3b39b1c875df03f0937b2b7036a93f3fee"
integrity sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==
@@ -16823,6 +17011,18 @@ util@^0.11.0:
dependencies:
inherits "2.0.3"
util@^0.12.0:
version "0.12.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888"
integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==
dependencies:
inherits "^2.0.3"
is-arguments "^1.0.4"
is-generator-function "^1.0.7"
is-typed-array "^1.1.3"
safe-buffer "^5.1.2"
which-typed-array "^1.1.2"
util@~0.10.1:
version "0.10.4"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901"
@@ -17424,6 +17624,19 @@ which-pm-runs@^1.0.0:
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
which-typed-array@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff"
integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==
dependencies:
available-typed-arrays "^1.0.2"
call-bind "^1.0.0"
es-abstract "^1.18.0-next.1"
foreach "^2.0.5"
function-bind "^1.1.1"
has-symbols "^1.0.1"
is-typed-array "^1.1.3"
which@1, which@^1.2.14, which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"