)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"32e80b6b4f8ec7d1a0619dcdc49242778f2bd59e","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add sync traits command for placement"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add \u0027placement-manage traits sync\u0027 command to update os-traits"},{"line_number":10,"context_line":"library to database. Default behavior is to only insert newly"},{"line_number":11,"context_line":"added traits, if \u0027--force\u0027 is used, any trait not listed in"},{"line_number":12,"context_line":"os-traits library will be removed from database."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Partially-Implements: blueprint resource-provider-traits"},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"bff0334d_8a333362","line":12,"range":{"start_line":10,"start_character":0,"end_line":12,"end_character":48},"updated":"2017-04-12 09:02:49.000000000","message":"According to Alex\u0027s comment about force parameter, it seems the description here is misleading","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add sync traits command for placement"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add \u0027placement-manage traits sync\u0027 command to update os-traits"},{"line_number":10,"context_line":"library to database. Default behavior is to only insert newly"},{"line_number":11,"context_line":"added traits, if \u0027--force\u0027 is used, any trait not listed in"},{"line_number":12,"context_line":"os-traits library will be removed from database."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Partially-Implements: blueprint resource-provider-traits"},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9ff52f3f_7a6c0636","line":12,"range":{"start_line":10,"start_character":0,"end_line":12,"end_character":48},"in_reply_to":"bff0334d_8a333362","updated":"2017-04-13 14:42:49.000000000","message":"Yeah, I\u0027ll update description also","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"}],"nova/cmd/placement_manage.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"af032a65d1f6679bf4042b2d188265a4adf48d89","unresolved":false,"context_lines":[{"line_number":37,"context_line":"class TraitCommands(object):"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    @args(\u0027--force\u0027, dest\u003d\u0027force\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":40,"context_line":"          help\u003d\"Don\u0027t prompt (answer \u0027y\u0027)\")"},{"line_number":41,"context_line":"    def sync(self, force\u003dFalse):"},{"line_number":42,"context_line":"        \"\"\"Sync os-traits library to database\"\"\""},{"line_number":43,"context_line":"        ctxt \u003d context.get_admin_context()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7ffa3b31_b8af2293","line":40,"range":{"start_line":40,"start_character":16,"end_line":40,"end_character":41},"updated":"2017-04-17 05:56:17.000000000","message":"You need a better help text at here","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"da6aec19d9cac09d1709713e6c00383659e95e0a","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \"\"\"Sync os-traits library to database\"\"\""},{"line_number":43,"context_line":"        ctxt \u003d context.get_admin_context()"},{"line_number":44,"context_line":"        trait_mapping \u003d {trait.name: trait.id"},{"line_number":45,"context_line":"                         for trait in TraitList.get_all(ctxt).objects}"},{"line_number":46,"context_line":"        db_trait_names \u003d set(trait_mapping.keys())"},{"line_number":47,"context_line":"        os_trait_names \u003d set(os_traits.get_traits())"},{"line_number":48,"context_line":"        insert_traits \u003d os_trait_names.difference(db_trait_names)"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_70f7c38c","line":45,"range":{"start_line":45,"start_character":38,"end_line":45,"end_character":69},"updated":"2017-04-12 07:00:39.000000000","message":"It is enough for just writing \u0027TraitList.get_all(ctxt)\u0027","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \"\"\"Sync os-traits library to database\"\"\""},{"line_number":43,"context_line":"        ctxt \u003d context.get_admin_context()"},{"line_number":44,"context_line":"        trait_mapping \u003d {trait.name: trait.id"},{"line_number":45,"context_line":"                         for trait in TraitList.get_all(ctxt).objects}"},{"line_number":46,"context_line":"        db_trait_names \u003d set(trait_mapping.keys())"},{"line_number":47,"context_line":"        os_trait_names \u003d set(os_traits.get_traits())"},{"line_number":48,"context_line":"        insert_traits \u003d os_trait_names.difference(db_trait_names)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_8ebd636a","line":45,"range":{"start_line":45,"start_character":38,"end_line":45,"end_character":69},"in_reply_to":"bff0334d_70f7c38c","updated":"2017-04-13 14:42:49.000000000","message":"Done","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"da6aec19d9cac09d1709713e6c00383659e95e0a","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        if insert_traits:"},{"line_number":51,"context_line":"            self._add_traits(ctxt, insert_traits)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        # remove traits from database when force flag is set"},{"line_number":54,"context_line":"        if force:"},{"line_number":55,"context_line":"            delete_traits \u003d db_trait_names.difference(os_trait_names)"},{"line_number":56,"context_line":"            if delete_traits:"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_6b48f82b","line":53,"range":{"start_line":53,"start_character":8,"end_line":53,"end_character":60},"updated":"2017-04-12 07:00:39.000000000","message":"The meaning of force flag is strange.\n\nWhen force\u003dFalse, we can remove the traits which aren\u0027t associated with any resource provider. And warning to the user about the traits which associated with resource provider not removed.\n\nWhen force\u003dTrue, we can remove all the traits, whatever the traits are associated with RP or not.","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        if insert_traits:"},{"line_number":51,"context_line":"            self._add_traits(ctxt, insert_traits)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        # remove traits from database when force flag is set"},{"line_number":54,"context_line":"        if force:"},{"line_number":55,"context_line":"            delete_traits \u003d db_trait_names.difference(os_trait_names)"},{"line_number":56,"context_line":"            if delete_traits:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_a6e15ed3","line":53,"range":{"start_line":53,"start_character":8,"end_line":53,"end_character":60},"in_reply_to":"bff0334d_6b48f82b","updated":"2017-04-13 14:42:49.000000000","message":"Yep, current behavior here is strange.","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"da6aec19d9cac09d1709713e6c00383659e95e0a","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        # remove traits from database when force flag is set"},{"line_number":54,"context_line":"        if force:"},{"line_number":55,"context_line":"            delete_traits \u003d db_trait_names.difference(os_trait_names)"},{"line_number":56,"context_line":"            if delete_traits:"},{"line_number":57,"context_line":"                print(\"The following traits will be removed from database: \""},{"line_number":58,"context_line":"                        \"%(traits)s\" % {\u0027traits\u0027: \u0027, \u0027.join(delete_traits)})"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_0b63acb3","line":55,"range":{"start_line":55,"start_character":12,"end_line":55,"end_character":69},"updated":"2017-04-12 07:00:39.000000000","message":"This will delete the custom trait?","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"32e80b6b4f8ec7d1a0619dcdc49242778f2bd59e","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        # remove traits from database when force flag is set"},{"line_number":54,"context_line":"        if force:"},{"line_number":55,"context_line":"            delete_traits \u003d db_trait_names.difference(os_trait_names)"},{"line_number":56,"context_line":"            if delete_traits:"},{"line_number":57,"context_line":"                print(\"The following traits will be removed from database: \""},{"line_number":58,"context_line":"                        \"%(traits)s\" % {\u0027traits\u0027: \u0027, \u0027.join(delete_traits)})"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_ea6f5f25","line":55,"range":{"start_line":55,"start_character":12,"end_line":55,"end_character":69},"in_reply_to":"bff0334d_0b63acb3","updated":"2017-04-12 09:02:49.000000000","message":"+1, we should keep custom traits","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        # remove traits from database when force flag is set"},{"line_number":54,"context_line":"        if force:"},{"line_number":55,"context_line":"            delete_traits \u003d db_trait_names.difference(os_trait_names)"},{"line_number":56,"context_line":"            if delete_traits:"},{"line_number":57,"context_line":"                print(\"The following traits will be removed from database: \""},{"line_number":58,"context_line":"                        \"%(traits)s\" % {\u0027traits\u0027: \u0027, \u0027.join(delete_traits)})"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_4eb75b88","line":55,"range":{"start_line":55,"start_character":12,"end_line":55,"end_character":69},"in_reply_to":"bff0334d_0b63acb3","updated":"2017-04-13 14:42:49.000000000","message":"Done","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"da6aec19d9cac09d1709713e6c00383659e95e0a","unresolved":false,"context_lines":[{"line_number":69,"context_line":"                trait.name \u003d trait_name"},{"line_number":70,"context_line":"                trait.create()"},{"line_number":71,"context_line":"                traits.append(trait)"},{"line_number":72,"context_line":"            except Exception as e:"},{"line_number":73,"context_line":"                print(\"Failed to add trait %(trait)s: %(e)s\" %"},{"line_number":74,"context_line":"                    {\u0027trait\u0027: trait_name, \u0027e\u0027: e})"},{"line_number":75,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_10cab719","line":72,"range":{"start_line":72,"start_character":12,"end_line":72,"end_character":34},"updated":"2017-04-12 07:00:39.000000000","message":"How about handle the \u0027DBDuplicated\u0027 first, then continue when there is duplicated item in the db. And return fault for other unexpected exception.","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":69,"context_line":"                trait.name \u003d trait_name"},{"line_number":70,"context_line":"                trait.create()"},{"line_number":71,"context_line":"                traits.append(trait)"},{"line_number":72,"context_line":"            except Exception as e:"},{"line_number":73,"context_line":"                print(\"Failed to add trait %(trait)s: %(e)s\" %"},{"line_number":74,"context_line":"                    {\u0027trait\u0027: trait_name, \u0027e\u0027: e})"},{"line_number":75,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_1aff3aab","line":72,"in_reply_to":"9ff52f3f_d7d1b259","updated":"2017-04-13 14:42:49.000000000","message":"The more likely exceptions here are related to database failure I think, I\u0027m now leaning towards exiting and logging the exception. What do you think?","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":16150,"name":"Lei Zhang","email":"lei.a.zhang@intel.com","username":"leizhang"},"change_message_id":"cfba76f659eccf6e950304f2b9c2a6091d227a78","unresolved":false,"context_lines":[{"line_number":69,"context_line":"                trait.name \u003d trait_name"},{"line_number":70,"context_line":"                trait.create()"},{"line_number":71,"context_line":"                traits.append(trait)"},{"line_number":72,"context_line":"            except Exception as e:"},{"line_number":73,"context_line":"                print(\"Failed to add trait %(trait)s: %(e)s\" %"},{"line_number":74,"context_line":"                    {\u0027trait\u0027: trait_name, \u0027e\u0027: e})"},{"line_number":75,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_a61efe6d","line":72,"range":{"start_line":72,"start_character":12,"end_line":72,"end_character":34},"in_reply_to":"bff0334d_10cab719","updated":"2017-04-13 14:42:49.000000000","message":"Unless administrators are executing the command at same time, I cannot find other cases \u0027DBDuplicated\u0027 could happen, but I guess there\u0027s no harm to catch it.","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"b267f8a9784cbf0a1108c9d1e30b9c3b539939ce","unresolved":false,"context_lines":[{"line_number":69,"context_line":"                trait.name \u003d trait_name"},{"line_number":70,"context_line":"                trait.create()"},{"line_number":71,"context_line":"                traits.append(trait)"},{"line_number":72,"context_line":"            except Exception as e:"},{"line_number":73,"context_line":"                print(\"Failed to add trait %(trait)s: %(e)s\" %"},{"line_number":74,"context_line":"                    {\u0027trait\u0027: trait_name, \u0027e\u0027: e})"},{"line_number":75,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ff52f3f_d7d1b259","line":72,"in_reply_to":"bff0334d_10cab719","updated":"2017-04-13 11:44:55.000000000","message":"Yes, please catch explicit exceptions that you expect first, not the generic catch all.\n\nShould we let catastrophic exceptions rise and cause the tool to exit, or must we catch them in the loop? I\u0027m not sure which is better.","commit_id":"c1b8882f0534dd7b1e6108212f8dc0beb4420a71"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4c654abc1ac26b64ec00d49199f82590dd5d2879","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        delete_traits \u003d list(filter("},{"line_number":59,"context_line":"            lambda t: not t.startswith(Trait.CUSTOM_NAMESPACE), diff_traits))"},{"line_number":60,"context_line":"        if delete_traits:"},{"line_number":61,"context_line":"            delete_trait_id \u003d ["},{"line_number":62,"context_line":"                trait_mapping[name] for name in delete_traits]"},{"line_number":63,"context_line":"            associated_trait_id \u003d self._get_associated_traits("},{"line_number":64,"context_line":"                ctxt, delete_trait_id)"},{"line_number":65,"context_line":"            if associated_trait_id and force:"}],"source_content_type":"text/x-python","patch_set":8,"id":"5ff73747_779d6708","line":62,"range":{"start_line":61,"start_character":0,"end_line":62,"end_character":62},"updated":"2017-05-01 21:45:10.000000000","message":"nit: cleaner formatting for list comprehensions:\n\n            delete_trait_id \u003d [trait_mapping[name]\n                               for name in delete_traits]","commit_id":"8613d42545983b5ceaa0530c2dd2cd099059fe8b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4c654abc1ac26b64ec00d49199f82590dd5d2879","unresolved":false,"context_lines":[{"line_number":70,"context_line":"                    associated_trait_id)"},{"line_number":71,"context_line":"                print(\"Traits associated with resource providers \""},{"line_number":72,"context_line":"                      \"won\u0027t be deleted, specify --force to remove \""},{"line_number":73,"context_line":"                       \"associated traits.\""},{"line_number":74,"context_line":"                )"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"            self._delete_traits(ctxt, delete_trait_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"5ff73747_178623ba","line":73,"range":{"start_line":73,"start_character":22,"end_line":73,"end_character":23},"updated":"2017-05-01 21:45:10.000000000","message":"nit: whitespace mis-alignment","commit_id":"8613d42545983b5ceaa0530c2dd2cd099059fe8b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4c654abc1ac26b64ec00d49199f82590dd5d2879","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                print(\"Failed to add duplicated trait %(trait)s: %(e)s\" %"},{"line_number":88,"context_line":"                    {\u0027trait\u0027: trait_name, \u0027e\u0027: e})"},{"line_number":89,"context_line":"                continue"},{"line_number":90,"context_line":"        return traits"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    @staticmethod"},{"line_number":93,"context_line":"    @db_api.api_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":8,"id":"5ff73747_97c353ed","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":21},"updated":"2017-05-01 21:45:10.000000000","message":"This value isn\u0027t used anywhere that I can see.","commit_id":"8613d42545983b5ceaa0530c2dd2cd099059fe8b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4c654abc1ac26b64ec00d49199f82590dd5d2879","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        # remove rows from both trait and association table"},{"line_number":96,"context_line":"        context.session.query(models.ResourceProviderTrait).filter("},{"line_number":97,"context_line":"            models.ResourceProviderTrait.trait_id.in_(trait_ids)"},{"line_number":98,"context_line":"        ).delete(synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":99,"context_line":"        context.session.query(models.Trait).filter("},{"line_number":100,"context_line":"            models.Trait.id.in_(trait_ids)).delete("},{"line_number":101,"context_line":"                synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":102,"context_line":"        return context.session"}],"source_content_type":"text/x-python","patch_set":8,"id":"5ff73747_17af432a","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":9},"updated":"2017-05-01 21:45:10.000000000","message":"I know that this is technically legal Python, but it hurts my eyes to see two lines at different semantic levels indented to the same level.","commit_id":"8613d42545983b5ceaa0530c2dd2cd099059fe8b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4c654abc1ac26b64ec00d49199f82590dd5d2879","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":106,"context_line":"    def _get_associated_traits(context, trait_ids):"},{"line_number":107,"context_line":"        res \u003d context.session.query("},{"line_number":108,"context_line":"            models.ResourceProviderTrait.trait_id).\\"},{"line_number":109,"context_line":"            filter(models.ResourceProviderTrait.trait_id.in_(trait_ids)).all()"},{"line_number":110,"context_line":"        return [row[0] for row in res]"},{"line_number":111,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"5ff73747_d779dbc4","line":108,"range":{"start_line":108,"start_character":51,"end_line":108,"end_character":52},"updated":"2017-05-01 21:45:10.000000000","message":"You are inside parentheses, so this continuation character is not needed.","commit_id":"8613d42545983b5ceaa0530c2dd2cd099059fe8b"}]}
