From 69fc33656ccc8de239436837422c55ff3fe21118 Mon Sep 17 00:00:00 2001 From: James Page Date: Tue, 8 Nov 2016 12:10:08 +0000 Subject: [PATCH] Updates for alignment with RDO Mitaka Misc updates as a result of testing with latest OpenStack Mitaka RDO packages from IBM: - neutron.conf: disable neutron_rootwrap_daemon - non-functional. - nova.conf: set lock_path to /var/lib/nova/tmp inline with rpm packaging. - run proxy install process during config-changed, ensuring that any new compute hosts get installed and configured. - enable and start services on install, as rpm packages install disabled. - refactor use of proxy in hooks module to ensure its not created on module load, but as an when required. - change behaviour of remote-key to write key to secured local file, avoiding the need to run this charm from a local copy with the key embedded. README updated for any behavioural changes in configuration. Change-Id: I53d7331a2ddcf73bc41bc8d73be5bf165bf55a92 --- README.md | 17 +++++-- hooks/fabfile.py | 24 ++++++---- hooks/nova_compute_hooks.py | 83 ++++++++++++----------------------- hooks/nova_compute_proxy.py | 26 +++++++++-- templates/mitaka/neutron.conf | 4 ++ templates/mitaka/nova.conf | 2 +- tests/basic_deployment.py | 7 ++- 7 files changed, 91 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index cea6ffb..788598a 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,27 @@ advance: Once you have this setup you must configure the charm as follow: -* Place the key to the nova-compute node in the files directory of the - charm. * Apply the following charm config: * remote-user: username used to access and configure the power node. * remote-repos: Yum repository url(s) or file url(s) * remote-hosts: IP address of power node + * remote-key: Private key string to use for access * Example: ``` remote-user: youruser remote-repos: file:///tmp/openstack-iso/openstack,file:///tmp/other-iso/repofs - remote-key: id_dsa + remote-key: | + -----BEGIN DSA PRIVATE KEY----- + MIIBugIBAAKBgQD3IG188Q07kQdbRJhlZqknNpoGDB1r9+XGq9+7nmWGKusbOn6L + 5VdyoHnx0BvgHHJmOAvJ+39sex9KvToEM0Jfav30EfffVzIrjaZZBMZkO/kWkEdd + TJrpMoW5nqiyNQRHCJWKkTiT7hNwS7AzUFkH1cR16bkabUfNhx3nWVsfGQIVAM7l + FlrJwujvWxOOHIRrihVmnUylAoGBAKGjWAPuj23p2II8NSTfaK/VJ9CyEF1RQ4Pv + +wtCRRE/DoN/3jpFnQz8Yjt6dYEewdcWFDG9aJ/PLvm/qX335TSz86pfYBd2Q3dp + 9/RuaXTnLK6L/gdgkGcDXG8fy2kk0zteNjMjpzbaYpjZmIQ4lu3StUkwTm8EppZz + b0KXUNhwAn8bSTxNIZnlfoYzzwT2XPjHMlqeFbYxJMo9Dk5+AY6+tmr4/uR5ySDD + A+Txxh7RPhIBQwrIdGlOYOR3Mh03NcYuU+yrUsv4xLP8SeWcfiuAXFctXu0kzvPC + uIQ1EfKCrOtbWPcbza2ipo1J8MN/vzLCu69Jdq8af0OqJFoDcY0vAhUAxh2BNdRr + HyF1bGCP1t8JdMJVtb0= + -----END DSA PRIVATE KEY----- remote-hosts: 10.10.10.10 10.10.10.11 ``` diff --git a/hooks/fabfile.py b/hooks/fabfile.py index 19e56f3..b323da2 100644 --- a/hooks/fabfile.py +++ b/hooks/fabfile.py @@ -40,22 +40,30 @@ def copy_file_as_root(src, dest): def yum_install(packages): - sudo('yum install --skip-broken -y %s' % ' '.join(packages)) + sudo('yum install --skip-broken -y {}'.format(' '.join(packages))) def restart_service(service): - sudo('service %s restart' % service) + sudo('systemctl restart {}'.format(service)) + + +def start_service(service): + sudo('systemctl start {}'.format(service)) + + +def enable_service(service): + sudo('systemctl enable {}'.format(service)) def add_bridge(bridge_name): - sudo('ovs-vsctl -- --may-exist add-br %s' % bridge_name) + sudo('ovs-vsctl -- --may-exist add-br {}'.format(bridge_name)) def add_bridge_port(bridge_name, port): - sudo('ovs-vsctl -- --may-exist add-port %s %s' % (bridge_name, - port)) - sudo('ip link set %s up' % port) - sudo('ip link set %s promisc on' % port) + sudo('ovs-vsctl -- --may-exist add-port {} {}'.format(bridge_name, + port)) + sudo('ip link set {} up'.format(port)) + sudo('ip link set {} promisc on'.format(port)) def enable_shell(user): @@ -76,4 +84,4 @@ def fix_selinux_permission(path): def fix_local_ip(f): - sudo('sed -i "s!LOCAL_IP!%s!g" %s' % (env.host, f)) + sudo('sed -i "s!LOCAL_IP!{}!g" {}'.format(env.host, f)) diff --git a/hooks/nova_compute_hooks.py b/hooks/nova_compute_hooks.py index 2f45330..4cf0429 100755 --- a/hooks/nova_compute_hooks.py +++ b/hooks/nova_compute_hooks.py @@ -31,7 +31,6 @@ from charmhelpers.fetch import ( from nova_compute_utils import ( restart_map, register_configs, - NOVA_CONF, assess_status, ) from nova_compute_proxy import ( @@ -41,28 +40,34 @@ from nova_compute_proxy import ( hooks = Hooks() CONFIGS = register_configs() -proxy = REMOTEProxy(user=config('remote-user'), - ssh_key=config('remote-key'), - hosts=config('remote-hosts'), - repository=config('remote-repos'), - password=config('remote-password')) + + +def get_proxy(): + return REMOTEProxy(user=config('remote-user'), + ssh_key=config('remote-key'), + hosts=config('remote-hosts'), + repository=config('remote-repos'), + password=config('remote-password')) @hooks.hook('install.real') def install(): apt_install(['fabric'], fatal=True) - proxy.install() @hooks.hook('config-changed') -@restart_on_change(restart_map(), proxy.restart_service) def config_changed(): + proxy = get_proxy() + proxy.install() proxy.configure() if config('instances-path') is not None: proxy.fix_path_ownership(config('instances-path'), user='nova') - [compute_joined(rid) for rid in relation_ids('cloud-compute')] - CONFIGS.write_all() + @restart_on_change(restart_map(), proxy.restart_service) + def write_config(): + CONFIGS.write_all() + write_config() + proxy.commit() @@ -73,63 +78,31 @@ def amqp_joined(relation_id=None): vhost=config('rabbit-vhost')) -@hooks.hook('amqp-relation-changed') -@hooks.hook('amqp-relation-departed') -@restart_on_change(restart_map(), proxy.restart_service) -def amqp_changed(): - if 'amqp' not in CONFIGS.complete_contexts(): - log('amqp relation incomplete. Peer not ready?') - return - CONFIGS.write_all() - proxy.commit() - - -@hooks.hook('image-service-relation-changed') -@restart_on_change(restart_map(), proxy.restart_service) -def image_service_changed(): - if 'image-service' not in CONFIGS.complete_contexts(): - log('image-service relation incomplete. Peer not ready?') - return - CONFIGS.write(NOVA_CONF) - proxy.commit() - - -@hooks.hook('cloud-compute-relation-joined') -def compute_joined(rid=None): - pass - - -@hooks.hook('cloud-compute-relation-changed', - 'neutron-plugin-api-relation-changed') -@restart_on_change(restart_map(), proxy.restart_service) -def compute_changed(): - CONFIGS.write_all() - proxy.commit() - - @hooks.hook('amqp-relation-broken', 'image-service-relation-broken', - 'neutron-plugin-api-relation-broken') -@restart_on_change(restart_map(), proxy.restart_service) + 'neutron-plugin-api-relation-broken', + 'nova-ceilometer-relation-changed', + 'cloud-compute-relation-changed', + 'neutron-plugin-api-relation-changed', + 'image-service-relation-changed', + 'amqp-relation-changed', + 'amqp-relation-departed') def relation_broken(): - CONFIGS.write_all() + proxy = get_proxy() + + @restart_on_change(restart_map(), proxy.restart_service) + def write_config(): + CONFIGS.write_all() + write_config() proxy.commit() @hooks.hook('upgrade-charm') def upgrade_charm(): - proxy.install() for r_id in relation_ids('amqp'): amqp_joined(relation_id=r_id) -@hooks.hook('nova-ceilometer-relation-changed') -@restart_on_change(restart_map(), proxy.restart_service) -def nova_ceilometer_relation_changed(): - CONFIGS.write_all() - proxy.commit() - - @hooks.hook('update-status') def update_status(): log('Updating status.') diff --git a/hooks/nova_compute_proxy.py b/hooks/nova_compute_proxy.py index 2c60edd..2c97c99 100644 --- a/hooks/nova_compute_proxy.py +++ b/hooks/nova_compute_proxy.py @@ -17,12 +17,14 @@ import tempfile from collections import OrderedDict from charmhelpers.core.hookenv import ( - charm_dir, log, config, + service_name ) from charmhelpers.core.host import ( - file_hash + file_hash, + mkdir, + write_file, ) from charmhelpers.fetch import ( apt_install, @@ -33,6 +35,8 @@ from fabfile import ( copy_file_as_root, yum_install, restart_service, + start_service, + enable_service, enable_shell, disable_shell, fix_path_ownership, @@ -61,6 +65,10 @@ PACKAGES = ['openstack-nova-compute', 'openstack-neutron-openvswitch', 'python-neutronclient'] +SERVICES = ['openstack-nova-compute', + 'neutron-openvswitch-agent', + 'openvswitch'] + CONFIG_FILES = [ '/etc/neutron/neutron.conf', '/etc/neutron/plugins/ml2/openvswitch_agent.ini', @@ -84,7 +92,13 @@ class REMOTEProxy(): self._init_fabric() def _write_key(self): - return os.path.join(charm_dir(), 'files', self.ssh_key) + key_path = os.path.join('/var/lib/charm', + service_name(), + 'ssh_key') + mkdir(os.path.dirname(key_path)) + write_file(key_path, self.ssh_key, + perms=0o400) + return key_path def _init_fabric(self): env.warn_only = True @@ -98,6 +112,7 @@ class REMOTEProxy(): def install(self): self._setup_yum() self._install_packages() + self._enable_services() def _setup_yum(self): log('Setup yum') @@ -116,6 +131,11 @@ class REMOTEProxy(): def _install_packages(self): execute(yum_install, PACKAGES) + def _enable_services(self): + for service in SERVICES: + execute(enable_service, service) + execute(start_service, service) + def configure(self): self.add_bridges() diff --git a/templates/mitaka/neutron.conf b/templates/mitaka/neutron.conf index de844c9..7c6b4ca 100644 --- a/templates/mitaka/neutron.conf +++ b/templates/mitaka/neutron.conf @@ -27,6 +27,10 @@ notification_topics = notifications [AGENT] root_helper = sudo neutron-rootwrap /etc/neutron/rootwrap.conf +# NOTE(jamespage): unset daemon helper as this is not functional +# neutron will fallback to single commands using +# root_helper above. +root_helper_daemon = [keystone_authtoken] signing_dir = /var/lib/neutron/keystone-signing diff --git a/templates/mitaka/nova.conf b/templates/mitaka/nova.conf index 34e6bb3..17d3d9d 100644 --- a/templates/mitaka/nova.conf +++ b/templates/mitaka/nova.conf @@ -149,7 +149,7 @@ allow_live_migration = True {% include "parts/section-cinder" %} [oslo_concurrency] -lock_path=/var/lock/nova +lock_path = /var/lib/nova/tmp [workarounds] disable_libvirt_livesnapshot = False diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 1119154..fbfd46f 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -123,6 +123,9 @@ class NovaBasicDeployment(OpenStackAmuletDeployment): if not os.path.exists(key_file_path): raise + with open('files/id_rsa_tmp', 'r') as key_file: + self.ssh_key = key_file.read() + # Copy new local test pub key into remote-compute and # add it to the authorized_hosts. u.log.debug('Copying pub key into simulated remote-compute host') @@ -206,7 +209,7 @@ class NovaBasicDeployment(OpenStackAmuletDeployment): nova_config = { 'remote-user': 'ubuntu', 'remote-repos': "file:///mnt/osmitakacomp,file:///mnt/osprereqs", - 'remote-key': 'id_rsa_tmp', + 'remote-key': self.ssh_key, 'remote-hosts': str(self.compute_addr), } nova_cc_config = {} @@ -393,7 +396,7 @@ class NovaBasicDeployment(OpenStackAmuletDeployment): 'my_ip': 'LOCAL_IP', }, 'oslo_concurrency': { - 'lock_path': '/var/lock/nova' + 'lock_path': '/var/lib/nova/tmp' }, 'oslo_messaging_rabbit': { 'rabbit_userid': 'nova',