)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"57ed250999a2b9defc12798eb9184b246e29563e","unresolved":false,"context_lines":[{"line_number":14,"context_line":"it only as a util class. However after this series the nova services"},{"line_number":15,"context_line":"would like to use such a class via RPC which requires an OVO. This"},{"line_number":16,"context_line":"patch makes sure that the new OVO is used by nova and the old plain"},{"line_number":17,"context_line":"object is used by placement. This way placement is not forced to use"},{"line_number":18,"context_line":"an OVO where no OVO functionality is required."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: I46c97d2641d9685ef59771314665a17a5236097d"},{"line_number":21,"context_line":"blueprint: bandwidth-resource-provider"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"5f7c97a3_68862bbc","line":18,"range":{"start_line":17,"start_character":29,"end_line":18,"end_character":46},"updated":"2018-05-24 23:10:45.000000000","message":"++","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0941f2284d39ff4a302454ec6ea49ec27528e370","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add request_spec.RequestGroup versioned object"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Later patches will introduce a field in RequestSpec using this type as"},{"line_number":10,"context_line":"the field type."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch refactors the usage of placement.lib.RequestGroup. Until now"},{"line_number":13,"context_line":"this class was used both by placement and nova services and they used"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"5f7c97a3_5a749a36","line":10,"updated":"2018-06-18 16:08:11.000000000","message":"If you want to be more complete, you could say \"why\" here. As written it\u0027s not clear why having the versioned object is necessary, other than because you say you\u0027re going to need it. For what?","commit_id":"a747224b434ddb5f0703dcf178d7ea8f730b6337"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d927a1cafa4caa9f89245a8f73a1cd5b6da1bbe1","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add request_spec.RequestGroup versioned object"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Later patches will introduce a field in RequestSpec using this type as"},{"line_number":10,"context_line":"the field type."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch refactors the usage of placement.lib.RequestGroup. Until now"},{"line_number":13,"context_line":"this class was used both by placement and nova services and they used"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"5f7c97a3_f34a2381","line":10,"in_reply_to":"5f7c97a3_5a749a36","updated":"2018-06-21 14:07:38.000000000","message":"Done","commit_id":"a747224b434ddb5f0703dcf178d7ea8f730b6337"}],"nova/api/openstack/placement/lib.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fef4a0941c96a8322619b0afa582d03e270307eb","unresolved":false,"context_lines":[{"line_number":20,"context_line":"    def __init__(self, use_same_provider\u003dTrue, resources\u003dNone,"},{"line_number":21,"context_line":"                 required_traits\u003dNone, forbidden_traits\u003dNone, member_of\u003dNone):"},{"line_number":22,"context_line":"        \"\"\"Create a grouping of resource and trait requests."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"        :param use_same_provider:"},{"line_number":25,"context_line":"            If True, (the default) this RequestGroup represents requests for"},{"line_number":26,"context_line":"            resources and traits which must be satisfied by a single resource"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_77c1b153","side":"PARENT","line":23,"updated":"2018-05-16 15:59:35.000000000","message":"unnecessary change","commit_id":"9706d89d52552d86c40f45e349e1fdba5cb2a5cd"}],"nova/objects/fields.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"57ed250999a2b9defc12798eb9184b246e29563e","unresolved":false,"context_lines":[{"line_number":1207,"context_line":"    AUTO_TYPE \u003d fields.Set(fields.String())"},{"line_number":1208,"context_line":""},{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":"class ListOfListOfStringsField(fields.AutoTypedField):"},{"line_number":1211,"context_line":"    AUTO_TYPE \u003d fields.List(fields.List(fields.String()))"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_8b24e161","line":1210,"range":{"start_line":1210,"start_character":12,"end_line":1210,"end_character":16},"updated":"2018-05-24 23:10:45.000000000","message":"Lists","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d058afd01e8b11269b1a7070785b357463d9af77","unresolved":false,"context_lines":[{"line_number":1207,"context_line":"    AUTO_TYPE \u003d fields.Set(fields.String())"},{"line_number":1208,"context_line":""},{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":"class ListOfListOfStringsField(fields.AutoTypedField):"},{"line_number":1211,"context_line":"    AUTO_TYPE \u003d fields.List(fields.List(fields.String()))"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_6342aa11","line":1210,"range":{"start_line":1210,"start_character":12,"end_line":1210,"end_character":16},"in_reply_to":"5f7c97a3_8b24e161","updated":"2018-05-29 15:16:43.000000000","message":"Done","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"}],"nova/objects/request_spec.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"57ed250999a2b9defc12798eb9184b246e29563e","unresolved":false,"context_lines":[{"line_number":816,"context_line":"        \u0027member_of\u0027: fields.ListOfListOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, **kwargs):"},{"line_number":820,"context_line":"        super(RequestGroup, self).__init__(**kwargs)"},{"line_number":821,"context_line":"        self.obj_set_defaults()"},{"line_number":822,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":823,"context_line":"        if \u0027required_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_0bd771f0","line":820,"range":{"start_line":819,"start_character":0,"end_line":820,"end_character":52},"updated":"2018-05-24 23:10:45.000000000","message":"In case poorly-behaved consumers invoke this with the context param unnamed (which I see very often with ovos), this should be made to match the super\u0027s signature:\n\n def __init__(self, context\u003dNone, **kwargs):\n     super(RequestGroup, self).__init__(context\u003dcontext, **kwargs)\n     ...","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d058afd01e8b11269b1a7070785b357463d9af77","unresolved":false,"context_lines":[{"line_number":816,"context_line":"        \u0027member_of\u0027: fields.ListOfListOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, **kwargs):"},{"line_number":820,"context_line":"        super(RequestGroup, self).__init__(**kwargs)"},{"line_number":821,"context_line":"        self.obj_set_defaults()"},{"line_number":822,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":823,"context_line":"        if \u0027required_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_be7c59b6","line":820,"range":{"start_line":819,"start_character":0,"end_line":820,"end_character":52},"in_reply_to":"5f7c97a3_0bd771f0","updated":"2018-05-29 15:16:43.000000000","message":"Good point. Done.","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":15554,"name":"Bence Romsics","email":"bence.romsics@gmail.com","username":"ebenrom","status":"inactive contributor"},"change_message_id":"ee74563beafc5b7cd0ea8c6d1f92a95c45a4b2b7","unresolved":false,"context_lines":[{"line_number":813,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":814,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":815,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":816,"context_line":"        \u0027member_of\u0027: fields.ListOfListsOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_ddbd0303","line":816,"range":{"start_line":816,"start_character":9,"end_line":816,"end_character":18},"updated":"2018-06-06 09:42:02.000000000","message":"Maybe make this plural? Since microversion 1.24 that would make more sense. member_ofs? member_of_params? member_of_queries?\n\nOr does it have to have the same name as in placement/lib.py?","commit_id":"1ad925e128a2e3ddc9e163d1370f8f3484cdce82"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c0272f2af297b58b61c994b3f8e3c56d777f6bf","unresolved":false,"context_lines":[{"line_number":813,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":814,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":815,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":816,"context_line":"        \u0027member_of\u0027: fields.ListOfListsOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_a08d7c2b","line":816,"range":{"start_line":816,"start_character":9,"end_line":816,"end_character":18},"in_reply_to":"5f7c97a3_ddbd0303","updated":"2018-06-06 11:33:21.000000000","message":"Good point. If we want to name it properly then we should do it now as we introduce the object now. I made it member_ofs as this is a list of member_of values","commit_id":"1ad925e128a2e3ddc9e163d1370f8f3484cdce82"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"61173ccfc557bec39fa75a415c8abdd9904fb3a1","unresolved":false,"context_lines":[{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":820,"context_line":"        super(RequestGroup, self).__init__(context, **kwargs)"},{"line_number":821,"context_line":"        self.obj_set_defaults()"},{"line_number":822,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":823,"context_line":"        if \u0027required_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_ce89156f","line":820,"range":{"start_line":820,"start_character":43,"end_line":820,"end_character":50},"updated":"2018-06-01 20:45:03.000000000","message":"nit: prefer context\u003dcontext here","commit_id":"1ad925e128a2e3ddc9e163d1370f8f3484cdce82"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c0272f2af297b58b61c994b3f8e3c56d777f6bf","unresolved":false,"context_lines":[{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":820,"context_line":"        super(RequestGroup, self).__init__(context, **kwargs)"},{"line_number":821,"context_line":"        self.obj_set_defaults()"},{"line_number":822,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":823,"context_line":"        if \u0027required_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_40bfc8fb","line":820,"range":{"start_line":820,"start_character":43,"end_line":820,"end_character":50},"in_reply_to":"5f7c97a3_ce89156f","updated":"2018-06-06 11:33:21.000000000","message":"Done","commit_id":"1ad925e128a2e3ddc9e163d1370f8f3484cdce82"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"ee90de9b4206c637fce7ec4977ca74ca13a39a7a","unresolved":false,"context_lines":[{"line_number":813,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":814,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":815,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":816,"context_line":"        \u0027member_ofs\u0027: fields.ListOfListsOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_49ca8c4f","line":816,"range":{"start_line":816,"start_character":9,"end_line":816,"end_character":19},"updated":"2018-06-06 15:28:50.000000000","message":"...except it\u0027s not plural anywhere else.  I think Dan just used the word \"aggregates\" when he put this in the request spec.","commit_id":"609b4476d6f1db791c74930dd60a7d69664e89be"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"57f4eec49c3859beb9e55fbef63b4a08854e34eb","unresolved":false,"context_lines":[{"line_number":813,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":814,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":815,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":816,"context_line":"        \u0027member_ofs\u0027: fields.ListOfListsOfStringsField(default\u003d[]),"},{"line_number":817,"context_line":"    }"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_a26ea5c6","line":816,"range":{"start_line":816,"start_character":9,"end_line":816,"end_character":19},"in_reply_to":"5f7c97a3_49ca8c4f","updated":"2018-06-08 12:02:57.000000000","message":"OK, let\u0027s call it \u0027aggregates\u0027","commit_id":"609b4476d6f1db791c74930dd60a7d69664e89be"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":855,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":856,"context_line":""},{"line_number":857,"context_line":"    fields \u003d {"},{"line_number":858,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(default\u003dTrue),"},{"line_number":859,"context_line":"        \u0027resources\u0027: fields.DictOfIntegersField(default\u003d{}),"},{"line_number":860,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":861,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_bd23a3bb","line":858,"range":{"start_line":858,"start_character":49,"end_line":858,"end_character":61},"updated":"2018-10-30 14:09:09.000000000","message":"I guess this defaults to True because that\u0027s what use_same_provider defaults to in the placement lib RequestGroup:\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/nova/api/openstack/placement/lib.py#L20\n\nEven though there isn\u0027t a default in the placement REST API from what I can tell.\n\nOr does use_same_provider just indicate it\u0027s a numbered request group?\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/nova/api/openstack/placement/util.py#L429\n\nA comment explaining what the field is / how it\u0027s used would be nice.","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":856,"context_line":""},{"line_number":857,"context_line":"    fields \u003d {"},{"line_number":858,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(default\u003dTrue),"},{"line_number":859,"context_line":"        \u0027resources\u0027: fields.DictOfIntegersField(default\u003d{}),"},{"line_number":860,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":861,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":862,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_28019304","line":859,"updated":"2018-10-30 14:09:09.000000000","message":"OK so this is our normal resources dict for allocations, e.g.:\n\n\"resources\": {\n    \"MEMORY_MB\": 1024,\n    \"VCPU\": 1\n}","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":857,"context_line":"    fields \u003d {"},{"line_number":858,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(default\u003dTrue),"},{"line_number":859,"context_line":"        \u0027resources\u0027: fields.DictOfIntegersField(default\u003d{}),"},{"line_number":860,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":861,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":862,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":863,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":864,"context_line":"        # The aggregates field has a form of"},{"line_number":865,"context_line":"        #     [[aggregate_UUID1],"},{"line_number":866,"context_line":"        #      [aggregate_UUID2, aggregate_UUID3]]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_c82a5f77","line":863,"range":{"start_line":860,"start_character":8,"end_line":863,"end_character":55},"updated":"2018-10-30 14:09:09.000000000","message":"The bug is fixed and released in 1.33.3:\n\nhttps://review.openstack.org/#/c/569417/\n\nSo we should bump upper-constraints and requirements/lower-constraints to require that version and drop the TODO.\n\nLooks like u-c is already OK:\n\nhttps://github.com/openstack/requirements/blob/master/upper-constraints.txt#L236\n\nBut not these:\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/requirements.txt#L56\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/lower-constraints.txt#L94","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"41b124333c56fb2f48797cc16c89750728c6c788","unresolved":false,"context_lines":[{"line_number":857,"context_line":"    fields \u003d {"},{"line_number":858,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(default\u003dTrue),"},{"line_number":859,"context_line":"        \u0027resources\u0027: fields.DictOfIntegersField(default\u003d{}),"},{"line_number":860,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":861,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":862,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":863,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":864,"context_line":"        # The aggregates field has a form of"},{"line_number":865,"context_line":"        #     [[aggregate_UUID1],"},{"line_number":866,"context_line":"        #      [aggregate_UUID2, aggregate_UUID3]]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_c495ee95","line":863,"range":{"start_line":860,"start_character":8,"end_line":863,"end_character":55},"in_reply_to":"3f79a3b5_c82a5f77","updated":"2018-11-05 21:58:18.000000000","message":"Done","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":861,"context_line":"        \u0027required_traits\u0027: fields.SetOfStringsField(),"},{"line_number":862,"context_line":"        # TODO(gibi): Needs to have default\u003dset() after bug 1771804 is fixed"},{"line_number":863,"context_line":"        \u0027forbidden_traits\u0027: fields.SetOfStringsField(),"},{"line_number":864,"context_line":"        # The aggregates field has a form of"},{"line_number":865,"context_line":"        #     [[aggregate_UUID1],"},{"line_number":866,"context_line":"        #      [aggregate_UUID2, aggregate_UUID3]]"},{"line_number":867,"context_line":"        # meaning that the request should be fulfilled from an RP that is a"},{"line_number":868,"context_line":"        # member of the aggregate aggregate_UUID1 and member of the aggregate"},{"line_number":869,"context_line":"        # aggregate_UUID2 or aggregate_UUID3 ."},{"line_number":870,"context_line":"        \u0027aggregates\u0027: fields.ListOfListsOfStringsField(default\u003d[]),"},{"line_number":871,"context_line":"    }"},{"line_number":872,"context_line":""},{"line_number":873,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_085ff710","line":870,"range":{"start_line":864,"start_character":8,"end_line":870,"end_character":67},"updated":"2018-10-30 14:09:09.000000000","message":"Hmm, the logical use of this sounds the same as Destination.aggregates which is already in the RequestSpec via the requested_destination field, but structurally you\u0027re modeling it differently, which could be confusing:\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/nova/objects/request_spec.py#L747\n\nShould we try to make those consistent with how Destination.aggregates works? I would think so.\n\nNote the default on that field is None rather than [].\n\n(later)\n\nI guess what you\u0027re going for here is to model this the same way as the existing RequestGroup in the placement lib module:\n\nhttps://github.com/openstack/nova/blob/d1e38f06bb5282dd9bf81d979926a0ebbfd93caa/nova/api/openstack/placement/lib.py#L32\n\nIn that case, it would align with that object rather than the Destination.aggregates field...which I guess is OK. Ultimately as long as the syntax / usage is clearly documented, like you have with the description here, it\u0027s probably OK. I just remember being quite confused with the Destination.aggregates stuff until Dan clearly documented its usage within the object.","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":873,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":874,"context_line":"        super(RequestGroup, self).__init__(context\u003dcontext, **kwargs)"},{"line_number":875,"context_line":"        self.obj_set_defaults()"},{"line_number":876,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":877,"context_line":"        if \u0027required_traits\u0027 not in self:"},{"line_number":878,"context_line":"            self.required_traits \u003d set()"},{"line_number":879,"context_line":"        if \u0027forbidden_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_a85b6321","line":876,"updated":"2018-10-30 14:09:09.000000000","message":"We can resolve this TODO now.","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"41b124333c56fb2f48797cc16c89750728c6c788","unresolved":false,"context_lines":[{"line_number":873,"context_line":"    def __init__(self, context\u003dNone, **kwargs):"},{"line_number":874,"context_line":"        super(RequestGroup, self).__init__(context\u003dcontext, **kwargs)"},{"line_number":875,"context_line":"        self.obj_set_defaults()"},{"line_number":876,"context_line":"        # TODO(gibi): Both defaulting can be removed after bug 1771804 is fixed"},{"line_number":877,"context_line":"        if \u0027required_traits\u0027 not in self:"},{"line_number":878,"context_line":"            self.required_traits \u003d set()"},{"line_number":879,"context_line":"        if \u0027forbidden_traits\u0027 not in self:"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_0413e65b","line":876,"in_reply_to":"3f79a3b5_a85b6321","updated":"2018-11-05 21:58:18.000000000","message":"Done","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"}],"nova/scheduler/utils.py":[{"author":{"_account_id":23630,"name":"Tovin Seven","email":"tovin07@gmail.com","username":"tovin07"},"change_message_id":"134cad9362d0bfac5930e74a434d9bf55d8c15eb","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        destination \u003d spec_obj.requested_destination"},{"line_number":380,"context_line":"        if destination and destination.aggregates:"},{"line_number":381,"context_line":"            grp \u003d res_req.get_request_group(None)"},{"line_number":382,"context_line":"            grp.member_of \u003d [list(ored.split(\u0027,\u0027))"},{"line_number":383,"context_line":"                             for ored in destination.aggregates]"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    return res_req"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_92aa5b6e","line":382,"range":{"start_line":382,"start_character":29,"end_line":382,"end_character":33},"updated":"2018-05-16 16:43:45.000000000","message":"redundant","commit_id":"a7804eaf5944006f3b019c1ddacdd40e206b1768"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a6e70268720cb626cff61a1faff83f6bd6c2e4c2","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        destination \u003d spec_obj.requested_destination"},{"line_number":380,"context_line":"        if destination and destination.aggregates:"},{"line_number":381,"context_line":"            grp \u003d res_req.get_request_group(None)"},{"line_number":382,"context_line":"            grp.member_of \u003d [list(ored.split(\u0027,\u0027))"},{"line_number":383,"context_line":"                             for ored in destination.aggregates]"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    return res_req"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_a6b626dc","line":382,"range":{"start_line":382,"start_character":29,"end_line":382,"end_character":33},"in_reply_to":"5f7c97a3_92aa5b6e","updated":"2018-05-17 12:31:32.000000000","message":"Done","commit_id":"a7804eaf5944006f3b019c1ddacdd40e206b1768"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"57ed250999a2b9defc12798eb9184b246e29563e","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        \"\"\""},{"line_number":244,"context_line":"        # NOTE(efried): The sorting herein is not necessary for the API; it is"},{"line_number":245,"context_line":"        # to make testing easier and logging/debugging predictable."},{"line_number":246,"context_line":"        def to_queryparams(request_group, suffix):"},{"line_number":247,"context_line":"            res \u003d request_group.resources"},{"line_number":248,"context_line":"            required_traits \u003d request_group.required_traits"},{"line_number":249,"context_line":"            forbidden_traits \u003d request_group.forbidden_traits"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_ebe235d5","line":246,"range":{"start_line":246,"start_character":12,"end_line":246,"end_character":26},"updated":"2018-05-24 23:10:45.000000000","message":"This needs to be moved into the new ovo as a method.  If you don\u0027t want to do that in this patch, cool, but would you mind at least adding a TODO for me please?","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d058afd01e8b11269b1a7070785b357463d9af77","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        \"\"\""},{"line_number":244,"context_line":"        # NOTE(efried): The sorting herein is not necessary for the API; it is"},{"line_number":245,"context_line":"        # to make testing easier and logging/debugging predictable."},{"line_number":246,"context_line":"        def to_queryparams(request_group, suffix):"},{"line_number":247,"context_line":"            res \u003d request_group.resources"},{"line_number":248,"context_line":"            required_traits \u003d request_group.required_traits"},{"line_number":249,"context_line":"            forbidden_traits \u003d request_group.forbidden_traits"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_fe2411c8","line":246,"range":{"start_line":246,"start_character":12,"end_line":246,"end_character":26},"in_reply_to":"5f7c97a3_ebe235d5","updated":"2018-05-29 15:16:43.000000000","message":"Done.","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a200c3a1dca70ccf05feac4d5f556d54f692d696","unresolved":false,"context_lines":[{"line_number":457,"context_line":"        destination \u003d spec_obj.requested_destination"},{"line_number":458,"context_line":"        if destination and destination.aggregates:"},{"line_number":459,"context_line":"            grp \u003d res_req.get_request_group(None)"},{"line_number":460,"context_line":"            grp.member_of \u003d [tuple(ored.split(\u0027,\u0027))"},{"line_number":461,"context_line":"                             for ored in destination.aggregates]"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":"    # Don\u0027t limit allocation candidates when using force_hosts or force_nodes."}],"source_content_type":"text/x-python","patch_set":25,"id":"3f79a3b5_de47f551","side":"PARENT","line":460,"range":{"start_line":460,"start_character":29,"end_line":460,"end_character":34},"updated":"2018-11-06 06:04:56.000000000","message":"Not sure why this was creating a tuple out of a list, but ok.","commit_id":"c64b03d218c4d05b9db47eaf7660cdab9baa6468"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a200c3a1dca70ccf05feac4d5f556d54f692d696","unresolved":false,"context_lines":[{"line_number":252,"context_line":"            res \u003d request_group.resources"},{"line_number":253,"context_line":"            required_traits \u003d request_group.required_traits"},{"line_number":254,"context_line":"            forbidden_traits \u003d request_group.forbidden_traits"},{"line_number":255,"context_line":"            aggregates \u003d request_group.aggregates"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"            resource_query \u003d \",\".join("},{"line_number":258,"context_line":"                sorted(\"%s:%s\" % (rc, amount)"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f79a3b5_f330ea08","line":255,"updated":"2018-11-06 06:04:56.000000000","message":"Note to self: this is a transition from the placement lib RequestGroup object to the nova RequestGroup OVO -- member_of \u003d\u003e aggregates.","commit_id":"d4f8974f873c1040a7ad8deaf3d380edca93e60f"}],"nova/tests/unit/api/openstack/placement/test_util.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"57ed250999a2b9defc12798eb9184b246e29563e","unresolved":false,"context_lines":[{"line_number":894,"context_line":"                None, self.resource_provider)"},{"line_number":895,"context_line":"            self.assertEqual(now, chosen_time)"},{"line_number":896,"context_line":"            mock_utc.assert_called_once_with(with_timezone\u003dTrue)"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":""},{"line_number":899,"context_line":"class TestRequestGroup(test.NoDBTestCase):"},{"line_number":900,"context_line":"    def test_stringification(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_0b9bf172","line":897,"updated":"2018-05-24 23:10:45.000000000","message":"I appreciate this port, though it\u0027s not as comprehensive as what it\u0027s replacing.\n\nIn particular, sorting of multiple entries within each attribute is no longer covered.","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d058afd01e8b11269b1a7070785b357463d9af77","unresolved":false,"context_lines":[{"line_number":894,"context_line":"                None, self.resource_provider)"},{"line_number":895,"context_line":"            self.assertEqual(now, chosen_time)"},{"line_number":896,"context_line":"            mock_utc.assert_called_once_with(with_timezone\u003dTrue)"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":""},{"line_number":899,"context_line":"class TestRequestGroup(test.NoDBTestCase):"},{"line_number":900,"context_line":"    def test_stringification(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_f2c20585","line":897,"in_reply_to":"5f7c97a3_0b9bf172","updated":"2018-05-29 15:16:43.000000000","message":"Good point. It turned out that the original coverage wasn\u0027t comprehensive enough either and the __str__ code is buggy as it did not sort the forbidden_traits. I fixing it here now but that might needs a separate independent bugfix. What do you think?","commit_id":"f90916f3bf2ec1315a9dd810bae02ddba48aecb2"}],"nova/tests/unit/objects/test_request_spec.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6bf77060fa266db0cdb71799828107ed5f98f3de","unresolved":false,"context_lines":[{"line_number":752,"context_line":"    pass"},{"line_number":753,"context_line":""},{"line_number":754,"context_line":""},{"line_number":755,"context_line":"class TestRequestGroupObject(test.TestCase):"},{"line_number":756,"context_line":"    def setUp(self):"},{"line_number":757,"context_line":"        super(TestRequestGroupObject, self).setUp()"},{"line_number":758,"context_line":"        self.user_id \u003d uuids.user_id"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f79a3b5_08bb7710","line":755,"updated":"2018-10-30 14:09:09.000000000","message":"Normally we\u0027d have the local/remote variant of this, but I guess this is just a versioned data bag at this point with no remotable objects so those are probably not needed yet.","commit_id":"1d6d3719efe0185fc40b487a97fa651959d7f645"}]}
