Merge lp:~hopem/charms/trusty/cinder-ceph/lp1535062 into lp:~openstack-charmers-archive/charms/trusty/cinder-ceph/next

Proposed by Edward Hope-Morley
Status: Merged
Merged at revision: 52
Proposed branch: lp:~hopem/charms/trusty/cinder-ceph/lp1535062
Merge into: lp:~openstack-charmers-archive/charms/trusty/cinder-ceph/next
Diff against target: 638 lines (+185/-114)
5 files modified
hooks/charmhelpers/contrib/openstack/context.py (+12/-2)
hooks/charmhelpers/contrib/openstack/templates/haproxy.cfg (+3/-2)
hooks/charmhelpers/contrib/openstack/utils.py (+95/-63)
hooks/charmhelpers/core/host.py (+73/-42)
hooks/charmhelpers/fetch/giturl.py (+2/-5)
To merge this branch: bzr merge lp:~hopem/charms/trusty/cinder-ceph/lp1535062
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+282880@code.launchpad.net
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #17513 cinder-ceph-next for hopem mp282880
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #16362 cinder-ceph-next for hopem mp282880
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #8874 cinder-ceph-next for hopem mp282880
    AMULET OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'hooks/charmhelpers/contrib/openstack/context.py'
--- hooks/charmhelpers/contrib/openstack/context.py 2016-01-04 21:26:40 +0000
+++ hooks/charmhelpers/contrib/openstack/context.py 2016-01-17 21:20:37 +0000
@@ -57,6 +57,7 @@
57 get_nic_hwaddr,57 get_nic_hwaddr,
58 mkdir,58 mkdir,
59 write_file,59 write_file,
60 pwgen,
60)61)
61from charmhelpers.contrib.hahelpers.cluster import (62from charmhelpers.contrib.hahelpers.cluster import (
62 determine_apache_port,63 determine_apache_port,
@@ -87,6 +88,8 @@
87 is_bridge_member,88 is_bridge_member,
88)89)
89from charmhelpers.contrib.openstack.utils import get_host_ip90from charmhelpers.contrib.openstack.utils import get_host_ip
91from charmhelpers.core.unitdata import kv
92
90CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'93CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
91ADDRESS_TYPES = ['admin', 'internal', 'public']94ADDRESS_TYPES = ['admin', 'internal', 'public']
9295
@@ -636,11 +639,18 @@
636 ctxt['ipv6'] = True639 ctxt['ipv6'] = True
637 ctxt['local_host'] = 'ip6-localhost'640 ctxt['local_host'] = 'ip6-localhost'
638 ctxt['haproxy_host'] = '::'641 ctxt['haproxy_host'] = '::'
639 ctxt['stat_port'] = ':::8888'
640 else:642 else:
641 ctxt['local_host'] = '127.0.0.1'643 ctxt['local_host'] = '127.0.0.1'
642 ctxt['haproxy_host'] = '0.0.0.0'644 ctxt['haproxy_host'] = '0.0.0.0'
643 ctxt['stat_port'] = ':8888'645
646 ctxt['stat_port'] = '8888'
647
648 db = kv()
649 ctxt['stat_password'] = db.get('stat-password')
650 if not ctxt['stat_password']:
651 ctxt['stat_password'] = db.set('stat-password',
652 pwgen(32))
653 db.flush()
644654
645 for frontend in cluster_hosts:655 for frontend in cluster_hosts:
646 if (len(cluster_hosts[frontend]['backends']) > 1 or656 if (len(cluster_hosts[frontend]['backends']) > 1 or
647657
=== modified file 'hooks/charmhelpers/contrib/openstack/templates/haproxy.cfg'
--- hooks/charmhelpers/contrib/openstack/templates/haproxy.cfg 2016-01-04 21:26:40 +0000
+++ hooks/charmhelpers/contrib/openstack/templates/haproxy.cfg 2016-01-17 21:20:37 +0000
@@ -33,13 +33,14 @@
33 timeout server 3000033 timeout server 30000
34{%- endif %}34{%- endif %}
3535
36listen stats {{ stat_port }}36listen stats
37 bind {{ local_host }}:{{ stat_port }}
37 mode http38 mode http
38 stats enable39 stats enable
39 stats hide-version40 stats hide-version
40 stats realm Haproxy\ Statistics41 stats realm Haproxy\ Statistics
41 stats uri /42 stats uri /
42 stats auth admin:password43 stats auth admin:{{ stat_password }}
4344
44{% if frontends -%}45{% if frontends -%}
45{% for service, ports in service_ports.items() -%}46{% for service, ports in service_ports.items() -%}
4647
=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
--- hooks/charmhelpers/contrib/openstack/utils.py 2016-01-04 21:26:40 +0000
+++ hooks/charmhelpers/contrib/openstack/utils.py 2016-01-17 21:20:37 +0000
@@ -103,68 +103,67 @@
103 ('2016.1', 'mitaka'),103 ('2016.1', 'mitaka'),
104])104])
105105
106# The ugly duckling106# The ugly duckling - must list releases oldest to newest
107SWIFT_CODENAMES = OrderedDict([107SWIFT_CODENAMES = OrderedDict([
108 ('1.4.3', 'diablo'),108 ('diablo',
109 ('1.4.8', 'essex'),109 ['1.4.3']),
110 ('1.7.4', 'folsom'),110 ('essex',
111 ('1.8.0', 'grizzly'),111 ['1.4.8']),
112 ('1.7.7', 'grizzly'),112 ('folsom',
113 ('1.7.6', 'grizzly'),113 ['1.7.4']),
114 ('1.10.0', 'havana'),114 ('grizzly',
115 ('1.9.1', 'havana'),115 ['1.7.6', '1.7.7', '1.8.0']),
116 ('1.9.0', 'havana'),116 ('havana',
117 ('1.13.1', 'icehouse'),117 ['1.9.0', '1.9.1', '1.10.0']),
118 ('1.13.0', 'icehouse'),118 ('icehouse',
119 ('1.12.0', 'icehouse'),119 ['1.11.0', '1.12.0', '1.13.0', '1.13.1']),
120 ('1.11.0', 'icehouse'),120 ('juno',
121 ('2.0.0', 'juno'),121 ['2.0.0', '2.1.0', '2.2.0']),
122 ('2.1.0', 'juno'),122 ('kilo',
123 ('2.2.0', 'juno'),123 ['2.2.1', '2.2.2']),
124 ('2.2.1', 'kilo'),124 ('liberty',
125 ('2.2.2', 'kilo'),125 ['2.3.0', '2.4.0', '2.5.0']),
126 ('2.3.0', 'liberty'),126 ('mitaka',
127 ('2.4.0', 'liberty'),127 ['2.5.0']),
128 ('2.5.0', 'liberty'),
129])128])
130129
131# >= Liberty version->codename mapping130# >= Liberty version->codename mapping
132PACKAGE_CODENAMES = {131PACKAGE_CODENAMES = {
133 'nova-common': OrderedDict([132 'nova-common': OrderedDict([
134 ('12.0.0', 'liberty'),133 ('12.0', 'liberty'),
135 ('13.0.0', 'mitaka'),134 ('13.0', 'mitaka'),
136 ]),135 ]),
137 'neutron-common': OrderedDict([136 'neutron-common': OrderedDict([
138 ('7.0.0', 'liberty'),137 ('7.0', 'liberty'),
139 ('8.0.0', 'mitaka'),138 ('8.0', 'mitaka'),
140 ]),139 ]),
141 'cinder-common': OrderedDict([140 'cinder-common': OrderedDict([
142 ('7.0.0', 'liberty'),141 ('7.0', 'liberty'),
143 ('8.0.0', 'mitaka'),142 ('8.0', 'mitaka'),
144 ]),143 ]),
145 'keystone': OrderedDict([144 'keystone': OrderedDict([
146 ('8.0.0', 'liberty'),145 ('8.0', 'liberty'),
147 ('9.0.0', 'mitaka'),146 ('9.0', 'mitaka'),
148 ]),147 ]),
149 'horizon-common': OrderedDict([148 'horizon-common': OrderedDict([
150 ('8.0.0', 'liberty'),149 ('8.0', 'liberty'),
151 ('9.0.0', 'mitaka'),150 ('9.0', 'mitaka'),
152 ]),151 ]),
153 'ceilometer-common': OrderedDict([152 'ceilometer-common': OrderedDict([
154 ('5.0.0', 'liberty'),153 ('5.0', 'liberty'),
155 ('6.0.0', 'mitaka'),154 ('6.0', 'mitaka'),
156 ]),155 ]),
157 'heat-common': OrderedDict([156 'heat-common': OrderedDict([
158 ('5.0.0', 'liberty'),157 ('5.0', 'liberty'),
159 ('6.0.0', 'mitaka'),158 ('6.0', 'mitaka'),
160 ]),159 ]),
161 'glance-common': OrderedDict([160 'glance-common': OrderedDict([
162 ('11.0.0', 'liberty'),161 ('11.0', 'liberty'),
163 ('12.0.0', 'mitaka'),162 ('12.0', 'mitaka'),
164 ]),163 ]),
165 'openstack-dashboard': OrderedDict([164 'openstack-dashboard': OrderedDict([
166 ('8.0.0', 'liberty'),165 ('8.0', 'liberty'),
167 ('9.0.0', 'mitaka'),166 ('9.0', 'mitaka'),
168 ]),167 ]),
169}168}
170169
@@ -227,6 +226,33 @@
227 error_out(e)226 error_out(e)
228227
229228
229def get_os_version_codename_swift(codename):
230 '''Determine OpenStack version number of swift from codename.'''
231 for k, v in six.iteritems(SWIFT_CODENAMES):
232 if k == codename:
233 return v[-1]
234 e = 'Could not derive swift version for '\
235 'codename: %s' % codename
236 error_out(e)
237
238
239def get_swift_codename(version):
240 '''Determine OpenStack codename that corresponds to swift version.'''
241 codenames = [k for k, v in six.iteritems(SWIFT_CODENAMES) if version in v]
242 if len(codenames) > 1:
243 # If more than one release codename contains this version we determine
244 # the actual codename based on the highest available install source.
245 for codename in reversed(codenames):
246 releases = UBUNTU_OPENSTACK_RELEASE
247 release = [k for k, v in six.iteritems(releases) if codename in v]
248 ret = subprocess.check_output(['apt-cache', 'policy', 'swift'])
249 if codename in ret or release[0] in ret:
250 return codename
251 elif len(codenames) == 1:
252 return codenames[0]
253 return None
254
255
230def get_os_codename_package(package, fatal=True):256def get_os_codename_package(package, fatal=True):
231 '''Derive OpenStack release codename from an installed package.'''257 '''Derive OpenStack release codename from an installed package.'''
232 import apt_pkg as apt258 import apt_pkg as apt
@@ -251,7 +277,14 @@
251 error_out(e)277 error_out(e)
252278
253 vers = apt.upstream_version(pkg.current_ver.ver_str)279 vers = apt.upstream_version(pkg.current_ver.ver_str)
254 match = re.match('^(\d+)\.(\d+)\.(\d+)', vers)280 if 'swift' in pkg.name:
281 # Fully x.y.z match for swift versions
282 match = re.match('^(\d+)\.(\d+)\.(\d+)', vers)
283 else:
284 # x.y match only for 20XX.X
285 # and ignore patch level for other packages
286 match = re.match('^(\d+)\.(\d+)', vers)
287
255 if match:288 if match:
256 vers = match.group(0)289 vers = match.group(0)
257290
@@ -263,13 +296,8 @@
263 # < Liberty co-ordinated project versions296 # < Liberty co-ordinated project versions
264 try:297 try:
265 if 'swift' in pkg.name:298 if 'swift' in pkg.name:
266 swift_vers = vers[:5]299 return get_swift_codename(vers)
267 if swift_vers not in SWIFT_CODENAMES:
268 # Deal with 1.10.0 upward
269 swift_vers = vers[:6]
270 return SWIFT_CODENAMES[swift_vers]
271 else:300 else:
272 vers = vers[:6]
273 return OPENSTACK_CODENAMES[vers]301 return OPENSTACK_CODENAMES[vers]
274 except KeyError:302 except KeyError:
275 if not fatal:303 if not fatal:
@@ -287,12 +315,14 @@
287315
288 if 'swift' in pkg:316 if 'swift' in pkg:
289 vers_map = SWIFT_CODENAMES317 vers_map = SWIFT_CODENAMES
318 for cname, version in six.iteritems(vers_map):
319 if cname == codename:
320 return version[-1]
290 else:321 else:
291 vers_map = OPENSTACK_CODENAMES322 vers_map = OPENSTACK_CODENAMES
292323 for version, cname in six.iteritems(vers_map):
293 for version, cname in six.iteritems(vers_map):324 if cname == codename:
294 if cname == codename:325 return version
295 return version
296 # e = "Could not determine OpenStack version for package: %s" % pkg326 # e = "Could not determine OpenStack version for package: %s" % pkg
297 # error_out(e)327 # error_out(e)
298328
@@ -458,11 +488,16 @@
458 cur_vers = get_os_version_package(package)488 cur_vers = get_os_version_package(package)
459 if "swift" in package:489 if "swift" in package:
460 codename = get_os_codename_install_source(src)490 codename = get_os_codename_install_source(src)
461 available_vers = get_os_version_codename(codename, SWIFT_CODENAMES)491 avail_vers = get_os_version_codename_swift(codename)
462 else:492 else:
463 available_vers = get_os_version_install_source(src)493 avail_vers = get_os_version_install_source(src)
464 apt.init()494 apt.init()
465 return apt.version_compare(available_vers, cur_vers) == 1495 if "swift" in package:
496 major_cur_vers = cur_vers.split('.', 1)[0]
497 major_avail_vers = avail_vers.split('.', 1)[0]
498 major_diff = apt.version_compare(major_avail_vers, major_cur_vers)
499 return avail_vers > cur_vers and (major_diff == 1 or major_diff == 0)
500 return apt.version_compare(avail_vers, cur_vers) == 1
466501
467502
468def ensure_block_device(block_device):503def ensure_block_device(block_device):
@@ -591,7 +626,7 @@
591 return yaml.load(projects_yaml)626 return yaml.load(projects_yaml)
592627
593628
594def git_clone_and_install(projects_yaml, core_project, depth=1):629def git_clone_and_install(projects_yaml, core_project):
595 """630 """
596 Clone/install all specified OpenStack repositories.631 Clone/install all specified OpenStack repositories.
597632
@@ -641,6 +676,9 @@
641 for p in projects['repositories']:676 for p in projects['repositories']:
642 repo = p['repository']677 repo = p['repository']
643 branch = p['branch']678 branch = p['branch']
679 depth = '1'
680 if 'depth' in p.keys():
681 depth = p['depth']
644 if p['name'] == 'requirements':682 if p['name'] == 'requirements':
645 repo_dir = _git_clone_and_install_single(repo, branch, depth,683 repo_dir = _git_clone_and_install_single(repo, branch, depth,
646 parent_dir, http_proxy,684 parent_dir, http_proxy,
@@ -685,19 +723,13 @@
685 """723 """
686 Clone and install a single git repository.724 Clone and install a single git repository.
687 """725 """
688 dest_dir = os.path.join(parent_dir, os.path.basename(repo))
689
690 if not os.path.exists(parent_dir):726 if not os.path.exists(parent_dir):
691 juju_log('Directory already exists at {}. '727 juju_log('Directory already exists at {}. '
692 'No need to create directory.'.format(parent_dir))728 'No need to create directory.'.format(parent_dir))
693 os.mkdir(parent_dir)729 os.mkdir(parent_dir)
694730
695 if not os.path.exists(dest_dir):731 juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))
696 juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))732 repo_dir = install_remote(repo, dest=parent_dir, branch=branch, depth=depth)
697 repo_dir = install_remote(repo, dest=parent_dir, branch=branch,
698 depth=depth)
699 else:
700 repo_dir = dest_dir
701733
702 venv = os.path.join(parent_dir, 'venv')734 venv = os.path.join(parent_dir, 'venv')
703735
704736
=== modified file 'hooks/charmhelpers/core/host.py'
--- hooks/charmhelpers/core/host.py 2016-01-04 21:26:40 +0000
+++ hooks/charmhelpers/core/host.py 2016-01-17 21:20:37 +0000
@@ -72,7 +72,9 @@
72 stopped = service_stop(service_name)72 stopped = service_stop(service_name)
73 upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))73 upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
74 sysv_file = os.path.join(initd_dir, service_name)74 sysv_file = os.path.join(initd_dir, service_name)
75 if os.path.exists(upstart_file):75 if init_is_systemd():
76 service('disable', service_name)
77 elif os.path.exists(upstart_file):
76 override_path = os.path.join(78 override_path = os.path.join(
77 init_dir, '{}.override'.format(service_name))79 init_dir, '{}.override'.format(service_name))
78 with open(override_path, 'w') as fh:80 with open(override_path, 'w') as fh:
@@ -80,9 +82,9 @@
80 elif os.path.exists(sysv_file):82 elif os.path.exists(sysv_file):
81 subprocess.check_call(["update-rc.d", service_name, "disable"])83 subprocess.check_call(["update-rc.d", service_name, "disable"])
82 else:84 else:
83 # XXX: Support SystemD too
84 raise ValueError(85 raise ValueError(
85 "Unable to detect {0} as either Upstart {1} or SysV {2}".format(86 "Unable to detect {0} as SystemD, Upstart {1} or"
87 " SysV {2}".format(
86 service_name, upstart_file, sysv_file))88 service_name, upstart_file, sysv_file))
87 return stopped89 return stopped
8890
@@ -94,7 +96,9 @@
94 Reenable starting again at boot. Start the service"""96 Reenable starting again at boot. Start the service"""
95 upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))97 upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
96 sysv_file = os.path.join(initd_dir, service_name)98 sysv_file = os.path.join(initd_dir, service_name)
97 if os.path.exists(upstart_file):99 if init_is_systemd():
100 service('enable', service_name)
101 elif os.path.exists(upstart_file):
98 override_path = os.path.join(102 override_path = os.path.join(
99 init_dir, '{}.override'.format(service_name))103 init_dir, '{}.override'.format(service_name))
100 if os.path.exists(override_path):104 if os.path.exists(override_path):
@@ -102,9 +106,9 @@
102 elif os.path.exists(sysv_file):106 elif os.path.exists(sysv_file):
103 subprocess.check_call(["update-rc.d", service_name, "enable"])107 subprocess.check_call(["update-rc.d", service_name, "enable"])
104 else:108 else:
105 # XXX: Support SystemD too
106 raise ValueError(109 raise ValueError(
107 "Unable to detect {0} as either Upstart {1} or SysV {2}".format(110 "Unable to detect {0} as SystemD, Upstart {1} or"
111 " SysV {2}".format(
108 service_name, upstart_file, sysv_file))112 service_name, upstart_file, sysv_file))
109113
110 started = service_running(service_name)114 started = service_running(service_name)
@@ -115,23 +119,29 @@
115119
116def service(action, service_name):120def service(action, service_name):
117 """Control a system service"""121 """Control a system service"""
118 cmd = ['service', service_name, action]122 if init_is_systemd():
123 cmd = ['systemctl', action, service_name]
124 else:
125 cmd = ['service', service_name, action]
119 return subprocess.call(cmd) == 0126 return subprocess.call(cmd) == 0
120127
121128
122def service_running(service):129def service_running(service_name):
123 """Determine whether a system service is running"""130 """Determine whether a system service is running"""
124 try:131 if init_is_systemd():
125 output = subprocess.check_output(132 return service('is-active', service_name)
126 ['service', service, 'status'],
127 stderr=subprocess.STDOUT).decode('UTF-8')
128 except subprocess.CalledProcessError:
129 return False
130 else:133 else:
131 if ("start/running" in output or "is running" in output):134 try:
132 return True135 output = subprocess.check_output(
133 else:136 ['service', service_name, 'status'],
137 stderr=subprocess.STDOUT).decode('UTF-8')
138 except subprocess.CalledProcessError:
134 return False139 return False
140 else:
141 if ("start/running" in output or "is running" in output):
142 return True
143 else:
144 return False
135145
136146
137def service_available(service_name):147def service_available(service_name):
@@ -146,10 +156,17 @@
146 return True156 return True
147157
148158
159SYSTEMD_SYSTEM = '/run/systemd/system'
160
161
162def init_is_systemd():
163 """Return True if the host system uses systemd, False otherwise."""
164 return os.path.isdir(SYSTEMD_SYSTEM)
165
166
149def adduser(username, password=None, shell='/bin/bash', system_user=False,167def adduser(username, password=None, shell='/bin/bash', system_user=False,
150 primary_group=None, secondary_groups=None):168 primary_group=None, secondary_groups=None):
151 """169 """Add a user to the system.
152 Add a user to the system.
153170
154 Will log but otherwise succeed if the user already exists.171 Will log but otherwise succeed if the user already exists.
155172
@@ -157,7 +174,7 @@
157 :param str password: Password for user; if ``None``, create a system user174 :param str password: Password for user; if ``None``, create a system user
158 :param str shell: The default shell for the user175 :param str shell: The default shell for the user
159 :param bool system_user: Whether to create a login or system user176 :param bool system_user: Whether to create a login or system user
160 :param str primary_group: Primary group for user; defaults to their username177 :param str primary_group: Primary group for user; defaults to username
161 :param list secondary_groups: Optional list of additional groups178 :param list secondary_groups: Optional list of additional groups
162179
163 :returns: The password database entry struct, as returned by `pwd.getpwnam`180 :returns: The password database entry struct, as returned by `pwd.getpwnam`
@@ -283,14 +300,12 @@
283300
284301
285def fstab_remove(mp):302def fstab_remove(mp):
286 """Remove the given mountpoint entry from /etc/fstab303 """Remove the given mountpoint entry from /etc/fstab"""
287 """
288 return Fstab.remove_by_mountpoint(mp)304 return Fstab.remove_by_mountpoint(mp)
289305
290306
291def fstab_add(dev, mp, fs, options=None):307def fstab_add(dev, mp, fs, options=None):
292 """Adds the given device entry to the /etc/fstab file308 """Adds the given device entry to the /etc/fstab file"""
293 """
294 return Fstab.add(dev, mp, fs, options=options)309 return Fstab.add(dev, mp, fs, options=options)
295310
296311
@@ -346,8 +361,7 @@
346361
347362
348def file_hash(path, hash_type='md5'):363def file_hash(path, hash_type='md5'):
349 """364 """Generate a hash checksum of the contents of 'path' or None if not found.
350 Generate a hash checksum of the contents of 'path' or None if not found.
351365
352 :param str hash_type: Any hash alrgorithm supported by :mod:`hashlib`,366 :param str hash_type: Any hash alrgorithm supported by :mod:`hashlib`,
353 such as md5, sha1, sha256, sha512, etc.367 such as md5, sha1, sha256, sha512, etc.
@@ -362,10 +376,9 @@
362376
363377
364def path_hash(path):378def path_hash(path):
365 """379 """Generate a hash checksum of all files matching 'path'. Standard
366 Generate a hash checksum of all files matching 'path'. Standard wildcards380 wildcards like '*' and '?' are supported, see documentation for the 'glob'
367 like '*' and '?' are supported, see documentation for the 'glob' module for381 module for more information.
368 more information.
369382
370 :return: dict: A { filename: hash } dictionary for all matched files.383 :return: dict: A { filename: hash } dictionary for all matched files.
371 Empty if none found.384 Empty if none found.
@@ -377,8 +390,7 @@
377390
378391
379def check_hash(path, checksum, hash_type='md5'):392def check_hash(path, checksum, hash_type='md5'):
380 """393 """Validate a file using a cryptographic checksum.
381 Validate a file using a cryptographic checksum.
382394
383 :param str checksum: Value of the checksum used to validate the file.395 :param str checksum: Value of the checksum used to validate the file.
384 :param str hash_type: Hash algorithm used to generate `checksum`.396 :param str hash_type: Hash algorithm used to generate `checksum`.
@@ -393,6 +405,7 @@
393405
394406
395class ChecksumError(ValueError):407class ChecksumError(ValueError):
408 """A class derived from Value error to indicate the checksum failed."""
396 pass409 pass
397410
398411
@@ -498,7 +511,7 @@
498511
499512
500def list_nics(nic_type=None):513def list_nics(nic_type=None):
501 '''Return a list of nics of given type(s)'''514 """Return a list of nics of given type(s)"""
502 if isinstance(nic_type, six.string_types):515 if isinstance(nic_type, six.string_types):
503 int_types = [nic_type]516 int_types = [nic_type]
504 else:517 else:
@@ -540,12 +553,13 @@
540553
541554
542def set_nic_mtu(nic, mtu):555def set_nic_mtu(nic, mtu):
543 '''Set MTU on a network interface'''556 """Set the Maximum Transmission Unit (MTU) on a network interface."""
544 cmd = ['ip', 'link', 'set', nic, 'mtu', mtu]557 cmd = ['ip', 'link', 'set', nic, 'mtu', mtu]
545 subprocess.check_call(cmd)558 subprocess.check_call(cmd)
546559
547560
548def get_nic_mtu(nic):561def get_nic_mtu(nic):
562 """Return the Maximum Transmission Unit (MTU) for a network interface."""
549 cmd = ['ip', 'addr', 'show', nic]563 cmd = ['ip', 'addr', 'show', nic]
550 ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')564 ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')
551 mtu = ""565 mtu = ""
@@ -557,6 +571,7 @@
557571
558572
559def get_nic_hwaddr(nic):573def get_nic_hwaddr(nic):
574 """Return the Media Access Control (MAC) for a network interface."""
560 cmd = ['ip', '-o', '-0', 'addr', 'show', nic]575 cmd = ['ip', '-o', '-0', 'addr', 'show', nic]
561 ip_output = subprocess.check_output(cmd).decode('UTF-8')576 ip_output = subprocess.check_output(cmd).decode('UTF-8')
562 hwaddr = ""577 hwaddr = ""
@@ -567,7 +582,7 @@
567582
568583
569def cmp_pkgrevno(package, revno, pkgcache=None):584def cmp_pkgrevno(package, revno, pkgcache=None):
570 '''Compare supplied revno with the revno of the installed package585 """Compare supplied revno with the revno of the installed package
571586
572 * 1 => Installed revno is greater than supplied arg587 * 1 => Installed revno is greater than supplied arg
573 * 0 => Installed revno is the same as supplied arg588 * 0 => Installed revno is the same as supplied arg
@@ -576,7 +591,7 @@
576 This function imports apt_cache function from charmhelpers.fetch if591 This function imports apt_cache function from charmhelpers.fetch if
577 the pkgcache argument is None. Be sure to add charmhelpers.fetch if592 the pkgcache argument is None. Be sure to add charmhelpers.fetch if
578 you call this function, or pass an apt_pkg.Cache() instance.593 you call this function, or pass an apt_pkg.Cache() instance.
579 '''594 """
580 import apt_pkg595 import apt_pkg
581 if not pkgcache:596 if not pkgcache:
582 from charmhelpers.fetch import apt_cache597 from charmhelpers.fetch import apt_cache
@@ -586,19 +601,27 @@
586601
587602
588@contextmanager603@contextmanager
589def chdir(d):604def chdir(directory):
605 """Change the current working directory to a different directory for a code
606 block and return the previous directory after the block exits. Useful to
607 run commands from a specificed directory.
608
609 :param str directory: The directory path to change to for this context.
610 """
590 cur = os.getcwd()611 cur = os.getcwd()
591 try:612 try:
592 yield os.chdir(d)613 yield os.chdir(directory)
593 finally:614 finally:
594 os.chdir(cur)615 os.chdir(cur)
595616
596617
597def chownr(path, owner, group, follow_links=True, chowntopdir=False):618def chownr(path, owner, group, follow_links=True, chowntopdir=False):
598 """619 """Recursively change user and group ownership of files and directories
599 Recursively change user and group ownership of files and directories
600 in given path. Doesn't chown path itself by default, only its children.620 in given path. Doesn't chown path itself by default, only its children.
601621
622 :param str path: The string path to start changing ownership.
623 :param str owner: The owner string to use when looking up the uid.
624 :param str group: The group string to use when looking up the gid.
602 :param bool follow_links: Also Chown links if True625 :param bool follow_links: Also Chown links if True
603 :param bool chowntopdir: Also chown path itself if True626 :param bool chowntopdir: Also chown path itself if True
604 """627 """
@@ -622,15 +645,23 @@
622645
623646
624def lchownr(path, owner, group):647def lchownr(path, owner, group):
648 """Recursively change user and group ownership of files and directories
649 in a given path, not following symbolic links. See the documentation for
650 'os.lchown' for more information.
651
652 :param str path: The string path to start changing ownership.
653 :param str owner: The owner string to use when looking up the uid.
654 :param str group: The group string to use when looking up the gid.
655 """
625 chownr(path, owner, group, follow_links=False)656 chownr(path, owner, group, follow_links=False)
626657
627658
628def get_total_ram():659def get_total_ram():
629 '''The total amount of system RAM in bytes.660 """The total amount of system RAM in bytes.
630661
631 This is what is reported by the OS, and may be overcommitted when662 This is what is reported by the OS, and may be overcommitted when
632 there are multiple containers hosted on the same machine.663 there are multiple containers hosted on the same machine.
633 '''664 """
634 with open('/proc/meminfo', 'r') as f:665 with open('/proc/meminfo', 'r') as f:
635 for line in f.readlines():666 for line in f.readlines():
636 if line:667 if line:
637668
=== modified file 'hooks/charmhelpers/fetch/giturl.py'
--- hooks/charmhelpers/fetch/giturl.py 2016-01-04 21:26:40 +0000
+++ hooks/charmhelpers/fetch/giturl.py 2016-01-17 21:20:37 +0000
@@ -22,7 +22,6 @@
22 filter_installed_packages,22 filter_installed_packages,
23 apt_install,23 apt_install,
24)24)
25from charmhelpers.core.host import mkdir
2625
27if filter_installed_packages(['git']) != []:26if filter_installed_packages(['git']) != []:
28 apt_install(['git'])27 apt_install(['git'])
@@ -50,8 +49,8 @@
50 cmd = ['git', '-C', dest, 'pull', source, branch]49 cmd = ['git', '-C', dest, 'pull', source, branch]
51 else:50 else:
52 cmd = ['git', 'clone', source, dest, '--branch', branch]51 cmd = ['git', 'clone', source, dest, '--branch', branch]
53 if depth:52 if depth:
54 cmd.extend(['--depth', depth])53 cmd.extend(['--depth', depth])
55 check_call(cmd)54 check_call(cmd)
5655
57 def install(self, source, branch="master", dest=None, depth=None):56 def install(self, source, branch="master", dest=None, depth=None):
@@ -62,8 +61,6 @@
62 else:61 else:
63 dest_dir = os.path.join(os.environ.get('CHARM_DIR'), "fetched",62 dest_dir = os.path.join(os.environ.get('CHARM_DIR'), "fetched",
64 branch_name)63 branch_name)
65 if not os.path.exists(dest_dir):
66 mkdir(dest_dir, perms=0o755)
67 try:64 try:
68 self.clone(source, dest_dir, branch, depth)65 self.clone(source, dest_dir, branch, depth)
69 except OSError as e:66 except OSError as e:

Subscribers

People subscribed via source and target branches