From 1715dadf8f176d0abf27af9946c6be761e9f6b64 Mon Sep 17 00:00:00 2001 From: Pierre Donias Date: Wed, 27 Sep 2017 17:36:23 +0200 Subject: [PATCH] feat(self): handle add/remove VDI on VM (#605) See vatesfr/xo-web#2348 --- src/api/disk.js | 36 +++++++++++++++++++++++++++++++----- src/api/vdi.coffee | 10 ++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/api/disk.js b/src/api/disk.js index 79dc5c0b5..780bc5096 100644 --- a/src/api/disk.js +++ b/src/api/disk.js @@ -1,12 +1,33 @@ -import {parseSize} from '../utils' +import { parseSize } from '../utils' +import { unauthorized } from 'xo-common/api-errors' // =================================================================== -export async function create ({name, size, sr}) { - const vdi = await this.getXapi(sr).createVdi(parseSize(size), { +export async function create ({ name, size, sr, vm, bootable, position, mode }) { + const attach = vm !== undefined + + let resourceSet + if (attach && (resourceSet = vm.resourceSet) != null) { + await this.checkResourceSetConstraints(resourceSet, this.user.id, [ sr.id ]) + await this.allocateLimitsInResourceSet({ disk: size }, resourceSet) + } else if (!(await this.hasPermissions(this.user.id, [ [ sr.id, 'administrate' ] ]))) { + throw unauthorized() + } + + const xapi = this.getXapi(sr) + const vdi = await xapi.createVdi(parseSize(size), { name_label: name, sr: sr._xapiId }) + + if (attach) { + await xapi.attachVdiToVm(vdi.$id, vm._xapiId, { + bootable, + position, + readOnly: mode === 'RO' + }) + } + return vdi.$id } @@ -15,11 +36,16 @@ create.description = 'create a new disk on a SR' create.params = { name: { type: 'string' }, size: { type: ['integer', 'string'] }, - sr: { type: 'string' } + sr: { type: 'string' }, + vm: { type: 'string', optional: true }, + bootable: { type: 'boolean', optional: true }, + mode: { type: 'string', optional: true }, + position: { type: 'string', optional: true } } create.resolve = { - sr: ['sr', 'SR', 'administrate'] + vm: ['vm', 'VM', 'administrate'], + sr: ['sr', 'SR', false] } // ------------------------------------------------------------------- diff --git a/src/api/vdi.coffee b/src/api/vdi.coffee index f8a530147..de645b69f 100644 --- a/src/api/vdi.coffee +++ b/src/api/vdi.coffee @@ -6,10 +6,20 @@ {invalidParameters, unauthorized} = require 'xo-common/api-errors' {isArray: $isArray, parseSize} = require '../utils' {JsonRpcError} = require 'json-rpc-peer' +{reduce} = require 'lodash' #===================================================================== delete_ = $coroutine ({vdi}) -> + resourceSet = reduce( + vdi.$VBDs + (resourceSet, vbd) => resourceSet || @getObject(@getObject(vbd, 'VBD').VM).resourceSet + undefined + ) + + if resourceSet != undefined + yield this.allocateLimitsInResourceSet({ disk: -vdi.size }, resourceSet) + yield @getXapi(vdi).deleteVdi(vdi._xapiId) return