Add memcache support for ipv4

charmhelpers was recently updated to support ipv4 for
MemcacheContext if no ipv6 network is available.  This change adds the
same functionality to the charms.openstack library, which means that
it can be used (automatically) by charms.openstack based charms.
e.g. designate, manila, barbican, etc.

Related-Bug: #1678124
Change-Id: Ice62ff85662b1c6039ea8db269d52e70ec394f09
This commit is contained in:
Alex Kavanagh 2017-05-04 19:41:54 +01:00
parent 580ae528be
commit f15bb1f01f
2 changed files with 141 additions and 40 deletions

View File

@ -801,32 +801,60 @@ class APIConfigurationAdapter(ConfigurationAdapter):
@property
def use_memcache(self):
release = ch_utils.get_os_codename_install_source(
self.openstack_origin)
if release not in ch_utils.OPENSTACK_RELEASES:
return ValueError("Unkown release {}".format(release))
return (ch_utils.OPENSTACK_RELEASES.index(release) >=
ch_utils.OPENSTACK_RELEASES.index('mitaka'))
return self.memcache.get('use_memcache', False)
@property
def memcache_server(self):
if ch_host.lsb_release()['DISTRIB_RELEASE'] > '14.04':
memcache_server = '::1'
else:
memcache_server = 'ip6-localhost'
return memcache_server
return self.memcache.get('memcache_server', '')
@property
def memcache_host(self):
return '[::1]'
return self.memcache.get('memcache_server_formatted', '')
@property
def memcache_port(self):
return '11211'
return self.memcache.get('memcache_port', '')
@property
def memcache_url(self):
return 'inet6:{}:{}'.format(self.memcache_host, self.memcache_port)
return self.memcache.get('memcache_url', '')
@property
@hookenv.cached
def memcache(self):
ctxt = {}
ctxt['use_memcache'] = False
if self.charm_instance:
if (ch_utils.OPENSTACK_RELEASES.index(
self.charm_instance.release) >=
ch_utils.OPENSTACK_RELEASES.index('mitaka')):
ctxt['use_memcache'] = True
if ctxt['use_memcache']:
# Trusty version of memcached does not support ::1 as a listen
# address so use host file entry instead
release = ch_host.lsb_release()['DISTRIB_CODENAME'].lower()
if ch_ip.is_ipv6_disabled():
if ch_host.CompareHostReleases(release) > 'trusty':
ctxt['memcache_server'] = '127.0.0.1'
else:
ctxt['memcache_server'] = 'localhost'
ctxt['memcache_server_formatted'] = '127.0.0.1'
ctxt['memcache_port'] = '11211'
ctxt['memcache_url'] = '{}:{}'.format(
ctxt['memcache_server_formatted'],
ctxt['memcache_port'])
else:
if ch_host.CompareHostReleases(release) > 'trusty':
ctxt['memcache_server'] = '::1'
else:
ctxt['memcache_server'] = 'ip6-localhost'
ctxt['memcache_server_formatted'] = '[::1]'
ctxt['memcache_port'] = '11211'
ctxt['memcache_url'] = 'inet6:{}:{}'.format(
ctxt['memcache_server_formatted'],
ctxt['memcache_port'])
return ctxt
def make_default_relation_adapter(base_cls, relation, properties):

View File

