)]}'
{"nova/objects/image_meta.py":[{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"dd2e89ea74c4d83cd76653bffddb13aee247e446","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    def obj_make_compatible(self, primitive, target_version):"},{"line_number":175,"context_line":"        super(ImageMetaProps, self).obj_make_compatible(primitive,"},{"line_number":176,"context_line":"                                                        target_version)"},{"line_number":177,"context_line":"        target_version \u003d versionutils.convert_version_to_tuple(target_version)"},{"line_number":178,"context_line":"        if target_version \u003c (1, 19):"},{"line_number":179,"context_line":"            primitive.pop(\u0027img_hide_hypervisor_id\u0027, None)"},{"line_number":180,"context_line":"        if target_version \u003c (1, 16) and \u0027hw_watchdog_action\u0027 in primitive:"}],"source_content_type":"text/x-python","patch_set":2,"id":"bf659307_6ed8547a","line":177,"updated":"2018-03-30 06:40:29.000000000","message":"The following code should be added.\n\n        if target_version \u003c (1, 20):\n            primitive.pop(\u0027trait_fields\u0027, None)","commit_id":"b29a308648c7825aedb091ce2f05737c029183b7"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"009c21c03257aea002522c2d72c2898d7028c58d","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    def obj_make_compatible(self, primitive, target_version):"},{"line_number":175,"context_line":"        super(ImageMetaProps, self).obj_make_compatible(primitive,"},{"line_number":176,"context_line":"                                                        target_version)"},{"line_number":177,"context_line":"        target_version \u003d versionutils.convert_version_to_tuple(target_version)"},{"line_number":178,"context_line":"        if target_version \u003c (1, 19):"},{"line_number":179,"context_line":"            primitive.pop(\u0027img_hide_hypervisor_id\u0027, None)"},{"line_number":180,"context_line":"        if target_version \u003c (1, 16) and \u0027hw_watchdog_action\u0027 in primitive:"}],"source_content_type":"text/x-python","patch_set":2,"id":"bf659307_c4afffe0","line":177,"in_reply_to":"bf659307_6ed8547a","updated":"2018-03-30 08:23:45.000000000","message":"Done","commit_id":"b29a308648c7825aedb091ce2f05737c029183b7"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"9f5625f1033560cbf84fedaccc06726bd55fc11c","unresolved":false,"context_lines":[{"line_number":465,"context_line":"        # The traits associated with the image. Traits are expected to be"},{"line_number":466,"context_line":"        # defined as starting with `trait:` like below:"},{"line_number":467,"context_line":"        # trait:HW_CPU_X86_AVX2"},{"line_number":468,"context_line":"        \u0027trait_fields\u0027: fields.DictOfStringsField(nullable\u003dTrue),"},{"line_number":469,"context_line":"    }"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    # The keys are the legacy property names and"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_9cd397d5","line":468,"updated":"2018-03-30 17:47:36.000000000","message":"Please call this \"required_traits\" and make it a ListOfStringsField().\n\nAdd a note that says doing this:\n\n for trait in image_meta.required_traits:\n\nwill yield trait strings such as \u0027HW_CPU_X86_AVX2\u0027 (in order to make it clear to the user that the list of things returned are not prefixed with \u0027trait:\u0027","commit_id":"54e3f26449bc0e7ffc42982b8786874d0b056ce3"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"b0ea7946eb012b0fa88842b23b3bb689f3f0d553","unresolved":false,"context_lines":[{"line_number":465,"context_line":"        # The traits associated with the image. Traits are expected to be"},{"line_number":466,"context_line":"        # defined as starting with `trait:` like below:"},{"line_number":467,"context_line":"        # trait:HW_CPU_X86_AVX2"},{"line_number":468,"context_line":"        \u0027trait_fields\u0027: fields.DictOfStringsField(nullable\u003dTrue),"},{"line_number":469,"context_line":"    }"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    # The keys are the legacy property names and"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_4af8d179","line":468,"in_reply_to":"bf659307_9cd397d5","updated":"2018-03-30 20:13:53.000000000","message":"Done","commit_id":"54e3f26449bc0e7ffc42982b8786874d0b056ce3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"9f5625f1033560cbf84fedaccc06726bd55fc11c","unresolved":false,"context_lines":[{"line_number":560,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":561,"context_line":"        if image_props:"},{"line_number":562,"context_line":"            self.trait_fields \u003d {k: v for k, v in image_props.items()"},{"line_number":563,"context_line":"                             if str(k).startswith(\"trait:\")}"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    @classmethod"},{"line_number":566,"context_line":"    def from_dict(cls, image_props):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_fcfad340","line":563,"updated":"2018-03-30 17:47:36.000000000","message":"Couple things...\n\nUse six.text_type(k), not str(k) otherwise you\u0027ll run into Py3K issues.\n\nSecondly, add the following here:\n\n and six.text_type(v) \u003d\u003d six.text_type(\u0027required\u0027)","commit_id":"54e3f26449bc0e7ffc42982b8786874d0b056ce3"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"b0ea7946eb012b0fa88842b23b3bb689f3f0d553","unresolved":false,"context_lines":[{"line_number":560,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":561,"context_line":"        if image_props:"},{"line_number":562,"context_line":"            self.trait_fields \u003d {k: v for k, v in image_props.items()"},{"line_number":563,"context_line":"                             if str(k).startswith(\"trait:\")}"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    @classmethod"},{"line_number":566,"context_line":"    def from_dict(cls, image_props):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_2afb1d79","line":563,"in_reply_to":"bf659307_fcfad340","updated":"2018-03-30 20:13:53.000000000","message":"Done","commit_id":"54e3f26449bc0e7ffc42982b8786874d0b056ce3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2565763469efb26f7a81fd09efd1fb1d7e9cf7bd","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027trait_fields\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_ea56852a","line":228,"range":{"start_line":228,"start_character":7,"end_line":228,"end_character":19},"updated":"2018-03-30 20:35:03.000000000","message":"required_traits","commit_id":"0e3d89e8df9022c0641588d3970c49ed9df9e296"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"43e631204b22458cf112c3c2fb12d47d24bab707","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027trait_fields\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_05b3aa4e","line":228,"range":{"start_line":228,"start_character":7,"end_line":228,"end_character":19},"in_reply_to":"bf659307_ea56852a","updated":"2018-03-30 21:10:21.000000000","message":"Done","commit_id":"0e3d89e8df9022c0641588d3970c49ed9df9e296"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2565763469efb26f7a81fd09efd1fb1d7e9cf7bd","unresolved":false,"context_lines":[{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"},{"line_number":568,"context_line":"                 if six.text_type(k).startswith(\"trait:\") and six.text_type(v)"},{"line_number":569,"context_line":"                 \u003d\u003d six.text_type(\u0027required\u0027)})"},{"line_number":570,"context_line":""},{"line_number":571,"context_line":"    @classmethod"},{"line_number":572,"context_line":"    def from_dict(cls, image_props):"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_6a3835ed","line":569,"range":{"start_line":568,"start_character":56,"end_line":569,"end_character":47},"updated":"2018-03-30 20:35:03.000000000","message":"little style nit... would be easier to read this like so:\n\n if six.text_type(k).startswith(\"trait:\")\n and six.text_type(v) \u003d\u003d six.test_type(\u0027required\u0027)","commit_id":"0e3d89e8df9022c0641588d3970c49ed9df9e296"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"43e631204b22458cf112c3c2fb12d47d24bab707","unresolved":false,"context_lines":[{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"},{"line_number":568,"context_line":"                 if six.text_type(k).startswith(\"trait:\") and six.text_type(v)"},{"line_number":569,"context_line":"                 \u003d\u003d six.text_type(\u0027required\u0027)})"},{"line_number":570,"context_line":""},{"line_number":571,"context_line":"    @classmethod"},{"line_number":572,"context_line":"    def from_dict(cls, image_props):"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_a5851e5c","line":569,"range":{"start_line":568,"start_character":56,"end_line":569,"end_character":47},"in_reply_to":"bf659307_6a3835ed","updated":"2018-03-30 21:10:21.000000000","message":"Done","commit_id":"0e3d89e8df9022c0641588d3970c49ed9df9e296"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"57b339b297c0b1381d5d95b1f4f4869242b2e581","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_abb96fcc","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"updated":"2018-03-31 02:02:51.000000000","message":"Why is this \"if\" needed?","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"ec09d87537ee2f90d1000facf1c4446995937b63","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_eb73e714","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"in_reply_to":"bf659307_6b327760","updated":"2018-03-31 02:15:32.000000000","message":"I see, but should we check traits in image_props rather than image_props it self? if image_props is not None here, but no traits are included, we could end up with a self.required_traits \u003d []?","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a1a16519d4a3812ebe42f149a7cccee7c5e0f27e","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_dc7492d1","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"in_reply_to":"bf659307_8ba10b49","updated":"2018-04-02 21:24:21.000000000","message":"Agree that this if makes no sense, and you can assume image_props is non-None. However, I don\u0027t think that this belongs here, per below.","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"065ccce677e44366094cac24389020c218fdd873","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_6b327760","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"in_reply_to":"bf659307_abb96fcc","updated":"2018-03-31 02:07:14.000000000","message":"only if the image props are defined, we want the required_traits to be initialized.\n\nthe test_default_prop_value unit test ensures the required_traits is set to none when no properties are present.","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2f4fbff408f43a17abf818c4e592b42fc31a6699","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_424e5c38","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"in_reply_to":"bf659307_dc7492d1","updated":"2018-04-02 21:51:57.000000000","message":"Sorry, re-reading this I think the question is not about None-ness of the property, but just whether or not we end up setting anything on the object if none of the properties are traits. Right?\n\nThe logic around whether or not we should set required_traits\u003d[] (i.e. L565) shouldn\u0027t depend on the empty-ness or None-ness of image_props as you have it, but whether or not any traits are found. Thus, I think this should be like:\n\n for trait in [key[6:] for key, value in image_props.items()\n               if key.startswith(\u0027trait:\u0027) and value \u003d\u003d \u0027required\u0027]:\n     if \u0027required_traits\u0027 not in self:\n         self.required_traits \u003d []\n     trait_name \u003d get_trait_name(key)\n     self.require_traits.append(trait_name)\n\nsomething like that. We only get required_traits set if we actually encounter at least one required trait. That behaves more like all the above handlers, which I think is what we want.","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"79f64bd00f750a02b00714f7689e559e8ea8d208","unresolved":false,"context_lines":[{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        if image_props:"},{"line_number":565,"context_line":"            self.required_traits \u003d []"},{"line_number":566,"context_line":"            self.required_traits.extend("},{"line_number":567,"context_line":"                {six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_8ba10b49","line":564,"range":{"start_line":564,"start_character":8,"end_line":564,"end_character":23},"in_reply_to":"bf659307_eb73e714","updated":"2018-03-31 02:27:15.000000000","message":"Not sure i understand how you would check for traits within image_prop..to determine if there are valid traits in the image_props we have to go through them.\n\nwe could refactor to look for valid traits first and if and only if there are valid traits we initialize the self.required_traits...but not sure if there is any advantage to this.\n\nWe just want to make sure the required_traits are not initialized if there are no image_props.\n\nwe could also remove the if, and always intialize required_traits...\n\nare there any guidelines to the nova project wrt initialization of variables?","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a1a16519d4a3812ebe42f149a7cccee7c5e0f27e","unresolved":false,"context_lines":[{"line_number":587,"context_line":"        # associated with the current name takes priority"},{"line_number":588,"context_line":"        obj._set_attr_from_legacy_names(image_props)"},{"line_number":589,"context_line":"        obj._set_attr_from_current_names(image_props)"},{"line_number":590,"context_line":"        obj._set_attr_from_trait_names(image_props)"},{"line_number":591,"context_line":""},{"line_number":592,"context_line":"        return obj"},{"line_number":593,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_9c7a9ab7","line":590,"updated":"2018-04-02 21:24:21.000000000","message":"This method is for creating this object from a legacy dict. I don\u0027t think we need to add handling for new attributes that could never have existed in the old dict, right?","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2f4fbff408f43a17abf818c4e592b42fc31a6699","unresolved":false,"context_lines":[{"line_number":587,"context_line":"        # associated with the current name takes priority"},{"line_number":588,"context_line":"        obj._set_attr_from_legacy_names(image_props)"},{"line_number":589,"context_line":"        obj._set_attr_from_current_names(image_props)"},{"line_number":590,"context_line":"        obj._set_attr_from_trait_names(image_props)"},{"line_number":591,"context_line":""},{"line_number":592,"context_line":"        return obj"},{"line_number":593,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_026624c2","line":590,"in_reply_to":"bf659307_9c7a9ab7","updated":"2018-04-02 21:51:57.000000000","message":"Ignore this.","commit_id":"cdb7e8f737a67983439113bdb853a6d8507d007d"},{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"3b05d39c4cba1e1bd1ae9c83ffd8707ad73feef0","unresolved":false,"context_lines":[{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import copy"},{"line_number":16,"context_line":"import six"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import versionutils"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_8cb4a281","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":10},"updated":"2018-04-03 09:08:42.000000000","message":"nit: It should be just after line 18.\n\nhttps://docs.openstack.org/hacking/latest/user/hacking.html#imports","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"ffea51fac9f1a37542dcb1aed265064f0b4d2453","unresolved":false,"context_lines":[{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import copy"},{"line_number":16,"context_line":"import six"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import versionutils"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_bb166fa7","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":10},"in_reply_to":"bf659307_8cb4a281","updated":"2018-04-03 22:27:36.000000000","message":"Done","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"dd227c64074c629e200169d1e01793e1bdb8243f","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027required_traits\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_d51f7269","line":228,"updated":"2018-04-03 15:58:15.000000000","message":"I wonder if we should prefix this with sch_ to match the other attributes, which are all scoped? We\u0027ll likely have sch_preferred_traits at some point, and maybe other related things.","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"3c57673ae8f501250a3ab74e2ba5a4f5aec585ad","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027required_traits\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_efcc0c8a","line":228,"in_reply_to":"bf659307_c73ca194","updated":"2018-04-04 13:52:34.000000000","message":"\u003e They\u0027re not scheduler-specific, though. They\u0027re just traits,\n \u003e nothing more.\n\nThese are properties of an image. They\u0027re traits that are \"required\". The only time that requiredness could be enforced is _during_scheduling_. If they\u0027re \"just traits\" then this should be called \"traits\", but we know that won\u0027t convey what we need.\n\nMy OCD also won\u0027t let me introduce a non-namespaced thing to a nicely namespaced object, especially when we know we have another one coming. How about \"traits_required\" so that when we add preferred we can do \"traits_preferred\" ?","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"ffea51fac9f1a37542dcb1aed265064f0b4d2453","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027required_traits\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_a74e4d94","line":228,"in_reply_to":"bf659307_c73ca194","updated":"2018-04-03 22:27:36.000000000","message":"Done","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cb20bc3dc38d44286fc3d0e8ac3ab94a208f16f4","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027required_traits\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_c73ca194","line":228,"in_reply_to":"bf659307_d51f7269","updated":"2018-04-03 21:54:19.000000000","message":"They\u0027re not scheduler-specific, though. They\u0027re just traits, nothing more. I mean, the traits themselves have namespaces (like HW_, etc) but the trait: prefix is nothing more than indicating that what is stored in the key part of the image property is a trait string...\n\nFrankly, unlike other oslo versioned objects, the fields in ImageMeta and ImageMetaProps don\u0027t store anything in the database so these objects are used as nothing more than a facade to \"standardize\" certain known key-value pairs.","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2ab03915390c4eb537600d010f814ccac30b0e54","unresolved":false,"context_lines":[{"line_number":225,"context_line":"    # \u0027hw_\u0027 - settings affecting the guest virtual machine hardware"},{"line_number":226,"context_line":"    # \u0027img_\u0027 - settings affecting the use of images by the compute node"},{"line_number":227,"context_line":"    # \u0027os_\u0027 - settings affecting the guest operating system setup"},{"line_number":228,"context_line":"    # \u0027required_traits\u0027 - Traits associated with the image."},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"    fields \u003d {"},{"line_number":231,"context_line":"        # name of guest hardware architecture eg i686, x86_64, ppc64"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf659307_4ab06a8c","line":228,"in_reply_to":"bf659307_efcc0c8a","updated":"2018-04-05 16:25:04.000000000","message":"traits_required and traits_preferred works for me, Dan.","commit_id":"f3770b74622f6f06d275dd61b6bd3c648830d62d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"02936367af3ce9b4aafc202f3df2b26821e3c3d5","unresolved":false,"context_lines":[{"line_number":465,"context_line":""},{"line_number":466,"context_line":"        # The required traits associated with the image. Traits are expected to"},{"line_number":467,"context_line":"        # be defined as starting with `trait:` like below:"},{"line_number":468,"context_line":"        # trait:HW_CPU_X86_AVX2"},{"line_number":469,"context_line":"        # for trait in image_meta.traits_required:"},{"line_number":470,"context_line":"        # will yield trait strings such as \u0027HW_CPU_X86_AVX2\u0027"},{"line_number":471,"context_line":"        \u0027traits_required\u0027: fields.ListOfStringsField(),"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_a081254d","line":468,"range":{"start_line":468,"start_character":10,"end_line":468,"end_character":31},"updated":"2018-04-05 17:43:06.000000000","message":"From the spec, this should be \"trait:HW_CPU_X86_AVX2\u003drequired\". And that\u0027s how the parsing logic below works too. So this should be updated.","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"ae0fcedc6dba306f044175b18d4dbad878ed5629","unresolved":false,"context_lines":[{"line_number":465,"context_line":""},{"line_number":466,"context_line":"        # The required traits associated with the image. Traits are expected to"},{"line_number":467,"context_line":"        # be defined as starting with `trait:` like below:"},{"line_number":468,"context_line":"        # trait:HW_CPU_X86_AVX2"},{"line_number":469,"context_line":"        # for trait in image_meta.traits_required:"},{"line_number":470,"context_line":"        # will yield trait strings such as \u0027HW_CPU_X86_AVX2\u0027"},{"line_number":471,"context_line":"        \u0027traits_required\u0027: fields.ListOfStringsField(),"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_40f7e9d5","line":468,"range":{"start_line":468,"start_character":10,"end_line":468,"end_character":31},"in_reply_to":"bf659307_a081254d","updated":"2018-04-05 18:20:31.000000000","message":"Done","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"ee5046e884ba7624dc31af6bb6749d69db46256c","unresolved":false,"context_lines":[{"line_number":465,"context_line":""},{"line_number":466,"context_line":"        # The required traits associated with the image. Traits are expected to"},{"line_number":467,"context_line":"        # be defined as starting with `trait:` like below:"},{"line_number":468,"context_line":"        # trait:HW_CPU_X86_AVX2"},{"line_number":469,"context_line":"        # for trait in image_meta.traits_required:"},{"line_number":470,"context_line":"        # will yield trait strings such as \u0027HW_CPU_X86_AVX2\u0027"},{"line_number":471,"context_line":"        \u0027traits_required\u0027: fields.ListOfStringsField(),"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_c0d1b931","line":468,"range":{"start_line":468,"start_character":10,"end_line":468,"end_character":31},"in_reply_to":"bf659307_a081254d","updated":"2018-04-05 17:51:25.000000000","message":"That is the key part, not the value. The value is \"required\".","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"02936367af3ce9b4aafc202f3df2b26821e3c3d5","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                self._set_numa_mem(image_props)"},{"line_number":555,"context_line":"            elif key \u003d\u003d \"hw_numa_cpus\":"},{"line_number":556,"context_line":"                self._set_numa_cpus(image_props)"},{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                if key not in image_props:"},{"line_number":559,"context_line":"                    continue"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        for trait in [six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_c0d0d956","line":561,"range":{"start_line":557,"start_character":12,"end_line":561,"end_character":52},"updated":"2018-04-05 17:43:06.000000000","message":"Doesn\u0027t this mean I could specify something like:\n\n  traits_required\u003dfoo\n\nIn image metadata and it would set set here, but blow up since it\u0027s not a list?","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"f4732edc2144990634686be13aaaba4d69dbddb5","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                self._set_numa_mem(image_props)"},{"line_number":555,"context_line":"            elif key \u003d\u003d \"hw_numa_cpus\":"},{"line_number":556,"context_line":"                self._set_numa_cpus(image_props)"},{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                if key not in image_props:"},{"line_number":559,"context_line":"                    continue"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        for trait in [six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_f4183c85","line":561,"range":{"start_line":557,"start_character":12,"end_line":561,"end_character":52},"in_reply_to":"bf659307_a07045de","updated":"2018-04-05 21:36:36.000000000","message":"fixed it by skipping when \u0027traits_required\u0027 is encountered as a key.\n\nBut the problem remains for the other fields.","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"936c7234f417ddabd192bbba0ffb02a214683ca8","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                self._set_numa_mem(image_props)"},{"line_number":555,"context_line":"            elif key \u003d\u003d \"hw_numa_cpus\":"},{"line_number":556,"context_line":"                self._set_numa_cpus(image_props)"},{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                if key not in image_props:"},{"line_number":559,"context_line":"                    continue"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        for trait in [six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_005331e4","line":561,"range":{"start_line":557,"start_character":12,"end_line":561,"end_character":52},"in_reply_to":"bf659307_c0d0d956","updated":"2018-04-05 17:43:39.000000000","message":"Should at least have a unit test for this.","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"ae0fcedc6dba306f044175b18d4dbad878ed5629","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                self._set_numa_mem(image_props)"},{"line_number":555,"context_line":"            elif key \u003d\u003d \"hw_numa_cpus\":"},{"line_number":556,"context_line":"                self._set_numa_cpus(image_props)"},{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                if key not in image_props:"},{"line_number":559,"context_line":"                    continue"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        for trait in [six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_a07045de","line":561,"range":{"start_line":557,"start_character":12,"end_line":561,"end_character":52},"in_reply_to":"bf659307_c0d0d956","updated":"2018-04-05 18:20:31.000000000","message":"isnt this the same problem with other fields like img_mappings, img_block_device_mapping which are complex datatypes like ListOfDictOfNullableStringsField etc?\n\nI can create bug to handle the above..if you want me to fix as part of this change, i am open to suggestions.","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6ec3a47a88fb3b76ba0ba3242e30bf5581013459","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                self._set_numa_mem(image_props)"},{"line_number":555,"context_line":"            elif key \u003d\u003d \"hw_numa_cpus\":"},{"line_number":556,"context_line":"                self._set_numa_cpus(image_props)"},{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                if key not in image_props:"},{"line_number":559,"context_line":"                    continue"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"                setattr(self, key, image_props[key])"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def _set_attr_from_trait_names(self, image_props):"},{"line_number":564,"context_line":"        for trait in [six.text_type(k[6:]) for k, v in image_props.items()"}],"source_content_type":"text/x-python","patch_set":12,"id":"bf659307_fafd8508","line":561,"range":{"start_line":557,"start_character":12,"end_line":561,"end_character":52},"in_reply_to":"bf659307_f4183c85","updated":"2018-04-05 22:45:24.000000000","message":"I think those other fields are coerced properly because I know that the block_device_mapping legacy field is used for image-defined BDMs in tempest scenarios, and set into the snapshot image metadata when taking a volume-backed instance snapshot:\n\nhttps://github.com/openstack/nova/blob/63e10f4321ea18a5b5494d56f5f73e160624d938/nova/compute/api.py#L2953\n\nSo you make a good point, and I\u0027m not sure if it would work to directly specify something like \"traits_required\u003d[\u0027CUSTOM_FOO\u0027]\". If we were going to support it, you\u0027d need a test either way to confirm it works.","commit_id":"f71ec495ebfbf24226d72df32ca1021c5da674e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e641d0a4ee0589e972681bd81d453c52a998c461","unresolved":false,"context_lines":[{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                # traits_required will be populated by"},{"line_number":559,"context_line":"                # _set_attr_from_trait_names"},{"line_number":560,"context_line":"                if key not in image_props or key \u003d\u003d \"traits_required\":"},{"line_number":561,"context_line":"                    continue"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"                setattr(self, key, image_props[key])"}],"source_content_type":"text/x-python","patch_set":14,"id":"bf659307_2fd5efb9","line":560,"updated":"2018-04-06 17:06:11.000000000","message":"Just so we\u0027re clear, this means I can\u0027t define an image with both a \"traits_required\" property and also individual \"trait:\u003cfoo\u003e\" properties and expect nova to merge them all. Using \u0027traits_required\u0027 in image meta is, in other words, not supported. It\u0027s not an error, but we\u0027ll ignore it in nova, and obviously wouldn\u0027t document it\u0027s usage in the glance docs:\n\nhttps://docs.openstack.org/python-glanceclient/latest/cli/property-keys.html","commit_id":"124a7d8cc6a9b0495ac4aa5b8e208b6613de74cd"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"4968cce1c0d8a1aaf8f625d5ba52cb0ccf3fec0c","unresolved":false,"context_lines":[{"line_number":557,"context_line":"            else:"},{"line_number":558,"context_line":"                # traits_required will be populated by"},{"line_number":559,"context_line":"                # _set_attr_from_trait_names"},{"line_number":560,"context_line":"                if key not in image_props or key \u003d\u003d \"traits_required\":"},{"line_number":561,"context_line":"                    continue"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"                setattr(self, key, image_props[key])"}],"source_content_type":"text/x-python","patch_set":14,"id":"bf659307_3abbebe5","line":560,"in_reply_to":"bf659307_2fd5efb9","updated":"2018-04-06 17:41:18.000000000","message":"\u003e Just so we\u0027re clear, this means I can\u0027t define an image with both a\n \u003e \"traits_required\" property and also individual \"trait:\u003cfoo\u003e\"\n \u003e properties and expect nova to merge them all. Using\n \u003e \u0027traits_required\u0027 in image meta is, in other words, not supported.\n \u003e It\u0027s not an error, but we\u0027ll ignore it in nova, and obviously\n \u003e wouldn\u0027t document it\u0027s usage in the glance docs:\n \u003e \n \u003e https://docs.openstack.org/python-glanceclient/latest/cli/property-keys.html\n\nyup. i think its a very remote edge case that folks want to use the exact field name and is easily remedied by using a pre-fix/suffix.\n\nwe will only support the \"trait:\" format for images and will document the same that all required traits on flavor and images will be merged by nova.","commit_id":"124a7d8cc6a9b0495ac4aa5b8e208b6613de74cd"}],"nova/tests/unit/objects/test_image_meta.py":[{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"dd2e89ea74c4d83cd76653bffddb13aee247e446","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        self.assertIsNone(virtprops.trait_fields.get(\u0027trait1:CUSTOM_FPGA\u0027))"},{"line_number":301,"context_line":"        self.assertIsNone(virtprops.trait_fields.get(\u0027trai:CUSTOM_FOO\u0027))"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"    def test_obj_make_compatible(self):"},{"line_number":304,"context_line":"        props \u003d {"},{"line_number":305,"context_line":"            \u0027hw_firmware_type\u0027: \u0027uefi\u0027,"},{"line_number":306,"context_line":"            \u0027hw_cpu_realtime_mask\u0027: \u0027^0-1\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"bf659307_2ecedcb3","line":303,"range":{"start_line":303,"start_character":7,"end_line":303,"end_character":32},"updated":"2018-03-30 06:40:29.000000000","message":"This test should be modified.","commit_id":"b29a308648c7825aedb091ce2f05737c029183b7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"4482fcb7659baa6c199721a3a25ddfcaa791daba","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        virtprops \u003d objects.ImageMetaProps.from_dict(props)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        self.assertIsInstance(virtprops.traits_required, list)"},{"line_number":321,"context_line":"        self.assertIn(\u0027CUSTOM_TRUSTED\u0027, virtprops.traits_required)"},{"line_number":322,"context_line":"        self.assertIn(\u0027HW_CPU_X86_AVX2\u0027, virtprops.traits_required)"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    def test_obj_make_compatible(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"bf659307_da2521ad","line":321,"updated":"2018-04-05 22:47:48.000000000","message":"Should probably also assert that virtprops.traits_required is length 2, or assert that \u0027foo\u0027 isn\u0027t in virtprops.traits_required.","commit_id":"f23405e6cba565ba3ed1064af8284723cdb78de8"},{"author":{"_account_id":17190,"name":"Arvind Nadendla","email":"arvindn05@gmail.com","username":"arvindn05"},"change_message_id":"f0951f24014e55c9853d7f6606615a4ffc957752","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        virtprops \u003d objects.ImageMetaProps.from_dict(props)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        self.assertIsInstance(virtprops.traits_required, list)"},{"line_number":321,"context_line":"        self.assertIn(\u0027CUSTOM_TRUSTED\u0027, virtprops.traits_required)"},{"line_number":322,"context_line":"        self.assertIn(\u0027HW_CPU_X86_AVX2\u0027, virtprops.traits_required)"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    def test_obj_make_compatible(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"bf659307_5aa83176","line":321,"in_reply_to":"bf659307_da2521ad","updated":"2018-04-05 23:16:14.000000000","message":"Done","commit_id":"f23405e6cba565ba3ed1064af8284723cdb78de8"}]}
