)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"340bcec2697195165b0198b49cc8d232c7cd0204","unresolved":false,"context_lines":[{"line_number":21,"context_line":"Closes-Bug: #1727260"},{"line_number":22,"context_line":"Signed-off-by: Sahid Orentino Ferdjaoui \u003csahid.ferdjaoui@redhat.com\u003e"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"(cherry picked from commit ce531dd1b763704b9043ddde8e80ac99cd193660)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Conflicts:"},{"line_number":27,"context_line":"\tnova/tests/unit/virt/libvirt/test_driver.py"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bf659307_36537f6d","line":24,"updated":"2018-04-12 16:32:09.000000000","message":"I would have preferred if you would have cherry picked from stable/queens instead of master, to show the order, so git cherry-pick -x d6a072b5c5a3ff9de7f4b42cda517ead17efe561 instead.","commit_id":"aad80146aab0f678f56fbcf2d1632f814ca6c8fd"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"340bcec2697195165b0198b49cc8d232c7cd0204","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"This latter issue means that we won\u0027t call encryptor.detach_volume()"},{"line_number":36,"context_line":"if we hit exception.DeviceNotFound when detaching the device from"},{"line_number":37,"context_line":"the guest.  For that we\u0027d need something similar to commit cd3eb60c."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Signed-off-by: Chris Friesen \u003cchris.friesen@windriver.com\u003e"},{"line_number":40,"context_line":"Change-Id: I4182642aab3fd2ffb1c97d2de9bdca58982289d8"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bf659307_b6f54f59","line":37,"range":{"start_line":37,"start_character":59,"end_line":37,"end_character":67},"updated":"2018-04-12 16:32:09.000000000","message":"For this, you could consider basing your cherry pick on top of https://review.openstack.org/#/c/543569/ if that helps any, otherwise the code diff is OK so explaining the conflict is good enough.","commit_id":"aad80146aab0f678f56fbcf2d1632f814ca6c8fd"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"27bcca6849b9e02184865558374ad6bae5dd9198","unresolved":false,"context_lines":[{"line_number":21,"context_line":"Closes-Bug: #1727260"},{"line_number":22,"context_line":"Signed-off-by: Sahid Orentino Ferdjaoui \u003csahid.ferdjaoui@redhat.com\u003e"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"(cherry picked from commit d6a072b5c5a3ff9de7f4b42cda517ead17efe561)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Conflicts:"},{"line_number":27,"context_line":"\tnova/tests/unit/virt/libvirt/test_driver.py"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"9f6a8fd7_13881b1d","line":24,"updated":"2018-04-19 12:51:36.000000000","message":"For some reason this omitted the cherry-picked line from stable/pike:\n\n(cherry picked from commit ce531dd1b763704b9043ddde8e80ac99cd193660)\n\nI expected to see:\n\n(cherry picked from commit ce531dd1b763704b9043ddde8e80ac99cd193660)\n(cherry picked from commit d6a072b5c5a3ff9de7f4b42cda517ead17efe561)","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"9c5b0c4cac3c84b3cd7fdf277bac023f92bd6968","unresolved":false,"context_lines":[{"line_number":21,"context_line":"Closes-Bug: #1727260"},{"line_number":22,"context_line":"Signed-off-by: Sahid Orentino Ferdjaoui \u003csahid.ferdjaoui@redhat.com\u003e"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"(cherry picked from commit d6a072b5c5a3ff9de7f4b42cda517ead17efe561)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Conflicts:"},{"line_number":27,"context_line":"\tnova/tests/unit/virt/libvirt/test_driver.py"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"9f6a8fd7_76f9404b","line":24,"in_reply_to":"9f6a8fd7_13881b1d","updated":"2018-04-19 16:10:33.000000000","message":"That was me, I didn\u0027t realize we were supposed to leave both the cherry-pick lines.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"6ca6beedb6b7b7c6d804ab95e49d1a34bd89a760","unresolved":false,"context_lines":[{"line_number":1422,"context_line":"                                                             live\u003dlive)"},{"line_number":1423,"context_line":"            wait_for_detach()"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"            if encryption:"},{"line_number":1426,"context_line":"                encryptor \u003d self._get_volume_encryptor(connection_info,"},{"line_number":1427,"context_line":"                                                       encryption)"},{"line_number":1428,"context_line":"                encryptor.detach_volume(**encryption)"},{"line_number":1429,"context_line":""},{"line_number":1430,"context_line":"        except exception.InstanceNotFound:"},{"line_number":1431,"context_line":"            # NOTE(zhaoqin): If the instance does not exist, _lookup_by_name()"}],"source_content_type":"text/x-python","patch_set":2,"id":"bf659307_31cdc984","line":1428,"range":{"start_line":1425,"start_character":0,"end_line":1428,"end_character":53},"updated":"2018-04-12 16:54:36.000000000","message":"I\u0027m wondering whether this should be moved down to line 1453 so that if exception.DeviceNotFound is raised in guest.detach_device_with_retry() we would still try to run this code.  Hypothetically this change seems like it would be similar to what happens in stable/queens and newer where we call encryptor.detach_volume() from _disconnect_volume()","commit_id":"5363c97bf53c229bb9c0e4062fa48b913dd4043d"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"d344fdacc49a216cab8effd351858e9f64dad714","unresolved":false,"context_lines":[{"line_number":1450,"context_line":"            encryptor \u003d self._get_volume_encryptor(connection_info,"},{"line_number":1451,"context_line":"                                                   encryption)"},{"line_number":1452,"context_line":"            encryptor.detach_volume(**encryption)"},{"line_number":1453,"context_line":""},{"line_number":1454,"context_line":"        self._disconnect_volume(connection_info, disk_dev, instance)"},{"line_number":1455,"context_line":""},{"line_number":1456,"context_line":"    def extend_volume(self, connection_info, instance):"}],"source_content_type":"text/x-python","patch_set":3,"id":"bf659307_4c3786ff","line":1453,"updated":"2018-04-12 17:57:40.000000000","message":"Indeed, this is needed to ensure that we detach through the encryptor in the event that DeviceNotFound is raised from guest.detach_device_with_retry on L1420.\n\nSee an earlier version of the cherry-picked patch from before the encryptor-related refactoring happened:\n\nhttps://review.openstack.org/#/c/515008/8/nova/virt/libvirt/driver.py","commit_id":"0f5a3be609fb6cd38cc20fbb04137e87a3e03251"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"119e53f464a39a1abf65a4a4868e70852019f4e2","unresolved":false,"context_lines":[{"line_number":1450,"context_line":"            encryptor \u003d self._get_volume_encryptor(connection_info,"},{"line_number":1451,"context_line":"                                                   encryption)"},{"line_number":1452,"context_line":"            encryptor.detach_volume(**encryption)"},{"line_number":1453,"context_line":""},{"line_number":1454,"context_line":"        self._disconnect_volume(connection_info, disk_dev, instance)"},{"line_number":1455,"context_line":""},{"line_number":1456,"context_line":"    def extend_volume(self, connection_info, instance):"}],"source_content_type":"text/x-python","patch_set":3,"id":"bf659307_e7c23353","line":1453,"in_reply_to":"bf659307_4c3786ff","updated":"2018-04-12 18:10:19.000000000","message":"Also, I realized that we need a try-except around this to catch ProcessExecutionError and ignore exit code 4 to handle the scenario where we detached from the guest successfully, detached the encryptor successfully, but failed the compute host detach below. Then later someone retries the detach, DeviceNotFound will be raised and we\u0027ll ignore it BUT we\u0027ll get here and then os-brick will raise ProcessExecutionError because of a \"device unknown/not found\" because we already detached through the encryptor last time.\n\nSince we don\u0027t have [0] and [1] in our stable/pike requirements [2], we need to do this here:\n\n except processutils.ProcessExecutionError as e:\n       # cryptsetup returns 4 when attempting to destroy a non-existent\n       # dm-crypt device. It indicates that the device is invalid, which\n       # means that the device is invalid (i.e., it has already been\n       # destroyed).\n       if e.exit_code \u003d\u003d 4:\n            LOG.debug(\"Ignoring exit code 4, volume already destroyed\")\n       else:\n            with excutils.save_and_reraise_exception():\n                LOG.error(\"Could not disconnect encrypted volume \"\n                          \"%(volume)s. If dm-crypt device is still active \"\n                          \"it will have to be destroyed manually for \"\n                          \"cleanup to succeed.\", {\u0027volume\u0027: target})\n\n\n[0] https://review.openstack.org/#/c/527491\n[1] https://review.openstack.org/#/c/527490\n[2] https://git.openstack.org/cgit/openstack/nova/tree/requirements.txt?h\u003dstable/pike#n55","commit_id":"0f5a3be609fb6cd38cc20fbb04137e87a3e03251"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ae469eee0ff9e94ece05d368748fa0f86898e40f","unresolved":false,"context_lines":[{"line_number":1459,"context_line":"            if e.exit_code \u003d\u003d 4:"},{"line_number":1460,"context_line":"                LOG.debug(\"Ignoring exit code 4, volume already destroyed\")"},{"line_number":1461,"context_line":"            else:"},{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.error(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_45d8b051","line":1462,"updated":"2018-04-13 00:17:31.000000000","message":"I think the only thing missing now is test coverage of this case, ProcessExecutionError raised with exit_code !\u003d 4, that the exception will get propagated out of detach_volume.","commit_id":"8feec1a12415205b6b30cd17be70b8ecd3d1d43c"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"cc32bdfdc5b6b7dd5d251da962e0c3380a87aaf0","unresolved":false,"context_lines":[{"line_number":1459,"context_line":"            if e.exit_code \u003d\u003d 4:"},{"line_number":1460,"context_line":"                LOG.debug(\"Ignoring exit code 4, volume already destroyed\")"},{"line_number":1461,"context_line":"            else:"},{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.error(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_e2b8c575","line":1462,"in_reply_to":"bf659307_45d8b051","updated":"2018-04-13 15:30:33.000000000","message":"I wondered if you\u0027d want that. :)\nDone.","commit_id":"8feec1a12415205b6b30cd17be70b8ecd3d1d43c"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"27bcca6849b9e02184865558374ad6bae5dd9198","unresolved":false,"context_lines":[{"line_number":988,"context_line":"                encryption \u003d encryptors.get_encryption_metadata("},{"line_number":989,"context_line":"                    context, self._volume_api, volume_id, connection_info)"},{"line_number":990,"context_line":""},{"line_number":991,"context_line":"                if encryption:"},{"line_number":992,"context_line":"                    # The volume must be detached from the VM before"},{"line_number":993,"context_line":"                    # disconnecting it from its encryptor. Otherwise, the"},{"line_number":994,"context_line":"                    # encryptor may report that the volume is still in use."},{"line_number":995,"context_line":"                    encryptor \u003d self._get_volume_encryptor(connection_info,"},{"line_number":996,"context_line":"                                                           encryption)"},{"line_number":997,"context_line":"                    try:"},{"line_number":998,"context_line":"                        encryptor.detach_volume(**encryption)"},{"line_number":999,"context_line":"                    except processutils.ProcessExecutionError as e:"},{"line_number":1000,"context_line":"                        if e.exit_code \u003d\u003d 4:"},{"line_number":1001,"context_line":"                            LOG.debug(\u0027Ignoring exit code 4, volume already \u0027"},{"line_number":1002,"context_line":"                                      \u0027destroyed\u0027)"},{"line_number":1003,"context_line":"                        else:"},{"line_number":1004,"context_line":"                            with excutils.save_and_reraise_exception():"},{"line_number":1005,"context_line":"                                LOG.warning("},{"line_number":1006,"context_line":"                                    \u0027Could not disconnect encrypted volume \u0027"},{"line_number":1007,"context_line":"                                    \u0027%(volume)s. If the device is still \u0027"},{"line_number":1008,"context_line":"                                    \u0027active, it will have to destroyed \u0027"},{"line_number":1009,"context_line":"                                    \u0027manually for cleanup to succeed.\u0027,"},{"line_number":1010,"context_line":"                                    {\u0027volume\u0027: disk_dev})"},{"line_number":1011,"context_line":""},{"line_number":1012,"context_line":"            try:"},{"line_number":1013,"context_line":"                self._disconnect_volume(connection_info, disk_dev, instance)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_b3284fe2","line":1010,"range":{"start_line":991,"start_character":16,"end_line":1010,"end_character":57},"updated":"2018-04-19 12:51:36.000000000","message":"OK similar logic.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"27bcca6849b9e02184865558374ad6bae5dd9198","unresolved":false,"context_lines":[{"line_number":1453,"context_line":"                encryptor.detach_volume(**encryption)"},{"line_number":1454,"context_line":"        except processutils.ProcessExecutionError as e:"},{"line_number":1455,"context_line":"            # cryptsetup returns 4 when attempting to destroy a non-existent"},{"line_number":1456,"context_line":"            # dm-crypt device. It indicates that the device is invalid, which"},{"line_number":1457,"context_line":"            # means that the device is invalid (i.e., it has already been"},{"line_number":1458,"context_line":"            # destroyed)."},{"line_number":1459,"context_line":"            if e.exit_code \u003d\u003d 4:"},{"line_number":1460,"context_line":"                LOG.debug(\"Ignoring exit code 4, volume already destroyed\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_734957ce","line":1457,"range":{"start_line":1456,"start_character":31,"end_line":1457,"end_character":46},"updated":"2018-04-19 12:51:36.000000000","message":"Which means the device is invalid because the device is invalid, right? :)","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"27bcca6849b9e02184865558374ad6bae5dd9198","unresolved":false,"context_lines":[{"line_number":1460,"context_line":"                LOG.debug(\"Ignoring exit code 4, volume already destroyed\")"},{"line_number":1461,"context_line":"            else:"},{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.error(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""},{"line_number":1466,"context_line":"                              \"cleanup to succeed.\", {\u0027volume\u0027: disk_dev})"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_b36daf33","line":1463,"range":{"start_line":1463,"start_character":24,"end_line":1463,"end_character":29},"updated":"2018-04-19 12:51:36.000000000","message":"In the other place we do this, this is a warning rather than an error.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"9c5b0c4cac3c84b3cd7fdf277bac023f92bd6968","unresolved":false,"context_lines":[{"line_number":1460,"context_line":"                LOG.debug(\"Ignoring exit code 4, volume already destroyed\")"},{"line_number":1461,"context_line":"            else:"},{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.error(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""},{"line_number":1466,"context_line":"                              \"cleanup to succeed.\", {\u0027volume\u0027: disk_dev})"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_c1b648fb","line":1463,"range":{"start_line":1463,"start_character":24,"end_line":1463,"end_character":29},"in_reply_to":"9f6a8fd7_b36daf33","updated":"2018-04-19 16:10:33.000000000","message":"In nova.virt.libvirt.storage.delete_volume() it\u0027s an error...happy to go either way.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"27bcca6849b9e02184865558374ad6bae5dd9198","unresolved":false,"context_lines":[{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.error(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""},{"line_number":1466,"context_line":"                              \"cleanup to succeed.\", {\u0027volume\u0027: disk_dev})"},{"line_number":1467,"context_line":""},{"line_number":1468,"context_line":"        self._disconnect_volume(connection_info, disk_dev, instance)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_f38327cb","line":1465,"range":{"start_line":1465,"start_character":59,"end_line":1465,"end_character":61},"updated":"2018-04-19 12:51:36.000000000","message":"too many spaces","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dfca5c314bc53a646770527240da2d78302ee265","unresolved":false,"context_lines":[{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""},{"line_number":1466,"context_line":"                              \"cleanup to succeed.\", {\u0027volume\u0027: disk_dev})"},{"line_number":1467,"context_line":""},{"line_number":1468,"context_line":"        self._disconnect_volume(connection_info, disk_dev, instance)"},{"line_number":1469,"context_line":""},{"line_number":1470,"context_line":"    def extend_volume(self, connection_info, instance):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_d0ddb442","line":1467,"updated":"2018-04-19 14:41:50.000000000","message":"while I understand the situation and why you need to add more than just a single backport, I\u0027m super not confident because this makes a special case.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"28a08b562f4d684e35f2f1e588df881559ab7baf","unresolved":false,"context_lines":[{"line_number":1464,"context_line":"                              \"%(volume)s. If dm-crypt device is still active \""},{"line_number":1465,"context_line":"                              \"it will have to be destroyed  manually for \""},{"line_number":1466,"context_line":"                              \"cleanup to succeed.\", {\u0027volume\u0027: disk_dev})"},{"line_number":1467,"context_line":""},{"line_number":1468,"context_line":"        self._disconnect_volume(connection_info, disk_dev, instance)"},{"line_number":1469,"context_line":""},{"line_number":1470,"context_line":"    def extend_volume(self, connection_info, instance):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f6a8fd7_933f4624","line":1467,"in_reply_to":"9f6a8fd7_d0ddb442","updated":"2018-04-19 15:19:01.000000000","message":"I thought this was the correct way to backport changes that depend on e.g. os-brick functionality being that we can\u0027t bump upper-constraints on stable branches, so we can\u0027t consume os-brick backports.","commit_id":"28d5646bffe58e21b8cdf21463bdf9610379958c"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"8f454920c64dbfb9f7d3a5686a262176dcad1389","unresolved":false,"context_lines":[{"line_number":1461,"context_line":"            else:"},{"line_number":1462,"context_line":"                with excutils.save_and_reraise_exception():"},{"line_number":1463,"context_line":"                    LOG.warning(\"Could not disconnect encrypted volume \""},{"line_number":1464,"context_line":"                                \"%(volume)s. If dm-crypt device is still\""},{"line_number":1465,"context_line":"                                \"active it will have to be destroyed manually \""},{"line_number":1466,"context_line":"                                \"for cleanup to succeed.\","},{"line_number":1467,"context_line":"                                {\u0027volume\u0027: disk_dev})"},{"line_number":1468,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"9f6a8fd7_cc87580f","line":1465,"range":{"start_line":1464,"start_character":72,"end_line":1465,"end_character":39},"updated":"2018-04-19 20:04:27.000000000","message":"You\u0027re missing a space between these words.","commit_id":"450bf7407711d19a008fae16348158911bee17ac"}]}
