Propagate vendor_data from nova-cloud-controller
When using DVR and L3HA neutron deployment options, Nova API Metadata requests are served from compute nodes, instead of from neutron-gateway nodes. This change allows nova-compute to receive vendor_data configuration values from nova-cloud-controller charm relation and write to nova-compute's nova.conf appropriately. This will be effictive for Queens and later OpenStack releases. Synced charm-helpers in order to import new context for writing the vendor_data.json file. Change-Id: I0c79e1bfac9fbe7009a7e862ad010cfa2de8cfda Closes-Bug: #1777714
This commit is contained in:
parent
247a645b6b
commit
af051c4fba
@ -294,8 +294,10 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
('bionic', None): self.bionic_queens,
|
||||
('bionic', 'cloud:bionic-rocky'): self.bionic_rocky,
|
||||
('bionic', 'cloud:bionic-stein'): self.bionic_stein,
|
||||
('bionic', 'cloud:bionic-train'): self.bionic_train,
|
||||
('cosmic', None): self.cosmic_rocky,
|
||||
('disco', None): self.disco_stein,
|
||||
('eoan', None): self.eoan_train,
|
||||
}
|
||||
return releases[(self.series, self.openstack)]
|
||||
|
||||
@ -313,6 +315,7 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
('bionic', 'queens'),
|
||||
('cosmic', 'rocky'),
|
||||
('disco', 'stein'),
|
||||
('eoan', 'train'),
|
||||
])
|
||||
if self.openstack:
|
||||
os_origin = self.openstack.split(':')[1]
|
||||
|
@ -54,11 +54,15 @@ NOVA_CLIENT_VERSION = "2"
|
||||
|
||||
OPENSTACK_RELEASES_PAIRS = [
|
||||
'trusty_icehouse', 'trusty_kilo', 'trusty_liberty',
|
||||
'trusty_mitaka', 'xenial_mitaka', 'xenial_newton',
|
||||
'yakkety_newton', 'xenial_ocata', 'zesty_ocata',
|
||||
'xenial_pike', 'artful_pike', 'xenial_queens',
|
||||
'bionic_queens', 'bionic_rocky', 'cosmic_rocky',
|
||||
'bionic_stein', 'disco_stein']
|
||||
'trusty_mitaka', 'xenial_mitaka',
|
||||
'xenial_newton', 'yakkety_newton',
|
||||
'xenial_ocata', 'zesty_ocata',
|
||||
'xenial_pike', 'artful_pike',
|
||||
'xenial_queens', 'bionic_queens',
|
||||
'bionic_rocky', 'cosmic_rocky',
|
||||
'bionic_stein', 'disco_stein',
|
||||
'bionic_train', 'eoan_train',
|
||||
]
|
||||
|
||||
|
||||
class OpenStackAmuletUtils(AmuletUtils):
|
||||
|
@ -521,6 +521,86 @@ class IdentityCredentialsContext(IdentityServiceContext):
|
||||
return {}
|
||||
|
||||
|
||||
class NovaVendorMetadataContext(OSContextGenerator):
|
||||
"""Context used for configuring nova vendor metadata on nova.conf file."""
|
||||
|
||||
def __init__(self, os_release_pkg, interfaces=None):
|
||||
"""Initialize the NovaVendorMetadataContext object.
|
||||
|
||||
:param os_release_pkg: the package name to extract the OpenStack
|
||||
release codename from.
|
||||
:type os_release_pkg: str
|
||||
:param interfaces: list of string values to be used as the Context's
|
||||
relation interfaces.
|
||||
:type interfaces: List[str]
|
||||
"""
|
||||
self.os_release_pkg = os_release_pkg
|
||||
if interfaces is not None:
|
||||
self.interfaces = interfaces
|
||||
|
||||
def __call__(self):
|
||||
cmp_os_release = CompareOpenStackReleases(
|
||||
os_release(self.os_release_pkg))
|
||||
ctxt = {'vendor_data': False}
|
||||
|
||||
vdata_providers = []
|
||||
vdata = config('vendor-data')
|
||||
vdata_url = config('vendor-data-url')
|
||||
|
||||
if vdata:
|
||||
try:
|
||||
# validate the JSON. If invalid, we do not set anything here
|
||||
json.loads(vdata)
|
||||
except (TypeError, ValueError) as e:
|
||||
log('Error decoding vendor-data. {}'.format(e), level=ERROR)
|
||||
else:
|
||||
ctxt['vendor_data'] = True
|
||||
# Mitaka does not support DynamicJSON
|
||||
# so vendordata_providers is not needed
|
||||
if cmp_os_release > 'mitaka':
|
||||
vdata_providers.append('StaticJSON')
|
||||
|
||||
if vdata_url:
|
||||
if cmp_os_release > 'mitaka':
|
||||
ctxt['vendor_data_url'] = vdata_url
|
||||
vdata_providers.append('DynamicJSON')
|
||||
else:
|
||||
log('Dynamic vendor data unsupported'
|
||||
' for {}.'.format(cmp_os_release), level=ERROR)
|
||||
if vdata_providers:
|
||||
ctxt['vendordata_providers'] = ','.join(vdata_providers)
|
||||
|
||||
return ctxt
|
||||
|
||||
|
||||
class NovaVendorMetadataJSONContext(OSContextGenerator):
|
||||
"""Context used for writing nova vendor metadata json file."""
|
||||
|
||||
def __init__(self, os_release_pkg):
|
||||
"""Initialize the NovaVendorMetadataJSONContext object.
|
||||
|
||||
:param os_release_pkg: the package name to extract the OpenStack
|
||||
release codename from.
|
||||
:type os_release_pkg: str
|
||||
"""
|
||||
self.os_release_pkg = os_release_pkg
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {'vendor_data_json': '{}'}
|
||||
|
||||
vdata = config('vendor-data')
|
||||
if vdata:
|
||||
try:
|
||||
# validate the JSON. If invalid, we return empty.
|
||||
json.loads(vdata)
|
||||
except (TypeError, ValueError) as e:
|
||||
log('Error decoding vendor-data. {}'.format(e), level=ERROR)
|
||||
else:
|
||||
ctxt['vendor_data_json'] = vdata
|
||||
|
||||
return ctxt
|
||||
|
||||
|
||||
class AMQPContext(OSContextGenerator):
|
||||
|
||||
def __init__(self, ssl_dir=None, rel_name='amqp', relation_prefix=None,
|
||||
@ -702,6 +782,25 @@ class CephContext(OSContextGenerator):
|
||||
ensure_packages(['ceph-common'])
|
||||
return ctxt
|
||||
|
||||
def context_complete(self, ctxt):
|
||||
"""Overridden here to ensure the context is actually complete.
|
||||
|
||||
We set `key` and `auth` to None here, by default, to ensure
|
||||
that the context will always evaluate to incomplete until the
|
||||
Ceph relation has actually sent these details; otherwise,
|
||||
there is a potential race condition between the relation
|
||||
appearing and the first unit actually setting this data on the
|
||||
relation.
|
||||
|
||||
:param ctxt: The current context members
|
||||
:type ctxt: Dict[str, ANY]
|
||||
:returns: True if the context is complete
|
||||
:rtype: bool
|
||||
"""
|
||||
if 'auth' not in ctxt or 'key' not in ctxt:
|
||||
return False
|
||||
return super(CephContext, self).context_complete(ctxt)
|
||||
|
||||
|
||||
class HAProxyContext(OSContextGenerator):
|
||||
"""Provides half a context for the haproxy template, which describes
|
||||
|
@ -217,6 +217,11 @@ def neutron_plugins():
|
||||
plugins['nsx']['config'] = '/etc/neutron/nsx.ini'
|
||||
plugins['vsp']['driver'] = (
|
||||
'nuage_neutron.plugins.nuage.plugin.NuagePlugin')
|
||||
if CompareOpenStackReleases(release) >= 'newton':
|
||||
plugins['vsp']['config'] = '/etc/neutron/plugins/ml2/ml2_conf.ini'
|
||||
plugins['vsp']['driver'] = 'neutron.plugins.ml2.plugin.Ml2Plugin'
|
||||
plugins['vsp']['server_packages'] = ['neutron-server',
|
||||
'neutron-plugin-ml2']
|
||||
return plugins
|
||||
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
{{ vendor_data_json }}
|
@ -120,6 +120,7 @@ OPENSTACK_RELEASES = (
|
||||
'queens',
|
||||
'rocky',
|
||||
'stein',
|
||||
'train',
|
||||
)
|
||||
|
||||
UBUNTU_OPENSTACK_RELEASE = OrderedDict([
|
||||
@ -139,6 +140,7 @@ UBUNTU_OPENSTACK_RELEASE = OrderedDict([
|
||||
('bionic', 'queens'),
|
||||
('cosmic', 'rocky'),
|
||||
('disco', 'stein'),
|
||||
('eoan', 'train'),
|
||||
])
|
||||
|
||||
|
||||
@ -159,6 +161,7 @@ OPENSTACK_CODENAMES = OrderedDict([
|
||||
('2018.1', 'queens'),
|
||||
('2018.2', 'rocky'),
|
||||
('2019.1', 'stein'),
|
||||
('2019.2', 'train'),
|
||||
])
|
||||
|
||||
# The ugly duckling - must list releases oldest to newest
|
||||
@ -195,6 +198,8 @@ SWIFT_CODENAMES = OrderedDict([
|
||||
['2.18.0', '2.19.0']),
|
||||
('stein',
|
||||
['2.20.0', '2.21.0']),
|
||||
('train',
|
||||
['2.22.0']),
|
||||
])
|
||||
|
||||
# >= Liberty version->codename mapping
|
||||
@ -208,6 +213,7 @@ PACKAGE_CODENAMES = {
|
||||
('17', 'queens'),
|
||||
('18', 'rocky'),
|
||||
('19', 'stein'),
|
||||
('20', 'train'),
|
||||
]),
|
||||
'neutron-common': OrderedDict([
|
||||
('7', 'liberty'),
|
||||
@ -218,6 +224,7 @@ PACKAGE_CODENAMES = {
|
||||
('12', 'queens'),
|
||||
('13', 'rocky'),
|
||||
('14', 'stein'),
|
||||
('15', 'train'),
|
||||
]),
|
||||
'cinder-common': OrderedDict([
|
||||
('7', 'liberty'),
|
||||
@ -228,6 +235,7 @@ PACKAGE_CODENAMES = {
|
||||
('12', 'queens'),
|
||||
('13', 'rocky'),
|
||||
('14', 'stein'),
|
||||
('15', 'train'),
|
||||
]),
|
||||
'keystone': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
@ -238,6 +246,7 @@ PACKAGE_CODENAMES = {
|
||||
('13', 'queens'),
|
||||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
]),
|
||||
'horizon-common': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
@ -248,6 +257,7 @@ PACKAGE_CODENAMES = {
|
||||
('13', 'queens'),
|
||||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
]),
|
||||
'ceilometer-common': OrderedDict([
|
||||
('5', 'liberty'),
|
||||
@ -258,6 +268,7 @@ PACKAGE_CODENAMES = {
|
||||
('10', 'queens'),
|
||||
('11', 'rocky'),
|
||||
('12', 'stein'),
|
||||
('13', 'train'),
|
||||
]),
|
||||
'heat-common': OrderedDict([
|
||||
('5', 'liberty'),
|
||||
@ -268,6 +279,7 @@ PACKAGE_CODENAMES = {
|
||||
('10', 'queens'),
|
||||
('11', 'rocky'),
|
||||
('12', 'stein'),
|
||||
('13', 'train'),
|
||||
]),
|
||||
'glance-common': OrderedDict([
|
||||
('11', 'liberty'),
|
||||
@ -278,6 +290,7 @@ PACKAGE_CODENAMES = {
|
||||
('16', 'queens'),
|
||||
('17', 'rocky'),
|
||||
('18', 'stein'),
|
||||
('19', 'train'),
|
||||
]),
|
||||
'openstack-dashboard': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
@ -288,6 +301,7 @@ PACKAGE_CODENAMES = {
|
||||
('13', 'queens'),
|
||||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
]),
|
||||
}
|
||||
|
||||
|
@ -1488,7 +1488,7 @@ def is_broker_action_done(action, rid=None, unit=None):
|
||||
@param action: name of action to be performed
|
||||
@returns True if action complete otherwise False
|
||||
"""
|
||||
rdata = relation_get(rid, unit) or {}
|
||||
rdata = relation_get(rid=rid, unit=unit) or {}
|
||||
broker_rsp = rdata.get(get_broker_rsp_key())
|
||||
if not broker_rsp:
|
||||
return False
|
||||
@ -1510,7 +1510,7 @@ def mark_broker_action_done(action, rid=None, unit=None):
|
||||
@param action: name of action to be performed
|
||||
@returns None
|
||||
"""
|
||||
rdata = relation_get(rid, unit) or {}
|
||||
rdata = relation_get(rid=rid, unit=unit) or {}
|
||||
broker_rsp = rdata.get(get_broker_rsp_key())
|
||||
if not broker_rsp:
|
||||
return
|
||||
|
@ -173,6 +173,14 @@ CLOUD_ARCHIVE_POCKETS = {
|
||||
'stein/proposed': 'bionic-proposed/stein',
|
||||
'bionic-stein/proposed': 'bionic-proposed/stein',
|
||||
'bionic-proposed/stein': 'bionic-proposed/stein',
|
||||
# Train
|
||||
'train': 'bionic-updates/train',
|
||||
'bionic-train': 'bionic-updates/train',
|
||||
'bionic-train/updates': 'bionic-updates/train',
|
||||
'bionic-updates/train': 'bionic-updates/train',
|
||||
'train/proposed': 'bionic-proposed/train',
|
||||
'bionic-train/proposed': 'bionic-proposed/train',
|
||||
'bionic-proposed/train': 'bionic-proposed/train',
|
||||
}
|
||||
|
||||
|
||||
@ -522,14 +530,16 @@ def add_source(source, key=None, fail_invalid=False):
|
||||
for r, fn in six.iteritems(_mapping):
|
||||
m = re.match(r, source)
|
||||
if m:
|
||||
# call the assoicated function with the captured groups
|
||||
# raises SourceConfigError on error.
|
||||
fn(*m.groups())
|
||||
if key:
|
||||
# Import key before adding the source which depends on it,
|
||||
# as refreshing packages could fail otherwise.
|
||||
try:
|
||||
import_key(key)
|
||||
except GPGKeyError as e:
|
||||
raise SourceConfigError(str(e))
|
||||
# call the associated function with the captured groups
|
||||
# raises SourceConfigError on error.
|
||||
fn(*m.groups())
|
||||
break
|
||||
else:
|
||||
# nothing matched. log an error and maybe sys.exit
|
||||
|
@ -12,6 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import uuid
|
||||
import os
|
||||
import platform
|
||||
@ -398,8 +399,38 @@ class SerialConsoleContext(context.OSContextGenerator):
|
||||
}
|
||||
|
||||
|
||||
class CloudComputeContext(context.OSContextGenerator):
|
||||
class CloudComputeVendorJSONContext(context.OSContextGenerator):
|
||||
"""Receives vendor_data.json from nova cloud controller node."""
|
||||
|
||||
interfaces = ['cloud-compute']
|
||||
|
||||
@property
|
||||
def vendor_json(self):
|
||||
"""
|
||||
Returns the json string to be written in vendor_data.json file,
|
||||
received from nova-cloud-controller charm through relation attribute
|
||||
vendor_json.
|
||||
"""
|
||||
for rid in relation_ids('cloud-compute'):
|
||||
for unit in related_units(rid):
|
||||
vendor_data_string = relation_get(
|
||||
'vendor_json', rid=rid, unit=unit)
|
||||
if vendor_data_string:
|
||||
return vendor_data_string
|
||||
|
||||
def __call__(self):
|
||||
"""
|
||||
Returns a dict in which the value of vendor_data_json is the json
|
||||
string to be written in vendor_data.json file.
|
||||
"""
|
||||
ctxt = {'vendor_data_json': '{}'}
|
||||
vendor_data = self.vendor_json
|
||||
if vendor_data:
|
||||
ctxt['vendor_data_json'] = vendor_data
|
||||
return ctxt
|
||||
|
||||
|
||||
class CloudComputeContext(context.OSContextGenerator):
|
||||
'''
|
||||
Generates main context for writing nova.conf and quantum.conf templates
|
||||
from a cloud-compute relation changed hook. Mainly used for determinig
|
||||
@ -437,6 +468,38 @@ class CloudComputeContext(context.OSContextGenerator):
|
||||
region = relation_get('region', rid=rid, unit=unit)
|
||||
return region
|
||||
|
||||
@property
|
||||
def vendor_data(self):
|
||||
"""
|
||||
Returns vendor metadata related parameters to be written in
|
||||
nova.conf, received from nova-cloud-controller charm through relation
|
||||
attribute vendor_data.
|
||||
"""
|
||||
vendor_data_json = {}
|
||||
for rid in relation_ids('cloud-compute'):
|
||||
for unit in related_units(rid):
|
||||
vendor_data_string = relation_get(
|
||||
'vendor_data', rid=rid, unit=unit)
|
||||
if vendor_data_string:
|
||||
vendor_data_json = json.loads(vendor_data_string)
|
||||
return vendor_data_json
|
||||
|
||||
def vendor_data_context(self):
|
||||
vdata_ctxt = {}
|
||||
vendor_data_json = self.vendor_data
|
||||
if vendor_data_json:
|
||||
# NOTE(ganso): avoid returning any extra keys to context
|
||||
if vendor_data_json.get('vendor_data'):
|
||||
vdata_ctxt['vendor_data'] = vendor_data_json['vendor_data']
|
||||
if vendor_data_json.get('vendor_data_url'):
|
||||
vdata_ctxt['vendor_data_url'] = vendor_data_json[
|
||||
'vendor_data_url']
|
||||
if vendor_data_json.get('vendordata_providers'):
|
||||
vdata_ctxt['vendordata_providers'] = vendor_data_json[
|
||||
'vendordata_providers']
|
||||
|
||||
return vdata_ctxt
|
||||
|
||||
def flat_dhcp_context(self):
|
||||
ec2_host = None
|
||||
for rid in relation_ids('cloud-compute'):
|
||||
@ -617,6 +680,8 @@ class CloudComputeContext(context.OSContextGenerator):
|
||||
if region:
|
||||
ctxt['region'] = region
|
||||
|
||||
ctxt.update(self.vendor_data_context())
|
||||
|
||||
if self.context_complete(ctxt):
|
||||
return ctxt
|
||||
|
||||
|
@ -86,6 +86,7 @@ from charmhelpers.core.hugepage import hugepage_support
|
||||
from nova_compute_context import (
|
||||
nova_metadata_requirement,
|
||||
CloudComputeContext,
|
||||
CloudComputeVendorJSONContext,
|
||||
LxdContext,
|
||||
MetadataServiceContext,
|
||||
NovaComputeLibvirtContext,
|
||||
@ -167,6 +168,7 @@ LIBVIRTD_CONF = '/etc/libvirt/libvirtd.conf'
|
||||
LIBVIRT_BIN = '/etc/default/libvirt-bin'
|
||||
LIBVIRT_BIN_OVERRIDES = '/etc/init/libvirt-bin.override'
|
||||
NOVA_CONF = '%s/nova.conf' % NOVA_CONF_DIR
|
||||
VENDORDATA_FILE = '%s/vendor_data.json' % NOVA_CONF_DIR
|
||||
QEMU_KVM = '/etc/default/qemu-kvm'
|
||||
NOVA_API_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'.format(NOVA_API_AA_PROFILE))
|
||||
NOVA_COMPUTE_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
||||
@ -211,6 +213,10 @@ BASE_RESOURCE_MAP = {
|
||||
context.IdentityCredentialsContext(
|
||||
rel_name='cloud-credentials')],
|
||||
},
|
||||
VENDORDATA_FILE: {
|
||||
'services': [],
|
||||
'contexts': [CloudComputeVendorJSONContext()],
|
||||
},
|
||||
NOVA_API_AA_PROFILE_PATH: {
|
||||
'services': ['nova-api'],
|
||||
'contexts': [NovaAPIAppArmorContext()],
|
||||
|
294
templates/queens/nova.conf
Normal file
294
templates/queens/nova.conf
Normal file
@ -0,0 +1,294 @@
|
||||
# queens
|
||||
###############################################################################
|
||||
# [ WARNING ]
|
||||
# Configuration file maintained by Juju. Local changes may be overwritten.
|
||||
{% if restart_trigger -%}
|
||||
# restart trigger: {{ restart_trigger }}
|
||||
{% endif -%}
|
||||
###############################################################################
|
||||
[DEFAULT]
|
||||
verbose={{ verbose }}
|
||||
debug={{ debug }}
|
||||
dhcpbridge_flagfile=/etc/nova/nova.conf
|
||||
dhcpbridge=/usr/bin/nova-dhcpbridge
|
||||
logdir=/var/log/nova
|
||||
state_path=/var/lib/nova
|
||||
force_dhcp_release=True
|
||||
use_syslog = {{ use_syslog }}
|
||||
ec2_private_dns_show_ip=True
|
||||
api_paste_config=/etc/nova/api-paste.ini
|
||||
enabled_apis=osapi_compute,metadata
|
||||
auth_strategy=keystone
|
||||
my_ip = {{ host_ip }}
|
||||
force_raw_images = {{ force_raw_images }}
|
||||
|
||||
{% if debug -%}
|
||||
default_log_levels = "amqp=WARN, amqplib=WARN, boto=WARN, qpid=WARN, sqlalchemy=WARN, suds=INFO, oslo.messaging=INFO, oslo_messaging=DEBUG, iso8601=WARN, requests.packages.urllib3.connectionpool=WARN, urllib3.connectionpool=WARN, websocket=WARN, requests.packages.urllib3.util.retry=WARN, urllib3.util.retry=WARN, keystonemiddleware=WARN, routes.middleware=WARN, stevedore=WARN, taskflow=WARN, keystoneauth=WARN, oslo.cache=INFO, dogpile.core.dogpile=INFO"
|
||||
{% endif -%}
|
||||
|
||||
{% if transport_url %}
|
||||
transport_url = {{ transport_url }}
|
||||
{% endif %}
|
||||
|
||||
{% if arch == 'aarch64' -%}
|
||||
libvirt_use_virtio_for_bridges=False
|
||||
libvirt_disk_prefix=vd
|
||||
{% endif -%}
|
||||
|
||||
{% if console_vnc_type -%}
|
||||
vnc_enabled = True
|
||||
novnc_enabled = True
|
||||
vnc_keymap = {{ console_keymap }}
|
||||
vncserver_listen = 0.0.0.0
|
||||
vncserver_proxyclient_address = {{ console_listen_addr }}
|
||||
{% if console_access_protocol == 'novnc' or console_access_protocol == 'vnc' -%}
|
||||
novncproxy_base_url = {{ novnc_proxy_address }}
|
||||
{% endif -%}
|
||||
{% if console_access_protocol == 'xvpvnc' or console_access_protocol == 'vnc' -%}
|
||||
xvpvncproxy_port = {{ xvpvnc_proxy_port }}
|
||||
xvpvncproxy_host = {{ xvpvnc_proxy_host }}
|
||||
xvpvncproxy_base_url = {{ xvpvnc_proxy_address }}
|
||||
{% endif -%}
|
||||
{% else -%}
|
||||
vnc_enabled = False
|
||||
novnc_enabled = False
|
||||
{% endif -%}
|
||||
|
||||
{% if neutron_plugin and neutron_plugin in ('ovs', 'midonet') -%}
|
||||
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtGenericVIFDriver
|
||||
{% if neutron_security_groups -%}
|
||||
security_group_api = neutron
|
||||
firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
|
||||
network_api_class=nova.network.neutronv2.api.API
|
||||
libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
|
||||
neutron_ovs_bridge=alubr0
|
||||
security_group_api=neutron
|
||||
firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||
{% endif -%}
|
||||
|
||||
{% if neutron_plugin and (neutron_plugin == 'nvp' or neutron_plugin == 'nsx') -%}
|
||||
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtOpenVswitchVirtualPortDriver
|
||||
security_group_api = neutron
|
||||
firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||
{% endif -%}
|
||||
|
||||
{% if neutron_plugin and neutron_plugin == 'Calico' -%}
|
||||
security_group_api = neutron
|
||||
firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||
{% endif -%}
|
||||
|
||||
{% if neutron_plugin and neutron_plugin == 'plumgrid' -%}
|
||||
security_group_api=neutron
|
||||
firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||
{% endif -%}
|
||||
|
||||
{% if network_manager != 'neutron' and network_manager_config -%}
|
||||
{% for key, value in network_manager_config.items() -%}
|
||||
{{ key }} = {{ value }}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if network_manager == 'neutron' -%}
|
||||
network_api_class = nova.network.neutronv2.api.API
|
||||
use_neutron = True
|
||||
{% else -%}
|
||||
network_manager = nova.network.manager.FlatDHCPManager
|
||||
{% endif -%}
|
||||
|
||||
{% if network_device_mtu -%}
|
||||
network_device_mtu = {{ network_device_mtu }}
|
||||
{% endif -%}
|
||||
|
||||
{% if volume_service -%}
|
||||
volume_api_class = nova.volume.cinder.API
|
||||
{% endif -%}
|
||||
|
||||
{% if user_config_flags -%}
|
||||
{% for key, value in user_config_flags.items() -%}
|
||||
{{ key }} = {{ value }}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if instances_path -%}
|
||||
instances_path = {{ instances_path }}
|
||||
{% endif -%}
|
||||
|
||||
{% if sections and 'DEFAULT' in sections -%}
|
||||
{% for key, value in sections['DEFAULT'] -%}
|
||||
{{ key }} = {{ value }}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if vcpu_pin_set -%}
|
||||
vcpu_pin_set = {{ vcpu_pin_set }}
|
||||
{% endif -%}
|
||||
reserved_host_memory_mb = {{ reserved_host_memory }}
|
||||
|
||||
{% if reserved_huge_pages -%}
|
||||
{% for value in reserved_huge_pages -%}
|
||||
reserved_huge_pages = {{ value }}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
||||
{% if default_availability_zone -%}
|
||||
default_availability_zone = {{ default_availability_zone }}
|
||||
{% endif -%}
|
||||
|
||||
{% if resume_guests_state_on_host_boot -%}
|
||||
resume_guests_state_on_host_boot = {{ resume_guests_state_on_host_boot }}
|
||||
{% endif -%}
|
||||
|
||||
metadata_workers = {{ workers }}
|
||||
|
||||
[pci]
|
||||
{% if pci_passthrough_whitelist -%}
|
||||
passthrough_whitelist = {{ pci_passthrough_whitelist }}
|
||||
{% endif -%}
|
||||
{% if pci_alias %}
|
||||
alias = {{ pci_alias }}
|
||||
{% endif %}
|
||||
|
||||
{% if network_manager == 'neutron' and network_manager_config -%}
|
||||
[neutron]
|
||||
url = {{ network_manager_config.neutron_url }}
|
||||
{% if network_manager_config.keystone_host or auth_host -%}
|
||||
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
|
||||
ovs_bridge = alubr0
|
||||
{% endif -%}
|
||||
{% if auth_host -%}
|
||||
auth_url = {{ auth_protocol }}://{{ auth_host }}:{{ auth_port }}
|
||||
auth_type = password
|
||||
{% if admin_domain_name -%}
|
||||
project_domain_name = {{ admin_domain_name }}
|
||||
user_domain_name = {{ admin_domain_name }}
|
||||
{% else -%}
|
||||
project_domain_name = default
|
||||
user_domain_name = default
|
||||
{% endif -%}
|
||||
project_name = {{ admin_tenant_name }}
|
||||
username = {{ admin_user }}
|
||||
password = {{ admin_password }}
|
||||
signing_dir = {{ signing_dir }}
|
||||
{% endif -%}
|
||||
{% if metadata_shared_secret -%}
|
||||
metadata_proxy_shared_secret = {{ metadata_shared_secret }}
|
||||
service_metadata_proxy=True
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-keystone-authtoken-mitaka" %}
|
||||
|
||||
{% if glance_api_servers -%}
|
||||
[glance]
|
||||
api_servers = {{ glance_api_servers }}
|
||||
{% endif -%}
|
||||
|
||||
{% if vendor_data or vendor_data_url -%}
|
||||
[api]
|
||||
vendordata_providers = {{ vendordata_providers }}
|
||||
{% if vendor_data -%}
|
||||
vendordata_jsonfile_path = /etc/nova/vendor_data.json
|
||||
{% endif -%}
|
||||
{% if vendor_data_url -%}
|
||||
vendordata_dynamic_targets = {{ vendor_data_url }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if console_access_protocol == 'spice' -%}
|
||||
[spice]
|
||||
agent_enabled = True
|
||||
enabled = True
|
||||
html5proxy_base_url = {{ spice_proxy_address }}
|
||||
keymap = {{ console_keymap }}
|
||||
server_listen = 0.0.0.0
|
||||
server_proxyclient_address = {{ console_listen_addr }}
|
||||
{% endif -%}
|
||||
|
||||
[libvirt]
|
||||
{% if cpu_mode -%}
|
||||
cpu_mode = {{ cpu_mode }}
|
||||
{% endif -%}
|
||||
{% if cpu_model -%}
|
||||
cpu_model = {{ cpu_model }}
|
||||
{% endif -%}
|
||||
{% if cpu_model_extra_flags %}
|
||||
cpu_model_extra_flags = {{ cpu_model_extra_flags }}
|
||||
{% endif %}
|
||||
{% if libvirt_images_type -%}
|
||||
images_type = {{ libvirt_images_type }}
|
||||
{% endif -%}
|
||||
{% if libvirt_images_type and rbd_pool -%}
|
||||
images_rbd_pool = {{ rbd_pool }}
|
||||
images_rbd_ceph_conf = {{ libvirt_rbd_images_ceph_conf }}
|
||||
inject_password = false
|
||||
inject_key = false
|
||||
inject_partition = -2
|
||||
{% endif -%}
|
||||
rbd_user = {{ rbd_user }}
|
||||
rbd_secret_uuid = {{ rbd_secret_uuid }}
|
||||
{% if live_migration_uri -%}
|
||||
live_migration_uri = {{ live_migration_uri }}
|
||||
{% endif -%}
|
||||
{% if live_migration_permit_post_copy -%}
|
||||
live_migration_permit_post_copy = {{ live_migration_permit_post_copy }}
|
||||
{% endif -%}
|
||||
{% if live_migration_permit_auto_converge -%}
|
||||
live_migration_permit_auto_converge = {{ live_migration_permit_auto_converge }}
|
||||
{% endif -%}
|
||||
{% if disk_cachemodes -%}
|
||||
disk_cachemodes = {{ disk_cachemodes }}
|
||||
{% endif %}
|
||||
# Disable tunnelled migration so that selective
|
||||
# live block migration can be supported.
|
||||
live_migration_tunnelled = False
|
||||
{% if use_multipath -%}
|
||||
volume_use_multipath = {{ use_multipath }}
|
||||
{% endif %}
|
||||
{% if default_ephemeral_format -%}
|
||||
default_ephemeral_format = {{ default_ephemeral_format }}
|
||||
{% endif %}
|
||||
hw_disk_discard = unmap
|
||||
|
||||
{% if virt_type == 'lxd' -%}
|
||||
[lxd]
|
||||
{% if enable_live_migration -%}
|
||||
allow_live_migration = True
|
||||
{% endif -%}
|
||||
{% if storage_pool -%}
|
||||
pool = {{ storage_pool }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% include "parts/section-database" %}
|
||||
|
||||
{% include "section-oslo-messaging-rabbit" %}
|
||||
|
||||
[notifications]
|
||||
# Starting in the Pike release, the notification_format includes both the
|
||||
# versioned and unversioned message notifications. Ceilometer does not yet
|
||||
# consume the versioned message notifications, so intentionally make the
|
||||
# notification format unversioned until this is implemented.
|
||||
notification_format = unversioned
|
||||
|
||||
{% include "section-oslo-notifications" %}
|
||||
|
||||
{% include "parts/section-cinder" %}
|
||||
|
||||
[oslo_concurrency]
|
||||
lock_path=/var/lock/nova
|
||||
|
||||
[workarounds]
|
||||
disable_libvirt_livesnapshot = False
|
||||
|
||||
{% include "parts/section-ephemeral" %}
|
||||
|
||||
{% include "parts/section-serial-console" %}
|
||||
|
||||
{% include "parts/section-placement" %}
|
@ -190,6 +190,17 @@ service_metadata_proxy=True
|
||||
api_servers = {{ glance_api_servers }}
|
||||
{% endif -%}
|
||||
|
||||
{% if vendor_data or vendor_data_url -%}
|
||||
[api]
|
||||
vendordata_providers = {{ vendordata_providers }}
|
||||
{% if vendor_data -%}
|
||||
vendordata_jsonfile_path = /etc/nova/vendor_data.json
|
||||
{% endif -%}
|
||||
{% if vendor_data_url -%}
|
||||
vendordata_dynamic_targets = {{ vendor_data_url }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% if console_access_protocol == 'spice' -%}
|
||||
[spice]
|
||||
agent_enabled = True
|
||||
|
@ -147,6 +147,46 @@ class NovaComputeContextTests(CharmTestCase):
|
||||
}
|
||||
self.assertEqual(ex_ctxt, cloud_compute())
|
||||
|
||||
@patch.object(context, '_network_manager')
|
||||
def test_cloud_compute_vendordata_context(self, netman):
|
||||
self.relation_ids.return_value = 'cloud-compute:0'
|
||||
self.related_units.return_value = 'nova-cloud-controller/0'
|
||||
data = ('{"vendor_data": true, "vendor_data_url": "fake_url",'
|
||||
' "foo": "bar",'
|
||||
' "vendordata_providers": "StaticJSON,DynamicJSON"}')
|
||||
self.test_relation.set({
|
||||
'vendor_data': data
|
||||
})
|
||||
cloud_compute = context.CloudComputeContext()
|
||||
ex_ctxt = {
|
||||
'vendor_data': True,
|
||||
'vendor_data_url': 'fake_url',
|
||||
'vendordata_providers': 'StaticJSON,DynamicJSON',
|
||||
}
|
||||
self.assertEqual(ex_ctxt, cloud_compute())
|
||||
|
||||
def test_cloud_compute_vendorJSON_context(self):
|
||||
self.relation_ids.return_value = 'cloud-compute:0'
|
||||
self.related_units.return_value = 'nova-cloud-controller/0'
|
||||
data = '{"good": json"}'
|
||||
self.test_relation.set({
|
||||
'vendor_json': data
|
||||
})
|
||||
cloud_compute = context.CloudComputeVendorJSONContext()
|
||||
ex_ctxt = {'vendor_data_json': data}
|
||||
self.assertEqual(ex_ctxt, cloud_compute())
|
||||
|
||||
def test_cloud_compute_vendorJSON_context_empty(self):
|
||||
self.relation_ids.return_value = 'cloud-compute:0'
|
||||
self.related_units.return_value = 'nova-cloud-controller/0'
|
||||
data = ''
|
||||
self.test_relation.set({
|
||||
'vendor_json': data
|
||||
})
|
||||
cloud_compute = context.CloudComputeVendorJSONContext()
|
||||
ex_ctxt = {'vendor_data_json': '{}'}
|
||||
self.assertEqual(ex_ctxt, cloud_compute())
|
||||
|
||||
@patch.object(context, '_neutron_plugin')
|
||||
@patch.object(context, '_neutron_url')
|
||||
@patch.object(context, '_network_manager')
|
||||
|
@ -276,6 +276,10 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
'contexts': [],
|
||||
'services': ['nova-compute']
|
||||
},
|
||||
'/etc/nova/vendor_data.json': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
},
|
||||
'/etc/ceph/secret.xml': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
@ -332,6 +336,10 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
'contexts': [],
|
||||
'services': ['nova-compute']
|
||||
},
|
||||
'/etc/nova/vendor_data.json': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
},
|
||||
'/etc/ceph/secret.xml': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
@ -386,6 +394,10 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
'contexts': [],
|
||||
'services': ['nova-compute', 'nova-api', 'nova-network']
|
||||
},
|
||||
'/etc/nova/vendor_data.json': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
},
|
||||
'/etc/ceph/secret.xml': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
@ -448,6 +460,10 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
'contexts': [],
|
||||
'services': ['nova-compute']
|
||||
},
|
||||
'/etc/nova/vendor_data.json': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
},
|
||||
'/etc/ceph/secret.xml': {
|
||||
'contexts': [],
|
||||
'services': []
|
||||
|
Loading…
Reference in New Issue
Block a user