)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":10,"context_line":"    https://review.openstack.org/#/c/626420/"},{"line_number":11,"context_line":"and its dependencies."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Depends-On: https://review.openstack.org/#/c/631242/"},{"line_number":14,"context_line":"Change-Id: Icd2ee9024dd4af0a7eb105eca14df8e458e9de77"},{"line_number":15,"context_line":"Blueprint: nova-cyborg-interaction"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"9fdfeff1_40f8657b","line":13,"range":{"start_line":13,"start_character":0,"end_line":13,"end_character":52},"updated":"2019-02-05 17:00:17.000000000","message":"This is not needed; it\u0027s the previous patch in this series.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"75ae62619114bbd75df36270da9347625d6719a4","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2019-02-06 21:59:40 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"WIP: Add Cyborg device profile groups to spec obj."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For Cyborg code, see:"},{"line_number":10,"context_line":"    https://review.openstack.org/#/c/626420/"},{"line_number":11,"context_line":"and its dependencies."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"9fdfeff1_172b3830","line":8,"updated":"2019-02-08 23:08:36.000000000","message":"More words here would be helpful. Something like:\n\nFind device profile groups named in flavor extra specs. Pull their contents from the cyborg API. Convert those contents to request groups. Add those groups to the request spec so they become part of the scheduling request and resulting allocations.","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":12,"context_line":"Generate RequestGroup objects and add them to the request spec"},{"line_number":13,"context_line":"   (in requested_resources field, following precedent)."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Depends-On: https://review.opendev.org/#/c/674520"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: Icd2ee9024dd4af0a7eb105eca14df8e458e9de77"},{"line_number":18,"context_line":"Blueprint: nova-cyborg-interaction"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":43,"id":"3fa7e38b_9f1484a1","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":49},"updated":"2019-11-26 22:31:57.000000000","message":"merged, can be removed.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":12,"context_line":"Generate RequestGroup objects and add them to the request spec"},{"line_number":13,"context_line":"   (in requested_resources field, following precedent)."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Depends-On: https://review.opendev.org/#/c/674520"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: Icd2ee9024dd4af0a7eb105eca14df8e458e9de77"},{"line_number":18,"context_line":"Blueprint: nova-cyborg-interaction"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":43,"id":"3fa7e38b_7fcc21bb","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":49},"in_reply_to":"3fa7e38b_9f1484a1","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"}],"nova/accelerator/cyborg.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_20f9a14c","line":38,"range":{"start_line":38,"start_character":4,"end_line":38,"end_character":40},"updated":"2019-02-05 17:00:17.000000000","message":"I don\u0027t think you have to do this anymore.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_65feceaf","line":38,"range":{"start_line":38,"start_character":4,"end_line":38,"end_character":40},"in_reply_to":"9fdfeff1_20f9a14c","updated":"2019-02-07 06:06:36.000000000","message":"\u0027extra_specs\u0027 could be None, so we need to check before dereferencing it. In any case, I moved this as a property under request_spec.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_cc50c761","line":38,"range":{"start_line":38,"start_character":4,"end_line":38,"end_character":40},"in_reply_to":"9fdfeff1_65feceaf","updated":"2019-02-08 23:03:43.000000000","message":"I confirmed that, irl, flavor.extra_specs is a) always present, b) always a dict (though possibly empty). So you can say\n\n dpname \u003d spec_obj.flavor.extra_specs.get(\u0027accel:device_profile\u0027)\n\nSo there\u0027s no need to do this checking or have a whole method, here or in Flavor. Just inline ^.\n\n[Later] but there\u0027s a bug in the setup of the fake spec obj (code that existed before you got here). I marked the fix for it in fake_flavor.py.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_3771d70d","line":38,"range":{"start_line":38,"start_character":4,"end_line":38,"end_character":40},"in_reply_to":"9fdfeff1_cc50c761","updated":"2019-02-20 05:58:09.000000000","message":"Done, except that, to avoid scattering \u0027accel:device_profile\u0027 all around, I localized that in objects/flavor.py as a property.\n\nWill get to UT in a subsequent commit.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"},{"line_number":42,"context_line":"                return val"},{"line_number":43,"context_line":"    return None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_00e33da6","line":42,"range":{"start_line":40,"start_character":0,"end_line":42,"end_character":26},"updated":"2019-02-05 17:00:17.000000000","message":"This is kind of ew. Why not\n\n return extra_specs.get(\u0027accel:device_profile\u0027)\n\n...which is O(1) and returns None if the key isn\u0027t present.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":37,"context_line":"def get_device_profile_name(spec_obj):"},{"line_number":38,"context_line":"    if \"extra_specs\" in spec_obj.flavor:"},{"line_number":39,"context_line":"        extra_specs \u003d spec_obj.flavor.extra_specs"},{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"},{"line_number":42,"context_line":"                return val"},{"line_number":43,"context_line":"    return None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_a5235605","line":42,"range":{"start_line":40,"start_character":0,"end_line":42,"end_character":26},"in_reply_to":"9fdfeff1_00e33da6","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"},{"line_number":42,"context_line":"                return val"},{"line_number":43,"context_line":"    return None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class _CyborgClient(object):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_408705b8","line":43,"updated":"2019-02-05 17:00:17.000000000","message":"So I\u0027m pretty sure this method isn\u0027t needed; you should just be able to say\n\n spec_obj.flavor.extra_specs.get(\u0027accel:device_profile\u0027)\n\nwhere you need it.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"},{"line_number":42,"context_line":"                return val"},{"line_number":43,"context_line":"    return None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class _CyborgClient(object):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_f764af4b","line":43,"in_reply_to":"9fdfeff1_052d8245","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        for key, val in extra_specs.items():"},{"line_number":41,"context_line":"            if key \u003d\u003d \u0027accel:device_profile\u0027:"},{"line_number":42,"context_line":"                return val"},{"line_number":43,"context_line":"    return None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class _CyborgClient(object):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_052d8245","line":43,"in_reply_to":"9fdfeff1_408705b8","updated":"2019-02-07 06:06:36.000000000","message":"We need to verify extra_specs is not None before calling get(). Every caller could do that; making it a property in request_spec makes it DRY.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class _CyborgClient(object):"},{"line_number":47,"context_line":"    def __init__(self):"},{"line_number":48,"context_line":"        # import remote_pdb; remote_pdb.set_trace(port\u003d12345)"},{"line_number":49,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_0091fdf1","line":48,"range":{"start_line":48,"start_character":8,"end_line":48,"end_character":61},"updated":"2019-02-05 17:00:17.000000000","message":"x","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class _CyborgClient(object):"},{"line_number":47,"context_line":"    def __init__(self):"},{"line_number":48,"context_line":"        # import remote_pdb; remote_pdb.set_trace(port\u003d12345)"},{"line_number":49,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_85265216","line":48,"range":{"start_line":48,"start_character":8,"end_line":48,"end_character":61},"in_reply_to":"9fdfeff1_0091fdf1","updated":"2019-02-07 06:06:36.000000000","message":"Ok","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        # import remote_pdb; remote_pdb.set_trace(port\u003d12345)"},{"line_number":49,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_83a97791","line":51,"range":{"start_line":51,"start_character":8,"end_line":51,"end_character":33},"updated":"2019-02-05 17:00:17.000000000","message":"docstring would be neat, especially to describe the shape of the return, which afaict is\n\n a list of\n   tuples of\n     0) dict of resource amounts, keyed by resource class\n     1) set of string names of required traits\n     2) set of string names of forbidden traits","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        # import remote_pdb; remote_pdb.set_trace(port\u003d12345)"},{"line_number":49,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_a53a7631","line":51,"range":{"start_line":51,"start_character":8,"end_line":51,"end_character":33},"in_reply_to":"9fdfeff1_83a97791","updated":"2019-02-07 06:06:36.000000000","message":"Ok","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        url \u003d \"/device_profiles\""},{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_80b64d8a","line":53,"range":{"start_line":53,"start_character":12,"end_line":53,"end_character":23},"updated":"2019-02-05 17:00:17.000000000","message":"this should eventually be an error?","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        url \u003d \"/device_profiles\""},{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_e5eabeaa","line":53,"range":{"start_line":53,"start_character":12,"end_line":53,"end_character":23},"in_reply_to":"9fdfeff1_80b64d8a","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        url \u003d \"/device_profiles\""},{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":57,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        if r.status_code !\u003d requests.codes.ok:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_207c41b4","line":56,"range":{"start_line":55,"start_character":0,"end_line":56,"end_character":33},"updated":"2019-02-05 17:00:17.000000000","message":"Remind me why you decided to make the API\n \n GET /device_profiles?name\u003dfoo\n\nrather than\n\n GET /device_profiles/foo\n\n?","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        if dp_name is None:"},{"line_number":53,"context_line":"            return None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        url \u003d \"/device_profiles\""},{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":57,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        if r.status_code !\u003d requests.codes.ok:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_45f2aa9c","line":56,"range":{"start_line":55,"start_character":0,"end_line":56,"end_character":33},"in_reply_to":"9fdfeff1_207c41b4","updated":"2019-02-07 06:06:36.000000000","message":"Because this is a collections API. See:\nhttps://developer.openstack.org/api-ref/network/v2/index.html#networks","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":57,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        if r.status_code !\u003d requests.codes.ok:"},{"line_number":60,"context_line":"            return None"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        ret_dict \u003d r.json()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_e07cf9ec","line":59,"range":{"start_line":59,"start_character":0,"end_line":59,"end_character":46},"updated":"2019-02-05 17:00:17.000000000","message":"The response object overrides __bool__ making the object evaluate as True when the status code is one of the good ones; so the idiom is simply to ask\n\n if r:\n\nThis saves a) having to import `requests` directly (which made me ook); and b) having to do things like figure out whether your API might sometimes return 204 vs 200 vs 201 or whatever.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":57,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        if r.status_code !\u003d requests.codes.ok:"},{"line_number":60,"context_line":"            return None"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        ret_dict \u003d r.json()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_65efaeb0","line":59,"range":{"start_line":59,"start_character":0,"end_line":59,"end_character":46},"in_reply_to":"9fdfeff1_e07cf9ec","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":60,"context_line":"            return None"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        ret_dict \u003d r.json()"},{"line_number":63,"context_line":"        dp_list \u003d ret_dict[\u0027device_profiles\u0027]"},{"line_number":64,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":65,"context_line":"            LOG.error(\u0027Expected 1 device profile but got %s\u0027, len(dp_list))"},{"line_number":66,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_8355f7fc","line":63,"updated":"2019-02-05 17:00:17.000000000","message":"Would be neat to include a comment here with an example of what the response dict looks like.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":60,"context_line":"            return None"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"        ret_dict \u003d r.json()"},{"line_number":63,"context_line":"        dp_list \u003d ret_dict[\u0027device_profiles\u0027]"},{"line_number":64,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":65,"context_line":"            LOG.error(\u0027Expected 1 device profile but got %s\u0027, len(dp_list))"},{"line_number":66,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_257d26e7","line":63,"in_reply_to":"9fdfeff1_8355f7fc","updated":"2019-02-07 06:06:36.000000000","message":"I put in a reference to cyborg/cyborg/objects/device_profile.py, so that changes don\u0027t make this comment obsolete.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        ret_dict \u003d r.json()"},{"line_number":63,"context_line":"        dp_list \u003d ret_dict[\u0027device_profiles\u0027]"},{"line_number":64,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":65,"context_line":"            LOG.error(\u0027Expected 1 device profile but got %s\u0027, len(dp_list))"},{"line_number":66,"context_line":"            return None"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        dp_json \u003d dp_list[0][\u0027json\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_0006dd21","line":65,"range":{"start_line":65,"start_character":58,"end_line":65,"end_character":59},"updated":"2019-02-05 17:00:17.000000000","message":"d","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        ret_dict \u003d r.json()"},{"line_number":63,"context_line":"        dp_list \u003d ret_dict[\u0027device_profiles\u0027]"},{"line_number":64,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":65,"context_line":"            LOG.error(\u0027Expected 1 device profile but got %s\u0027, len(dp_list))"},{"line_number":66,"context_line":"            return None"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        dp_json \u003d dp_list[0][\u0027json\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_45206af8","line":65,"range":{"start_line":65,"start_character":58,"end_line":65,"end_character":59},"in_reply_to":"9fdfeff1_0006dd21","updated":"2019-02-07 06:06:36.000000000","message":"Printing as string works fine too, but anyhoo: Done.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            return None"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        dp_json \u003d dp_list[0][\u0027json\u0027]"},{"line_number":69,"context_line":"        dp_dict \u003d jsonutils.loads(dp_json)"},{"line_number":70,"context_line":"        dp_groups \u003d dp_dict[\u0027groups\u0027]"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        nova_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_23468b51","line":69,"range":{"start_line":69,"start_character":18,"end_line":69,"end_character":42},"updated":"2019-02-05 17:00:17.000000000","message":"right, so here\u0027s what I was talking about before: I would prefer if we didn\u0027t need this step - if the dp_dict was already a dict.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        dp_dict \u003d jsonutils.loads(dp_json)"},{"line_number":70,"context_line":"        dp_groups \u003d dp_dict[\u0027groups\u0027]"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        nova_groups \u003d []"},{"line_number":73,"context_line":"        for group in dp_groups:"},{"line_number":74,"context_line":"            # Skip \u0027accel\u0027 properties"},{"line_number":75,"context_line":"            # Keep just the Placement-relevant keys"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_a32b5b2e","line":72,"updated":"2019-02-05 17:00:17.000000000","message":"Should find a way to reuse nova.scheduler.utils.ResourceRequest.from_extra_specs","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        dp_dict \u003d jsonutils.loads(dp_json)"},{"line_number":70,"context_line":"        dp_groups \u003d dp_dict[\u0027groups\u0027]"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        nova_groups \u003d []"},{"line_number":73,"context_line":"        for group in dp_groups:"},{"line_number":74,"context_line":"            # Skip \u0027accel\u0027 properties"},{"line_number":75,"context_line":"            # Keep just the Placement-relevant keys"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_77d51fb7","line":72,"in_reply_to":"9fdfeff1_4c7cd7ea","updated":"2019-02-20 05:58:09.000000000","message":"Reusing the parsing/validation logic from extra_specs took some careful refactoring in ResourceRequest class in scheduler/utils.py. Done in next commit.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        dp_dict \u003d jsonutils.loads(dp_json)"},{"line_number":70,"context_line":"        dp_groups \u003d dp_dict[\u0027groups\u0027]"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        nova_groups \u003d []"},{"line_number":73,"context_line":"        for group in dp_groups:"},{"line_number":74,"context_line":"            # Skip \u0027accel\u0027 properties"},{"line_number":75,"context_line":"            # Keep just the Placement-relevant keys"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_4c7cd7ea","line":72,"in_reply_to":"9fdfeff1_65e00e98","updated":"2019-02-08 23:03:43.000000000","message":"?\n\n[Later] I see that you are now returning RequestGroup instead of the components thereof. That\u0027s an improvement. But what I meant was actually calling nova.scheduler.utils.ResourceRequest.from_extra_specs (which you might have to modify slightly, I think) and cutting out all of this code that parses the fields.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        dp_dict \u003d jsonutils.loads(dp_json)"},{"line_number":70,"context_line":"        dp_groups \u003d dp_dict[\u0027groups\u0027]"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        nova_groups \u003d []"},{"line_number":73,"context_line":"        for group in dp_groups:"},{"line_number":74,"context_line":"            # Skip \u0027accel\u0027 properties"},{"line_number":75,"context_line":"            # Keep just the Placement-relevant keys"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_65e00e98","line":72,"in_reply_to":"9fdfeff1_a32b5b2e","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            required_traits \u003d set()"},{"line_number":78,"context_line":"            forbidden_traits \u003d set()"},{"line_number":79,"context_line":"            for k, v in group.items():"},{"line_number":80,"context_line":"                if k.startswith(\u0027resources:\u0027):"},{"line_number":81,"context_line":"                    key \u003d k[len(\u0027resources:\u0027):]"},{"line_number":82,"context_line":"                    resources[key] \u003d v"},{"line_number":83,"context_line":"                elif k.startswith(\u0027trait:\u0027):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_c3ba1fe0","line":80,"range":{"start_line":80,"start_character":33,"end_line":80,"end_character":42},"updated":"2019-02-05 17:00:17.000000000","message":"will we eventually want to support granular (numeric suffixes)?","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            required_traits \u003d set()"},{"line_number":78,"context_line":"            forbidden_traits \u003d set()"},{"line_number":79,"context_line":"            for k, v in group.items():"},{"line_number":80,"context_line":"                if k.startswith(\u0027resources:\u0027):"},{"line_number":81,"context_line":"                    key \u003d k[len(\u0027resources:\u0027):]"},{"line_number":82,"context_line":"                    resources[key] \u003d v"},{"line_number":83,"context_line":"                elif k.startswith(\u0027trait:\u0027):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_b7ece78f","line":80,"range":{"start_line":80,"start_character":33,"end_line":80,"end_character":42},"in_reply_to":"9fdfeff1_2c7953fb","updated":"2019-02-20 05:58:09.000000000","message":"Reuse of extra_specs parsng/validation removes the need for this.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            required_traits \u003d set()"},{"line_number":78,"context_line":"            forbidden_traits \u003d set()"},{"line_number":79,"context_line":"            for k, v in group.items():"},{"line_number":80,"context_line":"                if k.startswith(\u0027resources:\u0027):"},{"line_number":81,"context_line":"                    key \u003d k[len(\u0027resources:\u0027):]"},{"line_number":82,"context_line":"                    resources[key] \u003d v"},{"line_number":83,"context_line":"                elif k.startswith(\u0027trait:\u0027):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_2c7953fb","line":80,"range":{"start_line":80,"start_character":33,"end_line":80,"end_character":42},"in_reply_to":"9fdfeff1_654b2eb0","updated":"2019-02-08 23:03:43.000000000","message":"It\u0027s not about an array index. It\u0027s about grouping the requests to come from the same or different providers. http://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/granular-resource-requests.html","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            required_traits \u003d set()"},{"line_number":78,"context_line":"            forbidden_traits \u003d set()"},{"line_number":79,"context_line":"            for k, v in group.items():"},{"line_number":80,"context_line":"                if k.startswith(\u0027resources:\u0027):"},{"line_number":81,"context_line":"                    key \u003d k[len(\u0027resources:\u0027):]"},{"line_number":82,"context_line":"                    resources[key] \u003d v"},{"line_number":83,"context_line":"                elif k.startswith(\u0027trait:\u0027):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_654b2eb0","line":80,"range":{"start_line":80,"start_character":33,"end_line":80,"end_character":42},"in_reply_to":"9fdfeff1_c3ba1fe0","updated":"2019-02-07 06:06:36.000000000","message":"No. Device profile groups form a Python/JSON list, so the index is easily obtained.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                        forbidden_traits.add(key)"},{"line_number":89,"context_line":"                    else:"},{"line_number":90,"context_line":"                        # Should never happen for validated device profiles"},{"line_number":91,"context_line":"                        raise RuntimeError(\u0027Unknown trait \u0027 + k)"},{"line_number":92,"context_line":"            nova_groups.append((resources,"},{"line_number":93,"context_line":"                                required_traits, forbidden_traits))"},{"line_number":94,"context_line":"        return nova_groups"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_c39f7f63","line":91,"range":{"start_line":91,"start_character":24,"end_line":91,"end_character":64},"updated":"2019-02-05 17:00:17.000000000","message":"The error here is in fact that the *value* was not one of \u0027required\u0027 or \u0027forbidden\u0027. The error message implies that we\u0027re doing some kind of trait validation, which we\u0027re not.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                        forbidden_traits.add(key)"},{"line_number":89,"context_line":"                    else:"},{"line_number":90,"context_line":"                        # Should never happen for validated device profiles"},{"line_number":91,"context_line":"                        raise RuntimeError(\u0027Unknown trait \u0027 + k)"},{"line_number":92,"context_line":"            nova_groups.append((resources,"},{"line_number":93,"context_line":"                                required_traits, forbidden_traits))"},{"line_number":94,"context_line":"        return nova_groups"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_05efc287","line":91,"range":{"start_line":91,"start_character":24,"end_line":91,"end_character":64},"in_reply_to":"9fdfeff1_c39f7f63","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":47,"context_line":"           :returns [RequestGroup]"},{"line_number":48,"context_line":"        \"\"\""},{"line_number":49,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":50,"context_line":"            raise RuntimeError(\u0027Device profile name is invalid\u0027)"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"        url \u003d \"/device_profiles\""},{"line_number":53,"context_line":"        query \u003d {\"name\": dp_name}"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_2c62b33f","line":50,"range":{"start_line":50,"start_character":31,"end_line":50,"end_character":63},"updated":"2019-02-08 23:03:43.000000000","message":"exceptions need to be translated","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        if not r:"},{"line_number":57,"context_line":"            return None"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        # See cyborg/cyborg/objects/device_profile.py for"},{"line_number":60,"context_line":"        #    what fields constitute a device profile."}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_2c14f39f","line":57,"range":{"start_line":57,"start_character":19,"end_line":57,"end_character":23},"updated":"2019-02-08 23:03:43.000000000","message":"If this is an error, it should raise something. If it\u0027s not an error, it should return [].","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        dp_list \u003d r.json().get(\u0027device_profiles\u0027)"},{"line_number":62,"context_line":"        if dp_list is not None and len(dp_list) !\u003d 1:"},{"line_number":63,"context_line":"            LOG.error(\u0027Expected 1 device profile but got %d\u0027, len(dp_list))"},{"line_number":64,"context_line":"            return None"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"        dp_json \u003d dp_list[0][\u0027json\u0027]"},{"line_number":67,"context_line":"        # FIXME Return JSON from Cyborg API"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_4c65b744","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":23},"updated":"2019-02-08 23:03:43.000000000","message":"ditto","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":86,"context_line":"                        forbidden_traits.add(key)"},{"line_number":87,"context_line":"                    else:"},{"line_number":88,"context_line":"                        # Should never happen for validated device profiles"},{"line_number":89,"context_line":"                        raise RuntimeError(\u0027Unknown value \u0027 + v +"},{"line_number":90,"context_line":"                                           \u0027 for trait \u0027 + k)"},{"line_number":91,"context_line":"            rg \u003d objects.RequestGroup(resources\u003dresources,"},{"line_number":92,"context_line":"                                      required_traits\u003drequired_traits,"},{"line_number":93,"context_line":"                                      forbidden_traits\u003dforbidden_traits"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_cc676751","line":90,"range":{"start_line":89,"start_character":43,"end_line":90,"end_character":60},"updated":"2019-02-08 23:03:43.000000000","message":"exceptions need to be translated (and therefore the variables parameterized)","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"11c02b65632dc4f2cec5e1d073b1c8f7892fe464","unresolved":false,"context_lines":[{"line_number":25,"context_line":"   Each numbered RG corresponds to exactly one resource provider (RP)."},{"line_number":26,"context_line":"   A DP request group may request A \u003e\u003d 1 accelerators, and so result"},{"line_number":27,"context_line":"       in the creation of A ARQs."},{"line_number":28,"context_line":"   Each ARQ corresponds to exactly 1 DP request group."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"   A device profile is a dictionary:"},{"line_number":31,"context_line":"   { \"name\": \"mydpname\","}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_48495ab5","line":28,"range":{"start_line":28,"start_character":40,"end_line":28,"end_character":54},"updated":"2019-03-05 04:14:34.000000000","message":"you call it \"profile group\" below...","commit_id":"d90cc9cc37686d080e06173aed9b01752f5a9a07"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"11c02b65632dc4f2cec5e1d073b1c8f7892fe464","unresolved":false,"context_lines":[{"line_number":30,"context_line":"   A device profile is a dictionary:"},{"line_number":31,"context_line":"   { \"name\": \"mydpname\","},{"line_number":32,"context_line":"     \"uuid\": \u003cuuid\u003e,"},{"line_number":33,"context_line":"     \"profile_groups\": [ {\"group\": \u003cdevice_profile_group\u003e} ]"},{"line_number":34,"context_line":"   }"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"   A device profile group is a dictionary too:"}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_a858068a","line":33,"range":{"start_line":33,"start_character":6,"end_line":33,"end_character":20},"updated":"2019-03-05 04:14:34.000000000","message":"\"profile groups\" sounds like this is a group of device profiles. This isn\u0027t. It\u0027s a component of a *single* device profile which contains groups of resource requests (with some device configuration tags/properties). Recommend calling it \"request_groups\".","commit_id":"d90cc9cc37686d080e06173aed9b01752f5a9a07"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"5b15cee6ddd4e9d77881948b5ef73ddf28ed1d83","unresolved":false,"context_lines":[{"line_number":30,"context_line":"   A device profile is a dictionary:"},{"line_number":31,"context_line":"   { \"name\": \"mydpname\","},{"line_number":32,"context_line":"     \"uuid\": \u003cuuid\u003e,"},{"line_number":33,"context_line":"     \"profile_groups\": [ {\"group\": \u003cdevice_profile_group\u003e} ]"},{"line_number":34,"context_line":"   }"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"   A device profile group is a dictionary too:"}],"source_content_type":"text/x-python","patch_set":15,"id":"5fc1f717_1eb702db","line":33,"range":{"start_line":33,"start_character":6,"end_line":33,"end_character":20},"in_reply_to":"9fdfeff1_a858068a","updated":"2019-03-21 04:47:11.000000000","message":"Agreed. I am a little wary of calling it by the exact same name as the corresponding Nova concept, because this one has Cyborg-specific key-value pairs (properties). How about we just call it \u0027groups\u0027, and clarify in the comments/doc how they relate to Nova\u0027s RGs?","commit_id":"d90cc9cc37686d080e06173aed9b01752f5a9a07"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"11c02b65632dc4f2cec5e1d073b1c8f7892fe464","unresolved":false,"context_lines":[{"line_number":38,"context_line":"     \"resources:BAR\": \"1\","},{"line_number":39,"context_line":"     \"trait:A\": \"required\","},{"line_number":40,"context_line":"     \"trait:B\": \"forbidden\","},{"line_number":41,"context_line":"     \"accel:property1\": \"value\" # 0 or more Cyborg properties"},{"line_number":42,"context_line":"   }"},{"line_number":43,"context_line":"   See cyborg/cyborg/objects/device_profile.py for more details."},{"line_number":44,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"9fdfeff1_6869be24","line":41,"updated":"2019-03-05 04:14:34.000000000","message":"a) Why not call it a request group, since that\u0027s what it is?\n\nb) Why not structure this request group like so:\n\n {\n   \"resources\": {\n     \"CUSTOM_FOO\": 2,\n     \"CUSTOM_BAR\": 1\n   },\n   \"required\": [\n     \"CUSTOM_A\"\n   ],\n   \"forbidden\": [\n     \"CUSTOM_B\"\n   ],\n   \"properties\": {\n     \"property1\": \"value\"\n   }\n }\n\nc) Instead of \"FOO\", \"BAR\", \"A\" , \"B\" and \"property1\", it would be great to have realistic resource classes, trait identifiers, and properties so that the reader of the code gets a better idea of how this stuff lines up.","commit_id":"d90cc9cc37686d080e06173aed9b01752f5a9a07"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"5b15cee6ddd4e9d77881948b5ef73ddf28ed1d83","unresolved":false,"context_lines":[{"line_number":38,"context_line":"     \"resources:BAR\": \"1\","},{"line_number":39,"context_line":"     \"trait:A\": \"required\","},{"line_number":40,"context_line":"     \"trait:B\": \"forbidden\","},{"line_number":41,"context_line":"     \"accel:property1\": \"value\" # 0 or more Cyborg properties"},{"line_number":42,"context_line":"   }"},{"line_number":43,"context_line":"   See cyborg/cyborg/objects/device_profile.py for more details."},{"line_number":44,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":15,"id":"5fc1f717_65bdf800","line":41,"in_reply_to":"9fdfeff1_6869be24","updated":"2019-03-21 04:47:11.000000000","message":"\u003e a) Why not call it a request group, since that\u0027s what it is?\n\nWill do.\n\n \u003e b) Why not structure this request group like so:\n\nThis is designed to look like extra specs, because:\nA. A device profile is just \u0027flavor for devices\u0027. Had we not created the concept of a DP, this would have been part of the extra specs. Operators are familiar with that syntax.\nB. We leverage the parsing/validation code for extra specs. \n\n \u003e c) Instead of \"FOO\", \"BAR\", \"A\" , \"B\" and \"property1\", it would be\n \u003e great to have realistic resource classes, trait identifiers, and\n \u003e properties so that the reader of the code gets a better idea of how\n \u003e this stuff lines up.\n\nOK.","commit_id":"d90cc9cc37686d080e06173aed9b01752f5a9a07"},{"author":{"_account_id":28748,"name":"chenker","email":"chen.ke14@zte.com.cn","username":"chenke"},"change_message_id":"cd83d4d4d7c056d4b83b2a28c7fd34ae498e73fb","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"   A device profile group is a dictionary too:"},{"line_number":38,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","},{"line_number":39,"context_line":"      \"resources:CUSTOM_LOCAL_MEMORY\": \"1\","},{"line_number":40,"context_line":"      \"trait:CUSTOM_INTEL_PAC_ARRIA10\": \"required\","},{"line_number":41,"context_line":"      \"trait:CUSTOM_FUNCTION_NAME_FALCON_GZIP_1_1\": \"required\","},{"line_number":42,"context_line":"       # 0 or more Cyborg properties"}],"source_content_type":"text/x-python","patch_set":34,"id":"7faddb67_8399546e","line":39,"range":{"start_line":39,"start_character":6,"end_line":39,"end_character":43},"updated":"2019-08-27 11:52:43.000000000","message":"Hi, Sundar Nadathur.Could you explain to me the relationship between \"CUSTOM_LOCAL_MEMOR\" and the above \"CUSTOM_ACCELERATOR_FPGA\", do they correspond to the same RP? thank you very much.","commit_id":"a7cc557b10707d09b52a2aac07143fd659aad69e"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"c1309bbf9b5c0a258d59dec3cc86b9da073fbbf1","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"   A device profile group is a dictionary too:"},{"line_number":38,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","},{"line_number":39,"context_line":"      \"resources:CUSTOM_LOCAL_MEMORY\": \"1\","},{"line_number":40,"context_line":"      \"trait:CUSTOM_INTEL_PAC_ARRIA10\": \"required\","},{"line_number":41,"context_line":"      \"trait:CUSTOM_FUNCTION_NAME_FALCON_GZIP_1_1\": \"required\","},{"line_number":42,"context_line":"       # 0 or more Cyborg properties"}],"source_content_type":"text/x-python","patch_set":34,"id":"7faddb67_12dfdb38","line":39,"range":{"start_line":39,"start_character":6,"end_line":39,"end_character":43},"in_reply_to":"7faddb67_8399546e","updated":"2019-08-28 06:33:03.000000000","message":"Hi chenker, all resources requested in the same numbered request group (RG) must come from the same RP, as per [1]. A device profile request group will always be included by Nova as a numbered RG by design. So, the answer is yes.\n\n[1] https://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/granular-resource-requests.html","commit_id":"a7cc557b10707d09b52a2aac07143fd659aad69e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":21,"context_line":"   Note on object relationships:"},{"line_number":22,"context_line":"   1 device profile (DP) has D \u003e\u003d 1 request groups (just as a flavor"},{"line_number":23,"context_line":"       has many request groups)."},{"line_number":24,"context_line":"   Each DP request group corresponds to exactly 1 numbered request"},{"line_number":25,"context_line":"       group (RG) in the request spec."},{"line_number":26,"context_line":"   Each numbered RG corresponds to exactly one resource provider (RP)."},{"line_number":27,"context_line":"   A DP request group may request A \u003e\u003d 1 accelerators, and so result"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_5f9fec01","line":24,"range":{"start_line":24,"start_character":50,"end_line":24,"end_character":58},"updated":"2019-11-26 22:31:57.000000000","message":"Note that we can now do arbitrary suffixes. To that end, it wouldn\u0027t be a terrible idea for a dp group to have a \u0027name\u0027. Ideally DP[\u0027groups\u0027] would be a dict keyed by that name.\n\nCourse we\u0027re talking about changing the cyborg API to make that happen so... wishful thinking only.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"74af22dea5fc1af214f5ab7392291de03e7baab4","unresolved":false,"context_lines":[{"line_number":21,"context_line":"   Note on object relationships:"},{"line_number":22,"context_line":"   1 device profile (DP) has D \u003e\u003d 1 request groups (just as a flavor"},{"line_number":23,"context_line":"       has many request groups)."},{"line_number":24,"context_line":"   Each DP request group corresponds to exactly 1 numbered request"},{"line_number":25,"context_line":"       group (RG) in the request spec."},{"line_number":26,"context_line":"   Each numbered RG corresponds to exactly one resource provider (RP)."},{"line_number":27,"context_line":"   A DP request group may request A \u003e\u003d 1 accelerators, and so result"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_b68594b0","line":24,"range":{"start_line":24,"start_character":50,"end_line":24,"end_character":58},"in_reply_to":"3fa7e38b_5f9fec01","updated":"2019-12-03 19:32:20.000000000","message":"[Later] We\u0027re tying the requester_id to the request group name via [1], so we\u0027ll actually end up using the `device_profile_$n` as noted below.\n\n[1] https://review.opendev.org/#/c/696946/4/nova/scheduler/utils.py@337","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":35,"context_line":"   }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"   A device profile group is a dictionary too:"},{"line_number":38,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","},{"line_number":39,"context_line":"      \"resources:CUSTOM_LOCAL_MEMORY\": \"1\","},{"line_number":40,"context_line":"      \"trait:CUSTOM_INTEL_PAC_ARRIA10\": \"required\","},{"line_number":41,"context_line":"      \"trait:CUSTOM_FUNCTION_NAME_FALCON_GZIP_1_1\": \"required\","}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_5aa5ba02","line":38,"range":{"start_line":38,"start_character":7,"end_line":38,"end_character":16},"updated":"2019-11-26 22:31:57.000000000","message":"nts: these will obv need to get peeled apart so they can be reassembled with group identifiers.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    return _CyborgClient(context)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"},{"line_number":57,"context_line":"    \"\"\"Return the value to use in objects.RequestGroup.requester_id."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"       The requester_id is used to match device profile groups from"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_351d6f62","line":56,"range":{"start_line":56,"start_character":4,"end_line":56,"end_character":41},"updated":"2019-11-26 22:31:57.000000000","message":"...*this* could be the DP request group name.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"74af22dea5fc1af214f5ab7392291de03e7baab4","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    return _CyborgClient(context)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"},{"line_number":57,"context_line":"    \"\"\"Return the value to use in objects.RequestGroup.requester_id."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"       The requester_id is used to match device profile groups from"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1646e87c","line":56,"range":{"start_line":56,"start_character":4,"end_line":56,"end_character":41},"in_reply_to":"3fa7e38b_351d6f62","updated":"2019-12-03 19:32:20.000000000","message":"[Later] Yeah. It will be.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":59,"context_line":"       The requester_id is used to match device profile groups from"},{"line_number":60,"context_line":"       Cyborg to the request groups in request spec."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    req_id \u003d \"device_profile_\" + str(dp_group_id)"},{"line_number":63,"context_line":"    return req_id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_c729ea9b","line":62,"range":{"start_line":62,"start_character":33,"end_line":62,"end_character":36},"updated":"2019-11-25 18:43:06.000000000","message":"six.text_type?","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":59,"context_line":"       The requester_id is used to match device profile groups from"},{"line_number":60,"context_line":"       Cyborg to the request groups in request spec."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    req_id \u003d \"device_profile_\" + str(dp_group_id)"},{"line_number":63,"context_line":"    return req_id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1cc73b49","line":62,"range":{"start_line":62,"start_character":33,"end_line":62,"end_character":36},"in_reply_to":"3fa7e38b_c729ea9b","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027, ksa_auth\u003dauth)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def _get_device_profile_list(self, dp_name):"},{"line_number":74,"context_line":"        url \u003d self.DEVICE_PROFILE_URL"},{"line_number":75,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":76,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_3aeebe21","line":74,"range":{"start_line":74,"start_character":8,"end_line":74,"end_character":37},"updated":"2019-11-26 22:31:57.000000000","message":"nit, this seems pretty unnecessary","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027, ksa_auth\u003dauth)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def _get_device_profile_list(self, dp_name):"},{"line_number":74,"context_line":"        url \u003d self.DEVICE_PROFILE_URL"},{"line_number":75,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":76,"context_line":"        r \u003d self._client.get(url, params\u003dquery)"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_3cc47741","line":74,"range":{"start_line":74,"start_character":8,"end_line":74,"end_character":37},"in_reply_to":"3fa7e38b_3aeebe21","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        if not r:"},{"line_number":79,"context_line":"            raise exception.DeviceProfileError("},{"line_number":80,"context_line":"                name\u003ddp_name, msg\u003d\u0027Failed to get from Cyborg.\u0027)"},{"line_number":81,"context_line":"        return r.json().get(\u0027device_profiles\u0027)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def get_device_profile_groups(self, dp_name):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_fac02680","line":80,"range":{"start_line":80,"start_character":34,"end_line":80,"end_character":62},"updated":"2019-11-26 22:31:57.000000000","message":"This should be translated. But see below.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        if not r:"},{"line_number":79,"context_line":"            raise exception.DeviceProfileError("},{"line_number":80,"context_line":"                name\u003ddp_name, msg\u003d\u0027Failed to get from Cyborg.\u0027)"},{"line_number":81,"context_line":"        return r.json().get(\u0027device_profiles\u0027)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def get_device_profile_groups(self, dp_name):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1e0a9378","line":80,"range":{"start_line":80,"start_character":34,"end_line":80,"end_character":62},"in_reply_to":"3fa7e38b_fac02680","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":90,"context_line":"           :returns [\u003cdevice_profile_group\u003e]"},{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_271f9e70","line":93,"range":{"start_line":93,"start_character":8,"end_line":93,"end_character":44},"updated":"2019-11-25 18:43:06.000000000","message":"This seems unnecessary, but if it is, it seems like \"if not dp_name\" would be fine.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":90,"context_line":"           :returns [\u003cdevice_profile_group\u003e]"},{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_fcbd7fb1","line":93,"range":{"start_line":93,"start_character":8,"end_line":93,"end_character":44},"in_reply_to":"3fa7e38b_271f9e70","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_67127663","line":94,"range":{"start_line":94,"start_character":47,"end_line":94,"end_character":59},"updated":"2019-11-25 18:43:06.000000000","message":"In either of the cases you check for to hit this code, dp_name is not useful (either \"None\" or \"\").","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_ba4f0e34","line":94,"range":{"start_line":94,"start_character":47,"end_line":94,"end_character":59},"in_reply_to":"3fa7e38b_67127663","updated":"2019-11-26 22:31:57.000000000","message":"Yeah, but the exception message will freak out if you don\u0027t supply one.\n\nThis, the second DeviceProfileError I\u0027m seeing, is making me feel like DeviceProfileError should maybe not bother defining a msg_fmt (or you shouldn\u0027t bother using it in the code) -- just fully create the message each time.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_9cd80b25","line":94,"range":{"start_line":94,"start_character":47,"end_line":94,"end_character":59},"in_reply_to":"3fa7e38b_b5c07f2d","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_f557a900","line":94,"range":{"start_line":94,"start_character":47,"end_line":94,"end_character":59},"in_reply_to":"3fa7e38b_ba4f0e34","updated":"2019-12-04 09:09:46.000000000","message":"\u003e DeviceProfileError should maybe not bother defining a msg_fmt\n\nWith all the changes, every DeviceProfileError exception will have a valid dp_name.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"38a766d3614e2d4429b37c85080a51226f067d04","unresolved":false,"context_lines":[{"line_number":91,"context_line":"           :raises: DeviceProfileError"},{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_b5c07f2d","line":94,"range":{"start_line":94,"start_character":47,"end_line":94,"end_character":59},"in_reply_to":"3fa7e38b_ba4f0e34","updated":"2019-11-26 22:48:44.000000000","message":"\u003e Yeah, but the exception message will freak out if you don\u0027t supply\n \u003e one.\n\nRight but including an empty name in an error message is more confusing than helpful. If anything this could be name\u003d\u0027\u003cunspecified\u003e\u0027 or something. However, as I was saying for everything else here, I\u0027d rather we just check it once as input and not add all this defensive code everywhere that can\u0027t really generate a meaningful error message.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"},{"line_number":98,"context_line":"        if dp_list is None:"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_da4c4a41","line":95,"range":{"start_line":95,"start_character":51,"end_line":95,"end_character":65},"updated":"2019-11-26 22:31:57.000000000","message":"t9n\n\nditto below\n\nbut see above","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        \"\"\""},{"line_number":93,"context_line":"        if dp_name is None or dp_name \u003d\u003d \u0027\u0027:"},{"line_number":94,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name,"},{"line_number":95,"context_line":"                                               msg\u003d\u0027Invalid name\u0027)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"},{"line_number":98,"context_line":"        if dp_list is None:"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_15ce05b7","line":95,"range":{"start_line":95,"start_character":51,"end_line":95,"end_character":65},"in_reply_to":"3fa7e38b_da4c4a41","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":29745,"name":"Dustin Cowles","email":"cowlesd@gmail.com","username":"dustinc","status":"inactive"},"change_message_id":"5bb3b25efa6c7170604eae2227783579fef24c2d","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from nova import service_auth"},{"line_number":23,"context_line":"from nova import utils"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"\"\"\""},{"line_number":26,"context_line":"   Note on object relationships:"},{"line_number":27,"context_line":"   1 device profile (DP) has D \u003e\u003d 1 request groups (just as a flavor"},{"line_number":28,"context_line":"       has many request groups)."}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_eecf9388","line":25,"updated":"2019-12-27 20:28:33.000000000","message":"good comment, thanks..","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"fc41aa18d94dbced14a6f8904c02a716c26c4c57","unresolved":false,"context_lines":[{"line_number":40,"context_line":"   }"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"   A device profile group is a dictionary too:"},{"line_number":43,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","},{"line_number":44,"context_line":"      \"resources:CUSTOM_LOCAL_MEMORY\": \"1\","},{"line_number":45,"context_line":"      \"trait:CUSTOM_INTEL_PAC_ARRIA10\": \"required\","},{"line_number":46,"context_line":"      \"trait:CUSTOM_FUNCTION_NAME_FALCON_GZIP_1_1\": \"required\","},{"line_number":47,"context_line":"       # 0 or more Cyborg properties"},{"line_number":48,"context_line":"      \"accel:bitstream_id\": \"FB021995_BF21_4463_936A_02D49D4DB5E5\""},{"line_number":49,"context_line":"   }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"   See cyborg/cyborg/objects/device_profile.py for more details."},{"line_number":52,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_a91af567","line":49,"range":{"start_line":43,"start_character":4,"end_line":49,"end_character":4},"updated":"2019-12-28 04:51:41.000000000","message":"This example look good and it\u0027s a necessary adaptation for the different device.","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":55,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def get_client(context):"},{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1db4dc1c","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":33},"updated":"2020-02-05 16:31:42.000000000","message":"I guess this is a comment for the previous patch, but why aren\u0027t we doing the singleton thing here? Doing all the ksa(/sdk) setup for each client call seems excessive and unnecessary.\n\n(I think I remember Jay being opposed the singleton, but he was wrong :P )","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":55,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def get_client(context):"},{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1fa27bfc","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":33},"in_reply_to":"3fa7e38b_1db4dc1c","updated":"2020-02-06 06:41:46.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":55,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def get_client(context):"},{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5c8c76d7","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":33},"in_reply_to":"3fa7e38b_1fa27bfc","updated":"2020-02-06 16:50:56.000000000","message":"Singletons tends to make independent testing harder. Hopefully such client singleton is stateless so no test interference here. Anyhow I\u0027m not worried to much here.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":55,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def get_client(context):"},{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_8b82a3a5","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":33},"in_reply_to":"3fa7e38b_5c8c76d7","updated":"2020-02-06 20:01:25.000000000","message":"Ok. I don\u0027t see any obvious impact from singletons on the UT cases so far. I have already switched to singletons for the next patchset, so I\u0027ll leave it as is.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c868e6e77b4d9beb69bbabcadb56fc0d7cc6a240","unresolved":false,"context_lines":[{"line_number":55,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"def get_client(context):"},{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5d0d3f34","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":33},"in_reply_to":"3fa7e38b_8b82a3a5","updated":"2020-02-07 15:53:39.000000000","message":"OK","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"},{"line_number":63,"context_line":"    \"\"\"Return the value to use in objects.RequestGroup.requester_id."},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"       The requester_id is used to match device profile groups from"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_bd7d8871","line":62,"range":{"start_line":62,"start_character":42,"end_line":62,"end_character":53},"updated":"2020-02-05 16:31:42.000000000","message":"Would be good to have a docstring :param: for this indicating where it comes from. First place I looked for a DP group ID was in the dict on L44-50, but I don\u0027t see anything ID-ish in there.\n\n[Later] Okay, I see it\u0027s actually the index of the DP group in the device_profile[\u0027groups\u0027] list.\n\n[Later later] Actually, I don\u0027t see a point in this being a separate method. It\u0027s (reducible to) one LOC and only used in one place (L115 of this file). Having it inlined with some form of L65-6 as a code comment would IMO make things a lot easier to understand, as well as reducing LOC and indirection.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":59,"context_line":"    return _CyborgClient(context)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def get_device_profile_group_requester_id(dp_group_id):"},{"line_number":63,"context_line":"    \"\"\"Return the value to use in objects.RequestGroup.requester_id."},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"       The requester_id is used to match device profile groups from"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_dfa383fc","line":62,"range":{"start_line":62,"start_character":42,"end_line":62,"end_character":53},"in_reply_to":"3fa7e38b_bd7d8871","updated":"2020-02-06 06:41:46.000000000","message":"\u003e Would be good to have a docstring :param: for this indicating where\n \u003e it comes from. \n\nDone.\n \n \u003e [Later later] Actually, I don\u0027t see a point in this being a\n \u003e separate method. \n\nIt is meant to isolate the definition of the requester group id in one place, in case that changes.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":65,"context_line":"       The requester_id is used to match device profile groups from"},{"line_number":66,"context_line":"       Cyborg to the request groups in request spec."},{"line_number":67,"context_line":"    \"\"\""},{"line_number":68,"context_line":"    req_id \u003d \"device_profile_\" + six.text_type(dp_group_id)"},{"line_number":69,"context_line":"    return req_id"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_89c896a7","line":68,"range":{"start_line":68,"start_character":33,"end_line":68,"end_character":46},"updated":"2020-02-05 16:31:42.000000000","message":"We don\u0027t need to do this anymore","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":65,"context_line":"       The requester_id is used to match device profile groups from"},{"line_number":66,"context_line":"       Cyborg to the request groups in request spec."},{"line_number":67,"context_line":"    \"\"\""},{"line_number":68,"context_line":"    req_id \u003d \"device_profile_\" + six.text_type(dp_group_id)"},{"line_number":69,"context_line":"    return req_id"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_7fb92f14","line":68,"range":{"start_line":68,"start_character":33,"end_line":68,"end_character":46},"in_reply_to":"3fa7e38b_4f536c16","updated":"2020-02-06 06:41:46.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"36a300e08481c358039aaae2106e08262f380f41","unresolved":false,"context_lines":[{"line_number":65,"context_line":"       The requester_id is used to match device profile groups from"},{"line_number":66,"context_line":"       Cyborg to the request groups in request spec."},{"line_number":67,"context_line":"    \"\"\""},{"line_number":68,"context_line":"    req_id \u003d \"device_profile_\" + six.text_type(dp_group_id)"},{"line_number":69,"context_line":"    return req_id"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_4f536c16","line":68,"range":{"start_line":68,"start_character":33,"end_line":68,"end_character":46},"in_reply_to":"3fa7e38b_89c896a7","updated":"2020-02-05 18:21:53.000000000","message":"Since I asked for this initially, I\u0027ll point out that when I asked for it..we did need to, but no longer do because of the python3-only conversion which happened recently.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"fe74a0d9bd0c58a20fdc25bb19cdf8be4c56b172","unresolved":false,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _get_device_profile_list(self, dp_name):"},{"line_number":85,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":86,"context_line":"        r \u003d self._client.get(self.DEVICE_PROFILE_URL, params\u003dquery)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if not r:"},{"line_number":89,"context_line":"            msg \u003d _(\u0027Failed to get from Cyborg.\u0027)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_640d3891","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":67},"updated":"2020-02-05 08:37:47.000000000","message":"I guess there are more exceptions you need to handle, like keystoneauth1.EndPointNotFound, keystoneauth1.ClientException etc.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _get_device_profile_list(self, dp_name):"},{"line_number":85,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":86,"context_line":"        r \u003d self._client.get(self.DEVICE_PROFILE_URL, params\u003dquery)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if not r:"},{"line_number":89,"context_line":"            msg \u003d _(\u0027Failed to get from Cyborg.\u0027)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_eb0b17d1","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":67},"in_reply_to":"3fa7e38b_640d3891","updated":"2020-02-06 20:01:25.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _get_device_profile_list(self, dp_name):"},{"line_number":85,"context_line":"        query \u003d {\"name\": dp_name}"},{"line_number":86,"context_line":"        r \u003d self._client.get(self.DEVICE_PROFILE_URL, params\u003dquery)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if not r:"},{"line_number":89,"context_line":"            msg \u003d _(\u0027Failed to get from Cyborg.\u0027)"}],"source_content_type":"text/x-python","patch_set":55,"id":"1fa4df85_d3f472f3","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":67},"in_reply_to":"3fa7e38b_eb0b17d1","updated":"2020-03-08 23:24:21.000000000","message":"The next PS checks for ClientException. Many Nova calls to other services check for ClientException only: examples [1] [2]. \n\nEndpointException is an instance of CatalogException [3], which is an instance of ClientException [4].\n\n[1] https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/services.py#L289 \n[2] https://github.com/openstack/nova/blob/master/nova/cmd/manage.py#L1575 \n[3] https://github.com/openstack/keystoneauth/blob/master/keystoneauth1/exceptions/catalog.py#L25\n[4] https://github.com/openstack/keystoneauth/blob/master/keystoneauth1/exceptions/catalog.py#L21","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5c7a36bb","line":114,"range":{"start_line":114,"start_character":12,"end_line":114,"end_character":58},"updated":"2020-02-06 16:50:56.000000000","message":"Does the cyborg API make sure that the dp group list has a stable order per dp name between independent requests? If not the this kind of id generation feels problematic.\n\nI see that there is no natural id for a dp group in cyborg so API so I accept that we have to generate the id by the sequence number. I just want to be sure that such sequence number cannot change between requests.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_abf8bf4a","line":114,"range":{"start_line":114,"start_character":12,"end_line":114,"end_character":58},"in_reply_to":"3fa7e38b_25763e0d","updated":"2020-02-06 20:01:25.000000000","message":"Agreed. Once the set of groups for a device profile is persisted to the db, the retrieval doesn\u0027t do anything at the level of groups. The API implementation may filter lists of device profiles, but there is no filtering, sorting or any operation at the level of groups. So the group index is persistent for a given device profile.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b167a99c1348e80fb72459fb5a63580925359c77","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_25763e0d","line":114,"range":{"start_line":114,"start_character":12,"end_line":114,"end_character":58},"in_reply_to":"3fa7e38b_5c7a36bb","updated":"2020-02-06 17:43:25.000000000","message":"I was going to say it doesn\u0027t matter if the order is reproducible -- the only thing that matters is that the group ID be unique for a given request.\n\nBut it actually will matter eventually because we need to use the requester_id to correlate the provider from the allocation back to the device profile group it was made for.\n\nSo yeah, there does need to be *some* kind of stability here.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c868e6e77b4d9beb69bbabcadb56fc0d7cc6a240","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1d2ca792","line":114,"range":{"start_line":114,"start_character":12,"end_line":114,"end_character":58},"in_reply_to":"3fa7e38b_abf8bf4a","updated":"2020-02-07 15:53:39.000000000","message":"OK, thanks.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"},{"line_number":118,"context_line":"                match \u003d schedutils.ResourceRequest.XS_KEYPAT.match(key)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_3c497a8c","line":115,"range":{"start_line":115,"start_character":12,"end_line":115,"end_character":18},"updated":"2020-02-06 16:50:56.000000000","message":"as above if the dp_group_id is not stable then the req_id will not be stable too.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":112,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":113,"context_line":"        request_groups \u003d []"},{"line_number":114,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":115,"context_line":"            req_id \u003d get_device_profile_group_requester_id(dp_group_id)"},{"line_number":116,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":117,"context_line":"            for key, val in dp_group.items():"},{"line_number":118,"context_line":"                match \u003d schedutils.ResourceRequest.XS_KEYPAT.match(key)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_0b8f93d3","line":115,"range":{"start_line":115,"start_character":12,"end_line":115,"end_character":18},"in_reply_to":"3fa7e38b_3c497a8c","updated":"2020-02-06 20:01:25.000000000","message":"As above.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b4bee98fb7d75aceaae7fa7f30a608c3cf96275a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                    continue  # could be \u0027accel:foo\u003dbar\u0027, skip it"},{"line_number":121,"context_line":"                prefix, _ignore, name \u003d match.groups()"},{"line_number":122,"context_line":"                if prefix \u003d\u003d schedutils.ResourceRequest.XS_RES_PREFIX:"},{"line_number":123,"context_line":"                    rg.add_resource(rclass\u003dname, amount\u003dval)"},{"line_number":124,"context_line":"                elif prefix \u003d\u003d schedutils.ResourceRequest.XS_TRAIT_PREFIX:"},{"line_number":125,"context_line":"                    rg.add_trait(trait_name\u003dname, trait_type\u003dval)"},{"line_number":126,"context_line":"            request_groups.append(rg)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_44691cf5","line":123,"range":{"start_line":123,"start_character":36,"end_line":123,"end_character":59},"updated":"2020-02-05 08:50:33.000000000","message":"Will cyborg validate the name and val? if not, we should handle those at here.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"519ec7cf4140bba2662b663fad0a28b4b844450a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                    continue  # could be \u0027accel:foo\u003dbar\u0027, skip it"},{"line_number":121,"context_line":"                prefix, _ignore, name \u003d match.groups()"},{"line_number":122,"context_line":"                if prefix \u003d\u003d schedutils.ResourceRequest.XS_RES_PREFIX:"},{"line_number":123,"context_line":"                    rg.add_resource(rclass\u003dname, amount\u003dval)"},{"line_number":124,"context_line":"                elif prefix \u003d\u003d schedutils.ResourceRequest.XS_TRAIT_PREFIX:"},{"line_number":125,"context_line":"                    rg.add_trait(trait_name\u003dname, trait_type\u003dval)"},{"line_number":126,"context_line":"            request_groups.append(rg)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1e684887","line":123,"range":{"start_line":123,"start_character":36,"end_line":123,"end_character":59},"in_reply_to":"3fa7e38b_44691cf5","updated":"2020-02-05 16:21:21.000000000","message":"Cyborg validates device profiles in general. If the specific name or value is wrong, Placement is going to catch that and fail the request anyway.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b4bee98fb7d75aceaae7fa7f30a608c3cf96275a","unresolved":false,"context_lines":[{"line_number":122,"context_line":"                if prefix \u003d\u003d schedutils.ResourceRequest.XS_RES_PREFIX:"},{"line_number":123,"context_line":"                    rg.add_resource(rclass\u003dname, amount\u003dval)"},{"line_number":124,"context_line":"                elif prefix \u003d\u003d schedutils.ResourceRequest.XS_TRAIT_PREFIX:"},{"line_number":125,"context_line":"                    rg.add_trait(trait_name\u003dname, trait_type\u003dval)"},{"line_number":126,"context_line":"            request_groups.append(rg)"},{"line_number":127,"context_line":"        return request_groups"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_046b24ee","line":125,"range":{"start_line":125,"start_character":20,"end_line":125,"end_character":65},"updated":"2020-02-05 08:50:33.000000000","message":"ditto","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"519ec7cf4140bba2662b663fad0a28b4b844450a","unresolved":false,"context_lines":[{"line_number":122,"context_line":"                if prefix \u003d\u003d schedutils.ResourceRequest.XS_RES_PREFIX:"},{"line_number":123,"context_line":"                    rg.add_resource(rclass\u003dname, amount\u003dval)"},{"line_number":124,"context_line":"                elif prefix \u003d\u003d schedutils.ResourceRequest.XS_TRAIT_PREFIX:"},{"line_number":125,"context_line":"                    rg.add_trait(trait_name\u003dname, trait_type\u003dval)"},{"line_number":126,"context_line":"            request_groups.append(rg)"},{"line_number":127,"context_line":"        return request_groups"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_3e53c4e0","line":125,"range":{"start_line":125,"start_character":20,"end_line":125,"end_character":65},"in_reply_to":"3fa7e38b_046b24ee","updated":"2020-02-05 16:21:21.000000000","message":"Here too, Placement will catch it.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                elif prefix \u003d\u003d schedutils.ResourceRequest.XS_TRAIT_PREFIX:"},{"line_number":125,"context_line":"                    rg.add_trait(trait_name\u003dname, trait_type\u003dval)"},{"line_number":126,"context_line":"            request_groups.append(rg)"},{"line_number":127,"context_line":"        return request_groups"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_623f4cb2","line":127,"updated":"2020-02-06 16:50:56.000000000","message":"This method creates a list of RequestGroup objects. So this could be something like nova.objects.request_spec.RequestGroup.from_device_profile_request() called in a loop. \n\nSimilarly to the existing nova.objects.request_spec.RequestGroup.from_port_request()\n\nThis is a simple refactor so can be done separately later if we want a matching style.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        auth \u003d service_auth.get_auth_plugin(context)"},{"line_number":86,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027, ksa_auth\u003dauth)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def _call_cyborg(self, func, *args, **kwargs):"},{"line_number":89,"context_line":"        resp \u003d err_msg \u003d None"},{"line_number":90,"context_line":"        try:"},{"line_number":91,"context_line":"            resp \u003d func(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_91bdcd03","line":88,"updated":"2020-03-04 09:31:50.000000000","message":"note to self: this is like an error converting decorator","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        if err_msg:"},{"line_number":109,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr_msg)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        return resp.json().get(\u0027device_profiles\u0027)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":114,"context_line":"        \"\"\"Get list of profile group objects from the device profile."}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_3144191b","line":111,"range":{"start_line":111,"start_character":27,"end_line":111,"end_character":49},"updated":"2020-03-04 09:31:50.000000000","message":"Is there a case when cyborg API returns a non-error response without the device_profiles key?\nIf no then please make the key access non-conditional. As we handle the None case below I\u0027m OK to do this in a follow up if needed.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        if err_msg:"},{"line_number":109,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr_msg)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        return resp.json().get(\u0027device_profiles\u0027)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":114,"context_line":"        \"\"\"Get list of profile group objects from the device profile."}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_f9dad675","line":111,"range":{"start_line":111,"start_character":27,"end_line":111,"end_character":49},"in_reply_to":"1fa4df85_3144191b","updated":"2020-03-08 23:24:21.000000000","message":"No, in the current Cyborg implementation. But it would be too strict to prevent that implementation from changing ever. Also, as has been discussed before, Nova should not assume a specific Cyborg behavior, but check for it. The safer approach is to handle the case where this key is absent, as I have done here.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"37174c90f63a1195f082ea9ac1d4617e06668fa5","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        if err_msg:"},{"line_number":109,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr_msg)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        return resp.json().get(\u0027device_profiles\u0027)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_device_profile_groups(self, dp_name):"},{"line_number":114,"context_line":"        \"\"\"Get list of profile group objects from the device profile."}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_60290235","line":111,"range":{"start_line":111,"start_character":27,"end_line":111,"end_character":49},"in_reply_to":"1fa4df85_f9dad675","updated":"2020-03-10 17:00:37.000000000","message":"I expect that such a behavior change in the Cyborg API will be indicated by API versioning and therefore Nova as an Cyborg API user can depend on the current API definition which always has the key. I feel like we have different API philosophies. I rest my case.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":122,"context_line":"           :raises: DeviceProfileError"},{"line_number":123,"context_line":"        \"\"\""},{"line_number":124,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"},{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_d1758565","line":125,"range":{"start_line":125,"start_character":11,"end_line":125,"end_character":22},"updated":"2020-03-04 09:31:50.000000000","message":"OK this handles _get_device_profile_list returning None as well.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":122,"context_line":"           :raises: DeviceProfileError"},{"line_number":123,"context_line":"        \"\"\""},{"line_number":124,"context_line":"        dp_list \u003d self._get_device_profile_list(dp_name)"},{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_99e3a234","line":125,"range":{"start_line":125,"start_character":11,"end_line":125,"end_character":22},"in_reply_to":"1fa4df85_d1758565","updated":"2020-03-08 23:24:21.000000000","message":"Yes.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":129,"context_line":"            err \u003d _(\u0027Expected 1 device profile but got %s.\u0027) % len(dp_list)"},{"line_number":130,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":133,"context_line":"        request_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_f17c4120","line":130,"range":{"start_line":128,"start_character":0,"end_line":130,"end_character":69},"updated":"2020-03-04 09:31:50.000000000","message":"Does this mean cyborg does not enforce uniqueness of the name of the device profile? If yes, then why we are using name of the db in the flavor instead of the uuid? The whole integration will stop working as soon as somebody creates the second DB with the same name. This could very well be a usability issue for this solution.\n\nAnyhow I don\u0027t expect that we will change direction here, now. Would be nice to fix this later but honestly I don\u0027t see who will work on enhancing this.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"37174c90f63a1195f082ea9ac1d4617e06668fa5","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":129,"context_line":"            err \u003d _(\u0027Expected 1 device profile but got %s.\u0027) % len(dp_list)"},{"line_number":130,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":133,"context_line":"        request_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_e0709242","line":130,"range":{"start_line":128,"start_character":0,"end_line":130,"end_character":69},"in_reply_to":"1fa4df85_1957b2cc","updated":"2020-03-10 17:00:37.000000000","message":"Totally agree with using the same id in the error message as what the user originally provided. \n\nOK. I think I did not full grasp the intention behind the Cyborg API. I feel if we ask the user to use the name of the DP as a unique ID of what she needs in the flavor then allowing more than on DP to have the same name is wrong. But I rest my case.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"37174c90f63a1195f082ea9ac1d4617e06668fa5","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":129,"context_line":"            err \u003d _(\u0027Expected 1 device profile but got %s.\u0027) % len(dp_list)"},{"line_number":130,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":133,"context_line":"        request_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_60b7c2f6","line":130,"range":{"start_line":128,"start_character":0,"end_line":130,"end_character":69},"in_reply_to":"1fa4df85_97eff81c","updated":"2020-03-10 17:00:37.000000000","message":"\u003e Gibi, do you mean s/db/dp/ ?\n \u003e \n\nYes, DP. sorry.  :/","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":129,"context_line":"            err \u003d _(\u0027Expected 1 device profile but got %s.\u0027) % len(dp_list)"},{"line_number":130,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":133,"context_line":"        request_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_1957b2cc","line":130,"range":{"start_line":128,"start_character":0,"end_line":130,"end_character":69},"in_reply_to":"1fa4df85_97eff81c","updated":"2020-03-08 23:24:21.000000000","message":"Cyborg enforces that device profile names are unique [1]. Again, going back to the principle that Nova should not rely on specific Cyborg behavior for correct functioning, it is better to check explicitly for that.\n\nBTW, this Cyborg GET API allows several names to be listed as query params: that is why it returns a list.\n\nThe operator/admin specifies the dp name in the flavor. If that is not unique, we should show that name to the operator. Nova does not have dp UUIDs. Besides, if we were to use UUIDs in the error message, that is going to leave the operator nonplussed, as she specified a name in the flavor, not a UUID.\n\n[1] https://opendev.org/openstack/cyborg/src/branch/master/cyborg/db/sqlalchemy/models.py#L192","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"976a60c005a90ecadf872018e70a63526af8e112","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        if not dp_list:"},{"line_number":126,"context_line":"            msg \u003d _(\u0027Expected 1 device profile but got nothing.\u0027)"},{"line_number":127,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003dmsg)"},{"line_number":128,"context_line":"        if len(dp_list) !\u003d 1:"},{"line_number":129,"context_line":"            err \u003d _(\u0027Expected 1 device profile but got %s.\u0027) % len(dp_list)"},{"line_number":130,"context_line":"            raise exception.DeviceProfileError(name\u003ddp_name, msg\u003derr)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"        dp_groups \u003d dp_list[0][\u0027groups\u0027]"},{"line_number":133,"context_line":"        request_groups \u003d []"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_97eff81c","line":130,"range":{"start_line":128,"start_character":0,"end_line":130,"end_character":69},"in_reply_to":"1fa4df85_f17c4120","updated":"2020-03-04 14:48:02.000000000","message":"Gibi, do you mean s/db/dp/ ?\n\nI asked this before and I think the answer is that we are only supporting one profile right now, but cyborg has the ability to have multiples per name. Nova may only ever support one, but we need to make sure that we get back the expected cardinality and fail if not. I don\u0027t see that response in the history on this patch so I assume it\u0027s in one of the others from much earlier.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2f7f91746e95efe81ff4cc90062322d7c7cedd44","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        auth \u003d service_auth.get_auth_plugin(context)"},{"line_number":86,"context_line":"        self._client \u003d utils.get_ksa_adapter(\u0027accelerator\u0027, ksa_auth\u003dauth)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def _call_cyborg(self, func, *args, **kwargs):"},{"line_number":89,"context_line":"        resp \u003d err_msg \u003d None"},{"line_number":90,"context_line":"        try:"},{"line_number":91,"context_line":"            resp \u003d func(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":62,"id":"df33271e_ca515265","line":88,"updated":"2020-03-20 23:27:26.000000000","message":"Still feel we should have retries for the client https://review.opendev.org/#/c/712226/5","commit_id":"1be748782ec9c6c39df605c24930814b6971a646"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"884c5ab52ba90b5982c0c96d4befd509d3d4ab49","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            for key, val in dp_group.items():"},{"line_number":138,"context_line":"                match \u003d schedutils.ResourceRequest.XS_KEYPAT.match(key)"},{"line_number":139,"context_line":"                if not match:"},{"line_number":140,"context_line":"                    continue  # could be \u0027accel:foo\u003dbar\u0027, skip it"},{"line_number":141,"context_line":"                prefix, _ignore, name \u003d match.groups()"},{"line_number":142,"context_line":"                if prefix \u003d\u003d schedutils.ResourceRequest.XS_RES_PREFIX:"},{"line_number":143,"context_line":"                    rg.add_resource(rclass\u003dname, amount\u003dval)"}],"source_content_type":"text/x-python","patch_set":62,"id":"1fa4df85_59031843","line":140,"range":{"start_line":140,"start_character":30,"end_line":140,"end_character":65},"updated":"2020-03-19 07:23:32.000000000","message":"I didn\u0027t see unitest for this case.","commit_id":"1be748782ec9c6c39df605c24930814b6971a646"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a5d55f4114a16b68626254c6c89c8f0364632c16","unresolved":false,"context_lines":[{"line_number":36,"context_line":"       in the creation of A ARQs."},{"line_number":37,"context_line":"   Each ARQ corresponds to exactly 1 DP request group."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"   A device profile is a dictionary:"},{"line_number":40,"context_line":"   { \"name\": \"mydpname\","},{"line_number":41,"context_line":"     \"uuid\": \u003cuuid\u003e,"},{"line_number":42,"context_line":"     \"groups\": [ \u003cdevice_profile_request_group\u003e ]"},{"line_number":43,"context_line":"   }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"   A device profile group is a dictionary too:"},{"line_number":46,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","}],"source_content_type":"text/x-python","patch_set":63,"id":"df33271e_38f92a80","line":43,"range":{"start_line":39,"start_character":2,"end_line":43,"end_character":4},"updated":"2020-03-23 14:01:28.000000000","message":"given this needs to co evolve with nova we might want to consider making this an ovo at some point.\n\nspecificaly make this module convert the json form cybog into a nova object before returning it to the rest of nova so that we are not passing around dicts.","commit_id":"0c52730f6a138ce3b40efd6a0bd2809b2c41dada"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a5d55f4114a16b68626254c6c89c8f0364632c16","unresolved":false,"context_lines":[{"line_number":42,"context_line":"     \"groups\": [ \u003cdevice_profile_request_group\u003e ]"},{"line_number":43,"context_line":"   }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"   A device profile group is a dictionary too:"},{"line_number":46,"context_line":"    { \"resources:CUSTOM_ACCELERATOR_FPGA\": \"2\","},{"line_number":47,"context_line":"      \"resources:CUSTOM_LOCAL_MEMORY\": \"1\","},{"line_number":48,"context_line":"      \"trait:CUSTOM_INTEL_PAC_ARRIA10\": \"required\","},{"line_number":49,"context_line":"      \"trait:CUSTOM_FUNCTION_NAME_FALCON_GZIP_1_1\": \"required\","},{"line_number":50,"context_line":"       # 0 or more Cyborg properties"},{"line_number":51,"context_line":"      \"accel:bitstream_id\": \"FB021995_BF21_4463_936A_02D49D4DB5E5\""},{"line_number":52,"context_line":"   }"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"   See cyborg/cyborg/objects/device_profile.py for more details."},{"line_number":55,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":63,"id":"df33271e_78f3b29f","line":52,"range":{"start_line":45,"start_character":3,"end_line":52,"end_character":4},"updated":"2020-03-23 14:01:28.000000000","message":"this too.\n\n---later----\nthat said it looks like the function below are convertin ghte objes into a list of nova.objects.RequestGroup objects before retruning them so i guess we are already doing this.\n.i.e we are already using the adapter pateren here to prevent the cyborg specific dicts propagating into the rest of nova by converting them into objects.RequestGroup instances.","commit_id":"0c52730f6a138ce3b40efd6a0bd2809b2c41dada"}],"nova/api/openstack/compute/servers.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"884c5ab52ba90b5982c0c96d4befd509d3d4ab49","unresolved":false,"context_lines":[{"line_number":754,"context_line":"                exception.MultiattachNotSupportedOldMicroversion,"},{"line_number":755,"context_line":"                exception.CertificateValidationFailed,"},{"line_number":756,"context_line":"                exception.CreateWithPortResourceRequestOldVersion,"},{"line_number":757,"context_line":"                exception.DeviceProfileError,"},{"line_number":758,"context_line":"                exception.ComputeHostNotFound) as error:"},{"line_number":759,"context_line":"            raise exc.HTTPBadRequest(explanation\u003derror.format_message())"},{"line_number":760,"context_line":"        except INVALID_FLAVOR_IMAGE_EXCEPTIONS as error:"}],"source_content_type":"text/x-python","patch_set":62,"id":"1fa4df85_394adcab","line":757,"updated":"2020-03-19 07:23:32.000000000","message":"I didn\u0027t see a unittest for api layer.","commit_id":"1be748782ec9c6c39df605c24930814b6971a646"}],"nova/compute/api.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"244ff0c1dfe1032f8da07921bbc864bad52ea98f","unresolved":false,"context_lines":[{"line_number":1060,"context_line":"                # this becomes a nop."},{"line_number":1061,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1062,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1063,"context_line":"                RR \u003d scheduler_utils.ResourceRequest"},{"line_number":1064,"context_line":"                dp_request_groups \u003d ("},{"line_number":1065,"context_line":"                    RR.get_request_groups_for_device_profile("},{"line_number":1066,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":34,"id":"7faddb67_fc6fc690","line":1063,"range":{"start_line":1063,"start_character":16,"end_line":1063,"end_character":18},"updated":"2019-08-22 18:48:08.000000000","message":"This is not a proper local variable name. Make this \u0027resource_req\u0027 or something.","commit_id":"a7cc557b10707d09b52a2aac07143fd659aad69e"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"829c89bbe1c44081cc56903de7b448568a64e9b3","unresolved":false,"context_lines":[{"line_number":1060,"context_line":"                # this becomes a nop."},{"line_number":1061,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1062,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1063,"context_line":"                RR \u003d scheduler_utils.ResourceRequest"},{"line_number":1064,"context_line":"                dp_request_groups \u003d ("},{"line_number":1065,"context_line":"                    RR.get_request_groups_for_device_profile("},{"line_number":1066,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":34,"id":"7faddb67_2615e49b","line":1063,"range":{"start_line":1063,"start_character":16,"end_line":1063,"end_character":18},"in_reply_to":"7faddb67_fc6fc690","updated":"2019-08-29 08:15:23.000000000","message":"Done","commit_id":"a7cc557b10707d09b52a2aac07143fd659aad69e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":923,"context_line":"        # InstancePCIRequests object"},{"line_number":924,"context_line":"        pci_request_info \u003d pci_request.get_pci_requests_from_flavor("},{"line_number":925,"context_line":"            instance_type)"},{"line_number":926,"context_line":"        result \u003d self.network_api.create_resource_requests("},{"line_number":927,"context_line":"            context, requested_networks, pci_request_info)"},{"line_number":928,"context_line":"        network_metadata, port_resource_requests \u003d result"},{"line_number":929,"context_line":""},{"line_number":930,"context_line":"        # Creating servers with ports that have resource requests, like QoS"},{"line_number":931,"context_line":"        # minimum bandwidth rules, is only supported in a requested minimum"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1af2e29c","line":928,"range":{"start_line":926,"start_character":0,"end_line":928,"end_character":57},"updated":"2019-11-26 22:31:57.000000000","message":"I don\u0027t love how far away from RequestSpec creation this is happening, but for consistency with port resources, we should do the cyborg API query (accel resource request discovery/construction) here...","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":963,"context_line":"            \u0027pci_requests\u0027: pci_request_info,"},{"line_number":964,"context_line":"            \u0027numa_topology\u0027: numa_topology,"},{"line_number":965,"context_line":"            \u0027system_metadata\u0027: system_metadata,"},{"line_number":966,"context_line":"            \u0027port_resource_requests\u0027: port_resource_requests}"},{"line_number":967,"context_line":""},{"line_number":968,"context_line":"        options_from_image \u003d self._inherit_properties_from_image("},{"line_number":969,"context_line":"                boot_meta, auto_disk_config)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_7a267625","line":966,"range":{"start_line":966,"start_character":12,"end_line":966,"end_character":60},"updated":"2019-11-26 22:31:57.000000000","message":"...and stuff the requests in this dict...","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":963,"context_line":"            \u0027pci_requests\u0027: pci_request_info,"},{"line_number":964,"context_line":"            \u0027numa_topology\u0027: numa_topology,"},{"line_number":965,"context_line":"            \u0027system_metadata\u0027: system_metadata,"},{"line_number":966,"context_line":"            \u0027port_resource_requests\u0027: port_resource_requests}"},{"line_number":967,"context_line":""},{"line_number":968,"context_line":"        options_from_image \u003d self._inherit_properties_from_image("},{"line_number":969,"context_line":"                boot_meta, auto_disk_config)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_d64ae2ab","line":966,"range":{"start_line":966,"start_character":12,"end_line":966,"end_character":60},"in_reply_to":"3fa7e38b_7a267625","updated":"2019-12-04 09:09:46.000000000","message":"Isn\u0027t port_resource_requests meant for Neutron ports? Are we all ok with overloading it to include device resource requests?","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":1153,"context_line":"        security_groups \u003d self.security_group_api.populate_security_groups("},{"line_number":1154,"context_line":"                security_groups)"},{"line_number":1155,"context_line":"        self.security_group_api.ensure_default(context)"},{"line_number":1156,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1157,"context_line":"        instances_to_build \u003d []"},{"line_number":1158,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1159,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_ba4aaeaa","line":1156,"range":{"start_line":1156,"start_character":8,"end_line":1156,"end_character":30},"updated":"2019-11-26 22:31:57.000000000","message":"...and pull them back out here...","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":1183,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1184,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1185,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1186,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1187,"context_line":""},{"line_number":1188,"context_line":"                if block_device_mapping:"},{"line_number":1189,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_dad20afe","line":1186,"range":{"start_line":1186,"start_character":24,"end_line":1186,"end_character":46},"updated":"2019-11-26 22:31:57.000000000","message":"...and pass them through to RequestSpec.from_components here.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":1183,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1184,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1185,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1186,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1187,"context_line":""},{"line_number":1188,"context_line":"                if block_device_mapping:"},{"line_number":1189,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1024d3b1","line":1186,"range":{"start_line":1186,"start_character":24,"end_line":1186,"end_character":46},"in_reply_to":"3fa7e38b_dad20afe","updated":"2019-12-04 09:09:46.000000000","message":"To prevent scattered changes and yet keep the logic in _provision_instances(), I now call out to accelerator/cyborg.py from _provision_instances(), and add the device profile request groups to request_spec.resource_requests.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                # this becomes a nop."},{"line_number":1212,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1213,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1214,"context_line":"                rr \u003d scheduler_utils.ResourceRequest(req_spec)"},{"line_number":1215,"context_line":"                dp_request_groups \u003d ("},{"line_number":1216,"context_line":"                    rr.get_request_groups_for_device_profile("},{"line_number":1217,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_190d2634","line":1214,"updated":"2019-11-25 18:43:06.000000000","message":"If you check for non-falsey-ness of dp_name right here, and make the rest of the code conditional, you can avoid doing the work of building the ResourceRequest, and avoid the checks that the beginning of your other two methods. Otherwise everyone is running this code regardless of whether or not they should (and per your comment, this is not a nop, it just has no impact on the result or state).","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                # this becomes a nop."},{"line_number":1212,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1213,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1214,"context_line":"                rr \u003d scheduler_utils.ResourceRequest(req_spec)"},{"line_number":1215,"context_line":"                dp_request_groups \u003d ("},{"line_number":1216,"context_line":"                    rr.get_request_groups_for_device_profile("},{"line_number":1217,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_be181fcd","line":1214,"in_reply_to":"3fa7e38b_082ccbff","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                # this becomes a nop."},{"line_number":1212,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1213,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1214,"context_line":"                rr \u003d scheduler_utils.ResourceRequest(req_spec)"},{"line_number":1215,"context_line":"                dp_request_groups \u003d ("},{"line_number":1216,"context_line":"                    rr.get_request_groups_for_device_profile("},{"line_number":1217,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_bcddc714","line":1214,"in_reply_to":"3fa7e38b_190d2634","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"eed7e0caeaa94d39960fc976755f1e939ba3e1e1","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                # this becomes a nop."},{"line_number":1212,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1213,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1214,"context_line":"                rr \u003d scheduler_utils.ResourceRequest(req_spec)"},{"line_number":1215,"context_line":"                dp_request_groups \u003d ("},{"line_number":1216,"context_line":"                    rr.get_request_groups_for_device_profile("},{"line_number":1217,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_cc2eca41","line":1214,"in_reply_to":"3fa7e38b_190d2634","updated":"2019-11-27 17:54:12.000000000","message":"I\u0027ll go a step further: We should avoid creating this throwaway ResourceRequest entirely. The way port resources are processed is by directly creating a list of RequestGroup (see nova.network.neutronv2.api.API.create_resource_requests). If you need to reuse some of the parsing logic in ResourceRequest, factor that out into a helper.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a05e75aa240086189c81767f89e63c46e3c80777","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                # this becomes a nop."},{"line_number":1212,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1213,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1214,"context_line":"                rr \u003d scheduler_utils.ResourceRequest(req_spec)"},{"line_number":1215,"context_line":"                dp_request_groups \u003d ("},{"line_number":1216,"context_line":"                    rr.get_request_groups_for_device_profile("},{"line_number":1217,"context_line":"                        context, dp_name))"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_082ccbff","line":1214,"in_reply_to":"3fa7e38b_cc2eca41","updated":"2019-11-27 21:33:22.000000000","message":"Sundar and I discussed this a bit and agreed to the principle of creating a list of RequestGroup as suggested, and doing so in a method in the cyborg client that\u0027s a corollary to nova.network.neutronv2.api.API.create_resource_requests (which does the equivalent for ports), which would be invoked near same (L926) as suggested.\n\nSaid method will reuse some of the parsing logic (specifically the regex patterns) from ResourceRequest, but will not need to create an instance of that class. To assist with the sensible creation of RequestGroup, this minor refactor [1] can be slotted into the series.\n\n[1] https://review.opendev.org/696380","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c3ae334fc7bd9b91bb7f9e221712118966d5bada","unresolved":false,"context_lines":[{"line_number":1213,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1214,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1215,"context_line":"                            context, dp_name))"},{"line_number":1216,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"                # Create an instance object, but do not store in db yet."},{"line_number":1219,"context_line":"                instance \u003d objects.Instance(context\u003dcontext)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_8b1e230b","line":1216,"range":{"start_line":1216,"start_character":20,"end_line":1216,"end_character":48},"updated":"2019-12-04 15:42:39.000000000","message":"Note to other reviewers: this is always an empty list after from_components() called above on L1181, so despite looking scary, this should be safe.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"b5fa6e7383dcc7af6eed6dbe5f5c5a0fa087439c","unresolved":false,"context_lines":[{"line_number":1213,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1214,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1215,"context_line":"                            context, dp_name))"},{"line_number":1216,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"                # Create an instance object, but do not store in db yet."},{"line_number":1219,"context_line":"                instance \u003d objects.Instance(context\u003dcontext)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_9c574728","line":1216,"range":{"start_line":1216,"start_character":20,"end_line":1216,"end_character":48},"in_reply_to":"3fa7e38b_8b1e230b","updated":"2019-12-04 19:07:54.000000000","message":"It is either [] or has port resource requests. [1]\n\n[1] https://github.com/openstack/nova/commit/90b96170d3f269165f649e8b61739cf31ffb78b8#diff-cbbdc4d7c140314a7e0b2d97ebcd1f9cR475","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba591c0ad8bc368a281e2453f975e3c0b1911e17","unresolved":false,"context_lines":[{"line_number":1213,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1214,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1215,"context_line":"                            context, dp_name))"},{"line_number":1216,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"                # Create an instance object, but do not store in db yet."},{"line_number":1219,"context_line":"                instance \u003d objects.Instance(context\u003dcontext)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_bd447374","line":1216,"range":{"start_line":1216,"start_character":20,"end_line":1216,"end_character":48},"in_reply_to":"3fa7e38b_9c574728","updated":"2019-12-05 14:24:09.000000000","message":"My point was: it\u0027s always a list (i.e., it is always initialized).","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"3fa7e38b_3e1bc46f","updated":"2020-02-05 16:31:42.000000000","message":"Okay, I had to go refresh my memory on the discussion we had around this in PS43 [1]. The thrust of that conversation was that we should make the handling of device profiles as close to the handling of port resources as possible. I\u0027ll refresh those notes inline...\n\n[1] https://review.opendev.org/#/c/631243/43/nova/compute/api.py","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":872,"context_line":"                                    instance_type, root_bdm,"},{"line_number":873,"context_line":"                                    validate_numa\u003dvalidate_numa)"},{"line_number":874,"context_line":""},{"line_number":875,"context_line":"    def _validate_and_build_base_options(self, context, instance_type,"},{"line_number":876,"context_line":"                                         boot_meta, image_href, image_id,"},{"line_number":877,"context_line":"                                         kernel_id, ramdisk_id, display_name,"},{"line_number":878,"context_line":"                                         display_description, key_name,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_7e461c59","line":875,"range":{"start_line":875,"start_character":8,"end_line":875,"end_character":40},"updated":"2020-02-05 16:31:42.000000000","message":"The extraction/translation from extra specs should go in this method...","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":938,"context_line":"        # objects. The second call in below creates an InstancePCIRequest"},{"line_number":939,"context_line":"        # object for each SR-IOV port, and append it to the list in the"},{"line_number":940,"context_line":"        # InstancePCIRequests object"},{"line_number":941,"context_line":"        pci_request_info \u003d pci_request.get_pci_requests_from_flavor("},{"line_number":942,"context_line":"            instance_type, affinity_policy\u003dpci_numa_affinity_policy)"},{"line_number":943,"context_line":"        result \u003d self.network_api.create_resource_requests("},{"line_number":944,"context_line":"            context, requested_networks, pci_request_info,"},{"line_number":945,"context_line":"            affinity_policy\u003dpci_numa_affinity_policy)"},{"line_number":946,"context_line":"        network_metadata, port_resource_requests \u003d result"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"        # Creating servers with ports that have resource requests, like QoS"},{"line_number":949,"context_line":"        # minimum bandwidth rules, is only supported in a requested minimum"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1e5e0814","line":946,"range":{"start_line":941,"start_character":0,"end_line":946,"end_character":57},"updated":"2020-02-05 16:31:42.000000000","message":"...following this pattern.\n\nI.e. invoke cyborg.get_device_profile_request_groups (as modified -- see comment at L1226)...","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":981,"context_line":"            \u0027pci_requests\u0027: pci_request_info,"},{"line_number":982,"context_line":"            \u0027numa_topology\u0027: numa_topology,"},{"line_number":983,"context_line":"            \u0027system_metadata\u0027: system_metadata,"},{"line_number":984,"context_line":"            \u0027port_resource_requests\u0027: port_resource_requests}"},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"        options_from_image \u003d self._inherit_properties_from_image("},{"line_number":987,"context_line":"                boot_meta, auto_disk_config)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5ea1e0f5","line":984,"range":{"start_line":984,"start_character":12,"end_line":984,"end_character":60},"updated":"2020-02-05 16:31:42.000000000","message":"...and stuff the resulting dp_request_groups in a new key (like \u0027device_profile_requests\u0027) here.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5e24805f","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"updated":"2020-02-05 16:31:42.000000000","message":"Now you can extract the dp requests here\n\n device_profile_requests \u003d base_options.pop(\u0027device_profile_requests\u0027)\n\n...","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c868e6e77b4d9beb69bbabcadb56fc0d7cc6a240","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_bda0f3f3","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_2ff95081","updated":"2020-02-07 15:53:39.000000000","message":"Thanks Eric, I\u0027m OK with that refactor","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6f4526ce9692d334a3ddabc38fc966469c5aaead","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_790dd690","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_5e24805f","updated":"2020-02-05 17:06:49.000000000","message":"I see where you\u0027re going with this, to co-locate the code that collects resource requests. I think this change will move the existing code away from the BDM and network_info-adjacent places which, IMHO, are the real peers in functionality here, and not the port_resource_requests.\n\nSo, I see it as a win for resource-request locality and a loss for attachable-things locality. I don\u0027t feel that strongly so if you think it\u0027s important, then that\u0027s fine, but I\u0027d opt for leaving it the way it is I think, if I had to make a call.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c833bc75a5be7409cff057325098ac5824f4e671","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_f906a622","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_790dd690","updated":"2020-02-05 17:19:50.000000000","message":"Personally, I would prefer if the port/bandwidth logic from L941-952 happened here as well, rather than being buried in the base_options stuff. (Isn\u0027t L1182 the volume-related logic you want to co-locate with?) Would that kill two birds?\n\n(Obv that refactor could be done later)","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b167a99c1348e80fb72459fb5a63580925359c77","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_2ff95081","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_d43ccf2e","updated":"2020-02-06 17:43:25.000000000","message":"I took a swing at that refactor and put that patch above this one https://review.opendev.org/706083","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_3ff9771b","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_d43ccf2e","updated":"2020-02-06 06:41:46.000000000","message":"Looks like the overall preference is to have the port bandwidth logic moved here if at all, rather than move this code elsewhere. So, I\u0027ll leave this as is.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_0284580d","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_f906a622","updated":"2020-02-06 16:50:56.000000000","message":"\u003e Personally, I would prefer if the port/bandwidth logic from\n \u003e L941-952 happened here as well, rather than being buried in the\n \u003e base_options stuff. (Isn\u0027t L1182 the volume-related logic you want\n \u003e to co-locate with?) Would that kill two birds?\n \u003e \n \u003e (Obv that refactor could be done later)\n\nI\u0027m OK to move the logic of L941-952 here as a separate patch.  Then move L1226 - 1232 here as well, and have one resource_requests list with both neutron and cyborg request groups","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e594b3a6e330cd7118caf7869ee16f2c2fe32856","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"                context, instance_type, min_count, max_count)"},{"line_number":1171,"context_line":"        security_groups \u003d security_group_api.populate_security_groups("},{"line_number":1172,"context_line":"                security_groups)"},{"line_number":1173,"context_line":"        port_resource_requests \u003d base_options.pop(\u0027port_resource_requests\u0027)"},{"line_number":1174,"context_line":"        instances_to_build \u003d []"},{"line_number":1175,"context_line":"        # We could be iterating over several instances with several BDMs per"},{"line_number":1176,"context_line":"        # instance and those BDMs could be using a lot of the same images so"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_d43ccf2e","line":1173,"range":{"start_line":1173,"start_character":8,"end_line":1173,"end_character":75},"in_reply_to":"3fa7e38b_f906a622","updated":"2020-02-05 17:54:52.000000000","message":"Yeah.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_fedf6c36","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"updated":"2020-02-05 16:31:42.000000000","message":"...and pass them into RequestSpec.from_components here, alongside the port resource requests.\n\nL1232 would simply move to RequestSpec.from_components. That keeps the responsibility of mucking with RequestSpec.resource_requests constrained to just that method.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e594b3a6e330cd7118caf7869ee16f2c2fe32856","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_d415af96","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"in_reply_to":"3fa7e38b_39667e2a","updated":"2020-02-05 17:54:52.000000000","message":"That\u0027s fine, although my preference would be to not use from_components to merely set the requested_resources. Clearly from_components does not have the \"single responsibility of setting up the RequestSpec\" as the lines below all set things on req_spec...","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c833bc75a5be7409cff057325098ac5824f4e671","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_39667e2a","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"in_reply_to":"3fa7e38b_597a5a76","updated":"2020-02-05 17:19:50.000000000","message":"\u003e if we don\u0027t do the above, then I think we need a refactor *before*\n \u003e this to s/port_resource_requests/resource_requests/ and then pass\n \u003e them all in as one thing.\n\nYeah, I like that a lot better. So how would you feel about doing as I suggest at 941-6 (extracting and building the device profile request groups there) -- but then simply combining them with the port resource requests right away. Rename base_options[\u0027port_resource_requests\u0027] and related vars/params to just \u0027resource_requests\u0027 throughout the subsequent stack, and leave the logic as is.\n\n(Or remove the port_resource_requests kwarg from from_components and do the assignment here instead -- though I still prefer it if from_components has the single responsibility of setting up the RequestSpec.)","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_42ea50d9","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"in_reply_to":"3fa7e38b_d415af96","updated":"2020-02-06 16:50:56.000000000","message":"For me the from_components is a factory method on RequestSpec and it do help me to find out how a RequestSpec builds up, what are the inputs and such. It helps me to assume that if I have a RequestSpec object then I can be sure that it is already fully constructed. Sure I see that my assumption is imply wrong due to things set on request spec after construction. So I would move those initialization also into the factory method. \n\nAnyhow I\u0027m OK to rename port_resource_requests to resource_requests and use that as the union of all the resource requests coming for any direction (neutron, cyborg, at some future point flavor extra_spec). I suggest not to try to refactor from_components right now as that will lead to a rabbit hole.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b167a99c1348e80fb72459fb5a63580925359c77","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_b46fd327","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"in_reply_to":"3fa7e38b_d415af96","updated":"2020-02-06 17:43:25.000000000","message":"ack, did that in https://review.opendev.org/706083 as well.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6f4526ce9692d334a3ddabc38fc966469c5aaead","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                # RequestSpec before the instance is created."},{"line_number":1195,"context_line":"                instance_uuid \u003d uuidutils.generate_uuid()"},{"line_number":1196,"context_line":"                # Store the RequestSpec that will be used for scheduling."},{"line_number":1197,"context_line":"                req_spec \u003d objects.RequestSpec.from_components(context,"},{"line_number":1198,"context_line":"                        instance_uuid, boot_meta, instance_type,"},{"line_number":1199,"context_line":"                        base_options[\u0027numa_topology\u0027],"},{"line_number":1200,"context_line":"                        base_options[\u0027pci_requests\u0027], filter_properties,"},{"line_number":1201,"context_line":"                        instance_group, base_options[\u0027availability_zone\u0027],"},{"line_number":1202,"context_line":"                        security_groups\u003dsecurity_groups,"},{"line_number":1203,"context_line":"                        port_resource_requests\u003dport_resource_requests)"},{"line_number":1204,"context_line":""},{"line_number":1205,"context_line":"                if block_device_mapping:"},{"line_number":1206,"context_line":"                    # Record whether or not we are a BFV instance"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_597a5a76","line":1203,"range":{"start_line":1197,"start_character":0,"end_line":1203,"end_character":70},"in_reply_to":"3fa7e38b_fedf6c36","updated":"2020-02-05 17:06:49.000000000","message":"I specifically asked him not to use the from_components() method to construct the RequestSpec object. I still prefer that, and wish we hadn\u0027t added port_resource_requests() to it, since all it\u0027s doing is setting that field on the reqspec. I think it\u0027d be a lot clearer if we just did that on the resulting object here, where we have the context for it. IMHO from_components() largely exists to digest some of our legacy data structures into a reqspec, and while that should eventually not be needed, it also isn\u0027t the right place to put simple and modern additions, like just setting resource_requests. I\u0027d much prefer that to just happen here, right after we get req_spec back, much like the bfv stuff that happens right below, which is why he\u0027s adding the accelerator stuff there -- for locality with peers.\n\nSo my preference would be to leave what he has, and actually pull out setting port_resource_requests to here. If people are okay with that, I\u0027ll happily tack that refactor on to the end of this set.\n\nIf not, I\u0027m definitely not in favor of adding another accel_resource_requests parameter to that already-horrific method, especially when they\u0027re the same as the port resource requests. So if we don\u0027t do the above, then I think we need a refactor *before* this to s/port_resource_requests/resource_requests/ and then pass them all in as one thing.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"7099b92975b1d5d4646f5766ad5818fff2adadbf","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1228,"context_line":"                if dp_name:"},{"line_number":1229,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1230,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1231,"context_line":"                            context, dp_name))"},{"line_number":1232,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1233,"context_line":""},{"line_number":1234,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_e437e84b","line":1231,"range":{"start_line":1230,"start_character":24,"end_line":1231,"end_character":46},"updated":"2020-02-05 08:19:00.000000000","message":"The API layer should catch the exception raise from this method and convert it to http response code https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/servers.py#L683","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":1223,"context_line":"                if destination:"},{"line_number":1224,"context_line":"                    req_spec.requested_destination \u003d destination"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1227,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1228,"context_line":"                if dp_name:"},{"line_number":1229,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1230,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1231,"context_line":"                            context, dp_name))"},{"line_number":1232,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1233,"context_line":""},{"line_number":1234,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_9e33d8c3","line":1231,"range":{"start_line":1226,"start_character":0,"end_line":1231,"end_character":46},"updated":"2020-02-05 16:31:42.000000000","message":"To match more closely with the spirit of get_pci_requests_from_flavor/create_resource_requests (L941-6 above) I think you should fold this flavor introspection logic into get_device_profile_request_groups itself.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":1223,"context_line":"                if destination:"},{"line_number":1224,"context_line":"                    req_spec.requested_destination \u003d destination"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1227,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1228,"context_line":"                if dp_name:"},{"line_number":1229,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1230,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1231,"context_line":"                            context, dp_name))"},{"line_number":1232,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1233,"context_line":""},{"line_number":1234,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_c4073a1e","line":1231,"range":{"start_line":1226,"start_character":0,"end_line":1231,"end_character":46},"in_reply_to":"3fa7e38b_9e33d8c3","updated":"2020-02-06 06:41:46.000000000","message":"Previous comments on this code were to include the dp_name check \"right here\" [1].\n\n[1] https://review.opendev.org/#/c/631243/43/nova/compute/api.py@1214","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b167a99c1348e80fb72459fb5a63580925359c77","unresolved":false,"context_lines":[{"line_number":1223,"context_line":"                if destination:"},{"line_number":1224,"context_line":"                    req_spec.requested_destination \u003d destination"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1227,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1228,"context_line":"                if dp_name:"},{"line_number":1229,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1230,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1231,"context_line":"                            context, dp_name))"},{"line_number":1232,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1233,"context_line":""},{"line_number":1234,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_25edde8c","line":1231,"range":{"start_line":1226,"start_character":0,"end_line":1231,"end_character":46},"in_reply_to":"3fa7e38b_c4073a1e","updated":"2020-02-06 17:43:25.000000000","message":"The salient part there was avoiding the extra work of building objects or doing API calls. I stand by my comment.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1228,"context_line":"                if dp_name:"},{"line_number":1229,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1230,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1231,"context_line":"                            context, dp_name))"},{"line_number":1232,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1233,"context_line":""},{"line_number":1234,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_36ed12b8","line":1231,"range":{"start_line":1230,"start_character":24,"end_line":1231,"end_character":46},"in_reply_to":"3fa7e38b_e437e84b","updated":"2020-02-06 20:01:25.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":1458,"context_line":"        self._check_auto_disk_config(image\u003dboot_meta,"},{"line_number":1459,"context_line":"                                     auto_disk_config\u003dauto_disk_config)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        base_options, max_net_count, key_pair, security_groups, \\"},{"line_number":1462,"context_line":"            network_metadata \u003d self._validate_and_build_base_options("},{"line_number":1463,"context_line":"                    context, instance_type, boot_meta, image_href, image_id,"},{"line_number":1464,"context_line":"                    kernel_id, ramdisk_id, display_name, display_description,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_be66d4bb","line":1461,"range":{"start_line":1461,"start_character":8,"end_line":1461,"end_character":20},"updated":"2020-02-05 16:31:42.000000000","message":"(The device profiles end up in here...","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":1497,"context_line":"        tags \u003d self._create_tag_list_obj(context, tags)"},{"line_number":1498,"context_line":""},{"line_number":1499,"context_line":"        instances_to_build \u003d self._provision_instances("},{"line_number":1500,"context_line":"            context, instance_type, min_count, max_count, base_options,"},{"line_number":1501,"context_line":"            boot_meta, security_groups, block_device_mapping,"},{"line_number":1502,"context_line":"            shutdown_terminate, instance_group, check_server_group_quota,"},{"line_number":1503,"context_line":"            filter_properties, key_pair, tags, trusted_certs,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_3e08a4d6","line":1500,"range":{"start_line":1500,"start_character":58,"end_line":1500,"end_character":70},"updated":"2020-02-05 16:31:42.000000000","message":"...and get into _provision_instances here.)","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":1248,"context_line":"                if destination:"},{"line_number":1249,"context_line":"                    req_spec.requested_destination \u003d destination"},{"line_number":1250,"context_line":""},{"line_number":1251,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1252,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1253,"context_line":"                if dp_name:"},{"line_number":1254,"context_line":"                    dp_request_groups \u003d ("}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_a4452945","line":1251,"range":{"start_line":1251,"start_character":30,"end_line":1251,"end_character":45},"updated":"2020-03-04 09:31:50.000000000","message":"You don\u0027t have to dig into the request spec. There is an instance_type parameter to _provision_instance() that is a Flavor object. By not doing the request_spec hop you can simplify unit testing. See my comment there as well.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":1248,"context_line":"                if destination:"},{"line_number":1249,"context_line":"                    req_spec.requested_destination \u003d destination"},{"line_number":1250,"context_line":""},{"line_number":1251,"context_line":"                extra_specs \u003d req_spec.flavor.extra_specs"},{"line_number":1252,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1253,"context_line":"                if dp_name:"},{"line_number":1254,"context_line":"                    dp_request_groups \u003d ("}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_cd5db379","line":1251,"range":{"start_line":1251,"start_character":30,"end_line":1251,"end_character":45},"in_reply_to":"1fa4df85_a4452945","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ccd360617557a848a18c76766915f70da04435a8","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1253,"context_line":"                if dp_name:"},{"line_number":1254,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1255,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1256,"context_line":"                            context, dp_name))"},{"line_number":1257,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1258,"context_line":""},{"line_number":1259,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_97d4b921","line":1256,"range":{"start_line":1255,"start_character":24,"end_line":1256,"end_character":46},"updated":"2020-03-06 03:28:33.000000000","message":"I don\u0027t think we should get device profile in the loop at line 1217. If this is the request about multiple instances, but those multiple instances are sharing same device profile, so you are need to query the device profile one time.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"                dp_name \u003d extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":1253,"context_line":"                if dp_name:"},{"line_number":1254,"context_line":"                    dp_request_groups \u003d ("},{"line_number":1255,"context_line":"                        cyborg.get_device_profile_request_groups("},{"line_number":1256,"context_line":"                            context, dp_name))"},{"line_number":1257,"context_line":"                    req_spec.requested_resources.extend(dp_request_groups)"},{"line_number":1258,"context_line":""},{"line_number":1259,"context_line":"                # Create an instance object, but do not store in db yet."}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_2d7567fa","line":1256,"range":{"start_line":1255,"start_character":24,"end_line":1256,"end_character":46},"in_reply_to":"1fa4df85_97d4b921","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"}],"nova/objects/flavor.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        self._orig_extra_specs \u003d {}"},{"line_number":227,"context_line":"        self._orig_projects \u003d []"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    @property"},{"line_number":230,"context_line":"    def device_profile_name(self):"},{"line_number":231,"context_line":"        extra_specs \u003d self.get(\u0027extra_specs\u0027)"},{"line_number":232,"context_line":"        if extra_specs is not None:"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_17f6d8fa","line":229,"updated":"2019-02-08 23:03:43.000000000","message":"See PS7 fup - this isn\u0027t needed.","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4806a30a53c1c4200acbe813eca9e35f38ff8b45","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        self._orig_projects \u003d []"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    @property"},{"line_number":230,"context_line":"    def device_profile_name(self):"},{"line_number":231,"context_line":"        try:"},{"line_number":232,"context_line":"            return self.extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":233,"context_line":"        except exception.ObjectActionError:"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_7f00c101","line":230,"updated":"2019-08-06 16:54:04.000000000","message":"I\u0027d prefer we not do this. When I saw use of this in another patch above this, I went looking for the patch where you added this as a field to -2 it. So, this doesn\u0027t add it as a field, which is good, but I think it\u0027s going to be similarly confusing for people in the future. Let the versioned fields be properties and make it clear that extra_specs are what they are.","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a2ce96968521836e3b18909100f856af39fbf517","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        self._orig_projects \u003d []"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    @property"},{"line_number":230,"context_line":"    def device_profile_name(self):"},{"line_number":231,"context_line":"        try:"},{"line_number":232,"context_line":"            return self.extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":233,"context_line":"        except exception.ObjectActionError:"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_78494d5e","line":230,"in_reply_to":"7faddb67_7f00c101","updated":"2019-08-14 02:24:03.000000000","message":"Done","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4806a30a53c1c4200acbe813eca9e35f38ff8b45","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        try:"},{"line_number":232,"context_line":"            return self.extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":233,"context_line":"        except exception.ObjectActionError:"},{"line_number":234,"context_line":"            # There may not be any extra specs."},{"line_number":235,"context_line":"            return None"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_7f29a187","line":234,"updated":"2019-08-06 16:54:04.000000000","message":"This is wrong, and is another reason why hiding this is not great. This error means we couldn\u0027t load the extra specs, which will never be possible for instance-resident flavors that we can\u0027t load from the db by id. It does not mean that there aren\u0027t extra_specs, it means we don\u0027t have them loaded.","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a2ce96968521836e3b18909100f856af39fbf517","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        try:"},{"line_number":232,"context_line":"            return self.extra_specs.get(\u0027accel:device_profile\u0027)"},{"line_number":233,"context_line":"        except exception.ObjectActionError:"},{"line_number":234,"context_line":"            # There may not be any extra specs."},{"line_number":235,"context_line":"            return None"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_98444949","line":234,"in_reply_to":"7faddb67_7f29a187","updated":"2019-08-14 02:24:03.000000000","message":"Done","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"}],"nova/objects/request_spec.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4df348085d85d804d572533613f94aa631613005","unresolved":false,"context_lines":[{"line_number":503,"context_line":"        device_profile_request_groups \u003d ("},{"line_number":504,"context_line":"            schedutils.ResourceRequest.get_request_groups_for_device_profile("},{"line_number":505,"context_line":"                context, spec_obj.flavor.device_profile_name))"},{"line_number":506,"context_line":"        spec_obj.requested_resources.extend(device_profile_request_groups)"},{"line_number":507,"context_line":""},{"line_number":508,"context_line":"        # NOTE(sbauza): Default the other fields that are not part of the"},{"line_number":509,"context_line":"        # original contract"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_4a0c21eb","line":506,"updated":"2019-08-06 17:51:53.000000000","message":"I think this is the wrong place to do this. While it looks like this is effectively the constructor for RequestSpec objects, it\u0027s actually supposed to have been temporary as we transitioned from a big ugly tuple to objects. Thus, hiding something as complicated as a call out to another service in here is wrong.\n\nIMHO, this bit should be done explicitly after we\u0027ve constructed the object in compute/api, like we do for things like BDMs, etc.","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a2ce96968521836e3b18909100f856af39fbf517","unresolved":false,"context_lines":[{"line_number":503,"context_line":"        device_profile_request_groups \u003d ("},{"line_number":504,"context_line":"            schedutils.ResourceRequest.get_request_groups_for_device_profile("},{"line_number":505,"context_line":"                context, spec_obj.flavor.device_profile_name))"},{"line_number":506,"context_line":"        spec_obj.requested_resources.extend(device_profile_request_groups)"},{"line_number":507,"context_line":""},{"line_number":508,"context_line":"        # NOTE(sbauza): Default the other fields that are not part of the"},{"line_number":509,"context_line":"        # original contract"}],"source_content_type":"text/x-python","patch_set":30,"id":"7faddb67_2997f7ed","line":506,"in_reply_to":"7faddb67_4a0c21eb","updated":"2019-08-14 02:24:03.000000000","message":"Done","commit_id":"c4c826a658086d6eb009899eda2cbaa4be310e82"}],"nova/scheduler/manager.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"73315fc757648bc865318c8b0d8c13241cf7601c","unresolved":false,"context_lines":[{"line_number":97,"context_line":"            return"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        cyborg \u003d nova_utils.get_cyborg_client(ctxt)"},{"line_number":100,"context_line":"        devprof_groups \u003d cyborg.nova_device_profiles.list(name\u003ddp_name)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        # See python-cyborgclient/cyborgclient/v2/device_profiles.py"},{"line_number":103,"context_line":"        for dp_group in devprof_groups:"}],"source_content_type":"text/x-python","patch_set":1,"id":"bfdaf3ff_816da133","line":100,"range":{"start_line":100,"start_character":32,"end_line":100,"end_character":52},"updated":"2019-01-16 18:31:48.000000000","message":"Right, so as the previous patch is currently written, this is a red flag, because it means code in the cyborg client library has things with \u0027nova\u0027 in the name. If the preceding patch is reworked as suggested - where that code lives in a \"cyborg client\" written in nova itself - then this code remains mostly as is; it\u0027s just that \u0027nova_device_profiles\u0027 is a method on the cyborg-client-in-nova instead of in the cyborgclient lib.","commit_id":"14d99c22e914ee174da70a3e43270ad13cf92195"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from nova.scheduler import request_filter"},{"line_number":38,"context_line":"from nova.scheduler import utils"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"CONF \u003d nova.conf.CONF"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_c3b69fdd","side":"PARENT","line":40,"updated":"2019-02-05 17:00:17.000000000","message":"restore this\n\nwe don\u0027t actually have a pep rule enabled for it, but it is in the guidelines somewhere to have two blank lines after imports.","commit_id":"3227d8656c31a2f53c7e7b805c17e7710669bd33"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from nova.scheduler import request_filter"},{"line_number":38,"context_line":"from nova.scheduler import utils"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"CONF \u003d nova.conf.CONF"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_77fe7f39","side":"PARENT","line":40,"in_reply_to":"9fdfeff1_c3b69fdd","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"3227d8656c31a2f53c7e7b805c17e7710669bd33"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":167,"context_line":"        selections \u003d self.driver.select_destinations(ctxt, spec_obj,"},{"line_number":168,"context_line":"                instance_uuids, alloc_reqs_by_rp_uuid, provider_summaries,"},{"line_number":169,"context_line":"                allocation_request_version, return_alternates)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # If `return_objects` is False, we need to convert the selections to"},{"line_number":172,"context_line":"        # the older format, which is a list of host state dicts."},{"line_number":173,"context_line":"        if not return_objects:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_e3bba3c1","line":170,"updated":"2019-02-05 17:00:17.000000000","message":"unrelated whitespace change","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":167,"context_line":"        selections \u003d self.driver.select_destinations(ctxt, spec_obj,"},{"line_number":168,"context_line":"                instance_uuids, alloc_reqs_by_rp_uuid, provider_summaries,"},{"line_number":169,"context_line":"                allocation_request_version, return_alternates)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # If `return_objects` is False, we need to convert the selections to"},{"line_number":172,"context_line":"        # the older format, which is a list of host state dicts."},{"line_number":173,"context_line":"        if not return_objects:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_17fb7347","line":170,"in_reply_to":"9fdfeff1_e3bba3c1","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from nova.scheduler import request_filter"},{"line_number":38,"context_line":"from nova.scheduler import utils"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"CONF \u003d nova.conf.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_b7dcac74","side":"PARENT","line":40,"updated":"2019-02-08 23:03:43.000000000","message":"restore newline","commit_id":"28201d22bd396f6fa4a0c66c82775aebb48991e5"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        selections \u003d self.driver.select_destinations(ctxt, spec_obj,"},{"line_number":167,"context_line":"                instance_uuids, alloc_reqs_by_rp_uuid, provider_summaries,"},{"line_number":168,"context_line":"                allocation_request_version, return_alternates)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # If `return_objects` is False, we need to convert the selections to"},{"line_number":171,"context_line":"        # the older format, which is a list of host state dicts."},{"line_number":172,"context_line":"        if not return_objects:"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_d7d7f04e","line":169,"updated":"2019-02-08 23:03:43.000000000","message":"unrelated whitespace change","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7e5557425f1077d77b475142c1fe7ef859efbddf","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from nova.scheduler import request_filter"},{"line_number":38,"context_line":"from nova.scheduler import utils"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"CONF \u003d nova.conf.CONF"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_20f66afb","side":"PARENT","line":40,"updated":"2019-02-20 13:11:18.000000000","message":"seems unrelated","commit_id":"5a199bb165930d0377f47fd5e509144e3cd573e6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7e5557425f1077d77b475142c1fe7ef859efbddf","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        selections \u003d self.driver.select_destinations(ctxt, spec_obj,"},{"line_number":167,"context_line":"                instance_uuids, alloc_reqs_by_rp_uuid, provider_summaries,"},{"line_number":168,"context_line":"                allocation_request_version, return_alternates)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # If `return_objects` is False, we need to convert the selections to"},{"line_number":171,"context_line":"        # the older format, which is a list of host state dicts."},{"line_number":172,"context_line":"        if not return_objects:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_e0d7024f","line":169,"updated":"2019-02-20 13:11:18.000000000","message":"seems unrelated","commit_id":"01b09314ecc53bf2f642578ab9b4865a6c8ca96e"}],"nova/scheduler/utils.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":305,"context_line":"            qparams.extend(to_queryparams(rg, ident or \u0027\u0027))"},{"line_number":306,"context_line":"        return parse.urlencode(sorted(qparams))"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _add_request_groups(self, req_groups):"},{"line_number":309,"context_line":"        \"\"\"Add the provided request groups to the resource request.\"\"\""},{"line_number":310,"context_line":"        rg_ids \u003d [k for k in self._rg_by_id.keys() if k is not None]"},{"line_number":311,"context_line":"        if len(rg_ids) \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_1e7cfab3","line":308,"updated":"2019-02-05 17:00:17.000000000","message":"Should take a look at the new stuff for bandwidth providers. It suggests a clean way to handle adding a request group with a unique suffix - and you get to reuse the code.\n\nAt a glance, I think it entails:\n\n- Adding a from_device_profile method to nova.objects.request_spec.RequestGroup\n- Returning such a RequestGroup from the _CyborgClient method\n- Incorporating it into the spec object, in which case you get it added to the ResourceRequest for free via [1].\n\n[1] https://review.openstack.org/#/c/625942/7/nova/scheduler/utils.py","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":305,"context_line":"            qparams.extend(to_queryparams(rg, ident or \u0027\u0027))"},{"line_number":306,"context_line":"        return parse.urlencode(sorted(qparams))"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _add_request_groups(self, req_groups):"},{"line_number":309,"context_line":"        \"\"\"Add the provided request groups to the resource request.\"\"\""},{"line_number":310,"context_line":"        rg_ids \u003d [k for k in self._rg_by_id.keys() if k is not None]"},{"line_number":311,"context_line":"        if len(rg_ids) \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_979c430f","line":308,"in_reply_to":"9fdfeff1_1e7cfab3","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":319,"context_line":"        \"\"\"Add request groups from the device profile in extra specs.\"\"\""},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        def _get_request_groups_from_device_profile(spec_obj):"},{"line_number":322,"context_line":"            \"\"\"Get request groups from the device profile"},{"line_number":323,"context_line":"            \"\"\""},{"line_number":324,"context_line":"            dp_name \u003d cyborg.get_device_profile_name(spec_obj)"},{"line_number":325,"context_line":"            if dp_name is None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_c3121fb5","line":322,"range":{"start_line":322,"start_character":15,"end_line":322,"end_character":57},"updated":"2019-02-05 17:00:17.000000000","message":"This docstring doesn\u0027t add much value :P","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":319,"context_line":"        \"\"\"Add request groups from the device profile in extra specs.\"\"\""},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        def _get_request_groups_from_device_profile(spec_obj):"},{"line_number":322,"context_line":"            \"\"\"Get request groups from the device profile"},{"line_number":323,"context_line":"            \"\"\""},{"line_number":324,"context_line":"            dp_name \u003d cyborg.get_device_profile_name(spec_obj)"},{"line_number":325,"context_line":"            if dp_name is None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_b7a14749","line":322,"range":{"start_line":322,"start_character":15,"end_line":322,"end_character":57},"in_reply_to":"9fdfeff1_c3121fb5","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":328,"context_line":"            cyclient \u003d cyborg.get_client()"},{"line_number":329,"context_line":"            devprof_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"            # See python-cyborgclient/cyborgclient/v2/device_profiles.py"},{"line_number":332,"context_line":"            rg_list \u003d []"},{"line_number":333,"context_line":"            for dp_group in devprof_groups:"},{"line_number":334,"context_line":"                resources, required_traits, forbidden_traits \u003d \\"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_c3045f81","line":331,"range":{"start_line":331,"start_character":12,"end_line":331,"end_character":72},"updated":"2019-02-05 17:00:17.000000000","message":"This comment is no longer relevant.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":328,"context_line":"            cyclient \u003d cyborg.get_client()"},{"line_number":329,"context_line":"            devprof_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"            # See python-cyborgclient/cyborgclient/v2/device_profiles.py"},{"line_number":332,"context_line":"            rg_list \u003d []"},{"line_number":333,"context_line":"            for dp_group in devprof_groups:"},{"line_number":334,"context_line":"                resources, required_traits, forbidden_traits \u003d \\"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_5786dbbc","line":331,"range":{"start_line":331,"start_character":12,"end_line":331,"end_character":72},"in_reply_to":"9fdfeff1_c3045f81","updated":"2019-02-20 05:58:09.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            # See python-cyborgclient/cyborgclient/v2/device_profiles.py"},{"line_number":332,"context_line":"            rg_list \u003d []"},{"line_number":333,"context_line":"            for dp_group in devprof_groups:"},{"line_number":334,"context_line":"                resources, required_traits, forbidden_traits \u003d \\"},{"line_number":335,"context_line":"                    dp_group[0], dp_group[1], dp_group[2]"},{"line_number":336,"context_line":"                rg \u003d objects.RequestGroup(ctxt\u003dNone, resources\u003dresources,"},{"line_number":337,"context_line":"                                          required_traits\u003drequired_traits,"},{"line_number":338,"context_line":"                                          forbidden_traits\u003dforbidden_traits"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_a3ea7ba9","line":335,"range":{"start_line":334,"start_character":16,"end_line":335,"end_character":57},"updated":"2019-02-05 17:00:17.000000000","message":"backslash ew\n\nAlso, since you know your tuple is the right size, you can just say\n\n resources, required_traits, forbidden_traits \u003d dp_group","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"69aa4ac8dfa0976f68d96b8f32277e1b5ac84fd4","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            # See python-cyborgclient/cyborgclient/v2/device_profiles.py"},{"line_number":332,"context_line":"            rg_list \u003d []"},{"line_number":333,"context_line":"            for dp_group in devprof_groups:"},{"line_number":334,"context_line":"                resources, required_traits, forbidden_traits \u003d \\"},{"line_number":335,"context_line":"                    dp_group[0], dp_group[1], dp_group[2]"},{"line_number":336,"context_line":"                rg \u003d objects.RequestGroup(ctxt\u003dNone, resources\u003dresources,"},{"line_number":337,"context_line":"                                          required_traits\u003drequired_traits,"},{"line_number":338,"context_line":"                                          forbidden_traits\u003dforbidden_traits"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_97b52381","line":335,"range":{"start_line":334,"start_character":16,"end_line":335,"end_character":57},"in_reply_to":"9fdfeff1_a3ea7ba9","updated":"2019-02-20 05:58:09.000000000","message":"This whole code is not needed anymore","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":305,"context_line":"            qparams.extend(to_queryparams(rg, ident or \u0027\u0027))"},{"line_number":306,"context_line":"        return parse.urlencode(sorted(qparams))"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _add_request_groups(self, req_groups):"},{"line_number":309,"context_line":"        \"\"\"Add the provided request groups to the resource request.\"\"\""},{"line_number":310,"context_line":"        rg_ids \u003d [k for k in self._rg_by_id.keys() if k is not None]"},{"line_number":311,"context_line":"        if len(rg_ids) \u003d\u003d 0:"},{"line_number":312,"context_line":"            max_ident \u003d 0"},{"line_number":313,"context_line":"        else:"},{"line_number":314,"context_line":"            max_ident \u003d max(rg_ids)"},{"line_number":315,"context_line":"        for i, rg in enumerate(req_groups):"},{"line_number":316,"context_line":"            self._rg_by_id[max_ident + i + 1] \u003d rg"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def add_request_groups_from_device_profile(self, spec_obj):"},{"line_number":319,"context_line":"        \"\"\"Add request groups from the device profile in extra specs.\"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_ccac4737","line":316,"range":{"start_line":308,"start_character":0,"end_line":316,"end_character":50},"updated":"2019-02-08 23:03:43.000000000","message":"don\u0027t need this anymore, eh?","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":318,"context_line":"    def add_request_groups_from_device_profile(self, spec_obj):"},{"line_number":319,"context_line":"        \"\"\"Add request groups from the device profile in extra specs.\"\"\""},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        def _get_request_groups_from_device_profile(spec_obj):"},{"line_number":322,"context_line":"            dp_name \u003d spec_obj.flavor.device_profile_name"},{"line_number":323,"context_line":"            if dp_name is None:"},{"line_number":324,"context_line":"                # Extra specs may not have device profiles in all cases."},{"line_number":325,"context_line":"                # So this is not an error."},{"line_number":326,"context_line":"                return None"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"            cyclient \u003d cyborg.get_client()"},{"line_number":329,"context_line":"            req_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":330,"context_line":"            return req_groups"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        req_groups \u003d _get_request_groups_from_device_profile(spec_obj)"},{"line_number":333,"context_line":"        if req_groups is not None:"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_2c95d3e4","line":330,"range":{"start_line":321,"start_character":8,"end_line":330,"end_character":29},"updated":"2019-02-08 23:03:43.000000000","message":"What\u0027s the value in having this as an inner method rather than inline?","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":329,"context_line":"            req_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":330,"context_line":"            return req_groups"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        req_groups \u003d _get_request_groups_from_device_profile(spec_obj)"},{"line_number":333,"context_line":"        if req_groups is not None:"},{"line_number":334,"context_line":"            for req_group in req_groups:"},{"line_number":335,"context_line":"                self.add_request_group(req_group)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_ecb7cb85","line":334,"range":{"start_line":332,"start_character":8,"end_line":334,"end_character":40},"updated":"2019-02-08 23:03:43.000000000","message":"or\n\n for req_group in _get_request_groups_from_device_profile(spec_obj) or []:\n\n...but if get_device_profile_groups returns [] when there aren\u0027t any, you don\u0027t need the `or []`.","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        req_groups \u003d _get_request_groups_from_device_profile(spec_obj)"},{"line_number":333,"context_line":"        if req_groups is not None:"},{"line_number":334,"context_line":"            for req_group in req_groups:"},{"line_number":335,"context_line":"                self.add_request_group(req_group)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"def build_request_spec(image, instances, instance_type\u003dNone):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_775404cb","line":335,"range":{"start_line":335,"start_character":21,"end_line":335,"end_character":38},"updated":"2019-02-08 23:03:43.000000000","message":"This is worthy of a comment that we\u0027re adding the request groups with unique suffixes so they don\u0027t interfere with any other request groups from the actual flavor.","commit_id":"fed30b1344ce298d2afe6aa366f30e36586ff011"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7e5557425f1077d77b475142c1fe7ef859efbddf","unresolved":false,"context_lines":[{"line_number":305,"context_line":"            qparams.extend(to_queryparams(rg, ident or \u0027\u0027))"},{"line_number":306,"context_line":"        return parse.urlencode(sorted(qparams))"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _add_request_groups(self, req_groups):"},{"line_number":309,"context_line":"        \"\"\"Add the provided request groups to the resource request.\"\"\""},{"line_number":310,"context_line":"        rg_ids \u003d [k for k in self._rg_by_id.keys() if k is not None]"},{"line_number":311,"context_line":"        if len(rg_ids) \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_4035aea7","line":308,"updated":"2019-02-20 13:11:18.000000000","message":"This seems to be unused as the below code calls add_request_group() instead","commit_id":"01b09314ecc53bf2f642578ab9b4865a6c8ca96e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e17c71d25154cd557e0cee68189da4b4da8cd06e","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        self._group_policy \u003d policy"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @classmethod"},{"line_number":138,"context_line":"    def _match_and_add_from_extra_specs(cls, rr, key, val, rg_ident\u003dNone):"},{"line_number":139,"context_line":"        match \u003d cls.XS_KEYPAT.match(key)"},{"line_number":140,"context_line":"        if not match:"},{"line_number":141,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_b524d50e","line":138,"updated":"2019-07-08 15:48:08.000000000","message":"This shouldn\u0027t be a classmethod, IMHO, it should be a regular instance method on the ResourceRequest, and then you won\u0027t have to pass it in.","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a297894249e69f8b8c5e9e69d18aac3ed92616ea","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        self._group_policy \u003d policy"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @classmethod"},{"line_number":138,"context_line":"    def _match_and_add_from_extra_specs(cls, rr, key, val, rg_ident\u003dNone):"},{"line_number":139,"context_line":"        match \u003d cls.XS_KEYPAT.match(key)"},{"line_number":140,"context_line":"        if not match:"},{"line_number":141,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_6d739b17","line":138,"in_reply_to":"7faddb67_b524d50e","updated":"2019-07-31 05:21:33.000000000","message":"Done","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e17c71d25154cd557e0cee68189da4b4da8cd06e","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        # TODO(efried): Handle member_of[$N], which will need to be reconciled"},{"line_number":180,"context_line":"        # with destination.aggregates handling in resources_from_request_spec"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        ret \u003d req or cls()"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        for key, val in extra_specs.items():"},{"line_number":185,"context_line":"            if key \u003d\u003d \u0027group_policy\u0027:"}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_f5eb2dad","line":182,"updated":"2019-07-08 15:48:08.000000000","message":"Please do not perform random \"gardening\" on the code intermixed with functional changes. This does not need to change, so don\u0027t change it.","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a297894249e69f8b8c5e9e69d18aac3ed92616ea","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        # TODO(efried): Handle member_of[$N], which will need to be reconciled"},{"line_number":180,"context_line":"        # with destination.aggregates handling in resources_from_request_spec"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        ret \u003d req or cls()"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        for key, val in extra_specs.items():"},{"line_number":185,"context_line":"            if key \u003d\u003d \u0027group_policy\u0027:"}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_8d70570a","line":182,"in_reply_to":"7faddb67_f5eb2dad","updated":"2019-07-31 05:21:33.000000000","message":"Done","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e17c71d25154cd557e0cee68189da4b4da8cd06e","unresolved":false,"context_lines":[{"line_number":185,"context_line":"            if key \u003d\u003d \u0027group_policy\u0027:"},{"line_number":186,"context_line":"                ret._add_group_policy(val)"},{"line_number":187,"context_line":"                continue"},{"line_number":188,"context_line":"            cls._match_and_add_from_extra_specs(ret, key, val)"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"        return ret"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_350b058f","line":188,"updated":"2019-07-08 15:48:08.000000000","message":"Similarly, this appears to be just a refactor, so do that separately if it needs doing. Don\u0027t intermix that refactor with this functional change. I know you use this below, but you can set this up ahead of time and then use it. It seems like you\u0027re making a subtle change in the code you\u0027re moving, which is hard to see when mixed with the rest of the stuff here. Moving the code in a refactor patch and then making the change to that code that goes with the rest of the functional change here will make that clearer and easier to verify.","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"a297894249e69f8b8c5e9e69d18aac3ed92616ea","unresolved":false,"context_lines":[{"line_number":185,"context_line":"            if key \u003d\u003d \u0027group_policy\u0027:"},{"line_number":186,"context_line":"                ret._add_group_policy(val)"},{"line_number":187,"context_line":"                continue"},{"line_number":188,"context_line":"            cls._match_and_add_from_extra_specs(ret, key, val)"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"        return ret"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"7faddb67_2d636344","line":188,"in_reply_to":"7faddb67_350b058f","updated":"2019-07-31 05:21:33.000000000","message":"Done","commit_id":"7cee59ab06b50349517540caad6090ccd5d5dca5"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        self._translate_memory_encryption(request_spec.flavor, image)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        self._translate_vpmems_request(request_spec.flavor)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        self.strip_zeros()"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"    def _process_extra_specs(self, flavor):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_35c7af9b","line":145,"updated":"2019-11-26 22:31:57.000000000","message":"I am kind of wondering why we don\u0027t just add a \n\n self._translate_accel_request(...)\n\nhere (which would basically be all but the last four lines of get_request_groups_for_device_profile) rather than going through the trouble of\n- building a ResourceRequest just to\n- call get_request_groups_for_device_profile on it and\n- peel out just the accel request groups from that and\n- throw away the rest of the ResourceRequest and\n- send those request groups through with the RequestSpec to\n- build the ResourceRequest from them all over again.\n\nIt must have something to do with persisting those request groups in the RequestSpec? Is that what we actually want to do??","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"90a75cca6287dc49415840ad4777f9dd311b844b","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        self._translate_memory_encryption(request_spec.flavor, image)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        self._translate_vpmems_request(request_spec.flavor)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        self.strip_zeros()"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"    def _process_extra_specs(self, flavor):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_7168cdf3","line":145,"in_reply_to":"3fa7e38b_35c7af9b","updated":"2019-11-27 17:32:43.000000000","message":"Okay, disregard this one. I dug a bit more and talked to gibi \u0026 Dan. For future me:\n\nResourceRequest.__init__ is fine for simple culling of flavor/image-meta. But there are other things that need request groups that come from \"outside\". For example, bandwidth request groups come from the port associated with the boot request. Those kinds of things we process in _provision_instances while building the RequestSpec, and stuff them into RequestSpec.requested_resources. Then finally select_destinations calls resources_from_request_spec which does the ResourceRequest.__init__ and then *adds* the RequestSpec.resource_requests [1].\n\nAccelerator request groups come from the device profile associated with the boot request. Today that association happens to be via flavor extra specs, so technically we could do the processing from here (ResourceRequest.__init__) as suggested in my previous comment. BUT the eventual goal is to make it possible to specify device profiles as parameters to the boot request (more like ports), so it will need to be done from _provision_instances and populated into RequestSpec.requested_resources.\n\n[1] That last part, the separation of ResourceRequest.__init__ and appending RequestSpec.resource_requests, didn\u0027t make sense to me, so I proposed https://review.opendev.org/696354","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_f93feab1","line":251,"updated":"2019-11-25 18:43:06.000000000","message":"I think this needs a docstring. Your comments, especially on L266 and L270 are not helpful, and the comment on L261 tells us _what_ is happening (which we can see from the code) but not _why_.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_9e720312","line":251,"in_reply_to":"3fa7e38b_2872e713","updated":"2019-12-04 09:09:46.000000000","message":"Yup, this refactor is gone.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_5ce293d6","line":251,"in_reply_to":"3fa7e38b_55e7cbe4","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a05e75aa240086189c81767f89e63c46e3c80777","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_2872e713","line":251,"in_reply_to":"3fa7e38b_55e7cbe4","updated":"2019-11-27 21:33:22.000000000","message":"Later: if we do [1] this refactor goes away.\n\n[1] https://review.opendev.org/#/c/631243/43/nova/compute/api.py@1214","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"38a766d3614e2d4429b37c85080a51226f067d04","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_55e7cbe4","line":251,"in_reply_to":"3fa7e38b_5a9ffa01","updated":"2019-11-26 22:48:44.000000000","message":"Ack, so s/your/the/ comments. But, moving this out of the place it came from removes some context (including a clearer helper function name), so things become more obscure.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":248,"context_line":"                       \u0027value\u0027: trait})"},{"line_number":249,"context_line":"            self._add_trait(None, os_traits.HW_CPU_HYPERTHREADING, trait)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def _match_and_add_from_extra_specs(self, key, val, rg_ident\u003dNone):"},{"line_number":252,"context_line":"        match \u003d self.XS_KEYPAT.match(key)"},{"line_number":253,"context_line":"        if not match:"},{"line_number":254,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_5a9ffa01","line":251,"in_reply_to":"3fa7e38b_f93feab1","updated":"2019-11-26 22:31:57.000000000","message":"With the exception of L261-4, this is just a cut/paste refactor, so you don\u0027t deserve the beating for the quality of the comments. (I think they\u0027re mine, in fact.)\n\nThat said, I agree a docstring wouldn\u0027t hurt.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f62bd159c2268890a59d0c45c5c0cd305435717e","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        # Process \"trait[$N]\""},{"line_number":271,"context_line":"        elif prefix \u003d\u003d self.XS_TRAIT_PREFIX:"},{"line_number":272,"context_line":"            self._add_trait(suffix, name, val)"},{"line_number":273,"context_line":"        return"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def get_request_groups_for_device_profile(self, context, dp_name):"},{"line_number":276,"context_line":"        \"\"\"Create all RGs for the list of device profile groups."}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_d92b0e79","line":273,"updated":"2019-11-25 18:43:06.000000000","message":"This is not necessary.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        # Process \"trait[$N]\""},{"line_number":271,"context_line":"        elif prefix \u003d\u003d self.XS_TRAIT_PREFIX:"},{"line_number":272,"context_line":"            self._add_trait(suffix, name, val)"},{"line_number":273,"context_line":"        return"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def get_request_groups_for_device_profile(self, context, dp_name):"},{"line_number":276,"context_line":"        \"\"\"Create all RGs for the list of device profile groups."}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_1ccc1b61","line":273,"in_reply_to":"3fa7e38b_d92b0e79","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a05e75aa240086189c81767f89e63c46e3c80777","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            self._add_trait(suffix, name, val)"},{"line_number":273,"context_line":"        return"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def get_request_groups_for_device_profile(self, context, dp_name):"},{"line_number":276,"context_line":"        \"\"\"Create all RGs for the list of device profile groups."},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        Parse the resources/traits and validate them using the same logic"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_a857b75a","line":275,"range":{"start_line":275,"start_character":8,"end_line":275,"end_character":45},"updated":"2019-11-27 21:33:22.000000000","message":"right, so this is the method I talk about in [1] that ought to go into the cyborg client itself, as a corollary to create_resource_requests (perhaps it should even be named create_resource_requests...)\n\nhttps://review.opendev.org/#/c/631243/43/nova/compute/api.py@1214","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            self._add_trait(suffix, name, val)"},{"line_number":273,"context_line":"        return"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def get_request_groups_for_device_profile(self, context, dp_name):"},{"line_number":276,"context_line":"        \"\"\"Create all RGs for the list of device profile groups."},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        Parse the resources/traits and validate them using the same logic"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_3e5bcf86","line":275,"range":{"start_line":275,"start_character":8,"end_line":275,"end_character":45},"in_reply_to":"3fa7e38b_a857b75a","updated":"2019-12-04 09:09:46.000000000","message":"Nit: the new function in cyborg client returns a list of request groups, and so is named get_device_profile_groups.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        Parse the resources/traits and validate them using the same logic"},{"line_number":279,"context_line":"        as from_extra_specs. Each created RG has its requester_id field"},{"line_number":280,"context_line":"        filled with the device profle group id, which is used to match"},{"line_number":281,"context_line":"        ARQs to RGs in conductor/manager.py::create_and_bind_arqs()."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        See module comments in accelerator/cyborg for the relationship"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_ba294e9d","line":280,"range":{"start_line":280,"start_character":31,"end_line":280,"end_character":37},"updated":"2019-11-26 22:31:57.000000000","message":"profile","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        Parse the resources/traits and validate them using the same logic"},{"line_number":279,"context_line":"        as from_extra_specs. Each created RG has its requester_id field"},{"line_number":280,"context_line":"        filled with the device profle group id, which is used to match"},{"line_number":281,"context_line":"        ARQs to RGs in conductor/manager.py::create_and_bind_arqs()."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        See module comments in accelerator/cyborg for the relationship"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_fcd25ffd","line":280,"range":{"start_line":280,"start_character":31,"end_line":280,"end_character":37},"in_reply_to":"3fa7e38b_ba294e9d","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        dp_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":298,"context_line":"            req_id \u003d cyborg.get_device_profile_group_requester_id(dp_group_id)"},{"line_number":299,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":300,"context_line":"            rg_ident \u003d self.add_request_group(rg)"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"            for key, val in dp_group.items():"},{"line_number":303,"context_line":"                # Parse/validate resource/trait specs, ignore rest"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_959b03c7","line":300,"range":{"start_line":298,"start_character":12,"end_line":300,"end_character":49},"updated":"2019-11-26 22:31:57.000000000","message":"As noted elsewhere, since placement now accepts arbitrary strings as suffixes, you don\u0027t really need a separate rg_ident and req_id.\n\n(I recognize it might take a bit of work to get the rest of this file recognizing rg_ident as a string, and you would have to change the microversion we\u0027re using for GET /a_c, so I\u0027m not suggesting you actually change this... unless it makes something significantly easier somewhere else.)","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        dp_groups \u003d cyclient.get_device_profile_groups(dp_name)"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"        for dp_group_id, dp_group in enumerate(dp_groups):"},{"line_number":298,"context_line":"            req_id \u003d cyborg.get_device_profile_group_requester_id(dp_group_id)"},{"line_number":299,"context_line":"            rg \u003d objects.RequestGroup(requester_id\u003dreq_id)"},{"line_number":300,"context_line":"            rg_ident \u003d self.add_request_group(rg)"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"            for key, val in dp_group.items():"},{"line_number":303,"context_line":"                # Parse/validate resource/trait specs, ignore rest"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_de515b65","line":300,"range":{"start_line":298,"start_character":12,"end_line":300,"end_character":49},"in_reply_to":"3fa7e38b_959b03c7","updated":"2019-12-04 09:09:46.000000000","message":"As discussed, this is a possibility but not a requirement.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"}],"nova/tests/fixtures.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":2500,"context_line":""},{"line_number":2501,"context_line":"    dp_name \u003d \u0027fakedev-dp\u0027"},{"line_number":2502,"context_line":"    trait \u003d \u0027CUSTOM_FAKE_DEVICE\u0027"},{"line_number":2503,"context_line":"    device_profile \u003d _get_device_profile(dp_name, trait)"},{"line_number":2504,"context_line":""},{"line_number":2505,"context_line":"    def __init__(self, test):"},{"line_number":2506,"context_line":"        super(CyborgFixture, self).__init__()"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_950543c4","line":2503,"range":{"start_line":2503,"start_character":4,"end_line":2503,"end_character":56},"updated":"2019-11-26 22:31:57.000000000","message":"There\u0027s a danger of tests colliding by doing this at the class level, since the internal dicts are passed around by reference. Suggest getting rid of this and making fake_get_device_profile_list actually *invoke* _get_device_profile() so it gets a new one each time.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":2500,"context_line":""},{"line_number":2501,"context_line":"    dp_name \u003d \u0027fakedev-dp\u0027"},{"line_number":2502,"context_line":"    trait \u003d \u0027CUSTOM_FAKE_DEVICE\u0027"},{"line_number":2503,"context_line":"    device_profile \u003d _get_device_profile(dp_name, trait)"},{"line_number":2504,"context_line":""},{"line_number":2505,"context_line":"    def __init__(self, test):"},{"line_number":2506,"context_line":"        super(CyborgFixture, self).__init__()"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_f009f72a","line":2503,"range":{"start_line":2503,"start_character":4,"end_line":2503,"end_character":56},"in_reply_to":"3fa7e38b_950543c4","updated":"2019-12-04 09:09:46.000000000","message":"Addressed this with a copy.deepcopy() of the internal dicts.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":2504,"context_line":""},{"line_number":2505,"context_line":"    def __init__(self, test):"},{"line_number":2506,"context_line":"        super(CyborgFixture, self).__init__()"},{"line_number":2507,"context_line":"        self.test \u003d test"},{"line_number":2508,"context_line":""},{"line_number":2509,"context_line":"    @staticmethod"},{"line_number":2510,"context_line":"    def fake_get_device_profile_list(dp_name):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_156cf39b","line":2507,"range":{"start_line":2507,"start_character":0,"end_line":2507,"end_character":24},"updated":"2019-11-26 22:31:57.000000000","message":"This bizarre circular reference appears to be unused (at least in this patch). Suggest removing it, whereupon the whole __init__ method can go away.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":2504,"context_line":""},{"line_number":2505,"context_line":"    def __init__(self, test):"},{"line_number":2506,"context_line":"        super(CyborgFixture, self).__init__()"},{"line_number":2507,"context_line":"        self.test \u003d test"},{"line_number":2508,"context_line":""},{"line_number":2509,"context_line":"    @staticmethod"},{"line_number":2510,"context_line":"    def fake_get_device_profile_list(dp_name):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_fceb3fa1","line":2507,"range":{"start_line":2507,"start_character":0,"end_line":2507,"end_character":24},"in_reply_to":"3fa7e38b_156cf39b","updated":"2019-12-04 09:09:46.000000000","message":"Other fixtures do this:\nhttps://github.com/openstack/nova/blob/master/nova/tests/fixtures.py#L1613 \n\nIt is used like:\n\n  self.test.stub_out(...)\n\nBut I am not using that yet, so I agree we don\u0027t need this.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":2510,"context_line":"    def fake_get_device_profile_list(dp_name):"},{"line_number":2511,"context_line":"        return CyborgFixture.device_profile"},{"line_number":2512,"context_line":""},{"line_number":2513,"context_line":"    def setUp(self):"},{"line_number":2514,"context_line":"        super(CyborgFixture, self).setUp()"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_15439313","line":2514,"range":{"start_line":2513,"start_character":0,"end_line":2514,"end_character":42},"updated":"2019-11-26 22:31:57.000000000","message":"redundant","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":2510,"context_line":"    def fake_get_device_profile_list(dp_name):"},{"line_number":2511,"context_line":"        return CyborgFixture.device_profile"},{"line_number":2512,"context_line":""},{"line_number":2513,"context_line":"    def setUp(self):"},{"line_number":2514,"context_line":"        super(CyborgFixture, self).setUp()"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_d004fb16","line":2514,"range":{"start_line":2513,"start_character":0,"end_line":2514,"end_character":42},"in_reply_to":"3fa7e38b_15439313","updated":"2019-12-04 09:09:46.000000000","message":"Adding mocks here, so it won\u0027t be redundant in next patchset.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"fc41aa18d94dbced14a6f8904c02a716c26c4c57","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_69387dd3","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"updated":"2019-12-28 04:51:41.000000000","message":"I think it\u0027s redundant.\n\nMaybe it\u0027s \"\u0027trait:\u0027 + trait + \u0027: \u0027 +  \u0027required\u0027\"","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"fda98963b3860e74447a2f6f17d04b5fe7d7d829","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_6fa52f48","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"in_reply_to":"3fa7e38b_1d839905","updated":"2020-01-15 14:32:45.000000000","message":"Done","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"fda98963b3860e74447a2f6f17d04b5fe7d7d829","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_cfa8e322","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"in_reply_to":"3fa7e38b_1ee001f8","updated":"2020-01-15 14:32:45.000000000","message":"+1","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"17f81bb256d5157a296f6934ca647190b6f4577d","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_1d839905","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"in_reply_to":"3fa7e38b_1ee001f8","updated":"2020-01-15 07:42:07.000000000","message":"Ah, I think I miss something while read this code, yes, it;s key:value, this is correct.\n\n\u003e please put a trailing comma at the end of this line.\n\nYeah, it\u0027s better to add a comma at the end.","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a5d55f4114a16b68626254c6c89c8f0364632c16","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_8ca3f2ff","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"in_reply_to":"3fa7e38b_1ee001f8","updated":"2020-03-23 14:01:28.000000000","message":"the : is required as this is a dict\n\n\u0027trait:\u0027 + trait is the key : is the separtor and \u0027required\u0027 is the value","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"58b6bb88ac085fc3e338893bd312d704bd6ab672","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"           \u0027uuid\u0027: \u0027cbec22f3-ac29-444e-b4bb-98509f32faae\u0027,"},{"line_number":2542,"context_line":"           \u0027groups\u0027: [{"},{"line_number":2543,"context_line":"                \u0027resources:FPGA\u0027: \u00271\u0027,"},{"line_number":2544,"context_line":"                \u0027trait:\u0027 + trait: \u0027required\u0027"},{"line_number":2545,"context_line":"            }],"},{"line_number":2546,"context_line":"            # Skipping links key in Cyborg API return value"},{"line_number":2547,"context_line":"           }"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_1ee001f8","line":2544,"range":{"start_line":2544,"start_character":32,"end_line":2544,"end_character":33},"in_reply_to":"3fa7e38b_69387dd3","updated":"2020-01-03 16:28:59.000000000","message":"\u003e I think it\u0027s redundant.\n \u003e \n \u003e Maybe it\u0027s \"\u0027trait:\u0027 + trait + \u0027: \u0027 +  \u0027required\u0027\"\n\nI don\u0027t think so. He\u0027s generating a key:value here, so this works out to (as an example):\n\n \u0027trait:FOO\u0027: \u0027required\u0027\n\nwhich is what we want. What you have would generate just a string, which does not work given this is a dict.\n\nNote to Sundar, please put a trailing comma at the end of this line.","commit_id":"b5eb35744694bfd8e3c916281278c514c5d71d9b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":2535,"context_line":""},{"line_number":2536,"context_line":"    @staticmethod"},{"line_number":2537,"context_line":"    def fake_get_device_profile_list(dp_name):"},{"line_number":2538,"context_line":"        return copy.deepcopy(CyborgFixture.device_profile)"},{"line_number":2539,"context_line":""},{"line_number":2540,"context_line":"    def setUp(self):"},{"line_number":2541,"context_line":"        super(CyborgFixture, self).setUp()"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_82ca8844","line":2538,"updated":"2020-02-06 16:50:56.000000000","message":"can we simply call _get_device_profile() here, that way we can avoid a copy as that call always returns a new dict","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":2535,"context_line":""},{"line_number":2536,"context_line":"    @staticmethod"},{"line_number":2537,"context_line":"    def fake_get_device_profile_list(dp_name):"},{"line_number":2538,"context_line":"        return copy.deepcopy(CyborgFixture.device_profile)"},{"line_number":2539,"context_line":""},{"line_number":2540,"context_line":"    def setUp(self):"},{"line_number":2541,"context_line":"        super(CyborgFixture, self).setUp()"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_d6efde19","line":2538,"in_reply_to":"3fa7e38b_82ca8844","updated":"2020-02-06 20:01:25.000000000","message":"The next patchset removes this method altogether.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d6fd121deefe1913d4179a11793fb48fd0ad73e","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2542,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2543,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2544,"context_line":"            side_effect\u003dself.fake_get_device_profile_list)).mock"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_62544f24","line":2544,"range":{"start_line":2544,"start_character":12,"end_line":2544,"end_character":57},"updated":"2020-02-05 16:31:42.000000000","message":"There\u0027s way more copying and indirection going on here than necessary. _get_device_profile returns you a (deeply) new object every time, so this could just be\n\n return_value\u003d_get_device_profile(self.dp_name, self.trait)\n\nand you can get rid of `device_profile` and `fake_get_device_profile_list`.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"263e845eaf18c1de37f6d1711bb26ea8cf484484","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2542,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2543,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2544,"context_line":"            side_effect\u003dself.fake_get_device_profile_list)).mock"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_2afdb76c","line":2544,"range":{"start_line":2544,"start_character":12,"end_line":2544,"end_character":57},"in_reply_to":"3fa7e38b_62544f24","updated":"2020-02-06 06:41:46.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2542,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2543,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2544,"context_line":"            side_effect\u003dself.fake_get_device_profile_list)).mock"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_a2c54437","line":2544,"range":{"start_line":2544,"start_character":12,"end_line":2544,"end_character":57},"in_reply_to":"3fa7e38b_62544f24","updated":"2020-02-06 16:50:56.000000000","message":"I agree.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":2535,"context_line":"    def setUp(self):"},{"line_number":2536,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2537,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2538,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2539,"context_line":"            return_value\u003d_get_device_profile(self.dp_name, self.trait))).mock"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_315f3973","line":2538,"updated":"2020-03-04 09:31:50.000000000","message":"I would hook this into the ksa Adapter.get call as now the fixture operates not on the Nova-Cyborg boundary but inside Nova. This is confusing because it causes that the above device profile list is not in a form that the Cyborg API returns (does not have device_profiles key) as _get_device_profile_list already removes the device_profile keys from the Cyborg response. Alternatively we could make _get_device_profile_list just return a cyborg response unchanged and then we could hook the fixture to _get_device_profile_list without the confusion.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":2535,"context_line":"    def setUp(self):"},{"line_number":2536,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2537,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2538,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2539,"context_line":"            return_value\u003d_get_device_profile(self.dp_name, self.trait))).mock"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_796798b8","line":2538,"in_reply_to":"1fa4df85_315f3973","updated":"2020-03-08 23:24:21.000000000","message":"The questions/concerns about the \u0027device_profiles\u0027 key have been addressed in other comments. The problem with mocking the ksa Adapter GET is that the mock should handle both device profiles and ARQs, latter with only_resolved parameter, etc. The _get_device_profile_list() does only two things beyond calling Cyborg -- decode the JSON and retrieve the \u0027device_profiles\u0027 key -- both of which are tested by UT.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a136de550245958bc5389cd77bbf9740c127c9f5","unresolved":false,"context_lines":[{"line_number":2535,"context_line":"    def setUp(self):"},{"line_number":2536,"context_line":"        super(CyborgFixture, self).setUp()"},{"line_number":2537,"context_line":"        self.mock_get_dp \u003d self.useFixture(fixtures.MockPatch("},{"line_number":2538,"context_line":"            \u0027nova.accelerator.cyborg._CyborgClient._get_device_profile_list\u0027,"},{"line_number":2539,"context_line":"            return_value\u003d_get_device_profile(self.dp_name, self.trait))).mock"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_0275c8f9","line":2538,"in_reply_to":"1fa4df85_796798b8","updated":"2020-03-09 15:35:17.000000000","message":"OK. Let\u0027s consider the Fixture improvement separately","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"}],"nova/tests/functional/integrated_helpers.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":429,"context_line":""},{"line_number":430,"context_line":"    def _get_compute_provider_uuids(self):"},{"line_number":431,"context_line":"        \"\"\"Get list of UUIDs of compute node resource providers.\"\"\""},{"line_number":432,"context_line":"        providers \u003d self._get_all_providers()"},{"line_number":433,"context_line":"        uuids \u003d [rp[\u0027uuid\u0027] for rp in providers"},{"line_number":434,"context_line":"                 if rp[\u0027uuid\u0027] \u003d\u003d rp[\u0027root_provider_uuid\u0027]]"},{"line_number":435,"context_line":"        return uuids"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    def _create_trait(self, trait):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_550fcbdf","line":434,"range":{"start_line":432,"start_character":0,"end_line":434,"end_character":59},"updated":"2019-11-26 22:31:57.000000000","message":"take advantage of the COMPUTE_NODE trait now that https://review.opendev.org/#/c/688979/ is merged","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":429,"context_line":""},{"line_number":430,"context_line":"    def _get_compute_provider_uuids(self):"},{"line_number":431,"context_line":"        \"\"\"Get list of UUIDs of compute node resource providers.\"\"\""},{"line_number":432,"context_line":"        providers \u003d self._get_all_providers()"},{"line_number":433,"context_line":"        uuids \u003d [rp[\u0027uuid\u0027] for rp in providers"},{"line_number":434,"context_line":"                 if rp[\u0027uuid\u0027] \u003d\u003d rp[\u0027root_provider_uuid\u0027]]"},{"line_number":435,"context_line":"        return uuids"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    def _create_trait(self, trait):"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_50180b75","line":434,"range":{"start_line":432,"start_character":0,"end_line":434,"end_character":59},"in_reply_to":"3fa7e38b_550fcbdf","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"}],"nova/tests/functional/test_servers.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"aeda5fb0aac86307bde5339524b8582d7e427bc1","unresolved":false,"context_lines":[{"line_number":7440,"context_line":"        flavor.create()"},{"line_number":7441,"context_line":"        return flavor_id"},{"line_number":7442,"context_line":""},{"line_number":7443,"context_line":"    @mock.patch(\u0027nova.accelerator.cyborg._CyborgClient.\u0027"},{"line_number":7444,"context_line":"                \u0027_get_device_profile_list\u0027)"},{"line_number":7445,"context_line":"    def test_create_server(self, mock_get_dp):"},{"line_number":7446,"context_line":"        mock_get_dp.side_effect \u003d self.cyborg.fake_get_device_profile_list"},{"line_number":7447,"context_line":""},{"line_number":7448,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7449,"context_line":"        server_req \u003d self._build_server(flavor_id)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_952ea340","line":7446,"range":{"start_line":7443,"start_character":0,"end_line":7446,"end_character":74},"updated":"2019-11-26 22:31:57.000000000","message":"This (patching _get_device_profile_list to return your fake device profile) should be done by your fixture.","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"d36e49c9f4bd8d6c08d1787c034d93515642b099","unresolved":false,"context_lines":[{"line_number":7440,"context_line":"        flavor.create()"},{"line_number":7441,"context_line":"        return flavor_id"},{"line_number":7442,"context_line":""},{"line_number":7443,"context_line":"    @mock.patch(\u0027nova.accelerator.cyborg._CyborgClient.\u0027"},{"line_number":7444,"context_line":"                \u0027_get_device_profile_list\u0027)"},{"line_number":7445,"context_line":"    def test_create_server(self, mock_get_dp):"},{"line_number":7446,"context_line":"        mock_get_dp.side_effect \u003d self.cyborg.fake_get_device_profile_list"},{"line_number":7447,"context_line":""},{"line_number":7448,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7449,"context_line":"        server_req \u003d self._build_server(flavor_id)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fa7e38b_35d30162","line":7446,"range":{"start_line":7443,"start_character":0,"end_line":7446,"end_character":74},"in_reply_to":"3fa7e38b_952ea340","updated":"2019-12-04 09:09:46.000000000","message":"Done","commit_id":"7d31e45c4169c194112bd669fd87d47e23b25578"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"022ca343266be3cec4ed1097aaf06429f5ba8f04","unresolved":false,"context_lines":[{"line_number":7376,"context_line":"        self.assertNotIn(\u0027allocation\u0027, binding_profile)"},{"line_number":7377,"context_line":""},{"line_number":7378,"context_line":""},{"line_number":7379,"context_line":"class AcceleratorServerTest(ServersTestBase):"},{"line_number":7380,"context_line":""},{"line_number":7381,"context_line":"    ADMIN_API \u003d True"},{"line_number":7382,"context_line":"    compute_driver \u003d \u0027fake.SmallFakeDriver\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_ab42ff0b","line":7379,"range":{"start_line":7379,"start_character":28,"end_line":7379,"end_character":43},"updated":"2019-12-04 15:40:59.000000000","message":"Don\u0027t use this, it has a bunch of crusty old things in it which we don\u0027t want to use, e.g. CastAsCall fixture and it used to have a weird version of _wait_for_state_change which was different from InstanceHelperMixin\u0027s more useful _wait_for_state_change (I think they are the same now though).\n\nYou likely should be using ProviderUsageBaseTestCase since I would expect placement is going to be required for validating cyborg/nova tests since there are resource allocations involved, like QoS bandwidth aware neutron ports, right?\n\nIt would probably also be good to move any new tests into a new test module rather than test_servers.py - this module is getting big with everyone throwing everything in here.\n\nHow about a new nova/tests/functional/test_cyborg.py module?","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"022ca343266be3cec4ed1097aaf06429f5ba8f04","unresolved":false,"context_lines":[{"line_number":7378,"context_line":""},{"line_number":7379,"context_line":"class AcceleratorServerTest(ServersTestBase):"},{"line_number":7380,"context_line":""},{"line_number":7381,"context_line":"    ADMIN_API \u003d True"},{"line_number":7382,"context_line":"    compute_driver \u003d \u0027fake.SmallFakeDriver\u0027"},{"line_number":7383,"context_line":""},{"line_number":7384,"context_line":"    def setUp(self):"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_2b604fa4","line":7381,"updated":"2019-12-04 15:40:59.000000000","message":"See this is the kind of stuff you don\u0027t need from ServersTestBase. ProviderUsageBaseTestCase already creates an admin API fixture to use.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"022ca343266be3cec4ed1097aaf06429f5ba8f04","unresolved":false,"context_lines":[{"line_number":7388,"context_line":"        self.admin_api.microversion \u003d \u0027latest\u0027"},{"line_number":7389,"context_line":"        self._setup_placement()"},{"line_number":7390,"context_line":""},{"line_number":7391,"context_line":"    def _get_compute_provider_uuids(self):"},{"line_number":7392,"context_line":"        providers \u003d self.placement_api.get("},{"line_number":7393,"context_line":"            \u0027/resource_providers\u0027, required\u003dos_traits.COMPUTE_NODE,"},{"line_number":7394,"context_line":"            version\u003d\u00271.18\u0027).body[\u0027resource_providers\u0027]"},{"line_number":7395,"context_line":"        uuids \u003d [rp[\u0027uuid\u0027] for rp in providers]"},{"line_number":7396,"context_line":"        return uuids"},{"line_number":7397,"context_line":""},{"line_number":7398,"context_line":"    def _post_resource_provider(self, rp_name, parent_rp_uuid\u003dNone):"},{"line_number":7399,"context_line":"        body \u003d {\u0027name\u0027: rp_name}"},{"line_number":7400,"context_line":"        if parent_rp_uuid:"},{"line_number":7401,"context_line":"            body.update({\u0027parent_provider_uuid\u0027: parent_rp_uuid})"},{"line_number":7402,"context_line":"        return self.placement_api.post("},{"line_number":7403,"context_line":"            url\u003d\u0027/resource_providers\u0027,"},{"line_number":7404,"context_line":"            version\u003d\u00271.20\u0027, body\u003dbody).body"},{"line_number":7405,"context_line":""},{"line_number":7406,"context_line":"    def _update_inventory(self, rp_uuid, inv_body):"},{"line_number":7407,"context_line":"        return self.placement_api.put("},{"line_number":7408,"context_line":"            url\u003d (\u0027/resource_providers/%s/inventories\u0027 % rp_uuid),"},{"line_number":7409,"context_line":"            body\u003dinv_body).body"},{"line_number":7410,"context_line":""},{"line_number":7411,"context_line":"    def _create_trait(self, trait):"},{"line_number":7412,"context_line":"        return self.placement_api.put(\u0027/traits/%s\u0027 % trait, {}, version\u003d\u00271.6\u0027)"},{"line_number":7413,"context_line":""},{"line_number":7414,"context_line":"    def _set_provider_traits(self, rp_uuid, traits):"},{"line_number":7415,"context_line":"        provider \u003d self.placement_api.get("},{"line_number":7416,"context_line":"            \u0027/resource_providers/%s\u0027 % rp_uuid).body"},{"line_number":7417,"context_line":"        put_traits_req \u003d {"},{"line_number":7418,"context_line":"            \u0027resource_provider_generation\u0027: provider[\u0027generation\u0027],"},{"line_number":7419,"context_line":"            \u0027traits\u0027: traits"},{"line_number":7420,"context_line":"        }"},{"line_number":7421,"context_line":"        return self.placement_api.put("},{"line_number":7422,"context_line":"            \u0027/resource_providers/%s/traits\u0027 % rp_uuid,"},{"line_number":7423,"context_line":"            put_traits_req, version\u003d\u00271.6\u0027)"},{"line_number":7424,"context_line":""},{"line_number":7425,"context_line":"    def _setup_placement(self):"},{"line_number":7426,"context_line":"        compute_rp_uuids \u003d self._get_compute_provider_uuids()"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_ab6bdf83","line":7423,"range":{"start_line":7391,"start_character":4,"end_line":7423,"end_character":42},"updated":"2019-12-04 15:40:59.000000000","message":"Why redo all of this stuff? ProviderUsageBaseTestCase gives it to you for free.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0467bd9bd9bf44850908de54b2fe13cff9507e4c","unresolved":false,"context_lines":[{"line_number":7388,"context_line":"        self.admin_api.microversion \u003d \u0027latest\u0027"},{"line_number":7389,"context_line":"        self._setup_placement()"},{"line_number":7390,"context_line":""},{"line_number":7391,"context_line":"    def _get_compute_provider_uuids(self):"},{"line_number":7392,"context_line":"        providers \u003d self.placement_api.get("},{"line_number":7393,"context_line":"            \u0027/resource_providers\u0027, required\u003dos_traits.COMPUTE_NODE,"},{"line_number":7394,"context_line":"            version\u003d\u00271.18\u0027).body[\u0027resource_providers\u0027]"},{"line_number":7395,"context_line":"        uuids \u003d [rp[\u0027uuid\u0027] for rp in providers]"},{"line_number":7396,"context_line":"        return uuids"},{"line_number":7397,"context_line":""},{"line_number":7398,"context_line":"    def _post_resource_provider(self, rp_name, parent_rp_uuid\u003dNone):"},{"line_number":7399,"context_line":"        body \u003d {\u0027name\u0027: rp_name}"},{"line_number":7400,"context_line":"        if parent_rp_uuid:"},{"line_number":7401,"context_line":"            body.update({\u0027parent_provider_uuid\u0027: parent_rp_uuid})"},{"line_number":7402,"context_line":"        return self.placement_api.post("},{"line_number":7403,"context_line":"            url\u003d\u0027/resource_providers\u0027,"},{"line_number":7404,"context_line":"            version\u003d\u00271.20\u0027, body\u003dbody).body"},{"line_number":7405,"context_line":""},{"line_number":7406,"context_line":"    def _update_inventory(self, rp_uuid, inv_body):"},{"line_number":7407,"context_line":"        return self.placement_api.put("},{"line_number":7408,"context_line":"            url\u003d (\u0027/resource_providers/%s/inventories\u0027 % rp_uuid),"},{"line_number":7409,"context_line":"            body\u003dinv_body).body"},{"line_number":7410,"context_line":""},{"line_number":7411,"context_line":"    def _create_trait(self, trait):"},{"line_number":7412,"context_line":"        return self.placement_api.put(\u0027/traits/%s\u0027 % trait, {}, version\u003d\u00271.6\u0027)"},{"line_number":7413,"context_line":""},{"line_number":7414,"context_line":"    def _set_provider_traits(self, rp_uuid, traits):"},{"line_number":7415,"context_line":"        provider \u003d self.placement_api.get("},{"line_number":7416,"context_line":"            \u0027/resource_providers/%s\u0027 % rp_uuid).body"},{"line_number":7417,"context_line":"        put_traits_req \u003d {"},{"line_number":7418,"context_line":"            \u0027resource_provider_generation\u0027: provider[\u0027generation\u0027],"},{"line_number":7419,"context_line":"            \u0027traits\u0027: traits"},{"line_number":7420,"context_line":"        }"},{"line_number":7421,"context_line":"        return self.placement_api.put("},{"line_number":7422,"context_line":"            \u0027/resource_providers/%s/traits\u0027 % rp_uuid,"},{"line_number":7423,"context_line":"            put_traits_req, version\u003d\u00271.6\u0027)"},{"line_number":7424,"context_line":""},{"line_number":7425,"context_line":"    def _setup_placement(self):"},{"line_number":7426,"context_line":"        compute_rp_uuids \u003d self._get_compute_provider_uuids()"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_4bf02b92","line":7423,"range":{"start_line":7391,"start_character":4,"end_line":7423,"end_character":42},"in_reply_to":"3fa7e38b_ab6bdf83","updated":"2019-12-04 16:19:01.000000000","message":"ProviderUsageBaseTestCase does not provide a way to get compute nodes alone; one would have to query all nodes and filter. Probably not a big thing in a test env, but ...\n\nThe post_resource_provider in ProviderUsageBaseTestCase does not give me a way to created nested RPs, which I clearly need. I may want the ability to create an RP with a given UUID, and that\u0027s not there either.\n\nAlso, all the assertY methods in that class are intertwined with the generic resources (cpu/ram/disk). I need specific checks like [1].\n\nSo I can\u0027t use ProviderUsageBaseTestCase as it is and I\u0027m not allowed to take just the useful parts. What are the other options?\n\n[1] https://review.opendev.org/gitweb?p\u003dopenstack/nova.git;f\u003dnova/tests/functional/test_servers.py;hb\u003drefs/changes/35/673735/20#l7463","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6a33107160f65a24931d1cabdd304416f76e2a96","unresolved":false,"context_lines":[{"line_number":7445,"context_line":"        }"},{"line_number":7446,"context_line":"        self._update_inventory(self.device_rp_uuid, inventory)"},{"line_number":7447,"context_line":"        self._create_trait(self.cyborg.trait)"},{"line_number":7448,"context_line":"        self._set_provider_traits(self.device_rp_uuid, [self.cyborg.trait])"},{"line_number":7449,"context_line":""},{"line_number":7450,"context_line":"    def _create_acc_flavor(self):"},{"line_number":7451,"context_line":"        ctxt \u003d context.get_admin_context()"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_68516d30","line":7448,"updated":"2019-12-04 15:26:04.000000000","message":"So, because you dropped the refactor, you replicated all of this from it just so you could inherit from ServerTestBase and get what? self._wait_for_state_change() ? That\u0027s a little crazy!\n\nOther tests inherit from ProviderUsageBaseTestCase and do almost exactly what you have here.  They copy the (much smaller) state wait method instead of all the (more complicated) placement stuff. Maybe we just need a generic wait_for_state() helper or something so you can inherit from the provider test base. Right?","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0467bd9bd9bf44850908de54b2fe13cff9507e4c","unresolved":false,"context_lines":[{"line_number":7445,"context_line":"        }"},{"line_number":7446,"context_line":"        self._update_inventory(self.device_rp_uuid, inventory)"},{"line_number":7447,"context_line":"        self._create_trait(self.cyborg.trait)"},{"line_number":7448,"context_line":"        self._set_provider_traits(self.device_rp_uuid, [self.cyborg.trait])"},{"line_number":7449,"context_line":""},{"line_number":7450,"context_line":"    def _create_acc_flavor(self):"},{"line_number":7451,"context_line":"        ctxt \u003d context.get_admin_context()"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_cb373bfe","line":7448,"in_reply_to":"3fa7e38b_68516d30","updated":"2019-12-04 16:19:01.000000000","message":"Please see above.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"022ca343266be3cec4ed1097aaf06429f5ba8f04","unresolved":false,"context_lines":[{"line_number":7464,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7465,"context_line":"        server_req \u003d self._build_server(flavor_id)"},{"line_number":7466,"context_line":"        server \u003d self.api.post_server({\"server\": server_req})"},{"line_number":7467,"context_line":"        server \u003d self._wait_for_state_change(server, \u0027BUILD\u0027)"},{"line_number":7468,"context_line":""},{"line_number":7469,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_2b05afc1","line":7467,"range":{"start_line":7467,"start_character":17,"end_line":7467,"end_character":61},"updated":"2019-12-04 15:40:59.000000000","message":"This is exactly the old busted ServerTestBase._wait_for_state_change you *do not* want to use - it\u0027s waiting for the server status to transition *from* something (BUILD in this case) rather than the more correct InstanceHelperMixing._wait_for_state_change which waits for the server status to transition *to* a terminal state.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0467bd9bd9bf44850908de54b2fe13cff9507e4c","unresolved":false,"context_lines":[{"line_number":7464,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7465,"context_line":"        server_req \u003d self._build_server(flavor_id)"},{"line_number":7466,"context_line":"        server \u003d self.api.post_server({\"server\": server_req})"},{"line_number":7467,"context_line":"        server \u003d self._wait_for_state_change(server, \u0027BUILD\u0027)"},{"line_number":7468,"context_line":""},{"line_number":7469,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_16ffb600","line":7467,"range":{"start_line":7467,"start_character":17,"end_line":7467,"end_character":61},"in_reply_to":"3fa7e38b_2b05afc1","updated":"2019-12-04 16:19:01.000000000","message":"I found that curious too, but the majority of classes/tests in this file are using that. Perhaps it would be good to put an explanatory note on ServerTestBase class.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1429773effb8b1c823ab8ba09499df46f6066c88","unresolved":false,"context_lines":[{"line_number":7464,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7465,"context_line":"        server_req \u003d self._build_server(flavor_id)"},{"line_number":7466,"context_line":"        server \u003d self.api.post_server({\"server\": server_req})"},{"line_number":7467,"context_line":"        server \u003d self._wait_for_state_change(server, \u0027BUILD\u0027)"},{"line_number":7468,"context_line":""},{"line_number":7469,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_6b13a702","line":7467,"range":{"start_line":7467,"start_character":17,"end_line":7467,"end_character":61},"in_reply_to":"3fa7e38b_2b05afc1","updated":"2019-12-04 15:43:01.000000000","message":"Note that ProviderUsageBaseTestCase uses InstanceHelperMixin so that\u0027s why it has _wait_for_state_change also.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0467bd9bd9bf44850908de54b2fe13cff9507e4c","unresolved":false,"context_lines":[{"line_number":7464,"context_line":"        flavor_id \u003d self._create_acc_flavor()"},{"line_number":7465,"context_line":"        server_req \u003d self._build_server(flavor_id)"},{"line_number":7466,"context_line":"        server \u003d self.api.post_server({\"server\": server_req})"},{"line_number":7467,"context_line":"        server \u003d self._wait_for_state_change(server, \u0027BUILD\u0027)"},{"line_number":7468,"context_line":""},{"line_number":7469,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_36b51233","line":7467,"range":{"start_line":7467,"start_character":17,"end_line":7467,"end_character":61},"in_reply_to":"3fa7e38b_6b13a702","updated":"2019-12-04 16:19:01.000000000","message":"I still don\u0027t understand why a PlacementHelperMixin is a bad idea when InstanceHelperMixin is not.","commit_id":"b4d7cdeb577be92183afa808c700c726ea1b3371"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":7600,"context_line":"    def setUp(self):"},{"line_number":7601,"context_line":"        super(AcceleratorServerTest, self).setUp()"},{"line_number":7602,"context_line":"        self.cyborg \u003d self.useFixture(nova_fixtures.CyborgFixture())"},{"line_number":7603,"context_line":"        self._setup_placement()"},{"line_number":7604,"context_line":""},{"line_number":7605,"context_line":"    def _post_nested_resource_provider(self, rp_name, parent_rp_uuid):"},{"line_number":7606,"context_line":"        body \u003d {\u0027name\u0027: rp_name, \u0027parent_provider_uuid\u0027: parent_rp_uuid}"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_0200d868","line":7603,"updated":"2020-02-06 16:50:56.000000000","message":"The name is misleading as this function starts a compute service as well. As soon as you want one placement service and two compute services this will become a problem.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":7600,"context_line":"    def setUp(self):"},{"line_number":7601,"context_line":"        super(AcceleratorServerTest, self).setUp()"},{"line_number":7602,"context_line":"        self.cyborg \u003d self.useFixture(nova_fixtures.CyborgFixture())"},{"line_number":7603,"context_line":"        self._setup_placement()"},{"line_number":7604,"context_line":""},{"line_number":7605,"context_line":"    def _post_nested_resource_provider(self, rp_name, parent_rp_uuid):"},{"line_number":7606,"context_line":"        body \u003d {\u0027name\u0027: rp_name, \u0027parent_provider_uuid\u0027: parent_rp_uuid}"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_56620ea9","line":7603,"in_reply_to":"3fa7e38b_0200d868","updated":"2020-02-06 20:01:25.000000000","message":"Done","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":7616,"context_line":""},{"line_number":7617,"context_line":"        # Created nested RP for device"},{"line_number":7618,"context_line":"        resp \u003d self._post_nested_resource_provider("},{"line_number":7619,"context_line":"            \u0027FakeDevice\u0027, parent_rp_uuid\u003dself.compute1_rp_uuid)"},{"line_number":7620,"context_line":"        self.device_rp_uuid \u003d resp[\u0027uuid\u0027]"},{"line_number":7621,"context_line":"        inventory \u003d {"},{"line_number":7622,"context_line":"            \u0027resource_provider_generation\u0027: 0,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_82f368a0","line":7619,"range":{"start_line":7619,"start_character":13,"end_line":7619,"end_character":23},"updated":"2020-02-06 16:50:56.000000000","message":"You need a unique name as soon as you have more than one compute with cyborg devices. Also I suggest to try to mimic the naming scheme of the real cyborg service here as that would help matching the test to reality later.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c868e6e77b4d9beb69bbabcadb56fc0d7cc6a240","unresolved":false,"context_lines":[{"line_number":7616,"context_line":""},{"line_number":7617,"context_line":"        # Created nested RP for device"},{"line_number":7618,"context_line":"        resp \u003d self._post_nested_resource_provider("},{"line_number":7619,"context_line":"            \u0027FakeDevice\u0027, parent_rp_uuid\u003dself.compute1_rp_uuid)"},{"line_number":7620,"context_line":"        self.device_rp_uuid \u003d resp[\u0027uuid\u0027]"},{"line_number":7621,"context_line":"        inventory \u003d {"},{"line_number":7622,"context_line":"            \u0027resource_provider_generation\u0027: 0,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_1ddd876d","line":7619,"range":{"start_line":7619,"start_character":13,"end_line":7619,"end_character":23},"in_reply_to":"3fa7e38b_56e52e06","updated":"2020-02-07 15:53:39.000000000","message":"It is OK now. It will be only problematic when you need two such hosts as both host will try to create an RP with the same FakeDevice name. But I guess migration as such is out of scope now.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":7616,"context_line":""},{"line_number":7617,"context_line":"        # Created nested RP for device"},{"line_number":7618,"context_line":"        resp \u003d self._post_nested_resource_provider("},{"line_number":7619,"context_line":"            \u0027FakeDevice\u0027, parent_rp_uuid\u003dself.compute1_rp_uuid)"},{"line_number":7620,"context_line":"        self.device_rp_uuid \u003d resp[\u0027uuid\u0027]"},{"line_number":7621,"context_line":"        inventory \u003d {"},{"line_number":7622,"context_line":"            \u0027resource_provider_generation\u0027: 0,"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_56e52e06","line":7619,"range":{"start_line":7619,"start_character":13,"end_line":7619,"end_character":23},"in_reply_to":"3fa7e38b_82f368a0","updated":"2020-02-06 20:01:25.000000000","message":"Sure. It is a single host with a single device for now. Plus, this matches what Cyborg actually does: by default, we enable the Fake driver, which exposes a single device with a single resource provider, but that RP contains a large number of accelerators (16 currently). Example:\n\n $ openstack resource provider list -c uuid -c name\n +--------------------------------------+-----------------------------+\n | uuid                                 | name                        |\n +--------------------------------------+-----------------------------+\n | 9af9c421-3e3a-4be8-a269-128cb763b89d | \u003chostname\u003e                    |\n | 03631f82-20a9-3f67-a29d-dc1abe4041bf | FakeDevice                  |\n | 4c9822d7-be4a-3bc8-afe4-b43c51ca6cd9 | intel-fpga-dev_0000:01:00.0 |\n +--------------------------------------+-----------------------------+\n\nIn this test env, we only create 2 accelerators (line 7625 below) but any number \u003e 1 should work for testing.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e4d3177a37e7b294a9ce2fffa60b307230ccee5d","unresolved":false,"context_lines":[{"line_number":7649,"context_line":"            image_uuid\u003d\u0027155d900f-4e14-4e4c-a73d-069cbf4541e6\u0027,"},{"line_number":7650,"context_line":"            networks\u003d\u0027none\u0027, expected_state\u003d\u0027ACTIVE\u0027)"},{"line_number":7651,"context_line":""},{"line_number":7652,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_a21c64c3","line":7652,"updated":"2020-02-06 16:50:56.000000000","message":"This is a functional test so please validate the expected behavior based on external interfaces if possible. Like checking placement allocations. \n\nIf this is temporary as the code so far only does a single get of the DP then I\u0027m OK with this now. But a TODO would be helpful here for the reader.","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c868e6e77b4d9beb69bbabcadb56fc0d7cc6a240","unresolved":false,"context_lines":[{"line_number":7649,"context_line":"            image_uuid\u003d\u0027155d900f-4e14-4e4c-a73d-069cbf4541e6\u0027,"},{"line_number":7650,"context_line":"            networks\u003d\u0027none\u0027, expected_state\u003d\u0027ACTIVE\u0027)"},{"line_number":7651,"context_line":""},{"line_number":7652,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_ddcccfbf","line":7652,"in_reply_to":"3fa7e38b_5649ae2c","updated":"2020-02-07 15:53:39.000000000","message":"thanks","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"dc06cfc82b1bc833484ba206c22fe1cbbaec3914","unresolved":false,"context_lines":[{"line_number":7649,"context_line":"            image_uuid\u003d\u0027155d900f-4e14-4e4c-a73d-069cbf4541e6\u0027,"},{"line_number":7650,"context_line":"            networks\u003d\u0027none\u0027, expected_state\u003d\u0027ACTIVE\u0027)"},{"line_number":7651,"context_line":""},{"line_number":7652,"context_line":"        self.cyborg.mock_get_dp.assert_called_once_with(self.cyborg.dp_name)"}],"source_content_type":"text/x-python","patch_set":55,"id":"3fa7e38b_5649ae2c","line":7652,"in_reply_to":"3fa7e38b_a21c64c3","updated":"2020-02-06 20:01:25.000000000","message":"Yes, I check placement allocations in a later patch [1]. Will add a TODO here.\n\n[1] https://review.opendev.org/#/c/631244/59/nova/tests/functional/test_servers.py@7644","commit_id":"4a7c4ab1d41a852f168d172ae5d5d3c88a27b77f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":7602,"context_line":"            url\u003d\u0027/resource_providers\u0027, version\u003d\u00271.20\u0027, body\u003dbody).body"},{"line_number":7603,"context_line":""},{"line_number":7604,"context_line":"    def _setup_placement(self):"},{"line_number":7605,"context_line":"        compute_rp_uuids \u003d ["},{"line_number":7606,"context_line":"           rp[\u0027uuid\u0027] for rp in self._get_all_providers()"},{"line_number":7607,"context_line":"           if rp[\u0027uuid\u0027] \u003d\u003d rp[\u0027root_provider_uuid\u0027]]"},{"line_number":7608,"context_line":"        self.compute1_rp_uuid \u003d compute_rp_uuids[0]"},{"line_number":7609,"context_line":""},{"line_number":7610,"context_line":"        # Created nested RP for device"},{"line_number":7611,"context_line":"        resp \u003d self._post_nested_resource_provider("}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_f18761b4","line":7608,"range":{"start_line":7605,"start_character":0,"end_line":7608,"end_character":51},"updated":"2020-03-04 09:31:50.000000000","message":"you can use this helper instead:\n\n    self.compute1_rp_uuid \u003d self._get_provider_uuid_by_host(\u0027accel_host\u0027)","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":7602,"context_line":"            url\u003d\u0027/resource_providers\u0027, version\u003d\u00271.20\u0027, body\u003dbody).body"},{"line_number":7603,"context_line":""},{"line_number":7604,"context_line":"    def _setup_placement(self):"},{"line_number":7605,"context_line":"        compute_rp_uuids \u003d ["},{"line_number":7606,"context_line":"           rp[\u0027uuid\u0027] for rp in self._get_all_providers()"},{"line_number":7607,"context_line":"           if rp[\u0027uuid\u0027] \u003d\u003d rp[\u0027root_provider_uuid\u0027]]"},{"line_number":7608,"context_line":"        self.compute1_rp_uuid \u003d compute_rp_uuids[0]"},{"line_number":7609,"context_line":""},{"line_number":7610,"context_line":"        # Created nested RP for device"},{"line_number":7611,"context_line":"        resp \u003d self._post_nested_resource_provider("}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_01d95455","line":7608,"range":{"start_line":7605,"start_character":0,"end_line":7608,"end_character":51},"in_reply_to":"1fa4df85_f18761b4","updated":"2020-03-08 23:24:21.000000000","message":"There is only host in this test case. SO, it should make no difference.\n\nI\u0027ll recast this to be more similar to the way it is done in subsequent patches. That will make this explicit by setting self.NUM_HOSTS\u003d1 for this test case.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"37174c90f63a1195f082ea9ac1d4617e06668fa5","unresolved":false,"context_lines":[{"line_number":7612,"context_line":"        self.device_rp_uuids \u003d list(self.device_rp_map.values())"},{"line_number":7613,"context_line":""},{"line_number":7614,"context_line":"    def _create_device_rp(self, index, compute_rp_uuid,"},{"line_number":7615,"context_line":"                          resource\u003d\u0027FPGA\u0027, res_amt\u003d2):"},{"line_number":7616,"context_line":"        \"\"\"Created nested RP for a device. There is one per host."},{"line_number":7617,"context_line":""},{"line_number":7618,"context_line":"        :param index: Number of the device rp uuid for this setup"}],"source_content_type":"text/x-python","patch_set":61,"id":"1fa4df85_456bb8ef","line":7615,"range":{"start_line":7615,"start_character":43,"end_line":7615,"end_character":50},"updated":"2020-03-10 17:00:37.000000000","message":"nit: I would write it out resource_amount","commit_id":"fc17de58bc6cecaa20bacb8c579212da694ff181"}],"nova/tests/unit/compute/test_compute_api.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":60,"id":"1fa4df85_c4faa5bb","updated":"2020-03-04 09:31:50.000000000","message":"after you clean up the current unit test, it becomes clear that we don\u0027t have unit test coverage for the change in _provision_instance() as there is no flavor in the these tests that has a dp in the extra spec","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        self.compute_api \u003d compute_api.API()"},{"line_number":87,"context_line":"        self.context \u003d context.RequestContext(self.user_id,"},{"line_number":88,"context_line":"                                              self.project_id)"},{"line_number":89,"context_line":"        self.stub_out(\u0027nova.accelerator.cyborg._CyborgClient.\u0027"},{"line_number":90,"context_line":"                      \u0027get_device_profile_groups\u0027, lambda *a, **kw: [])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_vm_states(self, exclude_states\u003dNone):"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_24cff9b0","line":89,"updated":"2020-03-04 09:31:50.000000000","message":"you don\u0027t need this. The flavor used in these test does not have dp added to the extra_spec so cyborg is not called.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        self.compute_api \u003d compute_api.API()"},{"line_number":87,"context_line":"        self.context \u003d context.RequestContext(self.user_id,"},{"line_number":88,"context_line":"                                              self.project_id)"},{"line_number":89,"context_line":"        self.stub_out(\u0027nova.accelerator.cyborg._CyborgClient.\u0027"},{"line_number":90,"context_line":"                      \u0027get_device_profile_groups\u0027, lambda *a, **kw: [])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def _get_vm_states(self, exclude_states\u003dNone):"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_f0016406","line":89,"in_reply_to":"1fa4df85_24cff9b0","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4718,"context_line":"        fake_keypair \u003d objects.KeyPair(name\u003d\u0027test\u0027)"},{"line_number":4719,"context_line":"        fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4720,"context_line":"        fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4721,"context_line":"        mock_rs.return_value \u003d fake_rs"},{"line_number":4722,"context_line":""},{"line_number":4723,"context_line":"        @mock.patch.object(self.compute_api, \u0027_get_volumes_for_bdms\u0027)"},{"line_number":4724,"context_line":"        @mock.patch.object(self.compute_api,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_e4c48193","line":4721,"updated":"2020-03-04 09:31:50.000000000","message":"you don\u0027t need this if you use the instance_type in _provision_instance() instead of request_spec.flavor","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4718,"context_line":"        fake_keypair \u003d objects.KeyPair(name\u003d\u0027test\u0027)"},{"line_number":4719,"context_line":"        fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4720,"context_line":"        fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4721,"context_line":"        mock_rs.return_value \u003d fake_rs"},{"line_number":4722,"context_line":""},{"line_number":4723,"context_line":"        @mock.patch.object(self.compute_api, \u0027_get_volumes_for_bdms\u0027)"},{"line_number":4724,"context_line":"        @mock.patch.object(self.compute_api,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_ea98b6c0","line":4721,"in_reply_to":"1fa4df85_e4c48193","updated":"2020-03-08 23:24:21.000000000","message":"To test that reqspec.request_groups got the right request groups from the device profile, we\u0027d need to mock this.\n\nHowever, I\u0027ll add new test cases; so this test case does not need it.","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4733,"context_line":"        def do_test(mock_bdm_v, mock_cdb, mock_sg, mock_cniq, mock_get_vols):"},{"line_number":4734,"context_line":"            mock_cniq.return_value \u003d 1"},{"line_number":4735,"context_line":"            self.compute_api._provision_instances(self.context,"},{"line_number":4736,"context_line":"                                                  mock.sentinel.flavor,"},{"line_number":4737,"context_line":"                                                  1, 1, mock.MagicMock(),"},{"line_number":4738,"context_line":"                                                  {}, None,"},{"line_number":4739,"context_line":"                                                  None, None, None, {}, None,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_a468c986","line":4736,"range":{"start_line":4736,"start_character":50,"end_line":4736,"end_character":71},"updated":"2020-03-04 09:31:50.000000000","message":"pass the result of self._create_flavor() here","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4733,"context_line":"        def do_test(mock_bdm_v, mock_cdb, mock_sg, mock_cniq, mock_get_vols):"},{"line_number":4734,"context_line":"            mock_cniq.return_value \u003d 1"},{"line_number":4735,"context_line":"            self.compute_api._provision_instances(self.context,"},{"line_number":4736,"context_line":"                                                  mock.sentinel.flavor,"},{"line_number":4737,"context_line":"                                                  1, 1, mock.MagicMock(),"},{"line_number":4738,"context_line":"                                                  {}, None,"},{"line_number":4739,"context_line":"                                                  None, None, None, {}, None,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_8d749bd0","line":4736,"range":{"start_line":4736,"start_character":50,"end_line":4736,"end_character":71},"in_reply_to":"1fa4df85_a468c986","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4744,"context_line":"                \u0027test\u0027,"},{"line_number":4745,"context_line":"                mock_instance.return_value.keypairs.objects[0].name)"},{"line_number":4746,"context_line":"            self.compute_api._provision_instances(self.context,"},{"line_number":4747,"context_line":"                                                  mock.sentinel.flavor,"},{"line_number":4748,"context_line":"                                                  1, 1, mock.MagicMock(),"},{"line_number":4749,"context_line":"                                                  {}, None,"},{"line_number":4750,"context_line":"                                                  None, None, None, {}, None,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_e472417b","line":4747,"range":{"start_line":4747,"start_character":50,"end_line":4747,"end_character":70},"updated":"2020-03-04 09:31:50.000000000","message":"pass the result of self._create_flavor() here","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4744,"context_line":"                \u0027test\u0027,"},{"line_number":4745,"context_line":"                mock_instance.return_value.keypairs.objects[0].name)"},{"line_number":4746,"context_line":"            self.compute_api._provision_instances(self.context,"},{"line_number":4747,"context_line":"                                                  mock.sentinel.flavor,"},{"line_number":4748,"context_line":"                                                  1, 1, mock.MagicMock(),"},{"line_number":4749,"context_line":"                                                  {}, None,"},{"line_number":4750,"context_line":"                                                  None, None, None, {}, None,"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_2d7fa7ab","line":4747,"range":{"start_line":4747,"start_character":50,"end_line":4747,"end_character":70},"in_reply_to":"1fa4df85_e472417b","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4771,"context_line":"            mock_check_num_inst_quota.return_value \u003d 2"},{"line_number":4772,"context_line":"            fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4773,"context_line":"            fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4774,"context_line":"            mock_req_spec_from_components.return_value \u003d fake_rs"},{"line_number":4775,"context_line":""},{"line_number":4776,"context_line":"            ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":4777,"context_line":"            flavor \u003d self._create_flavor()"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_84bd8d03","line":4774,"updated":"2020-03-04 09:31:50.000000000","message":"you don\u0027t need this","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4771,"context_line":"            mock_check_num_inst_quota.return_value \u003d 2"},{"line_number":4772,"context_line":"            fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4773,"context_line":"            fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4774,"context_line":"            mock_req_spec_from_components.return_value \u003d fake_rs"},{"line_number":4775,"context_line":""},{"line_number":4776,"context_line":"            ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":4777,"context_line":"            flavor \u003d self._create_flavor()"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_2a57aecc","line":4774,"in_reply_to":"1fa4df85_84bd8d03","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4860,"context_line":"            inst_mapping_mock \u003d mock.MagicMock()"},{"line_number":4861,"context_line":"            fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4862,"context_line":"            fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4863,"context_line":"            mock_rs.return_value \u003d fake_rs"},{"line_number":4864,"context_line":""},{"line_number":4865,"context_line":"            mock_check_num_inst_quota.return_value \u003d 1"},{"line_number":4866,"context_line":"            mock_inst_mapping.return_value \u003d inst_mapping_mock"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_a4ba0907","line":4863,"updated":"2020-03-04 09:31:50.000000000","message":"ditto","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4860,"context_line":"            inst_mapping_mock \u003d mock.MagicMock()"},{"line_number":4861,"context_line":"            fake_rs \u003d fake_request_spec.fake_spec_obj()"},{"line_number":4862,"context_line":"            fake_rs.flavor.extra_specs \u003d {}"},{"line_number":4863,"context_line":"            mock_rs.return_value \u003d fake_rs"},{"line_number":4864,"context_line":""},{"line_number":4865,"context_line":"            mock_check_num_inst_quota.return_value \u003d 1"},{"line_number":4866,"context_line":"            mock_inst_mapping.return_value \u003d inst_mapping_mock"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_cda05345","line":4863,"in_reply_to":"1fa4df85_a4ba0907","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":4965,"context_line":"            flavor \u003d self._create_flavor(extra_specs\u003d{})"},{"line_number":4966,"context_line":"            req_spec_mock \u003d mock.MagicMock()"},{"line_number":4967,"context_line":"            req_spec_mock.flavor \u003d flavor"},{"line_number":4968,"context_line":"            mock_req_spec_from_components.return_value \u003d req_spec_mock"},{"line_number":4969,"context_line":"            boot_meta \u003d {"},{"line_number":4970,"context_line":"                \u0027id\u0027: \u0027fake-image-id\u0027,"},{"line_number":4971,"context_line":"                \u0027properties\u0027: {\u0027mappings\u0027: []},"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_643e518d","line":4968,"updated":"2020-03-04 09:31:50.000000000","message":"ditto","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":4965,"context_line":"            flavor \u003d self._create_flavor(extra_specs\u003d{})"},{"line_number":4966,"context_line":"            req_spec_mock \u003d mock.MagicMock()"},{"line_number":4967,"context_line":"            req_spec_mock.flavor \u003d flavor"},{"line_number":4968,"context_line":"            mock_req_spec_from_components.return_value \u003d req_spec_mock"},{"line_number":4969,"context_line":"            boot_meta \u003d {"},{"line_number":4970,"context_line":"                \u0027id\u0027: \u0027fake-image-id\u0027,"},{"line_number":4971,"context_line":"                \u0027properties\u0027: {\u0027mappings\u0027: []},"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_6d06ff54","line":4968,"in_reply_to":"1fa4df85_643e518d","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"94a8da77c56ea6a397f9431d24c4dcf095981bc6","unresolved":false,"context_lines":[{"line_number":5045,"context_line":"        def test(mock_objects, mock_secgroup, mock_cniq):"},{"line_number":5046,"context_line":"            ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":5047,"context_line":"            mock_cniq.return_value \u003d 1"},{"line_number":5048,"context_line":"            self.compute_api._provision_instances(ctxt, None, None, None,"},{"line_number":5049,"context_line":"                                                  mock.MagicMock(), None, None,"},{"line_number":5050,"context_line":"                                                  [], None, None, None, None,"},{"line_number":5051,"context_line":"                                                  None, objects.TagList(),"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_446235b0","line":5048,"range":{"start_line":5048,"start_character":56,"end_line":5048,"end_character":60},"updated":"2020-03-04 09:31:50.000000000","message":"pass the result of self._create_flavor() here","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"0a47b1191febf7c44ef1efd7f4972dc156a18a6e","unresolved":false,"context_lines":[{"line_number":5045,"context_line":"        def test(mock_objects, mock_secgroup, mock_cniq):"},{"line_number":5046,"context_line":"            ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":5047,"context_line":"            mock_cniq.return_value \u003d 1"},{"line_number":5048,"context_line":"            self.compute_api._provision_instances(ctxt, None, None, None,"},{"line_number":5049,"context_line":"                                                  mock.MagicMock(), None, None,"},{"line_number":5050,"context_line":"                                                  [], None, None, None, None,"},{"line_number":5051,"context_line":"                                                  None, objects.TagList(),"}],"source_content_type":"text/x-python","patch_set":60,"id":"1fa4df85_2de327a6","line":5048,"range":{"start_line":5048,"start_character":56,"end_line":5048,"end_character":60},"in_reply_to":"1fa4df85_446235b0","updated":"2020-03-08 23:24:21.000000000","message":"Done","commit_id":"41efb22ba660b2578f842cb543336f8c1d38a89f"}],"nova/tests/unit/fake_flavor.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"82dfc13a52aced144b865fda02d972dff75d0363","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def fake_flavor_obj(context, **updates):"},{"line_number":53,"context_line":"    expected_attrs \u003d updates.pop(\u0027expected_attrs\u0027, None)"},{"line_number":54,"context_line":"    return objects.Flavor._from_db_object(context,"},{"line_number":55,"context_line":"               objects.Flavor(), fake_db_flavor(**updates),"},{"line_number":56,"context_line":"               expected_attrs\u003dexpected_attrs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"9fdfeff1_37843c5e","side":"PARENT","line":53,"range":{"start_line":53,"start_character":51,"end_line":53,"end_character":55},"updated":"2019-02-08 23:03:43.000000000","message":"s/None/[\u0027extra_specs\u0027]/ to fix your unit test failure. This is what happens in real life, so it\u0027s a legit change.","commit_id":"28201d22bd396f6fa4a0c66c82775aebb48991e5"}],"nova/tests/unit/scheduler/test_device_profile.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f8a848d947123dac9b422e3f80a2646bbbe10fb1","unresolved":false,"context_lines":[{"line_number":30,"context_line":"        rr \u003d utils.ResourceRequest()"},{"line_number":31,"context_line":"        prev_rr \u003d rr"},{"line_number":32,"context_line":"        rr.add_request_groups_from_device_profile(spec_obj)"},{"line_number":33,"context_line":"        self.assertEqual(prev_rr, rr)  # Compare by identity"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_b9d06855","line":33,"range":{"start_line":33,"start_character":52,"end_line":33,"end_character":60},"updated":"2019-02-05 17:00:17.000000000","message":"assertIs would be comparing by identity. This will use __eq__.","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"03c147298483c9f8f4fed61b1437976c90e097fe","unresolved":false,"context_lines":[{"line_number":30,"context_line":"        rr \u003d utils.ResourceRequest()"},{"line_number":31,"context_line":"        prev_rr \u003d rr"},{"line_number":32,"context_line":"        rr.add_request_groups_from_device_profile(spec_obj)"},{"line_number":33,"context_line":"        self.assertEqual(prev_rr, rr)  # Compare by identity"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_eb44b61d","line":33,"range":{"start_line":33,"start_character":52,"end_line":33,"end_character":60},"in_reply_to":"9fdfeff1_b9d06855","updated":"2019-02-07 06:06:36.000000000","message":"Done","commit_id":"da77815ed27edd01705f612e9cdb12e14a38f082"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3cf3a5480f593be99c41a1eabed164633f63908a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2014 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":27,"id":"7faddb67_103d53dc","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"updated":"2019-07-31 17:50:26.000000000","message":"You should remove this.","commit_id":"d75b9fc02fc7c76e220d725cf7404cce172b50d8"},{"author":{"_account_id":21672,"name":"Sundar Nadathur","email":"sundar.nadathur@intel.com","username":"nsundar"},"change_message_id":"8b262d5816d840f158aea61b69a588ed6654b30d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2014 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":27,"id":"7faddb67_8f0599c4","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"in_reply_to":"7faddb67_103d53dc","updated":"2019-08-01 04:24:22.000000000","message":"Done","commit_id":"d75b9fc02fc7c76e220d725cf7404cce172b50d8"}]}
