Merge lp:~hopem/charms/trusty/ceilometer/lp1518975 into lp:~openstack-charmers-archive/charms/trusty/ceilometer/next

Proposed by Edward Hope-Morley on 2016-02-11
Status: Merged
Merged at revision: 115
Proposed branch: lp:~hopem/charms/trusty/ceilometer/lp1518975
Merge into: lp:~openstack-charmers-archive/charms/trusty/ceilometer/next
Diff against target: 662 lines (+211/-96)
8 files modified
charmhelpers/contrib/openstack/amulet/deployment.py (+3/-2)
charmhelpers/contrib/openstack/context.py (+11/-7)
charmhelpers/contrib/openstack/neutron.py (+18/-6)
charmhelpers/contrib/openstack/utils.py (+108/-43)
charmhelpers/contrib/python/packages.py (+22/-7)
charmhelpers/core/host.py (+41/-26)
charmhelpers/fetch/giturl.py (+5/-3)
tests/charmhelpers/contrib/openstack/amulet/deployment.py (+3/-2)
To merge this branch: bzr merge lp:~hopem/charms/trusty/ceilometer/lp1518975
Reviewer Review Type Date Requested Status
OpenStack Charmers 2016-02-11 Pending
Review via email: mp+285746@code.launchpad.net
To post a comment you must log in.

charm_unit_test #198 ceilometer-next for hopem mp285746
    UNIT OK: passed

Build: http://10.245.162.36:8080/job/charm_unit_test/198/

charm_lint_check #217 ceilometer-next for hopem mp285746
    LINT OK: passed

Build: http://10.245.162.36:8080/job/charm_lint_check/217/

116. By Edward Hope-Morley on 2016-02-11

charm-helpers sync

charm_lint_check #224 ceilometer-next for hopem mp285746
    LINT OK: passed

Build: http://10.245.162.36:8080/job/charm_lint_check/224/

charm_unit_test #216 ceilometer-next for hopem mp285746
    UNIT OK: passed

Build: http://10.245.162.36:8080/job/charm_unit_test/216/

charm_amulet_test #101 ceilometer-next for hopem mp285746
    AMULET OK: passed

Build: http://10.245.162.36:8080/job/charm_amulet_test/101/

charm_amulet_test #112 ceilometer-next for hopem mp285746
    AMULET OK: passed

