Files
nova-specs/specs/newton/approved/generic-resource-pools.rst
Jay Pipes d1caf4eaac resource-providers: generic resource pools
Adds specification for generic resource pools in Nova, which solves the
problem of incorrect capacity and usage information for shared storage
resources.

blueprint: generic-resource-pools
ApiImpact

Change-Id: Ia4e8e7a939e1752fdb59805b4067a125dc9ca976
2016-05-16 21:45:23 +00:00

921 lines
30 KiB
ReStructuredText

..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
======================
Generic Resource Pools
======================
https://blueprints.launchpad.net/nova/+spec/generic-resource-pools
This blueprint aims to address the problem of incorrect resource usage
reporting by introducing the concept of a generic resource pool that manages a
particular amount of some resource.
Problem description
===================
Within a cloud deployment, there are a number of resources that may be consumed
by a user. Some resource types are provided by a compute node; these types of
resources include CPU, memory, PCI devices and local ephemeral disk. Other
types of resources, however, are *not* provided by a compute node, but instead
are provided by some external resource pool. An example of such a resource
would be a shared storage pool like that provided by Ceph or an NFS share.
Unfortunately, due to legacy reasons, Nova considers resources as only being
provided by a compute node. The tracking of resources assumes that it is the
compute node that provides the resource, and therefore when reporting usage of
certain resources, Nova naively calculates resource usage and availability by
simply summing amounts across all compute nodes in its database. This ends up
causing a number of problems [1] with usage and capacity amounts being
incorrect.
Use Cases
---------
As a deployer that has chosen to use a shared storage solution for storing
instance ephemeral disks, I want Nova and Horizon to report the correct
usage and capacity information for disk resources.
As an advanced Neutron user, I wish to use the new routed networks
functionality and be able to have Nova understand that a particular pre-created
Neutron port is associated with a specific subnet pool segment, and ensure that
my instance is booted on a compute node that matches that segment.
As an advanced Cinder user, if I specify a Cinder volume-id on the nova boot
command, I want Nova to be able to know which compute nodes are attached to a
Cinder storage pool that contains the requested volume.
Proposed change
===============
We propose to introduce the concept of a `resource pool` in Nova, and to create
a new RESTful scheduler API that allows the querying and management of these
resource pools.
A resource pool is simply a resource provider for one or more resource types to
multiple consumers of those resources. Resource pools are not specific to
shared storage, even though the impetus for their design is to solve the
problem of shared storage accounting in Nova.
A RESTful API is proposed (see below for details) that will allow
administrative (or service) users to create resource pools, to update the
capacity and usage information for those pools, and to indicate which compute
nodes can use the pool's resources by associating the pool with one or more
aggregates.
Scenario 1: Shared disk storage used for VM disk images
-------------------------------------------------------
In this scenario, we are attempting to make Nova aware that a set of compute
nodes in an environment use shared storage for VM disk images. The shared
storage is an NFS share that has 100 TB of total disk space. Around 1 TB of
this share has already been consumed by unrelated things.
All compute nodes in row 1, racks 6 through 10, are connected to this share.
1) The cloud deployer creates an aggregate representing all the compute
nodes in row 1, racks 6 through 10::
$AGG_UUID=`openstack aggregate create r1rck0610`
# for all compute nodes in the system that are in racks 6-10 in row 1...
openstack aggregate add host $AGG_UUID $HOSTNAME
2) The cloud deployer creates a resource pool representing the NFS share::
$RP_UUID=`openstack resource-pool create "/mnt/nfs/row1racks0610/" \
--aggregate-uuid=$AGG_UUID`
Under the covers this command line does two REST API requests.
One to create the resource-pool, another to associate the
aggregate.
3) The cloud deployer updates the resource pool's capacity of shared disk::
openstack resource-pool set inventory $RP_UUID \
--resource-class=DISK_GB \
--total=100000 --reserved=1000 \
--min-unit=50 --max-unit=10000 --step-size=10 \
--allocation-ratio=1.0
.. note::
The `--reserved` field indicates the portion of the NFS share that has been
consumed by non-accounted-for consumers. When Nova calculates if a resource
pool has the capacity to meet a request for some amount of resources, it
checks using the following formula: ((TOTAL - RESERVED) * ALLOCATION_RATIO)
- USED >= REQUESTED_AMOUNT
Scenario 2a: Using Neutron routed networks functionality
--------------------------------------------------------
In this (future) scenario, we are assuming the Neutron routed networks
functionality is available in our deployment. There are a set of routed
networks, each containing a set of IP addresses, that represent the physical
network topology in the datacenter. Let us assume that routed network with the
identifier `rnA` represents the subnet IP pool for all compute nodes in rack 1
in row 3 of the datacenter. This subnet has a CIDR of `192.168.10.1/24`. Let us
also assume that unmanaged devices are consuming the bottom 5 IP addresses on
the subnet.
1) The network administrator creates a network and routed network segments
representing broadcast domains for rack 1 in row 3::
$NET_UUID=`openstack network create "routed network"`
$SEG_UUID=`openstack subnet pool create $NET_UUID`
$SUBNET_UUID=`openstack subnet create $SEG_UUID --cidr=192.168.10.1/24`
2) The cloud deployer creates an aggregate representing all the compute
nodes in row 3, racks 1 through 5::
$AGG_UUID=`openstack aggregate create "row 3, rack 1"`
# for all compute nodes in the system that are in racks 1 in row 3...
openstack aggregate add host $AGG_UUID $HOSTNAME
3) The cloud deployer creates a resource pool representing the routed network's
pool of IPs::
openstack resource-pool create "routed network rack 1 row 3" \
--uuid=$SUBNET_UUID \
--aggregate-uuid=$AGG_UUID
.. note::
Please note that the `--uuid` field in the `openstack resource-pool create`
call above is an optional argument to `openstack resource-pool create`. You
may have noticed that in the first use case, we do not provide a UUID when
creating the resource pool.
The `--uuid` parameter allows passing in a UUID identifier so that external
systems can supply an already-known external global identifier for the
resource pool. If the `--uuid` parameter is not provided in the call to
`openstack resource-pool create`, a new UUID will automatically be assigned
and displayed to the user.
In the case above, we are assuming that the call to the `openstack
subnet create` returns some value containing a UUID for the subnet IP
allocation pool (the segment).
4) The cloud deployer updates the resource pool's capacity of IPv4 addresses::
openstack resource-pool set inventory $RP_UUID \
--resource-class=IPV4_ADDRESS \
--total=254 --reserved=5 \
--min-unit=1 --max-unit=1 --step-size=1 \
--allocation-ratio=1.0
.. note::
Instead of cloud deployer manually updating the resource pool's inventory,
it's more likely that a script would call the `neutron subnet-XXX` commands
to determine capacity and reserved amounts.
5) The cloud user creates a port in Neutron, asking for an IP out of a
particular subnet::
PORT_UUID=`openstack port create --network-id=$NET_UUID --fixed-ip \
subnet=$SUBNET_UUID`
6) The cloud user boots an instance, specifying the ID of the port created
in step 5::
openstack server create --nic port_id=$PORT_UUID --image XXX --flavor AAA
7) During (or perhaps before) the scheduling process, Nova will want to answer
the question, "if this port ID is a member of a resource pool containing
`IPV4_ADDRESS` resources, which compute nodes are possible target
destinations that are associated with that IPv4 subnet?".
The Nova scheduler (or conductor) would be able to determine the set of
compute nodes used in placement decisions by looking at the aggregates that
the resource pool representing that subnet was associated with, which will
in turn allow it to identify the compute nodes associated with those
aggregates.
What this gives the cloud user is basic network affinity during scheduling,
with the cloud user only needing to specify a port ID.
Scenario 2b: Live migration of instance booted in scenario 2a
-------------------------------------------------------------
Assume that the virtual machine launched in step #6 of Scenario 2a needs to be
live-migrated -- perhaps because the compute host is failing or being upgraded.
Live migration moves a workload from a source host to a destination host,
keeping the workload's networking setup intact. In the case where an instance
was booted with a port that is associated with a particular resource pool
containing a routed network's set of IP addresses, we need to ensure that the
target host is in the same aggregate as the source host (since the routed
network only spans the compute hosts in a particular aggregate).
With the generic resource pool information, we can have the scheduler (or
conductor) limit the set of compute nodes used in determining the
live-migration's destination host by examining the resource providers that
match the `IPV4_ADDRESS` resource class for the instance UUID as a consumer.
From this list we can identify the aggregates associated with the resource
provider and from the list of aggregates we can determine the compute hosts
that can serve as target destinations for the migration.
Alternatives
------------
An alternative approach to having an entity in the Nova system to represent
these resource pools would be to have Nova somehow examine a configuration flag
to determine whether disk resources on a compute node are using shared storage
versus locally available. There are a couple problems with this approach:
* This approach is not generic and assumes the only shared resource is disk
space
* This information isn't really configuration data but rather system inventory
data, and therefore belongs in the database, not configuration files
Data model impact
-----------------
A new many-to-many mapping table in the API database will be created to enable
an aggregate to be associated with one or more resource pools::
CREATE TABLE resource_provider_aggregates (
resource_provider_id INT NOT NULL,
aggregate_id INT NOT NULL,
PRIMARY KEY (aggregate_id, resource_provider_id),
FOREIGN KEY fk_aggregates (aggregate_id)
REFERENCES aggregates (id),
FOREIGN KEY fk_resource_providers (resource_provider_id),
REFERENCES resource_providers (id)
);
A new nova object model for resource pools will be introduced. This object
model will be a thin facade over the `resource_providers` table and allow
querying for the aggregates associated with the resource pool along with the
inventory and allocation records for the pool.
REST API impact
---------------
*ALL* below API calls are meant only for cloud administrators and/or service
users.
*Note*: All of the below API calls should be implemented in
`/nova/api/openstack/placement/`, **not** in `/nova/api/openstack/compute/`
since these calls will be part of the split-out scheduler REST API. There
should be a wholly separate placement API endpoint, started on a different port
than the Nova API, and served by a different service daemon defined in
`/nova/cmd/placement-api.py`.
Microversion support shall be added to the new placement API from the start.
ETags will be used to protect against the lost update problem. This
means that when doing a `PUT` the request must include an `If-Match`
header containing an ETag that matches the server's current ETag for
the resource.
The API changes add resource endpoints to:
* `GET` a list of resource pools
* `POST` a new resource pool
* `GET` a single resource pool with links to its sub-resources
* `PUT` a single resource pool to change its name
* `DELETE` a single resource pool and its associated inventories (if
no allocations are present) and aggregates (the association is
removed, not the aggregates themselves)
* `GET` a list of the inventories associated with a single resource
pool
* `POST` a new inventory of a particular resource class
* `GET` a single inventory of a given resource class
* `PUT` an update to an inventory
* `DELETE` an inventory (if no allocations are present)
* `PUT` a list of aggregates to associate with this resource
* `GET` that list of aggregates
* `GET` a list, by resource class, of usages
This provides granular access to the resources that matter while
providing straightfoward access to usage information.
Details follow.
The following new REST API calls will be added:
`GET /resource_pools`
**********************
Return a list of all resource pools in this Nova deployment.
Example::
200 OK
Content-Type: application/json
{
"resource_pools": [
{
"uuid": "b6b065cc-fcd9-4342-a7b0-2aed2d146518",
"name": "RBD volume group",
"links": [
{
"rel": "self",
"href": "/resource_pools/b6b065cc-fcd9-4342-a7b0-2aed2d146518"
},
{
"rel": "inventories",
"href": "/resource_pools/b6b065cc-fcd9-4342-a7b0-2aed2d146518/inventories"
},
{
"rel": "aggregates",
"href": "resource_pools/b6b065cc-fcd9-4342-a7b0-2aed2d146518/aggregates"
},
{
"rel": "usages",
"href": "resource-pools/b6b065cc-fcd9-4342-a7b0-2aed2d146518/usages"
}
]
},
{
"uuid": "eaaf1c04-ced2-40e4-89a2-87edded06d64",
"name": "Global NFS share",
"links": [
{
"rel": "self",
"href": "/resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64"
},
{
"rel": "inventories",
"href": "/resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories"
},
{
"rel": "aggregates",
"href": "resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/aggregates"
},
{
"rel": "usages",
"href": "resource-pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/usages"
}
]
}
]
}
`POST /resource_pools`
**********************
Create one new resource pool.
An example POST request::
Content-type: application/json
{
"name": "Global NFS share",
"uuid": "eaaf1c04-ced2-40e4-89a2-87edded06d64"
}
The body of the request must match the following JSONSchema document::
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"uuid": {
"type": "uuid"
}
},
"required": [
"name"
]
"additionalProperties": False
}
The response body is empty. The headers include a location header
pointing to the created resource pool::
201 Created
Location: /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64
A `409 Conflict` response code will be returned if another resource pool
exists with the provided name.
`GET /resource_pools/{uuid}`
****************************
Retrieve a representation of the resource pool identified by `{uuid}`.
Example::
GET /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64
200 OK
Content-Type: application/json
{
"uuid": "eaaf1c04-ced2-40e4-89a2-87edded06d64",
"name": "Global NFS share",
"links": [
{
"rel": "self",
"href": "/resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64"
},
{
"rel": "inventories",
"href": "/resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories"
},
{
"rel": "aggregates",
"href": "resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/aggregates"
},
{
"rel": "usages",
"href": "resource-pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/usages"
}
]
}
If the resource pool does not exist a `404 Not Found` must be
returned.
`PUT /resource_pools/{uuid}`
*****************************
Update the name of resource pool identified by `{uuid}`.
Example::
PUT /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64
Content-type: application/json
{
"name": "Global NFS share"
}
The returned HTTP response code will be one of the following:
* `204 No Content` if the request was successful and the resource
pool was updated.
* `400 Bad Request` for bad or invalid syntax.
* `404 Not Found` if a resource pool with `{uuid}` does not exist.
* `409 Conflict` if another resource pool exists with the provided
name.
`DELETE /resource_pools/{uuid}`
********************************
Delete the resource pool identified by `{uuid}`.
This will also disassociate aggregates and delete inventories.
The body of the request and the response is empty.
The returned HTTP response code will be one of the following:
* `204 No Content` if the request was successful and the resource
pool was removed.
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found.
* `409 Conflict` if there exist allocations records for any of the
inventories that would be deleted as a result of removing the
resource pool.
`GET /resource_pools/{uuid}/inventories`
*****************************************
Retrieve a list of inventories that are associated with the resource
pool identified by `{uuid}`.
Example::
GET /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories
200 OK
Content-Type: application/json
{
"inventories": {
'DISK_GB': {
"total": 2048,
"reserved": 512,
"min_unit": 10,
"max_unit": 1024,
"step_size": 10,
"allocation_ratio": 1.0
},
'IPV4_ADDRESS': {
"total": 256,
"reserved": 2,
"min_unit": 1,
"max_unit": 1,
"step_size": 1,
"allocation_ratio": 1.0
}
}
}
The returned HTTP response code will be one of the following:
* `200 OK` if the resource pools exists.
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found.
`POST /resource_pools/{uuid}/inventories`
*****************************************
Create a new inventory for the resource pool identified by `{uuid}`.
Example::
POST /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories
Content-Type: application/json
{
"resource_class": "DISK_GB",
"total": 2048,
"reserved": 512,
"min_unit": 10,
"max_unit": 1024,
"step_size": 10,
"allocation_ratio": 1.0
}
The body of the request must match the following JSONSchema document::
{
"type": "object",
"properties": {
"resource_class": {
"type": "string",
"pattern": "^[A-Z_]+"
},
"total": {
"type": "integer"
},
"reserved": {
"type": "integer"
},
"min_unit": {
"type": "integer"
},
"max_unit": {
"type": "integer"
},
"step_size": {
"type": "integer"
},
"allocation_ratio": {
"type": "number"
},
},
"required": [
"resource_class",
"total"
],
"additionalProperties": False
}
The response body is empty. The headers include a location header
pointing to the created resource pool::
201 Created
Location: /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories/DISK_GB
.. note::
If some non-Nova things have consumed some amount of resources in the pool,
the "reserved" field should be used to adjust the total capacity of the
inventory.
The returned HTTP response code will be one of the following:
* `201 Created` if the inventory is successfully created
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found
* `400 Bad Request` for bad or invalid syntax (for example an
invalid resource class)
* `409 Conflict` if an inventory for the proposed resource class
already exists
`GET /resource_pools/{uuid}/inventories/{resource_class}`
**********************************************************
Retrieve a single inventory of class `{resource_class}` associated
with the resource pool identified by `{uuid}`.
Example::
GET /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories/DISK_GB
200 OK
{
"resource_class": "DISK_GB",
"total": 2048,
"reserved": 512,
"min_unit": 10,
"max_unit": 1024,
"step_size": 10,
"allocation_ratio": 1.0
}
The returned HTTP response code will be one of the following:
* `200 OK` if the inventory exists
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found or an inventory of `{resource_class}` is not associated
with the resource pool
`PUT /resource_pools/{uuid}/inventories/{resource_class}`
**********************************************************
Update an existing inventory.
Example::
PUT /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories/DISK_GB
{
"total": 1024,
"reserved": 512,
"min_unit": 10,
"max_unit": 1024,
"step_size": 10,
"allocation_ratio": 1.0
}
The body of the request must match the JSONSchema document described
in the inventory POST above, except that `resource_class` is not
required and if present is ignored.
The returned HTTP response code will be one of the following:
* `204 No Content` if the inventory is successfully created
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found
* `400 Bad Request` for bad or invalid syntax
* `409 Conflict` if the changes `total`, `reserved` or
`allocation_ratio` would causes existing allocations to be in
conflict with proposed capacity
`DELETE /resource_pools/{uuid}/inventories/{resource_class}`
*************************************************************
Delete an existing inventory.
Example::
DELETE /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/inventories/DISK_GB
The body is empty.
The returned HTTP response code will be one of the following:
* `204 No Content` if the inventory is successfully removed
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found or if there is no associated inventory of
`{resource_class}`
* `400 Bad Request` for bad or invalid syntax
* `409 Conflict` if there are existing allocations for this
inventory
`GET /resource_pools/{uuid}/aggregates`
***************************************
Get a list of aggregates associated with this resource pool.
Example::
GET /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/aggregates
{"aggregates":
[
"21d7c4aa-d0b6-41b1-8513-12a1eac17c0c",
"7a2e7fd2-d1ec-4989-b530-5508c3582025"
]
}
.. note:: The use of a name `aggregates` list preserves the option
of adding other keys to the object later. This is standard
api-wg form for collection resources.
The returned HTTP response code will be one of the following:
* `200 OK` if the resource pool exists
* `404 Not Found` if the resource pool identified by `{uuid}` was
not found
`PUT /resource_pools/{uuid}/aggregates`
**************************************
Associate a list of aggregates with this resource pool.
Example::
PUT /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/aggregates
[
"21d7c4aa-d0b6-41b1-8513-12a1eac17c0c",
"b455ae1f-5f4e-4b19-9384-4989aff5fee9"
]
The returned HTTP response code will be one of the following:
* `204 No content` if the aggregates are successfully updated
* `404 Not Found` if the resource pool does not exist
* `400 Bad Request` for bad or invalid syntax.
`GET /resource_pools/{uuid}/usages`
***********************************
Retrieve a report of usage information for resources associated with
the resource pool identified by `{uuid}`. The value is a dictionary
of resource classes paired with the sum of the allocations of that
resource class for this resource pool.
Example::
GET /resource_pools/eaaf1c04-ced2-40e4-89a2-87edded06d64/usages
{
"usages": {
"DISK_GB": 480,
"IPV4_ADDRESS": 2
}
}
The returned HTTP response code will be one of the following:
* `200 OK` if the resource pool exists. If there are no associated
inventories the `usages` dictionary should be empty.
* `404 Not Found` if the resource pool does not exist.
.. note:: Usages are read only.
Security impact
---------------
None.
Notifications impact
--------------------
We should create new notification messages for when resource pools are created,
destroyed, updated, associated with an aggregate and disassociated from an
aggregate.
Other end user impact
---------------------
New openstackclient CLI commands should be created for the corresponding
functionality:
* `openstack resource-pool list`
* `openstack resource-pool show $UUID`
* `openstack resource-pool create "Global NFS share" \
--aggregate-uuid=$AGG_UUID \
[--uuid=$UUID]`
* `openstack resource-pool delete $UUID`
* `openstack resource-pool update $UUID --name="New name"`
* `openstack resource-pool list inventory $UUID`
* `openstack resource-pool set inventory $UUID \
--resource-class=DISK_GB \
--total=1024 \
--reserved=450 \
--min-unit=1 \
--max-unit=1 \
--step-size=1 \
--allocation-ratio=1.0`
* `openstack resource-pool delete inventory $UUID \
--resource-class=DISK_GB`
* `openstack resource-pool add aggregate $UUID $AGG_UUID`
* `openstack resource-pool delete aggregate $UUID $AGG_UUID`
Performance Impact
------------------
None.
Other deployer impact
---------------------
Deployers who are using shared storage will need to create a resource pool for
their shared disk storage, create any host aggregates that may need to be
created for any compute nodes that utilize that shared storage, associate the
resource pool with those aggregates, and schedule (cronjob or the like) some
script to periodically run `openstack resource-pool set inventory $UUID
--resource-class=DISK_GB --total=X --reserved=Y`.
We should include a sample script along with the documentation for this.
Developer impact
----------------
None.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
cdent
Other contributors:
jaypipes
Work Items
----------
* Create database models and migrations for new `resource_provider_aggregates`
table.
* Create `nova.objects` models for `ResourcePool`
* Create REST API controllers for resource pool querying and handling
* Modify resource tracker to pull information on aggregates the compute node is
associated with and the resource pools available for those aggregates. If the
instance is requesting some amount of DISK_GB resources and the compute node
is associated with a resource pool that contains available DISK_GB inventory,
then the resource tracker shall claim the resources (write an allocation
record) against the resource pool, not the compute node itself.
* Modify the scheduler to look at resource pool information for aggregates
associated with compute nodes to determine if request can be fulfilled by the
resource pool
For this particular step, the changes to the existing filter scheduler
should be minimal. Right now, the host manager queries the list of all
aggregates in the deployment upon each call to
`select_destinations()`. This call to
`nova.objects.AggregateList.get_all()` returns a set of aggregate
objects that are then collated to the hosts that are in each
aggregate. During certain filter `host_passes()` checks, the
aggregate's extra specs can be queried to determine if certain
capability requests are satisfied. We will want to return inventory
and usage information for each resource pool assigned to each
aggregate so that filters like the `DiskFilter` can query not just the
host's `local_gb` value but also the aggregate's inventory information
for share disk storage.
* Docs and example cronjob scripts for updating capacity and usage information
for a shared resource pool of disk
* Functional integration tests in a multi-node devstack environment with shared
storage
Dependencies
============
* `policy-in-code` Blueprint must be completed before this one since we want to
use the new policy framework in the new placement API modules
* `resource-classes` Blueprint must be completed before this one.
* `resource-providers` Blueprint must be completed before this one in order to
ensure the `resource-providers`, `inventories` and `allocations` tables
exist.
* `compute-node-inventory-newton` Blueprint must be completed in order for all
compute nodes to have a UUID column and a record in the `resource_providers`
table. This is necessary in order to determine which resource providers are
resource pools and not compute nodes.
* The part of the `resource-providers-allocations` blueprint that involves
migrating the `inventories`, `allocations`, `aggregates`,
`resource_providers` tables to the top-level API database must be completed
before this
Testing
=======
Full unit and functional integration tests must be added that demonstrate
proper resource accounting of shared storage represented with a generic
resource pool.
Documentation Impact
====================
Developer docs should be added that detail the new resource pool functionality,
how external scripts can keep capacity and usage information updated for a
resource pool.
References
==========
[1] Bugs related to resource usage reporting and calculation:
* Hypervisor summary shows incorrect total storage (Ceph)
https://bugs.launchpad.net/nova/+bug/1387812
* rbd backend reports wrong 'local_gb_used' for compute node
https://bugs.launchpad.net/nova/+bug/1493760
* nova hypervisor-stats shows wrong disk usage with shared storage
https://bugs.launchpad.net/nova/+bug/1414432
* report disk consumption incorrect in nova-compute
https://bugs.launchpad.net/nova/+bug/1315988
* VMWare: available disk spaces(hypervisor-list) only based on a single
datastore instead of all available datastores from cluster
https://bugs.launchpad.net/nova/+bug/1347039
History
=======
.. list-table:: Revisions
:header-rows: 1
* - Release Name
- Description
* - Newton
- Introduced