Several changes designed to bring the openstack api 1.1 closer to spec
- add ram limits to the nova compute quotas - enable injected file limits and injected file size limits to be overridden in the quota database table - expose quota limits as absolute limits in the openstack api 1.1 limits resource - add support for controlling 'unlimited' quotas to nova-manage
This commit is contained in:
		@@ -417,12 +417,16 @@ class ProjectCommands(object):
 | 
				
			|||||||
        arguments: project_id [key] [value]"""
 | 
					        arguments: project_id [key] [value]"""
 | 
				
			||||||
        ctxt = context.get_admin_context()
 | 
					        ctxt = context.get_admin_context()
 | 
				
			||||||
        if key:
 | 
					        if key:
 | 
				
			||||||
 | 
					            if value.lower() == 'unlimited':
 | 
				
			||||||
 | 
					                value = None
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                db.quota_update(ctxt, project_id, key, value)
 | 
					                db.quota_update(ctxt, project_id, key, value)
 | 
				
			||||||
            except exception.ProjectQuotaNotFound:
 | 
					            except exception.ProjectQuotaNotFound:
 | 
				
			||||||
                db.quota_create(ctxt, project_id, key, value)
 | 
					                db.quota_create(ctxt, project_id, key, value)
 | 
				
			||||||
        project_quota = quota.get_quota(ctxt, project_id)
 | 
					        project_quota = quota.get_project_quotas(ctxt, project_id)
 | 
				
			||||||
        for key, value in project_quota.iteritems():
 | 
					        for key, value in project_quota.iteritems():
 | 
				
			||||||
 | 
					            if value is None:
 | 
				
			||||||
 | 
					                value = 'unlimited'
 | 
				
			||||||
            print '%s: %s' % (key, value)
 | 
					            print '%s: %s' % (key, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def remove(self, project_id, user_id):
 | 
					    def remove(self, project_id, user_id):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								nova/quota.py
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								nova/quota.py
									
									
									
									
									
								
							@@ -28,6 +28,8 @@ flags.DEFINE_integer('quota_instances', 10,
 | 
				
			|||||||
                     'number of instances allowed per project')
 | 
					                     'number of instances allowed per project')
 | 
				
			||||||
flags.DEFINE_integer('quota_cores', 20,
 | 
					flags.DEFINE_integer('quota_cores', 20,
 | 
				
			||||||
                     'number of instance cores allowed per project')
 | 
					                     'number of instance cores allowed per project')
 | 
				
			||||||
 | 
					flags.DEFINE_integer('quota_ram', 50 * 1024,
 | 
				
			||||||
 | 
					                     'megabytes of instance ram allowed per project')
 | 
				
			||||||
flags.DEFINE_integer('quota_volumes', 10,
 | 
					flags.DEFINE_integer('quota_volumes', 10,
 | 
				
			||||||
                     'number of volumes allowed per project')
 | 
					                     'number of volumes allowed per project')
 | 
				
			||||||
