Exemplo n.º 1
0
    def _check_create_allocations(self, inventory_kwargs,
                                  bad_used, good_used):
        consumer_uuid = uuidsentinel.consumer
        rp_class = fields.ResourceClass.DISK_GB
        rp = self._make_rp_and_inventory(resource_class=rp_class,
                                         **inventory_kwargs)

        # allocation, bad step_size
        allocation = objects.Allocation(resource_provider=rp,
                                        consumer_id=consumer_uuid,
                                        resource_class=rp_class,
                                        used=bad_used)
        allocation_list = objects.AllocationList(self.context,
                                                 objects=[allocation])
        self.assertRaises(exception.InvalidAllocationConstraintsViolated,
                          allocation_list.create_all)

        # correct for step size
        allocation.used = good_used
        allocation_list = objects.AllocationList(self.context,
                                                 objects=[allocation])
        allocation_list.create_all()

        # check usage
        self._validate_usage(rp, allocation.used)
Exemplo n.º 2
0
    def start_fixture(self):
        super(AllocationFixture, self).start_fixture()
        self.context = context.get_admin_context()
        # Stealing from the super
        rp_name = os.environ['RP_NAME']
        rp_uuid = os.environ['RP_UUID']
        rp = objects.ResourceProvider(self.context, name=rp_name, uuid=rp_uuid)
        rp.create()

        # Create some DISK_GB inventory and allocations.
        inventory = objects.Inventory(self.context,
                                      resource_provider=rp,
                                      resource_class='DISK_GB',
                                      total=2048,
                                      step_size=10,
                                      min_unit=10,
                                      max_unit=600)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        alloc1 = objects.Allocation(self.context,
                                    resource_provider=rp,
                                    resource_class='DISK_GB',
                                    consumer_id=uuidutils.generate_uuid(),
                                    used=500)
        alloc2 = objects.Allocation(self.context,
                                    resource_provider=rp,
                                    resource_class='DISK_GB',
                                    consumer_id=uuidutils.generate_uuid(),
                                    used=500)
        alloc_list = objects.AllocationList(self.context,
                                            objects=[alloc1, alloc2])
        alloc_list.create_all()

        # Create some VCPU inventory and allocations.
        inventory = objects.Inventory(self.context,
                                      resource_provider=rp,
                                      resource_class='VCPU',
                                      total=8,
                                      max_unit=4)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        alloc1 = objects.Allocation(self.context,
                                    resource_provider=rp,
                                    resource_class='VCPU',
                                    consumer_id=uuidutils.generate_uuid(),
                                    used=2)
        alloc2 = objects.Allocation(self.context,
                                    resource_provider=rp,
                                    resource_class='VCPU',
                                    consumer_id=uuidutils.generate_uuid(),
                                    used=4)
        alloc_list = objects.AllocationList(self.context,
                                            objects=[alloc1, alloc2])
        alloc_list.create_all()

        # The ALT_RP_XXX variables are for a resource provider that has
        # not been created in the Allocation fixture
        os.environ['ALT_RP_UUID'] = uuidutils.generate_uuid()
        os.environ['ALT_RP_NAME'] = uuidutils.generate_uuid()
Exemplo n.º 3
0
    def test_create(self, mock_ensure_cache):
        rp = objects.ResourceProvider(context=self.context,
                                      uuid=_RESOURCE_PROVIDER_UUID,
                                      name=_RESOURCE_PROVIDER_NAME)
        rp.create()
        inv = objects.Inventory(context=self.context,
                                resource_provider=rp,
                                resource_class=_RESOURCE_CLASS_NAME,
                                total=16,
                                reserved=2,
                                min_unit=1,
                                max_unit=8,
                                step_size=1,
                                allocation_ratio=1.0)
        inv.create()
        obj = objects.Allocation(context=self.context,
                                 resource_provider=rp,
                                 resource_class=_RESOURCE_CLASS_NAME,
                                 consumer_id=uuids.fake_instance,
                                 used=8)
        alloc_list = objects.AllocationList(self.context, objects=[obj])
        alloc_list.create_all()

        rp_al = resource_provider.AllocationList
        saved_allocations = rp_al.get_all_by_resource_provider_uuid(
            self.context, rp.uuid)
        self.assertEqual(1, len(saved_allocations))
        self.assertEqual(obj.used, saved_allocations[0].used)
