Example #1
0
    def _setup_cells(self):
        """Setup a normal cellsv2 environment.

        This sets up the CellDatabase fixture with two cells, one cell0
        and one normal cell. CellMappings are created for both so that
        cells-aware code can find those two databases.
        """
        celldbs = nova_fixtures.CellDatabases()
        celldbs.add_cell_database(objects.CellMapping.CELL0_UUID)
        celldbs.add_cell_database(uuids.cell1, default=True)
        self.useFixture(celldbs)

        ctxt = context.get_context()
        fake_transport = 'fake://nowhere/'

        c0 = objects.CellMapping(
            context=ctxt,
            uuid=objects.CellMapping.CELL0_UUID,
            name='cell0',
            transport_url=fake_transport,
            database_connection=objects.CellMapping.CELL0_UUID)
        c0.create()

        c1 = objects.CellMapping(
            context=ctxt,
            uuid=uuids.cell1,
            name=CELL1_NAME,
            transport_url=fake_transport,
            database_connection=uuids.cell1)
        c1.create()

        self.cell_mappings = {cm.name: cm for cm in (c0, c1)}
Example #2
0
    def setUp(self):
        super(ComputeHostAPIMultiCellTestCase, self).setUp()
        self.host_api = compute_api.HostAPI()
        self.useFixture(nova_fixtures.Database(database='api'))
        celldbs = nova_fixtures.CellDatabases()
        celldbs.add_cell_database(objects.CellMapping.CELL0_UUID)
        celldbs.add_cell_database(uuids.cell1, default=True)
        celldbs.add_cell_database(uuids.cell2)
        self.useFixture(celldbs)

        self.ctxt = context.get_admin_context()
        cell0 = objects.CellMapping(
            context=self.ctxt,
            uuid=objects.CellMapping.CELL0_UUID,
            database_connection=objects.CellMapping.CELL0_UUID,
            transport_url='none:///')
        cell0.create()
        cell1 = objects.CellMapping(context=self.ctxt,
                                    uuid=uuids.cell1,
                                    database_connection=uuids.cell1,
                                    transport_url='none:///')
        cell1.create()
        cell2 = objects.CellMapping(context=self.ctxt,
                                    uuid=uuids.cell2,
                                    database_connection=uuids.cell2,
                                    transport_url='none:///')
        cell2.create()
        self.cell_mappings = (cell0, cell1, cell2)
Example #3
0
    def test_populate_user_id_instance_get_fail(self, mock_inst_get):
        cells = []
        celldbs = fixtures.CellDatabases()

        # Create two cell databases and map them
        for uuid in (uuidsentinel.cell1, uuidsentinel.cell2):
            cm = cell_mapping.CellMapping(context=self.context, uuid=uuid,
                                          database_connection=uuid,
                                          transport_url='fake://')
            cm.create()
            cells.append(cm)
            celldbs.add_cell_database(uuid)
        self.useFixture(celldbs)

        # Create one instance per cell
        for cell in cells:
            with context.target_cell(self.context, cell) as cctxt:
                inst = instance.Instance(
                    cctxt,
                    project_id=self.context.project_id,
                    user_id=self.context.user_id)
                inst.create()
            create_mapping(project_id=self.context.project_id,
                           user_id=None, cell_id=cell.id,
                           instance_uuid=inst.uuid)

        # Simulate the first cell is down/has some error
        mock_inst_get.side_effect = [test.TestingException(),
                                     instance.InstanceList(objects=[inst])]

        found, done = instance_mapping.populate_user_id(self.context, 1000)
        # Verify we continue to the next cell when a down/error cell is
        # encountered.
        self.assertEqual(2, found)
        self.assertEqual(1, done)
Example #4
0
 def setUp(self):
     super(CellDatabasesTestCase, self).setUp()
     self.useFixture(nova_fixtures.Database(database='api'))
     fix = nova_fixtures.CellDatabases()
     fix.add_cell_database('blah')
     fix.add_cell_database('wat')
     self.useFixture(fix)
Example #5
0
 def setUp(self):
     super(QuotaTestCase, self).setUp()
     self.useFixture(nova_fixtures.SpawnIsSynchronousFixture())
     self.useFixture(nova_fixtures.Database(database='api'))
     fix = nova_fixtures.CellDatabases()
     fix.add_cell_database('cell1')
     fix.add_cell_database('cell2')
     self.useFixture(fix)
    def setUp(self):
        super(CellDatabasesTestCase, self).setUp()
        self.useFixture(nova_fixtures.Database(database='api'))
        fix = nova_fixtures.CellDatabases()
        fix.add_cell_database('cell0')
        fix.add_cell_database('cell1')
        fix.add_cell_database('cell2')
        self.useFixture(fix)

        self.context = context.RequestContext('fake-user', 'fake-project')
