core: Add all supported releases - packages map

For principal - subordinate plugin type relations where the
principal Python payload imports code from packages managed by a
subordinate, upgrades can be problematic.

This helper will allow a subordinate charm to inform its principal
about all implemented release - packages combinations ahead of time.
With this information in place the principal can do the upgrade in
one operation without risk of charm relation RPC type processing at
a critical moment.

Related-Bug: #1806111
Change-Id: I455501c1c2cdb53e62b533be95d2493bf1a5027a
This commit is contained in:
Frode Nordahl 2021-03-18 15:05:25 +01:00
parent df9a2eddec
commit ccb778f111
No known key found for this signature in database
GPG Key ID: 6A5D59A3BA48373F
2 changed files with 81 additions and 0 deletions

View File

@ -391,6 +391,40 @@ class BaseOpenStackCharm(object, metaclass=BaseOpenStackCharmMeta):
# Note refers back to the Metaclass property for this charm.
return self.__class__.singleton
@property
def releases_packages_map(self):
"""Provide a map of all supported releases and their packages.
:returns: Map of release, package type and install / purge packages.
Example:
{
'mitaka': {
'deb': {
'install': ['python-ldappool'],
'purge': []
}
},
'rocky': {
'deb': {
'install': ['python3-ldap', 'python3-ldappool'],
'purge': ['python-ldap', 'python-ldappool']}
}
}
:rtype: Dict[str,Dict[str,List[str]]]
"""
return {
release: {
package_type: {
'install': (instance.packages if package_type == 'deb'
else instance.snaps),
'purge': (instance.purge_packages if package_type == 'deb'
else []),
},
}
for release, pkg_instance in _releases.items()
for package_type, instance in pkg_instance.items()
}
def __init__(self, interfaces=None, config=None, release=None):
"""Instantiate an instance of the class.

View File

@ -127,6 +127,53 @@ class TestBaseOpenStackCharmMeta(BaseOpenStackCharmTest):
class TestC2(chm_core.BaseOpenStackCharm):
release = 'liberty'
def test_releases_packages_map(self):
self.maxDiff = None
self.patch_object(chm_core, '_releases', new={})
class TestC1(chm_core.BaseOpenStackCharm):
release = 'liberty'
packages = ['l_inst_one', 'l_inst_two']
purge_packages = ['l_purge']
class TestC2(chm_core.BaseOpenStackCharm):
release = 'mitaka'
packages = ['m_inst_one', 'm_inst_two']
purge_packages = ['m_purge']
class TestC3(chm_core.BaseOpenStackCharm):
release = 'ocata'
package_type = 'snap'
snaps = ['o_snap_one', 'o_snap_two']
# from any charm release instance we see package_type / install_purge
# lists registered by all other charm release instances
for cls in (TestC1, TestC2, TestC3):
instance = cls()
self.assertDictEqual(
instance.releases_packages_map,
{
'liberty': {
'deb': {
'install': ['l_inst_one', 'l_inst_two'],
'purge': ['l_purge']
}
},
'mitaka': {
'deb': {
'install': ['m_inst_one', 'm_inst_two'],
'purge': ['m_purge']
}
},
'ocata': {
'snap': {
'install': ['o_snap_one', 'o_snap_two'],
'purge': []
}
}
}
)
class TestFunctions(BaseOpenStackCharmTest):