Fix the mysql start up issue after restore

When the trove guest image is built without the proper permission
setting for /tmp directory in which ini file is created. (could happen
when using non-official ways of image building), mysqld_safe will fail
to reset the root password after mysql restore due to AppArmour
complaints. As a consequence it fails the whole mysql restore procedure.

Changing init-file ownership fixes this problem and makes the backup and
restore successful.

Co-Authored-By: Jake Yip <jake.yip@unimelb.edu.au>

Closes-Bug: #1791878

Change-Id: Ia164345239197f93fb63697212a9b96c900fbe89
This commit is contained in:
Rocky 2018-09-11 22:55:39 +10:00
parent e10725fe38
commit 803b50d5ea
2 changed files with 19 additions and 16 deletions

View File

@ -83,8 +83,9 @@ class MySQLRestoreMixin(object):
if not os.path.exists(run_dir):
utils.execute("mkdir", run_dir,
run_as_root=True, root_helper="sudo")
utils.execute("chown", "mysql:mysql", run_dir, err_log_file.name,
run_as_root=True, root_helper="sudo")
utils.execute("chown", "mysql:mysql", run_dir, err_log_file.name,
init_file.name, run_as_root=True, root_helper="sudo")
child = pexpect.spawn(
"sudo mysqld_safe --init-file=%s --log-error=%s" %
(init_file.name, err_log_file.name))
@ -135,24 +136,26 @@ class MySQLRestoreMixin(object):
for initial datastore configuration.
"""
with tempfile.NamedTemporaryFile(mode='w') as init_file:
try:
# Do not attempt to delete these files as the 'trove' user.
# The process writing into it may have assumed its ownership.
# Only owners can delete temporary files (restricted deletion).
init_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
operating_system.write_file(init_file.name,
self.RESET_ROOT_MYSQL_COMMANDS)
operating_system.chmod(init_file.name, FileMode.ADD_READ_ALL,
as_root=True)
# Do not attempt to delete the file as the 'trove' user.
# The process writing into it may have assumed its ownership.
# Only owners can delete temporary
# files (restricted deletion).
err_log_file = tempfile.NamedTemporaryFile(
suffix=self._ERROR_LOG_SUFFIX,
delete=False)
try:
self._start_mysqld_safe_with_init_file(init_file, err_log_file)
finally:
err_log_file.close()
operating_system.remove(
err_log_file.name, force=True, as_root=True)
self._start_mysqld_safe_with_init_file(init_file, err_log_file)
finally:
init_file.close()
err_log_file.close()
operating_system.remove(
init_file.name, force=True, as_root=True)
operating_system.remove(
err_log_file.name, force=True, as_root=True)
def _find_first_error_message(self, fp):
if self._is_non_zero_file(fp):

View File

@ -14,7 +14,7 @@
import mock
import os
from mock import ANY, DEFAULT, Mock, patch, PropertyMock
from mock import ANY, call, DEFAULT, Mock, patch, PropertyMock
from testtools.testcase import ExpectedException
from trove.common import exception
from trove.common import utils
@ -356,9 +356,9 @@ class GuestAgentBackupTest(trove_testtools.TestCase):
chmod.assert_called_once_with(
ANY, operating_system.FileMode.ADD_READ_ALL, as_root=True)
# Make sure the temporary error log got deleted as root
# Make sure the temporary files got deleted as root
# (see bug/1423759).
remove.assert_called_once_with(ANY, force=True, as_root=True)
remove.assert_has_calls(2 * [call(ANY, force=True, as_root=True)])
@mock.patch.object(ImportOverrideStrategy, '_initialize_import_directory')
def test_backup_encrypted_mongodump_command(self, _):