def test_archive_deleted_rows_with_undeleted_residue(self): # Boots a server, deletes it, and then tries to archive it. server = self._create_server() server_id = server['id'] # Assert that there are instance_actions. instance_actions are # interesting since we don't soft delete them but they have a foreign # key back to the instances table. actions = self.api.get_instance_actions(server_id) self.assertTrue(len(actions), 'No instance actions for server: %s' % server_id) self._delete_server(server) # Verify we have the soft deleted instance in the database. admin_context = context.get_admin_context(read_deleted='yes') # This will raise InstanceNotFound if it's not found. instance = db.instance_get_by_uuid(admin_context, server_id) # Make sure it's soft deleted. self.assertNotEqual(0, instance.deleted) # Undelete the instance_extra record to make sure we delete it anyway extra = db.instance_extra_get_by_instance_uuid(admin_context, instance.uuid) self.assertNotEqual(0, extra.deleted) db.instance_extra_update_by_uuid(admin_context, instance.uuid, {'deleted': 0}) extra = db.instance_extra_get_by_instance_uuid(admin_context, instance.uuid) self.assertEqual(0, extra.deleted) # Verify we have some system_metadata since we'll check that later. self.assertTrue(len(instance.system_metadata), 'No system_metadata for instance: %s' % server_id) # Create a pci_devices record to simulate an instance that had a PCI # device allocated at the time it was deleted. There is a window of # time between deletion of the instance record and freeing of the PCI # device in nova-compute's _complete_deletion method during RT update. db.pci_device_update( admin_context, 1, 'fake-address', { 'compute_node_id': 1, 'address': 'fake-address', 'vendor_id': 'fake', 'product_id': 'fake', 'dev_type': 'fake', 'label': 'fake', 'status': 'allocated', 'instance_uuid': instance.uuid }) # Now try and archive the soft deleted records. results, deleted_instance_uuids, archived = \ db.archive_deleted_rows(max_rows=100) # verify system_metadata was dropped self.assertIn('instance_system_metadata', results) self.assertEqual(len(instance.system_metadata), results['instance_system_metadata']) # Verify that instances rows are dropped self.assertIn('instances', results) # Verify that instance_actions and actions_event are dropped # by the archive self.assertIn('instance_actions', results) self.assertIn('instance_actions_events', results) self.assertEqual(sum(results.values()), archived) # Verify that the pci_devices record has not been dropped self.assertNotIn('pci_devices', results)
def _get_target(self, context, target): """Processes and validates the CLI given target and adapts it for policy authorization. :returns: None if the given target is None, otherwise returns a proper authorization target. :raises nova.exception.InvalidAttribute: if a key in the given target is not an acceptable. :raises nova.exception.InstanceNotFound: if 'instance_id' is given, and there is no instance match the id. """ if not target: return None new_target = {} for t in target: key, value = t.split('=') if key not in self._ACCEPTABLE_TARGETS: raise exception.InvalidAttribute(attr=key) new_target[key] = value # if the target is an instance_id, return an instance instead. instance_id = new_target.get('instance_id') if instance_id: admin_ctxt = nova_context.get_admin_context() instance = db.instance_get_by_uuid(admin_ctxt, instance_id) new_target = { 'user_id': instance['user_id'], 'project_id': instance['project_id'] } return new_target
def test_archive_deleted_rows(self): # Boots a server, deletes it, and then tries to archive it. server = self._create_server() server_id = server['id'] # Assert that there are instance_actions. instance_actions are # interesting since we don't soft delete them but they have a foreign # key back to the instances table. actions = self.api.get_instance_actions(server_id) self.assertTrue(len(actions), 'No instance actions for server: %s' % server_id) self._delete_server(server) # Verify we have the soft deleted instance in the database. admin_context = context.get_admin_context(read_deleted='yes') # This will raise InstanceNotFound if it's not found. instance = db.instance_get_by_uuid(admin_context, server_id) # Make sure it's soft deleted. self.assertNotEqual(0, instance.deleted) # Verify we have some system_metadata since we'll check that later. self.assertTrue(len(instance.system_metadata), 'No system_metadata for instance: %s' % server_id) # Now try and archive the soft deleted records. results, deleted_instance_uuids, archived = \ db.archive_deleted_rows(max_rows=100) # verify system_metadata was dropped self.assertIn('instance_system_metadata', results) self.assertEqual(len(instance.system_metadata), results['instance_system_metadata']) # Verify that instances rows are dropped self.assertIn('instances', results) # Verify that instance_actions and actions_event are dropped # by the archive self.assertIn('instance_actions', results) self.assertIn('instance_actions_events', results) self.assertEqual(sum(results.values()), archived)
def get_marker_record(self, ctx, marker): try: im = objects.InstanceMapping.get_by_instance_uuid(ctx, marker) except exception.InstanceMappingNotFound: raise exception.MarkerNotFound(marker=marker) elevated = ctx.elevated(read_deleted='yes') with context.target_cell(elevated, im.cell_mapping) as cctx: try: # NOTE(danms): We query this with no columns_to_join() # as we're just getting values for the sort keys from # it and none of the valid sort keys are on joined # columns. db_inst = db.instance_get_by_uuid(cctx, marker, columns_to_join=[]) except exception.InstanceNotFound: raise exception.MarkerNotFound(marker=marker) return im.cell_mapping.uuid, db_inst