-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quota based on placement resource class
This is a spec about quota count based on placement resource class.
- Loading branch information
Showing
1 changed file
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,255 @@ | ||
.. | ||
This work is licensed under a Creative Commons Attribution 3.0 Unported | ||
License. | ||
http://creativecommons.org/licenses/by/3.0/legalcode | ||
|
||
============================================= | ||
Quota Check Based on Placement Resource Class | ||
============================================= | ||
|
||
Include the URL of your launchpad blueprint: | ||
|
||
https://blueprints.launchpad.net/nova/+spec/example | ||
|
||
This spec proposes a way to count the quota based on the placement resource | ||
class. | ||
|
||
Problem description | ||
=================== | ||
|
||
There are two problems need to be resolved for the currently quota system in | ||
Nova: | ||
|
||
* Nova only supports very few build-in resources quota check. But acutally, | ||
Nova isn't limited to manage just those few build-in resources. Cureently, | ||
Nova also support GPU, PCI/SRIOV. With placement service, the user also can | ||
define custom resource, but also expected to be count by the quota system. | ||
Just like the Baremetal users, the operator want to limit the usages for a | ||
specific kind of Baremetal node. | ||
* With Cellv2, when a child cell down, nova can't count the quota usage | ||
correctly, since part of resource usages are recorded in the child cell DB. | ||
|
||
Use Cases | ||
--------- | ||
|
||
* The baremetal operator wants to count the quota of specific kind of BM node. | ||
* The operator wants to count the quota of specific resource in an aggregate. | ||
* The operator wants to count the quota for a custom resources which is | ||
traced by the placement. | ||
|
||
Proposed change | ||
=============== | ||
|
||
The proposal is going to: | ||
* Keep the existed bulild-in quota works as before. | ||
* Re-use the existed Quota REST API and DB table to store the quota limit. | ||
* Count the usages by the Placement API. | ||
* When booting the instance, the resource classes in the flavor extra spec | ||
will be count by the quota system. | ||
|
||
In this proposal, there is nothing change for the existed build-in quotas, it | ||
will works as before and basically same code path. | ||
|
||
Reuse the existed `/os-quota-sets` API to query and update the quota limit, | ||
the API schema for `PUT /os-quota-sets/{project_id}?user_id={user_id}` will be | ||
allowed to specific a quota limit for a specific placement resource class. | ||
|
||
Also reuse the currently DB tables `quotas` and `project_user_quotas` to store | ||
the limit for the resource class. For the aggregate quota, we need new DB table | ||
to store the limit. | ||
|
||
Using the Placement `GET /usages` API to implement the quota | ||
usage count. | ||
|
||
For a specific user and project's resource usage, which is traced by the | ||
placement, can be queried by:: | ||
|
||
GET /usages?project_id=<project_id>&user_id=<user_id> | ||
|
||
Responses: | ||
|
||
{ | ||
"usages": { | ||
"CUSTOM_RC_BAREMETAL_GOLD": 2, | ||
"DISK_GB": 2, | ||
"MEMORY_MB": 256, | ||
"VCPU": 2 | ||
} | ||
} | ||
|
||
This API is already supported in Pike release with placement microversion 1.10. | ||
|
||
To count the usages only in a specific aggregate, we need to add new query | ||
parameter `member_in` to `GET /usages` API, the query is as below:: | ||
|
||
GET /usages?project_id=<project_id>&user_id=<user_id>&member_in=<aggregate_uuid> | ||
|
||
To count the quota for a specific aggregate, the operator should use Placement | ||
API to add specific resource provider into an aggregate. | ||
|
||
When booting an instance, if there is any resource class specified by the | ||
flavor extra spec, and there is quota limit for that resource class, then the | ||
quota limit will be checked for this resource class. | ||
|
||
Alternatives | ||
------------ | ||
|
||
N/A | ||
|
||
Data model impact | ||
----------------- | ||
|
||
TODO: Alex is still verifying this | ||
|
||
The new DB table should be added:: | ||
|
||
class ProjectUserAggregateQuota(API_BASE): | ||
__tablename__ = 'project_user_aggregate_quotas' | ||
uniq_name = ( | ||
"uniq_project_user_quotas0user_id0project_id0resource0aggregate_uuid") | ||
__table_args__ = ( | ||
schema.UniqueConstraint( | ||
"user_id", "project_id", "resource", "aggregate_uuid" | ||
name=uniq_name), | ||
Index('project_user_quotas_project_id_idx', | ||
'project_id'), | ||
Index('project_user_quotas_user_id_idx', | ||
'user_id',) | ||
) | ||
id = Column(Integer, primary_key=True, nullable=False) | ||
|
||
project_id = Column(String(255), nullable=False) | ||
user_id = Column(String(255), nullable=False) | ||
|
||
resource = Column(String(255), nullable=False) | ||
hard_limit = Column(Integer) | ||
aggregate_uuid = Column(String(255), nullable=False) | ||
|
||
|
||
REST API impact | ||
--------------- | ||
|
||
This spec proposes to change the API schema of | ||
`PUT /os-quota-sets/{project_id}` to accept extra properties than the build-in | ||
quotas. | ||
|
||
To create/update a quota limit for a resource class, the request is as below:: | ||
|
||
PUT /os-quota-sets/{project_id} | ||
{ | ||
'CUSTOM_RC_BAREMETAL_GOLD': 10 | ||
} | ||
|
||
To create/update a quota limit for a resource class in a specific aggregate, | ||
the request is as below:: | ||
|
||
PUT /os-quota-sets/{project_id}?aggregate_uuid={aggregate_uuid} | ||
|
||
{ | ||
'CUSTOM_RC_BAREMETAL_GOLD': 10 | ||
} | ||
|
||
But the aggregate quota must less than the user quota, same as the user quota | ||
must less than the project quota. If the aggregate is more than the user quota, | ||
the HTTPBadRequest(400) will be returned. | ||
|
||
Then you can query the quota and the usages by the API `GET /quotas` and | ||
`GET /quotas/detail``. | ||
|
||
Security impact | ||
--------------- | ||
|
||
N/A | ||
|
||
Notifications impact | ||
-------------------- | ||
|
||
N/A | ||
|
||
Other end user impact | ||
--------------------- | ||
|
||
N/A | ||
|
||
Performance Impact | ||
------------------ | ||
|
||
When checking the quota for a resource class, there is REST API call to the | ||
placement API to get the usages. All the resource classes` usage can be | ||
done that single API call. The performance should be ok. | ||
|
||
Other deployer impact | ||
--------------------- | ||
|
||
* The existed quotas still work as before, so there is nothing change. | ||
* To check quota for a resource class, the deployer needs to ensure the | ||
flavor consume for that resource class, and there is quota limit in the | ||
system for that resource class. | ||
|
||
Developer impact | ||
---------------- | ||
|
||
N/A | ||
|
||
Implementation | ||
============== | ||
|
||
Assignee(s) | ||
----------- | ||
|
||
Who is leading the writing of the code? Or is this a blueprint where you're | ||
throwing it out there to see who picks it up? | ||
|
||
If more than one person is working on the implementation, please designate the | ||
primary author and contact. | ||
|
||
Primary assignee: | ||
<launchpad-id or None> | ||
|
||
Other contributors: | ||
<launchpad-id or None> | ||
|
||
Work Items | ||
---------- | ||
|
||
Work items or tasks -- break the feature up into the things that need to be | ||
done to implement it. Those parts might end up being done by different people, | ||
but we're mostly trying to understand the timeline for implementation. | ||
|
||
|
||
Dependencies | ||
============ | ||
|
||
N/A | ||
|
||
Testing | ||
======= | ||
|
||
Add related unit tests and functional tests. | ||
|
||
Documentation Impact | ||
==================== | ||
|
||
N/A | ||
|
||
References | ||
========== | ||
|
||
N/A | ||
|
||
History | ||
======= | ||
|
||
Optional section intended to be used each time the spec is updated to describe | ||
new design, API or any database schema updated. Useful to let reader understand | ||
what's happened along the time. | ||
|
||
.. list-table:: Revisions | ||
:header-rows: 1 | ||
|
||
* - Release Name | ||
- Description | ||
* - Pike | ||
- Introduced |