Merge "Fix apply configuration on prepare"
This commit is contained in:
commit
654eb0f96e
@ -260,6 +260,10 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
users, device_path, mount_point, backup_info,
|
||||
config_contents, root_password, overrides,
|
||||
cluster_config, snapshot)
|
||||
if overrides:
|
||||
LOG.info(_("Applying user-specified configuration "
|
||||
"(called from 'prepare')."))
|
||||
self.apply_overrides_on_prepare(context, overrides)
|
||||
except Exception as ex:
|
||||
self.prepare_error = True
|
||||
LOG.exception(_("An error occurred preparing datastore: %s") %
|
||||
@ -307,6 +311,10 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
ex.message)
|
||||
raise
|
||||
|
||||
def apply_overrides_on_prepare(self, context, overrides):
|
||||
self.update_overrides(context, overrides)
|
||||
self.restart(context)
|
||||
|
||||
@abc.abstractmethod
|
||||
def do_prepare(self, context, packages, databases, memory_mb, users,
|
||||
device_path, mount_point, backup_info, config_contents,
|
||||
@ -336,6 +344,14 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
LOG.info(_('No post_prepare work has been defined.'))
|
||||
pass
|
||||
|
||||
#################
|
||||
# Service related
|
||||
#################
|
||||
@abc.abstractmethod
|
||||
def restart(self, context):
|
||||
"""Restart the database service."""
|
||||
pass
|
||||
|
||||
#####################
|
||||
# File System related
|
||||
#####################
|
||||
|
@ -222,7 +222,7 @@ class MySqlManager(manager.Manager):
|
||||
self._perform_restore(backup_info, context,
|
||||
mount_point + "/data", app)
|
||||
LOG.debug("Securing MySQL now.")
|
||||
app.secure(config_contents, overrides)
|
||||
app.secure(config_contents)
|
||||
enable_root_on_restore = (backup_info and
|
||||
self.mysql_admin().is_root_enabled())
|
||||
if root_password and not backup_info:
|
||||
|
@ -656,7 +656,7 @@ class BaseMySqlApp(object):
|
||||
LOG.info(_("Finished installing MySQL server."))
|
||||
self.start_mysql()
|
||||
|
||||
def secure(self, config_contents, overrides):
|
||||
def secure(self, config_contents):
|
||||
LOG.info(_("Generating admin password."))
|
||||
admin_password = utils.generate_random_password()
|
||||
clear_expired_password()
|
||||
@ -669,7 +669,6 @@ class BaseMySqlApp(object):
|
||||
self.stop_db()
|
||||
|
||||
self._reset_configuration(config_contents, admin_password)
|
||||
self._apply_user_overrides(overrides)
|
||||
self.start_mysql()
|
||||
|
||||
LOG.debug("MySQL secure complete.")
|
||||
|
@ -1358,7 +1358,7 @@ class MySqlAppTest(trove_testtools.TestCase):
|
||||
@patch.object(utils, 'generate_random_password',
|
||||
return_value='some_password')
|
||||
@patch.object(dbaas_base, 'clear_expired_password')
|
||||
def test_secure(self, auth_pwd_mock, clear_pwd_mock):
|
||||
def test_secure(self, clear_pwd_mock, auth_pwd_mock):
|
||||
|
||||
self.mySqlApp.start_mysql = Mock()
|
||||
self.mySqlApp.stop_db = Mock()
|
||||
@ -1370,16 +1370,12 @@ class MySqlAppTest(trove_testtools.TestCase):
|
||||
|
||||
with patch.object(BaseDbStatus, 'prepare_completed') as patch_pc:
|
||||
patch_pc.__get__ = Mock(return_value=True)
|
||||
self.mySqlApp.secure('contents', 'overrides')
|
||||
self.mySqlApp.secure('contents')
|
||||
|
||||
self.assertTrue(self.mySqlApp.stop_db.called)
|
||||
reset_config_calls = [call('contents', auth_pwd_mock.return_value),
|
||||
call('contents', auth_pwd_mock.return_value)]
|
||||
self.mySqlApp._reset_configuration.has_calls(reset_config_calls)
|
||||
self.mySqlApp._reset_configuration.assert_has_calls(
|
||||
[call('contents', auth_pwd_mock.return_value)])
|
||||
|
||||
apply_overrides_calls = [call('overrides'),
|
||||
call('overrides')]
|
||||
self.mySqlApp._reset_configuration.has_calls(apply_overrides_calls)
|
||||
self.assertTrue(self.mySqlApp.start_mysql.called)
|
||||
self.assert_reported_status(rd_instance.ServiceStatuses.NEW)
|
||||
|
||||
@ -1470,7 +1466,7 @@ class MySqlAppTest(trove_testtools.TestCase):
|
||||
self.mysql_starts_successfully()
|
||||
sqlalchemy.create_engine = Mock()
|
||||
|
||||
self.assertRaises(IOError, self.mySqlApp.secure, "foo", None)
|
||||
self.assertRaises(IOError, self.mySqlApp.secure, "foo")
|
||||
|
||||
self.assertTrue(self.mySqlApp.stop_db.called)
|
||||
self.assertFalse(self.mySqlApp.start_mysql.called)
|
||||
@ -1545,7 +1541,7 @@ class MySqlAppMockTest(trove_testtools.TestCase):
|
||||
app._wait_for_mysql_to_be_really_alive = MagicMock(
|
||||
return_value=True)
|
||||
app.stop_db = MagicMock(return_value=None)
|
||||
app.secure('foo', None)
|
||||
app.secure('foo')
|
||||
reset_config_calls = [call('foo', auth_pwd_mock.return_value)]
|
||||
app._reset_configuration.assert_has_calls(reset_config_calls)
|
||||
self.assertTrue(mock_execute.called)
|
||||
@ -1570,7 +1566,7 @@ class MySqlAppMockTest(trove_testtools.TestCase):
|
||||
app = MySqlApp(mock_status)
|
||||
dbaas_base.clear_expired_password = \
|
||||
MagicMock(return_value=None)
|
||||
self.assertRaises(RuntimeError, app.secure, None, None)
|
||||
self.assertRaises(RuntimeError, app.secure, None)
|
||||
self.assertTrue(mock_execute.called)
|
||||
# At least called twice
|
||||
self.assertTrue(mock_execute.call_count >= 2)
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Copyright 2015 Tesora Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -12,11 +13,14 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import getpass
|
||||
import os
|
||||
|
||||
from mock import ANY
|
||||
from mock import DEFAULT
|
||||
from mock import MagicMock
|
||||
from mock import Mock
|
||||
from mock import patch
|
||||
from proboscis.asserts import assert_equal
|
||||
from proboscis.asserts import assert_true
|
||||
@ -30,6 +34,7 @@ from trove.tests.unittests import trove_testtools
|
||||
|
||||
|
||||
class MockManager(manager.Manager):
|
||||
|
||||
def __init__(self):
|
||||
super(MockManager, self).__init__('mysql')
|
||||
self._app = MagicMock()
|
||||
@ -50,6 +55,7 @@ class MockManager(manager.Manager):
|
||||
|
||||
|
||||
class ManagerTest(trove_testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ManagerTest, self).setUp()
|
||||
|
||||
@ -312,3 +318,146 @@ class ManagerTest(trove_testtools.TestCase):
|
||||
for key in os_mocks.keys():
|
||||
assert_true(os_mocks[key].call_count == 1,
|
||||
"%s not called" % key)
|
||||
|
||||
def test_prepare_single(self):
|
||||
packages = Mock()
|
||||
databases = Mock()
|
||||
memory_mb = Mock()
|
||||
users = Mock()
|
||||
device_path = Mock()
|
||||
mount_point = Mock()
|
||||
backup_info = Mock()
|
||||
config_contents = Mock()
|
||||
root_password = Mock()
|
||||
overrides = Mock()
|
||||
snapshot = Mock()
|
||||
|
||||
self._assert_prepare(
|
||||
self.context, packages, databases, memory_mb, users, device_path,
|
||||
mount_point, backup_info, config_contents, root_password,
|
||||
overrides, None, snapshot)
|
||||
|
||||
def test_prepare_cluster(self):
|
||||
packages = Mock()
|
||||
databases = Mock()
|
||||
memory_mb = Mock()
|
||||
users = Mock()
|
||||
device_path = Mock()
|
||||
mount_point = Mock()
|
||||
backup_info = Mock()
|
||||
config_contents = Mock()
|
||||
root_password = Mock()
|
||||
overrides = Mock()
|
||||
cluster_config = Mock()
|
||||
snapshot = Mock()
|
||||
|
||||
self._assert_prepare(
|
||||
self.context, packages, databases, memory_mb, users, device_path,
|
||||
mount_point, backup_info, config_contents, root_password,
|
||||
overrides, cluster_config, snapshot)
|
||||
|
||||
def _assert_prepare(self, context, packages, databases, memory_mb, users,
|
||||
device_path, mount_point, backup_info, config_contents,
|
||||
root_password, overrides, cluster_config, snapshot):
|
||||
|
||||
is_error_expected = False
|
||||
is_post_process_expected = cluster_config is not None
|
||||
|
||||
with patch.multiple(self.manager,
|
||||
do_prepare=DEFAULT, post_prepare=DEFAULT,
|
||||
apply_overrides_on_prepare=DEFAULT,
|
||||
create_database=DEFAULT, create_user=DEFAULT):
|
||||
self.manager.prepare(
|
||||
context, packages, databases, memory_mb, users,
|
||||
device_path, mount_point, backup_info, config_contents,
|
||||
root_password, overrides, cluster_config, snapshot)
|
||||
|
||||
self.manager.status.begin_install.assert_called_once_with()
|
||||
self.manager.do_prepare.assert_called_once_with(
|
||||
context,
|
||||
packages,
|
||||
databases,
|
||||
memory_mb,
|
||||
users,
|
||||
device_path,
|
||||
mount_point,
|
||||
backup_info,
|
||||
config_contents,
|
||||
root_password,
|
||||
overrides,
|
||||
cluster_config,
|
||||
snapshot)
|
||||
self.manager.apply_overrides_on_prepare.assert_called_once_with(
|
||||
context,
|
||||
overrides)
|
||||
self.manager.status.end_install(
|
||||
error_occurred=is_error_expected,
|
||||
post_processing=is_post_process_expected)
|
||||
self.manager.post_prepare.assert_called_once_with(
|
||||
context,
|
||||
packages,
|
||||
databases,
|
||||
memory_mb,
|
||||
users,
|
||||
device_path,
|
||||
mount_point,
|
||||
backup_info,
|
||||
config_contents,
|
||||
root_password,
|
||||
overrides,
|
||||
cluster_config,
|
||||
snapshot)
|
||||
|
||||
if not is_post_process_expected:
|
||||
self.manager.create_database.assert_called_once_with(
|
||||
context,
|
||||
databases)
|
||||
self.manager.create_user.assert_called_once_with(
|
||||
context,
|
||||
users)
|
||||
else:
|
||||
self.assertEqual(0, self.manager.create_database.call_count)
|
||||
self.assertEqual(0, self.manager.create_user.call_count)
|
||||
|
||||
def test_apply_overrides_on_prepare(self):
|
||||
overrides = Mock()
|
||||
with patch.multiple(self.manager,
|
||||
update_overrides=DEFAULT, restart=DEFAULT):
|
||||
self.manager.apply_overrides_on_prepare(self.context, overrides)
|
||||
|
||||
self.manager.update_overrides.assert_called_once_with(
|
||||
self.context, overrides)
|
||||
self.manager.restart.assert_called_once_with(self.context)
|
||||
|
||||
def test_apply_overrides_on_prepare_failure(self):
|
||||
packages = Mock()
|
||||
databases = Mock()
|
||||
memory_mb = Mock()
|
||||
users = Mock()
|
||||
device_path = Mock()
|
||||
mount_point = Mock()
|
||||
backup_info = Mock()
|
||||
config_contents = Mock()
|
||||
root_password = Mock()
|
||||
overrides = Mock()
|
||||
cluster_config = Mock()
|
||||
snapshot = Mock()
|
||||
|
||||
expected_failure = Exception("Error in 'apply_overrides_on_prepare'.")
|
||||
|
||||
with patch.multiple(
|
||||
self.manager, do_prepare=DEFAULT,
|
||||
apply_overrides_on_prepare=MagicMock(
|
||||
side_effect=expected_failure
|
||||
)):
|
||||
self.assertRaisesRegexp(
|
||||
Exception, "Error in 'apply_overrides_on_prepare'.",
|
||||
self.manager.prepare,
|
||||
self.context, packages, databases, memory_mb, users,
|
||||
device_path, mount_point, backup_info, config_contents,
|
||||
root_password, overrides, cluster_config, snapshot)
|
||||
|
||||
self.manager.status.begin_install.assert_called_once_with()
|
||||
self.manager.status.end_install(
|
||||
error_occurred=True,
|
||||
post_processing=ANY)
|
||||
|
@ -37,6 +37,7 @@ from trove.guestagent.volume import VolumeDevice
|
||||
|
||||
|
||||
class GuestAgentManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GuestAgentManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
@ -282,7 +283,7 @@ class GuestAgentManagerTest(testtools.TestCase):
|
||||
'/var/lib/mysql/data')
|
||||
dbaas.MySqlApp.install_if_needed.assert_any_call(None)
|
||||
# We don't need to make sure the exact contents are there
|
||||
dbaas.MySqlApp.secure.assert_any_call(None, None)
|
||||
dbaas.MySqlApp.secure.assert_any_call(None)
|
||||
dbaas.MySqlApp.secure_root.assert_any_call(
|
||||
secure_remote_root=not is_root_enabled)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user