diff options
| author | Billy Olsen <billy.olsen@canonical.com> | 2016-05-12 13:26:38 -0700 |
|---|---|---|
| committer | Billy Olsen <billy.olsen@canonical.com> | 2016-05-12 13:26:38 -0700 |
| commit | 9e3a8e056ac0acec8c57e983c8e49c13e78614af (patch) | |
| tree | 4acfa37f24fc84b6db3f6c27ff74f183def187c4 | |
| parent | 87079a1babd0143bba4f5a5eca60470399061e89 (diff) | |
| parent | a71bc020ec12f543e8aaa0671c16c9b96e0ae7ca (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. Prior to versions of MongoDB 2.6, specifying the master/slave flag on startup did not cause MongoDB to error out and MongoDB ignored the flag. Closes-Bug: #1513094
| -rwxr-xr-x | hooks/hooks.py | 146 | ||||
| -rwxr-xr-x | tests/01_deploy_single.py | 2 | ||||
| -rwxr-xr-x | tests/02_deploy_shard_test.py | 4 | ||||
| -rwxr-xr-x | tests/03_deploy_replicaset.py | 4 | ||||
| -rw-r--r-- | unit_tests/test_hooks.py | 18 |
5 files changed, 83 insertions, 91 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..c5e91f2 100755 --- a/tests/01_deploy_single.py +++ b/tests/01_deploy_single.py @@ -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..6343785 100755 --- a/tests/02_deploy_shard_test.py +++ b/tests/02_deploy_shard_test.py @@ -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..cae5930 100755 --- a/tests/03_deploy_replicaset.py +++ b/tests/03_deploy_replicaset.py @@ -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/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) |
