diff options
| author | billy.olsen@canonical.com <> | 2016-05-05 10:08:05 -0700 | 
|---|---|---|
| committer | billy.olsen@canonical.com <> | 2016-05-05 10:08:05 -0700 | 
| commit | a71bc020ec12f543e8aaa0671c16c9b96e0ae7ca (patch) | |
| tree | 1118938cb5c3323894bf8d36b2b73acdcb6028be | |
| parent | 87079a1babd0143bba4f5a5eca60470399061e89 (diff) | |
Move parameter logic from altering init conf file to the /etc/mongodb.conf
file. The mongdob service is already configured to read parameters from the /etc/mongodb.conf file and moving the configuration options inside the config file allows the systemd style service to start properly. Also, as of MongoDB 2.6, the specification of master/slave flags on startup is not allowed to be specified with the replicaset flags. This change allows for the master/slave flag to be specified in the /etc/mongodb.conf file only when the replica-set (peer) relation has not been established. Closes-Bug: #1513094 
| -rwxr-xr-x | hooks/hooks.py | 146 | ||||
| -rwxr-xr-x | tests/01_deploy_single.py | 4 | ||||
| -rwxr-xr-x | tests/02_deploy_shard_test.py | 6 | ||||
| -rwxr-xr-x | tests/03_deploy_replicaset.py | 6 | ||||
| -rwxr-xr-x | tests/04_deploy_with_storage.py | 4 | ||||
| -rwxr-xr-x | tests/50_relate_ceilometer_test.py | 2 | ||||
| -rw-r--r-- | unit_tests/test_hooks.py | 18 | 
7 files changed, 89 insertions, 97 deletions
| diff --git a/hooks/hooks.py b/hooks/hooks.py index 4801dc8..c5fe7c0 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -46,6 +46,7 @@ from charmhelpers.core.host import (  from charmhelpers.core.hookenv import (  close_port,  config, + is_relation_made,  open_port,  unit_get,  relation_get, @@ -331,6 +332,10 @@ def mongodb_conf(config_data=None):  if not config_data['web_admin_ui']:  config.append("nohttpinterface = true")  config.append("") + else: + config.append("rest = true") + config.append("httpinterface = true") + config.append("")  # noscripting  if config_data['noscripting']: @@ -367,14 +372,23 @@ def mongodb_conf(config_data=None):  config.append("mms-interval = %s" % config_data['mms-interval'])  config.append("") - # master/slave - if config_data['master'] == "self": - config.append("master = true") + # Set either replica-set or master, depending upon whether the + # the replica-set (peer) relation is established. If the user + # chooses to use juju scale out (e.g. juju add-unit) then the + # charm will use replica-set replication. The user may opt to + # do master/slave replication or sharding as a different form + # of scaleout. + if is_relation_made('replica-set'): + config.append("replSet = %s" % config_data['replicaset'])  config.append("")  else: - config.append("slave = true") - config.append("source = %s" % config_data['master']) - config.append("") + if config_data['master'] == "self": + config.append("master = true") + config.append("") + else: + config.append("slave = true") + config.append("source = %s" % config_data['master']) + config.append("")  # arbiter  if config_data['arbiter'] != "disabled" and \ @@ -405,6 +419,27 @@ def mongodb_conf(config_data=None):  return('\n'.join(config)) +def get_current_mongo_config(): + """Reads the current mongo configuration file and returns a dict + containing the key/value pairs found in the configuration file. + + :returns dict: key/value pairs of the configuration file. + """ + results = {} + with open(default_mongodb_config, 'r') as f: + for line in f: + line = line.strip() + + # Skip over comments, blank lines, and any other line + # that appears to not contain a key = value pair. + if line.startswith('#') or '=' not in line: + continue + + key, value = line.split('=', 1) + results[key.strip()] = value.strip() + return results + +  def mongo_client(host=None, command=None):  if host is None or command is None:  return(False) @@ -541,22 +576,19 @@ def enable_replset(replicaset_name=None):  try:  juju_log('enable_replset: trying to get lock on: %s' %  default_mongodb_init_config) - with FileLock(INIT_LOCKFILE): - juju_log('enable_replset: lock acquired', level=DEBUG) - with open(default_mongodb_init_config) as mongo_init_file: - mongodb_init_config = mongo_init_file.read() - if re.search(' --replSet %s ' % replicaset_name, - mongodb_init_config, re.MULTILINE) is None: - juju_log('enable_replset: --replset not preset,' - ' enabling', - level=DEBUG) - mongodb_init_config = regex_sub([(' -- ', - ' -- --replSet %s ' % - replicaset_name)], - mongodb_init_config) - update_file(default_mongodb_init_config, - mongodb_init_config) - retVal = True + + current_config = get_current_mongo_config() + config_data = config() + + if 'replSet' in current_config and \ + current_config['replSet'] == config_data['replicaset']: + juju_log('enable_replset: replica set is already enabled', + level=DEBUG) + else: + juju_log('enable_replset: enabling replicaset %s' % + config_data['replicaset'], level=DEBUG) + mongodb_config = mongodb_conf(config_data) + retVal = update_file(default_mongodb_config, mongodb_config)  juju_log('enable_replset will return: %s' % str(retVal), level=DEBUG) @@ -582,64 +614,6 @@ def update_daemon_options(daemon_options=None):  return(update_file(default_mongodb_init_config, mongodb_init_config)) -def disable_replset(replicaset_name=None): - if replicaset_name is None: - retVal = False - try: - mongodb_init_config = open(default_mongodb_init_config).read() - if re.search(' --replSet %s ' % replicaset_name, - mongodb_init_config, re.MULTILINE) is not None: - mongodb_init_config = regex_sub([ - (' --replSet %s ' % replicaset_name, ' ') - ], mongodb_init_config) - retVal = update_file(default_mongodb_init_config, mongodb_init_config) - except Exception, e: - juju_log(str(e)) - retVal = False - finally: - return(retVal) - - -def enable_web_admin_ui(port=None): - if port is None: - juju_log("enable_web_admin_ui: port not defined.") - return(False) - try: - mongodb_init_config = open(default_mongodb_init_config).read() - if re.search(' --rest ', mongodb_init_config, re.MULTILINE) is None: - mongodb_init_config = regex_sub([(' -- ', ' -- --rest ')], - mongodb_init_config) - retVal = update_file(default_mongodb_init_config, mongodb_init_config) - except Exception, e: - juju_log(str(e)) - retVal = False - finally: - if retVal: - open_port(port) - return(retVal) - - -def disable_web_admin_ui(port=None): - if port is None: - juju_log("disable_web_admin_ui: port not defined.") - return(False) - try: - mongodb_init_config = open(default_mongodb_init_config).read() - if re.search(' --rest ', - mongodb_init_config, - re.MULTILINE) is not None: - mongodb_init_config = regex_sub([(' --rest ', ' ')], - mongodb_init_config) - retVal = update_file(default_mongodb_init_config, mongodb_init_config) - except Exception, e: - juju_log(str(e)) - retVal = False - finally: - if retVal: - close_port(port) - return(retVal) - -  def enable_arbiter(master_node=None, host=None):  juju_log("enable_arbiter: master_node: %s, host: %s" %  (master_node, host)) @@ -1002,9 +976,9 @@ def config_changed():  # web_admin_ui  if config_data['web_admin_ui']: - enable_web_admin_ui(new_web_admin_ui_port) + open_port(new_web_admin_ui_port)  else: - disable_web_admin_ui(current_web_admin_ui_port) + close_port(current_web_admin_ui_port)  # replicaset_master  if config_data['replicaset_master'] != "auto": @@ -1141,7 +1115,7 @@ def database_relation_joined():  relation_set(relation_id(), relation_data) -@hooks.hook('replicaset-relation-joined') +@hooks.hook('replica-set-relation-joined')  def replica_set_relation_joined():  juju_log("replica_set_relation_joined-start")  my_hostname = unit_get('private-address') @@ -1194,7 +1168,7 @@ def am_i_primary():  raise TimeoutException('Unable to determine if local unit is primary') -@hooks.hook('replicaset-relation-changed') +@hooks.hook('replica-set-relation-changed')  def replica_set_relation_changed():  private_address = unit_get('private-address')  remote_hostname = relation_get('hostname') @@ -1228,7 +1202,7 @@ def replica_set_relation_changed():  juju_log('replica_set_relation_changed-finish') -@hooks.hook('replicaset-relation-departed') +@hooks.hook('replica-set-relation-departed')  def replica_set_relation_departed():  juju_log('replica_set_relation_departed-start') @@ -1259,7 +1233,7 @@ def replica_set_relation_departed():  juju_log('replica_set_relation_departed-finish') -@hooks.hook('replicaset-relation-broken') +@hooks.hook('replica-set-relation-broken')  def replica_set_relation_broken():  juju_log('replica_set_relation_broken-start') diff --git a/tests/01_deploy_single.py b/tests/01_deploy_single.py index 885ee26..fd2cabc 100755 --- a/tests/01_deploy_single.py +++ b/tests/01_deploy_single.py @@ -5,7 +5,7 @@ from pymongo import MongoClient  seconds = 900 -d = amulet.Deployment(series='trusty') +d = amulet.Deployment(series='xenial')  d.add('mongodb', charm='mongodb')  d.expose('mongodb') @@ -36,7 +36,7 @@ def validate_world_connectivity():  amulet.raise_status(amulet.FAIL, msg="Failed to insert test data")  # Can we delete from a shard using the Mongos hub?  result = db.amulet.remove(insert_id) - if result['err'] is not None: + if 'err' in result and result['err'] is not None:  amulet.raise_status(amulet.FAIL, msg="Failed to remove test data") diff --git a/tests/02_deploy_shard_test.py b/tests/02_deploy_shard_test.py index 2ff0750..5ff0250 100755 --- a/tests/02_deploy_shard_test.py +++ b/tests/02_deploy_shard_test.py @@ -16,7 +16,7 @@ seconds = 1400  #########################################################  # 3shard cluster configuration  ######################################################### -d = amulet.Deployment(series='trusty') +d = amulet.Deployment(series='xenial')  d.add('configsvr', charm='mongodb', units=scale)  d.add('mongos', charm='mongodb', units=scale) @@ -92,7 +92,7 @@ def validate_status_interface():  def validate_running_services():  for service in sentry_dict:  output = sentry_dict[service].run('service mongodb status') - service_active = str(output).find('mongodb start/running') + service_active = str(output).find('active (running)')  if service_active == -1:  message = "Failed to find running MongoDB on host {}".format(  service) @@ -115,7 +115,7 @@ def validate_world_connectivity():  amulet.raise_status(amulet.FAIL, msg="Failed to insert test data")  # Can we delete from a shard using the Mongos hub?  result = db.amulet.remove(insert_id) - if result['err'] is not None: + if 'err' in result and result['err'] is not None:  amulet.raise_status(amulet.FAIL, msg="Failed to remove test data") diff --git a/tests/03_deploy_replicaset.py b/tests/03_deploy_replicaset.py index 02d25f5..7be3141 100755 --- a/tests/03_deploy_replicaset.py +++ b/tests/03_deploy_replicaset.py @@ -23,7 +23,7 @@ wait_for_replicaset = 600  #########################################################  # 3shard cluster configuration  ######################################################### -d = amulet.Deployment(series='trusty') +d = amulet.Deployment(series='xenial')  d.add('mongodb', charm='mongodb', units=scale)  d.expose('mongodb') @@ -63,7 +63,7 @@ def validate_status_interface():  def validate_running_services():  for service in sentry_dict:  output = sentry_dict[service].run('service mongodb status') - service_active = str(output).find('mongodb start/running') + service_active = str(output).find('active (running)')  if service_active == -1:  message = "Failed to find running MongoDB on host {}".format(  service) @@ -158,7 +158,7 @@ def validate_world_connectivity():  amulet.raise_status(amulet.FAIL, msg="Failed to insert test data")  # Can we delete from a shard using the Mongos hub?  result = db.amulet.remove(insert_id) - if result['err'] is not None: + if 'err' in result and result['err'] is not None:  amulet.raise_status(amulet.FAIL, msg="Failed to remove test data") diff --git a/tests/04_deploy_with_storage.py b/tests/04_deploy_with_storage.py index 46aef57..347b7ef 100755 --- a/tests/04_deploy_with_storage.py +++ b/tests/04_deploy_with_storage.py @@ -20,9 +20,9 @@ wait_for_relation = 60*5  #########################################################  # 3shard cluster configuration  ######################################################### -d = amulet.Deployment(series='trusty') +d = amulet.Deployment(series='xenial') -d.add('mongodb', units=scale, series='trusty', +d.add('mongodb', units=scale, series='xenial',  constraints={'root-disk': '20480M'})  d.add('storage', charm='cs:~chris-gondolin/trusty/storage-5', series='trusty')  d.configure('storage', {'provider': 'local'}) diff --git a/tests/50_relate_ceilometer_test.py b/tests/50_relate_ceilometer_test.py index ef45166..52571d8 100755 --- a/tests/50_relate_ceilometer_test.py +++ b/tests/50_relate_ceilometer_test.py @@ -7,7 +7,7 @@ class TestDeploy(object):  def __init__(self, time=2500):  # Attempt to load the deployment topology from a bundle. - self.deploy = amulet.Deployment(series="trusty") + self.deploy = amulet.Deployment(series="xenial")  # If something errored out, attempt to continue by  # manually specifying a standalone deployment diff --git a/unit_tests/test_hooks.py b/unit_tests/test_hooks.py index 4573b2c..85331f7 100644 --- a/unit_tests/test_hooks.py +++ b/unit_tests/test_hooks.py @@ -3,6 +3,7 @@ from mock import patch, call  import hooks  from test_utils import CharmTestCase +from test_utils import mock_open  from pymongo.errors import OperationFailure  from subprocess import CalledProcessError @@ -339,3 +340,20 @@ class MongoHooksTest(CharmTestCase):  call1 = call('juju-local:27017', 'juju-remote:27017')  mock_leave_replset.assert_has_calls([call1]) + + def test_get_current_mongo_config(self): + test_config = u""" + # Comment + key = value + one=two + + three =four + """ + expected = { + 'key': 'value', + 'one': 'two', + 'three': 'four' + } + with mock_open('/etc/mongodb.conf', test_config): + results = hooks.get_current_mongo_config() + self.assertEqual(results, expected) | 