Exemplo n.º 4
0
def set_allocations(req):
    context = req.environ['placement.context']
    consumer_uuid = util.wsgi_path_item(req.environ, 'consumer_uuid')
    data = _extract_allocations(req.body, ALLOCATION_SCHEMA)
    allocation_data = data['allocations']

    # If the body includes an allocation for a resource provider
    # that does not exist, raise a 400.
    allocation_objects = []
    for allocation in allocation_data:
        resource_provider_uuid = allocation['resource_provider']['uuid']

        try:
            resource_provider = objects.ResourceProvider.get_by_uuid(
                context, resource_provider_uuid)
        except exception.NotFound:
            raise webob.exc.HTTPBadRequest(
                _("Allocation for resource provider '%(rp_uuid)s' "
                  "that does not exist.") %
                {'rp_uuid': resource_provider_uuid},
                json_formatter=util.json_error_formatter)

        resources = allocation['resources']
        for resource_class in resources:
            allocation = objects.Allocation(
                resource_provider=resource_provider,
                consumer_id=consumer_uuid,
                resource_class=resource_class,
                used=resources[resource_class])
            allocation_objects.append(allocation)

    allocations = objects.AllocationList(context, objects=allocation_objects)

    try:
        allocations.create_all()
        LOG.debug("Successfully wrote allocations %s", allocations)
    # InvalidInventory is a parent for several exceptions that
    # indicate either that Inventory is not present, or that
    # capacity limits have been exceeded.
    except exception.NotFound as exc:
        raise webob.exc.HTTPBadRequest(
                _("Unable to allocate inventory for resource provider "
                  "%(rp_uuid)s: %(error)s") %
            {'rp_uuid': resource_provider_uuid, 'error': exc})
    except exception.InvalidInventory as exc:
        LOG.exception(_LE("Bad inventory"))
        raise webob.exc.HTTPConflict(
            _('Unable to allocate inventory: %(error)s') % {'error': exc},
            json_formatter=util.json_error_formatter)
    except exception.ConcurrentUpdateDetected as exc:
        LOG.exception(_LE("Concurrent Update"))
        raise webob.exc.HTTPConflict(
            _('Inventory changed while attempting to allocate: %(error)s') %
            {'error': exc},
            json_formatter=util.json_error_formatter)

    req.response.status = 204
    req.response.content_type = None
    return req.response
Exemplo n.º 5
0
 def test_create_with_id_fails(self):
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=_RESOURCE_PROVIDER_UUID,
                                   name=_RESOURCE_PROVIDER_NAME)
     rp.create()
     inv = objects.Inventory(context=self.context,
                             resource_provider=rp,
                             resource_class=_RESOURCE_CLASS_NAME,
                             total=16,
                             reserved=2,
                             min_unit=1,
                             max_unit=8,
                             step_size=1,
                             allocation_ratio=1.0)
     inv.create()
     obj = objects.Allocation(context=self.context,
                              id=99,
                              resource_provider=rp,
                              resource_class=_RESOURCE_CLASS_NAME,
                              consumer_id=uuids.fake_instance,
                              used=8)
     alloc_list = objects.AllocationList(self.context, objects=[obj])
     self.assertRaises(exception.ObjectActionError, alloc_list.create_all)
