Adds primary/secondary multisite relation

A new relation with primary/secondary nomenclature is added and the
old master/slave relation is marked as *Deprecated*. In future,
master/slave relation would be completely removed.

Change-Id: I9cda48b74a20aaa9a41baedc79332bfaf13951d3
func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/926
This commit is contained in:
utkarshbhatthere 2022-09-22 11:39:37 +00:00
parent c1c9531a7f
commit 367a2aedcb
8 changed files with 96 additions and 53 deletions

View File

@ -340,7 +340,7 @@ def mon_relation(rid=None, unit=None):
# NOTE(jamespage):
# Multi-site deployments need to defer restart as the
# zone is not created until the master relation is
# zone is not created until the primary relation is
# joined; restarting here will cause a restart burst
# in systemd and stop the process restarting once
# zone configuration is complete.
@ -690,8 +690,8 @@ def radosgw_user_changed(relation_id=None):
'daemon-id': socket.gethostname()})
@hooks.hook('master-relation-joined')
def master_relation_joined(relation_id=None):
@hooks.hook('primary-relation-joined')
def primary_relation_joined(relation_id=None):
if not ready_for_service(legacy=False):
log('unit not ready, deferring multisite configuration')
return
@ -742,9 +742,9 @@ def master_relation_joined(relation_id=None):
multisite.create_realm(realm, default=True)
mutation = True
# Migration if master site has buckets configured.
# Migration if primary site has buckets configured.
# Migration involves renaming existing zone/zongroups such that existing
# buckets and their objects can be preserved on the master site.
# buckets and their objects can be preserved on the primary site.
if multisite.check_cluster_has_buckets() is True:
log('Migrating to multisite with zone ({}) and zonegroup ({})'
.format(zone, zonegroup), level=DEBUG)
@ -821,8 +821,8 @@ def master_relation_joined(relation_id=None):
secret=secret)
@hooks.hook('master-relation-departed')
@hooks.hook('slave-relation-departed')
@hooks.hook('primary-relation-departed')
@hooks.hook('secondary-relation-departed')
def multisite_relation_departed():
if not is_leader():
log('Cannot remove multisite relation, this unit is not the leader')
@ -868,8 +868,8 @@ def multisite_relation_departed():
raise RuntimeError("Residual multisite config at local site.")
@hooks.hook('slave-relation-changed')
def slave_relation_changed(relation_id=None, unit=None):
@hooks.hook('secondary-relation-changed')
def secondary_relation_changed(relation_id=None, unit=None):
if not is_leader():
log('Cannot setup multisite configuration, this unit is not the '
'leader')
@ -884,7 +884,7 @@ def slave_relation_changed(relation_id=None, unit=None):
master_data.get('access_key'),
master_data.get('secret'),
master_data.get('url'))):
log("Defer processing until master RGW has provided required data")
log("Defer processing until primary RGW has provided required data")
return
public_url = '{}:{}'.format(
@ -933,6 +933,9 @@ def slave_relation_changed(relation_id=None, unit=None):
if zone not in multisite.list_zones():
log('zone {} not found, creating now'.format(zone))
multisite.pull_period(url=master_data['url'],
access_key=master_data['access_key'],
secret=master_data['secret'])
multisite.create_zone(zone,
endpoints=endpoints,
default=False, master=False,
@ -953,6 +956,27 @@ def slave_relation_changed(relation_id=None, unit=None):
log('No mutation detected.', 'INFO')
@hooks.hook('master-relation-departed')
@hooks.hook('slave-relation-departed')
def master_slave_relation_departed():
log("departed relation is deprecated", "WARN")
multisite_relation_departed()
@hooks.hook('master-relation-joined')
def master_relation_joined(relation_id=None):
log("This relation is deprecated, use primary-secondary relation instead",
"WARN")
primary_relation_joined(relation_id)
@hooks.hook('slave-relation-changed')
def slave_relation_changed(relation_id=None, unit=None):
log("This relation is deprecated, use primary-secondary relation instead",
"WARN")
secondary_relation_changed(relation_id, unit)
@hooks.hook('leader-settings-changed')
def leader_settings_changed():
# NOTE: leader unit will only ever set leader storage
@ -962,19 +986,30 @@ def leader_settings_changed():
if restart_nonce_changed(leader_get('restart_nonce')):
service_restart(service_name())
if not is_leader():
# Deprecated Master/Slave relation
for r_id in relation_ids('master'):
master_relation_joined(r_id)
# Primary/Secondary relation
for r_id in relation_ids('primary'):
primary_relation_joined(r_id)
for r_id in relation_ids('radosgw-user'):
radosgw_user_changed(r_id)
def process_multisite_relations():
"""Re-trigger any pending master/slave relations"""
"""Re-trigger any pending multisite relations"""
# Deprecated Master/Slave relation
for r_id in relation_ids('master'):
master_relation_joined(r_id)
for r_id in relation_ids('slave'):
for unit in related_units(r_id):
slave_relation_changed(r_id, unit)
# Primary/Secondary relation
for r_id in relation_ids('primary'):
primary_relation_joined(r_id)
for r_id in relation_ids('secondary'):
for unit in related_units(r_id):
secondary_relation_changed(r_id, unit)
if __name__ == '__main__':

View File

@ -218,10 +218,14 @@ def check_optional_config_and_relations(configs):
leader_get('secret'),
leader_get('restart_nonce'))
# An operator may have deployed both relations
primary_rids = relation_ids('master') + relation_ids('primary')
secondary_rids = relation_ids('slave') + relation_ids('secondary')
multisite_rids = primary_rids + secondary_rids
# Any realm or zonegroup config is present, multisite checks can be done.
# zone config can't be used because it's used by default.
if config('realm') or config('zonegroup') or relation_ids('master') \
or relation_ids('slave'):
if config('realm') or config('zonegroup') or multisite_rids:
# All of Realm, zonegroup, and zone must be configured.
if not all(multisite_config):
return ('blocked',
@ -229,14 +233,14 @@ def check_optional_config_and_relations(configs):
'(realm={realm}, zonegroup={zonegroup}'
', zone={zone})'.format(**config()))
# Master/Slave Relation should be configured.
if not (relation_ids('master') or relation_ids('slave')):
# Primary/Secondary Relation should be configured.
if not multisite_rids:
return ('blocked',
'multi-site configuration but master/slave '
'multi-site configuration but primary/secondary '
'relation missing')
# Primary site status check
if relation_ids('master'):
if primary_rids:
# Migration: The system is not multisite already.
if not multisite.is_multisite_configured(config('zone'),
config('zonegroup')):
@ -261,7 +265,7 @@ def check_optional_config_and_relations(configs):
'waiting for configuration of master zone')
# Secondary site status check
if relation_ids('slave'):
if secondary_rids:
# Migration: The system is not multisite already.
if not multisite.is_multisite_configured(config('zone'),
config('zonegroup')):
@ -270,7 +274,7 @@ def check_optional_config_and_relations(configs):
"Non-Pristine RGW site can't be used as secondary")
multisite_ready = False
for rid in relation_ids('slave'):
for rid in secondary_rids:
for unit in related_units(rid):
if relation_get('url', unit=unit, rid=rid):
multisite_ready = True

