예제 #1
0
    def on_end(self, resource_id):
        """Remove the hosts from the pool."""
        reservations = db_api.reservation_get_all_by_values(
            resource_id=resource_id)
        for reservation in reservations:
            if reservation['status'] not in ['completed', 'deleted']:
                allocations = db_api.host_allocation_get_all_by_values(
                    reservation_id=reservation['id'])
                pool = rp.ReservationPool()
                for allocation in allocations:
                    db_api.host_allocation_destroy(allocation['id'])
                    hyp = self.nova.hypervisors.get(
                            self._get_hypervisor_from_name_or_id(
                            allocation['compute_host_id'])
                    )
                    if hyp.__dict__['running_vms'] > 0:
                        hyp = self.nova.hypervisors.search(hyp.__dict__['hypervisor_hostname'], servers=True)
                        for server in hyp[0].__dict__['servers']:
                            s = self.nova.servers.get(server['uuid'])
                            s.delete()
                pool.delete(reservation['resource_id'])

            db_api.reservation_update(reservation['id'],
                                      {'status': 'completed'})
            host_reservation = db_api.host_reservation_get_by_reservation_id(
                reservation['id'])
            db_api.host_reservation_update(host_reservation['id'],
                                           {'status': 'completed'})
예제 #2
0
    def setUp(self):
        super(ReservationPoolTestCase, self).setUp()
        self.pool_name = 'pool-name-xxx'
        self.project_id = 'project-uuid'
        self.fake_aggregate = AggregateFake(i=123,
                                            name='fooname',
                                            hosts=['host1', 'host2'])
        conf = cfg.CONF[host_plugin.RESOURCE_TYPE]
        self.freepool_name = conf.aggregate_freepool_name
        self.project_id_key = conf.project_id_key
        self.climate_owner = conf.climate_owner
        self.climate_az_prefix = conf.climate_az_prefix

        self.fake_freepool = AggregateFake(i=456,
                                           name=self.freepool_name,
                                           hosts=['host3'])

        self.set_context(context.ClimateContext(project_id=self.project_id))

        self.nova_client = nova_client
        self.nova = self.patch(self.nova_client, 'Client').return_value

        self.patch(self.nova.aggregates, 'set_metadata')
        self.patch(self.nova.aggregates, 'remove_host')

        self.patch(base, 'url_for').return_value = 'http://foo.bar'
        self.pool = rp.ReservationPool()

        self.p_name = self.patch(self.pool, '_generate_aggregate_name')
        self.p_name.return_value = self.pool_name
예제 #3
0
    def delete_computehost(self, host_id):
        host = db_api.host_get(host_id)
        if not host:
            raise manager_ex.HostNotFound(host=host_id)

        with trusts.create_ctx_from_trust(host['trust_id']):
            # TODO(sbauza):
            #  - Check if no leases having this host scheduled
            inventory = nova_inventory.NovaInventory()
            servers = inventory.get_servers_per_host(
                host['hypervisor_hostname'])
            if servers:
                raise manager_ex.HostHavingServers(
                    host=host['hypervisor_hostname'], servers=servers)

            try:
                pool = rp.ReservationPool()
                pool.remove_computehost(self.freepool_name,
                                        host['service_name'])
                # NOTE(sbauza): Extracapabilities will be destroyed thanks to
                #  the DB FK.
                db_api.host_destroy(host_id)
            except db_ex.ClimateDBException:
                # Nothing so bad, but we need to advert the admin
                # he has to rerun
                raise manager_ex.CantRemoveHost(host=host_id,
                                                pool=self.freepool_name)
예제 #4
0
 def on_start(self, resource_id):
     """Add the hosts in the pool."""
     reservations = db_api.reservation_get_all_by_values(
         resource_id=resource_id)
     for reservation in reservations:
         pool = rp.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'])
             pool.add_computehost(reservation['resource_id'],
                                  host['service_name'])