Example #7
0
    def _setup_cells(self):
        # NOTE(danms): Override the base class's cell setup so we can have two
        self.cells = fixtures.CellDatabases()
        self.cells.add_cell_database(uuidsentinel.cell1, default=True)
        self.cells.add_cell_database(uuidsentinel.cell2)
        self.useFixture(self.cells)

        cm = objects.CellMapping(context=self.context,
                                 uuid=uuidsentinel.cell1,
                                 name='cell1',
                                 transport_url='fake://nowhere/',
                                 database_connection=uuidsentinel.cell1)
        cm.create()
        cm = objects.CellMapping(context=self.context,
                                 uuid=uuidsentinel.cell2,
                                 name='cell2',
                                 transport_url='fake://nowhere/',
                                 database_connection=uuidsentinel.cell2)
        cm.create()
Example #8
0
    def _setup_cells(self):
        ctxt = context.get_admin_context()
        self.celldbs = fixtures.CellDatabases()
        cells = []
        for uuid in (uuids.cell1, uuids.cell2, uuids.cell3):
            cm = objects.CellMapping(context=ctxt,
                                     uuid=uuid,
                                     database_connection=uuid,
                                     transport_url='fake://')
            cm.create()
            cells.append(cm)
            self.celldbs.add_cell_database(uuid)
        self.useFixture(self.celldbs)

        for cell in cells:
            for i in (1, 2, 3):
                # Make one host in each cell unmapped
                mapped = 0 if i == 2 else 1

                host = 'host-%s-%i' % (cell.uuid, i)
                if mapped:
                    hm = objects.HostMapping(context=ctxt,
                                             cell_mapping=cell,
                                             host=host)
                    hm.create()

                with context.target_cell(ctxt, cell):
                    cn = objects.ComputeNode(context=ctxt,
                                             vcpus=1,
                                             memory_mb=1,
                                             local_gb=1,
                                             vcpus_used=0,
                                             memory_mb_used=0,
                                             local_gb_used=0,
                                             hypervisor_type='danvm',
                                             hypervisor_version='1',
                                             cpu_info='foo',
                                             cpu_allocation_ratio=1.0,
                                             ram_allocation_ratio=1.0,
                                             disk_allocation_ratio=1.0,
                                             mapped=mapped,
                                             host=host)
                    cn.create()
Example #9
0
    def setUp(self):
        super(ServerGroupTestV21, self).setUp()
        self._setup_controller()
        self.req = fakes.HTTPRequest.blank('')
        self.admin_req = fakes.HTTPRequest.blank('', use_admin_context=True)
        self.foo_req = fakes.HTTPRequest.blank('', project_id='foo')
        self.policy = self.useFixture(policy_fixture.RealPolicyFixture())

        self.useFixture(fixtures.Database(database='api'))
        cells = fixtures.CellDatabases()
        cells.add_cell_database(uuidsentinel.cell1)
        cells.add_cell_database(uuidsentinel.cell2)
        self.useFixture(cells)

        ctxt = context.get_admin_context()
        self.cells = {}
        for uuid in (uuidsentinel.cell1, uuidsentinel.cell2):
            cm = objects.CellMapping(context=ctxt,
                                uuid=uuid,
                                database_connection=uuid,
                                transport_url=uuid)
            cm.create()
            self.cells[cm.uuid] = cm
Example #10
0
    def _setup_cells(self):
        """Setup a normal cellsv2 environment.

        This sets up the CellDatabase fixture with two cells, one cell0
        and one normal cell. CellMappings are created for both so that
        cells-aware code can find those two databases.
        """
        celldbs = nova_fixtures.CellDatabases()

        ctxt = context.get_context()
        fake_transport = 'fake://nowhere/'

        c0 = objects.CellMapping(
            context=ctxt,
            uuid=objects.CellMapping.CELL0_UUID,
            name='cell0',
            transport_url=fake_transport,
            database_connection=objects.CellMapping.CELL0_UUID)
        c0.create()
        self.cell_mappings[c0.name] = c0
        celldbs.add_cell_database(objects.CellMapping.CELL0_UUID)

        for x in range(self.NUMBER_OF_CELLS):
            name = 'cell%i' % (x + 1)
            uuid = getattr(uuids, name)
            cell = objects.CellMapping(
                context=ctxt,
                uuid=uuid,
                name=name,
                transport_url=fake_transport,
                database_connection=uuid)
            cell.create()
            self.cell_mappings[name] = cell
            # cell1 is the default cell
            celldbs.add_cell_database(uuid, default=(x == 0))

        self.useFixture(celldbs)
