96c1788e94
Fix use of OVS DPDK context by direct use of methods on context for OVS table values. For modern OVS versions that require the PCI address of the DPDK device for type=dpdk ports, use a hash of the PCI address for the port name rather than the index of the PCI device in the current list of devices to use; this is idempotent in the event that the configuration changes and new devices appear in the list of devices to use for DPDK. Only set OVS table values if the value has changed; OVS will try to re-allocate hugepage memory, irrespective as to whether the table value actually changed. Switch to using /run/libvirt-vhost-user for libvirt created DPDK sockets, allowing libvirt to directly create the socket as part of instance creation; Use systemd-tmpfiles to ensure that the vhost-user subdirectory is re-created on boot with the correct permissions. Scan data-port and dpdk-bond-mappings for PCI devices to use for DPDK to avoid having to replicate all PCI devices in data-port configuration when DPDK bonds are in use. Change-Id: I2964046bc8681fa870d61c6cd23b6ad6fee47bf4
169 lines
4.9 KiB
Python
Executable File
169 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2016 Canonical Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import sys
|
|
|
|
from copy import deepcopy
|
|
|
|
from charmhelpers.contrib.openstack.utils import (
|
|
pausable_restart_on_change as restart_on_change,
|
|
)
|
|
|
|
from charmhelpers.core.hookenv import (
|
|
Hooks,
|
|
UnregisteredHookError,
|
|
config,
|
|
log,
|
|
relation_set,
|
|
relation_ids,
|
|
)
|
|
|
|
from neutron_ovs_utils import (
|
|
DHCP_PACKAGES,
|
|
DVR_PACKAGES,
|
|
METADATA_PACKAGES,
|
|
OVS_DEFAULT,
|
|
configure_ovs,
|
|
configure_sriov,
|
|
get_shared_secret,
|
|
register_configs,
|
|
restart_map,
|
|
use_dvr,
|
|
enable_nova_metadata,
|
|
enable_local_dhcp,
|
|
install_packages,
|
|
purge_packages,
|
|
assess_status,
|
|
install_tmpfilesd,
|
|
)
|
|
|
|
hooks = Hooks()
|
|
CONFIGS = register_configs()
|
|
|
|
|
|
@hooks.hook()
|
|
def install():
|
|
install_packages()
|
|
|
|
|
|
# NOTE(wolsen): Do NOT add restart_on_change decorator without consideration
|
|
# for the implications of modifications to the /etc/default/openvswitch-switch.
|
|
@hooks.hook('upgrade-charm')
|
|
def upgrade_charm():
|
|
if OVS_DEFAULT in restart_map():
|
|
# In the 16.10 release of the charms, the code changed from managing
|
|
# the /etc/default/openvswitch-switch file only when dpdk was enabled
|
|
# to always managing this file. Thus, an upgrade of the charm from a
|
|
# release prior to 16.10 or higher will always cause the contents of
|
|
# the file to change and will trigger a restart of the
|
|
# openvswitch-switch service, which in turn causes a temporary
|
|
# network outage. To prevent this outage, determine if the
|
|
# /etc/default/openvswitch-switch file needs to be migrated and if
|
|
# so, migrate the file but do NOT restart the openvswitch-switch
|
|
# service.
|
|
# See bug LP #1712444
|
|
with open(OVS_DEFAULT, 'r') as f:
|
|
# The 'Service restart triggered ...' line was added to the
|
|
# OVS_DEFAULT template in the 16.10 version of the charm to allow
|
|
# restarts so we use this as the key to see if the file needs
|
|
# migrating.
|
|
if 'Service restart triggered' not in f.read():
|
|
CONFIGS.write(OVS_DEFAULT)
|
|
|
|
|
|
@hooks.hook('neutron-plugin-relation-changed')
|
|
@hooks.hook('config-changed')
|
|
@restart_on_change(restart_map())
|
|
def config_changed():
|
|
install_packages()
|
|
install_tmpfilesd()
|
|
|
|
configure_ovs()
|
|
CONFIGS.write_all()
|
|
# NOTE(fnordahl): configure_sriov must be run after CONFIGS.write_all()
|
|
# to allow us to enable boot time execution of init script
|
|
configure_sriov()
|
|
for rid in relation_ids('neutron-plugin'):
|
|
neutron_plugin_joined(relation_id=rid)
|
|
|
|
|
|
@hooks.hook('neutron-plugin-api-relation-changed')
|
|
@restart_on_change(restart_map())
|
|
def neutron_plugin_api_changed():
|
|
if use_dvr():
|
|
install_packages()
|
|
else:
|
|
purge_packages(DVR_PACKAGES)
|
|
configure_ovs()
|
|
CONFIGS.write_all()
|
|
# If dvr setting has changed, need to pass that on
|
|
for rid in relation_ids('neutron-plugin'):
|
|
neutron_plugin_joined(relation_id=rid)
|
|
|
|
|
|
@hooks.hook('neutron-plugin-relation-joined')
|
|
def neutron_plugin_joined(relation_id=None):
|
|
if enable_local_dhcp():
|
|
install_packages()
|
|
else:
|
|
pkgs = deepcopy(DHCP_PACKAGES)
|
|
# NOTE: only purge metadata packages if dvr is not
|
|
# in use as this will remove the l3 agent
|
|
# see https://pad.lv/1515008
|
|
if not use_dvr():
|
|
pkgs.extend(METADATA_PACKAGES)
|
|
purge_packages(pkgs)
|
|
secret = get_shared_secret() if enable_nova_metadata() else None
|
|
rel_data = {
|
|
'metadata-shared-secret': secret,
|
|
}
|
|
relation_set(relation_id=relation_id, **rel_data)
|
|
|
|
|
|
@hooks.hook('amqp-relation-joined')
|
|
def amqp_joined(relation_id=None):
|
|
relation_set(relation_id=relation_id,
|
|
username=config('rabbit-user'),
|
|
vhost=config('rabbit-vhost'))
|
|
|
|
|
|
@hooks.hook('amqp-relation-changed')
|
|
@hooks.hook('amqp-relation-departed')
|
|
@restart_on_change(restart_map())
|
|
def amqp_changed():
|
|
if 'amqp' not in CONFIGS.complete_contexts():
|
|
log('amqp relation incomplete. Peer not ready?')
|
|
return
|
|
CONFIGS.write_all()
|
|
|
|
|
|
@hooks.hook('neutron-control-relation-changed')
|
|
@restart_on_change(restart_map(), stopstart=True)
|
|
def restart_check():
|
|
CONFIGS.write_all()
|
|
|
|
|
|
def main():
|
|
try:
|
|
hooks.execute(sys.argv)
|
|
except UnregisteredHookError as e:
|
|
log('Unknown hook {} - skipping.'.format(e))
|
|
assess_status(CONFIGS)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|