Esempio n. 1
0
    def _restore_backup(self):
        if not self._backup:
            return

        log.info("Restoring backup %s" % (self._backup, ))
        create_log.info("RESTORE-START:")
        new_name = db_settings.restore_database(self._backup)
        create_log.info("RESTORE-DONE:%s" % (new_name, ))
Esempio n. 2
0
    def _restore_backup(self):
        if not self._backup:
            return

        log.info("Restoring backup %s" % (self._backup, ))
        create_log.info("RESTORE-START:")
        new_name = db_settings.restore_database(self._backup)
        create_log.info("RESTORE-DONE:%s" % (new_name, ))
Esempio n. 3
0
def restore_database(user_hash, time=None):
    assert user_hash

    # If the database doesn't exist, get_default_store will fail
    try:
        default_store = get_default_store()
    except Exception:
        default_store = None

    if default_store is not None and db_settings.has_database():
        try:
            default_store.lock_database()
        except DatabaseError:
            raise TaskException(
                "Could not lock database. This means that there are other "
                "clients connected. Make sure to close every Stoq client "
                "before updating the database")
        except Exception:
            raise TaskException(
                "Database is empty or in a corrupted state. Fix or drop it "
                "before trying to proceed with the restore")
        else:
            default_store.unlock_database()

        # FIXME: Windows will not liberate resource for other process to
        # write to the file. We should write our own TemporaryFile on Stoq
        # that handles all those cases for us and use here
        with tempfile.NamedTemporaryFile(delete=False) as f:
            pass
        try:
            if not db_settings.dump_database(f.name):
                raise TaskException("Failed to dump the database")
            backup_name = db_settings.restore_database(f.name)
            logger.info("Created a backup of the current database state on %s",
                        backup_name)
        finally:
            os.unlink(f.name)

    tmp_path = tempfile.mkdtemp()
    try:
        restore_path = os.path.join(tmp_path, 'stoq')
        backup.restore(restore_path, user_hash, time=time)

        # None will make the default store be closed, which we need
        # to sucessfully restore the database
        set_default_store(None)
        db_settings.clean_database(db_settings.dbname, force=True)
        db_settings.execute_sql(os.path.join(restore_path, 'stoq.dump'),
                                lock_database=True)

        logger.info("Backup restore finished sucessfully")
    finally:
        # get_default_store will recreate it (since we closed it above)
        get_default_store()
        shutil.rmtree(tmp_path, ignore_errors=True)
Esempio n. 4
0
def restore_database(user_hash, time=None):
    assert user_hash

    # If the database doesn't exist, get_default_store will fail
    try:
        default_store = get_default_store()
    except Exception:
        default_store = None

    if default_store is not None and db_settings.has_database():
        try:
            default_store.lock_database()
        except DatabaseError:
            raise TaskException(
                "Could not lock database. This means that there are other "
                "clients connected. Make sure to close every Stoq client "
                "before updating the database")
        except Exception:
            raise TaskException(
                "Database is empty or in a corrupted state. Fix or drop it "
                "before trying to proceed with the restore")
        else:
            default_store.unlock_database()

        # FIXME: Windows will not liberate resource for other process to
        # write to the file. We should write our own TemporaryFile on Stoq
        # that handles all those cases for us and use here
        with tempfile.NamedTemporaryFile(delete=False) as f:
            pass
        try:
            if not db_settings.dump_database(f.name):
                raise TaskException("Failed to dump the database")
            backup_name = db_settings.restore_database(f.name)
            logger.info("Created a backup of the current database state on %s",
                        backup_name)
        finally:
            os.unlink(f.name)

    tmp_path = tempfile.mkdtemp()
    try:
        restore_path = os.path.join(tmp_path, 'stoq')
        logger.info("restoring database to %s", restore_path)
        backup.restore(restore_path, user_hash, time=time)

        # None will make the default store be closed, which we need
        # to sucessfully restore the database
        set_default_store(None)
        db_settings.clean_database(db_settings.dbname, force=True)
        db_settings.execute_sql(os.path.join(restore_path, 'stoq.dump'),
                                lock_database=True)

        logger.info("Backup restore finished sucessfully")
    finally:
        # get_default_store will recreate it (since we closed it above)
        get_default_store()
Esempio n. 5
0
def restore_database(user_hash, time=None):
    assert user_hash

    # If the database doesn't exist, get_default_store will fail
    try:
        default_store = get_default_store()
    except Exception:
        default_store = None

    if default_store is not None and db_settings.has_database():
        try:
            default_store.lock_database()
        except DatabaseError:
            raise TaskException(
                "Could not lock database. This means that there are other "
                "clients connected. Make sure to close every Stoq client "
                "before updating the database")
        except Exception:
            raise TaskException(
                "Database is empty or in a corrupted state. Fix or drop it "
                "before trying to proceed with the restore")
        else:
            default_store.unlock_database()

        with tempfile.NamedTemporaryFile() as f:
            if not db_settings.dump_database(f.name):
                raise TaskException("Failed to dump the database")
            backup_name = db_settings.restore_database(f.name)
            logger.info("Created a backup of the current database state on %s",
                        backup_name)

    tmp_path = tempfile.mkdtemp()
    try:
        # None will make the default store be closed, which we need
        # to sucessfully restore the database
        set_default_store(None)
        restore_path = os.path.join(tmp_path, 'stoq')

        backup.restore(restore_path, user_hash, time=time)

        db_settings.clean_database(db_settings.dbname, force=True)
        db_settings.execute_sql(os.path.join(restore_path, 'stoq.dump'),
                                lock_database=True)

        logger.info("Backup restore finished sucessfully")
    finally:
        # get_default_store will recreate it (since we closed it above)
        get_default_store()
        shutil.rmtree(tmp_path, ignore_errors=True)