@ -698,42 +698,115 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
c = adapters.APIConfigurationAdapter()
self.assertEqual(c.determine_service_port(80), 70)
def test_memcache_ctx(self):
class MockCharmInstance(object):
api_ports = {}
name = 'hello'
def __init__(self, release):
self.release = release
mch_result = False
class MCHR(object):
class_thing = None
def __init__(self, thing):
self.thing = thing
self.__class__.class_thing = self
def __gt__(self, other):
return mch_result
mpo = mock.patch.object
with mpo(adapters.ch_host, 'lsb_release') as lsb_r, \
mpo(adapters.ch_host, 'CompareHostReleases', new=MCHR), \
mpo(adapters.ch_ip, 'is_ipv6_disabled') as is_ipv6_disabled:
# first no memcache
mci = MockCharmInstance('liberty')
c = adapters.APIConfigurationAdapter(charm_instance=mci)
self.assertEquals(c.memcache['use_memcache'], False)
# next switch on memcache
mci = MockCharmInstance('mitaka')
# start with ipv6 disabled and ubuntu release is trusty
lsb_r.return_value = {'DISTRIB_CODENAME': 'trusty'}
is_ipv6_disabled.return_value = True
c = adapters.APIConfigurationAdapter(charm_instance=mci)
self.assertEquals(c.memcache['use_memcache'], True)
self.assertEquals(MCHR.class_thing.thing, 'trusty')
self.assertEquals(c.memcache['memcache_server'], 'localhost')
self.assertEquals(c.memcache['memcache_server_formatted'],
'127.0.0.1')
self.assertEquals(c.memcache['memcache_port'], '11211')
self.assertEquals(c.memcache['memcache_url'],
'127.0.0.1:11211')
# make us later than trusty
mch_result = True
self.assertEquals(c.memcache['memcache_server'], '127.0.0.1')
# now do ipv6 not disabled.
mch_result = False
is_ipv6_disabled.return_value = False
c = adapters.APIConfigurationAdapter(charm_instance=mci)
self.assertEquals(c.memcache['use_memcache'], True)
self.assertEquals(MCHR.class_thing.thing, 'trusty')
self.assertEquals(c.memcache['memcache_server'], 'ip6-localhost')
self.assertEquals(c.memcache['memcache_server_formatted'], '[::1]')
self.assertEquals(c.memcache['memcache_port'], '11211')
self.assertEquals(c.memcache['memcache_url'], 'inet6:[::1]:11211')
# make us later than trusty
mch_result = True
self.assertEquals(c.memcache['memcache_server'], '::1')
def test_use_memcache(self):
test_config = {'openstack-origin': 'distro'}
with mock.patch.object(adapters.hookenv, 'config',
new=lambda: test_config):
with mock.patch.object(adapters.ch_utils,
'get_os_codename_install_source',
return_value='liberty'):
c = adapters.APIConfigurationAdapter()
self.assertFalse(c.use_memcache)
with mock.patch.object(adapters.ch_utils,
'get_os_codename_install_source',
return_value='newton'):
c = adapters.APIConfigurationAdapter()
self.assertTrue(c.use_memcache)
with mock.patch.object(adapters.APIConfigurationAdapter, 'memcache',
new_callable=mock.PropertyMock) as memcache:
memcache.return_value = {}
c = adapters.APIConfigurationAdapter()
self.assertEquals(c.use_memcache, False)
memcache.return_value = {'use_memcache': False}
self.assertEquals(c.use_memcache, False)
memcache.return_value = {'use_memcache': True}
self.assertEquals(c.use_memcache, True)
def test_memcache_server(self):
with mock.patch.object(adapters.ch_host, 'lsb_release',
return_value={'DISTRIB_RELEASE': '14.04'}):
with mock.patch.object(adapters.APIConfigurationAdapter, 'memcache',
new_callable=mock.PropertyMock) as memcache:
memcache.return_value = {}
c = adapters.APIConfigurationAdapter()
self.assertEqual(c.memcache_server, 'ip6-localhost')
with mock.patch.object(adapters.ch_host, 'lsb_release',
return_value={'DISTRIB_RELEASE': '16.04'}):
c = adapters.APIConfigurationAdapter()
self.assertEqual(c.memcache_server, '::1')
self.assertEquals(c.memcache_server, '')
memcache.return_value = {'memcache_server': 'hello'}
self.assertEquals(c.memcache_server, 'hello')
def test_memcache_host(self):
self.assertEqual(adapters.APIConfigurationAdapter().memcache_host,
'[::1]')
with mock.patch.object(adapters.APIConfigurationAdapter, 'memcache',
new_callable=mock.PropertyMock) as memcache:
memcache.return_value = {}
c = adapters.APIConfigurationAdapter()
self.assertEquals(c.memcache_host, '')
memcache.return_value = {'memcache_server_formatted': 'hello'}
self.assertEquals(c.memcache_host, 'hello')
def test_memcache_port(self):
self.assertEqual(adapters.APIConfigurationAdapter().memcache_port,
'11211')
with mock.patch.object(adapters.APIConfigurationAdapter, 'memcache',
new_callable=mock.PropertyMock) as memcache:
memcache.return_value = {}
c = adapters.APIConfigurationAdapter()
self.assertEquals(c.memcache_port, '')
memcache.return_value = {'memcache_port': 'hello'}
self.assertEquals(c.memcache_port, 'hello')
def test_memcache_url(self):
self.assertEqual(adapters.APIConfigurationAdapter().memcache_url,
'inet6:[::1]:11211')
with mock.patch.object(adapters.APIConfigurationAdapter, 'memcache',
new_callable=mock.PropertyMock) as memcache:
memcache.return_value = {}
c = adapters.APIConfigurationAdapter()
self.assertEquals(c.memcache_url, '')
memcache.return_value = {'memcache_url': 'hello'}
self.assertEquals(c.memcache_url, 'hello')
class FakePeerHARelationAdapter(object):