)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"bd9e90238493aa2e087d24df30c678ae196daef4","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     LuyaoZhong \u003cluyao.zhong@intel.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-09-03 06:21:27 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"object: Introduce Resource and ResouceList objs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Introduce Resource and ResouceList objects, and add new resources"},{"line_number":10,"context_line":"field to instance, also old_/new_ resources fields to migration_context,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"7faddb67_a20e5ce1","line":7,"range":{"start_line":7,"start_character":31,"end_line":7,"end_character":38},"updated":"2019-09-03 15:56:36.000000000","message":"Resource","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"}],"nova/objects/base.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"88d9c4fd6e7b0d199e6e0393d59ed02697a8a439","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_ec20a69c","line":34,"updated":"2019-09-05 04:26:21.000000000","message":"they are totally same https://github.com/openstack/nova/blob/master/nova/objects/numa.py#L24?\n\nCan we remove that duplicated one in numa.py?","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"c0c1776e10027b4678a44baf302dde1652ea45af","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_825f793f","line":34,"in_reply_to":"7faddb67_ec20a69c","updated":"2019-09-05 10:31:18.000000000","message":"Done","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_e5f36972","line":34,"updated":"2019-09-10 14:22:47.000000000","message":"It shouldn\u0027t block this, but I\u0027ve restored [1] so we don\u0027t need to do this going forward. However, this should have been done separately\n\n[1] https://review.opendev.org/#/c/472285/","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_931751a4","line":34,"in_reply_to":"5faad753_e5f36972","updated":"2019-09-11 08:02:15.000000000","message":"it\u0027s not a problem I think. just handle the merge conflict if one of them is merged.","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"57c4934a9b929eaae4888efd20a63bab5bfe4b50","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"5faad753_643d04c3","line":34,"range":{"start_line":34,"start_character":4,"end_line":34,"end_character":20},"updated":"2019-09-12 13:08:16.000000000","message":"im not clear why this is needed.\nare you trying to work around the fact that by default the equality operator check if any of the fields are marked as changed?\n\nby the way the first check of equality is normal are the object the same type which is not checked here at all.\n\nif we have two different ovo with the same filed this will pass which is wrong.\n\nit will also pass if you comapre a base class to it children\nif the bas class is the first argument but not the other way around so this is not symentic \n\nmeaning a \u003d\u003d b will not be the same as b \u003d\u003d a in this implementation in all cases.","commit_id":"6568bf6c2de645347452d2a472778439c0a9ee91"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e72e4aef6edce12444c45484ca7b99109380ad9d","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"5faad753_64dc24e4","line":34,"range":{"start_line":34,"start_character":4,"end_line":34,"end_character":20},"in_reply_to":"5faad753_4472484b","updated":"2019-09-12 13:40:47.000000000","message":"they would be equivalent but generally not considered equal\nbut ill change my vote to +1 for now and file a bug to fix this for both uses.\n\nper\n\nhttps://www.python.org/dev/peps/pep-0207/#proposed-resolutions\n\nwhen inmplematning __eq__ for \u003d\u003d the interperter is allowed to swap the argument. so while its proably safe to assume that  obj_a is always not none it is not safe to assume that obj_a was the operand on the left hand side of the \u003d\u003d.\n\nas a result, when used to implemnt __eq__ the behavior of this could still change between python version and implementations. \n\nas i said ill file a bug to harden this and will not block on it now, it will work for our current needs.","commit_id":"6568bf6c2de645347452d2a472778439c0a9ee91"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"76ae6f215e994db204e007184058c708d10919e5","unresolved":false,"context_lines":[{"line_number":31,"context_line":"from nova import utils"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"5faad753_4472484b","line":34,"range":{"start_line":34,"start_character":4,"end_line":34,"end_character":20},"in_reply_to":"5faad753_643d04c3","updated":"2019-09-12 13:20:31.000000000","message":"We care about none of these things.\n\nIf they\u0027re \"different\" objects (subclasses or unrelated) but have the same fields with the same values, they *should* evaluate to equal.\n\nThis is copied in from numa.py for reuse (and that one is moved later). No new invention here.\n\nIf it\u0027s wrong, that should be fixed independently.","commit_id":"6568bf6c2de645347452d2a472778439c0a9ee91"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"57c4934a9b929eaae4888efd20a63bab5bfe4b50","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    for name in obj_a.fields:"},{"line_number":39,"context_line":"        set_a \u003d name in obj_a"}],"source_content_type":"text/x-python","patch_set":21,"id":"5faad753_84112055","line":36,"range":{"start_line":35,"start_character":4,"end_line":36,"end_character":20},"updated":"2019-09-12 13:08:16.000000000","message":"if obj_a was none and obj_b is none the this should return true but it wont\n\nthis is another case wehere a \u003d\u003d b will not be the same as b \u003d\u003d a\n\nthis is not a good implementation of equal.","commit_id":"6568bf6c2de645347452d2a472778439c0a9ee91"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"76ae6f215e994db204e007184058c708d10919e5","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":35,"context_line":"    if obj_b is None:"},{"line_number":36,"context_line":"        return False"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    for name in obj_a.fields:"},{"line_number":39,"context_line":"        set_a \u003d name in obj_a"}],"source_content_type":"text/x-python","patch_set":21,"id":"5faad753_84a12097","line":36,"range":{"start_line":35,"start_character":4,"end_line":36,"end_character":20},"in_reply_to":"5faad753_84112055","updated":"2019-09-12 13:20:31.000000000","message":"It\u0027s not an implementation of equal. It\u0027s an implementation of \"are all the fields the same\". When it\u0027s used to implement __eq__, obj_a is never None, so in that case it is valid too.","commit_id":"6568bf6c2de645347452d2a472778439c0a9ee91"}],"nova/objects/fields.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"1167eb9146e59dd83019520d253c6389b442af81","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    PATTERN \u003d r\u0027(^CUSTOM_)\u0027"},{"line_number":97,"context_line":"    for rclass in orc.STANDARDS:"},{"line_number":98,"context_line":"        PATTERN +\u003d (r\u0027|(^%s$)\u0027 % rclass)"},{"line_number":99,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @staticmethod"},{"line_number":102,"context_line":"    def coerce(obj, attr, value):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_e90df8e6","line":99,"range":{"start_line":96,"start_character":3,"end_line":99,"end_character":32},"updated":"2019-09-05 02:53:58.000000000","message":"I don\u0027t think we can do this standard rc validation. I think we can just copy this generic RC pattern https://github.com/openstack/placement/blob/master/placement/schemas/common.py#L19\n\nThe reason is that when we upgrade the cluster, we may transfer the object between old and new node, the old node my use old version os-resource-class lib, that means the old node doesn\u0027t know the new RC. So the deserialization will blowup. This is different with new field for version object, the conductor can strip that new field for old node. So I think this won\u0027t work.","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"c0c1776e10027b4678a44baf302dde1652ea45af","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    PATTERN \u003d r\u0027(^CUSTOM_)\u0027"},{"line_number":97,"context_line":"    for rclass in orc.STANDARDS:"},{"line_number":98,"context_line":"        PATTERN +\u003d (r\u0027|(^%s$)\u0027 % rclass)"},{"line_number":99,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @staticmethod"},{"line_number":102,"context_line":"    def coerce(obj, attr, value):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_427c21b5","line":99,"range":{"start_line":96,"start_character":3,"end_line":99,"end_character":32},"in_reply_to":"7faddb67_e90df8e6","updated":"2019-09-05 10:31:18.000000000","message":"Done","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"03c216d3daac80e2106df70779ab0404b0f0596d","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @staticmethod"},{"line_number":102,"context_line":"    def coerce(obj, attr, value):"},{"line_number":103,"context_line":"        if isinstance(value, six.string_types):"},{"line_number":104,"context_line":"            uppered \u003d value.upper()"},{"line_number":105,"context_line":"            if ResourceClass._REGEX.match(uppered):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_e9b418f3","line":102,"updated":"2019-09-05 03:06:51.000000000","message":"and we need unit test","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"c0c1776e10027b4678a44baf302dde1652ea45af","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @staticmethod"},{"line_number":102,"context_line":"    def coerce(obj, attr, value):"},{"line_number":103,"context_line":"        if isinstance(value, six.string_types):"},{"line_number":104,"context_line":"            uppered \u003d value.upper()"},{"line_number":105,"context_line":"            if ResourceClass._REGEX.match(uppered):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_c241f164","line":102,"in_reply_to":"7faddb67_e9b418f3","updated":"2019-09-05 10:31:18.000000000","message":"Add unittests for setting malformed resource_class field to Resource obj.","commit_id":"ad189639d372e5e19309154faa49563b13980de1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_65ff7934","line":95,"range":{"start_line":95,"start_character":21,"end_line":95,"end_character":22},"updated":"2019-09-10 14:22:47.000000000","message":"This isn\u0027t needed","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_3300dd67","line":95,"range":{"start_line":95,"start_character":21,"end_line":95,"end_character":22},"in_reply_to":"5faad753_65ff7934","updated":"2019-09-11 08:02:15.000000000","message":"Done","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_c5950de6","line":96,"range":{"start_line":96,"start_character":14,"end_line":96,"end_character":15},"updated":"2019-09-10 14:22:47.000000000","message":"neither is this","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"},{"line_number":100,"context_line":"    def coerce(obj, attr, value):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_45603d02","line":97,"range":{"start_line":95,"start_character":0,"end_line":97,"end_character":32},"updated":"2019-09-10 14:22:47.000000000","message":"Why not just:\n\n  _REGEX \u003d re.compile(\u0027^[A-Z0-9_]+$\u0027)\n\nI\u0027m not sure what splitting this out gets us. It\u0027s a simple alphanumeric+underscore check","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"},{"line_number":100,"context_line":"    def coerce(obj, attr, value):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_73b895c7","line":97,"range":{"start_line":95,"start_character":0,"end_line":97,"end_character":32},"in_reply_to":"5faad753_45603d02","updated":"2019-09-11 08:02:15.000000000","message":"refer to https://github.com/openstack/oslo.versionedobjects/blob/master/oslo_versionedobjects/fields.py#L387.\n\nwill drop _RC_TRAIT_CHAR, just keep PATTERN here.","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"8383ccf7a69b39d81414b1ead94880e240853e53","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    _RC_TRAIT_CHAR \u003d r\"[A-Z0-9_]\""},{"line_number":96,"context_line":"    PATTERN \u003d r\"^%s+$\" % _RC_TRAIT_CHAR"},{"line_number":97,"context_line":"    _REGEX \u003d re.compile(PATTERN)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"},{"line_number":100,"context_line":"    def coerce(obj, attr, value):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_0e456617","line":97,"range":{"start_line":95,"start_character":0,"end_line":97,"end_character":32},"in_reply_to":"5faad753_73b895c7","updated":"2019-09-11 16:12:03.000000000","message":"Thanks for the pointer :)","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            uppered \u003d value.upper()"},{"line_number":103,"context_line":"            if ResourceClass._REGEX.match(uppered):"},{"line_number":104,"context_line":"                return uppered"},{"line_number":105,"context_line":"        raise ValueError(_(\"Malformed Resource Class %s\") % (value,))"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"class ResourceClassField(AutoTypedField):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_6520d9b1","line":105,"range":{"start_line":105,"start_character":60,"end_line":105,"end_character":68},"updated":"2019-09-10 14:22:47.000000000","message":"style nit: s/(value,)/value/","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            uppered \u003d value.upper()"},{"line_number":103,"context_line":"            if ResourceClass._REGEX.match(uppered):"},{"line_number":104,"context_line":"                return uppered"},{"line_number":105,"context_line":"        raise ValueError(_(\"Malformed Resource Class %s\") % (value,))"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"class ResourceClassField(AutoTypedField):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_f3d005fa","line":105,"range":{"start_line":105,"start_character":60,"end_line":105,"end_character":68},"in_reply_to":"5faad753_6520d9b1","updated":"2019-09-11 08:02:15.000000000","message":"Done","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"8383ccf7a69b39d81414b1ead94880e240853e53","unresolved":false,"context_lines":[{"line_number":90,"context_line":"IPV6Network \u003d fields.IPV6Network"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class ResourceClass(fields.StringPattern):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    PATTERN \u003d r\"^[A-Z0-9_]+$\""},{"line_number":96,"context_line":"    _REGEX \u003d re.compile(PATTERN)"}],"source_content_type":"text/x-python","patch_set":20,"id":"5faad753_09bc8067","line":93,"range":{"start_line":93,"start_character":6,"end_line":93,"end_character":19},"updated":"2019-09-11 16:12:03.000000000","message":"I should have said this before, but can we call this SlugField instead? There\u0027s nothing specific to resources about this and by calling it SlugField we can easily reuse it later (it would make for a nice addition to oslo.versioned_objects in the future, actually)","commit_id":"02ac062d8f28d79c90538aa654150685143b1542"}],"nova/objects/instance.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f73e76fc2f4b14b6cb0429be0cbf3899e9e240d7","unresolved":false,"context_lines":[{"line_number":612,"context_line":"                trusted_certs.obj_to_primitive())"},{"line_number":613,"context_line":"        else:"},{"line_number":614,"context_line":"            updates[\u0027extra\u0027][\u0027trusted_certs\u0027] \u003d None"},{"line_number":615,"context_line":"        resources \u003d updates.pop(\u0027resources\u0027, None)"},{"line_number":616,"context_line":"        expected_attrs.append(\u0027resources\u0027)"},{"line_number":617,"context_line":"        if resources:"},{"line_number":618,"context_line":"            updates[\u0027extra\u0027][\u0027resources\u0027] \u003d jsonutils.dumps("},{"line_number":619,"context_line":"                resources.obj_to_primitive())"},{"line_number":620,"context_line":"        else:"},{"line_number":621,"context_line":"            updates[\u0027extra\u0027][\u0027resources\u0027] \u003d None"},{"line_number":622,"context_line":"        db_inst \u003d db.instance_create(self._context, updates)"},{"line_number":623,"context_line":"        self._from_db_object(self._context, self, db_inst, expected_attrs)"},{"line_number":624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_73caa74f","line":621,"range":{"start_line":615,"start_character":0,"end_line":621,"end_character":48},"updated":"2019-08-30 10:44:05.000000000","message":"I think we\u0027ve enough instances of this to add a helper method to do this for us. Something like:\n\n    def _create_extra_field(self, updates, field, obj_cls):\n        ...\n\nBut that\u0027s a cleanup for later","commit_id":"ea9e3a964bfeca5fcc83957a12a770c4d9dd9748"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":497,"context_line":"                instance._load_resources("},{"line_number":498,"context_line":"                    db_inst[\u0027extra\u0027].get(\u0027resources\u0027))"},{"line_number":499,"context_line":"            else:"},{"line_number":500,"context_line":"                instance.resources \u003d None"},{"line_number":501,"context_line":"        if any([x in expected_attrs for x in (\u0027flavor\u0027,"},{"line_number":502,"context_line":"                                              \u0027old_flavor\u0027,"},{"line_number":503,"context_line":"                                              \u0027new_flavor\u0027)]):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_8009432d","line":500,"updated":"2019-09-10 14:22:47.000000000","message":"as noted previously, I\u0027d really like a follow-up to standardize how we\u0027re doing this because it\u0027s pretty duplicated now","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":497,"context_line":"                instance._load_resources("},{"line_number":498,"context_line":"                    db_inst[\u0027extra\u0027].get(\u0027resources\u0027))"},{"line_number":499,"context_line":"            else:"},{"line_number":500,"context_line":"                instance.resources \u003d None"},{"line_number":501,"context_line":"        if any([x in expected_attrs for x in (\u0027flavor\u0027,"},{"line_number":502,"context_line":"                                              \u0027old_flavor\u0027,"},{"line_number":503,"context_line":"                                              \u0027new_flavor\u0027)]):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_d3d5c9e6","line":500,"in_reply_to":"5faad753_8009432d","updated":"2019-09-11 08:02:15.000000000","message":"Agree, I prefer another patch not in this patch series, I\u0027ll do that if I have time.","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"}],"nova/objects/numa.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":21,"context_line":"from nova.virt import hardware"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":25,"context_line":"    if obj_b is None:"},{"line_number":26,"context_line":"        return False"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    for name in obj_a.fields:"},{"line_number":29,"context_line":"        set_a \u003d name in obj_a"},{"line_number":30,"context_line":"        set_b \u003d name in obj_b"},{"line_number":31,"context_line":"        if set_a !\u003d set_b:"},{"line_number":32,"context_line":"            return False"},{"line_number":33,"context_line":"        elif not set_a:"},{"line_number":34,"context_line":"            continue"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"        if getattr(obj_a, name) !\u003d getattr(obj_b, name):"},{"line_number":37,"context_line":"            return False"},{"line_number":38,"context_line":"    return True"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_a251a364","line":38,"range":{"start_line":24,"start_character":0,"end_line":38,"end_character":15},"updated":"2019-08-30 15:19:55.000000000","message":"get rid of this and reference base.all_things_equal from...","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":65,"context_line":"            primitive.pop(\u0027network_metadata\u0027, None)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def __eq__(self, other):"},{"line_number":68,"context_line":"        return all_things_equal(self, other)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def __ne__(self, other):"},{"line_number":71,"context_line":"        return not (self \u003d\u003d other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_22cb731e","line":68,"range":{"start_line":68,"start_character":15,"end_line":68,"end_character":31},"updated":"2019-08-30 15:19:55.000000000","message":"here","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":179,"context_line":"            primitive.pop(\u0027reserved\u0027, None)"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    def __eq__(self, other):"},{"line_number":182,"context_line":"        return all_things_equal(self, other)"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    def __ne__(self, other):"},{"line_number":185,"context_line":"        return not (self \u003d\u003d other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_e2d0fbca","line":182,"range":{"start_line":182,"start_character":15,"end_line":182,"end_character":31},"updated":"2019-08-30 15:19:55.000000000","message":"here","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":216,"context_line":"    }"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"    def __eq__(self, other):"},{"line_number":219,"context_line":"        return all_things_equal(self, other)"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    def __ne__(self, other):"},{"line_number":222,"context_line":"        return not (self \u003d\u003d other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_82d907f5","line":219,"range":{"start_line":219,"start_character":15,"end_line":219,"end_character":31},"updated":"2019-08-30 15:19:55.000000000","message":"and here","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"        if getattr(obj_a, name) !\u003d getattr(obj_b, name):"},{"line_number":37,"context_line":"            return False"},{"line_number":38,"context_line":"    return True"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_c04dfb72","side":"PARENT","line":38,"updated":"2019-09-10 14:22:47.000000000","message":"This should really be a separate patch","commit_id":"3d0d97011f718cbdd7dd90b9a5785147fc56c4aa"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"88e28d46b05be672744ea9c37425532c34fbe0bc","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"        if getattr(obj_a, name) !\u003d getattr(obj_b, name):"},{"line_number":37,"context_line":"            return False"},{"line_number":38,"context_line":"    return True"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_4ea84cda","side":"PARENT","line":38,"in_reply_to":"5faad753_c04dfb72","updated":"2019-09-11 08:02:15.000000000","message":"Okay, changes in objects/numa.py will in a seperate patch","commit_id":"3d0d97011f718cbdd7dd90b9a5785147fc56c4aa"}],"nova/objects/resource.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"46cfa9c8a07a8adcf4f3fbaf29d9fd08b687c7db","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":23,"context_line":"class Resource(base.NovaPersistentObject, base.NovaObject):"},{"line_number":24,"context_line":"    # Version 1.0: Initial version"},{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_a96d5c9a","line":23,"range":{"start_line":23,"start_character":6,"end_line":23,"end_character":14},"updated":"2019-08-26 18:57:49.000000000","message":"per [1], I think you\u0027re going to need an __eq__ for this.\n\n[1] https://review.opendev.org/#/c/678449/3/nova/compute/provider_tree.py@234","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"8b6a4bd3099b11c986da64f6d35bba17873cf2cc","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":23,"context_line":"class Resource(base.NovaPersistentObject, base.NovaObject):"},{"line_number":24,"context_line":"    # Version 1.0: Initial version"},{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_e37da8b2","line":23,"range":{"start_line":23,"start_character":6,"end_line":23,"end_character":14},"in_reply_to":"7faddb67_a96d5c9a","updated":"2019-08-27 09:47:08.000000000","message":"Done","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"46cfa9c8a07a8adcf4f3fbaf29d9fd08b687c7db","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":36,"context_line":"class ResourceList(base.ObjectListBase, base.NovaObject):"},{"line_number":37,"context_line":"    # Version 1.0: Initial version"},{"line_number":38,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":39,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_69fc44b5","line":36,"range":{"start_line":36,"start_character":6,"end_line":36,"end_character":18},"updated":"2019-08-26 18:57:49.000000000","message":"...and possibly for this as well, for convenience.","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"8b6a4bd3099b11c986da64f6d35bba17873cf2cc","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":36,"context_line":"class ResourceList(base.ObjectListBase, base.NovaObject):"},{"line_number":37,"context_line":"    # Version 1.0: Initial version"},{"line_number":38,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":39,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_8346347b","line":36,"range":{"start_line":36,"start_character":6,"end_line":36,"end_character":18},"in_reply_to":"7faddb67_69fc44b5","updated":"2019-08-27 09:47:08.000000000","message":"This is for migration_context and instance, will not used in provider tree. So I don\u0027t add __eq__ method.","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"46cfa9c8a07a8adcf4f3fbaf29d9fd08b687c7db","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    fields \u003d {"},{"line_number":41,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":42,"context_line":"    }"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_092b5033","line":41,"range":{"start_line":41,"start_character":26,"end_line":41,"end_character":30},"updated":"2019-08-26 18:57:49.000000000","message":"is there any way to make this a Set?","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"63f77568733a40557db20c1af019f71212fad3cd","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    fields \u003d {"},{"line_number":41,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":42,"context_line":"    }"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_a2ed6e8f","line":41,"range":{"start_line":41,"start_character":26,"end_line":41,"end_character":30},"in_reply_to":"7faddb67_092b5033","updated":"2019-08-27 04:56:05.000000000","message":"Why do you want this to be a set?","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a630ac90a389d533cc6f57b3f8193e63f2aac934","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    fields \u003d {"},{"line_number":41,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":42,"context_line":"    }"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_e88000c2","line":41,"range":{"start_line":41,"start_character":26,"end_line":41,"end_character":30},"in_reply_to":"7faddb67_a2ed6e8f","updated":"2019-08-28 22:49:32.000000000","message":"For both this and the above, I was thinking through the best way to avoid redundant writes back to the database. If your cached _Provider has a ResourceList in it, and you compare it to what the virt driver returns you, and it\u0027s unchanged (which should be the vast majority of the time), you don\u0027t need to write back.\n\n...so ResourceList.__eq__ would help with that, but it would be more convenient to be able to compare Sets so you don\u0027t have to worry about ordering.","commit_id":"58e9a6477883ab1a3d76a376d0c641c6d871c688"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"aa3d9a9864f9368e54caf1e32bcb19beaa9928bc","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":46,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":47,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":48,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_779881cb","line":48,"updated":"2019-08-28 04:48:08.000000000","message":"It will be good to have comment about this field are expected a json-blob of OVO.\n\nAnd virt driver specific.","commit_id":"d4759b104e546984c011fa6beb765e741d5ce53d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a630ac90a389d533cc6f57b3f8193e63f2aac934","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":23,"context_line":"    if obj_b is None:"},{"line_number":24,"context_line":"        return False"},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_a86a0818","line":22,"updated":"2019-08-28 22:49:32.000000000","message":"let\u0027s factor this out of here and numa.py and put it into, say, nova.objects.base.","commit_id":"52b98777b69c97a8bb2156fcbbe8eb36a91781d0"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f73e76fc2f4b14b6cb0429be0cbf3899e9e240d7","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":23,"context_line":"    if obj_b is None:"},{"line_number":24,"context_line":"        return False"},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_f31217b4","line":22,"in_reply_to":"7faddb67_a86a0818","updated":"2019-08-30 10:44:05.000000000","message":"https://review.opendev.org/#/c/472285/","commit_id":"52b98777b69c97a8bb2156fcbbe8eb36a91781d0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"def all_things_equal(obj_a, obj_b):"},{"line_number":23,"context_line":"    if obj_b is None:"},{"line_number":24,"context_line":"        return False"},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_42f8ef48","line":22,"in_reply_to":"7faddb67_f31217b4","updated":"2019-08-30 15:19:55.000000000","message":"Does that work? Could reopen it :)","commit_id":"52b98777b69c97a8bb2156fcbbe8eb36a91781d0"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f73e76fc2f4b14b6cb0429be0cbf3899e9e240d7","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    fields \u003d {"},{"line_number":66,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":67,"context_line":"    }"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_53d20bff","line":66,"range":{"start_line":66,"start_character":9,"end_line":66,"end_character":16},"updated":"2019-08-30 10:44:05.000000000","message":"nit: resources?","commit_id":"ea9e3a964bfeca5fcc83957a12a770c4d9dd9748"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"113142fa665591b9fb1cc6cd257a072d2fe41e24","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    fields \u003d {"},{"line_number":66,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":67,"context_line":"    }"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_763a95cd","line":66,"range":{"start_line":66,"start_character":9,"end_line":66,"end_character":16},"in_reply_to":"7faddb67_53d20bff","updated":"2019-08-30 11:08:14.000000000","message":"it\u0027s objects because base.ObjectListBase is used here.","commit_id":"ea9e3a964bfeca5fcc83957a12a770c4d9dd9748"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f73e76fc2f4b14b6cb0429be0cbf3899e9e240d7","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":67,"context_line":"    }"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    @base.remotable_classmethod"},{"line_number":70,"context_line":"    def get_by_instance_uuid(cls, context, instance_uuid):"},{"line_number":71,"context_line":"        db_extra \u003d db.instance_extra_get_by_instance_uuid("},{"line_number":72,"context_line":"                context, instance_uuid, columns\u003d[\u0027resources\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_93f5e385","line":69,"updated":"2019-08-30 10:44:05.000000000","message":"Need to check but this needs to be remotable, yeah?\n\nLater: Yeah, we do. Need it load the \u0027Instance\u0027 object.","commit_id":"ea9e3a964bfeca5fcc83957a12a770c4d9dd9748"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    def __hash__(self):"},{"line_number":38,"context_line":"        metadata \u003d self.metadata if \u0027metadata\u0027 in self else None"},{"line_number":39,"context_line":"        return hash((self.rp_uuid, self.resource_class,"},{"line_number":40,"context_line":"                     self.identifier, metadata))"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_62788bc0","line":40,"updated":"2019-08-30 15:19:55.000000000","message":"✔","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5cd867db9f5bd1bb69f2af6943ca16f58502b2cb","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    fields \u003d {"},{"line_number":49,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Resource\u0027),"},{"line_number":50,"context_line":"    }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_2235b3f7","line":49,"range":{"start_line":49,"start_character":26,"end_line":49,"end_character":30},"updated":"2019-08-30 15:19:55.000000000","message":"Given that we\u0027re going to load this up once and then cache the ResourceZ in set()s in the RT, I think it\u0027s okay to keep this as a List.","commit_id":"eb2bdef003f7a94a081da2657970893e40d5263c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9531edabae364adfa71ed538361e34c23eb4ff2b","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_f2718346","line":28,"updated":"2019-09-03 18:35:59.000000000","message":"I think I\u0027d prefer this be \"uuid\" or \"rp\" or \"resource_provider\" or even \"provider\". I\u0027m guessing it\u0027s this to indicate that it\u0027s not the Resource object\u0027s uuid but the RP in placement, but still...","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"25a7b0bf66cfdb8ed84e6832cbaf6d961a4b2c8e","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_c41cba14","line":28,"in_reply_to":"7faddb67_9e405537","updated":"2019-09-04 12:51:22.000000000","message":"Yeah, agree with provider_uuid.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"6258d2354139b1cca8fafa751ee7b97195c390fa","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_9e405537","line":28,"in_reply_to":"7faddb67_f2718346","updated":"2019-09-04 03:29:19.000000000","message":"How about provider_uuid, we use that name in RequestGroup object.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9531edabae364adfa71ed538361e34c23eb4ff2b","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_32a15b96","line":29,"updated":"2019-09-03 18:35:59.000000000","message":"Ideally you\u0027d define a field type for this to make sure it fits the required format. This is how you constrain what shows up in the data that you\u0027re persisting and sending over the wire to ensure strong compatibility.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"6258d2354139b1cca8fafa751ee7b97195c390fa","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_3e9e01b8","line":29,"in_reply_to":"7faddb67_32a15b96","updated":"2019-09-04 03:29:19.000000000","message":"This is resource class. I saw RequestGroup object is using the string also. But we can have a new field based on StringPattern.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"25a7b0bf66cfdb8ed84e6832cbaf6d961a4b2c8e","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_454c419d","line":29,"in_reply_to":"7faddb67_3e9e01b8","updated":"2019-09-04 12:51:22.000000000","message":"I need to look into this.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"8015be176c97b400c19b5381b7b15e3537accea2","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_39985067","line":29,"in_reply_to":"7faddb67_454c419d","updated":"2019-09-04 15:01:22.000000000","message":"Add a new ResourceClassField.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9531edabae364adfa71ed538361e34c23eb4ff2b","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_92984f69","line":30,"updated":"2019-09-03 18:35:59.000000000","message":"And this is what kind of identifier? It\u0027s confusing to not know, given it has a uuid just above.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"25a7b0bf66cfdb8ed84e6832cbaf6d961a4b2c8e","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_e571addf","line":30,"in_reply_to":"7faddb67_5eb41d36","updated":"2019-09-04 12:51:22.000000000","message":"will add some comments","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"6258d2354139b1cca8fafa751ee7b97195c390fa","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_5eb41d36","line":30,"in_reply_to":"7faddb67_92984f69","updated":"2019-09-04 03:29:19.000000000","message":"It is resource\u0027s identifier. For mdev, it is an UUID. For pmem, it is namespace name. It is virt driver and device specific. Maybe we can rename it as \u0027resource_id\u0027?\n\nBut we really some comment at here to explain those fields.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9531edabae364adfa71ed538361e34c23eb4ff2b","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_d292474b","line":31,"updated":"2019-09-03 18:35:59.000000000","message":"nullable means metadata can be None. Do you want that, or do you really want no metadata to be an empty string? And why is this a string and not a dict? You should not have object fields that contain complex encodings.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"25a7b0bf66cfdb8ed84e6832cbaf6d961a4b2c8e","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_24a10eaa","line":31,"in_reply_to":"7faddb67_9e55b552","updated":"2019-09-04 12:51:22.000000000","message":"Yes, thanks for Alex\u0027s reply.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"7fed102db7fae05c22c9fc2dc49f19b80c09b028","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_9e55b552","line":31,"in_reply_to":"7faddb67_be92f19d","updated":"2019-09-04 04:32:07.000000000","message":"I think we need null, The reason is some devices may not need the specific metadata. So it can be null.","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"6258d2354139b1cca8fafa751ee7b97195c390fa","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027rp_uuid\u0027: fields.UUIDField(),"},{"line_number":29,"context_line":"        \u0027resource_class\u0027: fields.StringField(),"},{"line_number":30,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":31,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":32,"context_line":"    }"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7faddb67_be92f19d","line":31,"in_reply_to":"7faddb67_d292474b","updated":"2019-09-04 03:29:19.000000000","message":"It is a string, since it is version object\u0027s json blob. This is for virt driver and device specific metadata. For pmem, it is https://review.opendev.org/#/c/678453/13/nova/objects/resource.py. For mdev, we can have LibivrtMdevDevice. Since those are version object\u0027s json blob, so it is still under the version control.\n\nLuyao may confirm whether he really needs null","commit_id":"b2c12be1e2e1cd148b38660b3186472d08379dc3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"dc29b4900d713a13a2de179cdbe73a5525eb6839","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"7faddb67_71a9e6da","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"updated":"2019-09-05 13:47:31.000000000","message":"No, this is not okay. You can\u0027t just put unstructured data in a string field like this. That\u0027s the entire problem that these versioned objects were trying to solve.\n\nIf this is a serialized object, then you need to make it an ObjectField with a parent object type.","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c8ec6af29afe25b7d8f4d6e7cfe75125cbb20dfb","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"5faad753_485f3fe5","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"in_reply_to":"5faad753_08cb87a5","updated":"2019-09-05 22:14:34.000000000","message":"\u003e \u003e - Make this (Resource.metadata) an ObjectField(\u0027ResourceMetadata\u0027,\n \u003e \u003e nullable\u003dTrue)\n \u003e \n \u003e Yes, except not nullable\u003dTrue I suspect.\n\nOkay, if a Resource needs no `metadata`, rather than setting the field to None, you instead just don\u0027t set the field at all. And you would check whether it\u0027s set with\n\n if \u0027metadata\u0027 in res_obj:\n\nThis saves you having to check whether it\u0027s set *and* whether it\u0027s None:\n\n if \u0027metadata\u0027 in res_obj and res_obj.metadata is not None:\n\n \u003e \u003e - Use obj rather than json (de)serialization on the\n \u003e \u003e Resource.metadata field as needed.\n \u003e \n \u003e It should be automatic. Objects in fields are serialized when the\n \u003e container is serialized.\n\nOkay, so just \"remove json (de)serialization\".","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":23598,"name":"Zhong Luyao","email":"luyao.zhong@intel.com","username":"ZhongLuyao"},"change_message_id":"86ed3d485f9f28f9b6ffd36ad79a4369cc5eed50","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"5faad753_a7c4d941","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"in_reply_to":"5faad753_485f3fe5","updated":"2019-09-06 10:21:51.000000000","message":"Many thanks!","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2e7a155ad65d34091b5d5c28cdfe5d3d7a2fef05","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"5faad753_ff933fa2","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"in_reply_to":"5faad753_485f3fe5","updated":"2019-09-06 08:12:17.000000000","message":"Thanks Dan, Eric! I see now. That is what backport for. It is ok for load from DB. but we can\u0027t do backport when we pass it on the wire. Also understand the nullable should be false now.","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7edf2530e781aa8af742f4b6b8111a1eda03519b","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"5faad753_08cb87a5","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"in_reply_to":"5faad753_68ed5b24","updated":"2019-09-05 22:05:38.000000000","message":"\u003e - Create a new OVO base class, e.g. ResourceMetadata, and register\n \u003e it (decorate with @obj_base.NovaObjectRegistry.register)\n\nYes, with a comment that it shouldn\u0027t be used directly.\n\n \u003e - Make this (Resource.metadata) an ObjectField(\u0027ResourceMetadata\u0027,\n \u003e nullable\u003dTrue)\n\nYes, except not nullable\u003dTrue I suspect.\n\n \u003e - Make LibvirtPMEMDevice a subclass of ResourceMetadata (in the\n \u003e patch where it\u0027s introduced).\n\nYes.\n\n \u003e - Use obj rather than json (de)serialization on the\n \u003e Resource.metadata field as needed.\n\nIt should be automatic. Objects in fields are serialized when the container is serialized.","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"63f86a2f3db0fb3baba8828d635cc851c106203e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # for mdev, it will be a UUID, for vpmem, it\u0027s backend namespace name"},{"line_number":34,"context_line":"        \u0027identifier\u0027: fields.StringField(),"},{"line_number":35,"context_line":"        # metadata can be used to contain virt driver specific resource info"},{"line_number":36,"context_line":"        # it can be a json blob of version object\u0027s json blob,"},{"line_number":37,"context_line":"        # for vpmem, we will have LibvirtVPMEMDeivce obj"},{"line_number":38,"context_line":"        # for mdev, we can have LibivrtMdevDevice obj"},{"line_number":39,"context_line":"        \u0027metadata\u0027: fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":15,"id":"5faad753_68ed5b24","line":36,"range":{"start_line":36,"start_character":22,"end_line":36,"end_character":61},"in_reply_to":"7faddb67_71a9e6da","updated":"2019-09-05 22:03:50.000000000","message":"Discussed with Dan \u0026 Matt to clarify. I think this means:\n- Create a new OVO base class, e.g. ResourceMetadata, and register it (decorate with @obj_base.NovaObjectRegistry.register)\n- Make this (Resource.metadata) an ObjectField(\u0027ResourceMetadata\u0027, nullable\u003dTrue)\n- Make LibvirtPMEMDevice a subclass of ResourceMetadata (in the patch where it\u0027s introduced).\n- Use obj rather than json (de)serialization on the Resource.metadata field as needed.\n- Profit.","commit_id":"df1bcc557d0dbd017f8aa0ed25420286e765174a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"1a842e63287d691ea3d9a6e9e135f57e4531a114","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        db_extra \u003d db.instance_extra_get_by_instance_uuid("},{"line_number":73,"context_line":"                context, instance_uuid, columns\u003d[\u0027resources\u0027])"},{"line_number":74,"context_line":"        if not db_extra or db_extra[\u0027resources\u0027] is None:"},{"line_number":75,"context_line":"            return None"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        primitive \u003d jsonutils.loads(db_extra[\u0027resources\u0027])"},{"line_number":78,"context_line":"        resources \u003d cls.obj_from_primitive(primitive)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5faad753_7270c573","line":75,"range":{"start_line":75,"start_character":19,"end_line":75,"end_character":23},"updated":"2019-09-09 03:09:14.000000000","message":"you should return the empty list at here. like\nreturn base.obj_make_list(context, cls(context), objects.ResourceList,\n                                  [])","commit_id":"4ab14c0b1b2da0c78bdc4755649d75ced22e1231"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"70965bafa130c15a6ad30cd4f34e659c92d84919","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        db_extra \u003d db.instance_extra_get_by_instance_uuid("},{"line_number":73,"context_line":"                context, instance_uuid, columns\u003d[\u0027resources\u0027])"},{"line_number":74,"context_line":"        if not db_extra or db_extra[\u0027resources\u0027] is None:"},{"line_number":75,"context_line":"            return None"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        primitive \u003d jsonutils.loads(db_extra[\u0027resources\u0027])"},{"line_number":78,"context_line":"        resources \u003d cls.obj_from_primitive(primitive)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5faad753_b2139d0d","line":75,"range":{"start_line":75,"start_character":19,"end_line":75,"end_character":23},"in_reply_to":"5faad753_7270c573","updated":"2019-09-09 03:11:06.000000000","message":"Since the instance.resource isn\u0027t nullable. So if we give it a None, then it will blowup","commit_id":"4ab14c0b1b2da0c78bdc4755649d75ced22e1231"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"34b11277debe812adefef12aff6ec7d5c6d199a4","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        db_extra \u003d db.instance_extra_get_by_instance_uuid("},{"line_number":73,"context_line":"                context, instance_uuid, columns\u003d[\u0027resources\u0027])"},{"line_number":74,"context_line":"        if not db_extra or db_extra[\u0027resources\u0027] is None:"},{"line_number":75,"context_line":"            return None"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        primitive \u003d jsonutils.loads(db_extra[\u0027resources\u0027])"},{"line_number":78,"context_line":"        resources \u003d cls.obj_from_primitive(primitive)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5faad753_92e6a1e8","line":75,"range":{"start_line":75,"start_character":19,"end_line":75,"end_character":23},"in_reply_to":"5faad753_b2139d0d","updated":"2019-09-09 03:51:21.000000000","message":"oops, sorry, we are nullable\u003dtrue for instance.resources.","commit_id":"4ab14c0b1b2da0c78bdc4755649d75ced22e1231"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f33d93acb05cf2c20570742d2412beea1e5789c4","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":23,"context_line":"class ResourceMetadata(base.NovaObject):"},{"line_number":24,"context_line":"    # Version 1.0: Initial version"},{"line_number":25,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    # This is parent object of specific resources."},{"line_number":28,"context_line":"    # And it\u0027s used to be a object field of Resource,"},{"line_number":29,"context_line":"    # that is to say Resource.metadata."},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":18,"id":"5faad753_800f03e0","line":29,"range":{"start_line":22,"start_character":0,"end_line":29,"end_character":39},"updated":"2019-09-10 14:22:47.000000000","message":"This is a bit confusing. I guess I need to work up through the series to see how it\u0027s used","commit_id":"334e1a6011f9f0fcf6bb1e29b0d4816cab15d81b"}],"nova/tests/unit/objects/test_instance.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"1a842e63287d691ea3d9a6e9e135f57e4531a114","unresolved":false,"context_lines":[{"line_number":1513,"context_line":"        mock_get.assert_called_once_with(self.context, uuids.pci_devices)"},{"line_number":1514,"context_line":"        self.assertEqual(fake_pci_devices, pci_devices)"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"    @mock.patch(\u0027nova.objects.ResourceList.get_by_instance_uuid\u0027)"},{"line_number":1517,"context_line":"    def test_load_resources(self, mock_get):"},{"line_number":1518,"context_line":"        fake_resources \u003d objects.ResourceList()"},{"line_number":1519,"context_line":"        mock_get.return_value \u003d fake_resources"}],"source_content_type":"text/x-python","patch_set":17,"id":"5faad753_d20419c9","line":1516,"range":{"start_line":1516,"start_character":43,"end_line":1516,"end_character":63},"updated":"2019-09-09 03:09:14.000000000","message":"if this return None, then we will blow up","commit_id":"4ab14c0b1b2da0c78bdc4755649d75ced22e1231"}],"nova/tests/unit/objects/test_resource.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f73e76fc2f4b14b6cb0429be0cbf3899e9e240d7","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import mock"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from nova.objects import resource"},{"line_number":16,"context_line":"from nova.tests.unit.objects import test_objects"},{"line_number":17,"context_line":"from oslo_serialization import jsonutils"},{"line_number":18,"context_line":"from oslo_utils.fixture import uuidsentinel as uuids"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"fake_resources \u003d resource.ResourceList(objects\u003d["}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_b3fa5f74","line":18,"range":{"start_line":13,"start_character":0,"end_line":18,"end_character":52},"updated":"2019-08-30 10:44:05.000000000","message":"nit: These are grouped incorrectly:\n\n  import mock\n  from oslo_serialization import jsonutils\n  from oslo_utils.fixture import uuidsentinel as uuids\n\n  from nova.objects import resource\n  from nova.tests.unit.objects import test_objects","commit_id":"ea9e3a964bfeca5fcc83957a12a770c4d9dd9748"}]}
