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
This commit is contained in:
Hirotaka Wakabayashi 2023-01-27 14:34:49 +09:00
parent 7a62e826a4
commit 553c578923
2 changed files with 61 additions and 29 deletions

View File

@ -1,4 +1,4 @@
FROM ubuntu:18.04 FROM ubuntu:20.04
LABEL maintainer="anlin.kong@gmail.com" LABEL maintainer="anlin.kong@gmail.com"
ARG DATASTORE="mysql5.7" ARG DATASTORE="mysql5.7"

View File

@ -205,43 +205,75 @@ class MySqlManager(manager.Manager):
root_pass = utils.generate_random_password() root_pass = utils.generate_random_password()
self.app.save_password('root', root_pass) self.app.save_password('root', root_pass)
with tempfile.NamedTemporaryFile(mode='w') as init_file, \ init_file = tempfile.NamedTemporaryFile(mode='w')
tempfile.NamedTemporaryFile(suffix='.err') as err_file: operating_system.write_file(
operating_system.write_file( init_file.name,
init_file.name, f"ALTER USER 'root'@'localhost' IDENTIFIED BY '{root_pass}';"
f"ALTER USER 'root'@'localhost' IDENTIFIED BY '{root_pass}';" )
) err_file = tempfile.NamedTemporaryFile(suffix='.err')
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. # 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]: for file in [init_file.name, err_file.name]:
operating_system.chmod(file, operating_system.chown(file, CONF.database_service_uid,
operating_system.FileMode.SET_ALL_RWX(), CONF.database_service_uid, force=True,
force=True, as_root=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: 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( LOG.debug(
'The init container log: %s', 'The init container log: %s',
docker_util.get_container_logs(self.app.docker_client) docker_util.get_container_logs(self.app.docker_client)
) )
docker_util.remove_container(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') LOG.info('Finished to reset password for restore')