~landscape/charms/trusty/rabbitmq-server-backport-lp1500204/trunk

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/hahelpers/cluster.py

  • Committer: james.page at ubuntu
  • Date: 2015-08-10 16:38:33 UTC
  • Revision ID: james.page@ubuntu.com-20150810163833-lwvkk1s3iea5zd35
Tags: 15.07
[gnuoy] 15.07 Charm release

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    ERROR,
45
45
    WARNING,
46
46
    unit_get,
 
47
    is_leader as juju_is_leader
47
48
)
48
49
from charmhelpers.core.decorators import (
49
50
    retry_on_exception,
52
53
    bool_from_string,
53
54
)
54
55
 
 
56
DC_RESOURCE_NAME = 'DC'
 
57
 
55
58
 
56
59
class HAIncompleteConfig(Exception):
57
60
    pass
61
64
    pass
62
65
 
63
66
 
 
67
class CRMDCNotFound(Exception):
 
68
    pass
 
69
 
 
70
 
64
71
def is_elected_leader(resource):
65
72
    """
66
73
    Returns True if the charm executing this is the elected cluster leader.
67
74
 
68
75
    It relies on two mechanisms to determine leadership:
69
 
        1. If the charm is part of a corosync cluster, call corosync to
 
76
        1. If juju is sufficiently new and leadership election is supported,
 
77
        the is_leader command will be used.
 
78
        2. If the charm is part of a corosync cluster, call corosync to
70
79
        determine leadership.
71
 
        2. If the charm is not part of a corosync cluster, the leader is
 
80
        3. If the charm is not part of a corosync cluster, the leader is
72
81
        determined as being "the alive unit with the lowest unit numer". In
73
82
        other words, the oldest surviving unit.
74
83
    """
 
84
    try:
 
85
        return juju_is_leader()
 
86
    except NotImplementedError:
 
87
        log('Juju leadership election feature not enabled'
 
88
            ', using fallback support',
 
89
            level=WARNING)
 
90
 
75
91
    if is_clustered():
76
92
        if not is_crm_leader(resource):
77
93
            log('Deferring action to CRM leader.', level=INFO)
95
111
    return False
96
112
 
97
113
 
98
 
@retry_on_exception(5, base_delay=2, exc_type=CRMResourceNotFound)
 
114
def is_crm_dc():
 
115
    """
 
116
    Determine leadership by querying the pacemaker Designated Controller
 
117
    """
 
118
    cmd = ['crm', 'status']
 
119
    try:
 
120
        status = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
 
121
        if not isinstance(status, six.text_type):
 
122
            status = six.text_type(status, "utf-8")
 
123
    except subprocess.CalledProcessError as ex:
 
124
        raise CRMDCNotFound(str(ex))
 
125
 
 
126
    current_dc = ''
 
127
    for line in status.split('\n'):
 
128
        if line.startswith('Current DC'):
 
129
            # Current DC: juju-lytrusty-machine-2 (168108163) - partition with quorum
 
130
            current_dc = line.split(':')[1].split()[0]
 
131
    if current_dc == get_unit_hostname():
 
132
        return True
 
133
    elif current_dc == 'NONE':
 
134
        raise CRMDCNotFound('Current DC: NONE')
 
135
 
 
136
    return False
 
137
 
 
138
 
 
139
@retry_on_exception(5, base_delay=2,
 
140
                    exc_type=(CRMResourceNotFound, CRMDCNotFound))
99
141
def is_crm_leader(resource, retry=False):
100
142
    """
101
143
    Returns True if the charm calling this is the elected corosync leader,
104
146
    We allow this operation to be retried to avoid the possibility of getting a
105
147
    false negative. See LP #1396246 for more info.
106
148
    """
 
149
    if resource == DC_RESOURCE_NAME:
 
150
        return is_crm_dc()
107
151
    cmd = ['crm', 'resource', 'show', resource]
108
152
    try:
109
153
        status = subprocess.check_output(cmd, stderr=subprocess.STDOUT)