chore(xapi): convert to ESM

BREAKING CHANGE
This commit is contained in:
Julien Fontanet 2023-07-10 15:56:50 +02:00
parent 1005e295b2
commit c3e0308ad0
23 changed files with 104 additions and 128 deletions

View File

@ -1,7 +1,5 @@
'use strict'
// TODO: remove when Node >=15.0
module.exports = class AggregateError extends Error {
export default class AggregateError extends Error {
constructor(errors, message) {
super(message)
this.errors = errors

View File

@ -0,0 +1,7 @@
export { default as host } from './host.mjs'
export { default as SR } from './sr.mjs'
export { default as task } from './task.mjs'
export { default as VBD } from './vbd.mjs'
export { default as VDI } from './vdi.mjs'
export { default as VIF } from './vif.mjs'
export { default as VM } from './vm.mjs'

View File

@ -1,9 +1,7 @@
'use strict'
import fromCallback from 'promise-toolbox/fromCallback'
import { execFile } from 'node:child_process'
const fromCallback = require('promise-toolbox/fromCallback')
const { execFile } = require('node:child_process')
exports.getCurrentVmUuid = async function getCurrentVmUuid() {
export async function getCurrentVmUuid() {
const vm = (await read('vm')).trim()
const i = vm.lastIndexOf('/')
if (i === -1) {

View File

@ -1,8 +1,6 @@
'use strict'
const OPAQUE_REF_RE = /OpaqueRef:[0-9a-z-]+/
module.exports = function extractOpaqueRef(str) {
export default function extractOpaqueRef(str) {
const matches = OPAQUE_REF_RE.exec(str)
if (!matches) {
const error = new Error('no opaque ref found')

View File

@ -1,9 +1,7 @@
'use strict'
const RUNNING_POWER_STATES = {
Running: true,
Paused: true,
}
module.exports = vmOrPowerState =>
export default vmOrPowerState =>
(typeof vmOrPowerState === 'string' ? vmOrPowerState : vmOrPowerState.power_state) in RUNNING_POWER_STATES

View File

@ -1,9 +1,7 @@
'use strict'
import { strict as assert } from 'node:assert'
import test from 'test'
const assert = require('node:assert/strict')
const test = require('test')
const { parseDateTime } = require('./')
import { parseDateTime } from './index.mjs'
test('parseDateTime()', function () {
for (const [input, output] of [

View File

@ -1,8 +0,0 @@
#!/usr/bin/env node
'use strict'
const { Xapi } = require('./')
require('xen-api/dist/cli.js')
.default(opts => new Xapi(opts))
.catch(console.error.bind(console, 'FATAL'))

6
@xen-orchestra/xapi/cli.mjs Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env node
import { Xapi } from './index.mjs'
import CLI from 'xen-api/dist/cli.js'
CLI.default(opts => new Xapi(opts)).catch(console.error.bind(console, 'FATAL'))

View File

@ -1,10 +1,8 @@
'use strict'
import { asyncEach } from '@vates/async-each'
import { decorateClass } from '@vates/decorate-with'
import { defer } from 'golike-defer'
const { asyncEach } = require('@vates/async-each')
const { decorateClass } = require('@vates/decorate-with')
const { defer } = require('golike-defer')
const { getCurrentVmUuid } = require('./_XenStore.js')
import { getCurrentVmUuid } from './_XenStore.mjs'
const waitAgentRestart = (xapi, hostRef, prevAgentStartTime) =>
new Promise(resolve => {
@ -84,7 +82,7 @@ class Host {
await waitAgentRestart(this, ref, agentStartTime)
}
}
module.exports = Host
export default Host
decorateClass(Host, {
smartReboot: defer,

View File

@ -1,22 +1,23 @@
'use strict'
import assert from 'assert'
import pRetry from 'promise-toolbox/retry'
import { utcFormat, utcParse } from 'd3-time-format'
import { Xapi as Base } from 'xen-api'
import { createLogger } from '@xen-orchestra/log'
const assert = require('assert')
const pRetry = require('promise-toolbox/retry')
const { utcFormat, utcParse } = require('d3-time-format')
const { Xapi: Base } = require('xen-api')
import * as Mixins from './_Mixins.mjs'
const { warn } = require('@xen-orchestra/log').createLogger('xo:xapi')
const { warn } = createLogger('xo:xapi')
exports.extractOpaqueRef = require('./_extractOpaqueRef.js')
exports.isDefaultTemplate = require('./isDefaultTemplate.js')
export { default as extractOpaqueRef } from './_extractOpaqueRef.mjs'
export { default as isDefaultTemplate } from './isDefaultTemplate.mjs'
// VDI formats. (Raw is not available for delta vdi.)
exports.VDI_FORMAT_RAW = 'raw'
exports.VDI_FORMAT_VHD = 'vhd'
export const VDI_FORMAT_RAW = 'raw'
export const VDI_FORMAT_VHD = 'vhd'
// Format a date (pseudo ISO 8601) from one XenServer get by
// xapi.call('host.get_servertime', host.$ref) for example
exports.formatDateTime = utcFormat('%Y%m%dT%H:%M:%SZ')
export const formatDateTime = utcFormat('%Y%m%dT%H:%M:%SZ')
const parseDateTimeHelper = utcParse('%Y%m%dT%H:%M:%SZ')
@ -27,7 +28,7 @@ const parseDateTimeHelper = utcParse('%Y%m%dT%H:%M:%SZ')
* @returns {number|null} A Unix timestamp in seconds, or null if the field is empty (as encoded by XAPI).
* @throws {TypeError} If the input is not a string, number or Date object.
*/
exports.parseDateTime = function parseDateTime(input) {
export function parseDateTime(input) {
const type = typeof input
// If the value is a number, it is assumed to be a timestamp in seconds
@ -131,7 +132,7 @@ function removeWatcher(predicate, cb) {
}
}
class Xapi extends Base {
export class Xapi extends Base {
constructor({
callRetryWhenTooManyPendingTasks = { delay: 5e3, tries: 10 },
maxUncoalescedVdis,
@ -276,16 +277,8 @@ function mixin(mixins) {
})
defineProperties(xapiProto, descriptors)
}
mixin({
host: require('./host.js'),
SR: require('./sr.js'),
task: require('./task.js'),
VBD: require('./vbd.js'),
VDI: require('./vdi.js'),
VIF: require('./vif.js'),
VM: require('./vm.js'),
})
exports.Xapi = Xapi
mixin(Mixins)
function getCallRetryOpts() {
return this._callRetryWhenTooManyPendingTasks

View File

@ -1,3 +0,0 @@
'use strict'
module.exports = vmTpl => vmTpl.is_default_template || vmTpl.other_config.default_template === 'true'

View File

@ -0,0 +1 @@
export default vmTpl => vmTpl.is_default_template || vmTpl.other_config.default_template === 'true'

View File

@ -9,11 +9,12 @@
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"bin": {
"xo-xapi": "./cli.js"
"xo-xapi": "./cli.mjs"
},
"engines": {
"node": ">=14"
},
"main": "./index.mjs",
"peerDependencies": {
"xen-api": "^1.3.3"
},

View File

@ -1,16 +1,15 @@
'use strict'
import { asyncMap, asyncMapSettled } from '@xen-orchestra/async-map'
import { createLogger } from '@xen-orchestra/log'
import { decorateClass } from '@vates/decorate-with'
import { defer } from 'golike-defer'
import { incorrectState } from 'xo-common/api-errors.js'
import { VDI_FORMAT_VHD } from './index.mjs'
import { strict as assert } from 'node:assert'
import peekFooterFromStream from 'vhd-lib/peekFooterFromVhdStream.js'
const { asyncMap, asyncMapSettled } = require('@xen-orchestra/async-map')
const { decorateClass } = require('@vates/decorate-with')
const { defer } = require('golike-defer')
const { incorrectState } = require('xo-common/api-errors')
const { VDI_FORMAT_VHD } = require('./index.js')
const assert = require('node:assert').strict
const peekFooterFromStream = require('vhd-lib/peekFooterFromVhdStream')
import AggregateError from './_AggregateError.mjs'
const AggregateError = require('./_AggregateError.js')
const { warn } = require('@xen-orchestra/log').createLogger('xo:xapi:sr')
const { warn } = createLogger('xo:xapi:sr')
const OC_MAINTENANCE = 'xo:maintenanceState'
@ -174,6 +173,6 @@ class Sr {
return vdiRef
}
}
module.exports = Sr
export default Sr
decorateClass(Sr, { enableMaintenanceMode: defer, importVdi: defer })

View File

@ -1,8 +1,6 @@
'use strict'
import ignoreErrors from 'promise-toolbox/ignoreErrors'
const ignoreErrors = require('promise-toolbox/ignoreErrors')
module.exports = class Task {
export default class Task {
create(name = 'untitled task', description) {
return this.createTask(`[XO] ${name}`, description)
}

View File

@ -1,16 +1,15 @@
'use strict'
import identity from 'lodash/identity.js'
import ignoreErrors from 'promise-toolbox/ignoreErrors'
import { createLogger } from '@xen-orchestra/log'
import { Ref } from 'xen-api'
const identity = require('lodash/identity.js')
const ignoreErrors = require('promise-toolbox/ignoreErrors')
const { Ref } = require('xen-api')
import isVmRunning from './_isVmRunning.mjs'
const isVmRunning = require('./_isVmRunning.js')
const { warn } = require('@xen-orchestra/log').createLogger('xo:xapi:vbd')
const { warn } = createLogger('xo:xapi:vbd')
const noop = Function.prototype
module.exports = class Vbd {
export default class Vbd {
async create({
bootable = false,
currently_attached = false,

View File

@ -1,16 +1,16 @@
'use strict'
import CancelToken from 'promise-toolbox/CancelToken'
import pCatch from 'promise-toolbox/catch'
import pRetry from 'promise-toolbox/retry'
import { createLogger } from '@xen-orchestra/log'
import { decorateClass } from '@vates/decorate-with'
import { strict as assert } from 'node:assert'
const assert = require('node:assert').strict
const CancelToken = require('promise-toolbox/CancelToken')
const pCatch = require('promise-toolbox/catch')
const pRetry = require('promise-toolbox/retry')
const { decorateClass } = require('@vates/decorate-with')
import extractOpaqueRef from './_extractOpaqueRef.mjs'
import NbdClient from '@vates/nbd-client'
import { createNbdRawStream, createNbdVhdStream } from 'vhd-lib/createStreamNbd.js'
import { VDI_FORMAT_RAW, VDI_FORMAT_VHD } from './index.mjs'
const extractOpaqueRef = require('./_extractOpaqueRef.js')
const NbdClient = require('@vates/nbd-client')
const { createNbdRawStream, createNbdVhdStream } = require('vhd-lib/createStreamNbd.js')
const { VDI_FORMAT_RAW, VDI_FORMAT_VHD } = require('./index.js')
const { warn } = require('@xen-orchestra/log').createLogger('xo:xapi:vdi')
const { warn } = createLogger('xo:xapi:vdi')
const noop = Function.prototype
@ -155,7 +155,7 @@ class Vdi {
}
}
}
module.exports = Vdi
export default Vdi
decorateClass(Vdi, {
// work around a race condition in XCP-ng/XenServer where the disk is not fully unmounted yet

View File

@ -1,8 +1,6 @@
'use strict'
import isVmRunning from './_isVmRunning.mjs'
const isVmRunning = require('./_isVmRunning.js')
module.exports = class Vif {
export default class Vif {
async create(
{
currently_attached = true,

View File

@ -1,23 +1,21 @@
'use strict'
import CancelToken from 'promise-toolbox/CancelToken'
import groupBy from 'lodash/groupBy.js'
import hrp from 'http-request-plus'
import ignoreErrors from 'promise-toolbox/ignoreErrors'
import pickBy from 'lodash/pickBy.js'
import omit from 'lodash/omit.js'
import pCatch from 'promise-toolbox/catch'
import { asyncMap } from '@xen-orchestra/async-map'
import { createLogger } from '@xen-orchestra/log'
import { decorateClass } from '@vates/decorate-with'
import { defer } from 'golike-defer'
import { incorrectState, forbiddenOperation } from 'xo-common/api-errors.js'
import { JsonRpcError } from 'json-rpc-protocol'
import { Ref } from 'xen-api'
const CancelToken = require('promise-toolbox/CancelToken')
const groupBy = require('lodash/groupBy.js')
const hrp = require('http-request-plus')
const ignoreErrors = require('promise-toolbox/ignoreErrors')
const pickBy = require('lodash/pickBy.js')
const omit = require('lodash/omit.js')
const pCatch = require('promise-toolbox/catch')
const { asyncMap } = require('@xen-orchestra/async-map')
const { createLogger } = require('@xen-orchestra/log')
const { decorateClass } = require('@vates/decorate-with')
const { defer } = require('golike-defer')
const { incorrectState, forbiddenOperation } = require('xo-common/api-errors.js')
const { JsonRpcError } = require('json-rpc-protocol')
const { Ref } = require('xen-api')
const extractOpaqueRef = require('./_extractOpaqueRef.js')
const isDefaultTemplate = require('./isDefaultTemplate.js')
const isVmRunning = require('./_isVmRunning.js')
import extractOpaqueRef from './_extractOpaqueRef.mjs'
import isDefaultTemplate from './isDefaultTemplate.mjs'
import isVmRunning from './_isVmRunning.mjs'
const { warn } = createLogger('xo:xapi:vm')
@ -689,7 +687,7 @@ class Vm {
return ref
}
}
module.exports = Vm
export default Vm
decorateClass(Vm, {
checkpoint: defer,

View File

@ -1,6 +1,4 @@
'use strict'
const assert = require('node:assert/strict')
import assert from 'node:assert/strict'
// This module provides a way to associate data with a XAPI object.
//
@ -16,7 +14,7 @@ const assert = require('node:assert/strict')
* @param {string} params.uuid - The UUID of the object.
* @returns {object|undefined} The parsed data object, or undefined if there is no data.
*/
exports.extract = function extract({ other_config, uuid }) {
export function extract({ other_config, uuid }) {
const json = other_config['xo:' + uuid.slice(0, 8)]
if (json !== undefined) {
return JSON.parse(json)
@ -34,7 +32,7 @@ exports.extract = function extract({ other_config, uuid }) {
* @param {object|null} data - The data to merge with the XO data associated with the object. If null, the XO data for the object will be cleared.
* @returns {Promise<object|undefined>} A Promise that resolves to the updated XO data object, or undefined if the XO data for the given object is cleared.
*/
exports.set = async function set({ $type, $ref, $xapi, uuid }, data) {
export async function set({ $type, $ref, $xapi, uuid }, data) {
assert.equal(typeof data, 'object') // includes null
assert(!Array.isArray(data))

View File

@ -30,6 +30,7 @@
<!--packages-start-->
- @xen-orchestra/backups minor
- @xen-orchestra/xapi major
- complex-matcher patch
- xo-web minor

View File

@ -3,7 +3,7 @@ import { isDefaultTemplate, parseDateTime } from '@xen-orchestra/xapi'
import * as sensitiveValues from './sensitive-values.mjs'
import ensureArray from './_ensureArray.mjs'
import normalizeVmNetworks from './_normalizeVmNetworks.mjs'
import xoData from '@xen-orchestra/xapi/xoData.js'
import xoData from '@xen-orchestra/xapi/xoData.mjs'
import { createLogger } from '@xen-orchestra/log'
import { extractIpFromVmNetworks } from './_extractIpFromVmNetworks.mjs'
import { extractProperty, forEach, isEmpty, mapFilter, parseXml } from './utils.mjs'

View File

@ -6,7 +6,7 @@ import lte from 'lodash/lte.js'
import mapToArray from 'lodash/map.js'
import mapValues from 'lodash/mapValues.js'
import noop from 'lodash/noop.js'
import xoData from '@xen-orchestra/xapi/xoData.js'
import xoData from '@xen-orchestra/xapi/xoData.mjs'
import { decorateWith } from '@vates/decorate-with'
import { defer as deferrable } from 'golike-defer'
import { ignoreErrors, pCatch } from 'promise-toolbox'