)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f247f59a68ebeb5f638f76f461b208dbe488f691","unresolved":false,"context_lines":[{"line_number":12,"context_line":"with resource_providers that belong to at least one of the supplied"},{"line_number":13,"context_line":"aggregates."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Blueprint: placement-req-filter"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I5857e927a830914c96e040936804e322baccc24c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"df7087c5_2a2a507e","line":15,"updated":"2018-03-13 18:28:11.000000000","message":"This is the wrong blueprint, should be blueprint alloc-candidates-member-of","commit_id":"9d150fb48bb437a2f0f69073fd1dcdbc6b478a39"}],"nova/api/openstack/placement/handlers/allocation_candidate.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b57ba048f12fa73770e7afed3904ac17354aefeb","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        get_schema \u003d schema.GET_SCHEMA_1_16"},{"line_number":221,"context_line":"    util.validate_query_params(req, get_schema)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    requests \u003d util.parse_qs_request_groups(req.GET)"},{"line_number":224,"context_line":"    limit \u003d req.GET.getall(\u0027limit\u0027)"},{"line_number":225,"context_line":"    # JSONschema has already confirmed that limit has the form"},{"line_number":226,"context_line":"    # of an integer."}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_ea2b1ce8","line":223,"range":{"start_line":223,"start_character":4,"end_line":223,"end_character":52},"updated":"2018-03-12 19:13:45.000000000","message":"I have a feeling that we will want to add the parsing of member_of into the RequestGroup parsing. I just predict in the future we will have requests, as an example, for one VF that is on PF that is associated with one aggregate representing physical network A and another VF on a PF associated with a different physical network represented by a different aggregate.\n\nSo, basically, we\u0027d need a member_of\u003d and then a member_of1\u003d, etc..","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"7f05fca545b1d75ed4ec2c84a87bcf0673adb679","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        get_schema \u003d schema.GET_SCHEMA_1_16"},{"line_number":221,"context_line":"    util.validate_query_params(req, get_schema)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    requests \u003d util.parse_qs_request_groups(req.GET)"},{"line_number":224,"context_line":"    limit \u003d req.GET.getall(\u0027limit\u0027)"},{"line_number":225,"context_line":"    # JSONschema has already confirmed that limit has the form"},{"line_number":226,"context_line":"    # of an integer."}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_f7a1b247","line":223,"range":{"start_line":223,"start_character":4,"end_line":223,"end_character":52},"in_reply_to":"df7087c5_ea2b1ce8","updated":"2018-03-13 11:13:31.000000000","message":"Can we iterate instead and make that change when we actually need it?\n Then we can sort of understand things incrementally as they progress.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9d826705f514b22766dd3aab8d5e27797673c439","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        get_schema \u003d schema.GET_SCHEMA_1_16"},{"line_number":221,"context_line":"    util.validate_query_params(req, get_schema)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    requests \u003d util.parse_qs_request_groups(req.GET)"},{"line_number":224,"context_line":"    limit \u003d req.GET.getall(\u0027limit\u0027)"},{"line_number":225,"context_line":"    # JSONschema has already confirmed that limit has the form"},{"line_number":226,"context_line":"    # of an integer."}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_c0db8279","line":223,"range":{"start_line":223,"start_character":4,"end_line":223,"end_character":52},"in_reply_to":"df7087c5_f7a1b247","updated":"2018-03-13 12:29:24.000000000","message":"It\u0027s not really an iteration. I\u0027ve started making that change, and it changes the flow logic completely, so if we\u0027re ever going to need it, might as well do it now.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"7f05fca545b1d75ed4ec2c84a87bcf0673adb679","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    if limit:"},{"line_number":228,"context_line":"        limit \u003d int(limit[0])"},{"line_number":229,"context_line":"    # Get the aggregates, if any"},{"line_number":230,"context_line":"    aggs \u003d req.GET.getall(\u0027member_of\u0027) or []"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    try:"},{"line_number":233,"context_line":"        cands \u003d rp_obj.AllocationCandidates.get_by_requests(context, requests,"}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_ba68ffb8","line":230,"updated":"2018-03-13 11:13:31.000000000","message":"If \u0027in:\u0027 is being used, where is it being parsed?","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9d826705f514b22766dd3aab8d5e27797673c439","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    if limit:"},{"line_number":228,"context_line":"        limit \u003d int(limit[0])"},{"line_number":229,"context_line":"    # Get the aggregates, if any"},{"line_number":230,"context_line":"    aggs \u003d req.GET.getall(\u0027member_of\u0027) or []"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    try:"},{"line_number":233,"context_line":"        cands \u003d rp_obj.AllocationCandidates.get_by_requests(context, requests,"}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_00441a1a","line":230,"in_reply_to":"df7087c5_ba68ffb8","updated":"2018-03-13 12:29:24.000000000","message":"I think I missed that in this version. I do strip it out in the next.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"}],"nova/api/openstack/placement/lib.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        self.use_same_provider \u003d use_same_provider"},{"line_number":34,"context_line":"        self.resources \u003d resources or {}"},{"line_number":35,"context_line":"        self.required_traits \u003d required_traits or set()"},{"line_number":36,"context_line":"        self.member_of \u003d member_of or []"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_6478258f","line":36,"range":{"start_line":36,"start_character":38,"end_line":36,"end_character":40},"updated":"2018-03-16 15:47:14.000000000","message":"Is there a reason this isn\u0027t a set() (for consistency with required_traits)?  Order shouldn\u0027t matter.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        self.use_same_provider \u003d use_same_provider"},{"line_number":34,"context_line":"        self.resources \u003d resources or {}"},{"line_number":35,"context_line":"        self.required_traits \u003d required_traits or set()"},{"line_number":36,"context_line":"        self.member_of \u003d member_of or []"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_09e85a79","line":36,"range":{"start_line":36,"start_character":38,"end_line":36,"end_character":40},"in_reply_to":"df7087c5_6478258f","updated":"2018-03-19 18:52:42.000000000","message":"I had started with it as a list, and this was a holdover. I\u0027ll switch it to a set in the followup, just to make you happy. :)","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/api/openstack/placement/microversion.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    \u00271.19\u0027,  # Include generation and conflict detection in provider aggregates"},{"line_number":65,"context_line":"             # APIs"},{"line_number":66,"context_line":"    \u00271.20\u0027,  # Return 200 with provider payload from POST /resource_providers"},{"line_number":67,"context_line":"    \u00271.21\u0027,  # Support ?member_of\u003d\u003cagg UUIDs\u003e queryparam on"},{"line_number":68,"context_line":"             # GET /allocation_candidates"},{"line_number":69,"context_line":"]"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_a4b63d3d","line":67,"updated":"2018-03-16 15:47:14.000000000","message":"Wouldn\u0027t hurt my feelings if \u0027in:\u0027 was mentioned in this comment.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/api/openstack/placement/objects/resource_provider.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"eab9e0804cc853c35f790788576a51beb512448c","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"    #       shared_disk.resource_provider_id"},{"line_number":1216,"context_line":"    # LEFT JOIN resource_provider_aggregates AS sharing_disk_gb"},{"line_number":1217,"context_line":"    #  ON shared_disk_gb.aggregate_id \u003d sharing_disk_gb.aggregate_id"},{"line_number":1218,"context_line":"    # AND sharing_disk_gb.resource_provider_id IN ($RPS_SHARING_DISK)"},{"line_number":1219,"context_line":"    # WHERE ("},{"line_number":1220,"context_line":"    #   ("},{"line_number":1221,"context_line":"    #     COALESCE(usage_vcpu.used, 0) + $AMOUNT_VCPU \u003c\u003d"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_3d6feefc","line":1218,"updated":"2018-03-14 08:30:43.000000000","message":"so we should update this comment also.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"cca4ebb4a125e4914cd1ca92e9dc3303b243d713","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"    #       shared_disk.resource_provider_id"},{"line_number":1216,"context_line":"    # LEFT JOIN resource_provider_aggregates AS sharing_disk_gb"},{"line_number":1217,"context_line":"    #  ON shared_disk_gb.aggregate_id \u003d sharing_disk_gb.aggregate_id"},{"line_number":1218,"context_line":"    # AND sharing_disk_gb.resource_provider_id IN ($RPS_SHARING_DISK)"},{"line_number":1219,"context_line":"    # WHERE ("},{"line_number":1220,"context_line":"    #   ("},{"line_number":1221,"context_line":"    #     COALESCE(usage_vcpu.used, 0) + $AMOUNT_VCPU \u003c\u003d"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_3c404ba5","line":1218,"in_reply_to":"df7087c5_3d6feefc","updated":"2018-03-14 14:21:09.000000000","message":"Yeah, I just glossed over all this. Added some comments and more example SQL.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"89238dba2892c5de525ff98c343bee2f0e1a252d","unresolved":false,"context_lines":[{"line_number":1221,"context_line":"    # LEFT JOIN resource_provider_aggregates AS sharing_disk_gb"},{"line_number":1222,"context_line":"    #  ON shared_disk_gb.aggregate_id \u003d sharing_disk_gb.aggregate_id"},{"line_number":1223,"context_line":"    # AND sharing_disk_gb.resource_provider_id IN ($RPS_SHARING_DISK)"},{"line_number":1224,"context_line":"    # LEFT JOIN resource_provider_aggregates AS member_aggs"},{"line_number":1225,"context_line":"    #  ON rp.id \u003d member_aggs.resource_provider_id"},{"line_number":1226,"context_line":"    #  AND member_aggs.aggregate_id IN ($MEMBER_OF)"},{"line_number":1227,"context_line":"    # WHERE ("}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_0b2652cf","line":1224,"range":{"start_line":1224,"start_character":6,"end_line":1224,"end_character":11},"updated":"2018-03-14 19:10:00.000000000","message":"nit: this is INNER, not LEFT","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"92ee49077b7fc298467f7c6de8cc2290ed6706d2","unresolved":false,"context_lines":[{"line_number":1221,"context_line":"    # LEFT JOIN resource_provider_aggregates AS sharing_disk_gb"},{"line_number":1222,"context_line":"    #  ON shared_disk_gb.aggregate_id \u003d sharing_disk_gb.aggregate_id"},{"line_number":1223,"context_line":"    # AND sharing_disk_gb.resource_provider_id IN ($RPS_SHARING_DISK)"},{"line_number":1224,"context_line":"    # LEFT JOIN resource_provider_aggregates AS member_aggs"},{"line_number":1225,"context_line":"    #  ON rp.id \u003d member_aggs.resource_provider_id"},{"line_number":1226,"context_line":"    #  AND member_aggs.aggregate_id IN ($MEMBER_OF)"},{"line_number":1227,"context_line":"    # WHERE ("}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_265eed43","line":1224,"range":{"start_line":1224,"start_character":6,"end_line":1224,"end_character":11},"in_reply_to":"df7087c5_0b2652cf","updated":"2018-03-14 19:45:00.000000000","message":"Done","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"f1506cf248f2ec2e35a0a28a3b6cf92648db0761","unresolved":false,"context_lines":[{"line_number":3540,"context_line":""},{"line_number":3541,"context_line":"    @staticmethod"},{"line_number":3542,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":3543,"context_line":"    def _get_by_requests(context, requests, limit\u003dNone, member_of\u003dNone):"},{"line_number":3544,"context_line":"        # We first get the list of \"root providers\" that either have the"},{"line_number":3545,"context_line":"        # requested resources or are associated with the providers that"},{"line_number":3546,"context_line":"        # share one or more of the requested resource(s)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_32f86f79","line":3543,"updated":"2018-03-14 16:54:50.000000000","message":"member_of arg is not used, is it? You\u0027re getting it from the sharing_groups, which comes out of request?","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"92ee49077b7fc298467f7c6de8cc2290ed6706d2","unresolved":false,"context_lines":[{"line_number":3540,"context_line":""},{"line_number":3541,"context_line":"    @staticmethod"},{"line_number":3542,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":3543,"context_line":"    def _get_by_requests(context, requests, limit\u003dNone, member_of\u003dNone):"},{"line_number":3544,"context_line":"        # We first get the list of \"root providers\" that either have the"},{"line_number":3545,"context_line":"        # requested resources or are associated with the providers that"},{"line_number":3546,"context_line":"        # share one or more of the requested resource(s)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_e6a55548","line":3543,"in_reply_to":"df7087c5_32f86f79","updated":"2018-03-14 19:45:00.000000000","message":"Yup - that\u0027s left over from the initial version.","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"89238dba2892c5de525ff98c343bee2f0e1a252d","unresolved":false,"context_lines":[{"line_number":3540,"context_line":""},{"line_number":3541,"context_line":"    @staticmethod"},{"line_number":3542,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":3543,"context_line":"    def _get_by_requests(context, requests, limit\u003dNone, member_of\u003dNone):"},{"line_number":3544,"context_line":"        # We first get the list of \"root providers\" that either have the"},{"line_number":3545,"context_line":"        # requested resources or are associated with the providers that"},{"line_number":3546,"context_line":"        # share one or more of the requested resource(s)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_4b11aa5c","line":3543,"in_reply_to":"df7087c5_32f86f79","updated":"2018-03-14 19:10:00.000000000","message":"yes, that\u0027s correct Chris. member_of arg should be removed.","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"aeb1369778858455b9da187e6e206617feb52977","unresolved":false,"context_lines":[{"line_number":1223,"context_line":"    # AND sharing_disk_gb.resource_provider_id IN ($RPS_SHARING_DISK)"},{"line_number":1224,"context_line":"    # INNER JOIN resource_provider_aggregates AS member_aggs"},{"line_number":1225,"context_line":"    #  ON rp.id \u003d member_aggs.resource_provider_id"},{"line_number":1226,"context_line":"    #  AND member_aggs.aggregate_id IN ($MEMBER_OF)"},{"line_number":1227,"context_line":"    # WHERE ("},{"line_number":1228,"context_line":"    #   ("},{"line_number":1229,"context_line":"    #     COALESCE(usage_vcpu.used, 0) + $AMOUNT_VCPU \u003c\u003d"}],"source_content_type":"text/x-python","patch_set":7,"id":"df7087c5_25657e46","line":1226,"updated":"2018-03-15 00:56:43.000000000","message":"you need to join the aggregate table also.","commit_id":"8b2ec18bbac51e64bcf75bfeedb56ae0785c8023"}],"nova/api/openstack/placement/rest_api_version_history.rst":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"7f05fca545b1d75ed4ec2c84a87bcf0673adb679","unresolved":false,"context_lines":[{"line_number":238,"context_line":"---------------------------------------------------------------------"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"Add support for the `member_of` query parameter to the `GET"},{"line_number":241,"context_line":"/allocation_candidates` API. It accepts a comma-separated list of UUIDs for"},{"line_number":242,"context_line":"aggregates. If this parameter is provided, the only resource providers returned"},{"line_number":243,"context_line":"will be those in one of the specified aggregates that meet the other parts of"},{"line_number":244,"context_line":"the request."}],"source_content_type":"text/x-rst","patch_set":1,"id":"df7087c5_3753aa41","line":241,"updated":"2018-03-13 11:13:31.000000000","message":"the version on /resource_providers needs an \u0027in:\u0027 if it is a list to indicate that it is \"any\" instead of all.\n\nIt\u0027s \u0027in:\u0027 in the gabbi test. Maybe we don\u0027t need to be explicit about it here but just checking.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9d826705f514b22766dd3aab8d5e27797673c439","unresolved":false,"context_lines":[{"line_number":238,"context_line":"---------------------------------------------------------------------"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"Add support for the `member_of` query parameter to the `GET"},{"line_number":241,"context_line":"/allocation_candidates` API. It accepts a comma-separated list of UUIDs for"},{"line_number":242,"context_line":"aggregates. If this parameter is provided, the only resource providers returned"},{"line_number":243,"context_line":"will be those in one of the specified aggregates that meet the other parts of"},{"line_number":244,"context_line":"the request."}],"source_content_type":"text/x-rst","patch_set":1,"id":"df7087c5_80eeeab1","line":241,"in_reply_to":"df7087c5_3753aa41","updated":"2018-03-13 12:29:24.000000000","message":"Yes, it needs an \u0027in:\u0027. You\u0027re correct that I should make it explicit; I was more or less assuming that the \"any\" part of it was the only use case.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"df7087c5_e72677ce","line":264,"updated":"2018-03-16 15:47:14.000000000","message":"Here also \u0027in:\u0027 should be mentioned.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/api/openstack/placement/util.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"b6127925bb1226cd9e337aa81c169fb7b79f1bfe","unresolved":false,"context_lines":[{"line_number":317,"context_line":"    return ret"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"def normalize_member_of_qs_param(val):"},{"line_number":321,"context_line":"    \"\"\"Parse a member_of query string parameter value."},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    Valid values are either a single UUID, or the prefix \u0027in:\u0027 followed by two"}],"source_content_type":"text/x-python","patch_set":2,"id":"df7087c5_80bd8503","line":320,"updated":"2018-03-13 15:00:02.000000000","message":"Seems like basically everything in this file is just extending the utilities to support member_of, but not really related to the business of making it work for the one API we care about, right? Meaning, I would think we could split these changes out to stand alone.","commit_id":"a999941316c51885314fa04dd45a40413f51dfb1"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"eab9e0804cc853c35f790788576a51beb512448c","unresolved":false,"context_lines":[{"line_number":449,"context_line":"        raise webob.exc.HTTPBadRequest(msg % \u0027, \u0027.join(orphans))"},{"line_number":450,"context_line":"    # NOTE(edleafe): Not sure how to handle this microversion difference. If"},{"line_number":451,"context_line":"    # anyone has a better solution, let me know."},{"line_number":452,"context_line":"    supports_member_of \u003d any([hasattr(group, \"member_of\")"},{"line_number":453,"context_line":"                              for group in by_suffix.values()])"},{"line_number":454,"context_line":"    if supports_member_of:"},{"line_number":455,"context_line":"        orphans \u003d [(\u0027required%s\u0027 % suff) for suff, group in by_suffix.items()"},{"line_number":456,"context_line":"                   if group.member_of and not group.resources]"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_bdd45eea","line":453,"range":{"start_line":452,"start_character":3,"end_line":453,"end_character":63},"updated":"2018-03-14 08:30:43.000000000","message":"We needn\u0027t handle the microversion at here. Since the API layer will stop to accept the \u0027member_of\u0027 by the schema, so at here, we only do the similar thing with line 445, check if there is value of request_group.member_of.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"cca4ebb4a125e4914cd1ca92e9dc3303b243d713","unresolved":false,"context_lines":[{"line_number":449,"context_line":"        raise webob.exc.HTTPBadRequest(msg % \u0027, \u0027.join(orphans))"},{"line_number":450,"context_line":"    # NOTE(edleafe): Not sure how to handle this microversion difference. If"},{"line_number":451,"context_line":"    # anyone has a better solution, let me know."},{"line_number":452,"context_line":"    supports_member_of \u003d any([hasattr(group, \"member_of\")"},{"line_number":453,"context_line":"                              for group in by_suffix.values()])"},{"line_number":454,"context_line":"    if supports_member_of:"},{"line_number":455,"context_line":"        orphans \u003d [(\u0027required%s\u0027 % suff) for suff, group in by_suffix.items()"},{"line_number":456,"context_line":"                   if group.member_of and not group.resources]"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_e756bc2a","line":453,"range":{"start_line":452,"start_character":3,"end_line":453,"end_character":63},"in_reply_to":"df7087c5_bdd45eea","updated":"2018-03-14 14:21:09.000000000","message":"It\u0027s not an API issue; it\u0027s the RequestGroup class. I have to add that field to it. I only added the above code because I was getting lots of test failures without it. I\u0027ve now updated that class, and it\u0027s all working ok now.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":320,"context_line":"def normalize_member_of_qs_param(val):"},{"line_number":321,"context_line":"    \"\"\"Parse a member_of query string parameter value."},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    Valid values are either a single UUID, or the prefix \u0027in:\u0027 followed by two"},{"line_number":324,"context_line":"    or more comma-separated UUIDs."},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"    :param val: A member_of query parameter of either a single UUID, or a"},{"line_number":327,"context_line":"                comma-separated string of two or more UUIDs."}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_3a7fa666","line":324,"range":{"start_line":323,"start_character":0,"end_line":324,"end_character":34},"updated":"2018-03-16 15:47:14.000000000","message":"Technically zero or more.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":320,"context_line":"def normalize_member_of_qs_param(val):"},{"line_number":321,"context_line":"    \"\"\"Parse a member_of query string parameter value."},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    Valid values are either a single UUID, or the prefix \u0027in:\u0027 followed by two"},{"line_number":324,"context_line":"    or more comma-separated UUIDs."},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"    :param val: A member_of query parameter of either a single UUID, or a"},{"line_number":327,"context_line":"                comma-separated string of two or more UUIDs."}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_c90fc234","line":324,"range":{"start_line":323,"start_character":0,"end_line":324,"end_character":34},"in_reply_to":"df7087c5_3a7fa666","updated":"2018-03-19 18:52:42.000000000","message":"Actually, if you just requested \"in:\" with no uuids, it will fail the schema check. So technically, it is one or more.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fb6b37fe2efb61ff1b610ae1611ac352aa3a0ba5","unresolved":false,"context_lines":[{"line_number":320,"context_line":"def normalize_member_of_qs_param(val):"},{"line_number":321,"context_line":"    \"\"\"Parse a member_of query string parameter value."},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    Valid values are either a single UUID, or the prefix \u0027in:\u0027 followed by two"},{"line_number":324,"context_line":"    or more comma-separated UUIDs."},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"    :param val: A member_of query parameter of either a single UUID, or a"},{"line_number":327,"context_line":"                comma-separated string of two or more UUIDs."}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_4da87076","line":324,"range":{"start_line":323,"start_character":0,"end_line":324,"end_character":34},"in_reply_to":"df7087c5_c90fc234","updated":"2018-03-19 21:18:32.000000000","message":"How would it fail the schema check?\n\n GET_SCHEMA_1_21[\u0027properties\u0027][\u0027member_of\u0027] \u003d {\n     \"type\": [\"string\"]\n }","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            expected format."},{"line_number":331,"context_line":"    \"\"\""},{"line_number":332,"context_line":"    # Ensure that multiple values are prefixed with \"in:\""},{"line_number":333,"context_line":"    if \",\" in val and not val.startswith(\"in:\"):"},{"line_number":334,"context_line":"        msg \u003d _(\"Multiple values for \u0027member_of\u0027 must be prefixed with the \""},{"line_number":335,"context_line":"                \"\u0027in:\u0027 keyword. Got: %s\") % val"},{"line_number":336,"context_line":"        raise webob.exc.HTTPBadRequest(msg)"},{"line_number":337,"context_line":"    if val.startswith(\"in:\"):"},{"line_number":338,"context_line":"        ret \u003d val[3:].split(\",\")"},{"line_number":339,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_da754a65","line":336,"range":{"start_line":333,"start_character":0,"end_line":336,"end_character":43},"updated":"2018-03-16 15:47:14.000000000","message":"We\u0027re not this strict in GET /rps [1].  Which makes it easier to use [2] because you can always use \u0027in:\u0027 - you don\u0027t have to worry about counting your aggregates and branching based on 1, \u003e1, or even 0.\n\nWhile we\u0027re at it, I\u0027d like to see the code in [1] factored out into this utils method.  Then we\u0027re sure it behaves the same (in addition to the other benefits of code deduplication).\n\n[Later] Oh, sorry, I see the other code is indeed this strict; but this gives a more detailed error message for this condition.\n\nI\u0027d still like to see the code commonized, though.  (We wouldn\u0027t we need a new microversion to fork the more granular error message on the GET /rps side, would we?)\n\n[1] https://github.com/openstack/nova/blob/7cbb5764d499dfdc90ef4a963daf217d58c840d4/nova/api/openstack/placement/handlers/resource_provider.py#L198-L202\n[2] https://github.com/openstack/nova/blob/7cbb5764d499dfdc90ef4a963daf217d58c840d4/nova/scheduler/client/report.py#L484-L485","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            expected format."},{"line_number":331,"context_line":"    \"\"\""},{"line_number":332,"context_line":"    # Ensure that multiple values are prefixed with \"in:\""},{"line_number":333,"context_line":"    if \",\" in val and not val.startswith(\"in:\"):"},{"line_number":334,"context_line":"        msg \u003d _(\"Multiple values for \u0027member_of\u0027 must be prefixed with the \""},{"line_number":335,"context_line":"                \"\u0027in:\u0027 keyword. Got: %s\") % val"},{"line_number":336,"context_line":"        raise webob.exc.HTTPBadRequest(msg)"},{"line_number":337,"context_line":"    if val.startswith(\"in:\"):"},{"line_number":338,"context_line":"        ret \u003d val[3:].split(\",\")"},{"line_number":339,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_be5ffc70","line":336,"range":{"start_line":333,"start_character":0,"end_line":336,"end_character":43},"in_reply_to":"df7087c5_da754a65","updated":"2018-03-19 18:52:42.000000000","message":"Done","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        msg \u003d _(\"Invalid query string parameters: Expected \u0027member_of\u0027 \""},{"line_number":344,"context_line":"                \"parameter to contain valid UUID(s). Got: %s\") % val"},{"line_number":345,"context_line":"        raise webob.exc.HTTPBadRequest(msg)"},{"line_number":346,"context_line":"    return ret"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"def parse_qs_request_groups(qsdict):"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_faccce89","line":346,"updated":"2018-03-16 15:47:14.000000000","message":"For consistency with normalize_traits_qs_param, this should return a set.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        msg \u003d _(\"Invalid query string parameters: Expected \u0027member_of\u0027 \""},{"line_number":344,"context_line":"                \"parameter to contain valid UUID(s). Got: %s\") % val"},{"line_number":345,"context_line":"        raise webob.exc.HTTPBadRequest(msg)"},{"line_number":346,"context_line":"    return ret"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"def parse_qs_request_groups(qsdict):"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_7eade42f","line":346,"in_reply_to":"df7087c5_faccce89","updated":"2018-03-19 18:52:42.000000000","message":"Done","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":355,"context_line":"    ?resources\u003d$RESOURCE_CLASS_NAME:$AMOUNT,$RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":356,"context_line":"    \u0026required\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of\u003d$AGG_UUID"},{"line_number":357,"context_line":"    \u0026resources1\u003d$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":358,"context_line":"    \u0026required1\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of1\u003d$AGG_UUID"},{"line_number":359,"context_line":"    \u0026resources2\u003d$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":360,"context_line":"    \u0026required2\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of2\u003d$AGG_UUID"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_5ad5ba1a","line":358,"updated":"2018-03-16 15:47:14.000000000","message":"wouldn\u0027t hurt my feelings if one of these examples had multiple aggs.  Otherwise the real example on L374 may be confusing.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":355,"context_line":"    ?resources\u003d$RESOURCE_CLASS_NAME:$AMOUNT,$RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":356,"context_line":"    \u0026required\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of\u003d$AGG_UUID"},{"line_number":357,"context_line":"    \u0026resources1\u003d$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":358,"context_line":"    \u0026required1\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of1\u003d$AGG_UUID"},{"line_number":359,"context_line":"    \u0026resources2\u003d$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT"},{"line_number":360,"context_line":"    \u0026required2\u003d$TRAIT_NAME,$TRAIT_NAME\u0026member_of2\u003d$AGG_UUID"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_de93d0ff","line":358,"in_reply_to":"df7087c5_5ad5ba1a","updated":"2018-03-19 18:52:42.000000000","message":"Done","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":386,"context_line":"              \"MEMORY_MB\": 1024,"},{"line_number":387,"context_line":"              \"DISK_GB\" 50,"},{"line_number":388,"context_line":"          },"},{"line_number":389,"context_line":"          required_traits\u003d["},{"line_number":390,"context_line":"              \"HW_CPU_X86_VMX\","},{"line_number":391,"context_line":"              \"CUSTOM_STORAGE_RAID\","},{"line_number":392,"context_line":"          ],"},{"line_number":393,"context_line":"          member_of\u003d["},{"line_number":394,"context_line":"            9323b2b1-82c9-4e91-bdff-e95e808ef954,"},{"line_number":395,"context_line":"            8592a199-7d73-4465-8df6-ab00a6243c82,"},{"line_number":396,"context_line":"          ],"},{"line_number":397,"context_line":"      ),"},{"line_number":398,"context_line":"      RequestGroup("},{"line_number":399,"context_line":"          use_same_provider\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_bac2d651","line":396,"range":{"start_line":389,"start_character":0,"end_line":396,"end_character":12},"updated":"2018-03-16 15:47:14.000000000","message":"and these should be sets (d\u0027oh) here and below","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":386,"context_line":"              \"MEMORY_MB\": 1024,"},{"line_number":387,"context_line":"              \"DISK_GB\" 50,"},{"line_number":388,"context_line":"          },"},{"line_number":389,"context_line":"          required_traits\u003d["},{"line_number":390,"context_line":"              \"HW_CPU_X86_VMX\","},{"line_number":391,"context_line":"              \"CUSTOM_STORAGE_RAID\","},{"line_number":392,"context_line":"          ],"},{"line_number":393,"context_line":"          member_of\u003d["},{"line_number":394,"context_line":"            9323b2b1-82c9-4e91-bdff-e95e808ef954,"},{"line_number":395,"context_line":"            8592a199-7d73-4465-8df6-ab00a6243c82,"},{"line_number":396,"context_line":"          ],"},{"line_number":397,"context_line":"      ),"},{"line_number":398,"context_line":"      RequestGroup("},{"line_number":399,"context_line":"          use_same_provider\u003dTrue,"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_9e39d8f3","line":396,"range":{"start_line":389,"start_character":0,"end_line":396,"end_character":12},"in_reply_to":"df7087c5_bac2d651","updated":"2018-03-19 18:52:42.000000000","message":"Python sets are not JSON-serializable. They would need to be cast back into lists.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ec9ffc384878e7625f80892908fdd42a300030c7","unresolved":false,"context_lines":[{"line_number":1373,"context_line":"    # get those resource providers that are associated with any of the"},{"line_number":1374,"context_line":"    # list of aggregate uuids provided with \u0027member_of\u0027."},{"line_number":1375,"context_line":"    if member_of:"},{"line_number":1376,"context_line":"        member_join \u003d sa.join(join_chain, _AGG_TBL, _RP_AGG_TBL, sa.and_("},{"line_number":1377,"context_line":"                _AGG_TBL.c.id \u003d\u003d _RP_AGG_TBL.c.aggregate_id,"},{"line_number":1378,"context_line":"                _AGG_TBL.c.uuid.in_(member_of)))"},{"line_number":1379,"context_line":"        join_chain \u003d member_join"}],"source_content_type":"text/x-python","patch_set":2,"id":"df7087c5_60c5d1f0","line":1376,"updated":"2018-03-13 15:17:33.000000000","message":"missing the join of rp_tbl to rp_app_tbl?","commit_id":"a999941316c51885314fa04dd45a40413f51dfb1"}],"nova/tests/functional/api/openstack/placement/fixtures.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"eab9e0804cc853c35f790788576a51beb512448c","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        os.environ[\u0027CN2_UUID\u0027] \u003d cn2_uuid"},{"line_number":228,"context_line":"        os.environ[\u0027SS_UUID\u0027] \u003d ss_uuid"},{"line_number":229,"context_line":"        os.environ[\u0027AGG_UUID\u0027] \u003d agg_uuid"},{"line_number":230,"context_line":"        os.environ[\u0027AGGA_UUID\u0027] \u003d aggA_uuid"},{"line_number":231,"context_line":"        os.environ[\u0027AGGB_UUID\u0027] \u003d aggB_uuid"},{"line_number":232,"context_line":"        os.environ[\u0027AGGC_UUID\u0027] \u003d aggC_uuid"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"        cn1 \u003d rp_obj.ResourceProvider("},{"line_number":235,"context_line":"            self.context,"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_9de15a9e","line":232,"range":{"start_line":230,"start_character":8,"end_line":232,"end_character":43},"updated":"2018-03-14 08:30:43.000000000","message":"why we need those, since we use the fixture \u0027NonSharedStorageFixture\u0027","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"cca4ebb4a125e4914cd1ca92e9dc3303b243d713","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        os.environ[\u0027CN2_UUID\u0027] \u003d cn2_uuid"},{"line_number":228,"context_line":"        os.environ[\u0027SS_UUID\u0027] \u003d ss_uuid"},{"line_number":229,"context_line":"        os.environ[\u0027AGG_UUID\u0027] \u003d agg_uuid"},{"line_number":230,"context_line":"        os.environ[\u0027AGGA_UUID\u0027] \u003d aggA_uuid"},{"line_number":231,"context_line":"        os.environ[\u0027AGGB_UUID\u0027] \u003d aggB_uuid"},{"line_number":232,"context_line":"        os.environ[\u0027AGGC_UUID\u0027] \u003d aggC_uuid"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"        cn1 \u003d rp_obj.ResourceProvider("},{"line_number":235,"context_line":"            self.context,"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_8716e054","line":232,"range":{"start_line":230,"start_character":8,"end_line":232,"end_character":43},"in_reply_to":"df7087c5_9de15a9e","updated":"2018-03-14 14:21:09.000000000","message":"Heh, forgot to clean those up. Done.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"89238dba2892c5de525ff98c343bee2f0e1a252d","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"class NonSharedStorageFixture(APIFixture):"},{"line_number":308,"context_line":"    \"\"\"An APIFixture that has two compute nodes withlocal storage that do not"},{"line_number":309,"context_line":"    use shared storage."},{"line_number":310,"context_line":"    \"\"\""},{"line_number":311,"context_line":"    def start_fixture(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_86001903","line":308,"range":{"start_line":308,"start_character":48,"end_line":308,"end_character":57},"updated":"2018-03-14 19:10:00.000000000","message":"with local","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"89238dba2892c5de525ff98c343bee2f0e1a252d","unresolved":false,"context_lines":[{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        cn1_uuid \u003d uuidutils.generate_uuid()"},{"line_number":316,"context_line":"        cn2_uuid \u003d uuidutils.generate_uuid()"},{"line_number":317,"context_line":"        ss_uuid \u003d uuidutils.generate_uuid()"},{"line_number":318,"context_line":"        aggA_uuid \u003d uuidutils.generate_uuid()"},{"line_number":319,"context_line":"        aggB_uuid \u003d uuidutils.generate_uuid()"},{"line_number":320,"context_line":"        aggC_uuid \u003d uuidutils.generate_uuid()"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_8629f98a","line":317,"range":{"start_line":317,"start_character":8,"end_line":317,"end_character":43},"updated":"2018-03-14 19:10:00.000000000","message":"not used.","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"89238dba2892c5de525ff98c343bee2f0e1a252d","unresolved":false,"context_lines":[{"line_number":320,"context_line":"        aggC_uuid \u003d uuidutils.generate_uuid()"},{"line_number":321,"context_line":"        os.environ[\u0027CN1_UUID\u0027] \u003d cn1_uuid"},{"line_number":322,"context_line":"        os.environ[\u0027CN2_UUID\u0027] \u003d cn2_uuid"},{"line_number":323,"context_line":"        os.environ[\u0027SS_UUID\u0027] \u003d ss_uuid"},{"line_number":324,"context_line":"        os.environ[\u0027AGGA_UUID\u0027] \u003d aggA_uuid"},{"line_number":325,"context_line":"        os.environ[\u0027AGGB_UUID\u0027] \u003d aggB_uuid"},{"line_number":326,"context_line":"        os.environ[\u0027AGGC_UUID\u0027] \u003d aggC_uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_c63291f2","line":323,"range":{"start_line":323,"start_character":8,"end_line":323,"end_character":39},"updated":"2018-03-14 19:10:00.000000000","message":"not used","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"92ee49077b7fc298467f7c6de8cc2290ed6706d2","unresolved":false,"context_lines":[{"line_number":320,"context_line":"        aggC_uuid \u003d uuidutils.generate_uuid()"},{"line_number":321,"context_line":"        os.environ[\u0027CN1_UUID\u0027] \u003d cn1_uuid"},{"line_number":322,"context_line":"        os.environ[\u0027CN2_UUID\u0027] \u003d cn2_uuid"},{"line_number":323,"context_line":"        os.environ[\u0027SS_UUID\u0027] \u003d ss_uuid"},{"line_number":324,"context_line":"        os.environ[\u0027AGGA_UUID\u0027] \u003d aggA_uuid"},{"line_number":325,"context_line":"        os.environ[\u0027AGGB_UUID\u0027] \u003d aggB_uuid"},{"line_number":326,"context_line":"        os.environ[\u0027AGGC_UUID\u0027] \u003d aggC_uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_8632590f","line":323,"range":{"start_line":323,"start_character":8,"end_line":323,"end_character":39},"in_reply_to":"df7087c5_c63291f2","updated":"2018-03-14 19:45:00.000000000","message":"coppa pasta fail!","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        super(NonSharedStorageFixture, self).start_fixture()"},{"line_number":313,"context_line":"        self.context \u003d context.get_admin_context()"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        cn1_uuid \u003d uuidutils.generate_uuid()"},{"line_number":316,"context_line":"        cn2_uuid \u003d uuidutils.generate_uuid()"},{"line_number":317,"context_line":"        aggA_uuid \u003d uuidutils.generate_uuid()"},{"line_number":318,"context_line":"        aggB_uuid \u003d uuidutils.generate_uuid()"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_da7f8a12","line":315,"updated":"2018-03-16 15:47:14.000000000","message":"why not sentinels?","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        super(NonSharedStorageFixture, self).start_fixture()"},{"line_number":313,"context_line":"        self.context \u003d context.get_admin_context()"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        cn1_uuid \u003d uuidutils.generate_uuid()"},{"line_number":316,"context_line":"        cn2_uuid \u003d uuidutils.generate_uuid()"},{"line_number":317,"context_line":"        aggA_uuid \u003d uuidutils.generate_uuid()"},{"line_number":318,"context_line":"        aggB_uuid \u003d uuidutils.generate_uuid()"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_41460152","line":315,"in_reply_to":"df7087c5_da7f8a12","updated":"2018-03-19 18:52:42.000000000","message":"Consistency with the rest of the code in this module, perhaps?","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/tests/functional/api/openstack/placement/gabbits/allocation-candidates-member-of.yaml":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"eab9e0804cc853c35f790788576a51beb512448c","unresolved":false,"context_lines":[{"line_number":21,"context_line":"      - Invalid query string parameters"},{"line_number":22,"context_line":"      - \"\u0027member_of\u0027 was unexpected\""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"- name: get allocation candidates invalid member_of value"},{"line_number":25,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003dINVALID_UUID"},{"line_number":26,"context_line":"  status: 400"},{"line_number":27,"context_line":"  response_strings:"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"df7087c5_fd017639","line":24,"range":{"start_line":24,"start_character":34,"end_line":24,"end_character":57},"updated":"2018-03-14 08:30:43.000000000","message":"One more case we can add is: with `in` and invalid uuid.","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"cca4ebb4a125e4914cd1ca92e9dc3303b243d713","unresolved":false,"context_lines":[{"line_number":21,"context_line":"      - Invalid query string parameters"},{"line_number":22,"context_line":"      - \"\u0027member_of\u0027 was unexpected\""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"- name: get allocation candidates invalid member_of value"},{"line_number":25,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003dINVALID_UUID"},{"line_number":26,"context_line":"  status: 400"},{"line_number":27,"context_line":"  response_strings:"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"df7087c5_42ce7682","line":24,"range":{"start_line":24,"start_character":34,"end_line":24,"end_character":57},"in_reply_to":"df7087c5_fd017639","updated":"2018-03-14 14:21:09.000000000","message":"Done","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"f1506cf248f2ec2e35a0a28a3b6cf92648db0761","unresolved":false,"context_lines":[{"line_number":53,"context_line":"      - $ENVIRON[\u0027AGGA_UUID\u0027]"},{"line_number":54,"context_line":"  status: 200"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"- name: verify that the member_of call now returns 1 RP"},{"line_number":57,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":58,"context_line":"  status: 200"},{"line_number":59,"context_line":"  response_json_paths:"}],"source_content_type":"text/x-yaml","patch_set":6,"id":"df7087c5_92905b45","line":56,"updated":"2018-03-14 16:54:50.000000000","message":"nit: This name is a bit misleading as you\u0027re counting allocation requests, not resource providers.","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"92ee49077b7fc298467f7c6de8cc2290ed6706d2","unresolved":false,"context_lines":[{"line_number":53,"context_line":"      - $ENVIRON[\u0027AGGA_UUID\u0027]"},{"line_number":54,"context_line":"  status: 200"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"- name: verify that the member_of call now returns 1 RP"},{"line_number":57,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":58,"context_line":"  status: 200"},{"line_number":59,"context_line":"  response_json_paths:"}],"source_content_type":"text/x-yaml","patch_set":6,"id":"df7087c5_26758dcb","line":56,"in_reply_to":"df7087c5_92905b45","updated":"2018-03-14 19:45:00.000000000","message":"Done","commit_id":"0053b36ecabdfb10e7b5471fdd687b409ef1ce0f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"2c57cc8c5c710f258c78acdb53aadc703026c1e1","unresolved":false,"context_lines":[{"line_number":47,"context_line":"  response_json_paths:"},{"line_number":48,"context_line":"      $.allocation_requests.`len`: 0"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"- name: associate the first compute node with aggA"},{"line_number":51,"context_line":"  PUT: /resource_providers/$ENVIRON[\u0027CN1_UUID\u0027]/aggregates"},{"line_number":52,"context_line":"  data:"},{"line_number":53,"context_line":"      - $ENVIRON[\u0027AGGA_UUID\u0027]"},{"line_number":54,"context_line":"  status: 200"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"- name: verify that the member_of call now returns 1 allocation_candidate"},{"line_number":57,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"}],"source_content_type":"text/x-yaml","patch_set":8,"id":"df7087c5_fdf6088f","line":54,"range":{"start_line":50,"start_character":0,"end_line":54,"end_character":13},"updated":"2018-03-16 16:00:06.000000000","message":"Oh, yeah, this needs to be a dict with a generation.  See these [1] por ejemplo.\n\n[1] https://review.openstack.org/#/c/548249/7/nova/tests/functional/api/openstack/placement/gabbits/resource-provider-aggregates.yaml","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":47,"context_line":"  response_json_paths:"},{"line_number":48,"context_line":"      $.allocation_requests.`len`: 0"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"- name: associate the first compute node with aggA"},{"line_number":51,"context_line":"  PUT: /resource_providers/$ENVIRON[\u0027CN1_UUID\u0027]/aggregates"},{"line_number":52,"context_line":"  data:"},{"line_number":53,"context_line":"      - $ENVIRON[\u0027AGGA_UUID\u0027]"},{"line_number":54,"context_line":"  status: 200"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"- name: verify that the member_of call now returns 1 allocation_candidate"},{"line_number":57,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"}],"source_content_type":"text/x-yaml","patch_set":8,"id":"df7087c5_8165f9e3","line":54,"range":{"start_line":50,"start_character":0,"end_line":54,"end_character":13},"in_reply_to":"df7087c5_fdf6088f","updated":"2018-03-19 18:52:42.000000000","message":"Done","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83954d675e92ec9e35354a3e7500756c5ca41445","unresolved":false,"context_lines":[{"line_number":64,"context_line":"  data:"},{"line_number":65,"context_line":"      - $ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":66,"context_line":"  status: 200"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"- name: verify that the member_of call now returns both RPs"},{"line_number":69,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":70,"context_line":"  status: 200"}],"source_content_type":"text/x-yaml","patch_set":8,"id":"df7087c5_7da0b8f4","line":67,"updated":"2018-03-16 15:47:14.000000000","message":"Perhaps a test case where one of the computes is associated with multiple aggs to make sure we\u0027re not being exclusionary.  E.g. CN1[aggA, aggD], request with [aggA, aggB] and we should still get CN1.","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"7ff7603b9a472247fa013c4434b6fb7837f722ab","unresolved":false,"context_lines":[{"line_number":64,"context_line":"  data:"},{"line_number":65,"context_line":"      - $ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":66,"context_line":"  status: 200"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"- name: verify that the member_of call now returns both RPs"},{"line_number":69,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1,MEMORY_MB:1024,DISK_GB:100\u0026member_of\u003din:$ENVIRON[\u0027AGGA_UUID\u0027],$ENVIRON[\u0027AGGB_UUID\u0027]"},{"line_number":70,"context_line":"  status: 200"}],"source_content_type":"text/x-yaml","patch_set":8,"id":"df7087c5_61f785d6","line":67,"in_reply_to":"df7087c5_7da0b8f4","updated":"2018-03-19 18:52:42.000000000","message":"Done","commit_id":"2cbac1a7df7fdb985f52ddde7302815aa38ce1ec"}],"nova/tests/functional/api/openstack/placement/gabbits/allocation-candidates.yaml":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"7f05fca545b1d75ed4ec2c84a87bcf0673adb679","unresolved":false,"context_lines":[{"line_number":79,"context_line":"      - Invalid query string parameters"},{"line_number":80,"context_line":"      - \"Failed validating \u0027pattern\u0027\""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"- name: get bad member_of microversion"},{"line_number":83,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1\u0026member_of\u003din:f2634e5f-dfa2-45cc-addb-89815e917174,57492c1c-680a-472e-bd57-1f81e6c4a30b"},{"line_number":84,"context_line":"  request_headers:"},{"line_number":85,"context_line":"      openstack-api-version: placement 1.18"}],"source_content_type":"text/x-yaml","patch_set":1,"id":"df7087c5_1a01eb05","line":82,"updated":"2018-03-13 11:13:31.000000000","message":"Where are the gabbits that demonstrate it working. Was a \u0027git add\u0027 forgotten?","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9d826705f514b22766dd3aab8d5e27797673c439","unresolved":false,"context_lines":[{"line_number":79,"context_line":"      - Invalid query string parameters"},{"line_number":80,"context_line":"      - \"Failed validating \u0027pattern\u0027\""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"- name: get bad member_of microversion"},{"line_number":83,"context_line":"  GET: /allocation_candidates?resources\u003dVCPU:1\u0026member_of\u003din:f2634e5f-dfa2-45cc-addb-89815e917174,57492c1c-680a-472e-bd57-1f81e6c4a30b"},{"line_number":84,"context_line":"  request_headers:"},{"line_number":85,"context_line":"      openstack-api-version: placement 1.18"}],"source_content_type":"text/x-yaml","patch_set":1,"id":"df7087c5_00117aac","line":82,"in_reply_to":"df7087c5_1a01eb05","updated":"2018-03-13 12:29:24.000000000","message":"When I posted this, it was so that Jay could double-check the join logic. I mentioned on IRC that the tests would be coming in the next patch. Guess I should have mentioned it here, too.","commit_id":"e4e65b0d5deefca59ab3f6de23296d407c2d1f4d"}],"placement-api-ref/source/allocation_candidates.inc":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"91a9fa5db40589082a4a1d385f8ae0fe9fc228dd","unresolved":false,"context_lines":[{"line_number":32,"context_line":"  - resources: resources_query_required"},{"line_number":33,"context_line":"  - limit: allocation_candidates_limit"},{"line_number":34,"context_line":"  - required: allocation_candidates_required"},{"line_number":35,"context_line":"  - member_of: member_of"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"Response (microversions 1.12 - )"},{"line_number":38,"context_line":"--------------------------------"}],"source_content_type":"text/x-c++src","patch_set":9,"id":"bf659307_4b7c90b4","line":35,"updated":"2018-03-28 15:33:20.000000000","message":"This is using microversion 1.3 because it\u0027s specific to GET /resource_providers, not allocation_candidates.","commit_id":"a69e05d29a518e00f9a5b6d7e31fa7e4a0829023"}],"releasenotes/notes/allocation_candidates_support_member_of-92f7e1440ed63fe7.yaml":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"eab9e0804cc853c35f790788576a51beb512448c","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add support, in a new placement microversion 1.19, for the ``member_of``"},{"line_number":5,"context_line":"    query parameteri, representing one or more aggregate UUIDs. When supplied,"},{"line_number":6,"context_line":"    it will filter the returned allocation candidates to only those"},{"line_number":7,"context_line":"    resource_providers that are associated with (\"members of\") the specified"},{"line_number":8,"context_line":"    aggregate(s). This parameter can have a value of either a single aggregate"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"df7087c5_7d9b2617","line":5,"range":{"start_line":5,"start_character":10,"end_line":5,"end_character":20},"updated":"2018-03-14 08:30:43.000000000","message":"s/parameteri/parameter/","commit_id":"a4040691dc46bdb6425d5b7f85e5344cd18fa692"}]}
