Series Upgrade

Implement the series-upgrade feature allowing to move between Ubuntu
series.

Change-Id: Iea24af291b3d9d5b7771f35c2374e8d7e9b655c3
This commit is contained in:
David Ames 2018-08-10 07:55:17 -07:00
parent c5e835db33
commit 2623277ace
4 changed files with 91 additions and 3 deletions

View File

@ -186,7 +186,7 @@ SWIFT_CODENAMES = OrderedDict([
('queens', ('queens',
['2.16.0', '2.17.0']), ['2.16.0', '2.17.0']),
('rocky', ('rocky',
['2.18.0']), ['2.18.0', '2.19.0']),
]) ])
# >= Liberty version->codename mapping # >= Liberty version->codename mapping
@ -831,12 +831,25 @@ def _ows_check_if_paused(services=None, ports=None):
"""Check if the unit is supposed to be paused, and if so check that the """Check if the unit is supposed to be paused, and if so check that the
services/ports (if passed) are actually stopped/not being listened to. services/ports (if passed) are actually stopped/not being listened to.
if the unit isn't supposed to be paused, just return None, None If the unit isn't supposed to be paused, just return None, None
If the unit is performing a series upgrade, return a message indicating
this.
@param services: OPTIONAL services spec or list of service names. @param services: OPTIONAL services spec or list of service names.
@param ports: OPTIONAL list of port numbers. @param ports: OPTIONAL list of port numbers.
@returns state, message or None, None @returns state, message or None, None
""" """
if is_unit_upgrading_set():
state, message = check_actually_paused(services=services,
ports=ports)
if state is None:
# we're paused okay, so set maintenance and return
state = "blocked"
message = ("Ready for do-release-upgrade and reboot. "
"Set complete when finished.")
return state, message
if is_unit_paused_set(): if is_unit_paused_set():
state, message = check_actually_paused(services=services, state, message = check_actually_paused(services=services,
ports=ports) ports=ports)
@ -1339,7 +1352,7 @@ def pause_unit(assess_status_func, services=None, ports=None,
message = assess_status_func() message = assess_status_func()
if message: if message:
messages.append(message) messages.append(message)
if messages: if messages and not is_unit_upgrading_set():
raise Exception("Couldn't pause: {}".format("; ".join(messages))) raise Exception("Couldn't pause: {}".format("; ".join(messages)))
@ -1689,3 +1702,52 @@ def install_os_snaps(snaps, refresh=False):
snap_install(snap, snap_install(snap,
_ensure_flag(snaps[snap]['channel']), _ensure_flag(snaps[snap]['channel']),
_ensure_flag(snaps[snap]['mode'])) _ensure_flag(snaps[snap]['mode']))
def set_unit_upgrading():
"""Set the unit to a upgrading state in the local kv() store.
"""
with unitdata.HookData()() as t:
kv = t[0]
kv.set('unit-upgrading', True)
def clear_unit_upgrading():
"""Clear the unit from a upgrading state in the local kv() store
"""
with unitdata.HookData()() as t:
kv = t[0]
kv.set('unit-upgrading', False)
def is_unit_upgrading_set():
"""Return the state of the kv().get('unit-upgrading').
To help with units that don't have HookData() (testing)
if it excepts, return False
"""
try:
with unitdata.HookData()() as t:
kv = t[0]
# transform something truth-y into a Boolean.
return not(not(kv.get('unit-upgrading')))
except Exception:
return False
def series_upgrade_prepare(pause_unit_helper=None, configs=None):
""" Run common series upgrade prepare tasks."""
set_unit_upgrading()
if pause_unit_helper and configs:
if not is_unit_paused_set():
pause_unit_helper(configs)
def series_upgrade_complete(resume_unit_helper=None, configs=None):
""" Run common series upgrade complete tasks."""
clear_unit_paused()
clear_unit_upgrading()
if configs:
configs.write_all()
if resume_unit_helper:
resume_unit_helper(configs)

View File

@ -44,6 +44,8 @@ from cinder_utils import (
filesystem_mounted, filesystem_mounted,
assess_status, assess_status,
scrub_old_style_ceph, scrub_old_style_ceph,
pause_unit_helper,
resume_unit_helper,
) )
from cinder_contexts import ceph_config_file from cinder_contexts import ceph_config_file
@ -85,6 +87,8 @@ from charmhelpers.contrib.openstack.utils import (
is_unit_paused_set, is_unit_paused_set,
pausable_restart_on_change as restart_on_change, pausable_restart_on_change as restart_on_change,
CompareOpenStackReleases, CompareOpenStackReleases,
series_upgrade_prepare,
series_upgrade_complete,
) )
from charmhelpers.contrib.storage.linux.ceph import ( from charmhelpers.contrib.storage.linux.ceph import (
@ -154,6 +158,12 @@ def install():
@restart_on_change(restart_map(), stopstart=True) @restart_on_change(restart_map(), stopstart=True)
@harden() @harden()
def config_changed(): def config_changed():
# if we are paused, delay doing any config changed hooks.
# It is forced on the resume.
if is_unit_paused_set():
log("Unit is pause or upgrading. Skipping config_changed", "WARN")
return
conf = config() conf = config()
if conf['prefer-ipv6']: if conf['prefer-ipv6']:
@ -633,6 +643,20 @@ def certs_changed(relation_id=None, unit=None):
configure_https() configure_https()
@hooks.hook('pre-series-upgrade')
def pre_series_upgrade():
log("Running prepare series upgrade hook", "INFO")
series_upgrade_prepare(
pause_unit_helper, CONFIGS)
@hooks.hook('post-series-upgrade')
def post_series_upgrade():
log("Running complete series upgrade hook", "INFO")
series_upgrade_complete(
resume_unit_helper, CONFIGS)
if __name__ == '__main__': if __name__ == '__main__':
try: try:
hooks.execute(sys.argv) hooks.execute(sys.argv)

1
hooks/post-series-upgrade Symbolic link
View File

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

1
hooks/pre-series-upgrade Symbolic link
View File

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