Ejemplo n.º 1
0
    def expand(self, online_migration=True):
        """Run the expansion phase of a database migration."""
        if online_migration:
            self._validate_engine(db_api.get_engine())

        curr_heads = alembic_migrations.get_current_alembic_heads()
        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        contract_head = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        if not expand_head:
            sys.exit(
                _('Database expansion failed. Couldn\'t find head '
                  'revision of expand branch.'))
        elif (contract_head in curr_heads):
            print(_('Database is up to date. No migrations needed.'))
            sys.exit()

        if expand_head not in curr_heads:
            self._sync(version=expand_head)

            curr_heads = alembic_migrations.get_current_alembic_heads()
            if expand_head not in curr_heads:
                sys.exit(
                    _('Database expansion failed. Database expansion '
                      'should have brought the database version up to '
                      '"%(e_rev)s" revision. But, current revisions are'
                      ': %(curr_revs)s ') % {
                          'e_rev': expand_head,
                          'curr_revs': curr_heads
                      })
        else:
            print(_('Database expansion is up to date. No expansion needed.'))
Ejemplo n.º 2
0
    def expand(self):
        """Run the expansion phase of a rolling upgrade procedure."""
        engine = db_api.get_engine()
        if engine.engine.name != 'mysql':
            sys.exit(
                _('Rolling upgrades are currently supported only for '
                  'MySQL'))

        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        if not expand_head:
            sys.exit(
                _('Database expansion failed. Couldn\'t find head '
                  'revision of expand branch.'))

        self.sync(version=expand_head)

        curr_heads = alembic_migrations.get_current_alembic_heads()
        if expand_head not in curr_heads:
            sys.exit(
                _('Database expansion failed. Database expansion should '
                  'have brought the database version up to "%(e_rev)s" '
                  'revision. But, current revisions are: %(curr_revs)s ') % {
                      'e_rev': expand_head,
                      'curr_revs': curr_heads
                  })
Ejemplo n.º 3
0
    def check(self):
        """Report any pending database upgrades.

        An exit code of 3 indicates db expand is needed, see stdout output.
        An exit code of 4 indicates db migrate is needed, see stdout output.
        An exit code of 5 indicates db contract is needed, see stdout output.
        """
        engine = db_api.get_engine()
        self._validate_engine(engine)

        curr_heads = alembic_migrations.get_current_alembic_heads()

        expand_heads = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        contract_heads = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        if (contract_heads in curr_heads):
            print(_('Database is up to date. No upgrades needed.'))
            sys.exit()
        elif ((not expand_heads) or (expand_heads not in curr_heads)):
            print(
                _('Your database is not up to date. '
                  'Your first step is to run `glance-manage db expand`.'))
            sys.exit(3)
        elif data_migrations.has_pending_migrations(db_api.get_engine()):
            print(
                _('Your database is not up to date. '
                  'Your next step is to run `glance-manage db migrate`.'))
            sys.exit(4)
        elif ((not contract_heads) or (contract_heads not in curr_heads)):
            print(
                _('Your database is not up to date. '
                  'Your next step is to run `glance-manage db contract`.'))
            sys.exit(5)
Ejemplo n.º 4
0
    def migrate(self, online_migration=True):
        """Run the data migration phase of a database migration."""
        if online_migration:
            self._validate_engine(db_api.get_engine())

        curr_heads = alembic_migrations.get_current_alembic_heads()
        contract_head = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        if (contract_head in curr_heads):
            print(_('Database is up to date. No migrations needed.'))
            sys.exit()

        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        if expand_head not in curr_heads:
            sys.exit(
                _('Data migration did not run. Data migration cannot be '
                  'run before database expansion. Run database '
                  'expansion first using "glance-manage db expand"'))

        if data_migrations.has_pending_migrations(db_api.get_engine()):
            rows_migrated = data_migrations.migrate(db_api.get_engine())
            print(_('Migrated %s rows') % rows_migrated)
        else:
            print(_('Database migration is up to date. No migration needed.'))
Ejemplo n.º 5
0
    def sync(self, version=None):
        """Perform a complete (offline) database migration"""
        global USE_TRIGGERS

        # This flags let's us bypass trigger setup & teardown for non-rolling
        # upgrades. We set this as a global variable immediately before handing
        # off to sqlalchemy-migrate, because we can't pass arguments directly
        # to migrations that depend on it.
        USE_TRIGGERS = False

        curr_heads = alembic_migrations.get_current_alembic_heads()
        contract = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        if (contract in curr_heads):
            print(_('Database is up to date. No migrations needed.'))
            sys.exit()

        try:
            # NOTE(abhishekk): db_sync should not be used for online
            # migrations.
            self.expand(online_migration=False)
            self.migrate(online_migration=False)
            self.contract(online_migration=False)
            print(_('Database is synced successfully.'))
        except exception.GlanceException as e:
            sys.exit(_('Failed to sync database: ERROR: %s') % e)
