Skip to content

Commit

Permalink
Quota based on placement resource class
Browse files Browse the repository at this point in the history
This is a spec about quota count based on placement resource
class.
  • Loading branch information
soulxu committed Apr 26, 2018
1 parent 64de209 commit dc93139
Showing 1 changed file with 255 additions and 0 deletions.
255 changes: 255 additions & 0 deletions specs/quota-based-on-placement-resource-class.rst
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

0 comments on commit dc93139

Please sign in to comment.