trove/trove/guestagent/backup/backupagent.py

144 lines
5.7 KiB
Python

# Copyright 2013 Hewlett-Packard Development Company, L.P.
# 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
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
import logging
from trove.backup.models import DBBackup
from trove.backup.models import BackupState
from trove.common import cfg, utils
from trove.guestagent.dbaas import get_filesystem_volume_stats
from trove.guestagent.manager.mysql_service import ADMIN_USER_NAME
from trove.guestagent.manager.mysql_service import get_auth_password
from trove.guestagent.strategies.backup.base import BackupError
from trove.guestagent.strategies.backup.base import UnknownBackupType
from trove.guestagent.strategies.storage import get_storage_strategy
from trove.guestagent.strategies.backup import get_backup_strategy
from trove.guestagent.strategies.restore import get_restore_strategy
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
RUNNER = get_backup_strategy(CONF.backup_strategy,
CONF.backup_namespace)
BACKUP_CONTAINER = CONF.backup_swift_container
class BackupAgent(object):
def _get_restore_runner(self, backup_type):
"""Returns the RestoreRunner associated with this backup type."""
try:
runner = get_restore_strategy(backup_type, CONF.restore_namespace)
except ImportError:
raise UnknownBackupType("Unknown Backup type: %s" % backup_type)
return runner
def execute_backup(self, context, backup_id, runner=RUNNER):
LOG.debug("Searching for backup instance %s", backup_id)
backup = DBBackup.find_by(id=backup_id)
LOG.info("Setting task state to %s for instance %s",
BackupState.NEW, backup.instance_id)
backup.state = BackupState.NEW
backup.save()
LOG.info("Running backup %s", backup_id)
user = ADMIN_USER_NAME
password = get_auth_password()
swiftStorage = get_storage_strategy(
CONF.storage_strategy,
CONF.storage_namespace)(context)
# Store the size of the filesystem before the backup.
stats = get_filesystem_volume_stats(CONF.mount_point)
backup.size = stats.get('used', 0.0)
backup.state = BackupState.BUILDING
backup.save()
try:
with runner(filename=backup_id, user=user, password=password)\
as bkup:
LOG.info("Starting Backup %s", backup_id)
success, note, checksum, location = swiftStorage.save(
BACKUP_CONTAINER,
bkup)
LOG.info("Backup %s completed status: %s", backup_id, success)
LOG.info("Backup %s file size: %s", backup_id, bkup.content_length)
LOG.info('Backup %s file checksum: %s', backup_id, checksum)
LOG.info('Backup %s location: %s', backup_id, location)
if not success:
raise BackupError(backup.note)
except Exception as e:
LOG.error(e)
LOG.error("Error saving %s Backup", backup_id)
backup.state = BackupState.FAILED
backup.save()
raise
else:
LOG.info("Saving %s Backup Info to model", backup_id)
backup.state = BackupState.COMPLETED
backup.checksum = checksum
backup.location = location
backup.note = note
backup.backup_type = bkup.backup_type
backup.save()
def execute_restore(self, context, backup_id, restore_location):
try:
LOG.debug("Cleaning out restore location: %s", restore_location)
utils.execute_with_timeout("sudo", "chmod", "-R",
"0777", restore_location)
utils.clean_out(restore_location)
LOG.debug("Finding backup %s to restore", backup_id)
backup = DBBackup.find_by(id=backup_id)
LOG.debug("Getting Restore Runner of type %s", backup.backup_type)
restore_runner = self._get_restore_runner(backup.backup_type)
LOG.debug("Getting Storage Strategy")
storage_strategy = get_storage_strategy(
CONF.storage_strategy,
CONF.storage_namespace)(context)
LOG.debug("Preparing storage to download stream.")
download_stream = storage_strategy.load(context,
backup.location,
restore_runner.is_zipped)
with restore_runner(restore_stream=download_stream,
restore_location=restore_location) as runner:
LOG.debug("Restoring instance from backup %s to %s",
backup_id, restore_location)
content_size = runner.restore()
LOG.info("Restore from backup %s completed successfully to %s",
backup_id, restore_location)
LOG.info("Restore size: %s", content_size)
utils.execute_with_timeout("sudo", "chown", "-R",
"mysql", restore_location)
except Exception as e:
LOG.error(e)
LOG.error("Error restoring backup %s", backup_id)
raise
else:
LOG.info("Restored Backup %s", backup_id)