Specify storage IP for iscsi connector

The virt drivers supply a connector hash to cinder volumes when
attaching. This used to basically default to CONF.my_ip. This patch
allows the host to have a separate config option in the case the block
traffic is on a separate network.

DocImpact: Adds my_block_storage_ip config option for block traffic going
over a separate network.
Closes-Bug: #1347025

Change-Id: I2bab7226376acd7da78e038a230bf65613547ba6
This commit is contained in:
Cory Stone 2014-07-23 16:18:09 -05:00
parent 4c45902548
commit f5943ad3af
9 changed files with 94 additions and 5 deletions

View File

@ -46,6 +46,9 @@ netconf_opts = [
cfg.StrOpt('my_ip',
default=_get_my_ip(),
help='IP address of this host'),
cfg.StrOpt('my_block_storage_ip',
default='$my_ip',
help='Block storage IP address of this host'),
cfg.StrOpt('host',
default=socket.gethostname(),
help='Name of this node. This can be an opaque identifier. '

View File

@ -1491,6 +1491,28 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
self.assertEqual(fake_host, data.get('host'))
self.assertEqual(fake_initiator, data.get('initiator'))
def test_get_volume_connector_storage_ip(self):
self._instance_data = self._get_instance_data()
instance = db.instance_create(self._context, self._instance_data)
fake_my_ip = "fake_ip"
fake_my_block_ip = "fake_block_ip"
fake_host = "fake_host"
fake_initiator = "fake_initiator"
self.flags(my_ip=fake_my_ip)
self.flags(my_block_storage_ip=fake_my_block_ip)
self.flags(host=fake_host)
with mock.patch.object(volumeutils.VolumeUtils,
"get_iscsi_initiator") as mock_initiator:
mock_initiator.return_value = fake_initiator
data = self._conn.get_volume_connector(instance)
self.assertEqual(fake_my_block_ip, data.get('ip'))
self.assertEqual(fake_host, data.get('host'))
self.assertEqual(fake_initiator, data.get('initiator'))
def _setup_test_migrate_disk_and_power_off_mocks(self, same_host=False,
copy_exception=False,
size_exception=False):

View File

@ -857,6 +857,17 @@ class LibvirtConnTestCase(test.NoDBTestCase):
result = conn.get_volume_connector(volume)
self.assertThat(expected, matchers.DictMatches(result))
def test_get_connector_storage_ip(self):
ip = '100.100.100.100'
storage_ip = '101.101.101.101'
self.flags(my_block_storage_ip=storage_ip, my_ip=ip)
volume = {
'id': 'fake'
}
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
result = conn.get_volume_connector(volume)
self.assertEqual(storage_ip, result['ip'])
def test_lifecycle_event_registration(self):
calls = []

View File

@ -425,6 +425,17 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
self.assertIn('initiator', result)
self.assertIn('host', result)
@catch_notimplementederror
def test_get_volume_connector_storage_ip(self):
ip = 'my_ip'
storage_ip = 'storage_ip'
self.flags(my_block_storage_ip=storage_ip, my_ip=ip)
result = self.connection.get_volume_connector({'id': 'fake'})
self.assertIn('ip', result)
self.assertIn('initiator', result)
self.assertIn('host', result)
self.assertEqual(storage_ip, result['ip'])
@catch_notimplementederror
def test_attach_detach_volume(self):
instance_ref, network_info = self._get_running_instance()

View File

@ -45,7 +45,8 @@ class XenAPIDriverTestCase(stubs.XenAPITestBaseNoDB):
'supported_instances': arch.X86_64,
'host_cpu_info': {'cpu_count': 50},
'vcpus_used': 10,
'pci_passthrough_devices': ''}
'pci_passthrough_devices': '',
'host_other-config': {'iscsi_iqn': 'someiqn'}}
def test_available_resource(self):
driver = self._get_driver()
@ -99,3 +100,36 @@ class XenAPIDriverTestCase(stubs.XenAPITestBaseNoDB):
def test_public_api_signatures(self):
inst = self._get_driver()
self.assertPublicAPISignatures(driver.ComputeDriver(None), inst)
def test_get_volume_connector(self):
ip = '123.123.123.123'
driver = self._get_driver()
self.flags(connection_url='http://%s' % ip,
connection_password='test_pass', group='xenserver')
self.stubs.Set(driver.host_state, 'get_host_stats', self.host_stats)
connector = driver.get_volume_connector({'uuid': 'fake'})
self.assertIn('ip', connector)
self.assertEqual(connector['ip'], ip)
self.assertIn('initiator', connector)
self.assertEqual(connector['initiator'], 'someiqn')
def test_get_block_storage_ip(self):
my_ip = '123.123.123.123'
connection_ip = '124.124.124.124'
driver = self._get_driver()
self.flags(connection_url='http://%s' % connection_ip,
group='xenserver')
self.flags(my_ip=my_ip, my_block_storage_ip=my_ip)
ip = driver._get_block_storage_ip()
self.assertEqual(connection_ip, ip)
def test_get_block_storage_ip_conf(self):
driver = self._get_driver()
my_ip = '123.123.123.123'
my_block_storage_ip = '124.124.124.124'
self.flags(my_ip=my_ip, my_block_storage_ip=my_block_storage_ip)
ip = driver._get_block_storage_ip()
self.assertEqual(my_block_storage_ip, ip)

View File

@ -467,7 +467,9 @@ class FakeDriver(driver.ComputeDriver):
return 'disabled'
def get_volume_connector(self, instance):
return {'ip': '127.0.0.1', 'initiator': 'fake', 'host': 'fakehost'}
return {'ip': CONF.my_block_storage_ip,
'initiator': 'fake',
'host': 'fakehost'}
def get_available_nodes(self, refresh=False):
return _FAKE_NODES

View File

@ -208,7 +208,7 @@ class VolumeOps(object):
LOG.warn(_('Could not determine iscsi initiator name'),
instance=instance)
return {
'ip': CONF.my_ip,
'ip': CONF.my_block_storage_ip,
'host': CONF.host,
'initiator': self._initiator,
}

View File

@ -1307,7 +1307,7 @@ class LibvirtDriver(driver.ComputeDriver):
'world wide port names',
instance=instance)
connector = {'ip': CONF.my_ip,
connector = {'ip': CONF.my_block_storage_ip,
'host': CONF.host}
if self._initiator:

View File

@ -386,11 +386,17 @@ class XenAPIDriver(driver.ComputeDriver):
instance=instance)
self._initiator = None
return {
'ip': self.get_host_ip_addr(),
'ip': self._get_block_storage_ip(),
'initiator': self._initiator,
'host': self._hypervisor_hostname
}
def _get_block_storage_ip(self):
# If CONF.my_block_storage_ip is set, use it.
if CONF.my_block_storage_ip != CONF.my_ip:
return CONF.my_block_storage_ip
return self.get_host_ip_addr()
@staticmethod
def get_host_ip_addr():
xs_url = urlparse.urlparse(CONF.xenserver.connection_url)