Add initiator to initialize_connection
Some volumes need to know the name of the initiator that will be connecting to the iscsi volume. This adds a call down to the hypervisor driver to get the ip and the initiator name for the vm before calling initialize connection. This connection is passed down to the volume driver so that it can be used to authenticate when the hypervisor tries to connect to the volume. * Adds initiator initialize_connection * Makes a call to driver to get initiator name and ip address * Gets initiator from openiscsi for libvirt * Gets initiator from config for xenapi * Add tests for the driver calls * Fixes bug 924461 Change-Id: I5b6a2dd84560c7f7b447571e0abf0993e5512ca0
This commit is contained in:
@@ -652,9 +652,10 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
# NOTE(vish): actual driver detach done in driver.destroy, so
|
||||
# just tell nova-volume that we are done with it.
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
self.volume_api.terminate_connection(context,
|
||||
volume,
|
||||
FLAGS.my_ip)
|
||||
connector)
|
||||
self.volume_api.detach(context, volume)
|
||||
except exception.DiskNotFound as exc:
|
||||
LOG.warn(_("Ignoring DiskNotFound: %s") % exc)
|
||||
@@ -1597,10 +1598,10 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
msg = _("instance %(instance_uuid)s: booting with "
|
||||
"volume %(volume_id)s at %(mountpoint)s")
|
||||
LOG.audit(msg % locals(), context=context)
|
||||
address = FLAGS.my_ip
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
connection_info = self.volume_api.initialize_connection(context,
|
||||
volume,
|
||||
address)
|
||||
connector)
|
||||
self.volume_api.attach(context, volume, instance_id, mountpoint)
|
||||
return connection_info
|
||||
|
||||
@@ -1616,10 +1617,10 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
msg = _("instance %(instance_uuid)s: attaching volume %(volume_id)s"
|
||||
" to %(mountpoint)s")
|
||||
LOG.audit(msg % locals(), context=context)
|
||||
address = FLAGS.my_ip
|
||||
connector = self.driver.get_volume_connector(instance_ref)
|
||||
connection_info = self.volume_api.initialize_connection(context,
|
||||
volume,
|
||||
address)
|
||||
connector)
|
||||
try:
|
||||
self.driver.attach_volume(connection_info,
|
||||
instance_ref['name'],
|
||||
@@ -1631,7 +1632,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
LOG.exception(msg % locals(), context=context)
|
||||
self.volume_api.terminate_connection(context,
|
||||
volume,
|
||||
address)
|
||||
connector)
|
||||
|
||||
self.volume_api.attach(context, volume, instance_id, mountpoint)
|
||||
values = {
|
||||
@@ -1674,7 +1675,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
bdm = self._get_instance_volume_bdm(context, instance_id, volume_id)
|
||||
self._detach_volume(context, instance_ref, bdm)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.terminate_connection(context, volume, FLAGS.my_ip)
|
||||
connector = self.driver.get_volume_connector(instance_ref)
|
||||
self.volume_api.terminate_connection(context, volume, connector)
|
||||
self.volume_api.detach(context.elevated(), volume)
|
||||
self.db.block_device_mapping_destroy_by_instance_and_volume(
|
||||
context, instance_id, volume_id)
|
||||
@@ -1693,7 +1695,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
volume_id)
|
||||
self._detach_volume(context, instance_ref, bdm)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.terminate_connection(context, volume, FLAGS.my_ip)
|
||||
connector = self.driver.get_volume_connector(instance_ref)
|
||||
self.volume_api.terminate_connection(context, volume, connector)
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
|
||||
@@ -168,4 +168,7 @@ filterlist = [
|
||||
# nova/virt/libvirt/utils.py: 'mkswap'
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkswap'
|
||||
filters.CommandFilter("/sbin/mkswap", "root"),
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
filters.ReadFileFilter("/etc/iscsi/initiatorname.iscsi"),
|
||||
]
|
||||
|
||||
@@ -21,6 +21,10 @@ disk_sizes = {}
|
||||
disk_backing_files = {}
|
||||
|
||||
|
||||
def get_iscsi_initiator():
|
||||
return "fake.initiator.iqn"
|
||||
|
||||
|
||||
def create_image(disk_format, path, size):
|
||||
pass
|
||||
|
||||
|
||||
@@ -123,6 +123,10 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
def get_hypervisor_type(self):
|
||||
return self.hyperv
|
||||
self.fake_conn = FakeLibvirtConnection("Xen")
|
||||
self.connr = {
|
||||
'ip': '127.0.0.1',
|
||||
'initiator': 'fake_initiator'
|
||||
}
|
||||
|
||||
def test_libvirt_iscsi_driver(self):
|
||||
# NOTE(vish) exists is to make driver assume connecting worked
|
||||
@@ -136,8 +140,7 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
'name': name,
|
||||
'provider_auth': None,
|
||||
'provider_location': '%s,fake %s' % (location, iqn)}
|
||||
address = '127.0.0.1'
|
||||
connection_info = vol_driver.initialize_connection(vol, '127.0.0.1')
|
||||
connection_info = vol_driver.initialize_connection(vol, self.connr)
|
||||
mount_device = "vde"
|
||||
xml = libvirt_driver.connect_volume(connection_info, mount_device)
|
||||
tree = xml_to_tree(xml)
|
||||
@@ -145,7 +148,7 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
self.assertEqual(tree.get('type'), 'block')
|
||||
self.assertEqual(tree.find('./source').get('dev'), dev_str)
|
||||
libvirt_driver.disconnect_volume(connection_info, mount_device)
|
||||
connection_info = vol_driver.terminate_connection(vol, '127.0.0.1')
|
||||
connection_info = vol_driver.terminate_connection(vol, self.connr)
|
||||
expected_commands = [('iscsiadm', '-m', 'node', '-T', iqn,
|
||||
'-p', location),
|
||||
('iscsiadm', '-m', 'node', '-T', iqn,
|
||||
@@ -167,8 +170,7 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
name = 'volume-00000001'
|
||||
vol = {'id': 1, 'name': name}
|
||||
address = '127.0.0.1'
|
||||
connection_info = vol_driver.initialize_connection(vol, address)
|
||||
connection_info = vol_driver.initialize_connection(vol, self.connr)
|
||||
mount_device = "vde"
|
||||
xml = libvirt_driver.connect_volume(connection_info, mount_device)
|
||||
tree = xml_to_tree(xml)
|
||||
@@ -176,15 +178,14 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'sheepdog')
|
||||
self.assertEqual(tree.find('./source').get('name'), name)
|
||||
libvirt_driver.disconnect_volume(connection_info, mount_device)
|
||||
connection_info = vol_driver.terminate_connection(vol, '127.0.0.1')
|
||||
connection_info = vol_driver.terminate_connection(vol, self.connr)
|
||||
|
||||
def test_libvirt_rbd_driver(self):
|
||||
vol_driver = volume_driver.RBDDriver()
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
name = 'volume-00000001'
|
||||
vol = {'id': 1, 'name': name}
|
||||
address = '127.0.0.1'
|
||||
connection_info = vol_driver.initialize_connection(vol, address)
|
||||
connection_info = vol_driver.initialize_connection(vol, self.connr)
|
||||
mount_device = "vde"
|
||||
xml = libvirt_driver.connect_volume(connection_info, mount_device)
|
||||
tree = xml_to_tree(xml)
|
||||
@@ -193,7 +194,7 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
rbd_name = '%s/%s' % (FLAGS.rbd_pool, name)
|
||||
self.assertEqual(tree.find('./source').get('name'), rbd_name)
|
||||
libvirt_driver.disconnect_volume(connection_info, mount_device)
|
||||
connection_info = vol_driver.terminate_connection(vol, '127.0.0.1')
|
||||
connection_info = vol_driver.terminate_connection(vol, self.connr)
|
||||
|
||||
|
||||
class CacheConcurrencyTestCase(test.TestCase):
|
||||
@@ -355,6 +356,22 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
|
||||
return db.service_create(context.get_admin_context(), service_ref)
|
||||
|
||||
def test_get_connector(self):
|
||||
initiator = 'fake.initiator.iqn'
|
||||
ip = 'fakeip'
|
||||
self.flags(my_ip=ip)
|
||||
|
||||
conn = connection.LibvirtConnection(True)
|
||||
expected = {
|
||||
'ip': ip,
|
||||
'initiator': initiator
|
||||
}
|
||||
volume = {
|
||||
'id': 'fake'
|
||||
}
|
||||
result = conn.get_volume_connector(volume)
|
||||
self.assertDictMatch(expected, result)
|
||||
|
||||
def test_preparing_xml_info(self):
|
||||
conn = connection.LibvirtConnection(True)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
@@ -1764,6 +1781,17 @@ class NWFilterTestCase(test.TestCase):
|
||||
|
||||
|
||||
class LibvirtUtilsTestCase(test.TestCase):
|
||||
def test_get_iscsi_initiator(self):
|
||||
self.mox.StubOutWithMock(utils, 'execute')
|
||||
initiator = 'fake.initiator.iqn'
|
||||
rval = ("junk\nInitiatorName=%s\njunk\n" % initiator, None)
|
||||
utils.execute('cat', '/etc/iscsi/initiatorname.iscsi',
|
||||
run_as_root=True).AndReturn(rval)
|
||||
# Start test
|
||||
self.mox.ReplayAll()
|
||||
result = libvirt_utils.get_iscsi_initiator()
|
||||
self.assertEqual(initiator, result)
|
||||
|
||||
def test_create_image(self):
|
||||
self.mox.StubOutWithMock(utils, 'execute')
|
||||
utils.execute('qemu-img', 'create', '-f', 'raw',
|
||||
|
||||
@@ -224,6 +224,12 @@ class _VirtDriverTestCase(test.TestCase):
|
||||
self.assertNotIn(instance_ref['name'],
|
||||
self.connection.list_instances())
|
||||
|
||||
@catch_notimplementederror
|
||||
def test_get_volume_connector(self):
|
||||
result = self.connection.get_volume_connector({'id': 'fake'})
|
||||
self.assertTrue('ip' in result)
|
||||
self.assertTrue('initiator' in result)
|
||||
|
||||
@catch_notimplementederror
|
||||
def test_attach_detach_volume(self):
|
||||
instance_ref, network_info = self._get_running_instance()
|
||||
|
||||
@@ -623,3 +623,17 @@ class ComputeDriver(object):
|
||||
the cache and remove images which are no longer of interest.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_volume_connector(self, instance):
|
||||
"""
|
||||
Get connector information for the instance for attaching to volumes.
|
||||
|
||||
Connector information is a dictionary representing the ip of the
|
||||
machine that will be making the connection and and the name of the
|
||||
iscsi initiator as follows:
|
||||
{
|
||||
'ip': ip,
|
||||
'initiator': initiator,
|
||||
}
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -301,3 +301,6 @@ class FakeConnection(driver.ComputeDriver):
|
||||
def get_disk_available_least(self):
|
||||
""" """
|
||||
pass
|
||||
|
||||
def get_volume_connector(self, instance):
|
||||
return {'ip': '127.0.0.1', 'initiator': 'fake'}
|
||||
|
||||
@@ -187,6 +187,7 @@ class LibvirtConnection(driver.ComputeDriver):
|
||||
super(LibvirtConnection, self).__init__()
|
||||
|
||||
self._host_state = None
|
||||
self._initiator = None
|
||||
self._wrapped_conn = None
|
||||
self.container = None
|
||||
self.read_only = read_only
|
||||
@@ -423,6 +424,16 @@ class LibvirtConnection(driver.ComputeDriver):
|
||||
if os.path.exists(target):
|
||||
shutil.rmtree(target)
|
||||
|
||||
def get_volume_connector(self, _instance):
|
||||
if not self._initiator:
|
||||
self._initiator = libvirt_utils.get_iscsi_initiator()
|
||||
if not self._initiator:
|
||||
LOG.warn(_('Could not determine iscsi initiator name'))
|
||||
return {
|
||||
'ip': FLAGS.my_ip,
|
||||
'initiator': self._initiator,
|
||||
}
|
||||
|
||||
def volume_driver_method(self, method_name, connection_info,
|
||||
*args, **kwargs):
|
||||
driver_type = connection_info.get('driver_volume_type')
|
||||
@@ -723,7 +734,7 @@ class LibvirtConnection(driver.ComputeDriver):
|
||||
if virsh_output.startswith('/dev/'):
|
||||
LOG.info(_("cool, it's a device"))
|
||||
out, err = utils.execute('dd',
|
||||
"if=%s" % virsh_output,
|
||||
'if=%s' % virsh_output,
|
||||
'iflag=nonblock',
|
||||
run_as_root=True,
|
||||
check_exit_code=False)
|
||||
@@ -751,7 +762,8 @@ class LibvirtConnection(driver.ComputeDriver):
|
||||
|
||||
if FLAGS.libvirt_type == 'xen':
|
||||
# Xen is special
|
||||
virsh_output = utils.execute('virsh', 'ttyconsole',
|
||||
virsh_output = utils.execute('virsh',
|
||||
'ttyconsole',
|
||||
instance['name'])
|
||||
data = self._flush_xen_console(virsh_output)
|
||||
fpath = self._append_to_file(data, console_log)
|
||||
|
||||
@@ -44,6 +44,16 @@ def execute(*args, **kwargs):
|
||||
return utils.execute(*args, **kwargs)
|
||||
|
||||
|
||||
def get_iscsi_initiator():
|
||||
"""Get iscsi initiator name for this machine"""
|
||||
# NOTE(vish) openiscsi stores initiator name in a file that
|
||||
# needs root permission to read.
|
||||
contents = utils.read_file_as_root('/etc/iscsi/initiatorname.iscsi')
|
||||
for l in contents.split('\n'):
|
||||
if l.startswith('InitiatorName='):
|
||||
return l[l.index('=') + 1:].strip()
|
||||
|
||||
|
||||
def create_image(disk_format, path, size):
|
||||
"""Create a disk image
|
||||
|
||||
|
||||
@@ -178,6 +178,15 @@ class VMWareESXConnection(driver.ComputeDriver):
|
||||
"""Return link to instance's ajax console."""
|
||||
return self._vmops.get_ajax_console(instance)
|
||||
|
||||
def get_volume_connector(self, _instance):
|
||||
"""Return volume connector information"""
|
||||
# TODO(vish): When volume attaching is supported, return the
|
||||
# proper initiator iqn.
|
||||
return {
|
||||
'ip': FLAGS.vmwareapi_host_ip,
|
||||
'initiator': None
|
||||
}
|
||||
|
||||
def attach_volume(self, connection_info, instance_name, mountpoint):
|
||||
"""Attach volume storage to VM instance."""
|
||||
pass
|
||||
|
||||
@@ -179,6 +179,7 @@ class XenAPIConnection(driver.ComputeDriver):
|
||||
self._host_state = None
|
||||
self._product_version = self._session.get_product_version()
|
||||
self._vmops = VMOps(self._session, self._product_version)
|
||||
self._initiator = None
|
||||
|
||||
@property
|
||||
def host_state(self):
|
||||
@@ -348,6 +349,20 @@ class XenAPIConnection(driver.ComputeDriver):
|
||||
"""Return link to instance's ajax console"""
|
||||
return self._vmops.get_vnc_console(instance)
|
||||
|
||||
def get_volume_connector(self, _instance):
|
||||
"""Return volume connector information"""
|
||||
if not self._initiator:
|
||||
stats = self.get_host_stats(update=True)
|
||||
try:
|
||||
self._initiator = stats['host_other-config']['iscsi_iqn']
|
||||
except (TypeError, KeyError):
|
||||
LOG.warn(_('Could not determine iscsi initiator name'))
|
||||
self._initiator = None
|
||||
return {
|
||||
'ip': self.get_host_ip_addr(),
|
||||
'initiator': self._initiator
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_host_ip_addr():
|
||||
xs_url = urlparse.urlparse(FLAGS.xenapi_connection_url)
|
||||
|
||||
@@ -244,22 +244,22 @@ class API(base.Base):
|
||||
"args": {"volume_id": volume['id']}})
|
||||
|
||||
@wrap_check_policy
|
||||
def initialize_connection(self, context, volume, address):
|
||||
def initialize_connection(self, context, volume, connector):
|
||||
host = volume['host']
|
||||
queue = self.db.queue_get_for(context, FLAGS.volume_topic, host)
|
||||
return rpc.call(context, queue,
|
||||
{"method": "initialize_connection",
|
||||
"args": {"volume_id": volume['id'],
|
||||
"address": address}})
|
||||
"connector": connector}})
|
||||
|
||||
@wrap_check_policy
|
||||
def terminate_connection(self, context, volume, address):
|
||||
def terminate_connection(self, context, volume, connector):
|
||||
host = volume['host']
|
||||
queue = self.db.queue_get_for(context, FLAGS.volume_topic, host)
|
||||
return rpc.call(context, queue,
|
||||
{"method": "terminate_connection",
|
||||
"args": {"volume_id": volume['id'],
|
||||
"address": address}})
|
||||
"connector": connector}})
|
||||
|
||||
def _create_snapshot(self, context, volume, name, description,
|
||||
force=False):
|
||||
|
||||
@@ -215,12 +215,12 @@ class VolumeDriver(object):
|
||||
"""Make sure volume is exported."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
"""Allow connection to ip and return connection info."""
|
||||
def initialize_connection(self, volume, connector):
|
||||
"""Allow connection to connector and return connection info."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
"""Disallow connection from ip"""
|
||||
def terminate_connection(self, volume, connector):
|
||||
"""Disallow connection from connector"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_volume_stats(self, refresh=False):
|
||||
@@ -409,7 +409,7 @@ class ISCSIDriver(VolumeDriver):
|
||||
'-v', property_value)
|
||||
return self._run_iscsiadm(iscsi_properties, iscsi_command)
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
"""Initializes the connection and returns connection info.
|
||||
|
||||
The iscsi driver returns a driver_volume_type of 'iscsi'.
|
||||
@@ -433,7 +433,7 @@ class ISCSIDriver(VolumeDriver):
|
||||
'data': iscsi_properties
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
pass
|
||||
|
||||
def check_for_export(self, context, volume_id):
|
||||
@@ -461,13 +461,13 @@ class FakeISCSIDriver(ISCSIDriver):
|
||||
"""No setup necessary in fake mode."""
|
||||
pass
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
return {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': {}
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@@ -532,7 +532,7 @@ class RBDDriver(VolumeDriver):
|
||||
"""Removes an export for a logical volume"""
|
||||
pass
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
return {
|
||||
'driver_volume_type': 'rbd',
|
||||
'data': {
|
||||
@@ -540,7 +540,7 @@ class RBDDriver(VolumeDriver):
|
||||
}
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
pass
|
||||
|
||||
|
||||
@@ -601,7 +601,7 @@ class SheepdogDriver(VolumeDriver):
|
||||
"""Removes an export for a logical volume"""
|
||||
pass
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
return {
|
||||
'driver_volume_type': 'sheepdog',
|
||||
'data': {
|
||||
@@ -609,7 +609,7 @@ class SheepdogDriver(VolumeDriver):
|
||||
}
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
pass
|
||||
|
||||
|
||||
@@ -638,10 +638,10 @@ class LoggingVolumeDriver(VolumeDriver):
|
||||
def remove_export(self, context, volume):
|
||||
self.log_action('remove_export', volume)
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
self.log_action('initialize_connection', volume)
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
self.log_action('terminate_connection', volume)
|
||||
|
||||
def check_for_export(self, context, volume_id):
|
||||
|
||||
@@ -254,31 +254,51 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
# TODO(vish): refactor this into a more general "unreserve"
|
||||
self.db.volume_detached(context, volume_id)
|
||||
|
||||
def initialize_connection(self, context, volume_id, address):
|
||||
"""Initialize volume to be connected from address.
|
||||
def initialize_connection(self, context, volume_id, connector):
|
||||
"""Prepare volume for connection from host represented by connector.
|
||||
|
||||
This method calls the driver initialize_connection and returns
|
||||
it to the caller. The driver is responsible for doing any
|
||||
necessary security setup and returning a connection_info dictionary
|
||||
in the following format:
|
||||
{'driver_volume_type': driver_volume_type
|
||||
'data': data}
|
||||
it to the caller. The connector parameter is a dictionary with
|
||||
information about the host that will connect to the volume in the
|
||||
following format:
|
||||
{
|
||||
'ip': ip,
|
||||
'initiator': initiator,
|
||||
}
|
||||
|
||||
ip: the ip address of the connecting machine
|
||||
|
||||
initiator: the iscsi initiator name of the connecting machine.
|
||||
This can be None if the connecting machine does not support iscsi
|
||||
connections.
|
||||
|
||||
driver is responsible for doing any necessary security setup and
|
||||
returning a connection_info dictionary in the following format:
|
||||
{
|
||||
'driver_volume_type': driver_volume_type,
|
||||
'data': data,
|
||||
}
|
||||
|
||||
driver_volume_type: a string to identify the type of volume. This
|
||||
can be used by the calling code to determine the
|
||||
strategy for connecting to the volume. This could
|
||||
be 'iscsi', 'rbd', 'sheepdog', etc.
|
||||
|
||||
data: this is the data that the calling code will use to connect
|
||||
to the volume. Keep in mind that this will be serialized to
|
||||
json in various places, so it should not contain any non-json
|
||||
data types.
|
||||
"""
|
||||
volume_ref = self.db.volume_get(context, volume_id)
|
||||
return self.driver.initialize_connection(volume_ref, address)
|
||||
return self.driver.initialize_connection(volume_ref, connector)
|
||||
|
||||
def terminate_connection(self, context, volume_id, address):
|
||||
def terminate_connection(self, context, volume_id, connector):
|
||||
"""Cleanup connection from host represented by connector.
|
||||
|
||||
The format of connector is the same as for initialize_connection.
|
||||
"""
|
||||
volume_ref = self.db.volume_get(context, volume_id)
|
||||
self.driver.terminate_connection(volume_ref, address)
|
||||
self.driver.terminate_connection(volume_ref, connector)
|
||||
|
||||
def check_for_export(self, context, instance_id):
|
||||
"""Make sure whether volume is exported."""
|
||||
|
||||
@@ -203,7 +203,7 @@ class XenSMDriver(VolumeDriver):
|
||||
"""Safely, synchronously recreates an export for a logical volume."""
|
||||
pass
|
||||
|
||||
def initialize_connection(self, volume, address):
|
||||
def initialize_connection(self, volume, connector):
|
||||
try:
|
||||
xensm_properties = dict(self.db.sm_volume_get(self.ctxt,
|
||||
volume['id']))
|
||||
@@ -236,5 +236,5 @@ class XenSMDriver(VolumeDriver):
|
||||
'data': xensm_properties
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, address):
|
||||
def terminate_connection(self, volume, connector):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user