Resources patch() not capturing all the exceptions raised by jsonpatch

Bug #1271554 reported by Lucas Alvares Gomes
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Ironic
Fix Released
Medium
Lucas Alvares Gomes

Bug Description

We have a try/except block on the resources around jsonpatch.apply_patch() call but they are only capturing the JsonPatchException, which seems not enough to handle all the exceptions raised by the jsonpatch.apply_patch().

That's hw it looks in our code right now

        try:
            node = Node(**jsonpatch.apply_patch(rpc_node.as_dict(),
                                                jsonpatch.JsonPatch(patch)))
        except jsonpatch.JsonPatchException as e:
            LOG.exception(e)
            raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)

These are the exceptions not handled by us:

stack@stack-virtual-machine:~/devstack$ ironic node-update $NODE remove foo/pxe_preserve_ephemeral
member 'foo' not found in {'instance_uuid': u'b0b8b802-99b9-4329-b2e7-2d8e4af4ef3a', 'target_power_state': None, 'uuid': u'6fdbf5cd-36da-4c09-abaa-636705073440', 'driver_info': {u'pxe_deploy_ramdisk': u'c105a864-850e-4bea-8281-97cf826fdc53', u'pxe_instance_name': u'test', u'pxe_image_source': u'afeae16c-8217-42c3-b02b-e87273adb786', u'pxe_root_gb': u'5', u'ssh_username': u'root', u'ssh_key_filename': u'/home/stack/ssh_rsa', u'pxe_deploy_key': u'YUYQALNU552C6KIHPNK4GO64DMW76R2G', u'pxe_deploy_kernel': u'348fe5df-b273-4971-a9ea-80482d94b6a3', u'ssh_address': u'192.168.122.1', u'ssh_virt_type': u'virsh', u'pxe_ephemeral_gb': u'1'}, 'target_provision_state': None, 'last_error': None, 'created_at': datetime.datetime(2014, 1, 22, 11, 46, 33, tzinfo=<iso8601.iso8601.Utc object at 0x4a5a510>), 'extra': {}, 'driver': u'pxe_ssh', 'updated_at': datetime.datetime(2014, 1, 22, 14, 4, 9, tzinfo=<iso8601.iso8601.Utc object at 0x4a5a250>), 'chassis_id': None, 'id': 1, 'maintenance': False, 'provision_state': None, 'reservation': None, 'power_state': u'power off', 'properties': {}}
Traceback (most recent call last):

  File "/usr/local/lib/python2.7/dist-packages/wsmeext/pecan.py", line 77, in callfunction
    result = f(self, *args, **kwargs)

  File "/opt/stack/ironic/ironic/api/controllers/v1/node.py", line 559, in patch
    jsonpatch.JsonPatch(patch)))

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 141, in apply_patch
    return patch.apply(doc, in_place)

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 344, in apply
    obj = operation.apply(obj)

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 393, in apply
    subobj, part = self.pointer.to_last(obj)

  File "/usr/local/lib/python2.7/dist-packages/jsonpointer.py", line 152, in to_last
    doc = self.walk(doc, part)

  File "/usr/local/lib/python2.7/dist-packages/jsonpointer.py", line 228, in walk
    raise JsonPointerException("member '%s' not found in %s" % (part, doc))

JsonPointerException: member 'foo' not found in {'instance_uuid': u'b0b8b802-99b9-4329-b2e7-2d8e4af4ef3a', 'target_power_state': None, 'uuid': u'6fdbf5cd-36da-4c09-abaa-636705073440', 'driver_info': {u'pxe_deploy_ramdisk': u'c105a864-850e-4bea-8281-97cf826fdc53', u'pxe_instance_name': u'test', u'pxe_image_source': u'afeae16c-8217-42c3-b02b-e87273adb786', u'pxe_root_gb': u'5', u'ssh_username': u'root', u'ssh_key_filename': u'/home/stack/ssh_rsa', u'pxe_deploy_key': u'YUYQALNU552C6KIHPNK4GO64DMW76R2G', u'pxe_deploy_kernel': u'348fe5df-b273-4971-a9ea-80482d94b6a3', u'ssh_address': u'192.168.122.1', u'ssh_virt_type': u'virsh', u'pxe_ephemeral_gb': u'1'}, 'target_provision_state': None, 'last_error': None, 'created_at': datetime.datetime(2014, 1, 22, 11, 46, 33, tzinfo=<iso8601.iso8601.Utc object at 0x4a5a510>), 'extra': {}, 'driver': u'pxe_ssh', 'updated_at': datetime.datetime(2014, 1, 22, 14, 4, 9, tzinfo=<iso8601.iso8601.Utc object at 0x4a5a250>), 'chassis_id': None, 'id': 1, 'maintenance': False, 'provision_state': None, 'reservation': None, 'power_state': u'power off', 'properties': {}}

stack@stack-virtual-machine:~/devstack$ ironic node-update $NODE remove foo
u'foo'
Traceback (most recent call last):

  File "/usr/local/lib/python2.7/dist-packages/wsmeext/pecan.py", line 77, in callfunction
    result = f(self, *args, **kwargs)

  File "/opt/stack/ironic/ironic/api/controllers/v1/node.py", line 559, in patch
    jsonpatch.JsonPatch(patch)))

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 141, in apply_patch
    return patch.apply(doc, in_place)

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 344, in apply
    obj = operation.apply(obj)

  File "/usr/local/lib/python2.7/dist-packages/jsonpatch.py", line 395, in apply
    del subobj[part]

KeyError: u'foo'

stack@stack-virtual-machine:~/devstack$

Changed in ironic:
assignee: nobody → Lucas Alvares Gomes (lucasagomes)
milestone: none → icehouse-3
importance: Undecided → Medium
summary: - Resource patch() not capturing all the exceptions raised by
- jsonpatch.JsonPatch()
+ Resource patch() not capturing all the exceptions raised by jsonpatch
description: updated
summary: - Resource patch() not capturing all the exceptions raised by jsonpatch
+ Resourcea patch() not capturing all the exceptions raised by jsonpatch
description: updated
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to ironic (master)

Fix proposed to branch: master
Review: https://review.openstack.org/68457

Changed in ironic:
status: New → In Progress
summary: - Resourcea patch() not capturing all the exceptions raised by jsonpatch
+ Resources patch() not capturing all the exceptions raised by jsonpatch
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to ironic (master)

Reviewed: https://review.openstack.org/68457
Committed: https://git.openstack.org/cgit/openstack/ironic/commit/?id=c52781df05b41687d31a5c769f1d35d96adf7f44
Submitter: Jenkins
Branch: master

commit c52781df05b41687d31a5c769f1d35d96adf7f44
Author: Lucas Alvares Gomes <email address hidden>
Date: Wed Jan 22 17:46:53 2014 +0000

    Handle multiple exceptions raised by jsonpatch

    The jsonpatch.apply_patch() might raise different types of exceptions,
    this patch improve the exception handler on the jsonpatch.apply_patch()
    call to capture them and also creates a new exception called PatchError
    to avoid replicating the same error message across the resources.

    The patch also doesn't log the exception raised by the apply_patch()
    anymore, since the problem will be returned to the client directly via
    the API response.

    In the chassis.py an alias "api_utils" was created to the utils module
    to be more consistent with the ports and nodes resource.

    Closes-Bug: #1271554
    Change-Id: Ied1f5e573839520cc5f4e04548720f016f33349b

Changed in ironic:
status: In Progress → Fix Committed
Thierry Carrez (ttx)
Changed in ironic:
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in ironic:
milestone: icehouse-3 → 2014.1
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.