def test_update_metadata(self): self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') self.mox.StubOutWithMock(db, 'aggregate_metadata_add') db.aggregate_metadata_delete(self.context, 123, 'todelete') db.aggregate_metadata_add(self.context, 123, {'toadd': 'myval'}) self.mox.ReplayAll() fake_notifier.NOTIFICATIONS = [] agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {'foo': 'bar'} agg.obj_reset_changes() agg.update_metadata({'todelete': None, 'toadd': 'myval'}) self.assertEqual(2, len(fake_notifier.NOTIFICATIONS)) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual('aggregate.updatemetadata.start', msg.event_type) self.assertEqual({ 'todelete': None, 'toadd': 'myval' }, msg.payload['meta_data']) msg = fake_notifier.NOTIFICATIONS[1] self.assertEqual('aggregate.updatemetadata.end', msg.event_type) self.assertEqual({ 'todelete': None, 'toadd': 'myval' }, msg.payload['meta_data']) self.assertEqual({'foo': 'bar', 'toadd': 'myval'}, agg.metadata)
def test_aggregate_metadata_delete(self): aggregate = {'name': 'fake aggregate', 'id': 'fake-id'} self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') db.aggregate_metadata_delete(mox.IgnoreArg(), aggregate['id'], 'fake') self.mox.ReplayAll() result = self.conductor.aggregate_metadata_delete( self.context, aggregate, 'fake')
def update_metadata(self, context, updates): payload = {'aggregate_id': self.id, 'meta_data': updates} compute_utils.notify_about_aggregate_update(context, "updatemetadata.start", payload) to_add = {} for key, value in updates.items(): if value is None: try: db.aggregate_metadata_delete(context, self.id, key) except exception.AggregateMetadataNotFound: pass try: self.metadata.pop(key) except KeyError: pass else: to_add[key] = value self.metadata[key] = value db.aggregate_metadata_add(context, self.id, to_add) payload['meta_data'] = to_add compute_utils.notify_about_aggregate_update(context, "updatemetadata.end", payload) self.obj_reset_changes(fields=['metadata'])
def update_metadata(self, context, updates): payload = {'aggregate_id': self.id, 'meta_data': updates} compute_utils.notify_about_aggregate_update(context, "updatemetadata.start", payload) to_add = {} for key, value in updates.items(): if value is None: try: db.aggregate_metadata_delete(context, self.id, key) except exception.AggregateMetadataNotFound: pass try: self.metadata.pop(key) except KeyError: pass else: to_add[key] = value self.metadata[key] = value db.aggregate_metadata_add(context, self.id, to_add) compute_utils.notify_about_aggregate_update(context, "updatemetadata.end", payload) self.obj_reset_changes(fields=['metadata'])
def test_aggregate_metadata_delete(self): aggregate = {'name': 'fake aggregate', 'id': 'fake-id'} self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') db.aggregate_metadata_delete(mox.IgnoreArg(), aggregate['id'], 'fake') self.mox.ReplayAll() result = self.conductor.aggregate_metadata_delete(self.context, aggregate, 'fake')
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.assertDictMatch(metadata, expected)
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.assertDictMatch(metadata, expected)
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 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]]) main_compute = self._get_metadata(context, aggregate.id)['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 = self._get_metadata(context, aggregate.id)[host] self._eject_subordinate(aggregate.id, subordinate_info.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 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 %(host)s ' 'from the pool; No main found') % locals())
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 == FLAGS.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) 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 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())
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)
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)
def test_update_metadata(self): self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') self.mox.StubOutWithMock(db, 'aggregate_metadata_add') db.aggregate_metadata_delete(self.context, 123, 'todelete') db.aggregate_metadata_add(self.context, 123, {'toadd': 'myval'}) self.mox.ReplayAll() agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {'foo': 'bar'} agg.obj_reset_changes() agg.update_metadata({'todelete': None, 'toadd': 'myval'}) self.assertEqual({'foo': 'bar', 'toadd': 'myval'}, agg.metadata)
def test_update_metadata(self): self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') self.mox.StubOutWithMock(db, 'aggregate_metadata_add') db.aggregate_metadata_delete(self.context, 123, 'todelete') db.aggregate_metadata_add(self.context, 123, {'toadd': 'myval'}) self.mox.ReplayAll() agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {'foo': 'bar'} agg.obj_reset_changes() agg.update_metadata({'todelete': None, 'toadd': 'myval'}) self.assertEqual({'foo': 'bar', 'toadd': 'myval'}, agg.metadata)
def test_update_metadata(self): self.mox.StubOutWithMock(db, "aggregate_metadata_delete") self.mox.StubOutWithMock(db, "aggregate_metadata_add") db.aggregate_metadata_delete(self.context, 123, "todelete") db.aggregate_metadata_add(self.context, 123, {"toadd": "myval"}) self.mox.ReplayAll() agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {"foo": "bar"} agg.obj_reset_changes() agg.update_metadata({"todelete": None, "toadd": "myval"}) self.assertEqual({"foo": "bar", "toadd": "myval"}, agg.metadata)
def test_aggregate_metdata_get_by_host_with_key(self): """Ensure we can get aggregates by host.""" ctxt = context.get_admin_context() values = {"name": "fake_aggregate2", "availability_zone": "fake_avail_zone"} values2 = {"name": "fake_aggregate3", "availability_zone": "fake_avail_zone"} a1 = _create_aggregate_with_hosts(context=ctxt) a2 = _create_aggregate_with_hosts(context=ctxt, values=values) a3 = _create_aggregate_with_hosts( context=ctxt, values=values2, hosts=["foo.openstack.org"], metadata={"good": "value"} ) r1 = db.aggregate_metadata_get_by_host(ctxt, "foo.openstack.org", key="good") self.assertEqual(r1["good"], set(["value"])) self.assertFalse("fake_key1" in r1) # Delete metadata db.aggregate_metadata_delete(ctxt, a3.id, "good") r2 = db.aggregate_metadata_get_by_host(ctxt, "foo.openstack.org", key="good") self.assertFalse("good" in r2)
def test_aggregate_metdata_get_by_host_with_key(self): """Ensure we can get aggregates by host.""" ctxt = context.get_admin_context() values = {'name': 'fake_aggregate2', 'availability_zone': 'fake_avail_zone', } values2 = {'name': 'fake_aggregate3', 'availability_zone': 'fake_avail_zone', } a1 = _create_aggregate_with_hosts(context=ctxt) a2 = _create_aggregate_with_hosts(context=ctxt, values=values) a3 = _create_aggregate_with_hosts(context=ctxt, values=values2, hosts=['foo.openstack.org'], metadata={'good': 'value'}) r1 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org', key='good') self.assertEqual(r1['good'], set(['value'])) self.assertFalse('fake_key1' in r1) # Delete metadata db.aggregate_metadata_delete(ctxt, a3.id, 'good') r2 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org', key='good') self.assertFalse('good' in r2)
def test_update_metadata(self): self.mox.StubOutWithMock(db, "aggregate_metadata_delete") self.mox.StubOutWithMock(db, "aggregate_metadata_add") db.aggregate_metadata_delete(self.context, 123, "todelete") db.aggregate_metadata_add(self.context, 123, {"toadd": "myval"}) self.mox.ReplayAll() fake_notifier.NOTIFICATIONS = [] agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {"foo": "bar"} agg.obj_reset_changes() agg.update_metadata({"todelete": None, "toadd": "myval"}) self.assertEqual(2, len(fake_notifier.NOTIFICATIONS)) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual("aggregate.updatemetadata.start", msg.event_type) self.assertEqual({"todelete": None, "toadd": "myval"}, msg.payload["meta_data"]) msg = fake_notifier.NOTIFICATIONS[1] self.assertEqual("aggregate.updatemetadata.end", msg.event_type) self.assertEqual({"todelete": None, "toadd": "myval"}, msg.payload["meta_data"]) self.assertEqual({"foo": "bar", "toadd": "myval"}, agg.metadata)
def test_update_metadata(self): self.mox.StubOutWithMock(db, 'aggregate_metadata_delete') self.mox.StubOutWithMock(db, 'aggregate_metadata_add') db.aggregate_metadata_delete(self.context, 123, 'todelete') db.aggregate_metadata_add(self.context, 123, {'toadd': 'myval'}) self.mox.ReplayAll() fake_notifier.NOTIFICATIONS = [] agg = aggregate.Aggregate() agg._context = self.context agg.id = 123 agg.metadata = {'foo': 'bar'} agg.obj_reset_changes() agg.update_metadata({'todelete': None, 'toadd': 'myval'}) self.assertEqual(2, len(fake_notifier.NOTIFICATIONS)) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual('aggregate.updatemetadata.start', msg.event_type) self.assertEqual({'todelete': None, 'toadd': 'myval'}, msg.payload['meta_data']) msg = fake_notifier.NOTIFICATIONS[1] self.assertEqual('aggregate.updatemetadata.end', msg.event_type) self.assertEqual({'todelete': None, 'toadd': 'myval'}, msg.payload['meta_data']) self.assertEqual({'foo': 'bar', 'toadd': 'myval'}, agg.metadata)
def remove_from_aggregate(self, context, aggregate, host, **kwargs): """Remove a compute host from an aggregate.""" master_compute = aggregate.metadetails.get('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())
def test_aggregate_metadata_delete(self): aggregate = {"name": "fake aggregate", "id": "fake-id"} self.mox.StubOutWithMock(db, "aggregate_metadata_delete") db.aggregate_metadata_delete(mox.IgnoreArg(), aggregate["id"], "fake") self.mox.ReplayAll() result = self.conductor.aggregate_metadata_delete(self.context, aggregate, "fake")
def aggregate_metadata_delete(self, context, aggregate_id, key): return db.aggregate_metadata_delete(context, aggregate_id, key)
def aggregate_metadata_delete(self, context, aggregate, key): return db.aggregate_metadata_delete(context, aggregate['id'], key)