Pre-focal-enablement for rabbitmq-server charm
This patch updates the rabbitmq charm to work on focal as part of other test bundles, but does not update the charm for testing on focal. Hence focal/ussuri bundles are not added and the metadata.yaml does NOT include focal in this patchset. A further patchset will be submitted that adds the focal testing to the charm. In particular, this patchset is required for the cinder focal enablement. Change-Id: Ia239b7c2f0ed2383e220cf0fa4ade443149a3b32
This commit is contained in:
parent
8ddb700817
commit
5f6b1830d0
|
@ -12,6 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
@ -177,12 +178,20 @@ def list_vhosts():
|
|||
Returns a list of all the available vhosts
|
||||
"""
|
||||
try:
|
||||
output = subprocess.check_output([RABBITMQ_CTL, 'list_vhosts'])
|
||||
cmd = [RABBITMQ_CTL, 'list_vhosts']
|
||||
# NOTE(ajkavanagh): In focal and above, rabbitmq-server now has a
|
||||
# --formatter option.
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
cmd.append('--formatter=json')
|
||||
output = subprocess.check_output(cmd)
|
||||
output = output.decode('utf-8')
|
||||
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
decoded = json.loads(output)
|
||||
return [l['name'] for l in decoded]
|
||||
# NOTE(jamespage): Earlier rabbitmqctl versions append "...done"
|
||||
# to the output of list_vhosts
|
||||
if '...done' in output:
|
||||
elif '...done' in output:
|
||||
return output.split('\n')[1:-2]
|
||||
else:
|
||||
return output.split('\n')[1:-1]
|
||||
|
@ -199,12 +208,22 @@ def vhost_queue_info(vhost):
|
|||
"""
|
||||
cmd = [RABBITMQ_CTL, '-p', vhost, 'list_queues',
|
||||
'name', 'messages', 'consumers']
|
||||
# NOTE(ajkavanagh): In focal and above, rabbitmq-server now has a
|
||||
# --formatter option.
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
cmd.append('--formatter=json')
|
||||
output = subprocess.check_output(cmd).decode('utf-8')
|
||||
|
||||
queue_info = []
|
||||
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
decoded = json.loads(output)
|
||||
# note that the json is already in the desired output of queue_info
|
||||
# below
|
||||
return decoded
|
||||
# NOTE(jamespage): Earlier rabbitmqctl versions append "...done"
|
||||
# to the output of list_queues
|
||||
if '...done' in output:
|
||||
elif '...done' in output:
|
||||
queues = output.split('\n')[1:-2]
|
||||
else:
|
||||
queues = output.split('\n')[1:-1]
|
||||
|
@ -233,8 +252,20 @@ def create_vhost(vhost):
|
|||
|
||||
def user_exists(user):
|
||||
cmd = [RABBITMQ_CTL, 'list_users']
|
||||
# NOTE(ajkavanagh): In focal and above, rabbitmq-server now has a
|
||||
# --formatter option.
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
cmd.append('--formatter=json')
|
||||
out = subprocess.check_output(cmd).decode('utf-8')
|
||||
decoded = json.loads(out)
|
||||
users = [l['user'] for l in decoded]
|
||||
return user in users
|
||||
|
||||
# NOTE(ajkavanagh): pre 3.8.2 the code needs to deal with just a text
|
||||
# output
|
||||
out = subprocess.check_output(cmd).decode('utf-8')
|
||||
for line in out.split('\n')[1:]:
|
||||
lines = out.split('\n')[1:]
|
||||
for line in lines:
|
||||
_user = line.split('\t')[0]
|
||||
if _user == user:
|
||||
return True
|
||||
|
@ -314,7 +345,7 @@ def set_ha_mode(vhost, mode, params=None, sync_mode='automatic'):
|
|||
"all, exactly, nodes"))
|
||||
|
||||
log("Setting HA policy to vhost '%s'" % vhost, level='INFO')
|
||||
set_policy(vhost, 'HA', '^(?!amq\.).*', value)
|
||||
set_policy(vhost, 'HA', r'^(?!amq\.).*', value)
|
||||
|
||||
|
||||
def clear_ha_mode(vhost, name='HA', force=False):
|
||||
|
@ -430,7 +461,7 @@ def wait_app():
|
|||
try:
|
||||
status_cmd = ['rabbitmqctl', 'status']
|
||||
log(subprocess.check_output(status_cmd).decode('utf-8'), DEBUG)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
raise ex
|
||||
|
||||
|
@ -582,7 +613,7 @@ def leave_cluster():
|
|||
rabbitmqctl('reset')
|
||||
start_app()
|
||||
log('Successfully left cluster gracefully.')
|
||||
except:
|
||||
except Exception:
|
||||
# error, no nodes available for clustering
|
||||
log('Cannot leave cluster, we might be the last disc-node in the '
|
||||
'cluster.', level=ERROR)
|
||||
|
@ -770,9 +801,19 @@ def services():
|
|||
@cached
|
||||
def nodes(get_running=False):
|
||||
''' Get list of nodes registered in the RabbitMQ cluster '''
|
||||
# NOTE(ajkavanagh): In focal and above, rabbitmq-server now has a
|
||||
# --formatter option.
|
||||
if caching_cmp_pkgrevno('rabbitmq-server', '3.8.2') >= 0:
|
||||
cmd = [RABBITMQ_CTL, 'cluster_status', '--formatter=json']
|
||||
output = subprocess.check_output(cmd).decode('utf-8')
|
||||
decoded = json.loads(output)
|
||||
if get_running:
|
||||
return decoded['running_nodes']
|
||||
return decoded['disk_nodes'] + decoded['ram_nodes']
|
||||
|
||||
out = rabbitmqctl_normalized_output('cluster_status')
|
||||
cluster_status = {}
|
||||
for m in re.finditer("{([^,]+),(?!\[{)\[([^\]]*)", out):
|
||||
for m in re.finditer(r"{([^,]+),(?!\[{)\[([^\]]*)", out):
|
||||
state = m.group(1)
|
||||
items = m.group(2).split(',')
|
||||
items = [x.replace("'", '').strip() for x in items]
|
||||
|
@ -813,7 +854,7 @@ def get_node_hostname(ip_addr):
|
|||
''' Resolve IP address to hostname '''
|
||||
try:
|
||||
nodename = get_hostname(ip_addr, fqdn=False)
|
||||
except:
|
||||
except Exception:
|
||||
log('Cannot resolve hostname for %s using DNS servers' % ip_addr,
|
||||
level=WARNING)
|
||||
log('Falling back to use socket.gethostname()',
|
||||
|
|
2
tox.ini
2
tox.ini
|
@ -108,5 +108,5 @@ commands =
|
|||
functest-run-suite --keep-model --bundle {posargs}
|
||||
|
||||
[flake8]
|
||||
ignore = E402,E226
|
||||
ignore = E402,E226,E504
|
||||
exclude = */charmhelpers
|
||||
|
|
|
@ -92,6 +92,18 @@ RABBITMQCTL_CLUSTERSTATUS_RUNNING = b"""Cluster status of node 'rabbit@juju-deve
|
|||
{partitions,[]}]
|
||||
"""
|
||||
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING_382 = b"""
|
||||
{"running_nodes": [
|
||||
"rabbit@juju-devel3-machine-14",
|
||||
"rabbit@juju-devel3-machine-19"],
|
||||
"disk_nodes":
|
||||
["rabbit@juju-devel3-machine-14",
|
||||
"rabbit@juju-devel3-machine-19"],
|
||||
"ram_nodes": ["rabbit@juju-devel3-machine-42"]
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO = b"""Cluster status of node 'rabbit@juju-devel3-machine-14' ...
|
||||
[{nodes,[{disc,['rabbit@juju-devel3-machine-14']}]},
|
||||
{running_nodes,['rabbit@juju-devel3-machine-14']},
|
||||
|
@ -99,6 +111,17 @@ RABBITMQCTL_CLUSTERSTATUS_SOLO = b"""Cluster status of node 'rabbit@juju-devel3-
|
|||
{partitions,[]}]
|
||||
"""
|
||||
|
||||
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO_382 = b"""
|
||||
{"running_nodes": [
|
||||
"rabbit@juju-devel3-machine-14"],
|
||||
"disk_nodes":
|
||||
["rabbit@juju-devel3-machine-14"],
|
||||
"ram_nodes": []
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
RABBITMQCTL_LIST_QUEUES = b"""Listing queues ...
|
||||
a_sample_queue 0 1
|
||||
cinder-scheduler.cinder 0 1
|
||||
|
@ -107,6 +130,12 @@ myqueue 0 1
|
|||
...done
|
||||
"""
|
||||
|
||||
RABBITMQCTL_LIST_QUEUES_382 = (
|
||||
b'[{"name": "a_sample_queue", "messages": 0, "consumers": 1},'
|
||||
b'{"name": "cinder-scheduler.cinder", "messages": 0, "consumers": 1},'
|
||||
b'{"name": "cinder-fanout-12345", "messages": 250, "consumers": 0},'
|
||||
b'{"name": "myqueue", "messages": 0, "consumers": 1}]')
|
||||
|
||||
RABBITMQCTL_LIST_VHOSTS = b"""Listing vhosts ...
|
||||
/
|
||||
landscape
|
||||
|
@ -114,6 +143,9 @@ openstack
|
|||
...done
|
||||
"""
|
||||
|
||||
RABBITMQCTL_LIST_VHOSTS_382 = (b'[{"name": "/"},{"name": "landscape"},'
|
||||
b'{"name": "openstack"}]')
|
||||
|
||||
|
||||
class UtilsTests(CharmTestCase):
|
||||
def setUp(self):
|
||||
|
@ -189,38 +221,81 @@ class UtilsTests(CharmTestCase):
|
|||
mock_running_nodes.return_value = ['a', 'b']
|
||||
self.assertTrue(rabbit_utils.clustered())
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_nodes(self, mock_subprocess):
|
||||
def test_nodes(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a clustered deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.nodes(),
|
||||
['rabbit@juju-devel3-machine-14',
|
||||
'rabbit@juju-devel3-machine-19',
|
||||
'rabbit@juju-devel3-machine-42'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_running_nodes(self, mock_subprocess):
|
||||
def test_nodes_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a clustered deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.nodes(),
|
||||
['rabbit@juju-devel3-machine-14',
|
||||
'rabbit@juju-devel3-machine-19',
|
||||
'rabbit@juju-devel3-machine-42'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_running_nodes(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a clustered deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.running_nodes(),
|
||||
['rabbit@juju-devel3-machine-14',
|
||||
'rabbit@juju-devel3-machine-19'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_list_vhosts(self, mock_subprocess):
|
||||
def test_running_nodes_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a clustered deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.running_nodes(),
|
||||
['rabbit@juju-devel3-machine-14',
|
||||
'rabbit@juju-devel3-machine-19'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_list_vhosts(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure list_vhosts parses output into the proper list'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_LIST_VHOSTS
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.list_vhosts(),
|
||||
['/', 'landscape', 'openstack'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_vhost_queue_info(self, mock_subprocess):
|
||||
def test_list_vhosts_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure list_vhosts parses output into the proper list for
|
||||
rabbitmq_server 3.8.2+
|
||||
'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_LIST_VHOSTS_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.list_vhosts(),
|
||||
['/', 'landscape', 'openstack'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_vhost_queue_info(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure vhost_queue_info parses output into the proper format/info'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_LIST_QUEUES
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.vhost_queue_info('openstack'),
|
||||
[{'name': 'a_sample_queue', 'messages': 0,
|
||||
'consumers': 1},
|
||||
|
@ -230,19 +305,59 @@ class UtilsTests(CharmTestCase):
|
|||
'consumers': 0},
|
||||
{'name': 'myqueue', 'messages': 0, 'consumers': 1}])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_nodes_solo(self, mock_subprocess):
|
||||
def test_vhost_queue_info_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure vhost_queue_info parses output into the proper format/info'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_LIST_QUEUES_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.vhost_queue_info('openstack'),
|
||||
[{'name': 'a_sample_queue', 'messages': 0,
|
||||
'consumers': 1},
|
||||
{'name': 'cinder-scheduler.cinder', 'messages': 0,
|
||||
'consumers': 1},
|
||||
{'name': 'cinder-fanout-12345', 'messages': 250,
|
||||
'consumers': 0},
|
||||
{'name': 'myqueue', 'messages': 0, 'consumers': 1}])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_nodes_solo(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a single unit deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.nodes(),
|
||||
['rabbit@juju-devel3-machine-14'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_running_nodes_solo(self, mock_subprocess):
|
||||
def test_nodes_solo_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a single unit deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.nodes(),
|
||||
['rabbit@juju-devel3-machine-14'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_running_nodes_solo(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a single unit deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
self.assertEqual(rabbit_utils.running_nodes(),
|
||||
['rabbit@juju-devel3-machine-14'])
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
def test_running_nodes_solo_382(self, mock_subprocess, mock_cmp_pkgrevno):
|
||||
'''Ensure cluster_status can be parsed for a single unit deployment'''
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_SOLO_382
|
||||
mock_cmp_pkgrevno.return_value = 0
|
||||
self.assertEqual(rabbit_utils.running_nodes(),
|
||||
['rabbit@juju-devel3-machine-14'])
|
||||
|
||||
|
@ -702,6 +817,7 @@ class UtilsTests(CharmTestCase):
|
|||
rabbit_utils.forget_cluster_node('a')
|
||||
mock_rabbitmqctl.assert_called_with('forget_cluster_node', 'a')
|
||||
|
||||
@mock.patch('rabbit_utils.caching_cmp_pkgrevno')
|
||||
@mock.patch('rabbit_utils.forget_cluster_node')
|
||||
@mock.patch('rabbit_utils.relations_for_id')
|
||||
@mock.patch('rabbit_utils.subprocess')
|
||||
|
@ -709,10 +825,12 @@ class UtilsTests(CharmTestCase):
|
|||
def test_check_cluster_memberships(self, mock_relation_ids,
|
||||
mock_subprocess,
|
||||
mock_relations_for_id,
|
||||
mock_forget_cluster_node):
|
||||
mock_forget_cluster_node,
|
||||
mock_cmp_pkgrevno):
|
||||
mock_relation_ids.return_value = [0]
|
||||
mock_subprocess.check_output.return_value = \
|
||||
RABBITMQCTL_CLUSTERSTATUS_RUNNING
|
||||
mock_cmp_pkgrevno.return_value = -1
|
||||
mock_relations_for_id.return_value = [
|
||||
{'clustered': 'juju-devel3-machine-14'},
|
||||
{'clustered': 'juju-devel3-machine-19'},
|
||||
|
|
|
@ -306,6 +306,7 @@ class RelationUtil(CharmTestCase):
|
|||
if os.path.exists(tmpdir):
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
@patch('rabbit_utils.create_user')
|
||||
@patch('rabbitmq_server_relations.local_unit')
|
||||
@patch('charmhelpers.contrib.charmsupport.nrpe.NRPE.add_check')
|
||||
@patch('subprocess.check_call')
|
||||
|
@ -318,14 +319,17 @@ class RelationUtil(CharmTestCase):
|
|||
@patch('rabbitmq_server_relations.charm_dir')
|
||||
@patch('subprocess.check_output')
|
||||
@patch('rabbitmq_server_relations.config')
|
||||
def test_update_nrpe_checks(self, mock_config, mock_check_output,
|
||||
def test_update_nrpe_checks(self,
|
||||
mock_config,
|
||||
mock_check_output,
|
||||
mock_charm_dir, mock_fchown,
|
||||
mock_get_nagios_hostname,
|
||||
mock_get_nagios_unit_name, mock_config2,
|
||||
mock_nrpe_relation_ids,
|
||||
mock_get_rabbit_password_on_disk,
|
||||
mock_check_call, mock_add_check,
|
||||
mock_local_unit):
|
||||
mock_local_unit,
|
||||
mock_create_user):
|
||||
|
||||
self.test_config.set('ssl', 'on')
|
||||
|
||||
|
|
Loading…
Reference in New Issue