set-weight/remove-devices actions are leader-only

When running set-weight and remove-devices actions, they must be run
on the leader of the swift-proxy cluster.  Lacking this validation,
the ring builder file on a non-leader would get updated, but the
balance_rings action would fail, and the changes to the ring files
would not propogate to the remainder of the swift cluster.

Change-Id: I9134eb88b16e5ffe18f16ce30e03e469027b6670
Closes-Bug: 1882250
This commit is contained in:
Drew Freiberger 2020-06-10 08:03:37 -05:00
parent 4fc8daa1ae
commit 0ce1ee67f8
2 changed files with 28 additions and 2 deletions

View File

@ -44,6 +44,9 @@ from charmhelpers.core.hookenv import (
action_get,
action_set,
)
from charmhelpers.contrib.hahelpers.cluster import (
is_elected_leader,
)
from charmhelpers.contrib.openstack.utils import (
set_unit_paused,
clear_unit_paused,
@ -56,6 +59,7 @@ from lib.swift_utils import (
services,
set_weight_in_ring,
SWIFT_CONF_DIR,
SWIFT_HA_RES,
)
@ -133,6 +137,10 @@ def remove_devices(args):
:raises SwiftProxyCharmException: if pattern action_get('search-value')
doesn't match any device in the ring.
"""
if not is_elected_leader(SWIFT_HA_RES):
action_fail('Must run action on leader unit')
return
rings_valid = ['account', 'container', 'object', 'all']
rings_to_update = []
ring = action_get('ring')
@ -160,6 +168,10 @@ def set_weight(args):
:raises SwiftProxyCharmException: if pattern action_get('search-value')
doesn't match any device in the ring.
"""
if not is_elected_leader(SWIFT_HA_RES):
action_fail('Must run action on leader unit')
return
rings_valid = ['account', 'container', 'object', 'all']
ring = action_get('ring')
if ring not in rings_valid:

View File

@ -330,7 +330,14 @@ class RemoveDevicesTestCase(CharmTestCase):
actions.actions, ["action_fail",
"action_get",
"remove_from_ring",
"balance_rings"])
"balance_rings",
"is_elected_leader"])
self.is_elected_leader.return_value = True
def test_not_leader(self):
self.is_elected_leader.return_value = False
actions.actions.remove_devices([])
self.action_fail.assert_called()
def test_ring_valid(self):
self.action_get.side_effect = ['account', 'd1']
@ -354,7 +361,14 @@ class SetWeightTestCase(CharmTestCase):
actions.actions, ["action_fail",
"action_get",
"set_weight_in_ring",
"balance_rings"])
"balance_rings",
"is_elected_leader"])
self.is_elected_leader.return_value = True
def test_not_leader(self):
self.is_elected_leader.return_value = False
actions.actions.set_weight([])
self.action_fail.assert_called()
def test_ring_valid(self):
self.action_get.side_effect = ['account', 'd1', '0.0']