From ae9269d1b1afb2a73602f66dfe1e5a6b10cd3f50 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Fri, 7 Feb 2014 15:19:13 +0100 Subject: [PATCH] `vm.{eject,insert}Cd()`. --- src/api/vm.coffee | 70 ++++++++++++++++++++++++++++++++++++++++++++ src/spec.coffee | 2 ++ src/spec.spec.coffee | 2 ++ src/xo.coffee | 24 ++++++++++----- 4 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/api/vm.coffee b/src/api/vm.coffee index 29e0d1226..36e107946 100644 --- a/src/api/vm.coffee +++ b/src/api/vm.coffee @@ -31,6 +31,7 @@ $isVMRunning = do -> #===================================================================== +# FIXME: Make the method as atomic as possible. exports.create = -> # Validates and retrieves the parameters. { @@ -256,6 +257,75 @@ exports.delete = -> xapi.call 'VM.destroy', VM.ref +exports.ejectCd = -> + {id} = @getParams { + id: { type: 'string' } + } + + try + VM = @getObject id + catch + @throw 'NO_SUCH_OBJECT' + + xapi = @getXAPI VM + + # Finds the CD drive. + cdDriveRef = null + $each (@getObjects VM.$VBDs), (VBD, _1, _2, done) -> + if VBD.is_cd_drive + cdDriveRef = VBD.ref + done + + if cdDriveRef + xapi.call 'VBD.eject', cdDriveRef + xapi.call 'VBD.destroy', cdDriveRef + +exports.insertCd = -> + {id, cd_id, force} = @getParams { + id: { type: 'string' } + cd_id: { type: 'string' } + force: { type: 'boolean' } + } + + try + VM = @getObject id + VDI = @getObject cd_id + catch + @throw 'NO_SUCH_OBJECT' + + xapi = @getXAPI VM + + # Finds the CD drive. + cdDrive = null + $each (@getObjects VM.$VBDs), (VBD, _1, _2, done) -> + if VBD.is_cd_drive + cdDrive = VBD + done + + if cdDrive + cdDriveRef = cdDrive.ref + + if cdDrive.VDI + @throw 'INVALID_PARAMS' unless force + xapi.call 'VBD.eject', cdDriveRef + else + cdDriveRef = xapi.call 'VBD.create', { + bootable: true + device: '' + empty: true + mode: 'RO' + other_config: {} + qos_algorithm_params: {} + qos_algorithm_type: '' + type: 'CD' + unpluggable: true + userdevice: (xapi.call 'VM.get_allowed_VBD_devices', VM.ref)[0] + VDI: 'OpaqueRef:NULL' + VM: VM.ref + } + + xapi.call 'VBD.insert', cdDriveRef, VDI.ref + exports.migrate = -> {id, host_id} = @getParams { # Identifier of the VM to migrate. diff --git a/src/spec.coffee b/src/spec.coffee index 85ced53ce..edc5b6b77 100644 --- a/src/spec.coffee +++ b/src/spec.coffee @@ -668,6 +668,8 @@ module.exports = -> read_only: -> @genval.mode is 'RO' + is_cd_drive: -> @genval.type is 'CD' + # null if empty. # # TODO: Is it really equivalent? diff --git a/src/spec.spec.coffee b/src/spec.spec.coffee index cd7e38b1d..4fffbb6f9 100644 --- a/src/spec.spec.coffee +++ b/src/spec.spec.coffee @@ -670,6 +670,8 @@ describe 'spec', -> $expect(vbd.bootable).to.be.false + $expect(vbd.is_cd_drive).to.be.false + $expect(vbd.read_only).to.be.false $expect(vbd.VDI).to.equal 'OpaqueRef:1f7f9828-f4e7-41dd-20e6-3bf57c559a78' diff --git a/src/xo.coffee b/src/xo.coffee index 114e082c6..32a30d3f0 100644 --- a/src/xo.coffee +++ b/src/xo.coffee @@ -310,19 +310,29 @@ class $XO extends $EventEmitter @_xobjs.get key - # Returns all objects. - getObjects: -> - @_xobjs.get() + # Returns objects. + getObjects: (keys) -> + # Returns all objects if no keys are passed. + return @_xobjs.get() unless keys + + # Resolves all UUIDs. + {_UUIDsToKeys: UUIDsToKeys} = this + for key, index in keys + keys[index] = UUIDsToKeys[key] if key of UUIDsToKeys + + # Fetches all objects ignore those missing. + @_xobjs.get keys, true # Returns the XAPI connection associated to an object. getXAPI: (object) -> if $_.isString object object = @getObject object - if (poolRef = object.poolRef)? - @_xapis[poolRef] - else - null + {poolRef} = object + unless poolRef + throw new Error "no XAPI found for #{object.UUID}" + + @_xapis[poolRef] #=====================================================================