chore(xo-server): convert to ESM

This commit is contained in:
Julien Fontanet 2021-05-18 11:58:35 +02:00
parent da0cd0b99c
commit 254558e9de
134 changed files with 371 additions and 261 deletions

6
.gitignore vendored
View File

@ -19,9 +19,9 @@
/packages/xen-api/plot.dat
/packages/xo-server/.xo-server.*
/packages/xo-server/src/api/index.js
/packages/xo-server/src/xapi/mixins/index.js
/packages/xo-server/src/xo-mixins/index.js
/packages/xo-server/src/api/index.mjs
/packages/xo-server/src/xapi/mixins/index.mjs
/packages/xo-server/src/xo-mixins/index.mjs
/packages/xo-server-auth-ldap/ldap.cache.conf

View File

@ -0,0 +1,5 @@
module.exports = require('../../@xen-orchestra/babel-config')(require('./package.json'), {
'@babel/preset-env': {
modules: false,
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../@xen-orchestra/babel-config')(require('./package.json'))

View File

@ -1,6 +1,12 @@
#!/usr/bin/env node
'use strict'
import * as SourceMapSupport from 'source-map-support'
import Bluebird from 'bluebird'
import execPromise from 'exec-promise'
import { catchGlobalErrors } from '@xen-orchestra/log/configure.js'
import { createLogger } from '@xen-orchestra/log'
import boostrap from '../index.mjs'
// ===================================================================
@ -11,22 +17,20 @@ if (process.env.NODE_ENV === undefined) {
// Better stack traces if possible.
try {
require('source-map-support').install({
SourceMapSupport.install({
handleUncaughtExceptions: false,
})
} catch (_) {}
// Use Bluebird for all promises as it provides better performance and
// less memory usage.
const Bluebird = require('bluebird')
// Enable `async_hooks` because it's used by `@xen-orchestra/backups/Task` via `node-zone`
//
// See: http://bluebirdjs.com/docs/api/promise.config.html#async-hooks
Bluebird.config({ asyncHooks: true })
// Use Bluebird for all promises as it provides better performance and
// less memory usage.
global.Promise = Bluebird
require('@xen-orchestra/log/configure').catchGlobalErrors(require('@xen-orchestra/log').default('xo:xo-server'))
catchGlobalErrors(createLogger('xo:xo-server'))
require('exec-promise')(require('../'))
execPromise(boostrap)

View File

@ -8,4 +8,4 @@ if (process.env.DEBUG === undefined) {
}
// Import the real main module.
module.exports = require('./dist').default
export { default } from './dist/index.mjs'

View File

@ -22,7 +22,7 @@
"bin": "bin"
},
"engines": {
"node": ">=11"
"node": ">=14.13"
},
"dependencies": {
"@iarna/toml": "^2.2.1",
@ -58,7 +58,7 @@
"cookie": "^0.4.0",
"cookie-parser": "^1.4.3",
"d3-time-format": "^3.0.0",
"decorator-synchronized": "^0.5.0",
"decorator-synchronized": "^0.6.0",
"deptree": "^1.0.0",
"exec-promise": "^0.7.0",
"execa": "^5.0.0",
@ -142,17 +142,16 @@
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"babel-plugin-lodash": "^3.3.2",
"babel-plugin-transform-dev": "^2.0.1",
"cross-env": "^7.0.2",
"index-modules": "^0.3.0",
"index-modules": "^0.4.2",
"rimraf": "^3.0.0"
},
"scripts": {
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
"build": "cross-env NODE_ENV=production babel --keep-file-extension --source-maps --out-dir=dist/ src/",
"clean": "rimraf dist/",
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
"prebuild": "index-modules src/api src/xapi/mixins src/xo-mixins && yarn run clean",
"dev": "cross-env NODE_ENV=development babel --watch --keep-file-extension --source-maps --out-dir=dist/ src/",
"prebuild": "index-modules --index-file index.mjs src/api src/xapi/mixins src/xo-mixins && yarn run clean",
"predev": "yarn run prebuild",
"prepublishOnly": "yarn run build",
"start": "node bin/xo-server"

View File

@ -12,7 +12,7 @@ function* values(object) {
*
* @param {(Array|Object)} collection
*/
module.exports = asyncIteratorToStream(function* (collection) {
export default asyncIteratorToStream(function* (collection) {
for (const value of Array.isArray(collection) ? collection : values(collection)) {
yield JSON.stringify(value)
yield '\n'

View File

@ -1,6 +1,6 @@
/* eslint-env jest */
import ensureArray from './_ensureArray.js'
import ensureArray from './_ensureArray.mjs'
describe('ensureArray()', function () {
it('wrap the value in an array', function () {

View File

@ -1,6 +1,6 @@
import { MultiKeyMap } from '@vates/multi-key-map'
import ensureArray from './_ensureArray.js'
import ensureArray from './_ensureArray.mjs'
function removeCacheEntry(cache, keys) {
cache.delete(keys)

View File

@ -1,6 +1,6 @@
/* eslint-env jest */
import { debounceWithKey, REMOVE_CACHE_ENTRY } from './_pDebounceWithKey.js'
import { debounceWithKey, REMOVE_CACHE_ENTRY } from './_pDebounceWithKey.mjs'
describe('REMOVE_CACHE_ENTRY', () => {
it('clears the cache', async () => {

View File

@ -2,9 +2,9 @@ import { basename } from 'path'
import { fromCallback } from 'promise-toolbox'
import { pipeline } from 'readable-stream'
import createNdJsonStream from '../_createNdJsonStream.js'
import { REMOVE_CACHE_ENTRY } from '../_pDebounceWithKey.js'
import { safeDateFormat } from '../utils.js'
import createNdJsonStream from '../_createNdJsonStream.mjs'
import { REMOVE_CACHE_ENTRY } from '../_pDebounceWithKey.mjs'
import { safeDateFormat } from '../utils.mjs'
export function createJob({ schedules, ...job }) {
job.userId = this.user.id

View File

@ -8,7 +8,7 @@ import { noSuchObject } from 'xo-common/api-errors.js'
import { peekFooterFromVhdStream } from 'vhd-lib'
import { vmdkToVhd } from 'xo-vmdk-to-vhd'
import { VDI_FORMAT_VHD } from '../xapi/index.js'
import { VDI_FORMAT_VHD } from '../xapi/index.mjs'
const log = createLogger('xo:disk')

View File

@ -1,4 +1,4 @@
import xapiObjectToXo from '../xapi-object-to-xo.js'
import xapiObjectToXo from '../xapi-object-to-xo.mjs'
export function getBondModes() {
return ['balance-slb', 'active-backup', 'lacp']

View File

@ -1,8 +1,9 @@
// TODO: too low level, move into host.
import { filter, find } from 'lodash'
import filter from 'lodash/filter.js'
import find from 'lodash/find.js'
import { IPV4_CONFIG_MODES, IPV6_CONFIG_MODES } from '../xapi/index.js'
import { IPV4_CONFIG_MODES, IPV6_CONFIG_MODES } from '../xapi/index.mjs'
export function getIpv4ConfigurationModes() {
return IPV4_CONFIG_MODES

View File

@ -1,6 +1,6 @@
import { deprecate } from 'util'
import { getUserPublicProperties } from '../utils.js'
import { getUserPublicProperties } from '../utils.mjs'
// ===================================================================

View File

@ -1,9 +1,9 @@
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import { some } from 'lodash'
import some from 'lodash/some.js'
import ensureArray from '../_ensureArray.js'
import { asInteger } from '../xapi/utils.js'
import { forEach, parseXml } from '../utils.js'
import ensureArray from '../_ensureArray.mjs'
import { asInteger } from '../xapi/utils.mjs'
import { forEach, parseXml } from '../utils.mjs'
// ===================================================================

View File

@ -3,7 +3,6 @@ import getKeys from 'lodash/keys.js'
import moment from 'moment-timezone'
import { noSuchObject } from 'xo-common/api-errors.js'
import { version as xoServerVersion } from '../../package.json'
// ===================================================================
@ -30,7 +29,9 @@ getServerTimezone.description = 'return the timezone server'
// -------------------------------------------------------------------
export const getServerVersion = () => xoServerVersion
export function getServerVersion() {
return this.version
}
getServerVersion.description = 'return the version of xo-server'
getServerVersion.permission = null // user does not need to be authenticated

View File

@ -1,6 +1,6 @@
import isEmpty from 'lodash/isEmpty.js'
import { forbiddenOperation, invalidParameters } from 'xo-common/api-errors.js'
import { isEmpty } from 'lodash'
import { getUserPublicProperties } from '../utils.js'
import { getUserPublicProperties } from '../utils.mjs'
// ===================================================================

View File

@ -1,10 +1,10 @@
// FIXME: rename to disk.*
import reduce from 'lodash/reduce.js'
import { defer } from 'golike-defer'
import { invalidParameters } from 'xo-common/api-errors.js'
import { reduce } from 'lodash'
import { parseSize } from '../utils.js'
import { parseSize } from '../utils.mjs'
// ====================================================================

View File

@ -1,6 +1,6 @@
import { ignoreErrors } from 'promise-toolbox'
import { diffItems } from '../utils.js'
import { diffItems } from '../utils.mjs'
// ===================================================================

View File

@ -1,12 +1,13 @@
import * as multiparty from 'multiparty'
import assignWith from 'lodash/assignWith.js'
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import concat from 'lodash/concat.js'
import getStream from 'get-stream'
import { createLogger } from '@xen-orchestra/log'
import { defer } from 'golike-defer'
import { FAIL_ON_QUEUE } from 'limit-concurrency-decorator'
import { format } from 'json-rpc-peer'
import { ignoreErrors } from 'promise-toolbox'
import { assignWith, concat } from 'lodash'
import {
forbiddenOperation,
invalidParameters,
@ -15,7 +16,7 @@ import {
unauthorized,
} from 'xo-common/api-errors.js'
import { forEach, map, mapFilter, parseSize, safeDateFormat } from '../utils.js'
import { forEach, map, mapFilter, parseSize, safeDateFormat } from '../utils.mjs'
const log = createLogger('xo:vm')

View File

@ -2,7 +2,7 @@ import getStream from 'get-stream'
import { fromCallback } from 'promise-toolbox'
import { pipeline } from 'readable-stream'
import createNdJsonStream from '../_createNdJsonStream.js'
import createNdJsonStream from '../_createNdJsonStream.mjs'
// ===================================================================

View File

@ -1,17 +1,21 @@
import assert from 'assert'
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import execa from 'execa'
import filter from 'lodash/filter.js'
import find from 'lodash/find.js'
import fs from 'fs-extra'
import includes from 'lodash/includes.js'
import map from 'lodash/map.js'
import range from 'lodash/range.js'
import remove from 'lodash/remove.js'
import { createLogger } from '@xen-orchestra/log'
import { defer } from 'golike-defer'
import { tap, delay } from 'promise-toolbox'
import { invalidParameters } from 'xo-common/api-errors.js'
import { includes, remove, filter, find, range } from 'lodash'
import { Ref } from 'xen-api'
import ensureArray from '../_ensureArray.js'
import { parseXml } from '../utils.js'
import ensureArray from '../_ensureArray.mjs'
import { parseXml } from '../utils.mjs'
const log = createLogger('xo:xosan')

View File

@ -1,7 +1,7 @@
import Model from './model.js'
import Model from './model.mjs'
import { BaseError } from 'make-error'
import { EventEmitter } from 'events'
import { isObject, map } from './utils.js'
import { isObject, map } from './utils.mjs'
// ===================================================================

View File

@ -1,10 +1,15 @@
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import difference from 'lodash/difference.js'
import filter from 'lodash/filter.js'
import forEach from 'lodash/forEach.js'
import getKeys from 'lodash/keys.js'
import isEmpty from 'lodash/isEmpty.js'
import map from 'lodash/map.js'
import { createClient as createRedisClient } from 'redis'
import { difference, filter, forEach, isEmpty, keys as getKeys, map } from 'lodash'
import { ignoreErrors, promisifyAll } from 'promise-toolbox'
import { v4 as generateUuid } from 'uuid'
import Collection, { ModelAlreadyExists } from '../collection.js'
import Collection, { ModelAlreadyExists } from '../collection.mjs'
// ===================================================================

View File

@ -1,6 +1,6 @@
import { EventEmitter } from 'events'
import { noop } from './utils.js'
import { noop } from './utils.mjs'
// ===================================================================

View File

@ -4,7 +4,7 @@
//
// ```js
// import fatfs from 'fatfs'
// import fatfsBuffer, { init as fatfsBufferInit } from './fatfs-buffer.js'
// import fatfsBuffer, { init as fatfsBufferInit } from './fatfs-buffer.mjs'
//
// const buffer = fatfsBufferinit()
//

View File

@ -1,8 +1,8 @@
// See: https://gist.github.com/julien-f/5b9a3537eb82a34b04e2
const matcher = require('micromatch').matcher
import { matcher } from 'micromatch'
module.exports = function globMatcher(patterns, opts) {
export default function globMatcher(patterns, opts) {
if (!Array.isArray(patterns)) {
if (patterns[0] === '!') {
const m = matcher(patterns.slice(1), opts)

View File

@ -2,15 +2,21 @@ import appConf from 'app-conf'
import assert from 'assert'
import authenticator from 'otplib/authenticator.js'
import blocked from 'blocked-at'
import Bluebird from 'bluebird'
import compression from 'compression'
import createExpress from 'express'
import crypto from 'crypto'
import forOwn from 'lodash/forOwn.js'
import has from 'lodash/has.js'
import helmet from 'helmet'
import httpProxy from 'http-proxy'
import includes from 'lodash/includes.js'
import map from 'lodash/map.js'
import memoryStoreFactory from 'memorystore'
import merge from 'lodash/merge.js'
import ms from 'ms'
import proxyConsole from './proxy-console.js'
import once from 'lodash/once.js'
import proxyConsole from './proxy-console.mjs'
import pw from 'pw'
import serveStatic from 'serve-static'
import stoppable from 'stoppable'
@ -18,23 +24,21 @@ import WebServer from 'http-server-plus'
import WebSocket from 'ws'
import xdg from 'xdg-basedir'
import { createLogger } from '@xen-orchestra/log'
import { forOwn, map, merge, once } from 'lodash'
import { genSelfSignedCert } from '@xen-orchestra/self-signed'
import { parseDuration } from '@vates/parse-duration'
import { URL } from 'url'
import { compile as compilePug } from 'pug'
import { createServer as createProxyServer } from 'http-proxy'
import { fromCallback, fromEvent } from 'promise-toolbox'
import { ifDef } from '@xen-orchestra/defined'
import { join as joinPath } from 'path'
import JsonRpcPeer from 'json-rpc-peer'
import fse from 'fs-extra'
import { invalidCredentials } from 'xo-common/api-errors.js'
import { ensureDir, outputFile, readdir, readFile } from 'fs-extra'
import { Peer as JsonRpcPeer } from 'json-rpc-peer'
import ensureArray from './_ensureArray.js'
import Xo from './xo.js'
import ensureArray from './_ensureArray.mjs'
import Xo from './xo.mjs'
import bodyParser from 'body-parser'
import connectFlash from 'connect-flash'
@ -46,7 +50,15 @@ import { Strategy as LocalStrategy } from 'passport-local'
import transportConsole from '@xen-orchestra/log/transports/console.js'
import { configure } from '@xen-orchestra/log/configure.js'
import { generateToken } from './utils.js'
import { generateToken } from './utils.mjs'
// ===================================================================
const APP_DIR = new URL('..', import.meta.url).pathname
const [APP_NAME, APP_VERSION] = (() => {
const { name, version } = JSON.parse(fse.readFileSync(new URL('../package.json', import.meta.url)))
return [name, version]
})()
// ===================================================================
@ -67,9 +79,6 @@ const log = createLogger('xo:main')
// ===================================================================
const APP_DIR = joinPath(__dirname, '..')
const APP_NAME = 'xo-server'
const DEPRECATED_ENTRIES = ['users', 'servers']
async function loadConfiguration() {
@ -93,9 +102,9 @@ async function loadConfiguration() {
const LOCAL_CONFIG_FILE = `${xdg.config}/${APP_NAME}/config.z-auto.json`
async function updateLocalConfig(diff) {
// TODO lock file
const localConfig = await readFile(LOCAL_CONFIG_FILE).then(JSON.parse, () => ({}))
const localConfig = await fse.readFile(LOCAL_CONFIG_FILE).then(JSON.parse, () => ({}))
merge(localConfig, diff)
await outputFile(LOCAL_CONFIG_FILE, JSON.stringify(localConfig), {
await fse.outputFile(LOCAL_CONFIG_FILE, JSON.stringify(localConfig), {
mode: 0o600,
})
}
@ -160,7 +169,7 @@ async function setUpPassport(express, xo, { authentication: authCfg, http: { coo
}
// Registers the sign in form.
const signInPage = compilePug(await readFile(joinPath(__dirname, '..', 'signin.pug')))
const signInPage = compilePug(await fse.readFile(new URL('../signin.pug', import.meta.url)))
express.get('/signin', (req, res, next) => {
res.send(
signInPage({
@ -282,14 +291,10 @@ async function setUpPassport(express, xo, { authentication: authCfg, http: { coo
// ===================================================================
async function registerPlugin(pluginPath, pluginName) {
const plugin = require(pluginPath)
const { description, version = 'unknown' } = (() => {
try {
return require(pluginPath + '/package.json')
} catch (_) {
return {}
}
})()
const plugin = (await import(pluginPath)).default
const { description, version = 'unknown' } = await fse
.readFile(pluginPath + '/package.json')
.then(JSON.stringify, error => ({}))
// Supports both “normal” CommonJS and Babel's ES2015 modules.
let { default: factory = plugin, configurationSchema, configurationPresets, testSchema } = plugin
@ -304,7 +309,7 @@ async function registerPlugin(pluginPath, pluginName) {
xo: this,
getDataDir: () => {
const dir = `${datadir}/${pluginName}`
return ensureDir(dir).then(() => dir)
return fse.ensureDir(dir).then(() => dir)
},
})
: factory
@ -343,7 +348,7 @@ function registerPluginWrapper(pluginPath, pluginName) {
}
async function registerPluginsInPath(path, prefix) {
const files = await readdir(path).catch(error => {
const files = await fse.readdir(path).catch(error => {
if (error.code === 'ENOENT') {
return []
}
@ -361,7 +366,7 @@ async function registerPluginsInPath(path, prefix) {
async function registerPlugins(xo) {
await Promise.all(
[`${__dirname}/../node_modules`, '/usr/local/lib/node_modules'].map(path =>
[new URL('../node_modules', import.meta.url).pathname, '/usr/local/lib/node_modules'].map(path =>
Promise.all([
registerPluginsInPath.call(xo, path, 'xo-server-'),
registerPluginsInPath.call(xo, `${path}/@xen-orchestra`, 'server-'),
@ -389,7 +394,7 @@ async function makeWebServerListen(
try {
if (cert && key) {
try {
;[opts.cert, opts.key] = await Promise.all([readFile(cert), readFile(key)])
;[opts.cert, opts.key] = await Promise.all([fse.readFile(cert), fse.readFile(key)])
if (opts.key.includes('ENCRYPTED')) {
opts.passphrase = await new Promise(resolve => {
// eslint-disable-next-line no-console
@ -405,8 +410,8 @@ async function makeWebServerListen(
const pems = await genSelfSignedCert()
await Promise.all([
outputFile(cert, pems.cert, { flag: 'wx', mode: 0o400 }),
outputFile(key, pems.key, { flag: 'wx', mode: 0o400 }),
fse.outputFile(cert, pems.cert, { flag: 'wx', mode: 0o400 }),
fse.outputFile(key, pems.key, { flag: 'wx', mode: 0o400 }),
])
log.info('new certificate generated', { cert, key })
opts.cert = pems.cert
@ -448,11 +453,13 @@ const setUpProxies = (express, opts, xo) => {
return
}
const proxy = createProxyServer({
const proxy = httpProxy
.createServer({
changeOrigin: true,
ignorePath: true,
xfwd: true,
}).on('error', (error, req, res) => {
})
.on('error', (error, req, res) => {
// `res` can be either a `ServerResponse` or a `Socket` (which does not have
// `writeHead`)
if (!res.headersSent && typeof res.writeHead === 'function') {
@ -673,15 +680,15 @@ const setUpConsoleProxy = (webServer, xo) => {
// ===================================================================
const USAGE = (({ name, version }) => `Usage: ${name} [--safe-mode]
const USAGE = `Usage: ${APP_NAME} [--safe-mode]
${name} v${version}`)(require('../package.json'))
${APP_NAME} v${APP_VERSION}`
// ===================================================================
export default async function main(args) {
// makes sure the global Promise has not been changed by a lib
assert(global.Promise === require('bluebird'))
assert(global.Promise === Bluebird)
if (includes(args, '--help') || includes(args, '-h')) {
return USAGE
@ -725,6 +732,7 @@ export default async function main(args) {
const xo = new Xo({
appDir: APP_DIR,
appName: APP_NAME,
appVersion: APP_VERSION,
config,
httpServer: webServer,
safeMode,

View File

@ -8,8 +8,8 @@ import sublevel from 'subleveldown'
import util from 'util'
import { join as joinPath } from 'path'
import { forEach } from './utils.js'
import globMatcher from './glob-matcher.js'
import { forEach } from './utils.mjs'
import globMatcher from './glob-matcher.mjs'
// ===================================================================
@ -274,11 +274,14 @@ export default async function main() {
}
const config = await appConf.load('xo-server', {
appDir: joinPath(__dirname, '..'),
appDir: new URL('..', import.meta.url).pathname,
ignoreUnknownFormats: true,
})
if (args.repair) {
// TODO: remove once `import.meta.resolve` is stabilized
const require = (await import('module')).createRequire(import.meta.url)
// eslint-disable-next-line node/no-extraneous-require
const { repair } = require(require.resolve('level', {
paths: [require.resolve('level-party')],

View File

@ -1,8 +1,8 @@
/* eslint-env jest */
import { forEach } from 'lodash'
import { thunkToArray } from './utils.js'
import { crossProduct, mergeObjects } from './math.js'
import forEach from 'lodash/forEach.js'
import { thunkToArray } from './utils.mjs'
import { crossProduct, mergeObjects } from './math.mjs'
describe('mergeObjects', function () {
forEach(

View File

@ -1,6 +1,6 @@
import { EventEmitter } from 'events'
import { forEach, isEmpty } from './utils.js'
import { forEach, isEmpty } from './utils.mjs'
// ===================================================================

View File

@ -1,6 +1,6 @@
import Collection from '../collection/redis.js'
import Model from '../model.js'
import { forEach, multiKeyHash } from '../utils.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { forEach, multiKeyHash } from '../utils.mjs'
// ===================================================================

View File

@ -1,11 +1,11 @@
import isEmpty from 'lodash/isEmpty.js'
import Collection from '../collection/redis.js'
import Model from '../model.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { forEach } from '../utils.js'
import { forEach } from '../utils.mjs'
import { parseProp } from './utils.js'
import { parseProp } from './utils.mjs'
// ===================================================================

View File

@ -1,7 +1,7 @@
import Collection from '../collection/redis.js'
import Model from '../model.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { createLogger } from '@xen-orchestra/log'
import { forEach } from '../utils.js'
import { forEach } from '../utils.mjs'
const log = createLogger('xo:plugin-metadata')

View File

@ -1,8 +1,8 @@
import Collection from '../collection/redis.js'
import Model from '../model.js'
import { forEach } from '../utils.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { forEach } from '../utils.mjs'
import { parseProp } from './utils.js'
import { parseProp } from './utils.mjs'
// ===================================================================

View File

@ -1,8 +1,8 @@
import Collection from '../collection/redis.js'
import Model from '../model.js'
import { forEach, serializeError } from '../utils.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { forEach, serializeError } from '../utils.mjs'
import { parseProp } from './utils.js'
import { parseProp } from './utils.mjs'
// ===================================================================

View File

@ -1,5 +1,5 @@
import Collection from '../collection/redis.js'
import Model from '../model.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
// ===================================================================

View File

@ -1,9 +1,9 @@
import isEmpty from 'lodash/isEmpty.js'
import Collection from '../collection/redis.js'
import Model from '../model.js'
import Collection from '../collection/redis.mjs'
import Model from '../model.mjs'
import { parseProp } from './utils.js'
import { parseProp } from './utils.mjs'
// ===================================================================

View File

@ -2,8 +2,8 @@ import appConf from 'app-conf'
import pw from 'pw'
import { join as joinPath } from 'path'
import Xo from './xo.js'
import { generateToken } from './utils.js'
import Xo from './xo.mjs'
import { generateToken } from './utils.mjs'
const recoverAccount = async ([name]) => {
if (name === undefined || name === '--help' || name === '-h') {
@ -27,7 +27,7 @@ xo-server-recover-account <user name or email>
const xo = new Xo({
config: await appConf.load('xo-server', {
appDir: joinPath(__dirname, '..'),
appDir: new URL('..', import.meta.url).pathname,
ignoreUnknownFormats: true,
}),
})

View File

@ -3,13 +3,13 @@
import { createReadStream, readFile } from 'fs'
import { fromCallback } from 'promise-toolbox'
import streamToExistingBuffer from './stream-to-existing-buffer.js'
import streamToExistingBuffer from './stream-to-existing-buffer.mjs'
describe('streamToExistingBuffer()', () => {
it('read the content of a stream in a buffer', async () => {
const stream = createReadStream(__filename)
const stream = createReadStream(import.meta.url)
const expected = await fromCallback(readFile, __filename, 'utf-8')
const expected = await fromCallback(readFile, import.meta.url, 'utf-8')
const buf = Buffer.allocUnsafe(expected.length + 1)
buf[0] = 'A'.charCodeAt()

View File

@ -1,6 +1,6 @@
/* eslint-env jest */
import { camelToSnakeCase, diffItems, extractProperty, generateToken, parseSize, parseXml } from './utils.js'
import { camelToSnakeCase, diffItems, extractProperty, generateToken, parseSize, parseXml } from './utils.mjs'
// ===================================================================

View File

@ -1,11 +1,11 @@
import { isDefaultTemplate } from '@xen-orchestra/xapi'
import * as sensitiveValues from './sensitive-values.js'
import ensureArray from './_ensureArray.js'
import { extractIpFromVmNetworks } from './_extractIpFromVmNetworks.js'
import { extractProperty, forEach, isEmpty, mapFilter, parseXml } from './utils.js'
import { getVmDomainType, isHostRunning, isVmRunning, parseDateTime } from './xapi/index.js'
import { useUpdateSystem } from './xapi/utils.js'
import * as sensitiveValues from './sensitive-values.mjs'
import ensureArray from './_ensureArray.mjs'
import { extractIpFromVmNetworks } from './_extractIpFromVmNetworks.mjs'
import { extractProperty, forEach, isEmpty, mapFilter, parseXml } from './utils.mjs'
import { getVmDomainType, isHostRunning, isVmRunning, parseDateTime } from './xapi/index.mjs'
import { useUpdateSystem } from './xapi/utils.mjs'
// ===================================================================

View File

@ -1,10 +1,19 @@
import defaults from 'lodash/defaults.js'
import findKey from 'lodash/findKey.js'
import forEach from 'lodash/forEach.js'
import identity from 'lodash/identity.js'
import JSON5 from 'json5'
import limitConcurrency from 'limit-concurrency-decorator'
import synchronized from 'decorator-synchronized'
import map from 'lodash/map.js'
import mapValues from 'lodash/mapValues.js'
import mean from 'lodash/mean.js'
import sum from 'lodash/sum.js'
import uniq from 'lodash/uniq.js'
import zipWith from 'lodash/zipWith.js'
import { BaseError } from 'make-error'
import { defaults, findKey, forEach, identity, map, mapValues, mean, sum, uniq, zipWith } from 'lodash'
import { limitConcurrency } from 'limit-concurrency-decorator'
import { synchronized } from 'decorator-synchronized'
import { parseDateTime } from './xapi/index.js'
import { parseDateTime } from './xapi/index.mjs'
export class FaultyGranularity extends BaseError {}

View File

@ -1,34 +1,45 @@
/* eslint eslint-comments/disable-enable-pair: [error, {allowWholeFile: true}] */
/* eslint-disable camelcase */
import asyncMapSettled from '@xen-orchestra/async-map/legacy.js'
import concurrency from 'limit-concurrency-decorator'
import fatfs from 'fatfs'
import filter from 'lodash/filter.js'
import find from 'lodash/find.js'
import flatMap from 'lodash/flatMap.js'
import flatten from 'lodash/flatten.js'
import groupBy from 'lodash/groupBy.js'
import identity from 'lodash/identity.js'
import includes from 'lodash/includes.js'
import isEmpty from 'lodash/isEmpty.js'
import mapToArray from 'lodash/map.js'
import mixin from '@xen-orchestra/mixin/legacy.js'
import ms from 'ms'
import synchronized from 'decorator-synchronized'
import noop from 'lodash/noop.js'
import omit from 'lodash/omit.js'
import once from 'lodash/once.js'
import semver from 'semver'
import tarStream from 'tar-stream'
import uniq from 'lodash/uniq.js'
import { asyncMap } from '@xen-orchestra/async-map'
import { vmdkToVhd } from 'xo-vmdk-to-vhd'
import { cancelable, fromEvents, ignoreErrors, pCatch, pRetry } from 'promise-toolbox'
import { createLogger } from '@xen-orchestra/log'
import { decorateWith } from '@vates/decorate-with'
import { defer as deferrable } from 'golike-defer'
import { limitConcurrency } from 'limit-concurrency-decorator'
import { parseDuration } from '@vates/parse-duration'
import { PassThrough } from 'stream'
import { forbiddenOperation, operationFailed } from 'xo-common/api-errors.js'
import { Xapi as XapiBase } from '@xen-orchestra/xapi'
import { filter, find, flatMap, flatten, groupBy, identity, includes, isEmpty, noop, omit, once, uniq } from 'lodash'
import { Ref } from 'xen-api'
import { satisfies as versionSatisfies } from 'semver'
import { synchronized } from 'decorator-synchronized'
import ensureArray from '../_ensureArray.js'
import fatfsBuffer, { init as fatfsBufferInit } from '../fatfs-buffer.js'
import { asyncMapValues } from '../_asyncMapValues.js'
import { camelToSnakeCase, forEach, map, parseSize, pDelay, promisifyAll } from '../utils.js'
import ensureArray from '../_ensureArray.mjs'
import fatfsBuffer, { init as fatfsBufferInit } from '../fatfs-buffer.mjs'
import { asyncMapValues } from '../_asyncMapValues.mjs'
import { camelToSnakeCase, forEach, map, parseSize, pDelay, promisifyAll } from '../utils.mjs'
import mixins from './mixins/index.js'
import OTHER_CONFIG_TEMPLATE from './other-config-template.js'
import mixins from './mixins/index.mjs'
import OTHER_CONFIG_TEMPLATE from './other-config-template.mjs'
import {
asBoolean,
asInteger,
@ -40,7 +51,7 @@ import {
optional,
parseDateTime,
prepareXapiParam,
} from './utils.js'
} from './utils.mjs'
import { createVhdStreamWithLength } from 'vhd-lib'
const log = createLogger('xo:xapi')
@ -52,9 +63,7 @@ export const TAG_COPY_SRC = 'xo:copy_of'
// ===================================================================
// FIXME: remove this work around when fixed, https://phabricator.babeljs.io/T2877
// export * from './utils.js'
Object.assign(module.exports, require('./utils.js'))
export * from './utils.mjs'
// VDI formats. (Raw is not available for delta vdi.)
export const VDI_FORMAT_VHD = 'vhd'
@ -84,10 +93,10 @@ export default class Xapi extends XapiBase {
// close event is emitted when the export is canceled via browser. See https://github.com/vatesfr/xen-orchestra/issues/5535
const waitStreamEnd = async stream => fromEvents(await stream, ['end', 'close'])
this._exportVdi = concurrency(vdiExportConcurrency, waitStreamEnd)(this._exportVdi)
this.exportVm = concurrency(vmExportConcurrency, waitStreamEnd)(this.exportVm)
this._exportVdi = limitConcurrency(vdiExportConcurrency, waitStreamEnd)(this._exportVdi)
this.exportVm = limitConcurrency(vmExportConcurrency, waitStreamEnd)(this.exportVm)
this._snapshotVm = concurrency(vmSnapshotConcurrency)(this._snapshotVm)
this._snapshotVm = limitConcurrency(vmSnapshotConcurrency)(this._snapshotVm)
// Patch getObject to resolve _xapiId property.
this.getObject = (getObject => (...args) => {
@ -665,7 +674,7 @@ export default class Xapi extends XapiBase {
) {
const { version } = delta
if (!versionSatisfies(version, '^1')) {
if (!semver.satisfies(version, '^1')) {
throw new Error(`Unsupported delta backup version: ${version}`)
}

View File

@ -1,4 +1,4 @@
import { makeEditObject } from '../utils.js'
import { makeEditObject } from '../utils.mjs'
export default {
async _connectVif(vif) {

View File

@ -1,15 +1,20 @@
import filter from 'lodash/filter.js'
import find from 'lodash/find.js'
import groupBy from 'lodash/groupBy.js'
import mapValues from 'lodash/mapValues.js'
import pickBy from 'lodash/pickBy.js'
import some from 'lodash/some.js'
import unzip from 'unzipper'
import { createLogger } from '@xen-orchestra/log'
import { decorateWith } from '@vates/decorate-with'
import { defer as deferrable } from 'golike-defer'
import { filter, find, groupBy, mapValues, pickBy, some } from 'lodash'
import { timeout } from 'promise-toolbox'
import ensureArray from '../../_ensureArray.js'
import { debounceWithKey } from '../../_pDebounceWithKey.js'
import { forEach, mapFilter, parseXml } from '../../utils.js'
import ensureArray from '../../_ensureArray.mjs'
import { debounceWithKey } from '../../_pDebounceWithKey.mjs'
import { forEach, mapFilter, parseXml } from '../../utils.mjs'
import { extractOpaqueRef, parseDateTime, useUpdateSystem } from '../utils.js'
import { extractOpaqueRef, parseDateTime, useUpdateSystem } from '../utils.mjs'
// TOC -------------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More