18
18
Management class for Storage-related functions (attach, detach, etc).
21
from nova import exception
22
from nova import log as logging
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
28
LOG = logging.getLogger("nova.virt.xenapi.volumeops")
22
31
class VolumeOps(object):
33
Management class for Volume-related tasks
23
36
def __init__(self, session):
37
self.XenAPI = session.get_imported_xenapi()
24
38
self._session = session
39
# Load XenAPI module in the helper classes respectively
40
VolumeHelper.XenAPI = self.XenAPI
41
VMHelper.XenAPI = self.XenAPI
26
43
def attach_volume(self, instance_name, device_path, mountpoint):
27
# FIXME: that's going to be sorted when iscsi-xenapi lands in branch
44
"""Attach volume storage to VM instance"""
45
# Before we start, check that the VM exists
46
vm_ref = VMHelper.lookup(self._session, instance_name)
48
raise exception.NotFound(_('Instance %s not found')
50
# NOTE: No Resource Pool concept so far
51
LOG.debug(_("Attach_volume: %s, %s, %s"),
52
instance_name, device_path, mountpoint)
53
# Create the iSCSI SR, and the PDB through which hosts access SRs.
54
# But first, retrieve target info, like Host, IQN, LUN and SCSIID
55
vol_rec = VolumeHelper.parse_volume_info(device_path, mountpoint)
56
label = 'SR-%s' % vol_rec['volumeId']
57
description = 'Disk-for:%s' % instance_name
59
sr_ref = VolumeHelper.create_iscsi_storage(self._session,
63
# Introduce VDI and attach VBD to VM
65
vdi_ref = VolumeHelper.introduce_vdi(self._session, sr_ref)
66
except StorageError, exc:
68
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
69
raise Exception(_('Unable to create VDI on SR %s for instance %s')
74
vbd_ref = VMHelper.create_vbd(self._session,
76
vol_rec['deviceNumber'],
78
except self.XenAPI.Failure, exc:
80
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
81
raise Exception(_('Unable to use SR %s for instance %s')
86
task = self._session.call_xenapi('Async.VBD.plug',
88
self._session.wait_for_task(vol_rec['deviceNumber'], task)
89
except self.XenAPI.Failure, exc:
91
VolumeHelper.destroy_iscsi_storage(self._session,
93
raise Exception(_('Unable to attach volume to instance %s')
95
LOG.info(_('Mountpoint %s attached to instance %s'),
96
mountpoint, instance_name)
30
98
def detach_volume(self, instance_name, mountpoint):
31
# FIXME: that's going to be sorted when iscsi-xenapi lands in branch
99
"""Detach volume storage to VM instance"""
100
# Before we start, check that the VM exists
101
vm_ref = VMHelper.lookup(self._session, instance_name)
103
raise exception.NotFound(_('Instance %s not found')
106
LOG.debug(_("Detach_volume: %s, %s"), instance_name, mountpoint)
107
device_number = VolumeHelper.mountpoint_to_number(mountpoint)
109
vbd_ref = VMHelper.find_vbd_by_number(self._session,
110
vm_ref, device_number)
111
except StorageError, exc:
113
raise Exception(_('Unable to locate volume %s') % mountpoint)
116
sr_ref = VolumeHelper.find_sr_from_vbd(self._session,
118
VMHelper.unplug_vbd(self._session, vbd_ref)
119
except StorageError, exc:
121
raise Exception(_('Unable to detach volume %s') % mountpoint)
123
VMHelper.destroy_vbd(self._session, vbd_ref)
124
except StorageError, exc:
127
VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
128
LOG.info(_('Mountpoint %s detached from instance %s'),
129
mountpoint, instance_name)