Merge lp:~hopem/charms/trusty/glance/charm-helpers-sync-1396246 into lp:~openstack-charmers-archive/charms/trusty/glance/next

Proposed by Edward Hope-Morley on 2014-12-18
Status: Merged
Merged at revision: 87
Proposed branch: lp:~hopem/charms/trusty/glance/charm-helpers-sync-1396246
Merge into: lp:~openstack-charmers-archive/charms/trusty/glance/next
Diff against target: 145 lines (+74/-16)
3 files modified
hooks/charmhelpers/contrib/hahelpers/cluster.py (+26/-12)
hooks/charmhelpers/core/decorators.py (+41/-0)
hooks/charmhelpers/core/host.py (+7/-4)
To merge this branch: bzr merge lp:~hopem/charms/trusty/glance/charm-helpers-sync-1396246
Reviewer Review Type Date Requested Status
Corey Bryant 2014-12-18 Approve on 2014-12-18
Review via email: mp+245092@code.launchpad.net
To post a comment you must log in.

charm_lint_check #275 glance-next for hopem mp245092
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/275/

charm_unit_test #303 glance-next for hopem mp245092
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/303/

charm_amulet_test #438 glance-next for hopem mp245092
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/438/

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/charmhelpers/contrib/hahelpers/cluster.py'
2--- hooks/charmhelpers/contrib/hahelpers/cluster.py 2014-12-10 20:28:49 +0000
3+++ hooks/charmhelpers/contrib/hahelpers/cluster.py 2014-12-18 11:34:06 +0000
4@@ -13,6 +13,7 @@
5
6 import subprocess
7 import os
8+
9 from socket import gethostname as get_unit_hostname
10
11 import six
12@@ -28,12 +29,19 @@
13 WARNING,
14 unit_get,
15 )
16+from charmhelpers.core.decorators import (
17+ retry_on_exception,
18+)
19
20
21 class HAIncompleteConfig(Exception):
22 pass
23
24
25+class CRMResourceNotFound(Exception):
26+ pass
27+
28+
29 def is_elected_leader(resource):
30 """
31 Returns True if the charm executing this is the elected cluster leader.
32@@ -68,24 +76,30 @@
33 return False
34
35
36-def is_crm_leader(resource):
37+@retry_on_exception(5, base_delay=2, exc_type=CRMResourceNotFound)
38+def is_crm_leader(resource, retry=False):
39 """
40 Returns True if the charm calling this is the elected corosync leader,
41 as returned by calling the external "crm" command.
42+
43+ We allow this operation to be retried to avoid the possibility of getting a
44+ false negative. See LP #1396246 for more info.
45 """
46- cmd = [
47- "crm", "resource",
48- "show", resource
49- ]
50+ cmd = ['crm', 'resource', 'show', resource]
51 try:
52- status = subprocess.check_output(cmd).decode('UTF-8')
53+ status = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
54+ if not isinstance(status, six.text_type):
55+ status = six.text_type(status, "utf-8")
56 except subprocess.CalledProcessError:
57- return False
58- else:
59- if get_unit_hostname() in status:
60- return True
61- else:
62- return False
63+ status = None
64+
65+ if status and get_unit_hostname() in status:
66+ return True
67+
68+ if status and "resource %s is NOT running" % (resource) in status:
69+ raise CRMResourceNotFound("CRM resource %s not found" % (resource))
70+
71+ return False
72
73
74 def is_leader(resource):
75
76=== added file 'hooks/charmhelpers/core/decorators.py'
77--- hooks/charmhelpers/core/decorators.py 1970-01-01 00:00:00 +0000
78+++ hooks/charmhelpers/core/decorators.py 2014-12-18 11:34:06 +0000
79@@ -0,0 +1,41 @@
80+#
81+# Copyright 2014 Canonical Ltd.
82+#
83+# Authors:
84+# Edward Hope-Morley <opentastic@gmail.com>
85+#
86+
87+import time
88+
89+from charmhelpers.core.hookenv import (
90+ log,
91+ INFO,
92+)
93+
94+
95+def retry_on_exception(num_retries, base_delay=0, exc_type=Exception):
96+ """If the decorated function raises exception exc_type, allow num_retries
97+ retry attempts before raise the exception.
98+ """
99+ def _retry_on_exception_inner_1(f):
100+ def _retry_on_exception_inner_2(*args, **kwargs):
101+ retries = num_retries
102+ multiplier = 1
103+ while True:
104+ try:
105+ return f(*args, **kwargs)
106+ except exc_type:
107+ if not retries:
108+ raise
109+
110+ delay = base_delay * multiplier
111+ multiplier += 1
112+ log("Retrying '%s' %d more times (delay=%s)" %
113+ (f.__name__, retries, delay), level=INFO)
114+ retries -= 1
115+ if delay:
116+ time.sleep(delay)
117+
118+ return _retry_on_exception_inner_2
119+
120+ return _retry_on_exception_inner_1
121
122=== modified file 'hooks/charmhelpers/core/host.py'
123--- hooks/charmhelpers/core/host.py 2014-12-15 10:16:05 +0000
124+++ hooks/charmhelpers/core/host.py 2014-12-18 11:34:06 +0000
125@@ -162,13 +162,16 @@
126 uid = pwd.getpwnam(owner).pw_uid
127 gid = grp.getgrnam(group).gr_gid
128 realpath = os.path.abspath(path)
129- if os.path.exists(realpath):
130- if force and not os.path.isdir(realpath):
131+ path_exists = os.path.exists(realpath)
132+ if path_exists and force:
133+ if not os.path.isdir(realpath):
134 log("Removing non-directory file {} prior to mkdir()".format(path))
135 os.unlink(realpath)
136- else:
137+ os.makedirs(realpath, perms)
138+ os.chown(realpath, uid, gid)
139+ elif not path_exists:
140 os.makedirs(realpath, perms)
141- os.chown(realpath, uid, gid)
142+ os.chown(realpath, uid, gid)
143
144
145 def write_file(path, content, owner='root', group='root', perms=0o444):

Subscribers

People subscribed via source and target branches