Accept lists in pci-alias charm config

Allow json lists to be passed in via the pci-alias charm config
option so that multiple aliases can be set.

Increase amulet timeout due to gate failures

Change-Id: I3b5ea70224536f8d40f9c04482fa676c2b230bdd
Partial-Bug: #1735205
This commit is contained in:
Liam Young 2017-12-11 13:56:03 +00:00
parent d5c5cccb0a
commit 630a07013f
8 changed files with 135 additions and 5 deletions

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
from base64 import b64decode
@ -272,7 +273,12 @@ class NovaConfigContext(context.WorkerConfigContext):
ctxt = super(NovaConfigContext, self).__call__()
ctxt['scheduler_default_filters'] = config('scheduler-default-filters')
if config('pci-alias'):
ctxt['pci_alias'] = config('pci-alias')
aliases = json.loads(config('pci-alias'))
if isinstance(aliases, list):
ctxt['pci_aliases'] = [json.dumps(x, sort_keys=True)
for x in aliases]
else:
ctxt['pci_alias'] = json.dumps(aliases, sort_keys=True)
ctxt['disk_allocation_ratio'] = config('disk-allocation-ratio')
ctxt['cpu_allocation_ratio'] = config('cpu-allocation-ratio')

View File

@ -38,6 +38,9 @@ scheduler_default_filters = {{ scheduler_default_filters }}
{% if pci_alias %}
pci_alias = {{ pci_alias }}
{% endif %}
{% for alias in pci_aliases -%}
pci_alias = {{ alias }}
{% endfor -%}
cpu_allocation_ratio = {{ cpu_allocation_ratio }}
ram_allocation_ratio = {{ ram_allocation_ratio }}
disk_allocation_ratio = {{ disk_allocation_ratio }}
@ -174,4 +177,4 @@ lock_path=/var/lock/nova
[spice]
{% include "parts/spice" %}
{% include "parts/section-serial-console" %}
{% include "parts/section-serial-console" %}

View File

@ -38,6 +38,9 @@ scheduler_default_filters = {{ scheduler_default_filters }}
{% if pci_alias %}
pci_alias = {{ pci_alias }}
{% endif %}
{% for alias in pci_aliases -%}
pci_alias = {{ alias }}
{% endfor -%}
cpu_allocation_ratio = {{ cpu_allocation_ratio }}
ram_allocation_ratio = {{ ram_allocation_ratio }}
disk_allocation_ratio = {{ disk_allocation_ratio }}
@ -172,4 +175,4 @@ lock_path=/var/lock/nova
[spice]
{% include "parts/spice" %}
{% include "parts/section-serial-console" %}
{% include "parts/section-serial-console" %}

View File

@ -35,6 +35,9 @@ scheduler_default_filters = {{ scheduler_default_filters }}
{% if pci_alias %}
pci_alias = {{ pci_alias }}
{% endif %}
{% for alias in pci_aliases -%}
pci_alias = {{ alias }}
{% endfor -%}
cpu_allocation_ratio = {{ cpu_allocation_ratio }}
ram_allocation_ratio = {{ ram_allocation_ratio }}
disk_allocation_ratio = {{ disk_allocation_ratio }}

View File

@ -196,5 +196,8 @@ api_paste_config=/etc/nova/api-paste.ini
{% if pci_alias %}
alias = {{ pci_alias }}
{% endif %}
{% for alias in pci_aliases -%}
alias = {{ alias }}
{% endfor -%}
{% include "section-oslo-middleware" %}

View File

@ -219,5 +219,8 @@ api_paste_config=/etc/nova/api-paste.ini
{% if pci_alias %}
alias = {{ pci_alias }}
{% endif %}
{% for alias in pci_aliases -%}
alias = {{ alias }}
{% endfor -%}
{% include "section-oslo-middleware" %}

View File

