Avoid shared-db change when using access-network
When the percona-cluster charm sets an access-network but the default unit-get address is not on that network extra shared-db relations get executed. This is specifically a problem when running upgrades and trying to avoid API downtime. The root cause is that the access-network is not checked until the SharedDBContext is consulted. But then db_joined function will change it back to the wrong ip on subsequent runs. This change adds a check for access-network on the relation during the db_joined function and pushes IP selection off to get_relation_ip. Charm helpers sync to pull in changes to get_relation_ip. Change-Id: Ifc22d61f1de1092306b98d30fbea01fead855d14 Partial-bug: #1677647
This commit is contained in:
parent
bc777bb70a
commit
e7317bf571
|
@ -1232,31 +1232,50 @@ MAX_DEFAULT_WORKERS = 4
|
|||
DEFAULT_MULTIPLIER = 2
|
||||
|
||||
|
||||
def _calculate_workers():
|
||||
'''
|
||||
Determine the number of worker processes based on the CPU
|
||||
count of the unit containing the application.
|
||||
|
||||
Workers will be limited to MAX_DEFAULT_WORKERS in
|
||||
container environments where no worker-multipler configuration
|
||||
option been set.
|
||||
|
||||
@returns int: number of worker processes to use
|
||||
'''
|
||||
multiplier = config('worker-multiplier') or DEFAULT_MULTIPLIER
|
||||
count = int(_num_cpus() * multiplier)
|
||||
if multiplier > 0 and count == 0:
|
||||
count = 1
|
||||
|
||||
if config('worker-multiplier') is None and is_container():
|
||||
# NOTE(jamespage): Limit unconfigured worker-multiplier
|
||||
# to MAX_DEFAULT_WORKERS to avoid insane
|
||||
# worker configuration in LXD containers
|
||||
# on large servers
|
||||
# Reference: https://pad.lv/1665270
|
||||
count = min(count, MAX_DEFAULT_WORKERS)
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def _num_cpus():
|
||||
'''
|
||||
Compatibility wrapper for calculating the number of CPU's
|
||||
a unit has.
|
||||
|
||||
@returns: int: number of CPU cores detected
|
||||
'''
|
||||
try:
|
||||
return psutil.cpu_count()
|
||||
except AttributeError:
|
||||
return psutil.NUM_CPUS
|
||||
|
||||
|
||||
class WorkerConfigContext(OSContextGenerator):
|
||||
|
||||
@property
|
||||
def num_cpus(self):
|
||||
# NOTE: use cpu_count if present (16.04 support)
|
||||
if hasattr(psutil, 'cpu_count'):
|
||||
return psutil.cpu_count()
|
||||
else:
|
||||
return psutil.NUM_CPUS
|
||||
|
||||
def __call__(self):
|
||||
multiplier = config('worker-multiplier') or DEFAULT_MULTIPLIER
|
||||
count = int(self.num_cpus * multiplier)
|
||||
if multiplier > 0 and count == 0:
|
||||
count = 1
|
||||
|
||||
if config('worker-multiplier') is None and is_container():
|
||||
# NOTE(jamespage): Limit unconfigured worker-multiplier
|
||||
# to MAX_DEFAULT_WORKERS to avoid insane
|
||||
# worker configuration in LXD containers
|
||||
# on large servers
|
||||
# Reference: https://pad.lv/1665270
|
||||
count = min(count, MAX_DEFAULT_WORKERS)
|
||||
|
||||
ctxt = {"workers": count}
|
||||
ctxt = {"workers": _calculate_workers()}
|
||||
return ctxt
|
||||
|
||||
|
||||
|
@ -1264,7 +1283,7 @@ class WSGIWorkerConfigContext(WorkerConfigContext):
|
|||
|
||||
def __init__(self, name=None, script=None, admin_script=None,
|
||||
public_script=None, process_weight=1.00,
|
||||
admin_process_weight=0.75, public_process_weight=0.25):
|
||||
admin_process_weight=0.25, public_process_weight=0.75):
|
||||
self.service_name = name
|
||||
self.user = name
|
||||
self.group = name
|
||||
|
@ -1276,8 +1295,7 @@ class WSGIWorkerConfigContext(WorkerConfigContext):
|
|||
self.public_process_weight = public_process_weight
|
||||
|
||||
def __call__(self):
|
||||
multiplier = config('worker-multiplier') or 1
|
||||
total_processes = self.num_cpus * multiplier
|
||||
total_processes = _calculate_workers()
|
||||
ctxt = {
|
||||
"service_name": self.service_name,
|
||||
"user": self.user,
|
||||
|
|
|
@ -53,11 +53,10 @@ from charmhelpers.core.hookenv import (
|
|||
relation_get,
|
||||
relation_set,
|
||||
relation_ids,
|
||||
related_units,
|
||||
service_name,
|
||||
unit_get,
|
||||
UnregisteredHookError,
|
||||
status_set,
|
||||
network_get_primary_address,
|
||||
)
|
||||
|
||||
from charmhelpers.core.host import (
|
||||
|
@ -105,7 +104,8 @@ from charmhelpers.contrib.network.ip import (
|
|||
get_netmask_for_address,
|
||||
get_iface_for_address,
|
||||
get_ipv6_addr,
|
||||
is_ipv6
|
||||
is_ipv6,
|
||||
get_relation_ip,
|
||||
)
|
||||
from charmhelpers.contrib.openstack.ip import (
|
||||
canonical_url,
|
||||
|
@ -158,13 +158,14 @@ def db_joined():
|
|||
sync_db_with_multi_ipv6_addresses(config('database'),
|
||||
config('database-user'))
|
||||
else:
|
||||
host = None
|
||||
try:
|
||||
# NOTE: try to use network spaces
|
||||
host = network_get_primary_address('shared-db')
|
||||
except NotImplementedError:
|
||||
# NOTE: fallback to private-address
|
||||
host = unit_get('private-address')
|
||||
# Avoid churn check for access-network early
|
||||
access_network = None
|
||||
for unit in related_units():
|
||||
access_network = relation_get(unit=unit,
|
||||
attribute='access-network')
|
||||
if access_network:
|
||||
break
|
||||
host = get_relation_ip('shared-db', cidr_network=access_network)
|
||||
|
||||
relation_set(database=config('database'),
|
||||
username=config('database-user'),
|
||||
|
|
|
@ -59,9 +59,8 @@ TO_PATCH = [
|
|||
'relation_ids',
|
||||
'relation_set',
|
||||
'relation_get',
|
||||
'related_units',
|
||||
'service_name',
|
||||
'unit_get',
|
||||
'network_get_primary_address',
|
||||
# charmhelpers.core.host
|
||||
'apt_install',
|
||||
'apt_update',
|
||||
|
@ -99,6 +98,7 @@ TO_PATCH = [
|
|||
'get_ipv6_addr',
|
||||
'sync_db_with_multi_ipv6_addresses',
|
||||
'delete_keyring',
|
||||
'get_relation_ip',
|
||||
]
|
||||
|
||||
|
||||
|
@ -107,7 +107,6 @@ class GlanceRelationTests(CharmTestCase):
|
|||
def setUp(self):
|
||||
super(GlanceRelationTests, self).setUp(relations, TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
self.network_get_primary_address.side_effect = NotImplementedError
|
||||
|
||||
@patch.object(utils, 'config')
|
||||
@patch.object(utils, 'token_cache_pkgs')
|
||||
|
@ -178,40 +177,15 @@ class GlanceRelationTests(CharmTestCase):
|
|||
self.git_install.assert_called_with(projects_yaml)
|
||||
|
||||
def test_db_joined(self):
|
||||
self.unit_get.return_value = 'glance.foohost.com'
|
||||
self.get_relation_ip.return_value = '10.0.0.1'
|
||||
self.is_relation_made.return_value = False
|
||||
relations.db_joined()
|
||||
self.relation_set.assert_called_with(database='glance',
|
||||
username='glance',
|
||||
hostname='glance.foohost.com')
|
||||
self.unit_get.assert_called_with('private-address')
|
||||
|
||||
def test_db_joined_network_spaces(self):
|
||||
self.network_get_primary_address.side_effect = None
|
||||
self.network_get_primary_address.return_value = '192.168.20.1'
|
||||
self.unit_get.return_value = 'glance.foohost.com'
|
||||
self.is_relation_made.return_value = False
|
||||
relations.db_joined()
|
||||
self.relation_set.assert_called_with(database='glance',
|
||||
username='glance',
|
||||
hostname='192.168.20.1')
|
||||
self.assertFalse(self.unit_get.called)
|
||||
|
||||
def test_db_joined_with_ipv6(self):
|
||||
self.test_config.set('prefer-ipv6', True)
|
||||
self.is_relation_made.return_value = False
|
||||
relations.db_joined()
|
||||
relation_data = {
|
||||
'database': 'glance',
|
||||
'username': 'glance',
|
||||
}
|
||||
relation_data['hostname'] = '2001:db8:1::1'
|
||||
|
||||
self.sync_db_with_multi_ipv6_addresses.assert_called_with(
|
||||
'glance', 'glance')
|
||||
hostname='10.0.0.1')
|
||||
self.get_relation_ip.assert_called_with('shared-db', cidr_network=None)
|
||||
|
||||
def test_postgresql_db_joined(self):
|
||||
self.unit_get.return_value = 'glance.foohost.com'
|
||||
self.is_relation_made.return_value = False
|
||||
relations.pgsql_db_joined()
|
||||
self.relation_set.assert_called_with(database='glance'),
|
||||
|
|
Loading…
Reference in New Issue