diff --git a/nova/conf/quota.py b/nova/conf/quota.py index 2aa893af21cf..e39d4eaf91c0 100644 --- a/nova/conf/quota.py +++ b/nova/conf/quota.py @@ -17,10 +17,19 @@ from oslo_config import cfg +quota_group = cfg.OptGroup( + name='quota', + title='Quota Options', + help=""" +Quota options allow to manage quotas in openstack deployment. +""") + quota_opts = [ - cfg.IntOpt('quota_instances', + cfg.IntOpt('instances', min=-1, default=10, + deprecated_group='DEFAULT', + deprecated_name='quota_instances', help=""" The number of instances allowed per project. @@ -29,9 +38,11 @@ Possible Values * 10 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_cores', + cfg.IntOpt('cores', min=-1, default=20, + deprecated_group='DEFAULT', + deprecated_name='quota_cores', help=""" The number of instance cores or VCPUs allowed per project. @@ -40,9 +51,11 @@ Possible values: * 20 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_ram', + cfg.IntOpt('ram', min=-1, default=50 * 1024, + deprecated_group='DEFAULT', + deprecated_name='quota_ram', help=""" The number of megabytes of instance RAM allowed per project. @@ -51,9 +64,11 @@ Possible values: * 51200 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_floating_ips', + cfg.IntOpt('floating_ips', min=-1, default=10, + deprecated_group='DEFAULT', + deprecated_name='quota_floating_ips', help=""" The number of floating IPs allowed per project. Floating IPs are not allocated to instances by default. Users need to select them from the pool configured by @@ -64,9 +79,11 @@ Possible values: * 10 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_fixed_ips', + cfg.IntOpt('fixed_ips', min=-1, default=-1, + deprecated_group='DEFAULT', + deprecated_name='quota_fixed_ips', help=""" The number of fixed IPs allowed per project (this should be at least the number of instances allowed). Unlike floating IPs, fixed IPs are allocated dynamically @@ -77,9 +94,11 @@ Possible values: * -1 (default) : treated as unlimited. * Any positive integer. """), - cfg.IntOpt('quota_metadata_items', + cfg.IntOpt('metadata_items', min=-1, default=128, + deprecated_group='DEFAULT', + deprecated_name='quota_metadata_items', help=""" The number of metadata items allowed per instance. User can associate metadata while instance creation in the form of key-value pairs. @@ -89,9 +108,11 @@ Possible values: * 128 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_injected_files', + cfg.IntOpt('injected_files', min=-1, default=5, + deprecated_group='DEFAULT', + deprecated_name='quota_injected_files', help=""" The number of injected files allowed. It allow users to customize the personality of an instance by injecting data into it upon boot. Only text @@ -104,9 +125,11 @@ Possible values: * 5 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_injected_file_content_bytes', + cfg.IntOpt('injected_file_content_bytes', min=-1, default=10 * 1024, + deprecated_group='DEFAULT', + deprecated_name='quota_injected_file_content_bytes', help=""" The number of bytes allowed per injected file. @@ -115,9 +138,11 @@ Possible values: * 10240 (default) or any positive integer representing number of bytes. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_injected_file_path_length', + cfg.IntOpt('injected_file_path_length', min=-1, default=255, + deprecated_group='DEFAULT', + deprecated_name='quota_injected_file_path_length', help=""" The maximum allowed injected file path length. @@ -126,9 +151,11 @@ Possible values: * 255 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_security_groups', + cfg.IntOpt('security_groups', min=-1, default=10, + deprecated_group='DEFAULT', + deprecated_name='quota_security_groups', help=""" The number of security groups per project. @@ -137,9 +164,11 @@ Possible values: * 10 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_security_group_rules', + cfg.IntOpt('security_group_rules', min=-1, default=20, + deprecated_group='DEFAULT', + deprecated_name='quota_security_group_rules', help=""" The number of security rules per security group. The associated rules in each security group control the traffic to instances in the group. @@ -149,9 +178,11 @@ Possible values: * 20 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_key_pairs', + cfg.IntOpt('key_pairs', min=-1, default=100, + deprecated_group='DEFAULT', + deprecated_name='quota_key_pairs', help=""" The maximum number of key pairs allowed per user. Users can create at least one key pair for each project and use the key pair for multiple instances that @@ -162,9 +193,11 @@ Possible values: * 100 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_server_groups', + cfg.IntOpt('server_groups', min=-1, default=10, + deprecated_group='DEFAULT', + deprecated_name='quota_server_groups', help=""" Add quota values to constrain the number of server groups per project. Server group used to control the affinity and anti-affinity scheduling policy for a @@ -177,9 +210,11 @@ Possible values: * 10 (default) or any positive integer. * -1 : treated as unlimited. """), - cfg.IntOpt('quota_server_group_members', + cfg.IntOpt('server_group_members', min=-1, default=10, + deprecated_group='DEFAULT', + deprecated_name='quota_server_group_members', help=""" Add quota values to constrain the number of servers per server group. @@ -190,6 +225,7 @@ Possible values: """), cfg.IntOpt('reservation_expire', default=86400, + deprecated_group='DEFAULT', help=""" The number of seconds until a reservation expires. It represents the time period for invalidating quota reservations. @@ -201,6 +237,7 @@ Possible values: cfg.IntOpt('until_refresh', min=0, default=0, + deprecated_group='DEFAULT', help=""" The count of reservations until usage is refreshed. This defaults to 0 (off) to avoid additional load but it is useful to turn on to help keep quota usage @@ -213,6 +250,7 @@ Possible values: cfg.IntOpt('max_age', min=0, default=0, + deprecated_group='DEFAULT', help=""" The number of seconds between subsequent usage refreshes. This defaults to 0 (off) to avoid additional load but it is useful to turn on to help keep quota @@ -227,10 +265,12 @@ Possible values: # TODO(pumaranikar): Add a new config to select between the db_driver and # the no_op driver using stevedore. - cfg.StrOpt('quota_driver', + cfg.StrOpt('driver', default='nova.quota.DbQuotaDriver', deprecated_for_removal=True, deprecated_since='14.0.0', + deprecated_group='DEFAULT', + deprecated_name='quota_driver', help=""" Provides abstraction for quota checks. Users can configure a specific driver to use for quota checks. @@ -244,10 +284,9 @@ Possible values: def register_opts(conf): - conf.register_opts(quota_opts) + conf.register_group(quota_group) + conf.register_opts(quota_opts, group=quota_group) -# TODO(pumaranikar): We can consider moving these options to quota group -# and renaming them all to drop the quota bit. def list_opts(): - return {'DEFAULT': quota_opts} + return {quota_group: quota_opts} diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 0b1f1f1c3c62..fb3dc9eedf26 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -4510,7 +4510,7 @@ def _security_group_ensure_default(context): context.user_id, 'security_groups', 1, 0, - CONF.until_refresh, + CONF.quota.until_refresh, context.session) else: usage.update({'in_use': int(usage.first().in_use) + 1}) diff --git a/nova/quota.py b/nova/quota.py index 6313acf9fde5..361f93695051 100644 --- a/nova/quota.py +++ b/nova/quota.py @@ -485,7 +485,7 @@ class DbQuotaDriver(object): # Set up the reservation expiration if expire is None: - expire = CONF.reservation_expire + expire = CONF.quota.reservation_expire if isinstance(expire, six.integer_types): expire = datetime.timedelta(seconds=expire) if isinstance(expire, datetime.timedelta): @@ -539,7 +539,7 @@ class DbQuotaDriver(object): # have to do the work there. return db.quota_reserve(context, resources, quotas, user_quotas, deltas, expire, - CONF.until_refresh, CONF.max_age, + CONF.quota.until_refresh, CONF.quota.max_age, project_id=project_id, user_id=user_id) def commit(self, context, reservations, project_id=None, user_id=None): @@ -660,7 +660,8 @@ class DbQuotaDriver(object): resource_names = syncable_resources return db.quota_usage_refresh(context, resources, resource_names, - CONF.until_refresh, CONF.max_age, + CONF.quota.until_refresh, + CONF.quota.max_age, project_id=project_id, user_id=user_id) def destroy_all_by_project_and_user(self, context, project_id, user_id): @@ -1060,7 +1061,12 @@ class BaseResource(object): def default(self): """Return the default value of the quota.""" - return CONF[self.flag] if self.flag else -1 + # NOTE(mikal): special case for quota_networks, which is an API + # flag and not a quota flag + if self.flag == 'quota_networks': + return CONF[self.flag] + + return CONF.quota[self.flag] if self.flag else -1 class ReservableResource(BaseResource): @@ -1158,7 +1164,7 @@ class QuotaEngine(object): if self.__driver: return self.__driver if not self._driver_cls: - self._driver_cls = CONF.quota_driver + self._driver_cls = CONF.quota.driver if isinstance(self._driver_cls, six.string_types): self._driver_cls = importutils.import_object(self._driver_cls) self.__driver = self._driver_cls @@ -1520,30 +1526,30 @@ QUOTAS = QuotaEngine() resources = [ - ReservableResource('instances', '_sync_instances', 'quota_instances'), - ReservableResource('cores', '_sync_instances', 'quota_cores'), - ReservableResource('ram', '_sync_instances', 'quota_ram'), + ReservableResource('instances', '_sync_instances', 'instances'), + ReservableResource('cores', '_sync_instances', 'cores'), + ReservableResource('ram', '_sync_instances', 'ram'), ReservableResource('security_groups', '_sync_security_groups', - 'quota_security_groups'), + 'security_groups'), ReservableResource('floating_ips', '_sync_floating_ips', - 'quota_floating_ips'), - ReservableResource('fixed_ips', '_sync_fixed_ips', 'quota_fixed_ips'), - AbsoluteResource('metadata_items', 'quota_metadata_items'), - AbsoluteResource('injected_files', 'quota_injected_files'), + 'floating_ips'), + ReservableResource('fixed_ips', '_sync_fixed_ips', 'fixed_ips'), + AbsoluteResource('metadata_items', 'metadata_items'), + AbsoluteResource('injected_files', 'injected_files'), AbsoluteResource('injected_file_content_bytes', - 'quota_injected_file_content_bytes'), + 'injected_file_content_bytes'), AbsoluteResource('injected_file_path_bytes', - 'quota_injected_file_path_length'), + 'injected_file_path_length'), CountableResource('security_group_rules', db.security_group_rule_count_by_group, - 'quota_security_group_rules'), + 'security_group_rules'), CountableResource('key_pairs', _keypair_get_count_by_user, - 'quota_key_pairs'), + 'key_pairs'), ReservableResource('server_groups', '_sync_server_groups', - 'quota_server_groups'), + 'server_groups'), CountableResource('server_group_members', _server_group_count_members_by_user, - 'quota_server_group_members'), + 'server_group_members'), ] diff --git a/nova/tests/functional/test_server_group.py b/nova/tests/functional/test_server_group.py index 0e75973de942..7b91137cd658 100644 --- a/nova/tests/functional/test_server_group.py +++ b/nova/tests/functional/test_server_group.py @@ -228,7 +228,7 @@ class ServerGroupTestV21(ServerGroupTestBase): def test_boot_servers_with_affinity_overquota(self): # Tests that we check server group member quotas and cleanup created # resources when we fail with OverQuota. - self.flags(quota_server_group_members=1) + self.flags(server_group_members=1, group='quota') # make sure we start with 0 servers servers = self.api.get_servers(detail=False) self.assertEqual(0, len(servers)) diff --git a/nova/tests/unit/api/openstack/compute/test_security_groups.py b/nova/tests/unit/api/openstack/compute/test_security_groups.py index 25d5a3704fac..ceaac6206180 100644 --- a/nova/tests/unit/api/openstack/compute/test_security_groups.py +++ b/nova/tests/unit/api/openstack/compute/test_security_groups.py @@ -310,7 +310,7 @@ class TestSecurityGroupsV21(test.TestCase): self.req.environ['nova.context']) def test_create_security_group_quota_limit(self): - for num in range(1, CONF.quota_security_groups): + for num in range(1, CONF.quota.security_groups): name = 'test%s' % num sg = security_group_request_template(name=name) res_dict = self.controller.create(self.req, {'security_group': sg}) @@ -1200,7 +1200,7 @@ class TestSecurityGroupRulesV21(test.TestCase): self.req, self.invalid_id) def test_create_rule_quota_limit(self): - for num in range(100, 100 + CONF.quota_security_group_rules): + for num in range(100, 100 + CONF.quota.security_group_rules): rule = { 'ip_protocol': 'tcp', 'from_port': num, 'to_port': num, 'parent_group_id': self.sg2['id'], diff --git a/nova/tests/unit/api/openstack/compute/test_server_actions.py b/nova/tests/unit/api/openstack/compute/test_server_actions.py index b478d0fb1d1a..0166179a4569 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_actions.py +++ b/nova/tests/unit/api/openstack/compute/test_server_actions.py @@ -1134,7 +1134,7 @@ class ServerActionsControllerTestV21(test.TestCase): 'metadata': {}, }, } - for num in range(CONF.quota_metadata_items + 1): + for num in range(CONF.quota.metadata_items + 1): body['createImage']['metadata']['foo%i' % num] = "bar" self.assertRaises(webob.exc.HTTPForbidden, diff --git a/nova/tests/unit/api/openstack/compute/test_server_group_quotas.py b/nova/tests/unit/api/openstack/compute/test_server_group_quotas.py index a889f6de5ecb..516bfec56fc1 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_group_quotas.py +++ b/nova/tests/unit/api/openstack/compute/test_server_group_quotas.py @@ -104,7 +104,7 @@ class ServerGroupQuotasTestV21(test.TestCase): policies = ['anti-affinity'] sgroup['policies'] = policies # Start by creating as many server groups as we're allowed to. - for i in range(CONF.quota_server_groups): + for i in range(CONF.quota.server_groups): self.controller.create(self.req, body={'server_group': sgroup}) # Then, creating a server group should fail. diff --git a/nova/tests/unit/api/openstack/compute/test_server_metadata.py b/nova/tests/unit/api/openstack/compute/test_server_metadata.py index 34399c7087b0..b39dead5ef27 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_metadata.py +++ b/nova/tests/unit/api/openstack/compute/test_server_metadata.py @@ -75,7 +75,7 @@ def stub_server_metadata(): def stub_max_server_metadata(): metadata = {"metadata": {}} - for num in range(CONF.quota_metadata_items): + for num in range(CONF.quota.metadata_items): metadata['metadata']['key%i' % num] = "blah" return metadata @@ -582,7 +582,7 @@ class ServerMetaDataTestV21(test.TestCase): self.stub_out('nova.db.instance_metadata_update', return_create_instance_metadata) data = {"metadata": {}} - for num in range(CONF.quota_metadata_items + 1): + for num in range(CONF.quota.metadata_items + 1): data['metadata']['key%i' % num] = "blah" req = self._get_request() req.method = 'POST' @@ -621,7 +621,7 @@ class ServerMetaDataTestV21(test.TestCase): self.stub_out('nova.db.instance_metadata_update', return_create_instance_metadata) data = {"metadata": {}} - for num in range(CONF.quota_metadata_items + 1): + for num in range(CONF.quota.metadata_items + 1): data['metadata']['key%i' % num] = "blah" req = self._get_request() req.method = 'PUT' @@ -637,7 +637,7 @@ class ServerMetaDataTestV21(test.TestCase): self.stub_out('nova.db.instance_metadata_update', return_create_instance_metadata) data = {"metadata": {}} - for num in range(CONF.quota_metadata_items + 1): + for num in range(CONF.quota.metadata_items + 1): data['metadata']['key%i' % num] = "blah" req = self._get_request() req.method = 'PUT' diff --git a/nova/tests/unit/api/openstack/compute/test_serversV21.py b/nova/tests/unit/api/openstack/compute/test_serversV21.py index 3bcae4787b13..80d021f6a36d 100644 --- a/nova/tests/unit/api/openstack/compute/test_serversV21.py +++ b/nova/tests/unit/api/openstack/compute/test_serversV21.py @@ -2891,14 +2891,14 @@ class ServersControllerCreateTest(test.TestCase): self._test_create_instance_numa_topology_wrong(exc) def test_create_instance_too_much_metadata(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata']['vote'] = 'fiddletown' self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, self.req, body=self.body) def test_create_instance_metadata_key_too_long(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = {('a' * 260): '12345'} self.req.body = jsonutils.dump_as_bytes(self.body) @@ -2906,35 +2906,35 @@ class ServersControllerCreateTest(test.TestCase): self.controller.create, self.req, body=self.body) def test_create_instance_metadata_value_too_long(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = {'key1': ('a' * 260)} self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(exception.ValidationError, self.controller.create, self.req, body=self.body) def test_create_instance_metadata_key_blank(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = {'': 'abcd'} self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(exception.ValidationError, self.controller.create, self.req, body=self.body) def test_create_instance_metadata_not_dict(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = 'string' self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(exception.ValidationError, self.controller.create, self.req, body=self.body) def test_create_instance_metadata_key_not_string(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = {1: 'test'} self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(exception.ValidationError, self.controller.create, self.req, body=self.body) def test_create_instance_metadata_value_not_string(self): - self.flags(quota_metadata_items=1) + self.flags(metadata_items=1, group='quota') self.body['server']['metadata'] = {'test': ['a', 'list']} self.req.body = jsonutils.dump_as_bytes(self.body) self.assertRaises(exception.ValidationError, diff --git a/nova/tests/unit/compute/test_keypairs.py b/nova/tests/unit/compute/test_keypairs.py index 528a2a46b2cc..b5d737741a10 100644 --- a/nova/tests/unit/compute/test_keypairs.py +++ b/nova/tests/unit/compute/test_keypairs.py @@ -151,7 +151,7 @@ class CreateImportSharedTestMixIn(object): def test_quota_limit(self): def fake_quotas_count(self, context, resource, *args, **kwargs): - return CONF.quota_key_pairs + return CONF.quota.key_pairs self.stubs.Set(QUOTAS, "count", fake_quotas_count) diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index af130f94c251..947a755210ec 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -157,7 +157,7 @@ def _quota_reserve(context, project_id, user_id): sqlalchemy_api.QUOTA_SYNC_FUNCTIONS[sync_name] = getattr( sqlalchemy_api, sync_name) return db.quota_reserve(context, resources, quotas, user_quotas, deltas, - timeutils.utcnow(), CONF.until_refresh, + timeutils.utcnow(), CONF.quota.until_refresh, datetime.timedelta(days=1), project_id, user_id) @@ -2237,7 +2237,7 @@ class SecurityGroupTestCase(test.TestCase, ModelsObjectComparatorMixin): self.assertEqual(1, usage.in_use) def test_security_group_ensure_default_until_refresh(self): - self.flags(until_refresh=2) + self.flags(until_refresh=2, group='quota') self.ctxt.project_id = 'fake' self.ctxt.user_id = 'fake' db.security_group_ensure_default(self.ctxt) diff --git a/nova/tests/unit/test_quota.py b/nova/tests/unit/test_quota.py index b4d8b88fd4b7..49010335a527 100644 --- a/nova/tests/unit/test_quota.py +++ b/nova/tests/unit/test_quota.py @@ -42,8 +42,9 @@ class QuotaIntegrationTestCase(test.TestCase): def setUp(self): super(QuotaIntegrationTestCase, self).setUp() - self.flags(quota_instances=2, - quota_cores=4) + self.flags(instances=2, + cores=4, + group='quota') self.user_id = 'admin' self.project_id = 'admin' @@ -80,7 +81,7 @@ class QuotaIntegrationTestCase(test.TestCase): def test_too_many_instances(self): instance_uuids = [] - for i in range(CONF.quota_instances): + for i in range(CONF.quota.instances): instance = self._create_instance() instance_uuids.append(instance['uuid']) inst_type = flavors.get_flavor_by_name('m1.small') @@ -122,15 +123,15 @@ class QuotaIntegrationTestCase(test.TestCase): def test_many_cores_with_unlimited_quota(self): # Setting cores quota to unlimited: - self.flags(quota_cores=-1) + self.flags(cores=-1, group='quota') instance = self._create_instance(cores=4) db.instance_destroy(self.context, instance['uuid']) def test_too_many_addresses(self): # This test is specifically relying on nova-network. self.flags(use_neutron=False, - quota_floating_ips=1, network_manager='nova.network.manager.FlatDHCPManager') + self.flags(floating_ips=1, group='quota') # Apparently needed by the RPC tests... self.network = self.start_service('network', manager=CONF.network_manager) @@ -148,8 +149,8 @@ class QuotaIntegrationTestCase(test.TestCase): def test_auto_assigned(self): # This test is specifically relying on nova-network. self.flags(use_neutron=False, - quota_floating_ips=1, network_manager='nova.network.manager.FlatDHCPManager') + self.flags(floating_ips=1, group='quota') # Apparently needed by the RPC tests... self.network = self.start_service('network', manager=CONF.network_manager) @@ -168,7 +169,7 @@ class QuotaIntegrationTestCase(test.TestCase): def test_too_many_metadata_items(self): metadata = {} - for i in range(CONF.quota_metadata_items + 1): + for i in range(CONF.quota.metadata_items + 1): metadata['key%s' % i] = 'value%s' % i inst_type = flavors.get_flavor_by_name('m1.small') image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' @@ -198,38 +199,38 @@ class QuotaIntegrationTestCase(test.TestCase): def test_max_injected_files(self): files = [] - for i in range(CONF.quota_injected_files): + for i in range(CONF.quota.injected_files): files.append(('/my/path%d' % i, 'config = test\n')) self._create_with_injected_files(files) # no QuotaError def test_too_many_injected_files(self): files = [] - for i in range(CONF.quota_injected_files + 1): + for i in range(CONF.quota.injected_files + 1): files.append(('/my/path%d' % i, 'my\ncontent%d\n' % i)) self.assertRaises(exception.QuotaError, self._create_with_injected_files, files) def test_max_injected_file_content_bytes(self): - max = CONF.quota_injected_file_content_bytes + max = CONF.quota.injected_file_content_bytes content = ''.join(['a' for i in range(max)]) files = [('/test/path', content)] self._create_with_injected_files(files) # no QuotaError def test_too_many_injected_file_content_bytes(self): - max = CONF.quota_injected_file_content_bytes + max = CONF.quota.injected_file_content_bytes content = ''.join(['a' for i in range(max + 1)]) files = [('/test/path', content)] self.assertRaises(exception.QuotaError, self._create_with_injected_files, files) def test_max_injected_file_path_bytes(self): - max = CONF.quota_injected_file_path_length + max = CONF.quota.injected_file_path_length path = ''.join(['a' for i in range(max)]) files = [(path, 'config = quotatest')] self._create_with_injected_files(files) # no QuotaError def test_too_many_injected_file_path_bytes(self): - max = CONF.quota_injected_file_path_length + max = CONF.quota.injected_file_path_length path = ''.join(['a' for i in range(max + 1)]) files = [(path, 'config = quotatest')] self.assertRaises(exception.QuotaError, @@ -371,24 +372,24 @@ class BaseResourceTestCase(test.TestCase): def test_with_flag(self): # We know this flag exists, so use it... - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') self.assertEqual(resource.name, 'test_resource') - self.assertEqual(resource.flag, 'quota_instances') + self.assertEqual(resource.flag, 'instances') self.assertEqual(resource.default, 10) def test_with_flag_no_quota(self): - self.flags(quota_instances=-1) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=-1, group='quota') + resource = quota.BaseResource('test_resource', 'instances') self.assertEqual(resource.name, 'test_resource') - self.assertEqual(resource.flag, 'quota_instances') + self.assertEqual(resource.flag, 'instances') self.assertEqual(resource.default, -1) def test_quota_no_project_no_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver() context = FakeContext(None, None) quota_value = resource.quota(driver, context) @@ -396,8 +397,8 @@ class BaseResourceTestCase(test.TestCase): self.assertEqual(quota_value, 10) def test_quota_with_project_no_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver(by_project=dict( test_project=dict(test_resource=15), )) @@ -407,8 +408,8 @@ class BaseResourceTestCase(test.TestCase): self.assertEqual(quota_value, 15) def test_quota_no_project_with_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver(by_class=dict( test_class=dict(test_resource=20), )) @@ -418,8 +419,8 @@ class BaseResourceTestCase(test.TestCase): self.assertEqual(quota_value, 20) def test_quota_with_project_with_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver(by_project=dict( test_project=dict(test_resource=15), ), @@ -432,8 +433,8 @@ class BaseResourceTestCase(test.TestCase): self.assertEqual(quota_value, 15) def test_quota_override_project_with_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver(by_project=dict( test_project=dict(test_resource=15), override_project=dict(test_resource=20), @@ -445,8 +446,8 @@ class BaseResourceTestCase(test.TestCase): self.assertEqual(quota_value, 20) def test_quota_with_project_override_class(self): - self.flags(quota_instances=10) - resource = quota.BaseResource('test_resource', 'quota_instances') + self.flags(instances=10, group='quota') + resource = quota.BaseResource('test_resource', 'instances') driver = FakeDriver(by_class=dict( test_class=dict(test_resource=15), override_class=dict(test_resource=20), @@ -828,22 +829,23 @@ class DbQuotaDriverTestCase(test.TestCase): def setUp(self): super(DbQuotaDriverTestCase, self).setUp() - self.flags(quota_instances=10, - quota_cores=20, - quota_ram=50 * 1024, - quota_floating_ips=10, - quota_fixed_ips=10, - quota_metadata_items=128, - quota_injected_files=5, - quota_injected_file_content_bytes=10 * 1024, - quota_injected_file_path_length=255, - quota_security_groups=10, - quota_security_group_rules=20, - quota_server_groups=10, - quota_server_group_members=10, + self.flags(instances=10, + cores=20, + ram=50 * 1024, + floating_ips=10, + fixed_ips=10, + metadata_items=128, + injected_files=5, + injected_file_content_bytes=10 * 1024, + injected_file_path_length=255, + security_groups=10, + security_group_rules=20, + server_groups=10, + server_group_members=10, reservation_expire=86400, until_refresh=0, max_age=0, + group='quota' ) self.driver = quota.DbQuotaDriver() @@ -2217,7 +2219,7 @@ class DbQuotaDriverTestCase(test.TestCase): injected_file_path_bytes=256)) def test_limit_check_unlimited(self): - self.flags(quota_metadata_items=-1) + self.flags(metadata_items=-1, group='quota') self._stub_get_project_quotas() self.driver.limit_check(FakeContext('test_project', 'test_class'), quota.QUOTAS._resources, @@ -2308,7 +2310,7 @@ class DbQuotaDriverTestCase(test.TestCase): def test_reserve_until_refresh(self): self._stub_get_project_quotas() self._stub_quota_reserve() - self.flags(until_refresh=500) + self.flags(until_refresh=500, group='quota') expire = timeutils.utcnow() + datetime.timedelta(seconds=120) result = self.driver.reserve(FakeContext('test_project', 'test_class'), quota.QUOTAS._resources, @@ -2323,7 +2325,7 @@ class DbQuotaDriverTestCase(test.TestCase): def test_reserve_max_age(self): self._stub_get_project_quotas() self._stub_quota_reserve() - self.flags(max_age=86400) + self.flags(max_age=86400, group='quota') expire = timeutils.utcnow() + datetime.timedelta(seconds=120) result = self.driver.reserve(FakeContext('test_project', 'test_class'), quota.QUOTAS._resources, @@ -2750,7 +2752,7 @@ class QuotaReserveSqlAlchemyTestCase(QuotaSqlAlchemyBase): def test_quota_reserve_cores_unlimited(self): # Requesting 8 cores, quota_cores set to unlimited: - self.flags(quota_cores=-1) + self.flags(cores=-1, group='quota') self._init_usages(1, 8, 1 * 1024, 1) self.assertEqual(self.sync_called, set([])) self.usages_list[0]["in_use"] = 1 @@ -2767,7 +2769,7 @@ class QuotaReserveSqlAlchemyTestCase(QuotaSqlAlchemyBase): def test_quota_reserve_ram_unlimited(self): # Requesting 10*1024 ram, quota_ram set to unlimited: - self.flags(quota_ram=-1) + self.flags(ram=-1, group='quota') self._init_usages(1, 1, 10 * 1024, 1) self.assertEqual(self.sync_called, set([])) self.usages_list[0]["in_use"] = 1 @@ -3078,19 +3080,20 @@ class NoopQuotaDriverTestCase(test.TestCase): def setUp(self): super(NoopQuotaDriverTestCase, self).setUp() - self.flags(quota_instances=10, - quota_cores=20, - quota_ram=50 * 1024, - quota_floating_ips=10, - quota_metadata_items=128, - quota_injected_files=5, - quota_injected_file_content_bytes=10 * 1024, - quota_injected_file_path_length=255, - quota_security_groups=10, - quota_security_group_rules=20, + self.flags(instances=10, + cores=20, + ram=50 * 1024, + floating_ips=10, + metadata_items=128, + injected_files=5, + injected_file_content_bytes=10 * 1024, + injected_file_path_length=255, + security_groups=10, + security_group_rules=20, reservation_expire=86400, until_refresh=0, max_age=0, + group='quota' ) self.expected_with_usages = {} diff --git a/releasenotes/notes/quota-config-group-8028127074d43c48.yaml b/releasenotes/notes/quota-config-group-8028127074d43c48.yaml new file mode 100644 index 000000000000..72c96e9e7799 --- /dev/null +++ b/releasenotes/notes/quota-config-group-8028127074d43c48.yaml @@ -0,0 +1,26 @@ +--- +upgrade: + - | + Most quota options have been moved into their own + configuration group. The exception is quota_networks + as it is an API flag not a quota flag. These options are as + below: + + - ``quota_instances`` (now ``instances``) + - ``quota_cores`` (now ``cores``) + - ``quota_ram`` (now ``ram``) + - ``quota_floating_ips`` (now ``floating_ips``) + - ``quota_fixed_ips`` (now ``fixed_ips``) + - ``quota_metadata_items`` (now ``metadata_items``) + - ``quota_injected_files`` (now ``injected_files``) + - ``quota_injected_file_content_bytes`` (now ``injected_file_content_bytes``) + - ``quota_injected_file_path_length`` (now ``injected_file_path_length``) + - ``quota_security_groups`` (now ``security_groups``) + - ``quota_security_group_rules`` (now ``security_group_rules``) + - ``quota_key_pairs`` (now ``key_pairs``) + - ``quota_server_groups`` (now ``server_groups``) + - ``quota_server_group_members`` (now ``server_group_members``) + - ``reservation_expire`` + - ``until_refresh`` + - ``max_age`` + - ``quota_driver`` (now ``driver``)