Remove independent OpenStack upgrade

Ceilometer has had an openstack-origin and supported upgrading
the Ceilometer version independently of the principle that it is
associated with. This can cause issues with clashes in package
dependencies between the two. This change makes the
ability for the agent to be upgraded independently of the principle
and instead has the upgrade triggered by the principle. This brings
this charm inline with the other OpenStack subordinate charms.

Change-Id: I641ac2168ac705191d916eaa0624214791e1745d
Closes-Bug: #1802400
This commit is contained in:
Liam Young 2018-11-11 15:52:22 +00:00
parent 0d3a3f2060
commit 1a40c275d5
10 changed files with 40 additions and 270 deletions

View File

@ -2,5 +2,3 @@ pause:
description: Pause the ceilometer-agent unit. This action will stop ceilometer-agent services.
resume:
descrpition: Resume the ceilometer-agent unit. This action will start ceilometer-agent services.
openstack-upgrade:
description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.

View File

@ -1 +0,0 @@
openstack_upgrade.py

View File

@ -1,52 +0,0 @@
#!/usr/bin/python
#
# 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
sys.path.append('hooks/')
from charmhelpers.contrib.openstack.utils import (
do_action_openstack_upgrade,
)
from ceilometer_hooks import (
config_changed,
CONFIGS,
)
from ceilometer_utils import (
do_openstack_upgrade,
)
def openstack_upgrade():
"""Perform action-managed OpenStack upgrade.
Upgrades packages to the configured openstack-origin version and sets
the corresponding action status as a result.
If the charm was installed from source we cannot upgrade it.
For backwards compatibility a config flag (action-managed-upgrade) must
be set for this code to run, otherwise a full service level upgrade will
fire on config-changed."""
if (do_action_openstack_upgrade('ceilometer-common',
do_openstack_upgrade,
CONFIGS)):
config_changed()
if __name__ == '__main__':
openstack_upgrade()

View File

@ -1,33 +1,4 @@
options:
openstack-origin:
type: string
default: distro
description: |
Repository from which to install. May be one of the following:
distro (default), ppa:somecustom/ppa, a deb url sources entry,
or a supported Ubuntu Cloud Archive e.g.
.
cloud:<series>-<openstack-release>
cloud:<series>-<openstack-release>/updates
cloud:<series>-<openstack-release>/staging
cloud:<series>-<openstack-release>/proposed
.
See https://wiki.ubuntu.com/OpenStack/CloudArchive for info on which
cloud archives are available and supported.
.
NOTE: updating this setting to a source that is known to provide
a later version of OpenStack will trigger a software upgrade unless
action-managed-upgrade is set to True.
action-managed-upgrade:
type: boolean
default: False
description: |
If True enables openstack upgrades for this charm via juju actions.
You will still need to set openstack-origin to the new repository but
instead of an upgrade running automatically across all units, it will
wait for you to execute the openstack-upgrade action for this charm on
each unit. If False it will revert to existing behavior of upgrading
all units on config change.
nagios_context:
type: string
default: "juju"

View File