예제 #5
0
 def create_reservation(self, values):
     """Create reservation."""
     pool = rp.ReservationPool()
     pool_name = str(uuid.uuid4())
     pool_instance = pool.create(name=pool_name)
     reservation_values = {
         'id': pool_name,
         'lease_id': values['lease_id'],
         'resource_id': pool_instance.id,
         'resource_type': values['resource_type'],
         'status': 'pending',
     }
     reservation = db_api.reservation_create(reservation_values)
     min_host = values['min']
     max_host = values['max']
     if not min_host:
         raise manager_ex.MissingParameter(param="min")
     if not max_host:
         raise manager_ex.MissingParameter(param="max")
     try:
         min_host = int(str(min_host))
     except ValueError:
         raise manager_ex.MalformedParameter(param="min")
     try:
         max_host = int(str(max_host))
     except ValueError:
         raise manager_ex.MalformedParameter(param="max")
     count_range = str(values['min']) + '-' + str(values['max'])
     host_values = {
         'reservation_id': reservation['id'],
         'resource_properties': values['resource_properties'],
         'hypervisor_properties': values['hypervisor_properties'],
         'count_range': count_range,
         'status': 'pending',
     }
     db_api.host_reservation_create(host_values)
     host_ids = self._matching_hosts(
         values['hypervisor_properties'],
         values['resource_properties'],
         count_range,
         values['start_date'],
         values['end_date'],
     )
     if not host_ids:
         pool.delete(pool_name)
         raise manager_ex.NotEnoughHostsAvailable()
     for host_id in host_ids:
         db_api.host_allocation_create({'compute_host_id': host_id,
                                       'reservation_id': reservation['id']})
예제 #6
0
 def on_end(self, resource_id):
     """Remove the hosts from the pool."""
     reservations = db_api.reservation_get_all_by_values(
         resource_id=resource_id)
     for reservation in reservations:
         db_api.reservation_update(reservation['id'],
                                   {'status': 'completed'})
         host_reservation = db_api.host_reservation_get_by_reservation_id(
             reservation['id'])
         db_api.host_reservation_update(host_reservation['id'],
                                        {'status': 'completed'})
         allocations = db_api.host_allocation_get_all_by_values(
             reservation_id=reservation['id'])
         pool = rp.ReservationPool()
         for allocation in allocations:
             db_api.host_allocation_destroy(allocation['id'])
             if self.nova.hypervisors.get(
                     self._get_hypervisor_from_name_or_id(
                         allocation['compute_host_id'])
             ).__dict__['running_vms'] == 0:
                 pool.delete(reservation['resource_id'])
예제 #7
0
 def create_reservation(self, values):
     """Create reservation."""
     pool = rp.ReservationPool()
     pool_name = str(uuid.uuid4())
     pool_instance = pool.create(name=pool_name)
     reservation_values = {
         'id': pool_name,
         'lease_id': values['lease_id'],
         'resource_id': pool_instance.id,
         'resource_type': values['resource_type'],
         'status': 'pending',
     }
     reservation = db_api.reservation_create(reservation_values)
     count_range = str(values['min']) + '-' + str(values['max'])
     host_values = {
         'reservation_id': reservation['id'],
         'resource_properties': values['resource_properties'],
         'hypervisor_properties': values['hypervisor_properties'],
         'count_range': count_range,
         'status': 'pending',
     }
     db_api.host_reservation_create(host_values)
     host_ids = self._matching_hosts(
         values['hypervisor_properties'],
         values['resource_properties'],
         count_range,
         values['start_date'],
         values['end_date'],
     )
     if not host_ids:
         raise manager_ex.NotEnoughHostsAvailable()
     for host_id in host_ids:
         db_api.host_allocation_create({
             'compute_host_id': host_id,
             'reservation_id': reservation['id']
         })
