Пример #1
0
def restore_mysql(cfg, dst, backup_copy, cache):
    """Restore from mysql backup"""
    LOG.debug('mysql: %r', cfg)

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(cfg)
        exit(1)

    try:
        ensure_empty(dst)
        dst_storage = get_destination(
            cfg,
            get_hostname_from_backup_copy(backup_copy)
        )
        key = dst_storage.basename(backup_copy)
        copy = dst_storage.status()[key]
        if cache:
            restore_from_mysql(cfg, copy, dst, cache=Cache(cache))
        else:
            restore_from_mysql(cfg, copy, dst)

    except (TwinDBBackupError, CacheException) as err:
        LOG.error(err)
        exit(1)
    except (OSError, IOError) as err:
        LOG.error(err)
        exit(1)
Пример #2
0
def verify_mysql(cfg, hostname, dst, backup_copy):
    """Verify backup"""
    LOG.debug('mysql: %r', cfg)

    if not backup_copy:
        list_available_backups(cfg)
        exit(1)

    print(verify_mysql_backup(cfg, dst, backup_copy, hostname))
Пример #3
0
def restore_mysql(ctx, dst, backup_copy, cache):
    """Restore from mysql backup"""
    LOG.debug('mysql: %r', ctx.obj['twindb_config'])

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)

    try:
        ensure_empty(dst)

        incomplete_copy = MySQLCopy(
            path=backup_copy
        )
        dst_storage = ctx.obj['twindb_config'].destination(
            backup_source=incomplete_copy.host
        )
        mysql_status = MySQLStatus(dst=dst_storage)

        copies = [
            cp for cp in mysql_status if backup_copy.endswith(cp.name)
        ]
        try:
            copy = copies.pop(0)
        except IndexError:
            raise TwinDBBackupError(
                'Can not find copy %s in MySQL status. '
                'Inspect output of `twindb-backup status` and verify '
                'that correct copy is specified.'
                % backup_copy
            )
        if copies:
            raise TwinDBBackupError(
                'Multiple copies match pattern %s. Make sure you give unique '
                'copy name for restore.'
            )

        if cache:
            restore_from_mysql(
                ctx.obj['twindb_config'],
                copy,
                dst,
                cache=Cache(cache)
            )
        else:
            restore_from_mysql(ctx.obj['twindb_config'], copy, dst)

    except (TwinDBBackupError, CacheException) as err:
        LOG.error(err)
        LOG.debug(traceback.format_exc())
        exit(1)
    except (OSError, IOError) as err:
        LOG.error(err)
        LOG.debug(traceback.format_exc())
        exit(1)
Пример #4
0
def share_backup(ctx, s3_url):
    """Share backup copy for download"""
    if not s3_url:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)
    try:
        share(ctx.obj['twindb_config'], s3_url)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
Пример #5
0
def share_backup(ctx, s3_url):
    """Share backup copy for download"""
    if not s3_url:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)
    try:
        share(ctx.obj['twindb_config'], s3_url)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
Пример #6
0
def test_list_available_backups_ssh(mock_get_destination, tmpdir):

    backup_dir = tmpdir.mkdir('backups')

    mock_config = mock.Mock()
    mock_config.get.return_value = str(backup_dir)

    # Ssh destination
    mock_dst = mock.Mock()
    mock_dst.remote_path = '/foo/bar'

    mock_get_destination.return_value = mock_dst
    mock_dst.list_files.return_value = []

    list_available_backups(mock_config)

    calls = [
        mock.call(
            '/foo/bar', pattern='/hourly/files/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/daily/files/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/weekly/files/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/monthly/files/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/yearly/files/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/hourly/mysql/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/daily/mysql/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/weekly/mysql/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/monthly/mysql/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', pattern='/yearly/mysql/', recursive=True, files_only=True
        ),
        mock.call(
            '/foo/bar', files_only=True, pattern='/binlog/', recursive=True
        )
    ]
    mock_dst.list_files.assert_has_calls(calls)
