Ejemplo n.º 1
0
    def remove_from_aggregate(self, context, aggregate, host, slave_info=None):
        """Remove a compute host from an aggregate."""
        slave_info = slave_info or dict()
        if not self._is_hv_pool(context, aggregate.id):
            return

        invalid = {
            pool_states.CREATED: 'no hosts to remove',
            pool_states.CHANGING: 'setup in progress',
            pool_states.DISMISSED: 'aggregate deleted',
        }
        if (self._get_metadata(context, aggregate.id)[pool_states.KEY]
                in invalid.keys()):
            raise exception.InvalidAggregateAction(
                action='remove host',
                aggregate_id=aggregate.id,
                reason=invalid[self._get_metadata(
                    context, aggregate.id)[pool_states.KEY]])

        master_compute = self._get_metadata(context,
                                            aggregate.id)['master_compute']
        if master_compute == CONF.host and master_compute != host:
            # this is the master -> instruct it to eject a host from the pool
            host_uuid = self._get_metadata(context, aggregate.id)[host]
            self._eject_slave(aggregate.id, slave_info.get('compute_uuid'),
                              host_uuid)
            self._virtapi.aggregate_metadata_delete(context, aggregate.id,
                                                    host)
        elif master_compute == host:
            # Remove master from its own pool -> destroy pool only if the
            # master is on its own, otherwise raise fault. Destroying a
            # pool made only by master is fictional
            if len(aggregate.hosts) > 1:
                # NOTE: this could be avoided by doing a master
                # re-election, but this is simpler for now.
                raise exception.InvalidAggregateAction(
                    aggregate_id=aggregate.id,
                    action='remove_from_aggregate',
                    reason=_('Unable to eject %(host)s '
                             'from the pool; pool not empty') % locals())
            self._clear_pool(aggregate.id)
            for key in ['master_compute', host]:
                self._virtapi.aggregate_metadata_delete(
                    context, aggregate.id, key)
        elif master_compute and master_compute != host:
            # A master exists -> forward pool-eject request to master
            slave_info = self._create_slave_info()

            self.compute_rpcapi.remove_aggregate_host(context, aggregate.id,
                                                      host, master_compute,
                                                      slave_info)
        else:
            # this shouldn't have happened
            raise exception.AggregateError(
                aggregate_id=aggregate.id,
                action='remove_from_aggregate',
                reason=_('Unable to eject %(host)s '
                         'from the pool; No master found') % locals())
Ejemplo n.º 2
0
    def remove_from_aggregate(self,
                              context,
                              aggregate,
                              host,
                              subordinate_info=None):
        """Remove a compute host from an aggregate."""
        subordinate_info = subordinate_info or dict()
        if not pool_states.is_hv_pool(aggregate['metadata']):
            return

        invalid = {
            pool_states.CREATED: 'no hosts to remove',
            pool_states.CHANGING: 'setup in progress',
            pool_states.DISMISSED: 'aggregate deleted',
        }
        if aggregate['metadata'][pool_states.KEY] in invalid.keys():
            raise exception.InvalidAggregateAction(
                action='remove host',
                aggregate_id=aggregate['id'],
                reason=invalid[aggregate['metadata'][pool_states.KEY]])

        main_compute = aggregate['metadata']['main_compute']
        if main_compute == CONF.host and main_compute != host:
            # this is the main -> instruct it to eject a host from the pool
            host_uuid = aggregate['metadata'][host]
            self._eject_subordinate(aggregate['id'],
                                    subordinate_info.get('compute_uuid'),
                                    host_uuid)
            aggregate.update_metadata({host: None})
        elif main_compute == host:
            # Remove main from its own pool -> destroy pool only if the
            # main is on its own, otherwise raise fault. Destroying a
            # pool made only by main is fictional
            if len(aggregate['hosts']) > 1:
                # NOTE: this could be avoided by doing a main
                # re-election, but this is simpler for now.
                raise exception.InvalidAggregateAction(
                    aggregate_id=aggregate['id'],
                    action='remove_from_aggregate',
                    reason=_('Unable to eject %s '
                             'from the pool; pool not empty') % host)
            self._clear_pool(aggregate['id'])
            aggregate.update_metadata({'main_compute': None, host: None})
        elif main_compute and main_compute != host:
            # A main exists -> forward pool-eject request to main
            subordinate_info = self._create_subordinate_info()

            self.compute_rpcapi.remove_aggregate_host(context, aggregate['id'],
                                                      host, main_compute,
                                                      subordinate_info)
        else:
            # this shouldn't have happened
            raise exception.AggregateError(
                aggregate_id=aggregate['id'],
                action='remove_from_aggregate',
                reason=_('Unable to eject %s '
                         'from the pool; No main found') % host)
Ejemplo n.º 3
0
    def add_to_aggregate(self,
                         context,
                         aggregate,
                         host,
                         subordinate_info=None):
        """Add a compute host to an aggregate."""
        if not pool_states.is_hv_pool(aggregate['metadata']):
            return

        invalid = {
            pool_states.CHANGING: 'setup in progress',
            pool_states.DISMISSED: 'aggregate deleted',
            pool_states.ERROR: 'aggregate in error'
        }

        if (aggregate['metadata'][pool_states.KEY] in invalid.keys()):
            raise exception.InvalidAggregateAction(
                action='add host',
                aggregate_id=aggregate['id'],
                reason=aggregate['metadata'][pool_states.KEY])

        if (aggregate['metadata'][pool_states.KEY] == pool_states.CREATED):
            aggregate.update_metadata({pool_states.KEY: pool_states.CHANGING})
        if len(aggregate['hosts']) == 1:
            # this is the first host of the pool -> make it main
            self._init_pool(aggregate['id'], aggregate['name'])
            # save metadata so that we can find the main again
            metadata = {
                'main_compute': host,
                host: self._host_uuid,
                pool_states.KEY: pool_states.ACTIVE
            }
            aggregate.update_metadata(metadata)
        else:
            # the pool is already up and running, we need to figure out
            # whether we can serve the request from this host or not.
            main_compute = aggregate['metadata']['main_compute']
            if main_compute == CONF.host and main_compute != host:
                # this is the main ->  do a pool-join
                # To this aim, nova compute on the subordinate has to go down.
                # NOTE: it is assumed that ONLY nova compute is running now
                self._join_subordinate(aggregate['id'], host,
                                       subordinate_info.get('compute_uuid'),
                                       subordinate_info.get('url'),
                                       subordinate_info.get('user'),
                                       subordinate_info.get('passwd'))
                metadata = {
                    host: subordinate_info.get('xenhost_uuid'),
                }
                aggregate.update_metadata(metadata)
            elif main_compute and main_compute != host:
                # send rpc cast to main, asking to add the following
                # host with specified credentials.
                subordinate_info = self._create_subordinate_info()

                self.compute_rpcapi.add_aggregate_host(context, aggregate,
                                                       host, main_compute,
                                                       subordinate_info)
Ejemplo n.º 4
0
 def stub_add_host_to_aggregate(context, aggregate, host):
     raise exception.InvalidAggregateAction()