Exemplo n.º 6
0
 def test_create(self, mock_ensure_cache):
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=_RESOURCE_PROVIDER_UUID,
                                   name=_RESOURCE_PROVIDER_NAME)
     rp.create()
     inv = objects.Inventory(context=self.context,
                             resource_provider=rp,
                             resource_class=_RESOURCE_CLASS_NAME,
                             total=16,
                             reserved=2,
                             min_unit=1,
                             max_unit=8,
                             step_size=1,
                             allocation_ratio=1.0)
     inv.create()
     obj = objects.Allocation(context=self.context,
                              resource_provider=rp,
                              resource_class=_RESOURCE_CLASS_NAME,
                              consumer_id=uuids.fake_instance,
                              used=8)
     alloc_list = objects.AllocationList(self.context, objects=[obj])
     self.assertNotIn("id", obj)
     alloc_list.create_all()
     self.assertIn("id", obj)
    def test_allocation_list_create(self):
        consumer_uuid = uuidsentinel.consumer

        # Create two resource providers
        rp1_name = uuidsentinel.rp1_name
        rp1_uuid = uuidsentinel.rp1_uuid
        rp1_class = fields.ResourceClass.DISK_GB
        rp1_used = 6

        rp2_name = uuidsentinel.rp2_name
        rp2_uuid = uuidsentinel.rp2_uuid
        rp2_class = fields.ResourceClass.IPV4_ADDRESS
        rp2_used = 2

        rp1 = objects.ResourceProvider(
            self.context, name=rp1_name, uuid=rp1_uuid)
        rp1.create()
        rp2 = objects.ResourceProvider(
            self.context, name=rp2_name, uuid=rp2_uuid)
        rp2.create()

        # Two allocations, one for each resource provider.
        allocation_1 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid,
                                          resource_class=rp1_class,
                                          used=rp1_used)
        allocation_2 = objects.Allocation(resource_provider=rp2,
                                          consumer_id=consumer_uuid,
                                          resource_class=rp2_class,
                                          used=rp2_used)
        allocation_list = objects.AllocationList(
            self.context, objects=[allocation_1, allocation_2])

        # There's no inventory, we have a failure.
        self.assertRaises(exception.InvalidInventory,
                          allocation_list.create_all)

        # Add inventory for one of the two resource providers. This should also
        # fail, since rp2 has no inventory.
        inv = objects.Inventory(resource_provider=rp1,
                                resource_class=rp1_class,
                                total=1024)
        inv.obj_set_defaults()
        inv_list = objects.InventoryList(objects=[inv])
        rp1.set_inventory(inv_list)
        self.assertRaises(exception.InvalidInventory,
                          allocation_list.create_all)

        # Add inventory for the second resource provider
        inv = objects.Inventory(resource_provider=rp2,
                                resource_class=rp2_class,
                                total=255, reserved=2)
        inv.obj_set_defaults()
        inv_list = objects.InventoryList(objects=[inv])
        rp2.set_inventory(inv_list)

        # Now the allocations will work.
        allocation_list.create_all()

        # Check that those allocations changed usage on each
        # resource provider.
        rp1_usage = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, rp1_uuid)
        rp2_usage = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, rp2_uuid)
        self.assertEqual(rp1_used, rp1_usage[0].usage)
        self.assertEqual(rp2_used, rp2_usage[0].usage)

        # redo one allocation
        # TODO(cdent): This does not currently behave as expected
        # because a new allocataion is created, adding to the total
        # used, not replacing.
        rp1_used += 1
        allocation_1 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid,
                                          resource_class=rp1_class,
                                          used=rp1_used)
        allocation_list = objects.AllocationList(
            self.context, objects=[allocation_1])
        allocation_list.create_all()

        rp1_usage = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, rp1_uuid)
        self.assertEqual(rp1_used, rp1_usage[0].usage)

        # delete the allocations for the consumer
        # NOTE(cdent): The database uses 'consumer_id' for the
        # column, presumably because some ids might not be uuids, at
        # some point in the future.
        consumer_allocations = objects.AllocationList.get_all_by_consumer_id(
            self.context, consumer_uuid)
        consumer_allocations.delete_all()

        rp1_usage = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, rp1_uuid)
        rp2_usage = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, rp2_uuid)
        self.assertEqual(0, rp1_usage[0].usage)
        self.assertEqual(0, rp2_usage[0].usage)
