Example #1
0
    def add_to_aggregate(self, context, aggregate, host, **kwargs):
        """Add a compute host to an aggregate."""
        if not pool_states.is_hv_pool(context, aggregate.id):
            return

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

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

        if (db.aggregate_metadata_get(
                context,
                aggregate.id)[pool_states.KEY] == pool_states.CREATED):
            db.aggregate_metadata_add(context, aggregate.id,
                                      {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
            }
            db.aggregate_metadata_add(context, aggregate.id, 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 = db.aggregate_metadata_get(
                context, aggregate.id)['master_compute']
            if master_compute == FLAGS.host and master_compute != host:
                # this is the master ->  do a pool-join
                # To this aim, nova compute on the slave has to go down.
                # NOTE: it is assumed that ONLY nova compute is running now
                self._join_slave(aggregate.id, host,
                                 kwargs.get('compute_uuid'), kwargs.get('url'),
                                 kwargs.get('user'), kwargs.get('passwd'))
                metadata = {
                    host: kwargs.get('xenhost_uuid'),
                }
                db.aggregate_metadata_add(context, aggregate.id, metadata)
            elif master_compute and master_compute != host:
                # send rpc cast to master, asking to add the following
                # host with specified credentials.
                forward_request(context, "add_aggregate_host", master_compute,
                                aggregate.id, host, self._host_addr,
                                self._host_uuid)
Example #2
0
 def test_aggregate_create_delete_create_with_metadata(self):
     """Ensure aggregate metadata is deleted bug 1052479."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     expected_metadata = db.aggregate_metadata_get(ctxt, result['id'])
     self.assertDictMatch(expected_metadata, _get_fake_aggr_metadata())
     db.aggregate_delete(ctxt, result['id'])
     result = _create_aggregate(metadata=None)
     expected_metadata = db.aggregate_metadata_get(ctxt, result['id'])
     self.assertEqual(expected_metadata, {})
Example #3
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())
Example #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())
Example #5
0
    def add_to_aggregate(self, context, aggregate, host, **kwargs):
        """Add a compute host to an aggregate."""
        if not pool_states.is_hv_pool(context, aggregate.id):
            return

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

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

        if (db.aggregate_metadata_get(context, aggregate.id)[pool_states.KEY]
                == pool_states.CREATED):
            db.aggregate_metadata_add(context, aggregate.id,
                    {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}
            db.aggregate_metadata_add(context, aggregate.id, 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 = db.aggregate_metadata_get(context,
                    aggregate.id)['master_compute']
            if master_compute == FLAGS.host and master_compute != host:
                # this is the master ->  do a pool-join
                # To this aim, nova compute on the slave has to go down.
                # NOTE: it is assumed that ONLY nova compute is running now
                self._join_slave(aggregate.id, host,
                                 kwargs.get('compute_uuid'),
                                 kwargs.get('url'), kwargs.get('user'),
                                 kwargs.get('passwd'))
                metadata = {host: kwargs.get('xenhost_uuid'), }
                db.aggregate_metadata_add(context, aggregate.id, metadata)
            elif master_compute and master_compute != host:
                # send rpc cast to master, asking to add the following
                # host with specified credentials.
                forward_request(context, "add_aggregate_host", master_compute,
                                aggregate.id, host,
                                self._host_addr, self._host_uuid)
Example #6
0
 def test_aggregate_create_with_metadata(self):
     """Ensure aggregate can be created with metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     expected_metadata = db.aggregate_metadata_get(ctxt, result['id'])
     self.assertThat(expected_metadata,
                     matchers.DictMatches(_get_fake_aggr_metadata()))
Example #7
0
 def test_aggregate_metadata_add(self):
     """Ensure we can add metadata for the aggregate."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt, metadata=None)
     metadata = _get_fake_aggr_metadata()
     db.aggregate_metadata_add(ctxt, result.id, metadata)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(metadata, expected)
Example #8
0
 def test_aggregate_metadata_add(self):
     """Ensure we can add metadata for the aggregate."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt, metadata=None)
     metadata = _get_fake_aggr_metadata()
     db.aggregate_metadata_add(ctxt, result.id, metadata)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(metadata, expected)
Example #9
0
 def test_aggregate_update_with_metadata(self):
     """Ensure an aggregate can be updated with metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt, metadata=None)
     values = _get_fake_aggr_values()
     values['metadata'] = _get_fake_aggr_metadata()
     db.aggregate_update(ctxt, 1, values)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(_get_fake_aggr_metadata(), expected)
Example #10
0
 def test_aggregate_update_with_metadata(self):
     """Ensure an aggregate can be updated with metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt, metadata=None)
     values = _get_fake_aggr_values()
     values['metadata'] = _get_fake_aggr_metadata()
     db.aggregate_update(ctxt, 1, values)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(_get_fake_aggr_metadata(), expected)
Example #11
0
 def test_aggregate_metadata_delete(self):
     """Ensure we can delete metadata for the aggregate."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt, metadata=None)
     metadata = _get_fake_aggr_metadata()
     db.aggregate_metadata_add(ctxt, result.id, metadata)
     db.aggregate_metadata_delete(ctxt, result.id, metadata.keys()[0])
     expected = db.aggregate_metadata_get(ctxt, result.id)
     del metadata[metadata.keys()[0]]
     self.assertThat(metadata, matchers.DictMatches(expected))
Example #12
0
 def test_aggregate_update_with_existing_metadata(self):
     """Ensure an aggregate can be updated with existing metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     values = _get_fake_aggr_values()
     values['metadata'] = _get_fake_aggr_metadata()
     values['metadata']['fake_key1'] = 'foo'
     db.aggregate_update(ctxt, 1, values)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(values['metadata'], expected)
Example #13
0
 def test_aggregate_update_with_existing_metadata(self):
     """Ensure an aggregate can be updated with existing metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     values = _get_fake_aggr_values()
     values['metadata'] = _get_fake_aggr_metadata()
     values['metadata']['fake_key1'] = 'foo'
     db.aggregate_update(ctxt, 1, values)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     self.assertDictMatch(values['metadata'], expected)
Example #14
0
 def test_aggregate_metadata_update(self):
     """Ensure we can update metadata for the aggregate."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     metadata = _get_fake_aggr_metadata()
     key = metadata.keys()[0]
     db.aggregate_metadata_delete(ctxt, result.id, key)
     new_metadata = {key: 'foo'}
     db.aggregate_metadata_add(ctxt, result.id, new_metadata)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     metadata[key] = 'foo'
     self.assertDictMatch(metadata, expected)
Example #15
0
 def test_aggregate_metadata_update(self):
     """Ensure we can update metadata for the aggregate."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     metadata = _get_fake_aggr_metadata()
     key = metadata.keys()[0]
     db.aggregate_metadata_delete(ctxt, result.id, key)
     new_metadata = {key: 'foo'}
     db.aggregate_metadata_add(ctxt, result.id, new_metadata)
     expected = db.aggregate_metadata_get(ctxt, result.id)
     metadata[key] = 'foo'
     self.assertDictMatch(metadata, expected)
Example #16
0
 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())
Example #17
0
File: pool.py Project: SimiPro/nova
 def _is_hv_pool(self, context, aggregate_id):
     """Checks if aggregate is a hypervisor_pool"""
     metadata = db.aggregate_metadata_get(context, aggregate_id)
     return pool_states.POOL_FLAG in metadata.keys()
Example #18
0
 def aggregate_metadata_get(self, context, aggregate_id):
     return db.aggregate_metadata_get(context, aggregate_id)
Example #19
0
def is_hv_pool(context, aggregate_id):
    """Checks if aggregate is a hypervisor_pool"""
    metadata = db.aggregate_metadata_get(context, aggregate_id)
    return POOL_FLAG in metadata.keys()
Example #20
0
File: fake.py Project: gajen/nova
 def aggregate_metadata_get(self, context, aggregate_id):
     return db.aggregate_metadata_get(context, aggregate_id)
Example #21
0
 def test_aggregate_create_with_metadata(self):
     """Ensure aggregate can be created with metadata."""
     ctxt = context.get_admin_context()
     result = _create_aggregate(context=ctxt)
     expected_metadata = db.aggregate_metadata_get(ctxt, result['id'])
     self.assertDictMatch(expected_metadata, _get_fake_aggr_metadata())