def on_end(self, resource_id): """Remove the hosts from the pool.""" host_reservation = db_api.host_reservation_get(resource_id) db_api.host_reservation_update(host_reservation['id'], {'status': 'completed'}) allocations = db_api.host_allocation_get_all_by_values( reservation_id=host_reservation['reservation_id']) for allocation in allocations: db_api.host_allocation_destroy(allocation['id']) pool = nova.ReservationPool() for host in pool.get_computehosts(host_reservation['aggregate_id']): for server in self.nova.servers.list(search_opts={ "host": host, "all_tenants": 1 }): try: self.nova.servers.delete(server=server) except nova_exceptions.NotFound: LOG.info( 'Could not find server %s, may have been deleted ' 'concurrently.', server) except Exception as e: LOG.exception('Failed to delete %s: %s.', server, str(e)) try: pool.delete(host_reservation['aggregate_id']) except manager_ex.AggregateNotFound: pass
def on_start(self, resource_id): """Add the hosts in the pool.""" host_reservation = db_api.host_reservation_get(resource_id) pool = nova.ReservationPool() hosts = [] for allocation in db_api.host_allocation_get_all_by_values( reservation_id=host_reservation['reservation_id']): host = db_api.host_get(allocation['compute_host_id']) hosts.append(host['service_name']) pool.add_computehost(host_reservation['aggregate_id'], hosts) for host in hosts: for server in self.nova.servers.list(search_opts={ "host": host, "all_tenants": 1 }): try: LOG.info('Terminating preemptible instance %s (%s)', server.name, server.id) self.nova.servers.delete(server=server) except nova_exceptions.NotFound: LOG.info( 'Could not find server %s, may have been deleted ' 'concurrently.', server) except Exception as e: LOG.exception('Failed to delete %s: %s.', server, str(e))
def on_start(self, resource_id): """Add the hosts in the pool.""" host_reservation = db_api.host_reservation_get(resource_id) pool = nova.ReservationPool() for allocation in db_api.host_allocation_get_all_by_values( reservation_id=host_reservation['reservation_id']): host = db_api.host_get(allocation['compute_host_id']) pool.add_computehost(host_reservation['aggregate_id'], host['service_name'])
def before_end(self, resource_id): """Take an action before the end of a lease.""" host_reservation = db_api.host_reservation_get(resource_id) action = host_reservation['before_end'] if action == 'default': action = CONF[plugin.RESOURCE_TYPE].before_end if action == 'snapshot': pool = nova.ReservationPool() client = nova.BlazarNovaClient() for host in pool.get_computehosts( host_reservation['aggregate_id']): for server in client.servers.list( search_opts={"host": host, "all_tenants": 1}): client.servers.create_image(server=server)
def _reallocate(self, allocation): """Allocate an alternative host. :param: allocation: allocation to change. :return: True if an alternative host was successfully allocated. """ reservation = db_api.reservation_get(allocation['reservation_id']) h_reservation = db_api.host_reservation_get( reservation['resource_id']) lease = db_api.lease_get(reservation['lease_id']) pool = nova.ReservationPool() # Remove the old host from the aggregate. if reservation['status'] == status.reservation.ACTIVE: host = db_api.host_get(allocation['compute_host_id']) pool.remove_computehost(h_reservation['aggregate_id'], host['service_name']) # Allocate an alternative host. start_date = max(datetime.datetime.utcnow(), lease['start_date']) new_hostids = self._matching_hosts( reservation['hypervisor_properties'], reservation['resource_properties'], '1-1', start_date, lease['end_date'] ) if not new_hostids: db_api.host_allocation_destroy(allocation['id']) LOG.warn('Could not find alternative host for reservation %s ' '(lease: %s).', reservation['id'], lease['name']) return False else: new_hostid = new_hostids.pop() db_api.host_allocation_update(allocation['id'], {'compute_host_id': new_hostid}) LOG.warn('Resource changed for reservation %s (lease: %s).', reservation['id'], lease['name']) if reservation['status'] == status.reservation.ACTIVE: # Add the alternative host into the aggregate. new_host = db_api.host_get(new_hostid) pool.add_computehost(h_reservation['aggregate_id'], new_host['service_name']) return True
def update_reservation(self, reservation_id, values): """Update reservation.""" reservation = db_api.reservation_get(reservation_id) lease = db_api.lease_get(reservation['lease_id']) if (not [ x for x in values.keys() if x in ['min', 'max', 'hypervisor_properties', 'resource_properties'] ] and values['start_date'] >= lease['start_date'] and values['end_date'] <= lease['end_date']): # Nothing to update return dates_before = { 'start_date': lease['start_date'], 'end_date': lease['end_date'] } dates_after = { 'start_date': values['start_date'], 'end_date': values['end_date'] } host_reservation = db_api.host_reservation_get( reservation['resource_id']) self._update_allocations(dates_before, dates_after, reservation_id, reservation['status'], host_reservation, values) updates = {} if 'min' in values or 'max' in values: count_range = str( values.get('min', host_reservation['count_range'].split( '-')[0])) + '-' + str( values.get( 'max', host_reservation['count_range'].split('-')[1])) updates['count_range'] = count_range if 'hypervisor_properties' in values: updates['hypervisor_properties'] = values.get( 'hypervisor_properties') if 'resource_properties' in values: updates['resource_properties'] = values.get('resource_properties') if updates: db_api.host_reservation_update(host_reservation['id'], updates)
def on_end(self, resource_id): """Remove the hosts from the pool.""" host_reservation = db_api.host_reservation_get(resource_id) db_api.host_reservation_update(host_reservation['id'], {'status': 'completed'}) allocations = db_api.host_allocation_get_all_by_values( reservation_id=host_reservation['reservation_id']) for allocation in allocations: db_api.host_allocation_destroy(allocation['id']) pool = nova.ReservationPool() for host in pool.get_computehosts(host_reservation['aggregate_id']): for server in self.nova.servers.list(search_opts={ "host": host, "all_tenants": 1 }): self.nova.servers.delete(server=server) try: pool.delete(host_reservation['aggregate_id']) except manager_ex.AggregateNotFound: pass
def heal_reservations(self, failed_resources): """Heal reservations which suffer from resource failures. :param: failed_resources: a list of failed hosts. :return: a dictionary of {reservation id: flags to update} e.g. {'de27786d-bd96-46bb-8363-19c13b2c6657': {'missing_resources': True}} """ reservation_flags = {} failed_allocs = [] for host in failed_resources: failed_allocs += db_api.host_allocation_get_all_by_values( compute_host_id=host['id']) for alloc in failed_allocs: reservation = db_api.reservation_get(alloc['reservation_id']) if reservation['resource_type'] != plugin.RESOURCE_TYPE: continue lease = db_api.lease_get(reservation['lease_id']) host_reservation = None pool = None # Remove the failed host from the aggregate. if reservation['status'] == status.reservation.ACTIVE: host = db_api.host_get(alloc['compute_host_id']) host_reservation = db_api.host_reservation_get( reservation['resource_id']) with trusts.create_ctx_from_trust(lease['trust_id']): pool = nova.ReservationPool() pool.remove_computehost(host_reservation['aggregate_id'], host['service_name']) # Allocate alternative resource. start_date = max(datetime.datetime.utcnow(), lease['start_date']) new_hostids = self._matching_hosts( reservation['hypervisor_properties'], reservation['resource_properties'], '1-1', start_date, lease['end_date']) if not new_hostids: if reservation['id'] not in reservation_flags: reservation_flags[reservation['id']] = {} reservation_flags[reservation['id']].update( {'missing_resources': True}) db_api.host_allocation_destroy(alloc['id']) LOG.warn( 'Could not find alternative host for reservation %s ' '(lease: %s).', reservation['id'], lease['name']) else: new_hostid = new_hostids.pop() db_api.host_allocation_update(alloc['id'], {'compute_host_id': new_hostid}) if reservation['status'] == status.reservation.ACTIVE: # Add the alternative host into the aggregate. new_host = db_api.host_get(new_hostid) with trusts.create_ctx_from_trust(lease['trust_id']): pool.add_computehost(host_reservation['aggregate_id'], new_host['service_name']) if reservation['id'] not in reservation_flags: reservation_flags[reservation['id']] = {} reservation_flags[reservation['id']].update( {'resources_changed': True}) LOG.warn('Resource changed for reservation %s (lease: %s).', reservation['id'], lease['name']) return reservation_flags