flags.DEFINE_integer('quota_gigabytes', 1000,
 | 
					flags.DEFINE_integer('quota_gigabytes', 1000,
 | 
				
			||||||
@@ -44,14 +46,28 @@ flags.DEFINE_integer('quota_max_injected_file_path_bytes', 255,
 | 
				
			|||||||
                     'number of bytes allowed per injected file path')
 | 
					                     'number of bytes allowed per injected file path')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_quota(context, project_id):
 | 
					def _get_default_quotas():
 | 
				
			||||||
    rval = {'instances': FLAGS.quota_instances,
 | 
					    defaults = {
 | 
				
			||||||
 | 
					        'instances': FLAGS.quota_instances,
 | 
				
			||||||
        'cores': FLAGS.quota_cores,
 | 
					        'cores': FLAGS.quota_cores,
 | 
				
			||||||
 | 
					        'ram': FLAGS.quota_ram,
 | 
				
			||||||
        'volumes': FLAGS.quota_volumes,
 | 
					        'volumes': FLAGS.quota_volumes,
 | 
				
			||||||
        'gigabytes': FLAGS.quota_gigabytes,
 | 
					        'gigabytes': FLAGS.quota_gigabytes,
 | 
				
			||||||
        'floating_ips': FLAGS.quota_floating_ips,
 | 
					        'floating_ips': FLAGS.quota_floating_ips,
 | 
				
			||||||
            'metadata_items': FLAGS.quota_metadata_items}
 | 
					        'metadata_items': FLAGS.quota_metadata_items,
 | 
				
			||||||
 | 
					        'injected_files': FLAGS.quota_max_injected_files,
 | 
				
			||||||
 | 
					        'injected_file_content_bytes':
 | 
				
			||||||
 | 
					            FLAGS.quota_max_injected_file_content_bytes,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    # -1 in the quota flags means unlimited
 | 
				
			||||||
 | 
					    for key in defaults.keys():
 | 
				
			||||||
 | 
					        if defaults[key] == -1:
 | 
				
			||||||
 | 
					            defaults[key] = None
 | 
				
			||||||
 | 
					    return defaults
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_project_quotas(context, project_id):
 | 
				
			||||||
 | 
					    rval = _get_default_quotas()
 | 
				
			||||||
    quota = db.quota_get_all_by_project(context, project_id)
 | 
					    quota = db.quota_get_all_by_project(context, project_id)
 | 
				
			||||||
    for key in rval.keys():
 | 
					    for key in rval.keys():
 | 
				
			||||||
        if key in quota:
 | 
					        if key in quota:
 | 
				
			||||||
@@ -65,71 +81,81 @@ def _get_request_allotment(requested, used, quota):
 | 
				
			|||||||
    return quota - used
 | 
					    return quota - used
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_instances(context, num_instances, instance_type):
 | 
					def allowed_instances(context, requested_instances, instance_type):
 | 
				
			||||||
    """Check quota and return min(num_instances, allowed_instances)."""
 | 
					    """Check quota and return min(requested_instances, allowed_instances)."""
 | 
				
			||||||
    project_id = context.project_id
 | 
					    project_id = context.project_id
 | 
				
			||||||
    context = context.elevated()
 | 
					    context = context.elevated()
 | 
				
			||||||
    num_cores = num_instances * instance_type['vcpus']
 | 
					    requested_cores = requested_instances * instance_type['vcpus']
 | 
				
			||||||
    used_instances, used_cores = db.instance_data_get_for_project(context,
 | 
					    requested_ram = requested_instances * instance_type['memory_mb']
 | 
				
			||||||
                                                                  project_id)
 | 
					    usage = db.instance_data_get_for_project(context, project_id)
 | 
				
			||||||
    quota = get_quota(context, project_id)
 | 
					    used_instances, used_cores, used_ram = usage
 | 
				
			||||||
    allowed_instances = _get_request_allotment(num_instances, used_instances,
 | 
					    quota = get_project_quotas(context, project_id)
 | 
				
			||||||
 | 
					    allowed_instances = _get_request_allotment(requested_instances,
 | 
				
			||||||
 | 
					                                               used_instances,
 | 
				
			||||||
                                               quota['instances'])
 | 
					                                               quota['instances'])
 | 
				
			||||||
    allowed_cores = _get_request_allotment(num_cores, used_cores,
 | 
					    allowed_cores = _get_request_allotment(requested_cores, used_cores,
 | 
				
			||||||
                                           quota['cores'])
 | 
					                                           quota['cores'])
 | 
				
			||||||
 | 
					    allowed_ram = _get_request_allotment(requested_ram, used_ram, quota['ram'])
 | 
				
			||||||
    allowed_instances = min(allowed_instances,
 | 
					    allowed_instances = min(allowed_instances,
 | 
				
			||||||
                            int(allowed_cores // instance_type['vcpus']))
 | 
					                            allowed_cores // instance_type['vcpus'],
 | 
				
			||||||
    return min(num_instances, allowed_instances)
 | 
					                            allowed_ram // instance_type['memory_mb'])
 | 
				
			||||||
 | 
					    return min(requested_instances, allowed_instances)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_volumes(context, num_volumes, size):
 | 
					def allowed_volumes(context, requested_volumes, size):
 | 
				
			||||||
    """Check quota and return min(num_volumes, allowed_volumes)."""
 | 
					    """Check quota and return min(requested_volumes, allowed_volumes)."""
 | 
				
			||||||
    project_id = context.project_id
 | 
					    project_id = context.project_id
 | 
				
			||||||
    context = context.elevated()
 | 
					    context = context.elevated()
 | 
				
			||||||
    size = int(size)
 | 
					    size = int(size)
 | 
				
			||||||
    num_gigabytes = num_volumes * size
 | 
					    requested_gigabytes = requested_volumes * size
 | 
				
			||||||
    used_volumes, used_gigabytes = db.volume_data_get_for_project(context,
 | 
					    used_volumes, used_gigabytes = db.volume_data_get_for_project(context,
 | 
				
			||||||
                                                                  project_id)
 | 
					                                                                  project_id)
 | 
				
			||||||
    quota = get_quota(context, project_id)
 | 
					    quota = get_project_quotas(context, project_id)
 | 
				
			||||||
    allowed_volumes = _get_request_allotment(num_volumes, used_volumes,
 | 
					    allowed_volumes = _get_request_allotment(requested_volumes, used_volumes,
 | 
				
			||||||
                                             quota['volumes'])
 | 
					                                             quota['volumes'])
 | 
				
			||||||
    allowed_gigabytes = _get_request_allotment(num_gigabytes, used_gigabytes,
 | 
					    allowed_gigabytes = _get_request_allotment(requested_gigabytes,
 | 
				
			||||||
 | 
					                                               used_gigabytes,
 | 
				
			||||||
                                               quota['gigabytes'])
 | 
					                                               quota['gigabytes'])
 | 
				
			||||||
    allowed_volumes = min(allowed_volumes,
 | 
					    allowed_volumes = min(allowed_volumes,
 | 
				
			||||||
                          int(allowed_gigabytes // size))
 | 
					                          int(allowed_gigabytes // size))
 | 
				
			||||||
    return min(num_volumes, allowed_volumes)
 | 
					    return min(requested_volumes, allowed_volumes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_floating_ips(context, num_floating_ips):
 | 
					def allowed_floating_ips(context, requested_floating_ips):
 | 
				
			||||||
    """Check quota and return min(num_floating_ips, allowed_floating_ips)."""
 | 
					    """Check quota and return min(requested, allowed) floating ips."""
 | 
				
			||||||
    project_id = context.project_id
 | 
					    project_id = context.project_id
 | 
				
			||||||
    context = context.elevated()
 | 
					    context = context.elevated()
 | 
				
			||||||
    used_floating_ips = db.floating_ip_count_by_project(context, project_id)
 | 
					    used_floating_ips = db.floating_ip_count_by_project(context, project_id)
 | 
				
			||||||
    quota = get_quota(context, project_id)
 | 
					    quota = get_project_quotas(context, project_id)
 | 
				
			||||||
    allowed_floating_ips = _get_request_allotment(num_floating_ips,
 | 
					    allowed_floating_ips = _get_request_allotment(requested_floating_ips,
 | 
				
			||||||
                                                  used_floating_ips,
 | 
					                                                  used_floating_ips,
 | 
				
			||||||
                                                  quota['floating_ips'])
 | 
					                                                  quota['floating_ips'])
 | 
				
			||||||
    return min(num_floating_ips, allowed_floating_ips)
 | 
					    return min(requested_floating_ips, allowed_floating_ips)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_metadata_items(context, num_metadata_items):
 | 
					def _calculate_simple_quota(context, resource, requested):
 | 
				
			||||||
    """Check quota; return min(num_metadata_items,allowed_metadata_items)."""
 | 
					    """Check quota for resource; return min(requested, allowed)."""
 | 
				
			||||||
    project_id = context.project_id
 | 
					    quota = get_project_quotas(context, context.project_id)
 | 
				
			||||||
    context = context.elevated()
 | 
					    allowed = _get_request_allotment(requested, 0, quota[resource])
 | 
				
			||||||
    quota = get_quota(context, project_id)
 | 
					    return min(requested, allowed)
 | 
				
			||||||
    allowed_metadata_items = _get_request_allotment(num_metadata_items, 0,
 | 
					 | 
				
			||||||
                                                    quota['metadata_items'])
 | 
					 | 
				
			||||||
    return min(num_metadata_items, allowed_metadata_items)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_injected_files(context):
 | 
					def allowed_metadata_items(context, requested_metadata_items):
 | 
				
			||||||
 | 
					    """Return the number of metadata items allowed."""
 | 
				
			||||||
 | 
					    return _calculate_simple_quota(context, 'metadata_items',
 | 
				
			||||||
 | 
					                                   requested_metadata_items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def allowed_injected_files(context, requested_injected_files):
 | 
				
			||||||
    """Return the number of injected files allowed."""
 | 
					    """Return the number of injected files allowed."""
 | 
				
			||||||
    return FLAGS.quota_max_injected_files
 | 
					    return _calculate_simple_quota(context, 'injected_files',
 | 
				
			||||||
 | 
					                                   requested_injected_files)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_injected_file_content_bytes(context):
 | 
					def allowed_injected_file_content_bytes(context, requested_bytes):
 | 
				
			||||||
    """Return the number of bytes allowed per injected file content."""
 | 
					    """Return the number of bytes allowed per injected file content."""
 | 
				
			||||||
    return FLAGS.quota_max_injected_file_content_bytes
 | 
					    resource = 'injected_file_content_bytes'
 | 
				
			||||||
 | 
					    return _calculate_simple_quota(context, resource, requested_bytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def allowed_injected_file_path_bytes(context):
 | 
					def allowed_injected_file_path_bytes(context):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user