Example #11
0
    def test_populate_user_id(self, mock_log_warning):
        cells = []
        celldbs = fixtures.CellDatabases()

        # Create two cell databases and map them
        for uuid in (uuidsentinel.cell1, uuidsentinel.cell2):
            cm = cell_mapping.CellMapping(context=self.context,
                                          uuid=uuid,
                                          database_connection=uuid,
                                          transport_url='fake://')
            cm.create()
            cells.append(cm)
            celldbs.add_cell_database(uuid)
        self.useFixture(celldbs)

        # Create 5 instances per cell
        for cell in cells:
            for i in range(0, 5):
                with context.target_cell(self.context, cell) as cctxt:
                    inst = instance.Instance(
                        cctxt,
                        project_id=self.context.project_id,
                        user_id=self.context.user_id)
                    inst.create()
                # Make every other mapping have a NULL user_id
                # Will be a total of four mappings with NULL user_id
                user_id = self.context.user_id if i % 2 == 0 else None
                create_mapping(project_id=self.context.project_id,
                               user_id=user_id,
                               cell_id=cell.id,
                               instance_uuid=inst.uuid)

        # Create a SOFT_DELETED instance with a user_id=None instance mapping.
        # This should get migrated.
        with context.target_cell(self.context, cells[0]) as cctxt:
            inst = instance.Instance(cctxt,
                                     project_id=self.context.project_id,
                                     user_id=self.context.user_id,
                                     vm_state=vm_states.SOFT_DELETED)
            inst.create()
        create_mapping(project_id=self.context.project_id,
                       user_id=None,
                       cell_id=cells[0].id,
                       instance_uuid=inst.uuid,
                       queued_for_delete=True)

        # Create a deleted instance with a user_id=None instance mapping.
        # This should get migrated.
        with context.target_cell(self.context, cells[1]) as cctxt:
            inst = instance.Instance(cctxt,
                                     project_id=self.context.project_id,
                                     user_id=self.context.user_id)
            inst.create()
            inst.destroy()
        create_mapping(project_id=self.context.project_id,
                       user_id=None,
                       cell_id=cells[1].id,
                       instance_uuid=inst.uuid,
                       queued_for_delete=True)

        # Create an instance mapping for an instance not yet scheduled. It
        # should not get migrated because we won't know what user_id to use.
        unscheduled = create_mapping(project_id=self.context.project_id,
                                     user_id=None,
                                     cell_id=None)

        # Create two instance mappings for instances that no longer exist.
        # Example: residue from a manual cleanup or after a periodic compute
        # purge and before a database archive. This record should not get
        # migrated.
        nonexistent = []
        for i in range(2):
            nonexistent.append(
                create_mapping(project_id=self.context.project_id,
                               user_id=None,
                               cell_id=cells[i].id,
                               instance_uuid=uuidutils.generate_uuid()))

        # Create an instance mapping simulating a virtual interface migration
        # marker instance which has had map_instances run on it.
        # This should not be found by the migration.
        create_mapping(project_id=virtual_interface.FAKE_UUID, user_id=None)

        found, done = instance_mapping.populate_user_id(self.context, 2)
        # Two needed fixing, and honored the limit.
        self.assertEqual(2, found)
        self.assertEqual(2, done)

        found, done = instance_mapping.populate_user_id(self.context, 1000)
        # Only four left were fixable. The fifth instance found has no
        # cell and cannot be migrated yet. The 6th and 7th instances found have
        # no corresponding instance records and cannot be migrated.
        self.assertEqual(7, found)
        self.assertEqual(4, done)

        # Verify the orphaned instance mappings warning log message was only
        # emitted once.
        mock_log_warning.assert_called_once()

        # Check that we have only the expected number of records with
        # user_id set. We created 10 instances (5 per cell with 2 per cell
        # with NULL user_id), 1 SOFT_DELETED instance with NULL user_id,
        # 1 deleted instance with NULL user_id, and 1 not-yet-scheduled
        # instance with NULL user_id.
        # We expect 12 of them to have user_id set after migration (15 total,
        # with the not-yet-scheduled instance and the orphaned instance
        # mappings ignored).
        ims = instance_mapping.InstanceMappingList.get_by_project_id(
            self.context, self.context.project_id)
        self.assertEqual(12, len([im for im in ims if 'user_id' in im]))

        # Check that one instance mapping record (not yet scheduled) has not
        # been migrated by this script.
        # Check that two other instance mapping records (no longer existing
        # instances) have not been migrated by this script.
        self.assertEqual(15, len(ims))

        # Set the cell and create the instance for the mapping without a cell,
        # then run the migration again.
        unscheduled = instance_mapping.InstanceMapping.get_by_instance_uuid(
            self.context, unscheduled['instance_uuid'])
        unscheduled.cell_mapping = cells[0]
        unscheduled.save()
        with context.target_cell(self.context, cells[0]) as cctxt:
            inst = instance.Instance(cctxt,
                                     uuid=unscheduled.instance_uuid,
                                     project_id=self.context.project_id,
                                     user_id=self.context.user_id)
            inst.create()
        found, done = instance_mapping.populate_user_id(self.context, 1000)
        # Should have found the not-yet-scheduled instance and the orphaned
        # instance mappings.
        self.assertEqual(3, found)
        # Should have only migrated the not-yet-schedule instance.
        self.assertEqual(1, done)

        # Delete the orphaned instance mapping (simulate manual cleanup by an
        # operator).
        for db_im in nonexistent:
            nonexist = instance_mapping.InstanceMapping.get_by_instance_uuid(
                self.context, db_im['instance_uuid'])
            nonexist.destroy()

        # Run the script one last time to make sure it finds nothing left to
        # migrate.
        found, done = instance_mapping.populate_user_id(self.context, 1000)
        self.assertEqual(0, found)
        self.assertEqual(0, done)
