Skip to content

Commit 5505b6f

Browse files
committed
Follow up for unified limits
This addresses remaining comments from the unified limits series to add type hints to new code and add a docstring to the is_qfd_populated() method in nova/quota.py. Related to blueprint unified-limits-nova Change-Id: I948647b04b260e888a4c71c1fa3c2a7be5d140c5
1 parent 9ec6afe commit 5505b6f

File tree

5 files changed

+55
-13
lines changed

5 files changed

+55
-13
lines changed

mypy-files.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
nova/compute/manager.py
22
nova/crypto.py
33
nova/limit/local.py
4+
nova/limit/placement.py
45
nova/network/neutron.py
56
nova/pci
67
nova/privsep/path.py

nova/limit/local.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from oslo_log import log as logging
2121

2222
import nova.conf
23-
from nova import context as nova_context
2423
from nova import exception
2524
from nova.limit import utils as nova_limit_utils
2625
from nova import objects
@@ -80,7 +79,9 @@
8079
}
8180

8281

83-
def get_in_use(context, project_id):
82+
def get_in_use(
83+
context: 'nova.context.RequestContext', project_id: str
84+
) -> ty.Dict[str, int]:
8485
"""Returns in use counts for each resource, for given project.
8586
8687
This sounds simple but many resources can't be counted per project,
@@ -144,7 +145,7 @@ def enforce_api_limit(entity_type: str, count: int) -> None:
144145

145146

146147
def enforce_db_limit(
147-
context: nova_context.RequestContext,
148+
context: 'nova.context.RequestContext',
148149
entity_type: str,
149150
entity_scope: ty.Any,
150151
delta: int
@@ -192,15 +193,17 @@ def enforce_db_limit(
192193
raise EXCEPTIONS.get(entity_type, exception.OverQuota)(str(e))
193194

194195

195-
def _convert_keys_to_legacy_name(new_dict):
196+
def _convert_keys_to_legacy_name(
197+
new_dict: ty.Dict[str, int]
198+
) -> ty.Dict[str, int]:
196199
legacy = {}
197200
for new_name, old_name in LEGACY_LIMITS.items():
198201
# defensive incase oslo or keystone doesn't give us an answer
199202
legacy[old_name] = new_dict.get(new_name) or 0
200203
return legacy
201204

202205

203-
def get_legacy_default_limits():
206+
def get_legacy_default_limits() -> ty.Dict[str, int]:
204207
# TODO(johngarbutt): need oslo.limit API for this, it should do caching
205208
enforcer = limit.Enforcer(lambda: None)
206209
new_limits = enforcer.get_registered_limits(LEGACY_LIMITS.keys())

nova/limit/placement.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
import typing as ty
1516

1617
import os_resource_classes as orc
1718
from oslo_limit import exception as limit_exceptions
@@ -39,17 +40,23 @@
3940
}
4041

4142

42-
def _get_placement_usages(context, project_id):
43+
def _get_placement_usages(
44+
context: 'nova.context.RequestContext', project_id: str
45+
) -> ty.Dict[str, int]:
4346
global PLACEMENT_CLIENT
4447
if not PLACEMENT_CLIENT:
4548
PLACEMENT_CLIENT = report.SchedulerReportClient()
4649
return PLACEMENT_CLIENT.get_usages_counts_for_limits(context, project_id)
4750

4851

49-
def _get_usage(context, project_id, resource_names):
52+
def _get_usage(
53+
context: 'nova.context.RequestContext',
54+
project_id: str,
55+
resource_names: ty.List[str],
56+
) -> ty.Dict[str, int]:
5057
"""Called by oslo_limit's enforcer"""
5158
if not limit_utils.use_unified_limits():
52-
raise NotImplementedError("unified limits is disabled")
59+
raise NotImplementedError("Unified limits support is disabled")
5360

5461
count_servers = False
5562
resource_classes = []
@@ -113,7 +120,9 @@ def _get_usage(context, project_id, resource_names):
113120
return resource_counts
114121

115122

116-
def _get_deltas_by_flavor(flavor, is_bfv, count):
123+
def _get_deltas_by_flavor(
124+
flavor: 'objects.Flavor', is_bfv: bool, count: int
125+
) -> ty.Dict[str, int]:
117126
if flavor is None:
118127
raise ValueError("flavor")
119128
if count < 0:
@@ -132,16 +141,25 @@ def _get_deltas_by_flavor(flavor, is_bfv, count):
132141
return deltas
133142

134143

135-
def _get_enforcer(context, project_id):
144+
def _get_enforcer(
145+
context: 'nova.context.RequestContext', project_id: str
146+
) -> limit.Enforcer:
136147
# NOTE(johngarbutt) should we move context arg into oslo.limit?
137148
def callback(project_id, resource_names):
138149
return _get_usage(context, project_id, resource_names)
139150

140151
return limit.Enforcer(callback)
141152

142153

143-
def enforce_num_instances_and_flavor(context, project_id, flavor, is_bfvm,
144-
min_count, max_count, enforcer=None):
154+
def enforce_num_instances_and_flavor(
155+
context: 'nova.context.RequestContext',
156+
project_id: str,
157+
flavor: 'objects.Flavor',
158+
is_bfvm: bool,
159+
min_count: int,
160+
max_count: int,
161+
enforcer: ty.Optional[limit.Enforcer] = None
162+
) -> int:
145163
"""Return max instances possible, else raise TooManyInstances exception."""
146164
if not limit_utils.use_unified_limits():
147165
return max_count

nova/quota.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,26 @@ def _server_group_count_members_by_user_legacy(context, group, user_id):
12431243

12441244

12451245
def is_qfd_populated(context):
1246+
"""Check if user_id and queued_for_delete fields are populated.
1247+
1248+
This method is related to counting quota usage from placement. It is not
1249+
yet possible to count instances from placement, so in the meantime we can
1250+
use instance mappings for counting. This method is used to determine
1251+
whether the user_id and queued_for_delete columns are populated in the API
1252+
database's instance_mappings table. Instance mapping records are not
1253+
deleted from the database until the database is archived, so
1254+
queued_for_delete tells us whether or not we should count them for instance
1255+
quota usage. The user_id field enables us to scope instance quota usage to
1256+
a user (legacy quota).
1257+
1258+
Scoping instance quota to a user is only possible
1259+
when counting quota usage from placement is configured and unified limits
1260+
is not configured. When unified limits is configured, quotas are scoped
1261+
only to projects.
1262+
1263+
In the future when it is possible to count instance usage from placement,
1264+
this method will no longer be needed.
1265+
"""
12461266
global UID_QFD_POPULATED_CACHE_ALL
12471267
if not UID_QFD_POPULATED_CACHE_ALL:
12481268
LOG.debug('Checking whether user_id and queued_for_delete are '

nova/tests/unit/limit/test_placement.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def test_get_usage_unified_limits_disabled(self):
7979
self.flags(driver="nova.quota.NoopQuotaDriver", group="quota")
8080
e = self.assertRaises(NotImplementedError, placement_limits._get_usage,
8181
self.context, uuids.project, [])
82-
self.assertEqual("unified limits is disabled", str(e))
82+
self.assertEqual("Unified limits support is disabled", str(e))
8383

8484
@mock.patch.object(quota, "is_qfd_populated")
8585
@mock.patch.object(objects.InstanceMappingList, "get_counts")

0 commit comments

Comments
 (0)