@ -14,6 +14,7 @@
import amulet
import json
import tempfile
from charmhelpers.contrib.openstack.amulet.deployment import (
OpenStackAmuletDeployment
@ -25,6 +26,7 @@ from charmhelpers.contrib.openstack.amulet.utils import (
# ERROR
)
from charmhelpers.contrib.openstack.utils import CompareOpenStackReleases
from oslo_config import cfg
import keystoneclient
from keystoneclient.v3 import client as keystone_client_v3
@ -64,8 +66,8 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
self._deploy()
u.log.info('Waiting on extended status checks...')
exclude_services = []
self._auto_wait_for_status(exclude_services=exclude_services)
self.exclude_services = []
self._auto_wait_for_status(exclude_services=self.exclude_services)
self.d.sentry.wait()
self._initialize_tests()
@ -685,11 +687,33 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
section = "DEFAULT"
key_name = "pci_alias"
CONF = cfg.CONF
opt_group = cfg.OptGroup(name=section)
pci_opts = [cfg.MultiStrOpt(key_name)]
CONF.register_group(opt_group)
CONF.register_opts(pci_opts, opt_group)
_pci_alias2 = {
"name": " Cirrus Logic ",
"capability_type": "pci",
"product_id": "0ff2",
"vendor_id": "10de",
"device_type": "type-PCI"}
_pci_alias_list = "[{}, {}]".format(
json.dumps(_pci_alias1, sort_keys=True),
json.dumps(_pci_alias2, sort_keys=True))
unit = self.nova_cc_sentry
conf = '/etc/nova/nova.conf'
u.log.debug('Setting pci-alias to {}'.format(json.dumps(
_pci_alias1,
sort_keys=True)))
self.d.configure(
'nova-cloud-controller',
{'pci-alias': json.dumps(_pci_alias1, sort_keys=True)})
u.log.debug('Waiting for config change to take effect')
self.d.sentry.wait()
ret = u.validate_config_data(
unit,
@ -703,6 +727,29 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
section,
ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('Setting pci-alias to {}'.format(_pci_alias_list))
self.d.configure(
'nova-cloud-controller',
{'pci-alias': _pci_alias_list})
u.log.debug('Waiting for config change to take effect')
self.d.sentry.wait()
f = tempfile.NamedTemporaryFile(delete=False)
f.write(unit.file_contents(conf))
f.close()
CONF(default_config_files=[f.name])
if CompareOpenStackReleases(os_release) >= 'ocata':
alias_entries = CONF.pci.alias
else:
alias_entries = CONF.DEFAULT.pci_alias
assert alias_entries[0] == (
'{"capability_type": "pci", "device_type": "type-PF", '
'"name": "IntelNIC", "product_id": "1111", "vendor_id": "8086"}')
assert alias_entries[1] == (
'{"capability_type": "pci", "device_type": "type-PCI", '
'"name": " Cirrus Logic ", "product_id": "0ff2", '
'"vendor_id": "10de"}')
self.d.configure('nova-cloud-controller', {'pci-alias': ''})
self.d.sentry.wait()

View File

@ -14,6 +14,7 @@
from __future__ import print_function
import json
import mock
import nova_cc_context as context
@ -319,6 +320,67 @@ class NovaComputeContextTests(CharmTestCase):
self.assertEqual(ctxt['disk_allocation_ratio'],
self.config('disk-allocation-ratio'))
_pci_alias1 = {
"name": "IntelNIC",
"capability_type": "pci",
"product_id": "1111",
"vendor_id": "8086",
"device_type": "type-PF"}
_pci_alias2 = {
"name": " Cirrus Logic ",
"capability_type": "pci",
"product_id": "0ff2",
"vendor_id": "10de",
"device_type": "type-PCI"}
_pci_alias_list = [_pci_alias1, _pci_alias2]
@mock.patch('charmhelpers.contrib.openstack.ip.unit_get')
@mock.patch('charmhelpers.contrib.hahelpers.cluster.relation_ids')
@mock.patch('charmhelpers.core.hookenv.local_unit')
@mock.patch('charmhelpers.contrib.openstack.context.config')
def test_nova_config_context_multi_pci_alias(self, mock_config,
local_unit,
mock_relation_ids,
mock_unit_get):
local_unit.return_value = 'nova-cloud-controller/0'
mock_config.side_effect = self.test_config.get
mock_unit_get.return_value = '127.0.0.1'
self.test_config.set(
'pci-alias', json.dumps(self._pci_alias1))
ctxt = context.NovaConfigContext()()
self.assertEqual(
ctxt['pci_alias'],
('{"capability_type": "pci", "device_type": "type-PF", '
'"name": "IntelNIC", "product_id": "1111", '
'"vendor_id": "8086"}'))
@mock.patch('charmhelpers.contrib.openstack.ip.unit_get')
@mock.patch('charmhelpers.contrib.hahelpers.cluster.relation_ids')
@mock.patch('charmhelpers.core.hookenv.local_unit')
@mock.patch('charmhelpers.contrib.openstack.context.config')
def test_nova_config_context_multi_pci_aliases(self, mock_config,
local_unit,
mock_relation_ids,
mock_unit_get):
local_unit.return_value = 'nova-cloud-controller/0'
mock_config.side_effect = self.test_config.get
mock_unit_get.return_value = '127.0.0.1'
self.test_config.set(
'pci-alias', json.dumps(self._pci_alias_list))
ctxt = context.NovaConfigContext()()
self.assertEqual(
ctxt['pci_aliases'][0],
('{"capability_type": "pci", "device_type": "type-PF", '
'"name": "IntelNIC", "product_id": "1111", '
'"vendor_id": "8086"}'))
self.assertEqual(
ctxt['pci_aliases'][1],
('{"capability_type": "pci", "device_type": "type-PCI", '
'"name": " Cirrus Logic ", "product_id": "0ff2", '
'"vendor_id": "10de"}'))
@mock.patch.object(context, 'format_ipv6_addr')
@mock.patch.object(context, 'resolve_address')
@mock.patch.object(context, 'config')