Beispiel #1
0
 def _init_pool(self, aggregate_id, aggregate_name):
     """Set the name label of a XenServer pool."""
     try:
         pool_ref = self._session.pool.get_all()[0]
         self._session.pool.set_name_label(pool_ref, aggregate_name)
     except self._session.XenAPI.Failure as e:
         LOG.error("Unable to set up pool: %s.", e)
         raise exception.AggregateError(aggregate_id=aggregate_id,
                                        action='add_to_aggregate',
                                        reason=six.text_type(e.details))
Beispiel #2
0
 def _init_pool(self, aggregate_id, aggregate_name):
     """Set the name label of a XenServer pool."""
     try:
         pool_ref = self._session.call_xenapi("pool.get_all")[0]
         self._session.call_xenapi("pool.set_name_label", pool_ref,
                                   aggregate_name)
     except self._session.XenAPI.Failure as e:
         LOG.error(_("Unable to set up pool: %(e)s.") % locals())
         raise exception.AggregateError(aggregate_id=aggregate_id,
                                        action='add_to_aggregate',
                                        reason=str(e.details))
Beispiel #3
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['metadetails']):
            return

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

        master_compute = aggregate['metadetails']['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['metadetails'][host]
            self._eject_slave(aggregate['id'], slave_info.get('compute_uuid'),
                              host_uuid)
            self._virtapi.aggregate_metadata_delete(context, aggregate, 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, 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())
Beispiel #4
0
    def remove_from_aggregate(self, context, aggregate, host, **kwargs):
        """Remove a compute host from an aggregate."""
        if not pool_states.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 (db.aggregate_metadata_get(context, aggregate.id)[pool_states.KEY]
                in invalid.keys()):
            raise exception.InvalidAggregateAction(
                action='remove host',
                aggregate_id=aggregate.id,
                reason=invalid[db.aggregate_metadata_get(
                    context, aggregate.id)[pool_states.KEY]])

        master_compute = db.aggregate_metadata_get(
            context, aggregate.id)['master_compute']
        if master_compute == FLAGS.host and master_compute != host:
            # this is the master -> instruct it to eject a host from the pool
            host_uuid = db.aggregate_metadata_get(context, aggregate.id)[host]
            self._eject_slave(aggregate.id, kwargs.get('compute_uuid'),
                              host_uuid)
            db.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]:
                db.aggregate_metadata_delete(context, aggregate.id, key)
        elif master_compute and master_compute != host:
            # A master exists -> forward pool-eject request to master
            forward_request(context, "remove_aggregate_host", master_compute,
                            aggregate.id, host, self._host_addr,
                            self._host_uuid)
        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())
Beispiel #5
0
    def _eject_slave(self, aggregate_id, compute_uuid, host_uuid):
        """Eject a slave from a XenServer resource pool."""
        try:
            # shutdown nova-compute; if there are other VMs running, e.g.
            # guest instances, the eject will fail. That's a precaution
            # to deal with the fact that the admin should evacuate the host
            # first. The eject wipes out the host completely.
            vm_ref = self._session.VM.get_by_uuid(compute_uuid)
            self._session.VM.clean_shutdown(vm_ref)

            host_ref = self._session.host.get_by_uuid(host_uuid)
            self._session.pool.eject(host_ref)
        except self._session.XenAPI.Failure as e:
            LOG.error(_("Pool-eject failed: %s"), e)
            raise exception.AggregateError(aggregate_id=aggregate_id,
                                           action='remove_from_aggregate',
                                           reason=str(e.details))
Beispiel #6
0
 def _join_slave(self, aggregate_id, host, compute_uuid, url, user, passwd):
     """Joins a slave into a XenServer resource pool."""
     try:
         args = {'compute_uuid': compute_uuid,
                 'url': url,
                 'user': user,
                 'password': passwd,
                 'force': jsonutils.dumps(CONF.xenserver.use_join_force),
                 'master_addr': self._host_addr,
                 'master_user': CONF.xenserver.connection_username,
                 'master_pass': CONF.xenserver.connection_password, }
         self._session.call_plugin('xenhost', 'host_join', args)
     except self._session.XenAPI.Failure as e:
         LOG.error(_LE("Pool-Join failed: %s"), e)
         raise exception.AggregateError(aggregate_id=aggregate_id,
                                        action='add_to_aggregate',
                                        reason=_('Unable to join %s '
                                               'in the pool') % host)
Beispiel #7
0
 def _join_subordinate(self, aggregate_id, host, compute_uuid, url, user, passwd):
     """Joins a subordinate into a XenServer resource pool."""
     try:
         args = {'compute_uuid': compute_uuid,
                 'url': url,
                 'user': user,
                 'password': passwd,
                 'force': jsonutils.dumps(FLAGS.use_join_force),
                 'main_addr': self._host_addr,
                 'main_user': FLAGS.xenapi_connection_username,
                 'main_pass': FLAGS.xenapi_connection_password, }
         self._session.call_plugin('xenhost', 'host_join', args)
     except self._session.XenAPI.Failure as e:
         LOG.error(_("Pool-Join failed: %(e)s") % locals())
         raise exception.AggregateError(aggregate_id=aggregate_id,
                                        action='add_to_aggregate',
                                        reason=_('Unable to join %(host)s '
                                               'in the pool') % locals())
 def remove_from_aggregate(self, context, aggregate, host, **kwargs):
     """Remove a compute host from an aggregate."""
     main_compute = aggregate.metadetails.get('main_compute')
     if main_compute == FLAGS.host and main_compute != host:
         # this is the main -> instruct it to eject a host from the pool
         host_uuid = db.aggregate_metadata_get(context, aggregate.id)[host]
         self._eject_subordinate(aggregate.id, kwargs.get('compute_uuid'),
                                 host_uuid)
         db.aggregate_metadata_delete(context, aggregate.id, host)
     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 %(host)s '
                          'from the pool; pool not empty') % locals())
         self._clear_pool(aggregate.id)
         for key in ['main_compute', host]:
             db.aggregate_metadata_delete(context, aggregate.id, key)
     elif main_compute and main_compute != host:
         # A main exists -> forward pool-eject request to main
         forward_request(context, "remove_aggregate_host", main_compute,
                         aggregate.id, host, self._host_addr,
                         self._host_uuid)
     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 main found') % locals())