Renamed tests->unit_tests, updated as appropriate, re-synced charm-helpers

This commit is contained in:
James Page 2013-09-20 16:52:45 +01:00
parent d6d2583133
commit 88bc369e69
12 changed files with 138 additions and 80 deletions

View File

@ -5,8 +5,7 @@ lint:
#@charm proof
sync:
@charm-helper-sync -c charm-helpers-sync.yaml
@charm-helper-sync -c charm-helpers.yaml
test:
#@nosetests -svd tests/
@$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage tests
@$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests

View File

@ -2,5 +2,6 @@ branch: lp:~openstack-charmers/charm-helpers/to_upstream
destination: hooks/charmhelpers
include:
- core
- fetch
- contrib.openstack
- contrib.hahelpers

View File

@ -28,8 +28,11 @@ from charmhelpers.core.hookenv import (
ERROR
)
from charmhelpers.core.host import (
from charmhelpers.fetch import (
apt_install,
)
from charmhelpers.core.host import (
mount,
mounts,
service_start,

View File

@ -7,7 +7,7 @@ from subprocess import (
)
from charmhelpers.core.host import (
from charmhelpers.fetch import (
apt_install,
filter_installed_packages,
)
@ -48,6 +48,13 @@ class OSContextError(Exception):
pass
def ensure_packages(packages):
'''Install but do not upgrade required plugin packages'''
required = filter_installed_packages(packages)
if required:
apt_install(required, fatal=True)
def context_complete(ctxt):
_missing = []
for k, v in ctxt.iteritems():
@ -103,9 +110,9 @@ class SharedDBContext(OSContextGenerator):
'database_user': self.user,
'database_password': passwd,
}
if not context_complete(ctxt):
return {}
return ctxt
if context_complete(ctxt):
return ctxt
return {}
class IdentityServiceContext(OSContextGenerator):
@ -134,9 +141,9 @@ class IdentityServiceContext(OSContextGenerator):
'service_protocol': 'http',
'auth_protocol': 'http',
}
if not context_complete(ctxt):
return {}
return ctxt
if context_complete(ctxt):
return ctxt
return {}
class AMQPContext(OSContextGenerator):
@ -157,20 +164,30 @@ class AMQPContext(OSContextGenerator):
for rid in relation_ids('amqp'):
for unit in related_units(rid):
if relation_get('clustered', rid=rid, unit=unit):
rabbitmq_host = relation_get('vip', rid=rid, unit=unit)
ctxt['clustered'] = True
ctxt['rabbitmq_host'] = relation_get('vip', rid=rid,
unit=unit)
else:
rabbitmq_host = relation_get('private-address',
rid=rid, unit=unit)
ctxt = {
'rabbitmq_host': rabbitmq_host,
ctxt['rabbitmq_host'] = relation_get('private-address',
rid=rid, unit=unit)
ctxt.update({
'rabbitmq_user': username,
'rabbitmq_password': relation_get('password', rid=rid,
unit=unit),
'rabbitmq_virtual_host': vhost,
}
})
if context_complete(ctxt):
# Sufficient information found = break out!
break
# Used for active/active rabbitmq >= grizzly
ctxt['rabbitmq_hosts'] = []
for unit in related_units(rid):
ctxt['rabbitmq_hosts'].append(relation_get('private-address',
rid=rid, unit=unit))
if not context_complete(ctxt):
return {}
return ctxt
else:
return ctxt
class CephContext(OSContextGenerator):
@ -178,21 +195,33 @@ class CephContext(OSContextGenerator):
def __call__(self):
'''This generates context for /etc/ceph/ceph.conf templates'''
log('Generating tmeplate context for ceph')
if not relation_ids('ceph'):
return {}
log('Generating template context for ceph')
mon_hosts = []
auth = None
key = None
for rid in relation_ids('ceph'):
for unit in related_units(rid):
mon_hosts.append(relation_get('private-address', rid=rid,
unit=unit))
auth = relation_get('auth', rid=rid, unit=unit)
key = relation_get('key', rid=rid, unit=unit)
ctxt = {
'mon_hosts': ' '.join(mon_hosts),
'auth': auth,
'key': key,
}
if not os.path.isdir('/etc/ceph'):
os.mkdir('/etc/ceph')
if not context_complete(ctxt):
return {}
ensure_packages(['ceph-common'])
return ctxt
@ -341,10 +370,7 @@ class NeutronContext(object):
return None
def _ensure_packages(self):
'''Install but do not upgrade required plugin packages'''
required = filter_installed_packages(self.packages)
if required:
apt_install(required, fatal=True)
ensure_packages(self.packages)
def _save_flag_file(self):
if self.network_manager == 'quantum':

View File

@ -1,6 +1,6 @@
import os
from charmhelpers.core.host import apt_install
from charmhelpers.fetch import apt_install
from charmhelpers.core.hookenv import (
log,

View File

@ -1,12 +1,12 @@
#!/usr/bin/python
# Common python helper functions used for OpenStack charms.
from collections import OrderedDict
import apt_pkg as apt
import subprocess
import os
import socket
import sys
from charmhelpers.core.hookenv import (
@ -17,6 +17,9 @@ from charmhelpers.core.hookenv import (
from charmhelpers.core.host import (
lsb_release,
)
from charmhelpers.fetch import (
apt_install,
)
@ -130,7 +133,7 @@ def get_os_codename_package(package, fatal=True):
e = 'Could not determine version of uninstalled package: %s' % package
error_out(e)
vers = apt.UpstreamVersion(pkg.current_ver.ver_str)
vers = apt.upstream_version(pkg.current_ver.ver_str)
try:
if 'swift' in pkg.name:
@ -290,3 +293,69 @@ def openstack_upgrade_available(package):
available_vers = get_os_version_install_source(src)
apt.init()
return apt.version_compare(available_vers, cur_vers) == 1
def is_ip(address):
"""
Returns True if address is a valid IP address.
"""
try:
# Test to see if already an IPv4 address
socket.inet_aton(address)
return True
except socket.error:
return False
def ns_query(address):
try:
import dns.resolver
except ImportError:
apt_install('python-dnspython')
import dns.resolver
if isinstance(address, dns.name.Name):
rtype = 'PTR'
elif isinstance(address, basestring):
rtype = 'A'
answers = dns.resolver.query(address, rtype)
if answers:
return str(answers[0])
return None
def get_host_ip(hostname):
"""
Resolves the IP for a given hostname, or returns
the input if it is already an IP.
"""
if is_ip(hostname):
return hostname
return ns_query(hostname)
def get_hostname(address):
"""
Resolves hostname for given IP, or returns the input
if it is already a hostname.
"""
if not is_ip(address):
return address
try:
import dns.reversename
except ImportError:
apt_install('python-dnspython')
import dns.reversename
rev = dns.reversename.from_address(address)
result = ns_query(rev)
if not result:
return None
# strip trailing .
if result.endswith('.'):
return result[:-1]
return result

View File

@ -5,7 +5,6 @@
# Nick Moffitt <nick.moffitt@canonical.com>
# Matthew Wedgwood <matthew.wedgwood@canonical.com>
import apt_pkg
import os
import pwd
import grp
@ -20,20 +19,22 @@ from hookenv import log
def service_start(service_name):
service('start', service_name)
return service('start', service_name)
def service_stop(service_name):
service('stop', service_name)
return service('stop', service_name)
def service_restart(service_name):
service('restart', service_name)
return service('restart', service_name)
def service_reload(service_name, restart_on_failure=False):
if not service('reload', service_name) and restart_on_failure:
service('restart', service_name)
service_result = service('reload', service_name)
if not service_result and restart_on_failure:
service_result = service('restart', service_name)
return service_result
def service(action, service_name):
@ -136,49 +137,6 @@ def write_file(path, content, owner='root', group='root', perms=0444):
target.write(content)
def filter_installed_packages(packages):
"""Returns a list of packages that require installation"""
apt_pkg.init()
cache = apt_pkg.Cache()
_pkgs = []
for package in packages:
try:
p = cache[package]
p.current_ver or _pkgs.append(package)
except KeyError:
log('Package {} has no installation candidate.'.format(package),
level='WARNING')
_pkgs.append(package)
return _pkgs
def apt_install(packages, options=None, fatal=False):
"""Install one or more packages"""
options = options or []
cmd = ['apt-get', '-y']
cmd.extend(options)
cmd.append('install')
if isinstance(packages, basestring):
cmd.append(packages)
else:
cmd.extend(packages)
log("Installing {} with options: {}".format(packages,
options))
if fatal:
subprocess.check_call(cmd)
else:
subprocess.call(cmd)
def apt_update(fatal=False):
"""Update local apt cache"""
cmd = ['apt-get', 'update']
if fatal:
subprocess.check_call(cmd)
else:
subprocess.call(cmd)
def mount(device, mountpoint, options=None, persist=False):
'''Mount a filesystem'''
cmd_args = ['mount']

View File

@ -34,10 +34,12 @@ from charmhelpers.core.hookenv import (
from charmhelpers.core.host import (
restart_on_change,
apt_install,
apt_update,
service_stop, )
from charmhelpers.fetch import (
apt_install,
apt_update,)
from charmhelpers.contrib.hahelpers.cluster import (
canonical_url,
eligible_leader,

View File

@ -7,7 +7,7 @@ import glance_contexts
from collections import OrderedDict
from charmhelpers.core.host import (
from charmhelpers.fetch import (
apt_install,
apt_update, )

View File

@ -1,6 +1,6 @@
from mock import call, patch, MagicMock
from tests.test_utils import CharmTestCase
from unit_tests.test_utils import CharmTestCase
import hooks.glance_utils as utils
@ -275,7 +275,7 @@ class GlanceRelationTests(CharmTestCase):
@patch.object(relations, 'configure_https')
@patch.object(relations, 'object_store_joined')
@patch.object(relations, 'CONFIGS')
def test_keystone_changed_no_object_store_relation(self, configs, object_store_joined, configure_https):
def test_keystone_changed_with_object_store_relation(self, configs, object_store_joined, configure_https):
configs.complete_contexts = MagicMock()
configs.complete_contexts.return_value = ['identity-service']
configs.write = MagicMock()