)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":35511,"name":"Dawud","email":"dawud@stackhpc.com","username":"dawudm"},"change_message_id":"05e3e19ad6ca90d92c78d7e1946830add4f088b0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"6d4d29b7_011c6ca4","updated":"2026-09-01 14:42:23.000000000","message":"@jlarriba@redhat.com I have created a spec for this http://storyboard.openstack.org/#!/story/2011874","commit_id":"d85c5639495821f85f91e248ea31211fa69a545f"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"989a1cfa563f3503683daa64f63afdae7bb5198e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"2862fdde_a497cc37","updated":"2026-08-31 09:45:42.000000000","message":"Hi, thank for your contribution. However, this is introducing a whole new feature into CloudKitty that might be interesting, but I would love to have the chance to discuss it as a Spec before jumping into the code.\n\nCould you please submit a spec to cloudkitty-specs explaining the feature so it can be debated?","commit_id":"d85c5639495821f85f91e248ea31211fa69a545f"},{"author":{"_account_id":35511,"name":"Dawud","email":"dawud@stackhpc.com","username":"dawudm"},"change_message_id":"ed6048425661b3111dc0c1fcbdeb403b4630a59f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4cd67972_b7f00fcb","updated":"2026-10-06 13:05:27.000000000","message":"Spec has now merged","commit_id":"d85c5639495821f85f91e248ea31211fa69a545f"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"bba222431944bd891effa294ed88804036d9e620","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"a4982878_4f95aa66","in_reply_to":"6d4d29b7_011c6ca4","updated":"2026-09-15 09:42:58.000000000","message":"Thank you, please submit it to the cloudkitty-specs repo instead of using storyboard. There is where we are reviewing specs these days.\n\n(So sorry for the delay)","commit_id":"d85c5639495821f85f91e248ea31211fa69a545f"},{"author":{"_account_id":35511,"name":"Dawud","email":"dawud@stackhpc.com","username":"dawudm"},"change_message_id":"feef1435df7dd372ef4226efa73e523f23fbb511","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1fe9f72b_6f77ea14","in_reply_to":"a4982878_4f95aa66","updated":"2026-09-22 11:18:32.000000000","message":"full spec is at https://review.opendev.org/c/openstack/cloudkitty-specs/+/1006704","commit_id":"d85c5639495821f85f91e248ea31211fa69a545f"}],"cloudkitty/cli/storage_migrate.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"4ef6caf285df3565f6b83c8dc1fd26f99500b9a5","unresolved":true,"context_lines":[{"line_number":116,"context_line":"        copied +\u003d copied_in_page"},{"line_number":117,"context_line":"        offset +\u003d copied_in_page"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        if copied \u003e\u003d frames[\u0027total\u0027]:"},{"line_number":120,"context_line":"            break"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    return copied"}],"source_content_type":"text/x-python","patch_set":2,"id":"d41e1b44_7baca3a2","line":119,"updated":"2026-10-14 08:53:18.000000000","message":"In elasticsearch and opensearch, search queries default to tracking total hits up to 10,000.\n\nIf we are migrating from ES/OS to other system and we have 50000 dataframes, frames[\u0027total\u0027] evaluates to 10000. Once 10000 are copied, copied \u003e\u003d frames[\u0027total\u0027] becomes True, and the copy loop stops prematurely, leaving 40000 dataframes behind.\n\nI think this behaviour can be overriden by using track_total_hits\u003dTrue on the ES/OS client.","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"f94888d45abc2c3ee9a8b85703a41b0e075a4b25","unresolved":true,"context_lines":[{"line_number":338,"context_line":"        page_size\u003dCONF.page_size,"},{"line_number":339,"context_line":"        overwrite_destination\u003dCONF.overwrite_destination,"},{"line_number":340,"context_line":"    )"},{"line_number":341,"context_line":"    command.run()"}],"source_content_type":"text/x-python","patch_set":2,"id":"7b14468a_baf31f69","line":341,"updated":"2026-10-14 08:35:25.000000000","message":"If this raises a StorageMigrationError, it will just plain dump a python traceback directly at the customer plus a 0 exit code.\n\nFor a CLI tool, it is much better to catch the error, print the error message without the trace and exit with sys.exit(1).","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"}],"cloudkitty/storage/v2/__init__.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":104,"context_line":"        \"\"\""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @abc.abstractmethod"},{"line_number":107,"context_line":"    def get_bounds(self):"},{"line_number":108,"context_line":"        \"\"\"Returns the global time bounds stored in the backend."},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        :rtype: dict"}],"source_content_type":"text/x-python","patch_set":2,"id":"afd3f976_90c11a96","line":107,"updated":"2026-10-14 08:31:02.000000000","message":"Having this abstract method prevents drivers without it from instantiation even during normal operations (outside of the migration operation).\n\nIn the spec, you say:\n\n\"The v2 storage interface will gain a ``get_bounds`` method. Its base\nimplementation will raise ``NotImplementedError`` so existing third-party\ndrivers remain usable outside migration.\"\n\nI would like to see that behaviour implemented","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"}],"cloudkitty/storage/v2/elasticsearch/__init__.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    def get_bounds(self):"},{"line_number":171,"context_line":"        total, docs \u003d self._conn.retrieve("},{"line_number":172,"context_line":"            None, None, None, None, paginate\u003dFalse)"},{"line_number":173,"context_line":"        if not total:"},{"line_number":174,"context_line":"            return {\u0027begin\u0027: None, \u0027end\u0027: None}"},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"452b8a44_80da1fe1","line":172,"updated":"2026-10-14 08:31:02.000000000","message":"This has the same issue as opensearch.","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"}],"cloudkitty/storage/v2/influx.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":771,"context_line":"        return self.query(query)"},{"line_number":772,"context_line":""},{"line_number":773,"context_line":"    def get_bounds(self):"},{"line_number":774,"context_line":"        query \u003d f\u0027\u0027\u0027"},{"line_number":775,"context_line":"        from(bucket:\"{CONF.storage_influxdb.bucket}\")"},{"line_number":776,"context_line":"            |\u003e filter(fn: (r) \u003d\u003e r[\"_measurement\"] \u003d\u003d \"dataframes\")"},{"line_number":777,"context_line":"            |\u003e keep(columns: [\"_time\", \"{PERIOD_FIELD_NAME}\"])"}],"source_content_type":"text/x-python","patch_set":2,"id":"be20b9f1_a7ea0a6f","line":774,"updated":"2026-10-14 08:31:02.000000000","message":"This query does not include range(), which is required by Flux.","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"fa8aed83f4b2c2907f773d79c90c969b4800c336","unresolved":false,"context_lines":[{"line_number":771,"context_line":"        return self.query(query)"},{"line_number":772,"context_line":""},{"line_number":773,"context_line":"    def get_bounds(self):"},{"line_number":774,"context_line":"        query \u003d f\u0027\u0027\u0027"},{"line_number":775,"context_line":"        from(bucket:\"{CONF.storage_influxdb.bucket}\")"},{"line_number":776,"context_line":"            |\u003e filter(fn: (r) \u003d\u003e r[\"_measurement\"] \u003d\u003d \"dataframes\")"},{"line_number":777,"context_line":"            |\u003e keep(columns: [\"_time\", \"{PERIOD_FIELD_NAME}\"])"}],"source_content_type":"text/x-python","patch_set":2,"id":"759e2e6e_a875e565","line":774,"in_reply_to":"be20b9f1_a7ea0a6f","updated":"2026-10-14 08:37:23.000000000","message":"This was more related to issues solved by other patches pending review.","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":777,"context_line":"            |\u003e keep(columns: [\"_time\", \"{PERIOD_FIELD_NAME}\"])"},{"line_number":778,"context_line":"            |\u003e sort(columns: [\"_time\"])"},{"line_number":779,"context_line":"        \u0027\u0027\u0027"},{"line_number":780,"context_line":"        response \u003d self.query(query)"},{"line_number":781,"context_line":"        if not response:"},{"line_number":782,"context_line":"            return {\u0027begin\u0027: None, \u0027end\u0027: None}"},{"line_number":783,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"05058b6a_0e29a4ed","line":780,"updated":"2026-10-14 08:31:02.000000000","message":"This has the same issue as the opensearch/elasticsearch queries: it is downloading all influxdb data to memory before starting to migrate, which will have issues with big datasets.\n\nSurprisingly, the influxdb v1 implementation takes this in account with the LIMIT 1. This should have something similar (on the likes of |\u003e limit(n: 1), im not a Flux expert).","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":884,"context_line":"        }"},{"line_number":885,"context_line":""},{"line_number":886,"context_line":"    def delete(self, begin\u003dNone, end\u003dNone, filters\u003dNone):"},{"line_number":887,"context_line":"        begin \u003d tzutils.local_to_utc(begin) if begin else None"},{"line_number":888,"context_line":"        end \u003d tzutils.local_to_utc(end) if end else None"},{"line_number":889,"context_line":"        self._conn.delete(begin, end, filters)"},{"line_number":890,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3f769b25_0d3cda30","line":887,"updated":"2026-10-14 08:31:02.000000000","message":"You are silently here introducing the local to utc conversion to an existing v2 API method. This changes current behaviour without notifying anyone nor going through any kind of deprecation process.","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"}],"cloudkitty/storage/v2/opensearch/__init__.py":[{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"095fb257c9f3e1a1fe032ccef0ea6f8ce1962d56","unresolved":true,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def get_bounds(self):"},{"line_number":170,"context_line":"        total, docs \u003d self._conn.retrieve("},{"line_number":171,"context_line":"            None, None, None, None, paginate\u003dFalse)"},{"line_number":172,"context_line":"        if not total:"},{"line_number":173,"context_line":"            return {\u0027begin\u0027: None, \u0027end\u0027: None}"},{"line_number":174,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"f80dc015_73d02eda","line":171,"updated":"2026-10-14 08:31:02.000000000","message":"Setting paginate to false implies that this query is downloading everything between start and end to the system\u0027s memory. This could be potentially millions of records in a big system, which would kill the migration process.\n\nCould you use pagination here so migration can happen regardless of the amount of data that needs to be migrated?","commit_id":"bd40456a4df9907e5e7e6fa49e6b8133205521f9"}]}
