Example #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 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.InvalidAggregateActionDelete(
                    aggregate_id=aggregate['id'],
                    reason=invalid[aggregate['metadata'][pool_states.KEY]])

        master_compute = aggregate['metadata']['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 = aggregate['metadata'][host]
            self._eject_slave(aggregate['id'],
                              slave_info.get('compute_uuid'), host_uuid)
            aggregate.update_metadata({host: None})
        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.InvalidAggregateActionDelete(
                                    aggregate_id=aggregate['id'],
                                    reason=_('Unable to eject %s '
                                             'from the pool; pool not empty')
                                             % host)
            self._clear_pool(aggregate['id'])
            aggregate.update_metadata({'master_compute': None, host: None})
        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 %s '
                                           'from the pool; No master found')
                                           % host)
Example #2
0
    def add_to_aggregate(self, context, aggregate, host, slave_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.InvalidAggregateActionAdd(
                    aggregate_id=aggregate['id'],
                    reason=invalid[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 master
            self._init_pool(aggregate['id'], aggregate['name'])
            # save metadata so that we can find the master again
            metadata = {'master_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.
            master_compute = aggregate['metadata']['master_compute']
            if master_compute == CONF.host and master_compute != host:
                # this is the master ->  do a pool-join
                # To this aim, patron compute on the slave has to go down.
                # NOTE: it is assumed that ONLY patron compute is running now
                self._join_slave(aggregate['id'], host,
                                 slave_info.get('compute_uuid'),
                                 slave_info.get('url'), slave_info.get('user'),
                                 slave_info.get('passwd'))
                metadata = {host: slave_info.get('xenhost_uuid'), }
                aggregate.update_metadata(metadata)
            elif master_compute and master_compute != host:
                # send rpc cast to master, asking to add the following
                # host with specified credentials.
                slave_info = self._create_slave_info()

                self.compute_rpcapi.add_aggregate_host(
                    context, aggregate, host, master_compute, slave_info)