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 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. 3
0
    def update_reservation(self, reservation_id, new_values):
        """Updates an instance reservation with requested parameters.

        This method allows users to update an instance reservation under the
        following conditions.
        - If an instance reservation has not started yet
             - vcpus, memory_mb disk_gb and amount can be updateable unless
               Blazar can accommodate the new request.
        - If an instance reservation has already started
             - only amount is increasable.
        """
        self._validate_reservation_params(new_values)

        reservation = db_api.reservation_get(reservation_id)
        lease = db_api.lease_get(reservation['lease_id'])

        updatable = [
            'vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount',
            'resource_properties'
        ]
        if (not any([k in updatable for k in new_values.keys()])
                and new_values['start_date'] >= lease['start_date']
                and new_values['end_date'] <= lease['end_date']):
            # no update because of just shortening the reservation time
            return

        if (reservation['status'] == 'active'
                and any([k in updatable[:-1] for k in new_values.keys()])):
            msg = "An active reservation only accepts to update amount."
            raise mgr_exceptions.InvalidStateUpdate(msg)

        if reservation['status'] == 'error':
            msg = "An error reservation doesn't accept an updating request."
            raise mgr_exceptions.InvalidStateUpdate(msg)

        if new_values.get('affinity', None):
            new_values['affinity'] = bool_from_string(new_values['affinity'],
                                                      default=None)

        for key in updatable:
            if key not in new_values:
                new_values[key] = reservation[key]

        changed_hosts = self.pickup_hosts(reservation_id, new_values)

        if (reservation['status'] == 'active'
                and len(changed_hosts['removed']) > 0):
            err_msg = ("Instance reservation doesn't allow to reduce/replace "
                       "reserved instance slots when the reservation is in "
                       "active status.")
            raise mgr_exceptions.CantUpdateParameter(err_msg)

        db_api.instance_reservation_update(
            reservation['resource_id'],
            {key: new_values[key]
             for key in updatable})

        self.update_host_allocations(changed_hosts['added'],
                                     changed_hosts['removed'], reservation_id)

        try:
            self.update_resources(reservation_id)
        except mgr_exceptions.NovaClientError:
            raise