예제 #8
0
    def create_computehost(self, host_values):
        # TODO(sbauza):
        #  - Exception handling for HostNotFound
        host_id = host_values.pop('id', None)
        host_name = host_values.pop('name', None)
        try:
            trust_id = host_values.pop('trust_id')
        except KeyError:
            raise manager_ex.MissingTrustId()

        host_ref = host_id or host_name
        if host_ref is None:
            raise manager_ex.InvalidHost(host=host_values)

        with trusts.create_ctx_from_trust(trust_id):
            inventory = nova_inventory.NovaInventory()
            servers = inventory.get_servers_per_host(host_ref)
            if servers:
                raise manager_ex.HostHavingServers(host=host_ref,
                                                   servers=servers)
            host_details = inventory.get_host_details(host_ref)
            # NOTE(sbauza): Only last duplicate name for same extra capability
            # will be stored
            to_store = set(host_values.keys()) - set(host_details.keys())
            extra_capabilities_keys = to_store
            extra_capabilities = dict(
                (key, host_values[key]) for key in extra_capabilities_keys
            )
            pool = rp.ReservationPool()
            pool.add_computehost(self.freepool_name,
                                 host_details['service_name'])

            host = None
            cantaddextracapability = []
            try:
                if trust_id:
                    host_details.update({'trust_id': trust_id})
                host = db_api.host_create(host_details)
            except db_ex.ClimateDBException:
                # We need to rollback
                # TODO(sbauza): Investigate use of Taskflow for atomic
                # transactions
                pool.remove_computehost(self.freepool_name,
                                        host_details['service_name'])
            if host:
                for key in extra_capabilities:
                    values = {'computehost_id': host['id'],
                              'capability_name': key,
                              'capability_value': extra_capabilities[key],
                              }
                    try:
                        db_api.host_extra_capability_create(values)
                    except db_ex.ClimateDBException:
                        cantaddextracapability.append(key)
            if cantaddextracapability:
                raise manager_ex.CantAddExtraCapability(
                    keys=cantaddextracapability,
                    host=host['id'])
            if host:
                return self.get_computehost(host['id'])
            else:
                return None
예제 #9
0
 def update_reservation(self, reservation_id, values):
     """Update reservation."""
     reservation = db_api.reservation_get(reservation_id)
     lease = db_api.lease_get(reservation['lease_id'])
     pool = rp.ReservationPool()
     hosts_in_pool = pool.get_computehosts(
         reservation['resource_id'])
     if (values['start_date'] < lease['start_date'] or
             values['end_date'] > lease['end_date']):
         allocations = []
         for allocation in db_api.host_allocation_get_all_by_values(
                 reservation_id=reservation_id):
             full_periods = db_utils.get_full_periods(
                 allocation['compute_host_id'],
                 values['start_date'],
                 values['end_date'],
                 datetime.timedelta(seconds=1))
             if lease['start_date'] < values['start_date']:
                 max_start = values['start_date']
             else:
                 max_start = lease['start_date']
             if lease['end_date'] < values['end_date']:
                 min_end = lease['end_date']
             else:
                 min_end = values['end_date']
             if not (len(full_periods) == 0 or
                     (len(full_periods) == 1 and
                      full_periods[0][0] == max_start and
                      full_periods[0][1] == min_end)):
                 allocations.append(allocation)
                 if (hosts_in_pool and
                         self.nova.hypervisors.get(
                             self._get_hypervisor_from_name_or_id(
                                 allocation['compute_host_id'])
                         ).__dict__['running_vms'] > 0):
                     raise manager_ex.NotEnoughHostsAvailable()
         if allocations:
             host_reservation = (
                 db_api.host_reservation_get_by_reservation_id(
                     reservation_id))
             host_ids = self._matching_hosts(
                 host_reservation['hypervisor_properties'],
                 host_reservation['resource_properties'],
                 str(len(allocations)) + '-' + str(len(allocations)),
                 values['start_date'],
                 values['end_date'])
             if not host_ids:
                 raise manager_ex.NotEnoughHostsAvailable()
             if hosts_in_pool:
                 old_hosts = [allocation['compute_host_id']
                              for allocation in allocations]
                 pool.remove_computehost(reservation['resource_id'],
                                         old_hosts)
             for allocation in allocations:
                 db_api.host_allocation_destroy(allocation['id'])
             for host_id in host_ids:
                 db_api.host_allocation_create(
                     {'compute_host_id': host_id,
                      'reservation_id': reservation_id})
                 if hosts_in_pool:
                     host = db_api.host_get(host_id)
                     pool.add_computehost(reservation['resource_id'],
                                          host['service_name'])