Build: http://10.245.162.36:8080/job/charm_amulet_test/112/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/contrib/openstack/amulet/deployment.py'
2--- charmhelpers/contrib/openstack/amulet/deployment.py 2016-01-04 21:24:42 +0000
3+++ charmhelpers/contrib/openstack/amulet/deployment.py 2016-02-11 15:44:28 +0000
4@@ -121,11 +121,12 @@
5
6 # Charms which should use the source config option
7 use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
8- 'ceph-osd', 'ceph-radosgw']
9+ 'ceph-osd', 'ceph-radosgw', 'ceph-mon']
10
11 # Charms which can not use openstack-origin, ie. many subordinates
12 no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
13- 'openvswitch-odl', 'neutron-api-odl', 'odl-controller']
14+ 'openvswitch-odl', 'neutron-api-odl', 'odl-controller',
15+ 'cinder-backup']
16
17 if self.openstack:
18 for svc in services:
19
20=== modified file 'charmhelpers/contrib/openstack/context.py'
21--- charmhelpers/contrib/openstack/context.py 2016-01-08 02:37:03 +0000
22+++ charmhelpers/contrib/openstack/context.py 2016-02-11 15:44:28 +0000
23@@ -90,6 +90,12 @@
24 from charmhelpers.contrib.openstack.utils import get_host_ip
25 from charmhelpers.core.unitdata import kv
26
27+try:
28+ import psutil
29+except ImportError:
30+ apt_install('python-psutil', fatal=True)
31+ import psutil
32+
33 CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
34 ADDRESS_TYPES = ['admin', 'internal', 'public']
35
36@@ -1258,13 +1264,11 @@
37
38 @property
39 def num_cpus(self):
40- try:
41- from psutil import NUM_CPUS
42- except ImportError:
43- apt_install('python-psutil', fatal=True)
44- from psutil import NUM_CPUS
45-
46- return NUM_CPUS
47+ # NOTE: use cpu_count if present (16.04 support)
48+ if hasattr(psutil, 'cpu_count'):
49+ return psutil.cpu_count()
50+ else:
51+ return psutil.NUM_CPUS
52
53 def __call__(self):
54 multiplier = config('worker-multiplier') or 0
55
56=== modified file 'charmhelpers/contrib/openstack/neutron.py'
57--- charmhelpers/contrib/openstack/neutron.py 2016-01-04 21:24:42 +0000
58+++ charmhelpers/contrib/openstack/neutron.py 2016-02-11 15:44:28 +0000
59@@ -50,7 +50,7 @@
60 if kernel_version() >= (3, 13):
61 return []
62 else:
63- return ['openvswitch-datapath-dkms']
64+ return [headers_package(), 'openvswitch-datapath-dkms']
65
66
67 # legacy
68@@ -70,7 +70,7 @@
69 relation_prefix='neutron',
70 ssl_dir=QUANTUM_CONF_DIR)],
71 'services': ['quantum-plugin-openvswitch-agent'],
72- 'packages': [[headers_package()] + determine_dkms_package(),
73+ 'packages': [determine_dkms_package(),
74 ['quantum-plugin-openvswitch-agent']],
75 'server_packages': ['quantum-server',
76 'quantum-plugin-openvswitch'],
77@@ -111,7 +111,7 @@
78 relation_prefix='neutron',
79 ssl_dir=NEUTRON_CONF_DIR)],
80 'services': ['neutron-plugin-openvswitch-agent'],
81- 'packages': [[headers_package()] + determine_dkms_package(),
82+ 'packages': [determine_dkms_package(),
83 ['neutron-plugin-openvswitch-agent']],
84 'server_packages': ['neutron-server',
85 'neutron-plugin-openvswitch'],
86@@ -155,7 +155,7 @@
87 relation_prefix='neutron',
88 ssl_dir=NEUTRON_CONF_DIR)],
89 'services': [],
90- 'packages': [[headers_package()] + determine_dkms_package(),
91+ 'packages': [determine_dkms_package(),
92 ['neutron-plugin-cisco']],
93 'server_packages': ['neutron-server',
94 'neutron-plugin-cisco'],
95@@ -174,7 +174,7 @@
96 'neutron-dhcp-agent',
97 'nova-api-metadata',
98 'etcd'],
99- 'packages': [[headers_package()] + determine_dkms_package(),
100+ 'packages': [determine_dkms_package(),
101 ['calico-compute',
102 'bird',
103 'neutron-dhcp-agent',
104@@ -219,7 +219,7 @@
105 relation_prefix='neutron',
106 ssl_dir=NEUTRON_CONF_DIR)],
107 'services': [],
108- 'packages': [[headers_package()] + determine_dkms_package()],
109+ 'packages': [determine_dkms_package()],
110 'server_packages': ['neutron-server',
111 'python-neutron-plugin-midonet'],
112 'server_services': ['neutron-server']
113@@ -233,6 +233,18 @@
114 'neutron-plugin-ml2']
115 # NOTE: patch in vmware renames nvp->nsx for icehouse onwards
116 plugins['nvp'] = plugins['nsx']
117+ if release >= 'kilo':
118+ plugins['midonet']['driver'] = (
119+ 'neutron.plugins.midonet.plugin.MidonetPluginV2')
120+ if release >= 'liberty':
121+ midonet_origin = config('midonet-origin')
122+ if midonet_origin is not None and midonet_origin[4:5] == '1':
123+ plugins['midonet']['driver'] = (
124+ 'midonet.neutron.plugin_v1.MidonetPluginV2')
125+ plugins['midonet']['server_packages'].remove(
126+ 'python-neutron-plugin-midonet')
127+ plugins['midonet']['server_packages'].append(
128+ 'python-networking-midonet')
129 return plugins
130
131
132
133=== modified file 'charmhelpers/contrib/openstack/utils.py'
134--- charmhelpers/contrib/openstack/utils.py 2016-01-08 02:37:03 +0000
135+++ charmhelpers/contrib/openstack/utils.py 2016-02-11 15:44:28 +0000
136@@ -25,6 +25,7 @@
137 import re
138
139 import six
140+import tempfile
141 import traceback
142 import uuid
143 import yaml
144@@ -41,6 +42,7 @@
145 config,
146 log as juju_log,
147 charm_dir,
148+ DEBUG,
149 INFO,
150 related_units,
151 relation_ids,
152@@ -103,29 +105,28 @@
153 ('2016.1', 'mitaka'),
154 ])
155
156-# The ugly duckling
157+# The ugly duckling - must list releases oldest to newest
158 SWIFT_CODENAMES = OrderedDict([
159- ('1.4.3', 'diablo'),
160- ('1.4.8', 'essex'),
161- ('1.7.4', 'folsom'),
162- ('1.8.0', 'grizzly'),
163- ('1.7.7', 'grizzly'),
164- ('1.7.6', 'grizzly'),
165- ('1.10.0', 'havana'),
166- ('1.9.1', 'havana'),
167- ('1.9.0', 'havana'),
168- ('1.13.1', 'icehouse'),
169- ('1.13.0', 'icehouse'),
170- ('1.12.0', 'icehouse'),
171- ('1.11.0', 'icehouse'),
172- ('2.0.0', 'juno'),
173- ('2.1.0', 'juno'),
174- ('2.2.0', 'juno'),
175- ('2.2.1', 'kilo'),
176- ('2.2.2', 'kilo'),
177- ('2.3.0', 'liberty'),
178- ('2.4.0', 'liberty'),
179- ('2.5.0', 'liberty'),
180+ ('diablo',
181+ ['1.4.3']),
182+ ('essex',
183+ ['1.4.8']),
184+ ('folsom',
185+ ['1.7.4']),
186+ ('grizzly',
187+ ['1.7.6', '1.7.7', '1.8.0']),
188+ ('havana',
189+ ['1.9.0', '1.9.1', '1.10.0']),
190+ ('icehouse',
191+ ['1.11.0', '1.12.0', '1.13.0', '1.13.1']),
192+ ('juno',
193+ ['2.0.0', '2.1.0', '2.2.0']),
194+ ('kilo',
195+ ['2.2.1', '2.2.2']),
196+ ('liberty',
197+ ['2.3.0', '2.4.0', '2.5.0']),
198+ ('mitaka',
199+ ['2.5.0']),
200 ])
201
202 # >= Liberty version->codename mapping
203@@ -227,6 +228,33 @@
204 error_out(e)
205
206
207+def get_os_version_codename_swift(codename):
208+ '''Determine OpenStack version number of swift from codename.'''
209+ for k, v in six.iteritems(SWIFT_CODENAMES):
210+ if k == codename:
211+ return v[-1]
212+ e = 'Could not derive swift version for '\
213+ 'codename: %s' % codename
214+ error_out(e)
215+
216+
217+def get_swift_codename(version):
218+ '''Determine OpenStack codename that corresponds to swift version.'''
219+ codenames = [k for k, v in six.iteritems(SWIFT_CODENAMES) if version in v]
220+ if len(codenames) > 1:
221+ # If more than one release codename contains this version we determine
222+ # the actual codename based on the highest available install source.
223+ for codename in reversed(codenames):
224+ releases = UBUNTU_OPENSTACK_RELEASE
225+ release = [k for k, v in six.iteritems(releases) if codename in v]
226+ ret = subprocess.check_output(['apt-cache', 'policy', 'swift'])
227+ if codename in ret or release[0] in ret:
228+ return codename
229+ elif len(codenames) == 1:
230+ return codenames[0]
231+ return None
232+
233+
234 def get_os_codename_package(package, fatal=True):
235 '''Derive OpenStack release codename from an installed package.'''
236 import apt_pkg as apt
237@@ -270,7 +298,7 @@
238 # < Liberty co-ordinated project versions
239 try:
240 if 'swift' in pkg.name:
241- return SWIFT_CODENAMES[vers]
242+ return get_swift_codename(vers)
243 else:
244 return OPENSTACK_CODENAMES[vers]
245 except KeyError:
246@@ -289,12 +317,14 @@
247
248 if 'swift' in pkg:
249 vers_map = SWIFT_CODENAMES
250+ for cname, version in six.iteritems(vers_map):
251+ if cname == codename:
252+ return version[-1]
253 else:
254 vers_map = OPENSTACK_CODENAMES
255-
256- for version, cname in six.iteritems(vers_map):
257- if cname == codename:
258- return version
259+ for version, cname in six.iteritems(vers_map):
260+ if cname == codename:
261+ return version
262 # e = "Could not determine OpenStack version for package: %s" % pkg
263 # error_out(e)
264
265@@ -319,12 +349,42 @@
266
267
268 def import_key(keyid):
269- cmd = "apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 " \
270- "--recv-keys %s" % keyid
271- try:
272- subprocess.check_call(cmd.split(' '))
273- except subprocess.CalledProcessError:
274- error_out("Error importing repo key %s" % keyid)
275+ key = keyid.strip()
276+ if (key.startswith('-----BEGIN PGP PUBLIC KEY BLOCK-----') and
277+ key.endswith('-----END PGP PUBLIC KEY BLOCK-----')):
278+ juju_log("PGP key found (looks like ASCII Armor format)", level=DEBUG)
279+ juju_log("Importing ASCII Armor PGP key", level=DEBUG)
280+ with tempfile.NamedTemporaryFile() as keyfile:
281+ with open(keyfile.name, 'w') as fd:
282+ fd.write(key)
283+ fd.write("\n")
284+
285+ cmd = ['apt-key', 'add', keyfile.name]
286+ try:
287+ subprocess.check_call(cmd)
288+ except subprocess.CalledProcessError:
289+ error_out("Error importing PGP key '%s'" % key)
290+ else:
291+ juju_log("PGP key found (looks like Radix64 format)", level=DEBUG)
292+ juju_log("Importing PGP key from keyserver", level=DEBUG)
293+ cmd = ['apt-key', 'adv', '--keyserver',
294+ 'hkp://keyserver.ubuntu.com:80', '--recv-keys', key]
295+ try:
296+ subprocess.check_call(cmd)
297+ except subprocess.CalledProcessError:
298+ error_out("Error importing PGP key '%s'" % key)
299+
300+
301+def get_source_and_pgp_key(input):
302+ """Look for a pgp key ID or ascii-armor key in the given input."""
303+ index = input.strip()
304+ index = input.rfind('|')
305+ if index < 0:
306+ return input, None
307+
308+ key = input[index + 1:].strip('|')
309+ source = input[:index]
310+ return source, key
311
312
313 def configure_installation_source(rel):
314@@ -336,16 +396,16 @@
315 with open('/etc/apt/sources.list.d/juju_deb.list', 'w') as f:
316 f.write(DISTRO_PROPOSED % ubuntu_rel)
317 elif rel[:4] == "ppa:":
318- src = rel
319+ src, key = get_source_and_pgp_key(rel)
320+ if key:
321+ import_key(key)
322+
323 subprocess.check_call(["add-apt-repository", "-y", src])
324 elif rel[:3] == "deb":
325- l = len(rel.split('|'))
326- if l == 2:
327- src, key = rel.split('|')
328- juju_log("Importing PPA key from keyserver for %s" % src)
329+ src, key = get_source_and_pgp_key(rel)
330+ if key:
331 import_key(key)
332- elif l == 1:
333- src = rel
334+
335 with open('/etc/apt/sources.list.d/juju_deb.list', 'w') as f:
336 f.write(src)
337 elif rel[:6] == 'cloud:':
338@@ -460,11 +520,16 @@
339 cur_vers = get_os_version_package(package)
340 if "swift" in package:
341 codename = get_os_codename_install_source(src)
342- available_vers = get_os_version_codename(codename, SWIFT_CODENAMES)
343+ avail_vers = get_os_version_codename_swift(codename)
344 else:
345- available_vers = get_os_version_install_source(src)
346+ avail_vers = get_os_version_install_source(src)
347 apt.init()
348- return apt.version_compare(available_vers, cur_vers) == 1
349+ if "swift" in package:
350+ major_cur_vers = cur_vers.split('.', 1)[0]
351+ major_avail_vers = avail_vers.split('.', 1)[0]
352+ major_diff = apt.version_compare(major_avail_vers, major_cur_vers)
353+ return avail_vers > cur_vers and (major_diff == 1 or major_diff == 0)
354+ return apt.version_compare(avail_vers, cur_vers) == 1
355
356
357 def ensure_block_device(block_device):
358
359=== modified file 'charmhelpers/contrib/python/packages.py'
360--- charmhelpers/contrib/python/packages.py 2016-01-04 21:24:42 +0000
361+++ charmhelpers/contrib/python/packages.py 2016-02-11 15:44:28 +0000
362@@ -19,20 +19,35 @@
363
364 import os
365 import subprocess
366+import sys
367
368 from charmhelpers.fetch import apt_install, apt_update
369 from charmhelpers.core.hookenv import charm_dir, log
370
371-try:
372- from pip import main as pip_execute
373-except ImportError:
374- apt_update()
375- apt_install('python-pip')
376- from pip import main as pip_execute
377-
378 __author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
379
380
381+def pip_execute(*args, **kwargs):
382+ """Overriden pip_execute() to stop sys.path being changed.
383+
384+ The act of importing main from the pip module seems to cause add wheels
385+ from the /usr/share/python-wheels which are installed by various tools.
386+ This function ensures that sys.path remains the same after the call is
387+ executed.
388+ """
389+ try:
390+ _path = sys.path
391+ try:
392+ from pip import main as _pip_execute
393+ except ImportError:
394+ apt_update()
395+ apt_install('python-pip')
396+ from pip import main as _pip_execute
397+ _pip_execute(*args, **kwargs)
398+ finally:
399+ sys.path = _path
400+
401+
402 def parse_options(given, available):
403 """Given a set of options, check if available"""
404 for key, value in sorted(given.items()):
405
406=== modified file 'charmhelpers/core/host.py'
407--- charmhelpers/core/host.py 2016-01-08 02:37:03 +0000
408+++ charmhelpers/core/host.py 2016-02-11 15:44:28 +0000
409@@ -138,7 +138,8 @@
410 except subprocess.CalledProcessError:
411 return False
412 else:
413- if ("start/running" in output or "is running" in output):
414+ if ("start/running" in output or "is running" in output or
415+ "up and running" in output):
416 return True
417 else:
418 return False
419@@ -160,13 +161,13 @@
420
421
422 def init_is_systemd():
423+ """Return True if the host system uses systemd, False otherwise."""
424 return os.path.isdir(SYSTEMD_SYSTEM)
425
426
427 def adduser(username, password=None, shell='/bin/bash', system_user=False,
428 primary_group=None, secondary_groups=None):
429- """
430- Add a user to the system.
431+ """Add a user to the system.
432
433 Will log but otherwise succeed if the user already exists.
434
435@@ -174,7 +175,7 @@
436 :param str password: Password for user; if ``None``, create a system user
437 :param str shell: The default shell for the user
438 :param bool system_user: Whether to create a login or system user
439- :param str primary_group: Primary group for user; defaults to their username
440+ :param str primary_group: Primary group for user; defaults to username
441 :param list secondary_groups: Optional list of additional groups
442
443 :returns: The password database entry struct, as returned by `pwd.getpwnam`
444@@ -300,14 +301,12 @@
445
446
447 def fstab_remove(mp):
448- """Remove the given mountpoint entry from /etc/fstab
449- """
450+ """Remove the given mountpoint entry from /etc/fstab"""
451 return Fstab.remove_by_mountpoint(mp)
452
453
454 def fstab_add(dev, mp, fs, options=None):
455- """Adds the given device entry to the /etc/fstab file
456- """
457+ """Adds the given device entry to the /etc/fstab file"""
458 return Fstab.add(dev, mp, fs, options=options)
459
460
461@@ -363,8 +362,7 @@
462
463
464 def file_hash(path, hash_type='md5'):
465- """
466- Generate a hash checksum of the contents of 'path' or None if not found.
467+ """Generate a hash checksum of the contents of 'path' or None if not found.
468
469 :param str hash_type: Any hash alrgorithm supported by :mod:`hashlib`,
470 such as md5, sha1, sha256, sha512, etc.
471@@ -379,10 +377,9 @@
472
473
474 def path_hash(path):
475- """
476- Generate a hash checksum of all files matching 'path'. Standard wildcards
477- like '*' and '?' are supported, see documentation for the 'glob' module for
478- more information.
479+ """Generate a hash checksum of all files matching 'path'. Standard
480+ wildcards like '*' and '?' are supported, see documentation for the 'glob'
481+ module for more information.
482
483 :return: dict: A { filename: hash } dictionary for all matched files.
484 Empty if none found.
485@@ -394,8 +391,7 @@
486
487
488 def check_hash(path, checksum, hash_type='md5'):
489- """
490- Validate a file using a cryptographic checksum.
491+ """Validate a file using a cryptographic checksum.
492
493 :param str checksum: Value of the checksum used to validate the file.
494 :param str hash_type: Hash algorithm used to generate `checksum`.
495@@ -410,6 +406,7 @@
496
497
498 class ChecksumError(ValueError):
499+ """A class derived from Value error to indicate the checksum failed."""
500 pass
501
502
503@@ -515,7 +512,7 @@
504
505
506 def list_nics(nic_type=None):
507- '''Return a list of nics of given type(s)'''
508+ """Return a list of nics of given type(s)"""
509 if isinstance(nic_type, six.string_types):
510 int_types = [nic_type]
511 else:
512@@ -557,12 +554,13 @@
513
514
515 def set_nic_mtu(nic, mtu):
516- '''Set MTU on a network interface'''
517+ """Set the Maximum Transmission Unit (MTU) on a network interface."""
518 cmd = ['ip', 'link', 'set', nic, 'mtu', mtu]
519 subprocess.check_call(cmd)
520
521
522 def get_nic_mtu(nic):
523+ """Return the Maximum Transmission Unit (MTU) for a network interface."""
524 cmd = ['ip', 'addr', 'show', nic]
525 ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')
526 mtu = ""
527@@ -574,6 +572,7 @@
528
529
530 def get_nic_hwaddr(nic):
531+ """Return the Media Access Control (MAC) for a network interface."""
532 cmd = ['ip', '-o', '-0', 'addr', 'show', nic]
533 ip_output = subprocess.check_output(cmd).decode('UTF-8')
534 hwaddr = ""
535@@ -584,7 +583,7 @@
536
537
538 def cmp_pkgrevno(package, revno, pkgcache=None):
539- '''Compare supplied revno with the revno of the installed package
540+ """Compare supplied revno with the revno of the installed package
541
542 * 1 => Installed revno is greater than supplied arg
543 * 0 => Installed revno is the same as supplied arg
544@@ -593,7 +592,7 @@
545 This function imports apt_cache function from charmhelpers.fetch if
546 the pkgcache argument is None. Be sure to add charmhelpers.fetch if
547 you call this function, or pass an apt_pkg.Cache() instance.
548- '''
549+ """
550 import apt_pkg
551 if not pkgcache:
552 from charmhelpers.fetch import apt_cache
553@@ -603,19 +602,27 @@
554
555
556 @contextmanager
557-def chdir(d):
558+def chdir(directory):
559+ """Change the current working directory to a different directory for a code
560+ block and return the previous directory after the block exits. Useful to
561+ run commands from a specificed directory.
562+
563+ :param str directory: The directory path to change to for this context.
564+ """
565 cur = os.getcwd()
566 try:
567- yield os.chdir(d)
568+ yield os.chdir(directory)
569 finally:
570 os.chdir(cur)
571
572
573 def chownr(path, owner, group, follow_links=True, chowntopdir=False):
574- """
575- Recursively change user and group ownership of files and directories
576+ """Recursively change user and group ownership of files and directories
577 in given path. Doesn't chown path itself by default, only its children.
578
579+ :param str path: The string path to start changing ownership.
580+ :param str owner: The owner string to use when looking up the uid.
581+ :param str group: The group string to use when looking up the gid.
582 :param bool follow_links: Also Chown links if True
583 :param bool chowntopdir: Also chown path itself if True
584 """
585@@ -639,15 +646,23 @@
586
587
588 def lchownr(path, owner, group):
589+ """Recursively change user and group ownership of files and directories
590+ in a given path, not following symbolic links. See the documentation for
591+ 'os.lchown' for more information.
592+
593+ :param str path: The string path to start changing ownership.
594+ :param str owner: The owner string to use when looking up the uid.
595+ :param str group: The group string to use when looking up the gid.
596+ """
597 chownr(path, owner, group, follow_links=False)
598
599
600 def get_total_ram():
601- '''The total amount of system RAM in bytes.
602+ """The total amount of system RAM in bytes.
603
604 This is what is reported by the OS, and may be overcommitted when
605 there are multiple containers hosted on the same machine.
606- '''
607+ """
608 with open('/proc/meminfo', 'r') as f:
609 for line in f.readlines():
610 if line:
611
612=== modified file 'charmhelpers/fetch/giturl.py'
613--- charmhelpers/fetch/giturl.py 2016-01-08 02:37:03 +0000
614+++ charmhelpers/fetch/giturl.py 2016-02-11 15:44:28 +0000
615@@ -15,7 +15,7 @@
616 # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
617
618 import os
619-from subprocess import check_call
620+from subprocess import check_call, CalledProcessError
621 from charmhelpers.fetch import (
622 BaseFetchHandler,
623 UnhandledSource,
624@@ -49,8 +49,8 @@
625 cmd = ['git', '-C', dest, 'pull', source, branch]
626 else:
627 cmd = ['git', 'clone', source, dest, '--branch', branch]
628- if depth:
629- cmd.extend(['--depth', depth])
630+ if depth:
631+ cmd.extend(['--depth', depth])
632 check_call(cmd)
633
634 def install(self, source, branch="master", dest=None, depth=None):
635@@ -63,6 +63,8 @@
636 branch_name)
637 try:
638 self.clone(source, dest_dir, branch, depth)
639+ except CalledProcessError as e:
640+ raise UnhandledSource(e)
641 except OSError as e:
642 raise UnhandledSource(e.strerror)
643 return dest_dir
644
645=== modified file 'tests/charmhelpers/contrib/openstack/amulet/deployment.py'
646--- tests/charmhelpers/contrib/openstack/amulet/deployment.py 2016-01-04 21:24:42 +0000
647+++ tests/charmhelpers/contrib/openstack/amulet/deployment.py 2016-02-11 15:44:28 +0000
648@@ -121,11 +121,12 @@
649
650 # Charms which should use the source config option
651 use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
652- 'ceph-osd', 'ceph-radosgw']
653+ 'ceph-osd', 'ceph-radosgw', 'ceph-mon']
654
655 # Charms which can not use openstack-origin, ie. many subordinates
656 no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
657- 'openvswitch-odl', 'neutron-api-odl', 'odl-controller']
658+ 'openvswitch-odl', 'neutron-api-odl', 'odl-controller',
659+ 'cinder-backup']
660
661 if self.openstack:
662 for svc in services:

Subscribers

People subscribed via source and target branches