Ejemplo n.º 6
0
    def contract(self, online_migration=True):
        """Run the contraction phase of a database migration."""
        if online_migration:
            self._validate_engine(db_api.get_engine())

        curr_heads = alembic_migrations.get_current_alembic_heads()
        contract_head = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        if not contract_head:
            sys.exit(
                _('Database contraction failed. Couldn\'t find head '
                  'revision of contract branch.'))
        elif (contract_head in curr_heads):
            print(_('Database is up to date. No migrations needed.'))
            sys.exit()

        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        if expand_head not in curr_heads:
            sys.exit(
                _('Database contraction did not run. Database '
                  'contraction cannot be run before database expansion. '
                  'Run database expansion first using '
                  '"glance-manage db expand"'))

        if data_migrations.has_pending_migrations(db_api.get_engine()):
            sys.exit(
                _('Database contraction did not run. Database '
                  'contraction cannot be run before data migration is '
                  'complete. Run data migration using "glance-manage db '
                  'migrate".'))

        self._sync(version=contract_head)

        curr_heads = alembic_migrations.get_current_alembic_heads()
        if contract_head not in curr_heads:
            sys.exit(
                _('Database contraction failed. Database contraction '
                  'should have brought the database version up to '
                  '"%(e_rev)s" revision. But, current revisions are: '
                  '%(curr_revs)s ') % {
                      'e_rev': expand_head,
                      'curr_revs': curr_heads
                  })
Ejemplo n.º 7
0
    def contract(self):
        """Run the contraction phase of a rolling upgrade procedure."""
        engine = db_api.get_engine()
        if engine.engine.name != 'mysql':
            sys.exit(
                _('Rolling upgrades are currently supported only for '
                  'MySQL'))

        contract_head = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)
        if not contract_head:
            sys.exit(
                _('Database contraction failed. Couldn\'t find head '
                  'revision of contract branch.'))

        curr_heads = alembic_migrations.get_current_alembic_heads()
        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        if expand_head not in curr_heads:
            sys.exit(
                _('Database contraction did not run. Database '
                  'contraction cannot be run before database expansion. '
                  'Run database expansion first using '
                  '"glance-manage db expand"'))

        if data_migrations.has_pending_migrations(db_api.get_engine()):
            sys.exit(
                _('Database contraction did not run. Database '
                  'contraction cannot be run before data migration is '
                  'complete. Run data migration using "glance-manage db '
                  'migrate".'))

        self.sync(version=contract_head)

        curr_heads = alembic_migrations.get_current_alembic_heads()
        if contract_head not in curr_heads:
            sys.exit(
                _('Database contraction failed. Database contraction '
                  'should have brought the database version up to '
                  '"%(e_rev)s" revision. But, current revisions are: '
                  '%(curr_revs)s ') % {
                      'e_rev': expand_head,
                      'curr_revs': curr_heads
                  })
Ejemplo n.º 8
0
 def version(self):
     """Print database's current migration level"""
     current_heads = alembic_migrations.get_current_alembic_heads()
     if current_heads:
         # Migrations are managed by alembic
         for head in current_heads:
             print(head)
     else:
         # Migrations are managed by legacy versioning scheme
         print(
             _('Database is either not under migration control or under '
               'legacy migration control, please run '
               '"glance-manage db sync" to place the database under '
               'alembic migration control.'))
Ejemplo n.º 9
0
    def migrate(self):
        engine = db_api.get_engine()
        if engine.engine.name != 'mysql':
            sys.exit(
                _('Rolling upgrades are currently supported only for '
                  'MySQL'))

        curr_heads = alembic_migrations.get_current_alembic_heads()
        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)
        if expand_head not in curr_heads:
            sys.exit(
                _('Data migration did not run. Data migration cannot be '
                  'run before database expansion. Run database '
                  'expansion first using "glance-manage db expand"'))

        rows_migrated = data_migrations.migrate(db_api.get_engine())
        print(_('Migrated %s rows') % rows_migrated)
Ejemplo n.º 10
0
    def _sync(self, version):
        """
        Place an existing database under migration control and upgrade it.
        """

        alembic_migrations.place_database_under_alembic_control()

        a_config = alembic_migrations.get_alembic_config()
        alembic_command.upgrade(a_config, version)
        heads = alembic_migrations.get_current_alembic_heads()
        if heads is None:
            raise exception.GlanceException("Database sync failed")
        revs = ", ".join(heads)
        if version == 'heads':
            print(_("Upgraded database, current revision(s):"), revs)
        else:
            print(
                _('Upgraded database to: %(v)s, current revision(s): %(r)s') %
                {
                    'v': version,
                    'r': revs
                })