Example #12
0
    def test_populate_queued_for_delete(self):
        cells = []
        celldbs = fixtures.CellDatabases()

        # Create two cell databases and map them
        for uuid in (uuidsentinel.cell1, uuidsentinel.cell2):
            cm = cell_mapping.CellMapping(context=self.context,
                                          uuid=uuid,
                                          database_connection=uuid,
                                          transport_url='fake://')
            cm.create()
            cells.append(cm)
            celldbs.add_cell_database(uuid)
        self.useFixture(celldbs)

        # Create 5 instances per cell, two deleted, one with matching
        # queued_for_delete in the instance mapping
        for cell in cells:
            for i in range(0, 5):
                # Instance 4 should be SOFT_DELETED
                vm_state = (vm_states.SOFT_DELETED
                            if i == 4 else vm_states.ACTIVE)

                # Instance 2 should already be marked as queued_for_delete
                qfd = True if i == 2 else None

                with context.target_cell(self.context, cell) as cctxt:
                    inst = instance.Instance(
                        cctxt,
                        vm_state=vm_state,
                        project_id=self.context.project_id,
                        user_id=self.context.user_id)
                    inst.create()
                    if i in (2, 3):
                        # Instances 2 and 3 are hard-deleted
                        inst.destroy()

                instance_mapping.InstanceMapping._create_in_db(
                    self.context, {
                        'project_id': self.context.project_id,
                        'cell_id': cell.id,
                        'queued_for_delete': qfd,
                        'instance_uuid': inst.uuid
                    })

        done, total = instance_mapping.populate_queued_for_delete(
            self.context, 2)
        # First two needed fixing, and honored the limit
        self.assertEqual(2, done)
        self.assertEqual(2, total)

        done, total = instance_mapping.populate_queued_for_delete(
            self.context, 1000)

        # Last six included two that were already done, and spanned to the
        # next cell
        self.assertEqual(6, done)
        self.assertEqual(6, total)

        mappings = instance_mapping.InstanceMappingList.get_by_project_id(
            self.context, self.context.project_id)

        # Check that we have only the expected number of records with
        # True/False (which implies no NULL records).

        # Six deleted instances
        self.assertEqual(
            6, len([im for im in mappings if im.queued_for_delete is True]))
        # Four non-deleted instances
        self.assertEqual(
            4, len([im for im in mappings if im.queued_for_delete is False]))

        # Run it again to make sure we don't query the cell database for
        # instances if we didn't get any un-migrated mappings.
        with mock.patch('nova.objects.InstanceList.get_by_filters',
                        new_callable=mock.NonCallableMock):
            done, total = instance_mapping.populate_queued_for_delete(
                self.context, 1000)
        self.assertEqual(0, done)
        self.assertEqual(0, total)