Пример #7
0
def verify_mysql(cfg, hostname, dst, backup_copy):
    """Verify backup"""
    LOG.debug('mysql: %r', cfg)

    try:
        if not backup_copy:
            list_available_backups(cfg)
            exit(1)

        print(verify_mysql_backup(cfg, dst, backup_copy, hostname))

    finally:

        shutil.rmtree(dst, ignore_errors=True)
Пример #8
0
def restore_file(cfg, dst, backup_copy):
    """Restore from file backup"""
    LOG.debug('file: %r', cfg)

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(cfg)
        exit(1)

    try:
        ensure_empty(dst)
        restore_from_file(cfg, backup_copy, dst)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
Пример #9
0
def verify_mysql(ctx, hostname, dst, backup_copy):
    """Verify backup"""
    LOG.debug("mysql: %r", ctx.obj["twindb_config"])

    try:
        if not backup_copy:
            list_available_backups(ctx.obj["twindb_config"])
            exit(1)

        print(
            verify_mysql_backup(ctx.obj["twindb_config"], dst, backup_copy,
                                hostname))

    finally:

        shutil.rmtree(dst, ignore_errors=True)
Пример #10
0
def restore_mysql(ctx, dst, backup_copy, cache):
    """Restore from mysql backup"""
    LOG.debug('mysql: %r', ctx.obj['twindb_config'])

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)

    try:
        ensure_empty(dst)

        incomplete_copy = MySQLCopy(path=backup_copy)
        dst_storage = ctx.obj['twindb_config'].destination(
            backup_source=incomplete_copy.host)
        mysql_status = MySQLStatus(dst=dst_storage,
                                   status_directory=incomplete_copy.host)

        copies = [cp for cp in mysql_status if backup_copy.endswith(cp.name)]
        try:
            copy = copies.pop(0)
        except IndexError:
            raise TwinDBBackupError(
                'Can not find copy %s in MySQL status. '
                'Inspect output of `twindb-backup status` and verify '
                'that correct copy is specified.' % backup_copy)
        if copies:
            raise TwinDBBackupError(
                'Multiple copies match pattern %s. Make sure you give unique '
                'copy name for restore.')

        if cache:
            restore_from_mysql(ctx.obj['twindb_config'],
                               copy,
                               dst,
                               cache=Cache(cache))
        else:
            restore_from_mysql(ctx.obj['twindb_config'], copy, dst)

    except (TwinDBBackupError, CacheException) as err:
        LOG.error(err)
        LOG.debug(traceback.format_exc())
        exit(1)
    except (OSError, IOError) as err:
        LOG.error(err)
        LOG.debug(traceback.format_exc())
        exit(1)
Пример #11
0
def restore_file(ctx, dst, backup_copy):
    """Restore from file backup"""
    LOG.debug('file: %r', ctx.obj['twindb_config'])

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)

    try:
        ensure_empty(dst)
        copy = FileCopy(path=backup_copy)
        restore_from_file(ctx.obj['twindb_config'], copy, dst)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
    except KeyboardInterrupt:
        LOG.info('Exiting...')
        kill_children()
        exit(1)
Пример #12
0
def restore_file(ctx, dst, backup_copy):
    """Restore from file backup"""
    LOG.debug('file: %r', ctx.obj['twindb_config'])

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(ctx.obj['twindb_config'])
        exit(1)

    try:
        ensure_empty(dst)
        copy = FileCopy(path=backup_copy)
        restore_from_file(ctx.obj['twindb_config'], copy, dst)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
    except KeyboardInterrupt:
        LOG.info('Exiting...')
        kill_children()
        exit(1)
Пример #13
0
def verify_mysql(ctx, hostname, dst, backup_copy):
    """Verify backup"""
    LOG.debug('mysql: %r', ctx.obj['twindb_config'])

    try:
        if not backup_copy:
            list_available_backups(ctx.obj['twindb_config'])
            exit(1)

        print(
            verify_mysql_backup(
                ctx.obj['twindb_config'],
                dst,
                backup_copy,
                hostname
            )
        )

    finally:

        shutil.rmtree(dst, ignore_errors=True)
