summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-02-01 21:25:18 +0000
committerGerrit Code Review <review@openstack.org>2012-02-01 21:25:18 +0000
commit98a012fbb14d1b6463b9c8d13fcb1de742bae1d0 (patch)
tree3fd372e150b15001d39145a29d7aae7dc3bb49e3 /nova
parent260c96431f2dc5a5842aef5c105091bd8d64c552 (diff)
parentc56d677a7313b8b29406eaebdd27e59b2c1ee927 (diff)
downloadnova-98a012fbb14d1b6463b9c8d13fcb1de742bae1d0.tar.gz
nova-98a012fbb14d1b6463b9c8d13fcb1de742bae1d0.tar.xz
nova-98a012fbb14d1b6463b9c8d13fcb1de742bae1d0.zip
Merge "bug 921087: i18n-key and local-storage hard-coded in xenapi"
Diffstat (limited to 'nova')
-rw-r--r--nova/tests/test_xenapi.py69
-rw-r--r--nova/virt/xenapi/fake.py62
-rw-r--r--nova/virt/xenapi/vm_utils.py44
3 files changed, 135 insertions, 40 deletions
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 482cd450c..281e00fc0 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -1641,3 +1641,72 @@ class XenAPIDom0IptablesFirewallTestCase(test.TestCase):
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
if rule.chain == 'provider']
self.assertEqual(1, len(rules))
+
+
+class XenAPISRSelectionTestCase(test.TestCase):
+ """Unit tests for testing we find the right SR."""
+ def setUp(self):
+ super(XenAPISRSelectionTestCase, self).setUp()
+ self.stubs = stubout.StubOutForTesting()
+ stubs.stub_out_get_target(self.stubs)
+ xenapi_fake.reset()
+
+ def tearDown(self):
+ super(XenAPISRSelectionTestCase, self).tearDown()
+ self.stubs.UnsetAll()
+
+ def test_safe_find_sr_raise_exception(self):
+ """Ensure StorageRepositoryNotFound is raise when wrong filter."""
+ self.flags(sr_matching_filter='yadayadayada')
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
+ helper = vm_utils.VMHelper
+ helper.XenAPI = session.get_imported_xenapi()
+ self.assertRaises(exception.StorageRepositoryNotFound,
+ helper.safe_find_sr, session)
+
+ def test_safe_find_sr_local_storage(self):
+ """Ensure the default local-storage is found."""
+ self.flags(sr_matching_filter='other-config:i18n-key=local-storage')
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
+ helper = vm_utils.VMHelper
+ helper.XenAPI = session.get_imported_xenapi()
+ host_ref = xenapi_fake.get_all('host')[0]
+ local_sr = xenapi_fake.\
+ create_sr(name_label='Fake Storage',
+ type='lvm',
+ other_config={'i18n-original-value-name_label':
+ 'Local storage',
+ 'i18n-key': 'local-storage'},
+ host_ref=host_ref)
+ expected = helper.safe_find_sr(session)
+ self.assertEqual(local_sr, expected)
+
+ def test_safe_find_sr_by_other_criteria(self):
+ """Ensure the SR is found when using a different filter."""
+ self.flags(sr_matching_filter='other-config:my_fake_sr=true')
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
+ helper = vm_utils.VMHelper
+ helper.XenAPI = session.get_imported_xenapi()
+ host_ref = xenapi_fake.get_all('host')[0]
+ local_sr = xenapi_fake.\
+ create_sr(name_label='Fake Storage',
+ type='lvm',
+ other_config={'my_fake_sr': 'true'},
+ host_ref=host_ref)
+ expected = helper.safe_find_sr(session)
+ self.assertEqual(local_sr, expected)
+
+ def test_safe_find_sr_default(self):
+ """Ensure the default SR is found regardless of other-config."""
+ self.flags(sr_matching_filter='default-sr:true')
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
+ helper = vm_utils.VMHelper
+ pool_ref = xenapi_fake.create_pool('')
+ helper.XenAPI = session.get_imported_xenapi()
+ expected = helper.safe_find_sr(session)
+ self.assertEqual(session.call_xenapi('pool.get_default_SR', pool_ref),
+ expected)
diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py
index 9b0c2adce..b9f81bfb3 100644
--- a/nova/virt/xenapi/fake.py
+++ b/nova/virt/xenapi/fake.py
@@ -63,7 +63,7 @@ from nova import log as logging
from nova import utils
-_CLASSES = ['host', 'network', 'session', 'SR', 'VBD',
+_CLASSES = ['host', 'network', 'session', 'SR', 'VBD', 'pool',
'PBD', 'VDI', 'VIF', 'PIF', 'VM', 'VLAN', 'task']
_db_content = {}
@@ -93,6 +93,11 @@ def reset_table(table):
_db_content[table] = {}
+def create_pool(name_label):
+ return _create_object('pool',
+ {'name_label': name_label})
+
+
def create_host(name_label):
return _create_object('host',
{'name_label': name_label})
@@ -201,50 +206,40 @@ def create_local_pifs():
Do this one per host."""
for host_ref in _db_content['host'].keys():
_create_local_pif(host_ref)
- _create_local_sr_iso(host_ref)
def create_local_srs():
"""Create an SR that looks like the one created on the local disk by
- default by the XenServer installer. Do this one per host."""
+ default by the XenServer installer. Do this one per host. Also, fake
+ the installation of an ISO SR."""
for host_ref in _db_content['host'].keys():
- _create_local_sr(host_ref)
-
-
-def _create_local_sr(host_ref):
+ create_sr(name_label='Local storage',
+ type='lvm',
+ other_config={'i18n-original-value-name_label':
+ 'Local storage',
+ 'i18n-key': 'local-storage'},
+ host_ref=host_ref)
+ create_sr(name_label='Local storage ISO',
+ type='iso',
+ other_config={'i18n-original-value-name_label':
+ 'Local storage ISO',
+ 'i18n-key': 'local-storage-iso'},
+ host_ref=host_ref)
+
+
+def create_sr(**kwargs):
sr_ref = _create_object(
'SR',
- {'name_label': 'Local storage',
- 'type': 'lvm',
+ {'name_label': kwargs.get('name_label'),
+ 'type': kwargs.get('type'),
'content_type': 'user',
'shared': False,
'physical_size': str(1 << 30),
'physical_utilisation': str(0),
'virtual_allocation': str(0),
- 'other_config': {
- 'i18n-original-value-name_label': 'Local storage',
- 'i18n-key': 'local-storage'},
+ 'other_config': kwargs.get('other_config'),
'VDIs': []})
- pbd_ref = create_pbd('', host_ref, sr_ref, True)
- _db_content['SR'][sr_ref]['PBDs'] = [pbd_ref]
- return sr_ref
-
-
-def _create_local_sr_iso(host_ref):
- sr_ref = _create_object(
- 'SR',
- {'name_label': 'Local storage ISO',
- 'type': 'lvm',
- 'content_type': 'iso',
- 'shared': False,
- 'physical_size': str(1 << 30),
- 'physical_utilisation': str(0),
- 'virtual_allocation': str(0),
- 'other_config': {
- 'i18n-original-value-name_label': 'Local storage ISO',
- 'i18n-key': 'local-storage-iso'},
- 'VDIs': []})
- pbd_ref = create_pbd('', host_ref, sr_ref, True)
+ pbd_ref = create_pbd('', kwargs.get('host_ref'), sr_ref, True)
_db_content['SR'][sr_ref]['PBDs'] = [pbd_ref]
return sr_ref
@@ -356,6 +351,9 @@ class SessionBase(object):
def __init__(self, uri):
self._session = None
+ def pool_get_default_SR(self, _1, pool_ref):
+ return 'FAKE DEFAULT SR'
+
def VBD_plug(self, _1, ref):
rec = get_record('VBD', ref)
if rec['currently_attached']:
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 4c7ece9c5..f51bf7508 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -58,6 +58,15 @@ xenapi_vm_utils_opts = [
cfg.IntOpt('max_kernel_ramdisk_size',
default=16 * 1024 * 1024,
help='maximum size in bytes of kernel or ramdisk images'),
+ cfg.StrOpt('sr_matching_filter',
+ default='other-config:i18n-key=local-storage',
+ help='Filter for finding the SR to be used to install guest '
+ 'instances on. The default value is the Local Storage in '
+ 'default XenServer/XCP installations. To select an SR '
+ 'with a different matching criteria, you could set it to '
+ 'other-config:my_favorite_sr=true. On the other hand, to '
+ 'fall back on the Default SR, as displayed by XenCenter, '
+ 'set this flag to: default-sr:true'),
]
FLAGS = flags.FLAGS
@@ -965,15 +974,34 @@ class VMHelper(HelperBase):
def find_sr(cls, session):
"""Return the storage repository to hold VM images"""
host = session.get_xenapi_host()
+ try:
+ tokens = FLAGS.sr_matching_filter.split(':')
+ filter_criteria = tokens[0]
+ filter_pattern = tokens[1]
+ except IndexError:
+ # oops, flag is invalid
+ LOG.warning(_("Flag sr_matching_filter '%s' does not respect "
+ "formatting convention"), FLAGS.sr_matching_filter)
+ return None
- for sr_ref, sr_rec in cls.get_all_refs_and_recs(session, 'SR'):
- if not ('i18n-key' in sr_rec['other_config'] and
- sr_rec['other_config']['i18n-key'] == 'local-storage'):
- continue
- for pbd_ref in sr_rec['PBDs']:
- pbd_rec = cls.get_rec(session, 'PBD', pbd_ref)
- if pbd_rec and pbd_rec['host'] == host:
- return sr_ref
+ if filter_criteria == 'other-config':
+ key, value = filter_pattern.split('=', 1)
+ for sr_ref, sr_rec in cls.get_all_refs_and_recs(session, 'SR'):
+ if not (key in sr_rec['other_config'] and
+ sr_rec['other_config'][key] == value):
+ continue
+ for pbd_ref in sr_rec['PBDs']:
+ pbd_rec = cls.get_rec(session, 'PBD', pbd_ref)
+ if pbd_rec and pbd_rec['host'] == host:
+ return sr_ref
+ elif filter_criteria == 'default-sr' and filter_pattern == 'true':
+ pool_ref = session.call_xenapi('pool.get_all')[0]
+ return session.call_xenapi('pool.get_default_SR', pool_ref)
+ # No SR found!
+ LOG.warning(_("XenAPI is unable to find a Storage Repository to "
+ "install guest instances on. Please check your "
+ "configuration and/or configure the flag "
+ "'sr_matching_filter'"))
return None
@classmethod