Make Server metadata a passive store again

This change reverts the software deployments change which polls
the deployments API whenever a Server resource metadata is read.

The Server metadata has reverted to being a standard resource
metadata store, and the deployments are pushed into this metadata
directly in the database whenever the deployments API is used to
create or update a deployment.

As part of the effort to not require a Stack.load for polling metadata
this change is for
Partial-Bug: #1306743

Change-Id: Ib461e1bab816d4b9e332786004c53a2f73d773e8
This commit is contained in:
Steve Baker 2014-05-05 11:43:38 +12:00 committed by Clint Byrum
parent f671d4e3a6
commit f8b15273a2
5 changed files with 57 additions and 53 deletions

View File

@ -125,7 +125,8 @@ def resource_get_by_physical_resource_id(context, physical_resource_id):
.all())
for result in results:
if context is None or result.stack.tenant == context.tenant_id:
if context is None or context.tenant_id in (
result.stack.tenant, result.stack.stack_user_project_id):
return result
return None

View File

@ -345,13 +345,9 @@ class Server(stack_user.StackUser):
# This method is overridden by the derived CloudServer resource
return self.properties.get(self.CONFIG_DRIVE)
@staticmethod
def _get_deployments_metadata(heatclient, server_id):
return heatclient.software_deployments.metadata(
server_id=server_id)
def _build_deployments_metadata(self):
meta = {}
def _populate_deployments_metadata(self):
meta = self.metadata_get(True) or {}
meta['deployments'] = meta.get('deployments', [])
if self.transport_poll_server_heat():
meta['os-collect-config'] = {'heat': {
'user_id': self._get_user_id(),
@ -369,15 +365,7 @@ class Server(stack_user.StackUser):
'stack_name': self.stack.name,
'path': '%s.Metadata' % self.name}
}
deployments = []
# cannot query the deployments if the nova server does
# not exist yet
if self.resource_id:
deployments = self._get_deployments_metadata(
self.heat(), self.resource_id)
meta['deployments'] = deployments
return meta
self.metadata_set(meta)
def _register_access_key(self):
'''
@ -423,16 +411,6 @@ class Server(stack_user.StackUser):
else:
self.data_set('password', password, True)
def metadata_get(self, refresh=False):
if self.user_data_software_config():
return self._build_deployments_metadata()
else:
return super(Server, self).metadata_get(refresh)
def metadata_set(self, metadata):
if not self.user_data_software_config():
super(Server, self).metadata_set(metadata)
def user_data_raw(self):
return self.properties.get(self.USER_DATA_FORMAT) == self.RAW
@ -465,6 +443,7 @@ class Server(stack_user.StackUser):
if self.user_data_software_config():
self._create_transport_credentials()
self._populate_deployments_metadata()
if self.properties[self.ADMIN_USER]:
instance_user = self.properties[self.ADMIN_USER]

View File

@ -1169,6 +1169,14 @@ class EngineService(service.Service):
result = [api.format_software_config(sd.config) for sd in all_sd_s]
return result
def _push_metadata_software_deployments(self, cnxt, server_id):
rs = db_api.resource_get_by_physical_resource_id(cnxt, server_id)
if rs:
deployments = self.metadata_software_deployments(cnxt, server_id)
md = rs.rsrc_metadata or {}
md['deployments'] = deployments
rs.update_and_save({'rsrc_metadata': md})
@request_context
def show_software_deployment(self, cnxt, deployment_id):
sd = db_api.software_deployment_get(cnxt, deployment_id)
@ -1188,6 +1196,7 @@ class EngineService(service.Service):
'action': action,
'status': status,
'status_reason': status_reason})
self._push_metadata_software_deployments(cnxt, server_id)
return api.format_software_deployment(sd)
@request_context
@ -1209,6 +1218,7 @@ class EngineService(service.Service):
update_data['status_reason'] = status_reason
sd = db_api.software_deployment_update(cnxt,
deployment_id, update_data)
self._push_metadata_software_deployments(cnxt, sd.server_id)
return api.format_software_deployment(sd)
@request_context

View File

@ -2764,21 +2764,51 @@ class SoftwareConfigServiceTest(HeatTestCase):
action, status, status_reason, stack_user_project_id)
def test_list_software_deployments(self):
deployment = self._create_software_deployment()
stack_name = 'test_list_software_deployments'
stack = get_wordpress_stack(stack_name, self.ctx)
setup_mocks(self.m, stack)
self.m.ReplayAll()
stack.store()
stack.create()
server = stack['WebServer']
server_id = server.resource_id
deployment = self._create_software_deployment(
server_id=server_id)
deployment_id = deployment['id']
self.assertIsNotNone(deployment)
deployments = self.engine.list_software_deployments(
self.ctx, server_id=None)
self.assertIsNotNone(deployments)
deployment_ids = [x['id'] for x in deployments]
self.assertIn(deployment_id, deployment_ids)
self.assertIn(deployment, deployments)
deployments = self.engine.list_software_deployments(
self.ctx, server_id=str(uuid.uuid4()))
self.assertEqual([], deployments)
deployments = self.engine.list_software_deployments(
self.ctx, server_id=server.resource_id)
self.assertEqual([deployment], deployments)
rs = db_api.resource_get_by_physical_resource_id(self.ctx, server_id)
self.assertEqual(deployment['config_id'],
rs.rsrc_metadata.get('deployments')[0]['id'])
def test_metadata_software_deployments(self):
server_id = str(uuid.uuid4())
stack_name = 'test_list_software_deployments'
stack = get_wordpress_stack(stack_name, self.ctx)
setup_mocks(self.m, stack)
self.m.ReplayAll()
stack.store()
stack.create()
server = stack['WebServer']
server_id = server.resource_id
stack_user_project_id = str(uuid.uuid4())
d1 = self._create_software_deployment(
config_group='mygroup',
@ -2808,6 +2838,12 @@ class SoftwareConfigServiceTest(HeatTestCase):
self.assertEqual('02_second', metadata[1]['name'])
self.assertEqual('03_third', metadata[2]['name'])
# assert that metadata via metadata_software_deployments matches
# metadata via server resource
rs = db_api.resource_get_by_physical_resource_id(self.ctx, server_id)
self.assertEqual(metadata,
rs.rsrc_metadata.get('deployments'))
deployments = self.engine.metadata_software_deployments(
self.ctx, server_id=str(uuid.uuid4()))
self.assertEqual([], deployments)

View File

@ -508,16 +508,12 @@ class ServersTest(HeatTestCase):
self.m.StubOutWithMock(server, 'nova')
self.m.StubOutWithMock(server, 'keystone')
self.m.StubOutWithMock(server, 'heat')
self.m.StubOutWithMock(server, '_get_deployments_metadata')
server.nova().MultipleTimes().AndReturn(self.fc)
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
server.keystone().MultipleTimes().AndReturn(self.fkc)
server.heat().MultipleTimes().AndReturn(self.fc)
server._get_deployments_metadata(
self.fc, '5678').AndReturn({'foo': 'bar'})
self.m.StubOutWithMock(self.fc.servers, 'create')
self.fc.servers.create(
@ -552,7 +548,7 @@ class ServersTest(HeatTestCase):
'stack_name': 'software_config_s'
}
},
'deployments': {'foo': 'bar'}
'deployments': []
}, server.metadata_get())
created_server = servers.Server('WebServer',
@ -576,17 +572,12 @@ class ServersTest(HeatTestCase):
self.m.StubOutWithMock(server, 'nova')
self.m.StubOutWithMock(server, 'keystone')
self.m.StubOutWithMock(server, 'heat')
self.m.StubOutWithMock(server, '_get_deployments_metadata')
server.nova().MultipleTimes().AndReturn(self.fc)
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
server.keystone().MultipleTimes().AndReturn(self.fkc)
server.heat().MultipleTimes().AndReturn(self.fc)
server._get_deployments_metadata(
self.fc, '5678').AndReturn({'foo': 'bar'})
self.m.StubOutWithMock(self.fc.servers, 'create')
self.fc.servers.create(
@ -622,7 +613,7 @@ class ServersTest(HeatTestCase):
'user_id': '1234'
}
},
'deployments': {'foo': 'bar'}
'deployments': []
}, server.metadata_get())
created_server = servers.Server('WebServer',
@ -632,19 +623,6 @@ class ServersTest(HeatTestCase):
self.m.VerifyAll()
def test_server_metadata_with_empty_deploy(self):
stack_name = 'software_config_s'
(t, stack) = self._setup_test_stack(stack_name)
props = t['Resources']['WebServer']['Properties']
props['user_data_format'] = 'SOFTWARE_CONFIG'
server = servers.Server('WebServer',
t['Resources']['WebServer'], stack)
self.m.StubOutWithMock(server, 'keystone')
self.m.ReplayAll()
deployments = server.metadata_get()['deployments']
self.assertEqual([], deployments)
self.m.VerifyAll()
@mock.patch.object(clients.OpenStackClients, 'nova')
def test_server_create_default_admin_pass(self, mock_nova):
return_server = self.fc.servers.list()[1]