Exemplo n.º 8
0
    def test_allocation_checking(self):
        """Test that allocation check logic works with 2 resource classes on
        one provider.

        If this fails, we get a KeyError at create_all()
        """

        consumer_uuid = uuidsentinel.consumer
        consumer_uuid2 = uuidsentinel.consumer2

        # Create one resource provider with 2 classes
        rp1_name = uuidsentinel.rp1_name
        rp1_uuid = uuidsentinel.rp1_uuid
        rp1_class = fields.ResourceClass.DISK_GB
        rp1_used = 6

        rp2_class = fields.ResourceClass.IPV4_ADDRESS
        rp2_used = 2

        rp1 = objects.ResourceProvider(self.context,
                                       name=rp1_name,
                                       uuid=rp1_uuid)
        rp1.create()

        inv = objects.Inventory(resource_provider=rp1,
                                resource_class=rp1_class,
                                total=1024)
        inv.obj_set_defaults()

        inv2 = objects.Inventory(resource_provider=rp1,
                                 resource_class=rp2_class,
                                 total=255,
                                 reserved=2)
        inv2.obj_set_defaults()
        inv_list = objects.InventoryList(objects=[inv, inv2])
        rp1.set_inventory(inv_list)

        # create the allocations for a first consumer
        allocation_1 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid,
                                          resource_class=rp1_class,
                                          used=rp1_used)
        allocation_2 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid,
                                          resource_class=rp2_class,
                                          used=rp2_used)
        allocation_list = objects.AllocationList(
            self.context, objects=[allocation_1, allocation_2])
        allocation_list.create_all()

        # create the allocations for a second consumer, until we have
        # allocations for more than one consumer in the db, then we
        # won't actually be doing real allocation math, which triggers
        # the sql monster.
        allocation_1 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid2,
                                          resource_class=rp1_class,
                                          used=rp1_used)
        allocation_2 = objects.Allocation(resource_provider=rp1,
                                          consumer_id=consumer_uuid2,
                                          resource_class=rp2_class,
                                          used=rp2_used)
        allocation_list = objects.AllocationList(
            self.context, objects=[allocation_1, allocation_2])
        # If we are joining wrong, this will be a KeyError
        allocation_list.create_all()
Exemplo n.º 9
0
    def start_fixture(self):
        super(AllocationFixture, self).start_fixture()
        self.context = context.get_admin_context()

        # For use creating and querying allocations/usages
        os.environ['ALT_USER_ID'] = uuidutils.generate_uuid()
        project_id = os.environ['PROJECT_ID']
        user_id = os.environ['USER_ID']
        alt_user_id = os.environ['ALT_USER_ID']

        # Stealing from the super
        rp_name = os.environ['RP_NAME']
        rp_uuid = os.environ['RP_UUID']
        rp = objects.ResourceProvider(
            self.context, name=rp_name, uuid=rp_uuid)
        rp.create()

        # Create some DISK_GB inventory and allocations.
        # Each set of allocations must have the same consumer_id because only
        # the first allocation is used for the project/user association.
        consumer_id = uuidutils.generate_uuid()
        inventory = objects.Inventory(
            self.context, resource_provider=rp,
            resource_class='DISK_GB', total=2048,
            step_size=10, min_unit=10, max_unit=600)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        alloc1 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='DISK_GB',
            consumer_id=consumer_id,
            used=500)
        alloc2 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='DISK_GB',
            consumer_id=consumer_id,
            used=500)
        alloc_list = objects.AllocationList(
            self.context,
            objects=[alloc1, alloc2],
            project_id=project_id,
            user_id=user_id,
        )
        alloc_list.create_all()

        # Create some VCPU inventory and allocations.
        # Each set of allocations must have the same consumer_id because only
        # the first allocation is used for the project/user association.
        consumer_id = uuidutils.generate_uuid()
        inventory = objects.Inventory(
            self.context, resource_provider=rp,
            resource_class='VCPU', total=10,
            max_unit=4)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        alloc1 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='VCPU',
            consumer_id=consumer_id,
            used=2)
        alloc2 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='VCPU',
            consumer_id=consumer_id,
            used=4)
        alloc_list = objects.AllocationList(
                self.context,
                objects=[alloc1, alloc2],
                project_id=project_id,
                user_id=user_id)
        alloc_list.create_all()

        # Create a couple of allocations for a different user.
        # Each set of allocations must have the same consumer_id because only
        # the first allocation is used for the project/user association.
        consumer_id = uuidutils.generate_uuid()
        alloc1 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='DISK_GB',
            consumer_id=consumer_id,
            used=20)
        alloc2 = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='VCPU',
            consumer_id=consumer_id,
            used=1)
        alloc_list = objects.AllocationList(
                self.context,
                objects=[alloc1, alloc2],
                project_id=project_id,
                user_id=alt_user_id)
        alloc_list.create_all()

        # The ALT_RP_XXX variables are for a resource provider that has
        # not been created in the Allocation fixture
        os.environ['ALT_RP_UUID'] = uuidutils.generate_uuid()
        os.environ['ALT_RP_NAME'] = uuidutils.generate_uuid()