'Update our capacity in the self.my_cell_state CellState.
This will add/update 2 entries in our CellState.capacities,
\'ram_free\' and \'disk_free\'.
The values of these are both dictionaries with the following
format:
{\'total_mb\': <total_memory_free_in_the_cell>,
\'units_by_mb: <units_dictionary>}
<units_dictionary> contains the number of units that we can build for
every distinct memory or disk requirement that we have based on
instance types.  This number is computed by looking at room available
on every compute_node.
Take the following instance_types as an example:
[{\'memory_mb\': 1024, \'root_gb\': 10, \'ephemeral_gb\': 100},
{\'memory_mb\': 2048, \'root_gb\': 20, \'ephemeral_gb\': 200}]
capacities[\'ram_free\'][\'units_by_mb\'] would contain the following:
{\'1024\': <number_of_instances_that_will_fit>,
\'2048\': <number_of_instances_that_will_fit>}
capacities[\'disk_free\'][\'units_by_mb\'] would contain the following:
{\'122880\': <number_of_instances_that_will_fit>,
\'225280\': <number_of_instances_that_will_fit>}
Units are in MB, so 122880 = (10 + 100) * 1024.
NOTE(comstud): Perhaps we should only report a single number
available per instance_type.'

def _update_our_capacity(self, ctxt=None):

    if (not ctxt):
        ctxt = context.get_admin_context()
    reserve_level = (CONF.cells.reserve_percent / 100.0)
    def _defaultdict_int():
        return collections.defaultdict(int)
    compute_hosts = collections.defaultdict(_defaultdict_int)
    def _get_compute_hosts():
        service_refs = {service.host: service for service in objects.ServiceList.get_by_binary(ctxt, 'nova-compute')}
        compute_nodes = objects.ComputeNodeList.get_all(ctxt)
        for compute in compute_nodes:
            host = compute.host
            service = service_refs.get(host)
            if ((not service) or service['disabled']):
                continue
            alive = self.servicegroup_api.service_is_up(service)
            if (not alive):
                continue
            chost = compute_hosts[host]
            chost['free_ram_mb'] += max(0, compute.free_ram_mb)
            chost['free_disk_mb'] += (max(0, compute.free_disk_gb) * 1024)
            chost['total_ram_mb'] += max(0, compute.memory_mb)
            chost['total_disk_mb'] += (max(0, compute.local_gb) * 1024)
    _get_compute_hosts()
    if (not compute_hosts):
        self.my_cell_state.update_capacities({})
        return
    ram_mb_free_units = {}
    disk_mb_free_units = {}
    total_ram_mb_free = 0
    total_disk_mb_free = 0
    def _free_units(total, free, per_inst):
        if per_inst:
            min_free = (total * reserve_level)
            free = max(0, (free - min_free))
            return int((free / per_inst))
        else:
            return 0
    flavors = objects.FlavorList.get_all(ctxt)
    memory_mb_slots = frozenset([flavor.memory_mb for flavor in flavors])
    disk_mb_slots = frozenset([((flavor.root_gb + flavor.ephemeral_gb) * units.Ki) for flavor in flavors])
    for compute_values in compute_hosts.values():
        total_ram_mb_free += compute_values['free_ram_mb']
        total_disk_mb_free += compute_values['free_disk_mb']
        for memory_mb_slot in memory_mb_slots:
            ram_mb_free_units.setdefault(str(memory_mb_slot), 0)
            free_units = _free_units(compute_values['total_ram_mb'], compute_values['free_ram_mb'], memory_mb_slot)
            ram_mb_free_units[str(memory_mb_slot)] += free_units
        for disk_mb_slot in disk_mb_slots:
            disk_mb_free_units.setdefault(str(disk_mb_slot), 0)
            free_units = _free_units(compute_values['total_disk_mb'], compute_values['free_disk_mb'], disk_mb_slot)
            disk_mb_free_units[str(disk_mb_slot)] += free_units
    capacities = {'ram_free': {'total_mb': total_ram_mb_free, 'units_by_mb': ram_mb_free_units}, 'disk_free': {'total_mb': total_disk_mb_free, 'units_by_mb': disk_mb_free_units}}
    self.my_cell_state.update_capacities(capacities)
