示例#1
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)
    def test_has_pending_migrations_one_migration_with_pending(
            self, mock_find):
        mock_migration1 = mock.Mock()
        mock_migration1.has_migrations.return_value = True
        mock_find.return_value = [mock_migration1]

        self.assertTrue(data_migrations.has_pending_migrations(mock.Mock()))
示例#3
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.'))
    def test_has_pending_migrations_one_migration_with_pending(self,
                                                               mock_find):
        mock_migration1 = mock.Mock()
        mock_migration1.has_migrations.return_value = True
        mock_find.return_value = [mock_migration1]

        self.assertTrue(data_migrations.has_pending_migrations(mock.Mock()))
示例#5
0
    def test_migrate(self):
        """Test DB migrate"""
        self._db_command(db_method='expand')
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            self._db_command(db_method='migrate')
        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)

        cmd = ("sqlite3 {0} \"SELECT version_num FROM alembic_version\""
               ).format(self.db_filepath)
        exitcode, out, err = execute(cmd, raise_error=True)
        self.assertEqual(expand_head, out.rstrip().decode("utf-8"))
        self.assertEqual(False, data_migrations.has_pending_migrations(
            db_api.get_engine()))
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            exitcode, out, err = self._db_command(db_method='migrate')
            self.assertIn('Database migration is up to date. No migration '
                          'needed.', str(out))
示例#6
0
    def test_migrate(self):
        """Test DB migrate"""
        self._db_command(db_method='expand')
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            self._db_command(db_method='migrate')
        expand_head = alembic_migrations.get_alembic_branch_head(
            db_migration.EXPAND_BRANCH)

        cmd = (
            "sqlite3 {0} \"SELECT version_num FROM alembic_version\"").format(
                self.db_filepath)
        exitcode, out, err = execute(cmd, raise_error=True)
        self.assertEqual(expand_head, out.rstrip().decode("utf-8"))
        self.assertEqual(
            False, data_migrations.has_pending_migrations(db_api.get_engine()))
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            exitcode, out, err = self._db_command(db_method='migrate')
            self.assertIn(
                'Database migration is up to date. No migration '
                'needed.', out)
    def test_has_pending_migrations_mult_migration_no_pending(self, mock_find):
        mock_migration1 = mock.Mock()
        mock_migration1.has_migrations.return_value = False
        mock_migration2 = mock.Mock()
        mock_migration2.has_migrations.return_value = False
        mock_migration3 = mock.Mock()
        mock_migration3.has_migrations.return_value = False

        mock_find.return_value = [mock_migration1, mock_migration2,
                                  mock_migration3]

        self.assertFalse(data_migrations.has_pending_migrations(mock.Mock()))
    def test_has_pending_migrations_mult_migration_no_pending(self, mock_find):
        mock_migration1 = mock.Mock()
        mock_migration1.has_migrations.return_value = False
        mock_migration2 = mock.Mock()
        mock_migration2.has_migrations.return_value = False
        mock_migration3 = mock.Mock()
        mock_migration3.has_migrations.return_value = False

        mock_find.return_value = [
            mock_migration1, mock_migration2, mock_migration3
        ]

        self.assertFalse(data_migrations.has_pending_migrations(mock.Mock()))
示例#9
0
    def test_check(self):
        exitcode, out = self._check_db(3)
        self.assertEqual(3, exitcode)

        self._db_command(db_method='expand')
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            exitcode, out = self._check_db(4)
            self.assertEqual(4, exitcode)

        self._db_command(db_method='migrate')
        exitcode, out = self._check_db(5)
        self.assertEqual(5, exitcode)

        self._db_command(db_method='contract')
        exitcode, out = self._check_db(0)
        self.assertEqual(0, exitcode)
示例#10
0
    def test_check(self):
        exitcode, out = self._check_db(3)
        self.assertEqual(3, exitcode)

        self._db_command(db_method='expand')
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            exitcode, out = self._check_db(4)
            self.assertEqual(4, exitcode)

        self._db_command(db_method='migrate')
        exitcode, out = self._check_db(5)
        self.assertEqual(5, exitcode)

        self._db_command(db_method='contract')
        exitcode, out = self._check_db(0)
        self.assertEqual(0, exitcode)
示例#11
0
    def test_contract(self):
        """Test DB contract"""
        self._db_command(db_method='expand')
        if data_migrations.has_pending_migrations(db_api.get_engine()):
            self._db_command(db_method='migrate')
        self._db_command(db_method='contract')
        contract_head = alembic_migrations.get_alembic_branch_head(
            db_migration.CONTRACT_BRANCH)

        cmd = (
            "sqlite3 {0} \"SELECT version_num FROM alembic_version\"").format(
                self.db_filepath)
        exitcode, out, err = execute(cmd, raise_error=True)
        self.assertEqual(contract_head, out.rstrip().decode("utf-8"))
        exitcode, out, err = self._db_command(db_method='contract')
        self.assertIn('Database is up to date. No migrations needed.',
                      str(out))
示例#12
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
                  })
示例#13
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
                  })
 def test_has_pending_migrations_no_migrations(self, mock_find):
     mock_find.return_value = None
     self.assertFalse(data_migrations.has_pending_migrations(mock.Mock()))
 def test_has_pending_migrations_no_migrations(self, mock_find):
     mock_find.return_value = None
     self.assertFalse(data_migrations.has_pending_migrations(mock.Mock()))