Replicas per ring

This patchset implements 'replicas-account' and 'replicas-container'
charm options which can be used to set the desired number of replicas
per ring.

Change-Id: Ie7fa1b8c5619d0a5a278cd0eddaf1051de11f2a3
Closes-Bug: 1823696
This commit is contained in:
Tytus Kurek 2019-04-10 11:49:01 +00:00
parent 2b2ad66387
commit 1160493f3f
4 changed files with 94 additions and 5 deletions

View File

@ -102,7 +102,21 @@ options:
replicas:
type: int
default: 3
description: Minimum replicas for each object stored in the cluster.
description: Minimum replicas for each item stored in the cluster.
replicas-account:
type: int
default:
description: |
Minimum replicas for each account stored in the cluster.
.
NOTE: use only when you want to overwrite the global 'replicas' option.
replicas-container:
type: int
default:
description: |
Minimum replicas for each container stored in the cluster.
.
NOTE: use only when you want to overwrite the global 'replicas' option.
min-hours:
type: int
default: 0

View File

@ -65,6 +65,7 @@ from lib.swift_utils import (
assess_status,
try_initialize_swauth,
clear_storage_rings_available,
determine_replicas,
)
import charmhelpers.contrib.openstack.utils as openstack
@ -161,11 +162,11 @@ def config_changed():
if is_elected_leader(SWIFT_HA_RES):
log("Leader established, generating ring builders", level=INFO)
# initialize new storage rings.
for path in SWIFT_RINGS.values():
for ring, path in SWIFT_RINGS.items():
if not os.path.exists(path):
initialize_ring(path,
config('partition-power'),
config('replicas'),
determine_replicas(ring),
config('min-hours'))
if config('prefer-ipv6'):

View File

@ -1199,7 +1199,12 @@ def customer_check_assess_status(configs):
# Verify allowed_hosts is populated with enough unit IP addresses
ctxt = SwiftRingContext()()
if len(ctxt['allowed_hosts']) < config('replicas'):
replicas = [config('replicas'),
config('replicas-account'),
config('replicas-container')]
# Remove 'None' object types from the list
replicas = [r for r in replicas if r is not None]
if len(ctxt['allowed_hosts']) < max(replicas):
return ('blocked', 'Not enough related storage nodes')
# Verify there are enough storage zones to satisfy minimum replicas
@ -1273,3 +1278,27 @@ def assess_status_func(configs, check_services=None):
configs, required_interfaces,
charm_func=customer_check_assess_status,
services=check_services, ports=None)
def determine_replicas(ring):
""" Determine replicas (lp1823696)
Determine replicas based on 'replicas', 'replicas-account' and
'replicas-container' options.
:param ring: ring name
:type ring: str
:returns: replicas for the ring
"""
if ring == 'account':
if config('replicas-account'):
return config('replicas-account')
else:
return config('replicas')
elif ring == 'container':
if config('replicas-container'):
return config('replicas-container')
else:
return config('replicas')
else:
return config('replicas')

View File

@ -437,7 +437,7 @@ class SwiftUtilsTestCase(unittest.TestCase):
def customer_check_assess_status(
self, relation_ids, has_min_zones,
ctxt, workload_status, config):
config.return_value = 3
config.side_effect = [3, 3, 3]
relation_ids.return_value = []
s, m = swift_utils.customer_check_assess_status(None)
@ -596,3 +596,48 @@ class SwiftUtilsTestCase(unittest.TestCase):
'python-keystonemiddleware'],
swift_utils.determine_packages('rocky')
)
@mock.patch('lib.swift_utils.config')
def test_determine_replicas_account_set(self, config):
config.side_effect = lambda key: {
'replicas': 3,
'replicas-account': 2,
'replicas-container': None}[key]
replicas = swift_utils.determine_replicas('account')
self.assertEqual(replicas, 2)
@mock.patch('lib.swift_utils.config')
def test_determine_replicas_account_not_set(self, config):
config.side_effect = lambda key: {
'replicas': 3,
'replicas-account': None,
'replicas-container': None}[key]
replicas = swift_utils.determine_replicas('account')
self.assertEqual(replicas, 3)
@mock.patch('lib.swift_utils.config')
def test_determine_replicas_container_set(self, config):
config.side_effect = lambda key: {
'replicas': 3,
'replicas-account': None,
'replicas-container': 2}[key]
replicas = swift_utils.determine_replicas('container')
self.assertEqual(replicas, 2)
@mock.patch('lib.swift_utils.config')
def test_determine_replicas_container_not_set(self, config):
config.side_effect = lambda key: {
'replicas': 3,
'replicas-account': None,
'replicas-container': None}[key]
replicas = swift_utils.determine_replicas('container')
self.assertEqual(replicas, 3)
@mock.patch('lib.swift_utils.config')
def test_determine_replicas_object(self, config):
config.side_effect = lambda key: {
'replicas': 3,
'replicas-account': 2,
'replicas-container': 2}[key]
replicas = swift_utils.determine_replicas('object')
self.assertEqual(replicas, 3)