def reserve_resource(self, reservation_id, values):
        self.validate_reservation_param(values)

        hosts = self.pickup_hosts(reservation_id, values)

        instance_reservation_val = {
            'reservation_id': reservation_id,
            'vcpus': values['vcpus'],
            'memory_mb': values['memory_mb'],
            'disk_gb': values['disk_gb'],
            'amount': values['amount'],
            'affinity': bool_from_string(values['affinity'], default=None),
            'resource_properties': values['resource_properties']
            }
        instance_reservation = db_api.instance_reservation_create(
            instance_reservation_val)

        for host_id in hosts['added']:
            db_api.host_allocation_create({'compute_host_id': host_id,
                                          'reservation_id': reservation_id})

        try:
            flavor, group, pool = self._create_resources(instance_reservation)
        except nova_exceptions.ClientException:
            LOG.exception("Failed to create Nova resources "
                          "for reservation %s", reservation_id)
            self.cleanup_resources(instance_reservation)
            raise mgr_exceptions.NovaClientError()

        db_api.instance_reservation_update(instance_reservation['id'],
                                           {'flavor_id': flavor.id,
                                            'server_group_id': group.id,
                                            'aggregate_id': pool.id})

        return instance_reservation['id']
Esempio n. 2
0
    def update_resources(self, reservation_id):
        """Updates reserved resources in Nova.

        This method updates reserved resources in Compute service. If the
        reservation is in active status, it adds new allocated hosts into
        a reserved aggregate. If the reservation is not started yet, it
        updates a reserved flavor.
        """
        reservation = db_api.reservation_get(reservation_id)

        if reservation['status'] == 'active':
            pool = nova.ReservationPool()

            # Dict of number of instances to reserve on a host keyed by the
            # host id
            allocation_map = collections.defaultdict(lambda: 0)
            for allocation in db_api.host_allocation_get_all_by_values(
                    reservation_id=reservation['id']):
                host_id = allocation['compute_host_id']
                allocation_map[host_id] += 1

            for host_id, num in allocation_map.items():
                host = db_api.host_get(host_id)
                try:
                    pool.add_computehost(reservation['aggregate_id'],
                                         host['service_name'],
                                         stay_in=True)
                except mgr_exceptions.AggregateAlreadyHasHost:
                    pass
                except nova_exceptions.ClientException:
                    err_msg = ('Fail to add host %s to aggregate %s.' %
                               (host, reservation['aggregate_id']))
                    raise mgr_exceptions.NovaClientError(err_msg)
                self.placement_client.update_reservation_inventory(
                    host['hypervisor_hostname'], reservation['id'], num)
        else:
            try:
                self.nova.nova.flavors.delete(reservation['id'])
                self._create_flavor(reservation['id'], reservation['vcpus'],
                                    reservation['memory_mb'],
                                    reservation['disk_gb'],
                                    reservation['server_group_id'])
            except nova_exceptions.ClientException:
                LOG.exception(
                    "Failed to update Nova resources "
                    "for reservation %s", reservation['id'])
                raise mgr_exceptions.NovaClientError()
Esempio n. 3
0
    def reserve_resource(self, reservation_id, values):
        self.validate_reservation_param(values)

        # TODO(masahito) the instance reservation plugin only supports
        # anti-affinity rule in short-term goal.
        if bool_from_string(values['affinity']):
            raise exceptions.BlazarException('affinity = True is not '
                                             'supported.')

        hosts = self.pickup_hosts(reservation_id, values)

        if len(hosts['added']) < values['amount']:
            raise mgr_exceptions.HostNotFound("The reservation can't be "
                                              "accommodate because of less "
                                              "capacity.")

        instance_reservation_val = {
            'reservation_id': reservation_id,
            'vcpus': values['vcpus'],
            'memory_mb': values['memory_mb'],
            'disk_gb': values['disk_gb'],
            'amount': values['amount'],
            'affinity': bool_from_string(values['affinity']),
        }
        instance_reservation = db_api.instance_reservation_create(
            instance_reservation_val)

        for host_id in hosts['added']:
            db_api.host_allocation_create({
                'compute_host_id': host_id,
                'reservation_id': reservation_id
            })

        try:
            flavor, group, pool = self._create_resources(instance_reservation)
        except nova_exceptions.ClientException:
            LOG.exception(
                "Failed to create Nova resources "
                "for reservation %s", reservation_id)
            self.cleanup_resources(instance_reservation)
            raise mgr_exceptions.NovaClientError()

        db_api.instance_reservation_update(
            instance_reservation['id'], {
                'flavor_id': flavor.id,
                'server_group_id': group.id,
                'aggregate_id': pool.id
            })

        return instance_reservation['id']
Esempio n. 4
0
    def update_resources(self, reservation_id):
        """Updates reserved resources in Nova.

        This method updates reserved resources in Compute service. If the
        reservation is in active status, it adds new allocated hosts into
        a reserved aggregate. If the reservation is not started yet, it
        updates a reserved flavor.
        """
        reservation = db_api.reservation_get(reservation_id)

        if reservation['status'] == 'active':
            pool = nova.ReservationPool()
            for allocation in db_api.host_allocation_get_all_by_values(
                    reservation_id=reservation['id']):
                host = db_api.host_get(allocation['compute_host_id'])
                try:
                    pool.add_computehost(reservation['aggregate_id'],
                                         host['service_name'],
                                         stay_in=True)
                except mgr_exceptions.AggregateAlreadyHasHost:
                    pass
                except nova_exceptions.ClientException:
                    err_msg = ('Fail to add host %s to aggregate %s.' %
                               (host, reservation['aggregate_id']))
                    raise mgr_exceptions.NovaClientError(err_msg)
        else:
            try:
                self.nova.nova.flavors.delete(reservation['id'])
                self._create_flavor(reservation['id'], reservation['vcpus'],
                                    reservation['memory_mb'],
                                    reservation['disk_gb'],
                                    reservation['server_group_id'])
            except nova_exceptions.ClientException:
                LOG.exception(
                    "Failed to update Nova resources "
                    "for reservation %s", reservation['id'])
                raise mgr_exceptions.NovaClientError()