Do not set ha.available until clustered

The interface was setting ha.available immediately with no gating.

The hacluster charm sets a relation variable, clustered, when it has
enough peers and has setup corosync. This change updates the
interface to react to this setting. Only set ha.available when
clustered is set and True.

Change-Id: I23eb5e70537a62d5b9e5e24d09f37519b63a1717
Closes-Bug: #1749280
This commit is contained in:
David Ames 2018-02-21 20:00:44 +00:00
parent 52a760b8fb
commit bf858a38bc
1 changed files with 40 additions and 1 deletions

View File

@ -18,6 +18,7 @@ from charms.reactive import hook
from charms.reactive import RelationBase
from charms.reactive import scopes
from charms.reactive.helpers import data_changed
from charmhelpers.core import hookenv
class HAClusterRequires(RelationBase):
@ -32,13 +33,38 @@ class HAClusterRequires(RelationBase):
@hook('{requires:hacluster}-relation-changed')
def changed(self):
self.set_state('{relation_name}.available')
if self.is_clustered():
self.set_state('{relation_name}.available')
else:
self.remove_state('{relation_name}.available')
@hook('{requires:hacluster}-relation-{broken,departed}')
def departed(self):
self.remove_state('{relation_name}.available')
self.remove_state('{relation_name}.connected')
def is_clustered(self):
"""Has the hacluster charm set clustered?
The hacluster charm sets cluster=True when it determines it is ready.
Check the relation data for clustered and force a boolean return.
:returns: boolean
"""
clustered_values = self.get_remote_all('clustered')
if clustered_values:
# There is only ever one subordinate hacluster unit
clustered = clustered_values[0]
# Future versions of hacluster will return a bool
# Current versions return a string
if type(clustered) is bool:
return clustered
elif (clustered is not None and
(clustered.lower() == 'true' or
clustered.lower() == 'yes')):
return True
return False
def bind_on(self, iface=None, mcastport=None):
relation_data = {}
if iface:
@ -167,3 +193,16 @@ class HAClusterRequires(RelationBase):
resources.group(group, *dns_res_group_members)
self.set_local(resources=resources)
def get_remote_all(self, key, default=None):
"""Return a list of all values presented by remote units for key"""
values = []
for conversation in self.conversations():
for relation_id in conversation.relation_ids:
for unit in hookenv.related_units(relation_id):
value = hookenv.relation_get(key,
unit,
relation_id) or default
if value:
values.append(value)
return list(set(values))