diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-02-01 21:25:18 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-02-01 21:25:18 +0000 |
| commit | 98a012fbb14d1b6463b9c8d13fcb1de742bae1d0 (patch) | |
| tree | 3fd372e150b15001d39145a29d7aae7dc3bb49e3 /nova | |
| parent | 260c96431f2dc5a5842aef5c105091bd8d64c552 (diff) | |
| parent | c56d677a7313b8b29406eaebdd27e59b2c1ee927 (diff) | |
| download | nova-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.py | 69 | ||||
| -rw-r--r-- | nova/virt/xenapi/fake.py | 62 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 44 |
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 |