Esempio n. 6
0
    def update(self, plugins=True, backup=True):
        log.info("Upgrading database (plugins=%r, backup=%r)" % (
            plugins, backup))

        try:
            log.info("Locking database")
            self.default_store.lock_database()
        except DatabaseError:
            msg = _('Could not lock database. This means there are other clients '
                    'connected. Make sure to close every Stoq client '
                    'before updating the database')
            error(msg)

        # Database migration is actually run in subprocesses, We need to unlock
        # the tables again and let the upgrade continue
        log.info("Releasing database lock")
        self.default_store.unlock_database()

        sucess = db_settings.test_connection()
        if not sucess:
            # FIXME: Improve this message after 1.5 is released
            msg = _(u'Could not connect to the database using command line '
                    'tool! Aborting.') + ' '
            msg += _(u'Please, check if you can connect to the database '
                    'using:') + ' '
            msg += _(u'psql -l -h <server> -p <port> -U <username>')
            error(msg)
            return

        if backup:
            temporary = tempfile.mktemp(prefix="stoq-dump-")
            log.info("Making a backup to %s" % (temporary, ))
            create_log.info("BACKUP-START:")
            success = db_settings.dump_database(temporary)
            if not success:
                info(_(u'Could not create backup! Aborting.'))
                info(_(u'Please contact stoq team to inform this problem.\n'))
                return

        # We have to wrap a try/except statement inside a try/finally to
        # support python previous to 2.5 version.
        try:
            try:
                super(StoqlibSchemaMigration, self).update()
                if plugins:
                    self.update_plugins()
            except Exception:
                exc = sys.exc_info()
                tb_str = ''.join(traceback.format_exception(*exc))
                collect_traceback(exc, submit=True)
                create_log.info("ERROR:%s" % (tb_str, ))

                if backup:
                    log.info("Restoring backup %s" % (temporary, ))
                    create_log.info("RESTORE-START:")
                    new_name = db_settings.restore_database(temporary)
                    create_log.info("RESTORE-DONE:%s" % (new_name, ))
                return False
        finally:
            if backup is True:
                os.unlink(temporary)
        log.info("Migration done")
        return True
Esempio n. 7
0
    def update(self, plugins=True, backup=True):
        log.info("Upgrading database (plugins=%r, backup=%r)" %
                 (plugins, backup))

        try:
            log.info("Locking database")
            self.default_store.lock_database()
        except DatabaseError:
            msg = _(
                'Could not lock database. This means there are other clients '
                'connected. Make sure to close every Stoq client '
                'before updating the database')
            error(msg)

        # Database migration is actually run in subprocesses, We need to unlock
        # the tables again and let the upgrade continue
        log.info("Releasing database lock")
        self.default_store.unlock_database()

        sucess = db_settings.test_connection()
        if not sucess:
            # FIXME: Improve this message after 1.5 is released
            msg = _(u'Could not connect to the database using command line '
                    'tool! Aborting.') + ' '
            msg += _(u'Please, check if you can connect to the database '
                     'using:') + ' '
            msg += _(u'psql -l -h <server> -p <port> -U <username>')
            error(msg)
            return

        if backup:
            temporary = tempfile.mktemp(prefix="stoq-dump-")
            log.info("Making a backup to %s" % (temporary, ))
            create_log.info("BACKUP-START:")
            success = db_settings.dump_database(temporary)
            if not success:
                info(_(u'Could not create backup! Aborting.'))
                info(_(u'Please contact stoq team to inform this problem.\n'))
                return

        # We have to wrap a try/except statement inside a try/finally to
        # support python previous to 2.5 version.
        try:
            try:
                super(StoqlibSchemaMigration, self).update()
                if plugins:
                    self.update_plugins()
            except Exception:
                exc = sys.exc_info()
                tb_str = ''.join(traceback.format_exception(*exc))
                collect_traceback(exc, submit=True)
                create_log.info("ERROR:%s" % (tb_str, ))

                if backup:
                    log.info("Restoring backup %s" % (temporary, ))
                    create_log.info("RESTORE-START:")
                    new_name = db_settings.restore_database(temporary)
                    create_log.info("RESTORE-DONE:%s" % (new_name, ))
                return False
        finally:
            if backup is True:
                os.unlink(temporary)
        log.info("Migration done")
        return True