Skip to content

Commit 49bff9b

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Follow up for unified limits: PCPU and documentation"
2 parents 82a17a3 + d42fe46 commit 49bff9b

File tree

5 files changed

+173
-18
lines changed

5 files changed

+173
-18
lines changed

doc/source/admin/unified-limits.rst

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ To list all default quotas for a project, run:
135135

136136
This lists default quotas for all services and not just nova.
137137

138+
To show details about a default limit, run:
139+
140+
.. code-block:: console
141+
142+
$ openstack registered limit show <registered-limit-id>
143+
138144
To create a default quota limit, run:
139145

140146
.. code-block:: console
@@ -149,12 +155,18 @@ To create a default quota limit, run:
149155

150156
.. _Keystone tokens documentation: https://docs.openstack.org/keystone/latest/admin/tokens-overview.html#operation_create_system_token
151157

152-
To update a default value, run:
158+
To update a default quota value, run:
153159

154160
.. code-block:: console
155161
156162
$ openstack registered limit set --default-limit <value> <registered-limit-id>
157163
164+
To delete a default quota limit, run:
165+
166+
.. code-block:: console
167+
168+
$ openstack registered limit delete <registered-limit-id> [<registered-limit-id> ...]
169+
158170
View and update quota values for a project
159171
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160172

@@ -175,18 +187,36 @@ token and run:
175187
176188
$ openstack limit list
177189
190+
To show details about a quota limit, run:
191+
192+
.. code-block:: console
193+
194+
$ openstack limit show <limit-id>
195+
196+
To create a quota limit for a project, run:
197+
198+
.. code-block:: console
199+
200+
$ openstack limit create --service nova --project <project> --resource-limit <value> <resource-name>
201+
178202
To update quotas for a project, run:
179203

180204
.. code-block:: console
181205
182206
$ openstack limit set --resource-limit <value> <limit-id>
183207
208+
To delete quotas for a project, run:
209+
210+
.. code-block:: console
211+
212+
$ openstack limit delete <limit-id> [<limit-id> ...]
213+
184214
185215
Migration to unified limits quotas
186216
----------------------------------
187217

188-
There is a `nova-manage limits migrate_to_unified_limits`_ command available
189-
to help with moving from legacy Nova database quotas to Keystone unified limits
218+
There is a `nova-manage limits migrate_to_unified_limits`_ command available to
219+
help with moving from legacy Nova database quotas to Keystone unified limits
190220
quotas. The command will read quota limits from the Nova database and call the
191221
Keystone API to create the corresponding unified limits. Per-user quota limits
192222
will **not** be copied into Keystone because per-user quotas are not supported

doc/source/cli/nova-manage.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,46 @@ This command is useful for operators to migrate from legacy quotas to unified
18191819
limits. Limits are migrated by copying them from the Nova database to Keystone
18201820
by creating them using the Keystone API.
18211821

1822+
The Nova configuration file used by ``nova-manage`` must have a ``[keystone]``
1823+
section that contains authentication settings in order for the Keystone API
1824+
calls to succeed. As an example:
1825+
1826+
.. code-block:: ini
1827+
1828+
[keystone]
1829+
region_name = RegionOne
1830+
user_domain_name = Default
1831+
auth_url = http://127.0.0.1/identity
1832+
auth_type = password
1833+
username = admin
1834+
password = <password>
1835+
system_scope = all
1836+
1837+
By default `Keystone policy configuration`_, access to create, update, and
1838+
delete in the `unified limits API`_ is restricted to callers with
1839+
`system-scoped authorization tokens`_. The ``system_scope = all`` setting
1840+
indicates the scope for system operations. You will need to ensure that the
1841+
user configured under ``[keystone]`` has the necessary role and scope.
1842+
1843+
.. warning::
1844+
1845+
The ``limits migrate_to_unified_limits`` command will create limits only
1846+
for resources that exist in the legacy quota system and any resource that
1847+
does not have a unified limit in Keystone will use a quota limit of **0**.
1848+
1849+
For resource classes that are allocated by the placement service and have no
1850+
default limit set, you will need to create default limits manually. The most
1851+
common example is class:DISK_GB. All Nova API requests that need to allocate
1852+
DISK_GB will fail quota enforcement until a default limit for it is set in
1853+
Keystone.
1854+
1855+
See the :doc:`unified limits documentation
1856+
</admin/unified-limits>` about creating limits using the OpenStackClient.
1857+
1858+
.. _Keystone policy configuration: https://docs.openstack.org/keystone/latest/configuration/policy.html
1859+
.. _unified limits API: https://docs.openstack.org/api-ref/identity/v3/index.html#unified-limits
1860+
.. _system-scoped authorization tokens: https://docs.openstack.org/keystone/latest/admin/tokens-overview.html#system-scoped-tokens
1861+
18221862
.. versionadded:: 28.0.0 (2023.2 Bobcat)
18231863

