diff options
author | Hirotaka Wakabayashi <hiwkby@yahoo.com> | 2023-01-27 14:34:49 +0900 |
---|---|---|
committer | Hirotaka Wakabayashi <hiwkby@yahoo.com> | 2023-01-27 15:06:37 +0900 |
commit | 553c578923d30d0eb15ad5dbd0a2c583cae274a4 (patch) | |
tree | 935a64a0eb2b3175c48ba0fcb119a0025142852d | |
parent | 7a62e826a402de29b6a929569dab27adb3259975 (diff) | |
download | trove-553c578923d30d0eb15ad5dbd0a2c583cae274a4.tar.gz |
Fixes permission problem when restoring backup
This PR changes the owner of the file used by the docker container that
resets the mysql root password.
Original problem is the failure to restore mysql:5.7.x backup. The error
occurs because the container process tries to update the file that owned
by the others.
Story: 2010467
Task: 47017
Change-Id: I3d8ebaac4ee5e13af83c305ce28b51e4442d8c8b
-rw-r--r-- | backup/Dockerfile | 2 | ||||
-rw-r--r-- | trove/guestagent/datastore/mysql_common/manager.py | 90 |
2 files changed, 62 insertions, 30 deletions
diff --git a/backup/Dockerfile b/backup/Dockerfile index 3827bfc7..0d542db2 100644 --- a/backup/Dockerfile +++ b/backup/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM ubuntu:20.04 LABEL maintainer="anlin.kong@gmail.com" ARG DATASTORE="mysql5.7" diff --git a/trove/guestagent/datastore/mysql_common/manager.py b/trove/guestagent/datastore/mysql_common/manager.py index cd6546a1..890981fc 100644 --- a/trove/guestagent/datastore/mysql_common/manager.py +++ b/trove/guestagent/datastore/mysql_common/manager.py @@ -205,43 +205,75 @@ class MySqlManager(manager.Manager): root_pass = utils.generate_random_password() self.app.save_password('root', root_pass) - with tempfile.NamedTemporaryFile(mode='w') as init_file, \ - tempfile.NamedTemporaryFile(suffix='.err') as err_file: - operating_system.write_file( - init_file.name, - f"ALTER USER 'root'@'localhost' IDENTIFIED BY '{root_pass}';" - ) - command = ( - f'mysqld_safe --init-file={init_file.name} ' - f'--log-error={err_file.name} ' - f'--datadir={data_dir}' - ) - extra_volumes = { - init_file.name: {"bind": init_file.name, "mode": "rw"}, - err_file.name: {"bind": err_file.name, "mode": "rw"}, - } - - # Allow database service user to access the temporary files. + init_file = tempfile.NamedTemporaryFile(mode='w') + operating_system.write_file( + init_file.name, + f"ALTER USER 'root'@'localhost' IDENTIFIED BY '{root_pass}';" + ) + err_file = tempfile.NamedTemporaryFile(suffix='.err') + + # Get the original file owner and group before changing the owner. + from pathlib import Path + init_file_path = Path(init_file.name) + init_file_owner = init_file_path.owner() + init_file_group = init_file_path.group() + + # Allow database service user to access the temporary files. + try: for file in [init_file.name, err_file.name]: - operating_system.chmod(file, - operating_system.FileMode.SET_ALL_RWX(), - force=True, as_root=True) + operating_system.chown(file, CONF.database_service_uid, + CONF.database_service_uid, force=True, + as_root=True) + except Exception as err: + LOG.error('Failed to change file owner, error: %s', str(err)) + for file in [init_file.name, err_file.name]: + LOG.debug('Reverting the %s owner to %s ' + 'before close it.', file, init_file_owner) + operating_system.chown(file, init_file_owner, + init_file_group, force=True, + as_root=True) + init_file.close() + err_file.close() + raise err + + # Allow database service user to access the temporary files. + command = ( + f'mysqld --init-file={init_file.name} ' + f'--log-error={err_file.name} ' + f'--datadir={data_dir} ' + ) + extra_volumes = { + init_file.name: {"bind": init_file.name, "mode": "rw"}, + err_file.name: {"bind": err_file.name, "mode": "rw"}, + } + # Start the database container process. + try: + self.app.start_db(ds_version=ds_version, command=command, + extra_volumes=extra_volumes) + except Exception as err: + LOG.error('Failed to reset password for restore, error: %s', + str(err)) + raise err # re-raised at the end of the finally clause + finally: try: - self.app.start_db(ds_version=ds_version, command=command, - extra_volumes=extra_volumes) - except Exception as err: - LOG.error('Failed to reset password for restore, error: %s', - str(err)) - LOG.debug('Content in init error log file: %s', - err_file.read()) - raise err - finally: LOG.debug( 'The init container log: %s', docker_util.get_container_logs(self.app.docker_client) ) docker_util.remove_container(self.app.docker_client) + except Exception as err: + LOG.error('Failed to remove container. error: %s', + str(err)) + pass + for file in [init_file.name, err_file.name]: + LOG.debug('Reverting the %s owner to %s ' + 'before close it.', file, init_file_owner) + operating_system.chown(file, init_file_owner, + init_file_group, force=True, + as_root=True) + init_file.close() + err_file.close() LOG.info('Finished to reset password for restore') |