18
18
Management class for Storage-related functions (attach, detach, etc).
22
from nova import exception
23
from nova.virt.xenapi.vm_utils import VMHelper
24
from nova.virt.xenapi.volume_utils import VolumeHelper
25
from nova.virt.xenapi.volume_utils import StorageError
22
28
class VolumeOps(object):
30
Management class for Volume-related tasks
23
33
def __init__(self, session):
34
self.XenAPI = session.get_imported_xenapi()
24
35
self._session = session
36
# Load XenAPI module in the helper classes respectively
37
VolumeHelper.XenAPI = self.XenAPI
38
VMHelper.XenAPI = self.XenAPI
26
40
def attach_volume(self, instance_name, device_path, mountpoint):
27
# FIXME: that's going to be sorted when iscsi-xenapi lands in branch
41
"""Attach volume storage to VM instance"""
42
# Before we start, check that the VM exists
43
vm_ref = VMHelper.lookup(self._session, instance_name)
45
raise exception.NotFound(_('Instance %s not found')
47
# NOTE: No Resource Pool concept so far
48
logging.debug(_("Attach_volume: %s, %s, %s"),
49
instance_name, device_path, mountpoint)
50
# Create the iSCSI SR, and the PDB through which hosts access SRs.
51
# But first, retrieve target info, like Host, IQN, LUN and SCSIID
52
vol_rec = VolumeHelper.parse_volume_info(device_path, mountpoint)
53
label = 'SR-%s' % vol_rec['volumeId']
54
description = 'Disk-for:%s' % instance_name
56
sr_ref = VolumeHelper.create_iscsi_storage(self._session,
60
# Introduce VDI and attach VBD to VM
62
vdi_ref = VolumeHelper.introduce_vdi(self._session, sr_ref)
63
except StorageError, exc:
65
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
66
raise Exception(_('Unable to create VDI on SR %s for instance %s')
71
vbd_ref = VMHelper.create_vbd(self._session,
73
vol_rec['deviceNumber'],
75
except self.XenAPI.Failure, exc:
77
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
78
raise Exception(_('Unable to use SR %s for instance %s')
83
task = self._session.call_xenapi('Async.VBD.plug',
85
self._session.wait_for_task(vol_rec['deviceNumber'], task)
86
except self.XenAPI.Failure, exc:
88
VolumeHelper.destroy_iscsi_storage(self._session,
90
raise Exception(_('Unable to attach volume to instance %s')
92
logging.info(_('Mountpoint %s attached to instance %s'),
93
mountpoint, instance_name)
30
95
def detach_volume(self, instance_name, mountpoint):
31
# FIXME: that's going to be sorted when iscsi-xenapi lands in branch
96
"""Detach volume storage to VM instance"""
97
# Before we start, check that the VM exists
98
vm_ref = VMHelper.lookup(self._session, instance_name)
100
raise exception.NotFound(_('Instance %s not found')
103
logging.debug(_("Detach_volume: %s, %s"), instance_name, mountpoint)
104
device_number = VolumeHelper.mountpoint_to_number(mountpoint)
106
vbd_ref = VMHelper.find_vbd_by_number(self._session,
107
vm_ref, device_number)
108
except StorageError, exc:
110
raise Exception(_('Unable to locate volume %s') % mountpoint)
113
sr_ref = VolumeHelper.find_sr_from_vbd(self._session,
115
VMHelper.unplug_vbd(self._session, vbd_ref)
116
except StorageError, exc:
118
raise Exception(_('Unable to detach volume %s') % mountpoint)
120
VMHelper.destroy_vbd(self._session, vbd_ref)
121
except StorageError, exc:
124
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
125
logging.info(_('Mountpoint %s detached from instance %s'),
126
mountpoint, instance_name)