Пример #14
0
def restore_mysql(cfg, dst, backup_copy, cache):
    """Restore from mysql backup"""
    LOG.debug('mysql: %r', cfg)

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(cfg)
        exit(1)

    try:
        ensure_empty(dst)
        if cache:
            restore_from_mysql(cfg, backup_copy, dst, cache=Cache(cache))
        else:
            restore_from_mysql(cfg, backup_copy, dst)

    except (TwinDBBackupError, CacheException) as err:
        LOG.error(err)
        exit(1)
    except (OSError, IOError) as err:
        LOG.error(err)
        exit(1)
Пример #15
0
def restore_file(cfg, dst, backup_copy):
    """Restore from file backup"""
    LOG.debug('file: %r', cfg)

    if not backup_copy:
        LOG.info('No backup copy specified. Choose one from below:')
        list_available_backups(cfg)
        exit(1)

    try:
        ensure_empty(dst)
        copy = FileCopy(
            get_hostname_from_backup_copy(backup_copy),
            basename(backup_copy),
            get_run_type_from_backup_copy(backup_copy)
        )
        restore_from_file(cfg, copy, dst)
    except TwinDBBackupError as err:
        LOG.error(err)
        exit(1)
    except KeyboardInterrupt:
        LOG.info('Exiting...')
        kill_children()
        exit(1)
Пример #16
0
def test_list_available_backups_ssh(mock_popen, mock_get_destination, mock_os):

    mock_os.path.exists.return_value = True

    mock_config = mock.Mock()
    mock_config.get.return_value = "/foo/bar"

    mock_dst = mock.Mock()
    mock_dst.remote_path = '/foo/bar'

    mock_get_destination.return_value = mock_dst
    mock_dst.find_files.return_value = []

    list_available_backups(mock_config)
    mock_popen.assert_called_once_with(["find", '/foo/bar', '-type', 'f'])

    calls = [
        mock.call('/foo/bar', 'hourly'),
        mock.call('/foo/bar', 'daily'),
        mock.call('/foo/bar', 'weekly'),
        mock.call('/foo/bar', 'monthly'),
        mock.call('/foo/bar', 'yearly'),
    ]
    mock_dst.find_files.assert_has_calls(calls)
Пример #17
0
def test_list_available_backups_ssh():

    mock_config = mock.Mock()
    mock_config.keep_local_path = None

    # Ssh destination
    mock_dst = mock.Mock()
    mock_dst.remote_path = '/foo/bar'
    mock_dst.list_files.return_value = []

    mock_config.destination.return_value = mock_dst

    list_available_backups(mock_config)

    calls = [
        mock.call('/foo/bar',
                  pattern='/hourly/files/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/daily/files/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/weekly/files/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/monthly/files/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/yearly/files/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/hourly/mysql/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/daily/mysql/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/weekly/mysql/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/monthly/mysql/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  pattern='/yearly/mysql/',
                  recursive=True,
                  files_only=True),
        mock.call('/foo/bar',
                  files_only=True,
                  pattern='/binlog/',
                  recursive=True)
    ]
    mock_dst.list_files.assert_has_calls(calls)
Пример #18
0
def list_backups(ctx, copy_type):
    """List available backup copies"""
    list_available_backups(
        ctx.obj['twindb_config'],
        copy_type=copy_type
    )
Пример #19
0
def list_backups(ctx, copy_type):
    """List available backup copies"""
    list_available_backups(ctx.obj['twindb_config'], copy_type=copy_type)
Пример #20
0
def list_backups(cfg, copy_type):
    """List available backup copies"""
    list_available_backups(
        cfg,
        copy_type=copy_type
    )
Пример #21
0
def list_backups(cfg):
    """List available backup copies"""
    list_available_backups(cfg)