@ -21,7 +21,6 @@ from charmhelpers.fetch import (
apt_update
)
from charmhelpers.core.hookenv import (
config,
Hooks, UnregisteredHookError,
log,
is_relation_made,
@ -30,11 +29,7 @@ from charmhelpers.core.hookenv import (
relation_ids,
)
from charmhelpers.contrib.openstack.utils import (
configure_installation_source,
openstack_upgrade_available,
pausable_restart_on_change as restart_on_change,
os_release,
CompareOpenStackReleases,
is_unit_paused_set,
series_upgrade_prepare,
series_upgrade_complete,
@ -44,7 +39,6 @@ from ceilometer_utils import (
services,
register_configs,
NOVA_SETTINGS,
do_openstack_upgrade,
assess_status,
get_packages,
pause_unit_helper,
@ -58,8 +52,6 @@ CONFIGS = register_configs()
@hooks.hook('install.real')
def install():
origin = config('openstack-origin')
configure_installation_source(origin)
status_set('maintenance', 'Installing apt packages')
apt_update(fatal=True)
# Install -common package so we get accurate version determination
@ -95,6 +87,7 @@ def upgrade_charm():
nova_ceilometer_joined(rid)
@hooks.hook('nova-ceilometer-relation-changed')
@hooks.hook('config-changed')
@restart_on_change(restart_map(), stopstart=True)
def config_changed():
@ -104,19 +97,7 @@ def config_changed():
log("Unit is pause or upgrading. Skipping config_changed", "WARN")
return
if not config('action-managed-upgrade'):
if openstack_upgrade_available('ceilometer-common'):
status_set('maintenance', 'Running openstack upgrade')
do_openstack_upgrade(CONFIGS)
else:
# It's possible that a partial upgrade has occurred if nova-compute
# was upgraded first. If > mitaka call apt_install to allow
# packages which are enabled for specific OpenStack version to be
# installed if they haven't been already.
os_rel = os_release('ceilometer-common', reset_cache=True)
if (CompareOpenStackReleases(os_rel) >= 'mitaka'):
apt_install(filter_installed_packages(get_packages()),
fatal=True)
apt_install(filter_installed_packages(get_packages()), fatal=True)
if is_relation_made('nrpe-external-master'):
update_nrpe_config()
CONFIGS.write_all()

View File

@ -85,7 +85,7 @@ CONFIG_FILES = {
'hook_contexts': [
CeilometerServiceContext(ssl_dir=CEILOMETER_CONF_DIR),
context.InternalEndpointContext(),
context.MemcacheContext()],
context.MemcacheContext(package='ceilometer-common')],
'services': CEILOMETER_AGENT_SERVICES
},
}
@ -114,7 +114,9 @@ def register_configs():
configs.register(conf, CONFIG_FILES[conf]['hook_contexts'])
if enable_memcache(release=release):
configs.register(MEMCACHED_CONF, [context.MemcacheContext()])
configs.register(
MEMCACHED_CONF,
[context.MemcacheContext(package='ceilometer-common')])
return configs

View File

@ -0,0 +1 @@
ceilometer_hooks.py

View File

@ -1,66 +0,0 @@
# 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.
from mock import patch
import os
os.environ['JUJU_UNIT_NAME'] = 'ceilometer'
with patch('ceilometer_utils.register_configs') as register_configs:
with patch('ceilometer_utils.restart_map') as restart_map:
import openstack_upgrade
from test_utils import (
CharmTestCase
)
TO_PATCH = [
'config_changed',
'do_openstack_upgrade',
]
class TestCinderUpgradeActions(CharmTestCase):
def setUp(self):
super(TestCinderUpgradeActions, self).setUp(openstack_upgrade,
TO_PATCH)
@patch('charmhelpers.contrib.openstack.utils.juju_log')
@patch('charmhelpers.contrib.openstack.utils.config')
@patch('charmhelpers.contrib.openstack.utils.action_set')
@patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
def test_openstack_upgrade_true(self, upgrade_avail,
action_set, config, log):
upgrade_avail.return_value = True
config.return_value = True
openstack_upgrade.openstack_upgrade()
self.assertTrue(self.do_openstack_upgrade.called)
self.assertTrue(self.config_changed.called)
@patch('charmhelpers.contrib.openstack.utils.juju_log')
@patch('charmhelpers.contrib.openstack.utils.config')
@patch('charmhelpers.contrib.openstack.utils.action_set')
@patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
def test_openstack_upgrade_false(self, upgrade_avail,
action_set, config, log):
upgrade_avail.return_value = True
config.return_value = False
openstack_upgrade.openstack_upgrade()
self.assertFalse(self.do_openstack_upgrade.called)
self.assertFalse(self.config_changed.called)

View File

@ -13,34 +13,26 @@
# limitations under the License.
import json
from mock import patch, MagicMock
from mock import patch
import ceilometer_utils
# Patch out register_configs for import of hooks
_register_configs = ceilometer_utils.register_configs
ceilometer_utils.register_configs = MagicMock()
import ceilometer_hooks as hooks
# Renable old function
ceilometer_utils.register_configs = _register_configs
with patch('ceilometer_utils.register_configs'):
with patch('ceilometer_utils.restart_map'):
import ceilometer_hooks as hooks
from test_utils import CharmTestCase
TO_PATCH = [
'configure_installation_source',
'CONFIGS',
'apt_install',
'apt_update',
'config',
'filter_installed_packages',
'CONFIGS',
'relation_set',
'openstack_upgrade_available',
'do_openstack_upgrade',
'update_nrpe_config',
'is_relation_made',
'get_packages',
'os_release',
'is_relation_made',
'is_unit_paused_set',
'relation_set',
'update_nrpe_config',
]
@ -48,21 +40,12 @@ class CeilometerHooksTest(CharmTestCase):
def setUp(self):
super(CeilometerHooksTest, self).setUp(hooks, TO_PATCH)
self.config.side_effect = self.test_config.get
@patch('charmhelpers.core.hookenv.config')
def test_configure_source(self, mock_config):
self.test_config.set('openstack-origin', 'cloud:precise-havana')
hooks.hooks.execute(['hooks/install'])
self.configure_installation_source.\
assert_called_with('cloud:precise-havana')
@patch('charmhelpers.core.hookenv.config')
def test_install_hook(self, mock_config):
ceil_pkgs = ['pkg1', 'pkg2']
self.filter_installed_packages.return_value = ceil_pkgs
hooks.hooks.execute(['hooks/install'])
self.assertTrue(self.configure_installation_source.called)
self.apt_update.assert_called_with(fatal=True)
self.apt_install.assert_called_with(ceil_pkgs, fatal=True)
@ -89,56 +72,33 @@ class CeilometerHooksTest(CharmTestCase):
ceilometer_utils.NOVA_SETTINGS))
@patch('charmhelpers.core.hookenv.config')
def test_config_changed_no_upgrade(self, mock_config):
self.openstack_upgrade_available.return_value = False
self.os_release.return_value = 'liberty'
def test_config_changed(self, mock_config):
self.is_relation_made.return_value = True
self.is_unit_paused_set.return_value = False
self.filter_installed_packages.return_value = ['pkg1', 'pkg2']
hooks.hooks.execute(['hooks/config-changed'])
self.openstack_upgrade_available.\
assert_called_with('ceilometer-common')
self.assertFalse(self.do_openstack_upgrade.called)
self.assertTrue(self.CONFIGS.write_all.called)
self.assertTrue(self.update_nrpe_config.called)
self.assertFalse(self.apt_install.called)
@patch('charmhelpers.core.hookenv.config')
def test_config_changed_partial_upgrade(self, mock_config):
self.openstack_upgrade_available.return_value = False
self.os_release.return_value = 'mitaka'
hooks.hooks.execute(['hooks/config-changed'])
self.openstack_upgrade_available.\
assert_called_with('ceilometer-common')
self.assertFalse(self.do_openstack_upgrade.called)
self.assertTrue(self.CONFIGS.write_all.called)
self.assertTrue(self.update_nrpe_config.called)
self.assertTrue(self.apt_install.called)
@patch('charmhelpers.core.hookenv.config')
def test_config_changed_upgrade(self, mock_config):
self.openstack_upgrade_available.return_value = True
hooks.hooks.execute(['hooks/config-changed'])
self.openstack_upgrade_available.\
assert_called_with('ceilometer-common')
self.assertTrue(self.do_openstack_upgrade.called)
self.assertTrue(self.CONFIGS.write_all.called)
self.assertTrue(self.update_nrpe_config.called)
def test_config_changed_with_openstack_upgrade_action(self):
self.openstack_upgrade_available.return_value = True
self.test_config.set('action-managed-upgrade', True)
hooks.hooks.execute(['hooks/config-changed'])
self.assertFalse(self.do_openstack_upgrade.called)
self.update_nrpe_config.assert_called_once_with()
self.CONFIGS.write_all.assert_called_once_with()
self.apt_install.assert_called_once_with(['pkg1', 'pkg2'], fatal=True)
self.is_relation_made.assert_called_once_with('nrpe-external-master')
@patch('charmhelpers.core.hookenv.config')
def test_config_changed_no_nrpe(self, mock_config):
self.openstack_upgrade_available.return_value = False
self.os_release.return_value = 'mitaka'
self.is_relation_made.return_value = False
self.is_unit_paused_set.return_value = False
self.filter_installed_packages.return_value = ['pkg1', 'pkg2']
hooks.hooks.execute(['hooks/config-changed'])
self.openstack_upgrade_available.\
assert_called_with('ceilometer-common')
self.assertFalse(self.do_openstack_upgrade.called)
self.assertTrue(self.CONFIGS.write_all.called)
self.assertFalse(self.update_nrpe_config.called)
self.CONFIGS.write_all.assert_called_once_with()
self.apt_install.assert_called_once_with(['pkg1', 'pkg2'], fatal=True)
self.is_relation_made.assert_called_once_with('nrpe-external-master')
@patch('charmhelpers.core.hookenv.config')
def test_config_changed_paused(self, mock_config):
self.is_relation_made.return_value = True
self.is_unit_paused_set.return_value = True
self.filter_installed_packages.return_value = ['pkg1', 'pkg2']
hooks.hooks.execute(['hooks/config-changed'])
self.assertFalse(self.update_nrpe_config.called)
self.assertFalse(self.CONFIGS.write_all.called)
self.assertFalse(self.apt_install.called)

