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:
parent
2b2ad66387
commit
1160493f3f
16
config.yaml
16
config.yaml
|
@ -102,7 +102,21 @@ options:
|
||||||
replicas:
|
replicas:
|
||||||
type: int
|
type: int
|
||||||
default: 3
|
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:
|
min-hours:
|
||||||
type: int
|
type: int
|
||||||
default: 0
|
default: 0
|
||||||
|
|
|
@ -65,6 +65,7 @@ from lib.swift_utils import (
|
||||||
assess_status,
|
assess_status,
|
||||||
try_initialize_swauth,
|
try_initialize_swauth,
|
||||||
clear_storage_rings_available,
|
clear_storage_rings_available,
|
||||||
|
determine_replicas,
|
||||||
)
|
)
|
||||||
|
|
||||||
import charmhelpers.contrib.openstack.utils as openstack
|
import charmhelpers.contrib.openstack.utils as openstack
|
||||||
|
@ -161,11 +162,11 @@ def config_changed():
|
||||||
if is_elected_leader(SWIFT_HA_RES):
|
if is_elected_leader(SWIFT_HA_RES):
|
||||||
log("Leader established, generating ring builders", level=INFO)
|
log("Leader established, generating ring builders", level=INFO)
|
||||||
# initialize new storage rings.
|
# initialize new storage rings.
|
||||||
for path in SWIFT_RINGS.values():
|
for ring, path in SWIFT_RINGS.items():
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
initialize_ring(path,
|
initialize_ring(path,
|
||||||
config('partition-power'),
|
config('partition-power'),
|
||||||
config('replicas'),
|
determine_replicas(ring),
|
||||||
config('min-hours'))
|
config('min-hours'))
|
||||||
|
|
||||||
if config('prefer-ipv6'):
|
if config('prefer-ipv6'):
|
||||||
|
|
|
@ -1199,7 +1199,12 @@ def customer_check_assess_status(configs):
|
||||||
|
|
||||||
# Verify allowed_hosts is populated with enough unit IP addresses
|
# Verify allowed_hosts is populated with enough unit IP addresses
|
||||||
ctxt = SwiftRingContext()()
|
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')
|
return ('blocked', 'Not enough related storage nodes')
|
||||||
|
|
||||||
# Verify there are enough storage zones to satisfy minimum replicas
|
# 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,
|
configs, required_interfaces,
|
||||||
charm_func=customer_check_assess_status,
|
charm_func=customer_check_assess_status,
|
||||||
services=check_services, ports=None)
|
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')
|
||||||
|
|
|
@ -437,7 +437,7 @@ class SwiftUtilsTestCase(unittest.TestCase):
|
||||||
def customer_check_assess_status(
|
def customer_check_assess_status(
|
||||||
self, relation_ids, has_min_zones,
|
self, relation_ids, has_min_zones,
|
||||||
ctxt, workload_status, config):
|
ctxt, workload_status, config):
|
||||||
config.return_value = 3
|
config.side_effect = [3, 3, 3]
|
||||||
|
|
||||||
relation_ids.return_value = []
|
relation_ids.return_value = []
|
||||||
s, m = swift_utils.customer_check_assess_status(None)
|
s, m = swift_utils.customer_check_assess_status(None)
|
||||||
|
@ -596,3 +596,48 @@ class SwiftUtilsTestCase(unittest.TestCase):
|
||||||
'python-keystonemiddleware'],
|
'python-keystonemiddleware'],
|
||||||
swift_utils.determine_packages('rocky')
|
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)
|
||||||
|
|
Loading…
Reference in New Issue