Update pod support a manifest change

Currently, we don't support a manifest change when we update a pod.

This patch fix this problem so that we can update the label or other
useful attributes of a pod.

Partial-Bug: #1444383

Change-Id: I87e220e88bc32d7eee9d37c552aea9920a027056
This commit is contained in:
Lan Qi song 2015-04-15 16:25:59 +08:00 committed by Lan Qi Song
parent 6a07d7c7dc
commit 6ed3ccb9df
6 changed files with 32 additions and 6 deletions

View File

@ -262,19 +262,20 @@ class PodsController(rest.RestController):
raise exception.OperationNotPermitted
rpc_pod = objects.Pod.get_by_uuid(pecan.request.context, pod_uuid)
# Init manifest and manifest_url field because we don't store them
# in database.
rpc_pod['manifest'] = None
rpc_pod['manifest_url'] = None
try:
pod_dict = rpc_pod.as_dict()
pod = Pod(**api_utils.apply_jsonpatch(pod_dict, patch))
if pod.manifest or pod.manifest_url:
pod.parse_manifest()
except api_utils.JSONPATCH_EXCEPTIONS as e:
raise exception.PatchError(patch=patch, reason=e)
# Update only the fields that have changed
for field in objects.Pod.fields:
# ignore manifest_url as it was used for create pod
if field == 'manifest_url':
continue
if field == 'manifest':
continue
try:
patch_val = getattr(pod, field)
except AttributeError:
@ -285,7 +286,10 @@ class PodsController(rest.RestController):
if rpc_pod[field] != patch_val:
rpc_pod[field] = patch_val
rpc_pod.save()
if pod.manifest or pod.manifest_url:
pecan.request.rpcapi.pod_update(rpc_pod)
else:
rpc_pod.save()
return Pod.convert_with_links(rpc_pod)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204)

View File

@ -86,6 +86,9 @@ class API(rpc_service.API):
def pod_list(self, context, limit, marker, sort_key, sort_dir):
return objects.Pod.list(context, limit, marker, sort_key, sort_dir)
def pod_update(self, pod):
return self._call('pod_update', pod=pod)
def pod_delete(self, uuid):
return self._call('pod_delete', uuid=uuid)

View File

@ -154,6 +154,7 @@ class Handler(object):
return None
# call the pod object to persist in db
pod.refresh(context)
pod.save()
return pod
def pod_delete(self, context, uuid):

View File

@ -189,6 +189,10 @@ class Pod(base.MagnumObject):
"""
current = self.__class__.get_by_uuid(self._context, uuid=self.uuid)
for field in self.fields:
if field == 'manifest_url':
continue
if field == 'manifest':
continue
if (hasattr(self, base.get_attrname(field)) and
self[field] != current[field]):
self[field] = current[field]

View File

@ -211,6 +211,18 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
@mock.patch.object(rpcapi.API, 'pod_update')
@mock.patch.object(api_pod.Pod, 'parse_manifest')
def test_replace_with_manifest(self, parse_manifest, pod_update):
response = self.patch_json('/pods/%s' % self.pod.uuid,
[{'path': '/manifest',
'value': '{}',
'op': 'replace'}])
self.assertEqual(200, response.status_int)
self.assertEqual('application/json', response.content_type)
parse_manifest.assert_called_once_with()
self.assertTrue(pod_update.is_called)
def test_add_ok(self):
new_desc = 'pod_example_B_desc'
response = self.patch_json('/pods/%s' % self.pod.uuid,

View File

@ -455,6 +455,7 @@ class TestKube(base.TestCase):
expected_pod = self.mock_pod()
expected_pod.uuid = 'test-uuid'
expected_pod.refresh = mock.MagicMock()
expected_pod.save = mock.MagicMock()
mock_retrieve_k8s_master_url.return_value = expected_master_url
with patch.object(self.kube_handler, 'kube_cli') as mock_kube_cli:
@ -464,6 +465,7 @@ class TestKube(base.TestCase):
mock_kube_cli.pod_update.assert_called_once_with(
expected_master_url, expected_pod)
expected_pod.refresh.assert_called_once_with(self.context)
expected_pod.save.assert_called_once_with()
@patch('magnum.conductor.handlers.kube._retrieve_k8s_master_url')
def test_pod_update_with_failure(self,