Added ceph broker support

This commit is contained in:
Edward Hope-Morley 2014-11-20 10:29:40 -06:00
parent 1d543f4674
commit 80a19dc6a1
4 changed files with 61 additions and 69 deletions

View File

@ -5,31 +5,32 @@ import sys
import json
from cinder_utils import (
ensure_ceph_pool,
register_configs,
restart_map,
set_ceph_env_variables,
PACKAGES
)
from cinder_contexts import CephSubordinateContext
from charmhelpers.core.hookenv import (
Hooks,
UnregisteredHookError,
config,
service_name,
relation_get,
relation_set,
relation_ids,
log
log,
INFO,
ERROR,
)
from cinder_contexts import CephSubordinateContext
from charmhelpers.fetch import apt_install, apt_update
from charmhelpers.core.host import restart_on_change
from charmhelpers.contrib.storage.linux.ceph import ensure_ceph_keyring
from charmhelpers.contrib.hahelpers.cluster import eligible_leader
from charmhelpers.contrib.storage.linux.ceph import (
ensure_ceph_keyring,
CephBrokerRq,
CephBrokerRsp,
)
from charmhelpers.payload.execd import execd_preinstall
hooks = Hooks()
@ -52,22 +53,39 @@ def ceph_joined():
@hooks.hook('ceph-relation-changed')
@restart_on_change(restart_map())
def ceph_changed():
def ceph_changed(relation_id=None):
if 'ceph' not in CONFIGS.complete_contexts():
log('ceph relation incomplete. Peer not ready?')
return
service = service_name()
if not ensure_ceph_keyring(service=service,
user='cinder', group='cinder'):
log('Could not create ceph keyring: peer not ready?')
return
settings = relation_get(rid=relation_id)
if settings and 'broker_rsp' in settings:
rsp = CephBrokerRsp(settings['broker_rsp'])
# Non-zero return code implies failure
if rsp.exit_code:
log("Ceph broker request failed (rc=%s, msg=%s)" %
(rsp.exit_code, rsp.exit_msg), level=ERROR)
return
log("Ceph broker request succeeded (rc=%s, msg=%s)" %
(rsp.exit_code, rsp.exit_msg), level=INFO)
CONFIGS.write_all()
set_ceph_env_variables(service=service)
for rid in relation_ids('storage-backend'):
storage_backend(rid)
else:
svc = service_name()
if not ensure_ceph_keyring(service=svc,
user='cinder', group='cinder'):
log('Could not create ceph keyring: peer not ready?')
else:
CONFIGS.write_all()
set_ceph_env_variables(service=svc)
if eligible_leader(None):
ensure_ceph_pool(service=svc,
replicas=config('ceph-osd-replication-count'))
for rid in relation_ids('storage-backend'):
storage_backend(rid)
rq = CephBrokerRq()
replicas = config('ceph-osd-replication-count')
rq.add_op_create_pool(name=service, replica_count=replicas)
for rid in relation_ids('ceph'):
relation_set(relation_id=rid, broker_req=rq.request)
log("Request(s) sent to Ceph broker (rid=%s)" % (rid))
@hooks.hook('ceph-relation-broken',

View File

@ -6,11 +6,6 @@ from charmhelpers.core.hookenv import (
service_name,
)
from charmhelpers.contrib.storage.linux.ceph import (
create_pool as ceph_create_pool,
pool_exists as ceph_pool_exists,
)
from charmhelpers.contrib.openstack import (
templating,
context,
@ -100,13 +95,6 @@ def restart_map():
return OrderedDict(_map)
def ensure_ceph_pool(service, replicas):
'''Creates a ceph pool for service if one does not exist'''
# TODO: Ditto about moving somewhere sharable.
if not ceph_pool_exists(service=service, name=service):
ceph_create_pool(service=service, name=service, replicas=replicas)
def set_ceph_env_variables(service):
# XXX: Horrid kludge to make cinder-volume use
# a different ceph username than admin

View File

@ -14,7 +14,6 @@ utils.register_configs = _register_configs
TO_PATCH = [
# cinder_utils
'ensure_ceph_pool',
'ensure_ceph_keyring',
'register_configs',
'restart_map',
@ -23,6 +22,7 @@ TO_PATCH = [
# charmhelpers.core.hookenv
'config',
'relation_ids',
'relation_get',
'relation_set',
'service_name',
'log',
@ -30,7 +30,6 @@ TO_PATCH = [
'apt_install',
'apt_update',
# charmhelpers.contrib.hahelpers.cluster_utils
'eligible_leader',
'execd_preinstall',
'CephSubordinateContext'
]
@ -41,41 +40,47 @@ class TestCinderHooks(CharmTestCase):
super(TestCinderHooks, self).setUp(hooks, TO_PATCH)
self.config.side_effect = self.test_config.get
def test_install(self):
@patch('charmhelpers.core.hookenv.config')
def test_install(self, mock_config):
hooks.hooks.execute(['hooks/install'])
self.assertTrue(self.execd_preinstall.called)
self.assertTrue(self.apt_update.called)
self.apt_install.assert_called_with(['ceph-common'], fatal=True)
@patch('charmhelpers.core.hookenv.config')
@patch('os.mkdir')
def test_ceph_joined(self, mkdir):
def test_ceph_joined(self, mkdir, mock_config):
'''It correctly prepares for a ceph changed hook'''
with patch('os.path.isdir') as isdir:
isdir.return_value = False
hooks.hooks.execute(['hooks/ceph-relation-joined'])
mkdir.assert_called_with('/etc/ceph')
def test_ceph_changed_no_key(self):
@patch('charmhelpers.core.hookenv.config')
def test_ceph_changed_no_key(self, mock_config):
'''It does nothing when ceph key is not available'''
self.CONFIGS.complete_contexts.return_value = ['']
hooks.hooks.execute(['hooks/ceph-relation-changed'])
m = 'ceph relation incomplete. Peer not ready?'
self.log.assert_called_with(m)
def test_ceph_changed(self):
@patch('charmhelpers.core.hookenv.config')
def test_ceph_changed(self, mock_config):
'''It ensures ceph assets created on ceph changed'''
self.CONFIGS.complete_contexts.return_value = ['ceph']
rsp = json.dumps({'exit_code': 0})
self.relation_get.return_value = {'broker_rsp': rsp}
self.service_name.return_value = 'cinder'
self.ensure_ceph_keyring.return_value = True
hooks.hooks.execute(['hooks/ceph-relation-changed'])
self.ensure_ceph_keyring.assert_called_with(service='cinder',
user='cinder',
group='cinder')
self.ensure_ceph_pool.assert_called_with(service='cinder', replicas=3)
self.assertTrue(self.CONFIGS.write_all.called)
self.set_ceph_env_variables.assert_called_with(service='cinder')
def test_ceph_changed_no_keys(self):
@patch('charmhelpers.core.hookenv.config')
def test_ceph_changed_no_keys(self, mock_config):
'''It ensures ceph assets created on ceph changed'''
self.CONFIGS.complete_contexts.return_value = ['ceph']
self.service_name.return_value = 'cinder'
@ -86,16 +91,9 @@ class TestCinderHooks(CharmTestCase):
self.assertTrue(self.log.called)
self.assertFalse(self.CONFIGS.write_all.called)
def test_ceph_changed_no_leadership(self):
'''It does not attempt to create ceph pool if not leader'''
self.eligible_leader.return_value = False
self.service_name.return_value = 'cinder'
self.ensure_ceph_keyring.return_value = True
hooks.hooks.execute(['hooks/ceph-relation-changed'])
self.assertFalse(self.ensure_ceph_pool.called)
@patch('charmhelpers.core.hookenv.config')
@patch.object(hooks, 'storage_backend')
def test_upgrade_charm_related(self, _storage_backend):
def test_upgrade_charm_related(self, _storage_backend, mock_config):
self.CONFIGS.complete_contexts.return_value = ['ceph']
self.relation_ids.return_value = ['ceph:1']
hooks.hooks.execute(['hooks/upgrade-charm'])
@ -103,18 +101,21 @@ class TestCinderHooks(CharmTestCase):
assert self.CONFIGS.write_all.called
assert self.set_ceph_env_variables.called
@patch('charmhelpers.core.hookenv.config')
@patch.object(hooks, 'storage_backend')
def test_storage_backend_changed(self, _storage_backend):
def test_storage_backend_changed(self, _storage_backend, mock_config):
hooks.hooks.execute(['hooks/storage-backend-relation-changed'])
_storage_backend.assert_called_with()
def test_storage_backend_joined_no_ceph(self):
@patch('charmhelpers.core.hookenv.config')
def test_storage_backend_joined_no_ceph(self, mock_config):
self.CONFIGS.complete_contexts.return_value = []
hooks.hooks.execute(['hooks/storage-backend-relation-joined'])
assert self.log.called
assert not self.relation_set.called
def test_storage_backend_joined_ceph(self):
@patch('charmhelpers.core.hookenv.config')
def test_storage_backend_joined_ceph(self, mock_config):
def func():
return {'test': 1}
self.CONFIGS.complete_contexts.return_value = ['ceph']

View File

@ -10,9 +10,6 @@ TO_PATCH = [
# helpers.core.hookenv
'relation_ids',
'service_name',
# ceph utils
'ceph_create_pool',
'ceph_pool_exists',
# storage_utils
'get_os_codename_package',
'templating',
@ -32,18 +29,6 @@ class TestCinderUtils(CharmTestCase):
super(TestCinderUtils, self).setUp(cinder_utils, TO_PATCH)
self.service_name.return_value = 'cinder-ceph'
def test_ensure_ceph_pool(self):
self.ceph_pool_exists.return_value = False
cinder_utils.ensure_ceph_pool(service='cinder', replicas=3)
self.ceph_create_pool.assert_called_with(service='cinder',
name='cinder',
replicas=3)
def test_ensure_ceph_pool_already_exists(self):
self.ceph_pool_exists.return_value = True
cinder_utils.ensure_ceph_pool(service='cinder', replicas=3)
self.assertFalse(self.ceph_create_pool.called)
@patch('os.path.exists')
def test_register_configs_ceph(self, exists):
exists.return_value = True