View File

@ -14,7 +14,7 @@
import sys
from mock import MagicMock, patch, call
from mock import MagicMock, patch
# python-apt is not installed as part of test-requirements but is imported by
# some charmhelpers modules so create a fake import.
@ -81,30 +81,6 @@ class CeilometerUtilsTest(CharmTestCase):
'/etc/memcached.conf': ['memcached']}
self.assertEqual(restart_map, expect)
def test_do_openstack_upgrade(self):
self.config.side_effect = self.test_config.get
self.test_config.set('openstack-origin', 'cloud:precise-havana')
self.get_os_codename_install_source.return_value = 'havana'
self.get_os_codename_package.return_value = 'icehouse'
configs = MagicMock()
utils.do_openstack_upgrade(configs)
configs.set_release.assert_called_with(openstack_release='havana')
self.assertTrue(self.log.called)
self.apt_update.assert_called_with(fatal=True)
dpkg_opts = [
'--option', 'Dpkg::Options::=--force-confnew',
'--option', 'Dpkg::Options::=--force-confdef',
]
self.apt_install.assert_has_calls([
call(packages=utils.CEILOMETER_AGENT_PACKAGES,
options=dpkg_opts, fatal=True),
call(['python-ceilometer', 'ceilometer-common',
'ceilometer-agent-compute'], fatal=True),
])
self.configure_installation_source.assert_called_with(
'cloud:precise-havana'
)
def test_assess_status(self):
with patch.object(utils, 'assess_status_func') as asf:
callee = MagicMock()