)]}'
{"zun/api/controllers/v1/containers.py":[{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"8dddc5fe95a40d521d01207d83ec1572dc2eb522","unresolved":false,"context_lines":[{"line_number":436,"context_line":"    def _check_container_quotas(self, context, container_delta_dict,"},{"line_number":437,"context_line":"                                update_container\u003dFalse):"},{"line_number":438,"context_line":"        deltas \u003d {"},{"line_number":439,"context_line":"            \u0027containers\u0027: 0 if update_container else 0,"},{"line_number":440,"context_line":"            \u0027cpu\u0027: container_delta_dict.get(\u0027cpu\u0027, 0),"},{"line_number":441,"context_line":"            \u0027memory\u0027: container_delta_dict.get(\u0027memory\u0027, 0),"},{"line_number":442,"context_line":"            \u0027disk\u0027: container_delta_dict.get(\u0027disk\u0027, 0)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_271aa4c5","line":439,"range":{"start_line":439,"start_character":53,"end_line":439,"end_character":54},"updated":"2018-09-04 02:06:27.000000000","message":"I guess it is 1?","commit_id":"c639f49789943fb5400eef7c6f3a61f9e2b5e02e"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"8dddc5fe95a40d521d01207d83ec1572dc2eb522","unresolved":false,"context_lines":[{"line_number":465,"context_line":"                    if isinstance(count_as_dict[res_name], six.integer_types):"},{"line_number":466,"context_line":"                        total \u003d count_as_dict[res_name] + int(res_delta)"},{"line_number":467,"context_line":"                    else:"},{"line_number":468,"context_line":"                        total \u003d float(count_as_dict[res_name]) + res_delta"},{"line_number":469,"context_line":"                except TypeError as e:"},{"line_number":470,"context_line":"                    raise e"},{"line_number":471,"context_line":"                check_kwargs[res_name] \u003d total"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_c762d016","line":468,"range":{"start_line":468,"start_character":65,"end_line":468,"end_character":74},"updated":"2018-09-04 02:06:27.000000000","message":"The gate complained about this. The \u0027res_delta\u0027 is a unicode so we need to cast it to float before the addition.","commit_id":"c639f49789943fb5400eef7c6f3a61f9e2b5e02e"}],"zun/api/controllers/v1/quota_classes.py":[{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"cbbc6947d88b784c1133149395dca66e1946540c","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":33,"context_line":"    @exception.wrap_pecan_controller_exception"},{"line_number":34,"context_line":"    @validation.validate_query_param(pecan.request, schema.query_param_update)"},{"line_number":35,"context_line":"    def put(self, quota_class_name, **quota_classes_dict):"},{"line_number":36,"context_line":"        context \u003d pecan.request.context"},{"line_number":37,"context_line":"        policy.enforce(context, \u0027quota_class:update\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_e238fdee","line":34,"range":{"start_line":34,"start_character":16,"end_line":34,"end_character":36},"updated":"2018-08-11 23:29:43.000000000","message":"This catches the case that the data is provided in query string (i.e. http://url/?containers\u003d100) but it doesn\u0027t catch the case that the data is provided by request\u0027s body (i.e. {\u0027containers\u0027: 100}). Need to add the following as well:\n\n  @validation.validated(schema.query_param_update)","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"cbbc6947d88b784c1133149395dca66e1946540c","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":51,"context_line":"    @exception.wrap_pecan_controller_exception"},{"line_number":52,"context_line":"    def get(self, quota_class_name):"},{"line_number":53,"context_line":"        context \u003d pecan.request.context"},{"line_number":54,"context_line":"        policy.enforce(context, \u0027quota_class:get\u0027,"},{"line_number":55,"context_line":"                       action\u003d\u0027quota_class:get\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_82a7c9a7","line":52,"range":{"start_line":52,"start_character":8,"end_line":52,"end_character":11},"updated":"2018-08-11 23:29:43.000000000","message":"I tested this API and it looks there are some inconsistencies with nova. In particular, here is nova\u0027s output:\n\n  {\"metadata_items\": 128, \"server_groups\": 10, \"server_group_members\": 10, \"ram\": 51200, \"key_pairs\": 100, \"instances\": 10, \"cores\": 20, \"id\": \"test\"}\n\nHere is zun\u0027s output:\n\n  {\"disk\": 100, \"cpu\": 20, \"containers\": 10, \"memory\": 51200}\n\nThe inconsistencies I want to address are:\n\n* nova is using the name \"cores\" while zun is using \"cpu\"\n* nova is using the name \"ram\" while zun is using \"memory\"\n* nova has the key \"id\" while zun doesn\u0027t.","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"}],"zun/api/controllers/v1/quotas.py":[{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"9a9353f8a27995468de2afb3b8d40a5f5f5c652d","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":43,"context_line":"    @exception.wrap_pecan_controller_exception"},{"line_number":44,"context_line":"    @validation.validate_query_param(pecan.request, schema.query_param_update)"},{"line_number":45,"context_line":"    def put(self, **quotas_dict):"},{"line_number":46,"context_line":"        context \u003d pecan.request.context"},{"line_number":47,"context_line":"        policy.enforce(context, \u0027quota:update\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_513dfada","line":44,"range":{"start_line":44,"start_character":16,"end_line":44,"end_character":36},"updated":"2018-08-12 20:06:29.000000000","message":"Ditto. This validate parameters provided by query string, but couldn\u0027t validate parameters provided in request\u0027s body.","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"}],"zun/compute/api.py":[{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"82173c9c100d189b182144382897ac0334c83710","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        project_id \u003d context.project_id"},{"line_number":52,"context_line":"        deltas \u003d {"},{"line_number":53,"context_line":"            \u0027containers\u0027: 1,"},{"line_number":54,"context_line":"            \u0027cpu\u0027: container.cpu,"},{"line_number":55,"context_line":"            \u0027memory\u0027: container.memory,"},{"line_number":56,"context_line":"            \u0027disk\u0027: container.disk"},{"line_number":57,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_911ab2c9","line":54,"range":{"start_line":54,"start_character":19,"end_line":54,"end_character":32},"updated":"2018-08-12 19:09:34.000000000","message":"We need to handle the case that container.cpu is None. How about \u0027container.cpu or 0\u0027","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"82173c9c100d189b182144382897ac0334c83710","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        deltas \u003d {"},{"line_number":53,"context_line":"            \u0027containers\u0027: 1,"},{"line_number":54,"context_line":"            \u0027cpu\u0027: container.cpu,"},{"line_number":55,"context_line":"            \u0027memory\u0027: container.memory,"},{"line_number":56,"context_line":"            \u0027disk\u0027: container.disk"},{"line_number":57,"context_line":"        }"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_310b9e7d","line":55,"range":{"start_line":55,"start_character":32,"end_line":55,"end_character":38},"updated":"2018-08-12 19:09:34.000000000","message":"Ditto. We need to handle the case that container.memory is None","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"82173c9c100d189b182144382897ac0334c83710","unresolved":false,"context_lines":[{"line_number":53,"context_line":"            \u0027containers\u0027: 1,"},{"line_number":54,"context_line":"            \u0027cpu\u0027: container.cpu,"},{"line_number":55,"context_line":"            \u0027memory\u0027: container.memory,"},{"line_number":56,"context_line":"            \u0027disk\u0027: container.disk"},{"line_number":57,"context_line":"        }"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        self._check_deltas(context, project_id, deltas)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_51109aa8","line":56,"range":{"start_line":56,"start_character":30,"end_line":56,"end_character":34},"updated":"2018-08-12 19:09:34.000000000","message":"Ditto. We need to handle the case that container.disk is None","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"cbbc6947d88b784c1133149395dca66e1946540c","unresolved":false,"context_lines":[{"line_number":78,"context_line":"                                                   project_id)"},{"line_number":79,"context_line":"            if isinstance(count_as_dict[res_name], six.integer_types):"},{"line_number":80,"context_line":"                total \u003d count_as_dict[res_name] + int(res_delta)"},{"line_number":81,"context_line":"            elif isinstance(count_as_dict[res_name], float):"},{"line_number":82,"context_line":"                total \u003d count_as_dict[res_name] + float(res_delta)"},{"line_number":83,"context_line":"            check_kwargs[res_name] \u003d total"},{"line_number":84,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_48431314","line":81,"range":{"start_line":81,"start_character":12,"end_line":81,"end_character":16},"updated":"2018-08-11 23:29:43.000000000","message":"We should have a \u0027else\u0027 branch and throw exception if an unexpected type is given.","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"cbbc6947d88b784c1133149395dca66e1946540c","unresolved":false,"context_lines":[{"line_number":78,"context_line":"                                                   project_id)"},{"line_number":79,"context_line":"            if isinstance(count_as_dict[res_name], six.integer_types):"},{"line_number":80,"context_line":"                total \u003d count_as_dict[res_name] + int(res_delta)"},{"line_number":81,"context_line":"            elif isinstance(count_as_dict[res_name], float):"},{"line_number":82,"context_line":"                total \u003d count_as_dict[res_name] + float(res_delta)"},{"line_number":83,"context_line":"            check_kwargs[res_name] \u003d total"},{"line_number":84,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_883dab90","line":81,"range":{"start_line":81,"start_character":53,"end_line":81,"end_character":58},"updated":"2018-08-11 23:29:43.000000000","message":"While I tested it, the type is decimal.Decimal instead of float.","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"cbbc6947d88b784c1133149395dca66e1946540c","unresolved":false,"context_lines":[{"line_number":80,"context_line":"                total \u003d count_as_dict[res_name] + int(res_delta)"},{"line_number":81,"context_line":"            elif isinstance(count_as_dict[res_name], float):"},{"line_number":82,"context_line":"                total \u003d count_as_dict[res_name] + float(res_delta)"},{"line_number":83,"context_line":"            check_kwargs[res_name] \u003d total"},{"line_number":84,"context_line":"        try:"},{"line_number":85,"context_line":"            QUOTAS.limit_check(context, project_id, **check_kwargs)"},{"line_number":86,"context_line":"        except exception.OverQuota as exc:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_88a12bfb","line":83,"range":{"start_line":83,"start_character":37,"end_line":83,"end_character":42},"updated":"2018-08-11 23:29:43.000000000","message":"I hit this error:  UnboundLocalError: local variable \u0027total\u0027 referenced before assignment","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"9a9353f8a27995468de2afb3b8d40a5f5f5c652d","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            QUOTAS.limit_check(context, project_id, **check_kwargs)"},{"line_number":86,"context_line":"        except exception.OverQuota as exc:"},{"line_number":87,"context_line":"            # Report usage in the exception when going over quota"},{"line_number":88,"context_line":"            exc.kwargs[\u0027usages\u0027] \u003d count_as_dict"},{"line_number":89,"context_line":"            raise exc"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def container_create(self, context, new_container, extra_spec,"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_7cea4d0f","line":88,"range":{"start_line":88,"start_character":24,"end_line":88,"end_character":30},"updated":"2018-08-12 20:06:29.000000000","message":"It seems this parameter is unused? or there is a plan to use it? FWIW, here is how this parameter is used in nova: https://github.com/openstack/nova/blob/a29ace1d48b5473b9e7b5decdf3d5d19f3d262f3/nova/compute/utils.py#L955","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"82173c9c100d189b182144382897ac0334c83710","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                         requested_networks, requested_volumes, run,"},{"line_number":93,"context_line":"                         pci_requests\u003dNone):"},{"line_number":94,"context_line":"        try:"},{"line_number":95,"context_line":"            self._check_container_quotas(context, new_container)"},{"line_number":96,"context_line":"            host_state \u003d self._schedule_container(context, new_container,"},{"line_number":97,"context_line":"                                                  extra_spec)"},{"line_number":98,"context_line":"        except exception.OverQuota as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_9131525d","line":95,"range":{"start_line":95,"start_character":17,"end_line":95,"end_character":40},"updated":"2018-08-12 19:09:34.000000000","message":"There is a pitfall on this check. We need to do this check before creating \u0027new_container\u0027 in db, because this method calculates existing usage of quota by reading data from db.\n\nRight now, we do this check after the \u0027new_container\u0027 is created [1]. This will cause this method over-calculate the quota usage.\n\n[1] https://github.com/openstack/zun/blob/334f2280805ae36d99b0121778700b20d33e462c/zun/api/controllers/v1/containers.py#L408","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"},{"author":{"_account_id":11536,"name":"hongbin","email":"hongbin034@gmail.com","username":"hongbin"},"change_message_id":"82173c9c100d189b182144382897ac0334c83710","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        except exception.OverQuota as e:"},{"line_number":99,"context_line":"            new_container.status \u003d consts.ERROR"},{"line_number":100,"context_line":"            new_container.status_reason \u003d str(e)"},{"line_number":101,"context_line":"            new_container.save(context)"},{"line_number":102,"context_line":"            return"},{"line_number":103,"context_line":"        except exception.NoValidHost:"},{"line_number":104,"context_line":"            new_container.status \u003d consts.ERROR"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_51373a4e","line":101,"range":{"start_line":101,"start_character":26,"end_line":101,"end_character":30},"updated":"2018-08-12 19:09:34.000000000","message":"This will save the error and returns a 200 response, but what nova did is to raise this exception to end-users with a 403 response.\n\nPersonally, I am in flavor of the nova\u0027s approach because fail-fast is better. What do you think?","commit_id":"001f1dbad5f343f38a818e0a252dbe0cc980af14"}]}
