)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Matthew Allen \u003cmaallen@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-06-03 17:06:53 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"account: Quarantine truncated DBs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"While exercising the account-auditor in a SAIO, we observed that"},{"line_number":10,"context_line":"manually truncating an account database did not cause it to be"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"6962d0c3_11d7bc7b","line":7,"updated":"2026-06-04 18:49:24.000000000","message":"does it tho?\n\nhttps://review.opendev.org/c/openstack/swift/+/991709/1/test/unit/account/test_auditor.py#155","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"32b3fa15f4261f31c95a4bace7b18bdc7bafd343","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Matthew Allen \u003cmaallen@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-06-03 17:06:53 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"account: Quarantine truncated DBs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"While exercising the account-auditor in a SAIO, we observed that"},{"line_number":10,"context_line":"manually truncating an account database did not cause it to be"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"dd545874_fb6ea8fd","line":7,"in_reply_to":"6962d0c3_11d7bc7b","updated":"2026-06-26 00:01:13.000000000","message":"It fact, it does not. I\u0027ll add a test/tests that actually do quarantine the DB (as you suggested) and proceed from there.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Matthew Allen \u003cmaallen@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-06-03 17:06:53 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"account: Quarantine truncated DBs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"While exercising the account-auditor in a SAIO, we observed that"},{"line_number":10,"context_line":"manually truncating an account database did not cause it to be"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"8f8a0d1e_9514fd5b","line":7,"in_reply_to":"dd545874_fb6ea8fd","updated":"2026-06-28 00:17:06.000000000","message":"Done","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":true,"context_lines":[{"line_number":28,"context_line":"This intentionally narrows the quarantine trigger to a definitively-"},{"line_number":29,"context_line":"missing row rather than broadening the OperationalError catch, which"},{"line_number":30,"context_line":"would risk spurious quarantines on transient SQLITE_BUSY or"},{"line_number":31,"context_line":"pre-migration \"no such column\" errors."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"Change-Id: I35b689717c01b1649e9205f67d46958d3d5c16d2"},{"line_number":34,"context_line":"Signed-off-by: Matthew Allen \u003cmaallen@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0fb7072d_54cd81e3","line":31,"updated":"2026-06-04 18:49:24.000000000","message":"I think that\u0027s a reasonable justification, but possibly still to narrow - maybe we could add some kind of \"is this even a sqlite database?\" fallback verification to the OperationalError somehow.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":28,"context_line":"This intentionally narrows the quarantine trigger to a definitively-"},{"line_number":29,"context_line":"missing row rather than broadening the OperationalError catch, which"},{"line_number":30,"context_line":"would risk spurious quarantines on transient SQLITE_BUSY or"},{"line_number":31,"context_line":"pre-migration \"no such column\" errors."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"Change-Id: I35b689717c01b1649e9205f67d46958d3d5c16d2"},{"line_number":34,"context_line":"Signed-off-by: Matthew Allen \u003cmaallen@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fb8dc68e_033ca716","line":31,"in_reply_to":"0fb7072d_54cd81e3","updated":"2026-06-28 00:17:06.000000000","message":"Done","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":true,"context_lines":[{"line_number":28,"context_line":"This intentionally narrows the quarantine trigger to a definitively-"},{"line_number":29,"context_line":"missing row rather than broadening the OperationalError catch, which"},{"line_number":30,"context_line":"would risk spurious quarantines on transient SQLITE_BUSY or"},{"line_number":31,"context_line":"pre-migration \"no such column\" errors."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"Change-Id: I35b689717c01b1649e9205f67d46958d3d5c16d2"},{"line_number":34,"context_line":"Signed-off-by: Matthew Allen \u003cmaallen@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"835346bd_5c86360c","line":31,"in_reply_to":"fb8dc68e_033ca716","updated":"2026-09-17 16:01:34.000000000","message":"Plan to address in a subsequent patch to flesh out the auditor.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":46,"context_line":"sites."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"The auditor sees the resulting sqlite3.DatabaseError and the truncated"},{"line_number":49,"context_line":"DB is moved to quarantined/accounts/."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"These triggers stay narrow on purpose -- a definitively-missing table"},{"line_number":52,"context_line":"or row -- rather than broadening the OperationalError catch, which"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"e8ce5905_2d5c97bb","line":49,"updated":"2026-08-21 07:19:23.000000000","message":"idk, I don\u0027t see any auditor *changes* to support this - and the auditor test is doing the missing row case","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":46,"context_line":"sites."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"The auditor sees the resulting sqlite3.DatabaseError and the truncated"},{"line_number":49,"context_line":"DB is moved to quarantined/accounts/."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"These triggers stay narrow on purpose -- a definitively-missing table"},{"line_number":52,"context_line":"or row -- rather than broadening the OperationalError catch, which"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9c7644c1_0415e24c","line":49,"in_reply_to":"e8ce5905_2d5c97bb","updated":"2026-09-17 16:01:34.000000000","message":"This patch no longer claims auditor behavior.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":55,"context_line":""},{"line_number":56,"context_line":"Add broker-level tests for each guarded method, real file-truncation"},{"line_number":57,"context_line":"tests (empty and partial), and an auditor-level test asserting a"},{"line_number":58,"context_line":"truncated DB is moved to quarantined/accounts/ on the audit pass."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"Change-Id: I35b689717c01b1649e9205f67d46958d3d5c16d2"},{"line_number":61,"context_line":"Signed-off-by: Matthew Allen \u003cmaallen@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"cf9742e2_c9c95b80","line":58,"updated":"2026-08-21 07:19:23.000000000","message":"\u003e Add ... an auditor-level test asserting a truncated DB is moved to quarantined\n\nidk, there\u0027s only one new auditor test and I don\u0027t think I\u0027d describe it as doing that.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":55,"context_line":""},{"line_number":56,"context_line":"Add broker-level tests for each guarded method, real file-truncation"},{"line_number":57,"context_line":"tests (empty and partial), and an auditor-level test asserting a"},{"line_number":58,"context_line":"truncated DB is moved to quarantined/accounts/ on the audit pass."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"Change-Id: I35b689717c01b1649e9205f67d46958d3d5c16d2"},{"line_number":61,"context_line":"Signed-off-by: Matthew Allen \u003cmaallen@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"c55a6307_07cc344d","line":58,"in_reply_to":"cf9742e2_c9c95b80","updated":"2026-09-17 16:01:34.000000000","message":"The verify-claims skill and thorough review on my part should have eliminated the bogus claims in the earlier revisions. Of course, LMK if you see more.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"acb2b73343c8623d4a66fe4048caf666683036fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"04864b0f_30985098","updated":"2026-06-10 23:49:29.000000000","message":"Just some questions inline. I swear I wrote similar questions yesterday, but I don\u0027t see the review here now (or as drafts).. so feel like I\u0027m loosing my mind.. so if they do happen to appear twice then I appologise in advance 😛","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"11d7d6d6_25c90833","updated":"2026-06-04 18:49:24.000000000","message":"because the motivation of this change is improving robustness of the auditor I would suggest that the test_backend changes seem necessary but insufficient\n\nIf the title is \"quarantine truncated databases\" I would expect to see an auditor oriented test that sets up a screwy db runs audit and shows the quarantine:\n\n991709: sq? Add auditor quarantine regression tests | https://review.opendev.org/c/openstack/swift/+/991709\n\n^ N.B. the \"existing table missing row\" vs \"no such table\" difference.\n\nAlso don\u0027t be afraid to scope the operational error down some\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/db.py#L952\n\n^ I went looking for a \"better\" way to \"catagorize\" sqlite operational errors once and didn\u0027t find it; so I\u0027ve learned to live with:\n\n```\nif \u0027expected quarantine/migration condition\u0027 not in str(e):  raise\n```\n\nYMMV\n\nIf you want to limit the scope to just \"quarantine when table is missing row\" - that may still be useful, but maybe change/elaborate in the title?  I may have unfairly anchored \"truncated\" ~\u003d `: \u003e /some/path/to/a/hash.db`","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"32b3fa15f4261f31c95a4bace7b18bdc7bafd343","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4281ae02_3ce2e846","updated":"2026-06-26 00:01:13.000000000","message":"f","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"0da742c349dc1710e65a044add9a68c882eee0b8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1cb0c086_b8f0fabf","updated":"2026-06-04 09:16:07.000000000","message":"recheck\n\nFailures looks unrelated to this patch:\nERROR with Account server 158.69.69.167:6212/sdb2 re: Trying to GET /v1/AUTH_test: ConnectionTimeout (0.5s)\nERROR with Account server 158.69.69.167:6212/sdb2 re: Trying to POST /AUTH_test: ConnectionTimeout (0.5s)","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"12a7d31d_0abea34e","in_reply_to":"11d7d6d6_25c90833","updated":"2026-09-17 16:01:34.000000000","message":"This patch is now limited to quarantining when the stat row is missing. The plan is to now flesh out the auditor in a later patch in the chain.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1f658d21_2c054b60","updated":"2026-08-21 07:19:23.000000000","message":"what if instead of trying to make more call sites in common.db and [account|container]_backend know how to make brokers quarantine/seppuku we just actually added some quarntine logic into the db.auditor?\n\nI could imagine it being real cautious/curious when unexpected DatabaseErrors pop up:\n\n\u0027%s_stat\u0027 % db_type doesn\u0027t exist!?  what if I select 1 from db_type - what if select 1 from *some OTHER* db_type!?  what if I stat the file and it\u0027s zero bytes!?  Or some nominal value smaller than minimum reasonable bytes!?\n\nThe disadvantage is we don\u0027t necessarily get to quarantine in the normal server read path - and that might be a real problem if we were fighting with a bunch of tracebacks in prod b/c of corrupt dbs not quarantining fast enough \n\nThe advantage is we get to consider the quarantine huristic in the very narrow scope of a backgrouns auditor who\u0027s ONLY job is identify/classify the kinds of errors it discovers and then move that unexpected/non-conforming data out of the way\n\n... it has a license to be very methodical about it\u0027s huristic, and pretty wide leyway to say \"I know what I should expect and when something doesn\u0027t look right\" - that same context may not apply as boardly to any code that may be calling get_info on some path it found and passed into a broker class.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"}],"swift/account/backend.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2f74816accafe7576dccb82594755d340c69ba2d","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        with self.get() as conn:"},{"line_number":218,"context_line":"            row \u003d conn.execute("},{"line_number":219,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":220,"context_line":"            return zero_like(row[0])"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":223,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"ab366b81_96aa8cb1","side":"PARENT","line":220,"updated":"2026-07-10 07:13:27.000000000","message":"Is is trying to get one of the values out of account_stat too, is this also an candidate for quarantine? We\u0027re assuming there sill be a container_count in the row.","commit_id":"ca8749f344168ad1c4e07fdfd24e68ca04c57eae"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2f74816accafe7576dccb82594755d340c69ba2d","unresolved":false,"context_lines":[{"line_number":278,"context_line":"        with self.get() as conn:"},{"line_number":279,"context_line":"            row \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":280,"context_line":"                SELECT put_timestamp, delete_timestamp, status"},{"line_number":281,"context_line":"                FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":282,"context_line":"            return row[\u0027status\u0027] \u003d\u003d \"DELETED\" or ("},{"line_number":283,"context_line":"                row[\u0027delete_timestamp\u0027] \u003e row[\u0027put_timestamp\u0027])"},{"line_number":284,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e7f9ce26_16cfcaec","side":"PARENT","line":281,"updated":"2026-07-10 07:13:27.000000000","message":"doesn\u0027t this suffer from the same problem. If row is missing here the beow will fail, so we should probably quarantine here too?","commit_id":"ca8749f344168ad1c4e07fdfd24e68ca04c57eae"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":true,"context_lines":[{"line_number":345,"context_line":"        \"\"\""},{"line_number":346,"context_line":"        self._commit_puts_stale_ok()"},{"line_number":347,"context_line":"        with self.get() as conn:"},{"line_number":348,"context_line":"            data \u003d dict(conn.execute(\u0027\u0027\u0027"},{"line_number":349,"context_line":"                SELECT account, created_at,  put_timestamp, delete_timestamp,"},{"line_number":350,"context_line":"                       status_changed_at, container_count, object_count,"},{"line_number":351,"context_line":"                       bytes_used, hash, id"}],"source_content_type":"text/x-python","patch_set":1,"id":"79713395_f92b73d3","side":"PARENT","line":348,"updated":"2026-06-04 18:49:24.000000000","message":"oic, we removed the dict cast here","commit_id":"ca8749f344168ad1c4e07fdfd24e68ca04c57eae"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":345,"context_line":"        \"\"\""},{"line_number":346,"context_line":"        self._commit_puts_stale_ok()"},{"line_number":347,"context_line":"        with self.get() as conn:"},{"line_number":348,"context_line":"            data \u003d dict(conn.execute(\u0027\u0027\u0027"},{"line_number":349,"context_line":"                SELECT account, created_at,  put_timestamp, delete_timestamp,"},{"line_number":350,"context_line":"                       status_changed_at, container_count, object_count,"},{"line_number":351,"context_line":"                       bytes_used, hash, id"}],"source_content_type":"text/x-python","patch_set":1,"id":"5cb2448d_9ed73dba","side":"PARENT","line":348,"in_reply_to":"79713395_f92b73d3","updated":"2026-06-28 00:17:06.000000000","message":"Acknowledged","commit_id":"ca8749f344168ad1c4e07fdfd24e68ca04c57eae"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"acb2b73343c8623d4a66fe4048caf666683036fd","unresolved":true,"context_lines":[{"line_number":217,"context_line":"        with self.get() as conn:"},{"line_number":218,"context_line":"            row \u003d conn.execute("},{"line_number":219,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":220,"context_line":"            return zero_like(row[0])"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":223,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"b8e3ba21_0913c835","line":220,"updated":"2026-06-10 23:49:29.000000000","message":"the empty method also tries to read from account_stat, maybe this is less of an issue because its just one result.. but does it also need to trigger a quarantine of the row is missing?","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        with self.get() as conn:"},{"line_number":218,"context_line":"            row \u003d conn.execute("},{"line_number":219,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":220,"context_line":"            return zero_like(row[0])"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":223,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"9bba61c4_cb684c22","line":220,"in_reply_to":"82da1635_6adf556f","updated":"2026-06-28 00:17:06.000000000","message":"Done","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"32b3fa15f4261f31c95a4bace7b18bdc7bafd343","unresolved":true,"context_lines":[{"line_number":217,"context_line":"        with self.get() as conn:"},{"line_number":218,"context_line":"            row \u003d conn.execute("},{"line_number":219,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":220,"context_line":"            return zero_like(row[0])"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":223,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"82da1635_6adf556f","line":220,"in_reply_to":"b8e3ba21_0913c835","updated":"2026-06-26 00:01:13.000000000","message":"Agree it makes sense to have consistent behavior here. Will update.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":true,"context_lines":[{"line_number":271,"context_line":"        info \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":272,"context_line":"            SELECT put_timestamp, delete_timestamp, container_count, status"},{"line_number":273,"context_line":"            FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":274,"context_line":"        if not info:"},{"line_number":275,"context_line":"            self.quarantine(\"missing row in account_stat table\")"},{"line_number":276,"context_line":"        return self._is_deleted_info(**info)"},{"line_number":277,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"93f95f08_3d73b289","line":274,"updated":"2026-06-04 18:49:24.000000000","message":"here \"info\" is really more like \"data\" or \"row\" \n\nthe `if not row: quarantine()` pattern is well established in `common.db` e.g.\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/db.py#L948","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"32b3fa15f4261f31c95a4bace7b18bdc7bafd343","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        info \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":272,"context_line":"            SELECT put_timestamp, delete_timestamp, container_count, status"},{"line_number":273,"context_line":"            FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":274,"context_line":"        if not info:"},{"line_number":275,"context_line":"            self.quarantine(\"missing row in account_stat table\")"},{"line_number":276,"context_line":"        return self._is_deleted_info(**info)"},{"line_number":277,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"6a91df49_82e33b06","line":274,"in_reply_to":"93f95f08_3d73b289","updated":"2026-06-26 00:01:13.000000000","message":"Acknowledged","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"acb2b73343c8623d4a66fe4048caf666683036fd","unresolved":true,"context_lines":[{"line_number":282,"context_line":"                SELECT put_timestamp, delete_timestamp, status"},{"line_number":283,"context_line":"                FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":284,"context_line":"            return row[\u0027status\u0027] \u003d\u003d \"DELETED\" or ("},{"line_number":285,"context_line":"                row[\u0027delete_timestamp\u0027] \u003e row[\u0027put_timestamp\u0027])"},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":288,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"68c0859c_93e5364a","line":285,"updated":"2026-06-10 23:49:29.000000000","message":"is_status_deleted also has a call to the account_stat row, does this also need to trigger the quarantine?","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"32b3fa15f4261f31c95a4bace7b18bdc7bafd343","unresolved":true,"context_lines":[{"line_number":282,"context_line":"                SELECT put_timestamp, delete_timestamp, status"},{"line_number":283,"context_line":"                FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":284,"context_line":"            return row[\u0027status\u0027] \u003d\u003d \"DELETED\" or ("},{"line_number":285,"context_line":"                row[\u0027delete_timestamp\u0027] \u003e row[\u0027put_timestamp\u0027])"},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":288,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"9e2473b5_12acf538","line":285,"in_reply_to":"68c0859c_93e5364a","updated":"2026-06-26 00:01:13.000000000","message":"Yeah, this makes sense. Will update.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":282,"context_line":"                SELECT put_timestamp, delete_timestamp, status"},{"line_number":283,"context_line":"                FROM account_stat\u0027\u0027\u0027).fetchone()"},{"line_number":284,"context_line":"            return row[\u0027status\u0027] \u003d\u003d \"DELETED\" or ("},{"line_number":285,"context_line":"                row[\u0027delete_timestamp\u0027] \u003e row[\u0027put_timestamp\u0027])"},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":288,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"c5b7ebaa_afd6458b","line":285,"in_reply_to":"9e2473b5_12acf538","updated":"2026-06-28 00:17:06.000000000","message":"Done","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bd745d5986b4f95dcdff3c7fa56508146f145e41","unresolved":true,"context_lines":[{"line_number":341,"context_line":"        \"\"\""},{"line_number":342,"context_line":"        Get global data for the account."},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        :returns: dict with keys: account, created_at, put_timestamp,"},{"line_number":345,"context_line":"                  delete_timestamp, status_changed_at, container_count,"},{"line_number":346,"context_line":"                  object_count, bytes_used, hash, id"},{"line_number":347,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"b7c82f70_15cb5753","line":344,"updated":"2026-06-04 18:49:24.000000000","message":"oic, a *dict* - not just a sqlite3.Row that *acts like* a dict","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"07782cd719dfb7700c32dca49b1019e90d764b40","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        \"\"\""},{"line_number":342,"context_line":"        Get global data for the account."},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        :returns: dict with keys: account, created_at, put_timestamp,"},{"line_number":345,"context_line":"                  delete_timestamp, status_changed_at, container_count,"},{"line_number":346,"context_line":"                  object_count, bytes_used, hash, id"},{"line_number":347,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"c91bc66c_a138f198","line":344,"in_reply_to":"b7c82f70_15cb5753","updated":"2026-06-28 00:17:06.000000000","message":"Acknowledged","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"}],"swift/common/db.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":514,"context_line":"        \"\"\""},{"line_number":515,"context_line":"        row \u003d conn.execute(query, args).fetchone()"},{"line_number":516,"context_line":"        if not row:"},{"line_number":517,"context_line":"            self.quarantine(\"missing row in %s_stat table\" % self.db_type)"},{"line_number":518,"context_line":"        return row"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"    def possibly_quarantine(self, err):"}],"source_content_type":"text/x-python","patch_set":4,"id":"6acc308f_b2aaea1c","line":517,"updated":"2026-08-21 07:19:23.000000000","message":"I don\u0027t really see how we can infer from the signature that query includes `FROM %s_stat\u0027 % self.db_type` but also it seems like query is always `\u0027SELECT metadata FROM %s_stat\u0027 % self.db_type` ... which leads me to wonder if this method shouldn\u0027t just be `fetch_metadata_row` and it only ever has the one query and encapsulates the obvious/necessary/exact/specific error when we ever fail to fetch the metadata row\n\n\nmaybe we want `fetch_stat_row(columns)` - I think it depends how often that missing row in existing table error comes up; AFAIK outside of this change/tests I\u0027d never seen that before?  Now that I\u0027ve seen it the auditor should *definately* be able to discover/identify that case an quarantine those databases - i\u0027m less sure I know if it should happen unconditionally/always on any broker.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":514,"context_line":"        \"\"\""},{"line_number":515,"context_line":"        row \u003d conn.execute(query, args).fetchone()"},{"line_number":516,"context_line":"        if not row:"},{"line_number":517,"context_line":"            self.quarantine(\"missing row in %s_stat table\" % self.db_type)"},{"line_number":518,"context_line":"        return row"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"    def possibly_quarantine(self, err):"}],"source_content_type":"text/x-python","patch_set":4,"id":"8c322316_6cfc2dbd","line":517,"in_reply_to":"6acc308f_b2aaea1c","updated":"2026-09-17 16:01:34.000000000","message":"The get_stat_row helper now builds the query itself and takes the list of columns. Thanks for the tip!","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":538,"context_line":"            # But this error also fires when a different broker type opens the"},{"line_number":539,"context_line":"            # DB (e.g. an account broker reading a container DB). Check for a"},{"line_number":540,"context_line":"            # marker table that would identify a different DB type before"},{"line_number":541,"context_line":"            # quarantining, to avoid misquarantining a healthy DB."},{"line_number":542,"context_line":"            wrong_type_markers \u003d {"},{"line_number":543,"context_line":"                \u0027account\u0027: \u0027container_info\u0027,"},{"line_number":544,"context_line":"                \u0027container\u0027: \u0027account_stat\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"0a70ad69_11470dd7","line":541,"updated":"2026-08-21 07:19:23.000000000","message":"oh wow - like w/o bleeding the backend specific guard into common.db you could trigger a container-db quarantine just by pointed swift-account-info at it!?  Horrifying if true!\n\nmaybe there\u0027s some other guard for this:\n\n```\nDoes not appear to be a DB of type \"account\": /srv/node1/sdb1/containers/297/3e2/4a731d84d497b4ff813d01d71c4da3e2/4a731d84d497b4ff813d01d71c4da3e2.db\n```\n\n... and we\u0027re preserving that existing behavior via the re-raise","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":538,"context_line":"            # But this error also fires when a different broker type opens the"},{"line_number":539,"context_line":"            # DB (e.g. an account broker reading a container DB). Check for a"},{"line_number":540,"context_line":"            # marker table that would identify a different DB type before"},{"line_number":541,"context_line":"            # quarantining, to avoid misquarantining a healthy DB."},{"line_number":542,"context_line":"            wrong_type_markers \u003d {"},{"line_number":543,"context_line":"                \u0027account\u0027: \u0027container_info\u0027,"},{"line_number":544,"context_line":"                \u0027container\u0027: \u0027account_stat\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"d80a8da3_59fdad01","line":541,"in_reply_to":"0a70ad69_11470dd7","updated":"2026-09-17 16:01:34.000000000","message":"Clumsy wrong type markers are gone. This class of errors will now only be handled when we know the provenance of the database (i.e., auditor and replicator) and not in tools that accept arbitrary paths. The CLI tool change is now seated underneath this one in the stack. A future patch will address the situation where we detect the wrong database type.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":552,"context_line":"                except (sqlite3.OperationalError, sqlite3.DatabaseError):"},{"line_number":553,"context_line":"                    pass"},{"line_number":554,"context_line":"                else:"},{"line_number":555,"context_line":"                    raise err  # marker found → wrong DB type, not corruption"},{"line_number":556,"context_line":"            exc_hint \u003d \u0027missing %s_stat table\u0027 % self.db_type"},{"line_number":557,"context_line":"        elif \u0027disk I/O error\u0027 in str(err):"},{"line_number":558,"context_line":"            exc_hint \u003d \u0027disk error while accessing database\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"97c39ae5_46e0fe81","line":555,"updated":"2026-08-21 07:19:23.000000000","message":"wrong db type, not corruption?  Isn\u0027t that decision going to depend on the context?  Like if the account-auditor finds a container db laying around under /accounts that\u0027s a kind of \"corruption\" probably worth of quarantine - what\u0027s the alternative?  let the account-replciator blow up on it indefinately?","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":552,"context_line":"                except (sqlite3.OperationalError, sqlite3.DatabaseError):"},{"line_number":553,"context_line":"                    pass"},{"line_number":554,"context_line":"                else:"},{"line_number":555,"context_line":"                    raise err  # marker found → wrong DB type, not corruption"},{"line_number":556,"context_line":"            exc_hint \u003d \u0027missing %s_stat table\u0027 % self.db_type"},{"line_number":557,"context_line":"        elif \u0027disk I/O error\u0027 in str(err):"},{"line_number":558,"context_line":"            exc_hint \u003d \u0027disk error while accessing database\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"4cf97d9b_e392d0e0","line":555,"in_reply_to":"97c39ae5_46e0fe81","updated":"2026-09-17 16:01:34.000000000","message":"See above","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"}],"test/unit/account/test_backend.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2f74816accafe7576dccb82594755d340c69ba2d","unresolved":false,"context_lines":[{"line_number":496,"context_line":""},{"line_number":497,"context_line":"        with sqlite3.connect(db_path) as raw:"},{"line_number":498,"context_line":"            raw.execute(\u0027DELETE FROM account_stat\u0027)"},{"line_number":499,"context_line":"            raw.commit()"},{"line_number":500,"context_line":""},{"line_number":501,"context_line":"        broker \u003d AccountBroker(db_path, account\u003d\u0027test1\u0027)"},{"line_number":502,"context_line":"        db_dir \u003d os.path.dirname(db_path)"}],"source_content_type":"text/x-python","patch_set":1,"id":"09d853d1_0314dc9b","line":499,"updated":"2026-07-10 07:13:27.000000000","message":"raw.commit() will be called by the sqlite3.connect context manager so it\u0027s probably not required to do a commit here.. but also wont hurt.","commit_id":"4e2c5fb6c1cbe5ae636afa097c4f643fc0ce2536"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"80855bab1f2a1dd928c61865838f88581101330e","unresolved":true,"context_lines":[{"line_number":608,"context_line":"                             os.path.basename(db_dir))"},{"line_number":609,"context_line":"        with self.assertRaises(sqlite3.DatabaseError):"},{"line_number":610,"context_line":"            broker.get_info()"},{"line_number":611,"context_line":"        self.assertTrue(os.path.isdir(qpath))"},{"line_number":612,"context_line":"        self.assertFalse(os.path.exists(db_dir))"},{"line_number":613,"context_line":""},{"line_number":614,"context_line":"    def test_list_containers_iter(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"377bcbc0_25397da9","line":611,"updated":"2026-08-21 07:19:23.000000000","message":"why not raised.exception \"Quarntined due to\" assertion for this case?","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"},{"author":{"_account_id":39164,"name":"Matthew Allen","display_name":"Matthew Allen","email":"maallen@nvidia.com","username":"matthewallen"},"change_message_id":"a0f1f92d570474b0320b8833164c2dd26b6794e4","unresolved":false,"context_lines":[{"line_number":608,"context_line":"                             os.path.basename(db_dir))"},{"line_number":609,"context_line":"        with self.assertRaises(sqlite3.DatabaseError):"},{"line_number":610,"context_line":"            broker.get_info()"},{"line_number":611,"context_line":"        self.assertTrue(os.path.isdir(qpath))"},{"line_number":612,"context_line":"        self.assertFalse(os.path.exists(db_dir))"},{"line_number":613,"context_line":""},{"line_number":614,"context_line":"    def test_list_containers_iter(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"69e91189_b838eaa6","line":611,"in_reply_to":"377bcbc0_25397da9","updated":"2026-09-17 16:01:34.000000000","message":"Error message has been changed, see new patch lower in stack.","commit_id":"82a1607838e555d160901de6c7a6f5841070f6ad"}]}