View File

@ -30,6 +30,8 @@ requires:
interface: tls-certificates
slave:
interface: radosgw-multisite
secondary:
interface: radosgw-multisite
provides:
nrpe-external-master:
interface: nrpe-external-master
@ -38,6 +40,8 @@ provides:
interface: http
master:
interface: radosgw-multisite
primary:
interface: radosgw-multisite
object-store:
interface: swift-proxy
radosgw-user:

View File

@ -609,21 +609,21 @@ class MiscMultisiteTests(CharmTestCase):
'related_units',
'leader_get',
'is_leader',
'master_relation_joined',
'slave_relation_changed',
'primary_relation_joined',
'secondary_relation_changed',
'service_restart',
'service_name',
'multisite'
]
_relation_ids = {
'master': ['master:1'],
'slave': ['slave:1'],
'primary': ['primary:1'],
'secondary': ['secondary:1'],
}
_related_units = {
'master:1': ['rgw/0', 'rgw/1'],
'slave:1': ['rgw-s/0', 'rgw-s/1'],
'primary:1': ['rgw/0', 'rgw/1'],
'secondary:1': ['rgw-s/0', 'rgw-s/1'],
}
def setUp(self):
@ -642,14 +642,14 @@ class MiscMultisiteTests(CharmTestCase):
self.is_leader.return_value = False
ceph_hooks.leader_settings_changed()
self.service_restart.assert_called_once_with('rgw@hostname')
self.master_relation_joined.assert_called_once_with('master:1')
self.primary_relation_joined.assert_called_once_with('primary:1')
def test_process_multisite_relations(self):
ceph_hooks.process_multisite_relations()
self.master_relation_joined.assert_called_once_with('master:1')
self.slave_relation_changed.assert_has_calls([
call('slave:1', 'rgw-s/0'),
call('slave:1', 'rgw-s/1'),
self.primary_relation_joined.assert_called_once_with('primary:1')
self.secondary_relation_changed.assert_has_calls([
call('secondary:1', 'rgw-s/0'),
call('secondary:1', 'rgw-s/1'),
])
@ -684,7 +684,7 @@ class CephRadosMultisiteTests(CharmTestCase):
self.systemd_based_radosgw.return_value = True
class MasterMultisiteTests(CephRadosMultisiteTests):
class PrimaryMultisiteTests(CephRadosMultisiteTests):
_complete_config = {
'realm': 'testrealm',
@ -703,8 +703,8 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
'restart_nonce': 'foobar',
}
def test_master_relation_joined_missing_config(self):
ceph_hooks.master_relation_joined('master:1')
def test_primary_relation_joined_missing_config(self):
ceph_hooks.primary_relation_joined('primary:1')
self.config.assert_has_calls([
call('realm'),
call('zonegroup'),
@ -712,7 +712,7 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
])
self.relation_set.assert_not_called()
def test_master_relation_joined_create_everything(self):
def test_primary_relation_joined_create_everything(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.listen_port.return_value = 80
@ -725,7 +725,7 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
self.multisite.create_system_user.return_value = (
'mykey', 'mysecret',
)
ceph_hooks.master_relation_joined('master:1')
ceph_hooks.primary_relation_joined('primary:1')
self.config.assert_has_calls([
call('realm'),
call('zonegroup'),
@ -768,12 +768,12 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
call(restart_nonce=ANY),
])
self.relation_set.assert_called_with(
relation_id='master:1',
relation_id='primary:1',
access_key='mykey',
secret='mysecret',
)
def test_master_relation_joined_create_nothing(self):
def test_primary_relation_joined_create_nothing(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.is_leader.return_value = True
@ -786,7 +786,7 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
self.multisite.list_users.return_value = [
ceph_hooks.MULTISITE_SYSTEM_USER
]
ceph_hooks.master_relation_joined('master:1')
ceph_hooks.primary_relation_joined('primary:1')
self.multisite.create_realm.assert_not_called()
self.multisite.create_zonegroup.assert_not_called()
self.multisite.create_zone.assert_not_called()
@ -795,15 +795,15 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
self.service_restart.assert_not_called()
self.leader_set.assert_not_called()
def test_master_relation_joined_not_leader(self):
def test_primary_relation_joined_not_leader(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.listen_port.return_value = 80
self.is_leader.return_value = False
self.leader_get.side_effect = lambda attr: self._leader_data.get(attr)
ceph_hooks.master_relation_joined('master:1')
ceph_hooks.primary_relation_joined('primary:1')
self.relation_set.assert_called_once_with(
relation_id='master:1',
relation_id='primary:1',
realm='testrealm',
zonegroup='testzonegroup',
url='http://rgw:80',
@ -833,7 +833,7 @@ class MasterMultisiteTests(CephRadosMultisiteTests):
)
class SlaveMultisiteTests(CephRadosMultisiteTests):
class SecondaryMultisiteTests(CephRadosMultisiteTests):
_complete_config = {
'realm': 'testrealm',
@ -846,7 +846,7 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
'zonegroup': 'testzonegroup',
'access_key': 'anotherkey',
'secret': 'anothersecret',
'url': 'http://master:80'
'url': 'http://primary:80'
}
_test_bad_relation = {
@ -854,10 +854,10 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
'zonegroup': 'anotherzg',
'access_key': 'anotherkey',
'secret': 'anothersecret',
'url': 'http://master:80'
'url': 'http://primary:80'
}
def test_slave_relation_changed(self):
def test_secondary_relation_changed(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.is_leader.return_value = True
@ -867,7 +867,7 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
self.multisite.list_realms.return_value = []
self.multisite.list_zones.return_value = []
self.multisite.check_cluster_has_buckets.return_value = False
ceph_hooks.slave_relation_changed('slave:1', 'rgw/0')
ceph_hooks.secondary_relation_changed('secondary:1', 'rgw/0')
self.config.assert_has_calls([
call('realm'),
call('zonegroup'),
@ -878,7 +878,7 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
access_key=self._test_relation['access_key'],
secret=self._test_relation['secret'],
)
self.multisite.pull_period.assert_called_once_with(
self.multisite.pull_period.assert_called_with(
url=self._test_relation['url'],
access_key=self._test_relation['access_key'],
secret=self._test_relation['secret'],
@ -902,20 +902,20 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
self.service_restart.assert_called_once()
self.leader_set.assert_called_once_with(restart_nonce=ANY)
def test_slave_relation_changed_incomplete_relation(self):
def test_secondary_relation_changed_incomplete_relation(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.is_leader.return_value = True
self.relation_get.return_value = {}
ceph_hooks.slave_relation_changed('slave:1', 'rgw/0')
ceph_hooks.secondary_relation_changed('secondary:1', 'rgw/0')
self.config.assert_not_called()
def test_slave_relation_changed_mismatching_config(self):
def test_secondary_relation_changed_mismatching_config(self):
for k, v in self._complete_config.items():
self.test_config.set(k, v)
self.is_leader.return_value = True
self.relation_get.return_value = self._test_bad_relation
ceph_hooks.slave_relation_changed('slave:1', 'rgw/0')
ceph_hooks.secondary_relation_changed('secondary:1', 'rgw/0')
self.config.assert_has_calls([
call('realm'),
call('zonegroup'),
@ -923,9 +923,9 @@ class SlaveMultisiteTests(CephRadosMultisiteTests):
])
self.multisite.list_realms.assert_not_called()
def test_slave_relation_changed_not_leader(self):
def test_secondary_relation_changed_not_leader(self):
self.is_leader.return_value = False
ceph_hooks.slave_relation_changed('slave:1', 'rgw/0')
ceph_hooks.secondary_relation_changed('secondary:1', 'rgw/0')
self.relation_get.assert_not_called()
@patch.object(ceph_hooks, 'apt_install')