diff --git a/packages/xo-server/src/api/vm.mjs b/packages/xo-server/src/api/vm.mjs index fb7a66935..4425b1fe2 100644 --- a/packages/xo-server/src/api/vm.mjs +++ b/packages/xo-server/src/api/vm.mjs @@ -5,6 +5,7 @@ import asyncMapSettled from '@xen-orchestra/async-map/legacy.js' import { Task } from '@xen-orchestra/mixins/Tasks.mjs' import concat from 'lodash/concat.js' import hrp from 'http-request-plus' +import mapKeys from 'lodash/mapKeys.js' import { createLogger } from '@xen-orchestra/log' import { defer } from 'golike-defer' import { format } from 'json-rpc-peer' @@ -622,6 +623,8 @@ warmMigration.params = { // ------------------------------------------------------------------- +const autoPrefix = (pfx, str) => (str.startsWith(pfx) ? str : pfx + str) + export const set = defer(async function ($defer, params) { const VM = extract(params, 'VM') const xapi = this.getXapi(VM) @@ -646,6 +649,11 @@ export const set = defer(async function ($defer, params) { await xapi.call('VM.set_suspend_SR', VM._xapiRef, suspendSr === null ? Ref.EMPTY : suspendSr._xapiRef) } + const xenStoreData = extract(params, 'xenStoreData') + if (xenStoreData !== undefined) { + await this.getXapiObject(VM).update_xenstore_data(mapKeys(xenStoreData, (v, k) => autoPrefix('vm-data/', k))) + } + return xapi.editVm(vmId, params, async (limits, vm) => { const resourceSet = xapi.xo.getData(vm, 'resourceSet') @@ -747,6 +755,15 @@ set.params = { blockedOperations: { type: 'object', optional: true, properties: { '*': { type: ['boolean', 'null', 'string'] } } }, suspendSr: { type: ['string', 'null'], optional: true }, + + xenStoreData: { + description: 'properties that should be set or deleted (if null) in the VM XenStore', + optional: true, + type: 'object', + additionalProperties: { + type: ['null', 'string'], + }, + }, } set.resolve = {