18241864
.. rubric:: Options

doc/source/user/unified-limits.rst

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,21 @@ API`_.
2020
Types of quota
2121
--------------
2222

23+
Unified limit resource names for resources that are tracked as `resource
24+
classes`_ in the placement service follow the naming pattern of the ``class:``
25+
prefix followed by the name of the resource class. For example: class:VCPU,
26+
class:PCPU, class:MEMORY_MB, class:DISK_GB, class:VGPU.
27+
2328
.. list-table::
2429
:header-rows: 1
2530
:widths: 10 40
2631

2732
* - Quota name
2833
- Description
2934
* - class:VCPU
30-
- Number of instance cores (VCPUs) allowed per project.
35+
- Number of shared CPU cores (VCPUs) allowed per project.
36+
* - class:PCPU
37+
- Number of dedicated CPU cores (PCPUs) allowed per project.
3138
* - servers
3239
- Number of instances allowed per project.
3340
* - server_key_pairs
@@ -42,9 +49,11 @@ Types of quota
4249
- Number of servers per server group.
4350
* - class:DISK_GB
4451
- Gigabytes of instance disk allowed per project.
45-
* - class:<any resource in the placement service>
46-
- Any resource in the placement service that is allocated by Nova can have
47-
a quota limit specified for it. Example: class:VGPU.
52+
* - class:<any resource class in the placement service>
53+
- Any resource class in the placement service that is allocated by Nova
54+
can have a quota limit specified for it. Example: class:VGPU.
55+
56+
.. _resource classes: https://docs.openstack.org/os-resource-classes/latest
4857

4958
The following quotas were previously available but were removed in microversion
5059
2.36 as they proxied information available from the networking service.
@@ -125,6 +134,28 @@ For example:
125134
| 17c4552c5aad4afca4813f37530fc897 | 8b22bf8a66fa4524a522b2a21865bbf2 | server_group_members | 10 | None | None |
126135
+----------------------------------+----------------------------------+------------------------------------+---------------+-------------+-----------+
127136
137+
To show details about a default limit, run:
138+
139+
.. code-block:: console
140+
141+
$ openstack registered limit show <registered-limit-id>
142+
143+
For example:
144+
145+
.. code-block:: console
146+
147+
$ openstack registered limit show 8a658096236549788e61f4fcbd5a4a12
148+
+---------------+----------------------------------+
149+
| Field | Value |
150+
+---------------+----------------------------------+
151+
| default_limit | 20 |
152+
| description | None |
153+
| id | 8a658096236549788e61f4fcbd5a4a12 |
154+
| region_id | None |
155+
| resource_name | class:VCPU |
156+
| service_id | 8b22bf8a66fa4524a522b2a21865bbf2 |
157+
+---------------+----------------------------------+
158+
128159
To list the currently set quota values for your project, run:
129160

130161
.. code-block:: console
@@ -141,3 +172,27 @@ For example:
141172
+----------------------------------+----------------------------------+----------------------------------+---------------+----------------+-------------+-----------+
142173
| 8b3364b2241e4090aaaa49355c7a5b56 | 5cd3281595a9497ba87209701cd9f3f2 | 8b22bf8a66fa4524a522b2a21865bbf2 | class:VCPU | 5 | None | None |
143174
+----------------------------------+----------------------------------+----------------------------------+---------------+----------------+-------------+-----------+
175+
176+
To show details about a quota limimt, run:
177+
178+
.. code-block:: console
179+
180+
$ openstack limit show <limit-id>
181+
182+
For example:
183+
184+
.. code-block:: console
185+
186+
$ openstack limit show 8b3364b2241e4090aaaa49355c7a5b56
187+
+----------------+----------------------------------+
188+
| Field | Value |
189+
+----------------+----------------------------------+
190+
| description | None |
191+
| domain_id | None |
192+
| id | 8b3364b2241e4090aaaa49355c7a5b56 |
193+
| project_id | 5cd3281595a9497ba87209701cd9f3f2 |
194+
| region_id | None |
195+
| resource_limit | 5 |
196+
| resource_name | class:VCPU |
197+
| service_id | 8b22bf8a66fa4524a522b2a21865bbf2 |
198+
+----------------+----------------------------------+

nova/cmd/manage.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,17 @@ def _create_unified_limits(self, ctxt, legacy_defaults, project_id,
34253425
zip(unified_to_legacy_names.values(),
34263426
unified_to_legacy_names.keys()))
34273427

3428+
# Handle the special case of PCPU. With legacy quotas, there is no
3429+
# dedicated quota limit for PCPUs, so they share the quota limit for
3430+
# VCPUs: 'cores'. With unified limits, class:PCPU has its own dedicated
3431+
# quota limit, so we will just mirror the limit for class:VCPU and
3432+
# create a limit with the same value for class:PCPU.
3433+
if 'cores' in legacy_defaults:
3434+
# Just make up a dummy legacy resource 'pcores' for this.
3435+
legacy_defaults['pcores'] = legacy_defaults['cores']
3436+
unified_to_legacy_names['class:PCPU'] = 'pcores'
3437+
legacy_to_unified_names['pcores'] = 'class:PCPU'
3438+
34283439
# For auth, a section for [keystone] is required in the config:
34293440
#
34303441
# [keystone]
@@ -3489,6 +3500,11 @@ def _create_unified_limits(self, ctxt, legacy_defaults, project_id,
34893500
msg = f'Found project limits in the database: {legacy_projects} ...'
34903501
output(_(msg))
34913502

3503+
# Handle the special case of PCPU again for project limits.
3504+
if 'cores' in legacy_projects:
3505+
# Just make up a dummy legacy resource 'pcores' for this.
3506+
legacy_projects['pcores'] = legacy_projects['cores']
3507+
34923508
# Retrieve existing limits from Keystone.
34933509
project_limits = keystone_api.limits(
34943510
project_id=project_id, region_id=region_id)

nova/tests/functional/test_nova_manage.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,9 +2496,10 @@ def test_migrate_to_unified_limits_unexpected_error(self, mock_sdk):
24962496
mock_sdk.return_value.create_limit.side_effect = (
24972497
test.TestingException('oops!'))
24982498

2499-
# Create a couple of project limits.
2499+
# Create a few project limits.
25002500
objects.Quotas.create_limit(self.ctxt, uuids.project, 'ram', 8192)
25012501
objects.Quotas.create_limit(self.ctxt, uuids.project, 'instances', 25)
2502+
objects.Quotas.create_limit(self.ctxt, uuids.project, 'cores', 22)
25022503

25032504
return_code = self.cli.migrate_to_unified_limits(
25042505
project_id=uuids.project, verbose=True)
@@ -2511,10 +2512,16 @@ def test_migrate_to_unified_limits_unexpected_error(self, mock_sdk):
25112512
# cores, ram, metadata_items, injected_files,
25122513
# injected_file_content_bytes, injected_file_path_length, key_pairs,
25132514
# server_groups, and server_group_members.
2515+
#
2516+
# And there is 1 default limit value automatically generated for PCPU
2517+
# based on 'cores'.
25142518
self.assertEqual(
2515-
10, mock_sdk.return_value.create_registered_limit.call_count)
2519+
11, mock_sdk.return_value.create_registered_limit.call_count)
25162520

2517-
self.assertEqual(2, mock_sdk.return_value.create_limit.call_count)
2521+
# We expect that we attempted to create 4 project limits:
2522+
# class:MEMORY_MB, servers, and class:VCPU = 3 + special case
2523+
# class:PCPU = 4.
2524+
self.assertEqual(4, mock_sdk.return_value.create_limit.call_count)
25182525

25192526
def test_migrate_to_unified_limits_already_exists(self):
25202527
# Create a couple of unified limits to already exist.
@@ -2531,15 +2538,18 @@ def test_migrate_to_unified_limits_already_exists(self):
25312538
self.cli.migrate_to_unified_limits(
25322539
project_id=uuids.project, verbose=True)
25332540

2534-
# There are 10 default limit values in the config options, so because a
2535-
# limit for 'servers' already exists, we should have only created 9.
2541+
# There are 10 default limit values in the config options +
2542+
# 1 special case for PCPU which will be added based on VCPU = 11.
2543+
# Because a limit for 'servers' already exists, we should have only
2544+
# created 10.
25362545
mock_sdk = self.ul_api.mock_sdk_adapter
25372546
self.assertEqual(
2538-
9, mock_sdk.create_registered_limit.call_count)
2547+
10, mock_sdk.create_registered_limit.call_count)
25392548

25402549
# There already exists a project limit for 'class:VCPU', so we should
2541-
# have created only 1 project limit.
2542-
self.assertEqual(1, mock_sdk.create_limit.call_count)
2550+
# have created only 2 project limits. One for 'servers' and one for
2551+
# special case 'class:PCPU' generated from VCPU.
2552+
self.assertEqual(2, mock_sdk.create_limit.call_count)
25432553

25442554
def test_migrate_to_unified_limits(self):
25452555
# Set some defaults using the config options.
@@ -2587,10 +2597,14 @@ def test_migrate_to_unified_limits(self):
25872597
self.cli.migrate_to_unified_limits(
25882598
project_id=uuids.project, verbose=True)
25892599

2590-
# There should be 10 registered (default) limits now.
2600+
# There are 10 default limit values in the config options +
2601+
# 1 special case for PCPU which will be added based on VCPU = 11.
2602+
#
2603+
# There should be 11 registered (default) limits now.
25912604
expected_registered_limits = {
25922605
'servers': 5,
25932606
'class:VCPU': 10,
2607+
'class:PCPU': 10,
25942608
'class:MEMORY_MB': 4096,
25952609
'server_metadata_items': 64,
25962610
'server_injected_files': 3,
@@ -2602,7 +2616,7 @@ def test_migrate_to_unified_limits(self):
26022616
}
26032617

26042618
registered_limits = self.ul_api.registered_limits()
2605-
self.assertEqual(10, len(registered_limits))
2619+
self.assertEqual(11, len(registered_limits))
26062620
for rl in registered_limits:
26072621
self.assertEqual(
26082622
expected_registered_limits[rl.resource_name], rl.default_limit)
@@ -2634,7 +2648,7 @@ def test_migrate_to_unified_limits(self):
26342648

26352649
region_registered_limits = self.ul_api.registered_limits(
26362650
region_id=uuids.region)
2637-
self.assertEqual(10, len(region_registered_limits))
2651+
self.assertEqual(11, len(region_registered_limits))
26382652
for rl in region_registered_limits:
26392653
self.assertEqual(
26402654
expected_registered_limits[rl.resource_name], rl.default_limit)

0 commit comments

Comments
 (0)