)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f81ad1a0e27e968b8a3228d4dd6ab0185b486a42","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0875364e_3ae12da7","updated":"2025-04-30 14:11:55.000000000","message":"logic looks good to me","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"316e4b8bae942518b4559748ee9edce94a50910a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"57d8b590_e5935f52","in_reply_to":"0875364e_3ae12da7","updated":"2025-04-30 14:57:55.000000000","message":"BTW, I still want to add a periodic thread to clean every N minutes too, I just had to stop adding stuff to it in order to let it see daylight.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7a442b5fb074c84e4530fa3514b98d0b2f3314e2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"cb2a5244_71a61466","updated":"2025-05-08 15:04:18.000000000","message":"Looks good. I haven\u0027t tried it yet but with the --generic-cmd flag I will be able to try easily in my local devstack. So holding my +2 for that trial.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ccc43f7460d3e1346645824d8064299cadd89357","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"5420a909_e368d714","updated":"2025-05-13 20:01:48.000000000","message":"Noticed one typo. Other than that, looks reasonable to me.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1af359fa17bf34b795cd10fd60d63e026f8457ad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"db080f6d_fa2a1349","updated":"2025-05-09 09:39:23.000000000","message":"Upgrading my vote to +2 after successful local tests:\n* one-shot https://paste.opendev.org/show/bfyHIFORn8yYbedowfel/\n* periodic (was lazy to collect logs)\n* notification based (was lazy to collect logs)\n\nI have only only one observation. The notification trigger works for openstack server delete, for openstack server evacuate and openstack server shelve_offload the user needs to rely on the periodic cleaning. Which is fine.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2ffe67fcb17820921028a5b2de67a75aedcfbe95","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"a1252262_e5f914bd","updated":"2025-05-05 19:25:24.000000000","message":"recheck literally does not touch any tested code","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d5e6724856936bcbfcfaf8db4e66e1e1e7f12d34","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"df5fe714_9fe9ec5b","in_reply_to":"db080f6d_fa2a1349","updated":"2025-05-13 20:03:54.000000000","message":"Ack, although I was mostly ignoring the move operations because of the yet-merged placement bug around allocations. I guess we don\u0027t swap allocations for either of those, so maybe they\u0027re not affected, but I\u0027d also have to look closer to see what notification we want to use for each and make sure the timing works out.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"93aa3883b887096c7be0747294368321240540a6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"7d2f7dd4_cca31182","updated":"2025-05-13 20:17:54.000000000","message":"gibi was previously +2 and this is just a typo fix. The script looks reasonable and gibi\u0027s testing also looks good, so approving.","commit_id":"28331fee3cff7ac3ccbeb96c22556a5192642309"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"23e6ada72a788f2c527520a69b0aec5f2375288c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"2baeaf0d_a1655af2","updated":"2025-05-14 02:25:05.000000000","message":"recheck can\u0027t be tight if it\u0027s liquid and can\u0027t fail a test if the code in the patch isn\u0027t tested","commit_id":"28331fee3cff7ac3ccbeb96c22556a5192642309"}],"contrib/clean-on-delete.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"cd4c781c7b5ba3e1a39c4fc1753407ed250e9269","unresolved":true,"context_lines":[{"line_number":188,"context_line":"            pci_addr \u003d self.pci_addr_for_rp(child)"},{"line_number":189,"context_line":"            if pci_addr in nvmes:"},{"line_number":190,"context_line":"                LOG.info(\u0027NVMe device %s at PCI address %s (rp %s) \u0027"},{"line_number":191,"context_line":"                         \u0027needs cleaning: %s\u0027, nvmes[pci_addr], pci_addr, child.id,"},{"line_number":192,"context_line":"                         bool(needs_cleaning))"},{"line_number":193,"context_line":"                cleaner \u003d NVMECleaner(child, pci_addr,"},{"line_number":194,"context_line":"                                      devs\u003dnvmes[pci_addr])"}],"source_content_type":"text/x-python","patch_set":1,"id":"8dde42ea_b429f3f2","line":191,"updated":"2025-04-29 16:35:31.000000000","message":"Oops","commit_id":"95462e4569cab9af1d1b216b260b58c6bb47601a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ae746b60b1bbe0cb528236db49d986ea6c0efb82","unresolved":false,"context_lines":[{"line_number":188,"context_line":"            pci_addr \u003d self.pci_addr_for_rp(child)"},{"line_number":189,"context_line":"            if pci_addr in nvmes:"},{"line_number":190,"context_line":"                LOG.info(\u0027NVMe device %s at PCI address %s (rp %s) \u0027"},{"line_number":191,"context_line":"                         \u0027needs cleaning: %s\u0027, nvmes[pci_addr], pci_addr, child.id,"},{"line_number":192,"context_line":"                         bool(needs_cleaning))"},{"line_number":193,"context_line":"                cleaner \u003d NVMECleaner(child, pci_addr,"},{"line_number":194,"context_line":"                                      devs\u003dnvmes[pci_addr])"}],"source_content_type":"text/x-python","patch_set":1,"id":"dc873e7c_9c1e99ea","line":191,"in_reply_to":"8dde42ea_b429f3f2","updated":"2025-04-30 14:36:20.000000000","message":"Done","commit_id":"95462e4569cab9af1d1b216b260b58c6bb47601a"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f81ad1a0e27e968b8a3228d4dd6ab0185b486a42","unresolved":true,"context_lines":[{"line_number":59,"context_line":"        raise NotImplementedError()"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"class NVMECleaner(Cleaner):"},{"line_number":63,"context_line":"    def clean(self):"},{"line_number":64,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":65,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"}],"source_content_type":"text/x-python","patch_set":2,"id":"6066f413_f32855fe","line":62,"updated":"2025-04-30 14:11:55.000000000","message":"nice, we can add a FakeCleaner if we want to add some test coverage without having NVMe in CI.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7a442b5fb074c84e4530fa3514b98d0b2f3314e2","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        raise NotImplementedError()"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"class NVMECleaner(Cleaner):"},{"line_number":63,"context_line":"    def clean(self):"},{"line_number":64,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":65,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"}],"source_content_type":"text/x-python","patch_set":2,"id":"4c31d5cb_e93a7a5d","line":62,"in_reply_to":"6066f413_f32855fe","updated":"2025-05-08 15:04:18.000000000","message":"Done with the GenericCleaner you added.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f81ad1a0e27e968b8a3228d4dd6ab0185b486a42","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        self.rp \u003d client.find_resource_provider(rp_name)"},{"line_number":80,"context_line":"        self.dryrun \u003d dryrun"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def get_nvme_devices(self):"},{"line_number":83,"context_line":"        output \u003d subprocess.check_output(\u0027nvme list -v -o json\u0027, shell\u003dTrue)"},{"line_number":84,"context_line":"        data \u003d json.loads(output)"},{"line_number":85,"context_line":"        nvmes \u003d collections.defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ff58699d_7f3c2af2","line":82,"updated":"2025-04-30 14:11:55.000000000","message":"hm if you abstracted the cleaner and created an NVMECleaner, it might make sense to move this NVME specific logic behind that or similar abstraction.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        self.rp \u003d client.find_resource_provider(rp_name)"},{"line_number":80,"context_line":"        self.dryrun \u003d dryrun"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def get_nvme_devices(self):"},{"line_number":83,"context_line":"        output \u003d subprocess.check_output(\u0027nvme list -v -o json\u0027, shell\u003dTrue)"},{"line_number":84,"context_line":"        data \u003d json.loads(output)"},{"line_number":85,"context_line":"        nvmes \u003d collections.defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":2,"id":"619f45ac_edca9f02","line":82,"in_reply_to":"423ed3cf_4e475f78","updated":"2025-05-05 12:27:08.000000000","message":"Acknowledged","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ae746b60b1bbe0cb528236db49d986ea6c0efb82","unresolved":true,"context_lines":[{"line_number":79,"context_line":"        self.rp \u003d client.find_resource_provider(rp_name)"},{"line_number":80,"context_line":"        self.dryrun \u003d dryrun"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def get_nvme_devices(self):"},{"line_number":83,"context_line":"        output \u003d subprocess.check_output(\u0027nvme list -v -o json\u0027, shell\u003dTrue)"},{"line_number":84,"context_line":"        data \u003d json.loads(output)"},{"line_number":85,"context_line":"        nvmes \u003d collections.defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":2,"id":"423ed3cf_4e475f78","line":82,"in_reply_to":"ff58699d_7f3c2af2","updated":"2025-04-30 14:36:20.000000000","message":"Yes, I started doing that and this just got a little more complicated and verbose (it\u0027s what I mentioned to you yesterday about continuing to try to optimize). I had to just stop at some point and the high-level logic is the important part.\n\nI thought about a matching/factory type classmethod here, but then I need to cache the list of nvmes somewhere, etc, etc :)","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f81ad1a0e27e968b8a3228d4dd6ab0185b486a42","unresolved":true,"context_lines":[{"line_number":208,"context_line":"def main():"},{"line_number":209,"context_line":"    p \u003d argparse.ArgumentParser()"},{"line_number":210,"context_line":"    p.add_argument(\u0027--topic\u0027, default\u003dNone,"},{"line_number":211,"context_line":"                   help\u003d(\u0027Per-compute node notifications queue. Defaults \u0027"},{"line_number":212,"context_line":"                         \u0027to notifications-$provider_name)\u0027))"},{"line_number":213,"context_line":"    p.add_argument(\u0027--debug\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":214,"context_line":"                   help\u003d\u0027Enable verbose debug logging\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"cf6f8747_15777489","line":211,"updated":"2025-04-30 14:11:55.000000000","message":"This assumes some extra nova-compute configuration present to have that topic used by nova-compute, we need to document that.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":false,"context_lines":[{"line_number":208,"context_line":"def main():"},{"line_number":209,"context_line":"    p \u003d argparse.ArgumentParser()"},{"line_number":210,"context_line":"    p.add_argument(\u0027--topic\u0027, default\u003dNone,"},{"line_number":211,"context_line":"                   help\u003d(\u0027Per-compute node notifications queue. Defaults \u0027"},{"line_number":212,"context_line":"                         \u0027to notifications-$provider_name)\u0027))"},{"line_number":213,"context_line":"    p.add_argument(\u0027--debug\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":214,"context_line":"                   help\u003d\u0027Enable verbose debug logging\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"0b8ef146_901eb0c5","line":211,"in_reply_to":"39f7c48e_a59b82dc","updated":"2025-05-05 13:41:16.000000000","message":"Acknowledged","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":208,"context_line":"def main():"},{"line_number":209,"context_line":"    p \u003d argparse.ArgumentParser()"},{"line_number":210,"context_line":"    p.add_argument(\u0027--topic\u0027, default\u003dNone,"},{"line_number":211,"context_line":"                   help\u003d(\u0027Per-compute node notifications queue. Defaults \u0027"},{"line_number":212,"context_line":"                         \u0027to notifications-$provider_name)\u0027))"},{"line_number":213,"context_line":"    p.add_argument(\u0027--debug\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":214,"context_line":"                   help\u003d\u0027Enable verbose debug logging\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"39f7c48e_a59b82dc","line":211,"in_reply_to":"bfec92be_436283bf","updated":"2025-05-05 12:27:08.000000000","message":"I think adding it to the config doc here is enough.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ae746b60b1bbe0cb528236db49d986ea6c0efb82","unresolved":true,"context_lines":[{"line_number":208,"context_line":"def main():"},{"line_number":209,"context_line":"    p \u003d argparse.ArgumentParser()"},{"line_number":210,"context_line":"    p.add_argument(\u0027--topic\u0027, default\u003dNone,"},{"line_number":211,"context_line":"                   help\u003d(\u0027Per-compute node notifications queue. Defaults \u0027"},{"line_number":212,"context_line":"                         \u0027to notifications-$provider_name)\u0027))"},{"line_number":213,"context_line":"    p.add_argument(\u0027--debug\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":214,"context_line":"                   help\u003d\u0027Enable verbose debug logging\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"bfec92be_436283bf","line":211,"in_reply_to":"cf6f8747_15777489","updated":"2025-04-30 14:36:20.000000000","message":"Well, it says \"per-compute\" but yeah. Should we try to do that in the help text here, or a comment at the top of this file, or what?","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f81ad1a0e27e968b8a3228d4dd6ab0185b486a42","unresolved":true,"context_lines":[{"line_number":245,"context_line":"        return"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    transport \u003d oslo_messaging.get_notification_transport(cfg.CONF)"},{"line_number":248,"context_line":"    targets \u003d [oslo_messaging.Target(topic\u003dargs.topic)]"},{"line_number":249,"context_line":"    endpoints \u003d [c.endpoint]"},{"line_number":250,"context_line":"    if args.debug:"},{"line_number":251,"context_line":"        endpoints.insert(0, LoggerEndpoint())"}],"source_content_type":"text/x-python","patch_set":2,"id":"20d60ef5_91e533f0","line":248,"updated":"2025-04-30 14:11:55.000000000","message":"if we pass exchange\u003dnova here then we don\u0027t need a per compute topic to not steal notifications, instead we can use pooling by CONF.host.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ae746b60b1bbe0cb528236db49d986ea6c0efb82","unresolved":true,"context_lines":[{"line_number":245,"context_line":"        return"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    transport \u003d oslo_messaging.get_notification_transport(cfg.CONF)"},{"line_number":248,"context_line":"    targets \u003d [oslo_messaging.Target(topic\u003dargs.topic)]"},{"line_number":249,"context_line":"    endpoints \u003d [c.endpoint]"},{"line_number":250,"context_line":"    if args.debug:"},{"line_number":251,"context_line":"        endpoints.insert(0, LoggerEndpoint())"}],"source_content_type":"text/x-python","patch_set":2,"id":"d3254c36_28f444c9","line":248,"in_reply_to":"20d60ef5_91e533f0","updated":"2025-04-30 14:36:20.000000000","message":"We can, but I think it\u0027s going to be more robust if used as a single topic. The pooling also requires that something else consumes the notifications in the top-level topic, which means to enable this, someone has to stand up something else if they\u0027re not already consuming those. I\u0027m also a bit suspect of the pooling implementation, as I think it puts the onus on the publisher to duplicate everything on send. That means every compute node will duplicate every message for every pooled listener on every compute node. Then all those listeners will receive and drop every message not intended for their compute node. I think o.msg pooling was intended for active/active listening of a few workers, and not this n^2 fanout emulation.","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":false,"context_lines":[{"line_number":245,"context_line":"        return"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    transport \u003d oslo_messaging.get_notification_transport(cfg.CONF)"},{"line_number":248,"context_line":"    targets \u003d [oslo_messaging.Target(topic\u003dargs.topic)]"},{"line_number":249,"context_line":"    endpoints \u003d [c.endpoint]"},{"line_number":250,"context_line":"    if args.debug:"},{"line_number":251,"context_line":"        endpoints.insert(0, LoggerEndpoint())"}],"source_content_type":"text/x-python","patch_set":2,"id":"dbe08c74_28fa90d3","line":248,"in_reply_to":"d3254c36_28f444c9","updated":"2025-05-05 12:27:08.000000000","message":"OK. You convinced me. :) Per compute topic is the way to go","commit_id":"b5863cc1047973bc633ee8bfeb5233d4edb9c69f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":69,"context_line":"    def info(self, ctxt, publisher_id, event_type, payload, metadata):"},{"line_number":70,"context_line":"        if publisher_id \u003d\u003d self.publisher_filter:"},{"line_number":71,"context_line":"            LOG.info(\u0027Instance deleted on %s\u0027, publisher_id)"},{"line_number":72,"context_line":"            with LOCK:"},{"line_number":73,"context_line":"                self.cleaner.trigger()"},{"line_number":74,"context_line":"        else:"},{"line_number":75,"context_line":"            LOG.debug(\u0027Ignoring notification from %s !\u003d %s\u0027,"},{"line_number":76,"context_line":"                      publisher_id, self.publisher_filter)"}],"source_content_type":"text/x-python","patch_set":4,"id":"eccbc4d0_c055e35a","line":73,"range":{"start_line":72,"start_character":0,"end_line":73,"end_character":38},"updated":"2025-05-05 12:27:08.000000000","message":"hm, if the LOCK always need to be taken when trigger is called, then we can move the LOCK into the cleaner and take in in trigger to simplify the callers.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7a442b5fb074c84e4530fa3514b98d0b2f3314e2","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    def info(self, ctxt, publisher_id, event_type, payload, metadata):"},{"line_number":70,"context_line":"        if publisher_id \u003d\u003d self.publisher_filter:"},{"line_number":71,"context_line":"            LOG.info(\u0027Instance deleted on %s\u0027, publisher_id)"},{"line_number":72,"context_line":"            with LOCK:"},{"line_number":73,"context_line":"                self.cleaner.trigger()"},{"line_number":74,"context_line":"        else:"},{"line_number":75,"context_line":"            LOG.debug(\u0027Ignoring notification from %s !\u003d %s\u0027,"},{"line_number":76,"context_line":"                      publisher_id, self.publisher_filter)"}],"source_content_type":"text/x-python","patch_set":4,"id":"963a0c13_4810aa8b","line":73,"range":{"start_line":72,"start_character":0,"end_line":73,"end_character":38},"in_reply_to":"23746d13_b2ca28c7","updated":"2025-05-08 15:04:18.000000000","message":"thanks for the context.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    def info(self, ctxt, publisher_id, event_type, payload, metadata):"},{"line_number":70,"context_line":"        if publisher_id \u003d\u003d self.publisher_filter:"},{"line_number":71,"context_line":"            LOG.info(\u0027Instance deleted on %s\u0027, publisher_id)"},{"line_number":72,"context_line":"            with LOCK:"},{"line_number":73,"context_line":"                self.cleaner.trigger()"},{"line_number":74,"context_line":"        else:"},{"line_number":75,"context_line":"            LOG.debug(\u0027Ignoring notification from %s !\u003d %s\u0027,"},{"line_number":76,"context_line":"                      publisher_id, self.publisher_filter)"}],"source_content_type":"text/x-python","patch_set":4,"id":"23746d13_b2ca28c7","line":73,"range":{"start_line":72,"start_character":0,"end_line":73,"end_character":38},"in_reply_to":"8f19bcc2_74b74f98","updated":"2025-05-05 14:52:00.000000000","message":"Done","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":69,"context_line":"    def info(self, ctxt, publisher_id, event_type, payload, metadata):"},{"line_number":70,"context_line":"        if publisher_id \u003d\u003d self.publisher_filter:"},{"line_number":71,"context_line":"            LOG.info(\u0027Instance deleted on %s\u0027, publisher_id)"},{"line_number":72,"context_line":"            with LOCK:"},{"line_number":73,"context_line":"                self.cleaner.trigger()"},{"line_number":74,"context_line":"        else:"},{"line_number":75,"context_line":"            LOG.debug(\u0027Ignoring notification from %s !\u003d %s\u0027,"},{"line_number":76,"context_line":"                      publisher_id, self.publisher_filter)"}],"source_content_type":"text/x-python","patch_set":4,"id":"8f19bcc2_74b74f98","line":73,"range":{"start_line":72,"start_character":0,"end_line":73,"end_character":38},"in_reply_to":"eccbc4d0_c055e35a","updated":"2025-05-05 13:41:16.000000000","message":"The reason I did it this way is because I was considering a mechanism by which trigger just puts a request in a queue and the thread just wakes up and does stuff regardless of where it came from. I still haven\u0027t quite decided if I want to go to that level of complexity or not.\n\nThe case I\u0027m worried about is basically where we get a slow drip of deletes and keep re-scanning all the provider stuff, whether there is something to do or not. If we batched them in some way we could increase the latency, but reduce the load on placement. The notification listener has a batched mode we could use.\n\nAnyway, with fresh Monday brain, it\u0027s probably best to just keep this simple until we prove it needs to be complex.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":103,"context_line":"        for device in data[\u0027Devices\u0027]:"},{"line_number":104,"context_line":"            for controller in device[\u0027Controllers\u0027]:"},{"line_number":105,"context_line":"                for ns in controller[\u0027Namespaces\u0027]:"},{"line_number":106,"context_line":"                    self._nvmes[controller[\u0027Address\u0027]].append(ns[\u0027NameSpace\u0027])"},{"line_number":107,"context_line":"        LOG.debug(\u0027Found NVMe devices: %s\u0027, self._nvmes)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def match(self, pci_addr):"}],"source_content_type":"text/x-python","patch_set":4,"id":"75eb6406_3a9c0135","line":106,"range":{"start_line":106,"start_character":66,"end_line":106,"end_character":75},"updated":"2025-05-05 12:27:08.000000000","message":"are they really capitalizing the \"S\" in namespace, strange.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":103,"context_line":"        for device in data[\u0027Devices\u0027]:"},{"line_number":104,"context_line":"            for controller in device[\u0027Controllers\u0027]:"},{"line_number":105,"context_line":"                for ns in controller[\u0027Namespaces\u0027]:"},{"line_number":106,"context_line":"                    self._nvmes[controller[\u0027Address\u0027]].append(ns[\u0027NameSpace\u0027])"},{"line_number":107,"context_line":"        LOG.debug(\u0027Found NVMe devices: %s\u0027, self._nvmes)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def match(self, pci_addr):"}],"source_content_type":"text/x-python","patch_set":4,"id":"e1b42661_2b52c87d","line":106,"range":{"start_line":106,"start_character":66,"end_line":106,"end_character":75},"in_reply_to":"75eb6406_3a9c0135","updated":"2025-05-05 13:41:16.000000000","message":"Yeah :/","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        for device in data[\u0027Devices\u0027]:"},{"line_number":104,"context_line":"            for controller in device[\u0027Controllers\u0027]:"},{"line_number":105,"context_line":"                for ns in controller[\u0027Namespaces\u0027]:"},{"line_number":106,"context_line":"                    self._nvmes[controller[\u0027Address\u0027]].append(ns[\u0027NameSpace\u0027])"},{"line_number":107,"context_line":"        LOG.debug(\u0027Found NVMe devices: %s\u0027, self._nvmes)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def match(self, pci_addr):"}],"source_content_type":"text/x-python","patch_set":4,"id":"25cbf777_593ca1de","line":106,"range":{"start_line":106,"start_character":66,"end_line":106,"end_character":75},"in_reply_to":"e1b42661_2b52c87d","updated":"2025-05-05 14:52:00.000000000","message":"Done","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def clean(self, rp, pci_addr):"},{"line_number":113,"context_line":"        devices \u003d self._nvmes[pci_addr]"},{"line_number":114,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":115,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"},{"line_number":116,"context_line":"        # on what the NVMe supports."},{"line_number":117,"context_line":"        LOG.info(\u0027Cleaning %s\u0027, \u0027,\u0027.join(devices))"},{"line_number":118,"context_line":"        for nsdev in devices:"},{"line_number":119,"context_line":"            cmd \u003d \u0027nvme format -f -s1 /dev/%s\u0027 % nsdev"}],"source_content_type":"text/x-python","patch_set":4,"id":"7cc4cf5a_91b202b7","line":116,"range":{"start_line":114,"start_character":0,"end_line":116,"end_character":36},"updated":"2025-05-05 12:27:08.000000000","message":"I think it is good enough as an example. If we want to be super generic we can provide a config option so that the deployer can configure what paramteres to pass, or even the whole command to run with some /dev/% templating.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def clean(self, rp, pci_addr):"},{"line_number":113,"context_line":"        devices \u003d self._nvmes[pci_addr]"},{"line_number":114,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":115,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"},{"line_number":116,"context_line":"        # on what the NVMe supports."},{"line_number":117,"context_line":"        LOG.info(\u0027Cleaning %s\u0027, \u0027,\u0027.join(devices))"},{"line_number":118,"context_line":"        for nsdev in devices:"},{"line_number":119,"context_line":"            cmd \u003d \u0027nvme format -f -s1 /dev/%s\u0027 % nsdev"}],"source_content_type":"text/x-python","patch_set":4,"id":"fc7581e5_f4096056","line":116,"range":{"start_line":114,"start_character":0,"end_line":116,"end_character":36},"in_reply_to":"4a6773a1_5bb5340d","updated":"2025-05-05 14:52:00.000000000","message":"I\u0027m adding a `--generic-cmd` option to allow you to just delegate cleaning of any pci device by address to a script, so that should let people do whatever they need for more specialized NVMe devices, or anything else.\n\nIt also makes testing the \"cleaning failed\" path easier (with `--generic-cmd /bin/false`), and means you can test with any PCI device, not just an NVMe going forward by just passing `--generic-cmd /bin/true`","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def clean(self, rp, pci_addr):"},{"line_number":113,"context_line":"        devices \u003d self._nvmes[pci_addr]"},{"line_number":114,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":115,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"},{"line_number":116,"context_line":"        # on what the NVMe supports."},{"line_number":117,"context_line":"        LOG.info(\u0027Cleaning %s\u0027, \u0027,\u0027.join(devices))"},{"line_number":118,"context_line":"        for nsdev in devices:"},{"line_number":119,"context_line":"            cmd \u003d \u0027nvme format -f -s1 /dev/%s\u0027 % nsdev"}],"source_content_type":"text/x-python","patch_set":4,"id":"4a6773a1_5bb5340d","line":116,"range":{"start_line":114,"start_character":0,"end_line":116,"end_character":36},"in_reply_to":"7cc4cf5a_91b202b7","updated":"2025-05-05 13:41:16.000000000","message":"well, unless you want to run the \"sanitize\" command against the whole device instead of a namespace, which is probably what most people passing whole-devices through will want, if their hardware supports it (mine does not).","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7a442b5fb074c84e4530fa3514b98d0b2f3314e2","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def clean(self, rp, pci_addr):"},{"line_number":113,"context_line":"        devices \u003d self._nvmes[pci_addr]"},{"line_number":114,"context_line":"        # NOTE(danms): This may not be good enough (we may need to use the"},{"line_number":115,"context_line":"        # \"sanitize\" option), or we may need to provide more options based"},{"line_number":116,"context_line":"        # on what the NVMe supports."},{"line_number":117,"context_line":"        LOG.info(\u0027Cleaning %s\u0027, \u0027,\u0027.join(devices))"},{"line_number":118,"context_line":"        for nsdev in devices:"},{"line_number":119,"context_line":"            cmd \u003d \u0027nvme format -f -s1 /dev/%s\u0027 % nsdev"}],"source_content_type":"text/x-python","patch_set":4,"id":"f84d39d5_cb714ae1","line":116,"range":{"start_line":114,"start_character":0,"end_line":116,"end_character":36},"in_reply_to":"fc7581e5_f4096056","updated":"2025-05-08 15:04:18.000000000","message":"--generic-cmd is a good addition for testing indeed. Thanks","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":158,"context_line":"            # This has OTU traitage, but doesn\u0027t look like a PCI-in-placement"},{"line_number":159,"context_line":"            # provider, so skip it for safety."},{"line_number":160,"context_line":"            LOG.warning("},{"line_number":161,"context_line":"                \u0027Skipping provider %s because it has %i inventories\u0027,"},{"line_number":162,"context_line":"                rp.id, len(inventory))"},{"line_number":163,"context_line":"        # OTU devices are \"burned\" when they have reserved \u003d\u003d total"},{"line_number":164,"context_line":"        is_reserved \u003d inventory[0].reserved \u003d\u003d inventory[0].total"}],"source_content_type":"text/x-python","patch_set":4,"id":"43a540cf_240d937e","line":161,"updated":"2025-05-05 12:27:08.000000000","message":"I don\u0027t think we are skipping this provider here. That would require an explicit return here.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":158,"context_line":"            # This has OTU traitage, but doesn\u0027t look like a PCI-in-placement"},{"line_number":159,"context_line":"            # provider, so skip it for safety."},{"line_number":160,"context_line":"            LOG.warning("},{"line_number":161,"context_line":"                \u0027Skipping provider %s because it has %i inventories\u0027,"},{"line_number":162,"context_line":"                rp.id, len(inventory))"},{"line_number":163,"context_line":"        # OTU devices are \"burned\" when they have reserved \u003d\u003d total"},{"line_number":164,"context_line":"        is_reserved \u003d inventory[0].reserved \u003d\u003d inventory[0].total"}],"source_content_type":"text/x-python","patch_set":4,"id":"7bd8796a_c47057ac","line":161,"in_reply_to":"43a540cf_240d937e","updated":"2025-05-05 13:41:16.000000000","message":"Oops yep, this used to be structured differently so that it wasn\u0027t an issue, thanks.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            # This has OTU traitage, but doesn\u0027t look like a PCI-in-placement"},{"line_number":159,"context_line":"            # provider, so skip it for safety."},{"line_number":160,"context_line":"            LOG.warning("},{"line_number":161,"context_line":"                \u0027Skipping provider %s because it has %i inventories\u0027,"},{"line_number":162,"context_line":"                rp.id, len(inventory))"},{"line_number":163,"context_line":"        # OTU devices are \"burned\" when they have reserved \u003d\u003d total"},{"line_number":164,"context_line":"        is_reserved \u003d inventory[0].reserved \u003d\u003d inventory[0].total"}],"source_content_type":"text/x-python","patch_set":4,"id":"80df2619_cc06f53e","line":161,"in_reply_to":"7bd8796a_c47057ac","updated":"2025-05-05 14:52:00.000000000","message":"Done","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":167,"context_line":"        LOG.debug(\u0027Inventory for %s: %s\u0027, rp.id, inventory)"},{"line_number":168,"context_line":"        # A provider needs cleaning if it is reserved and has no allocations"},{"line_number":169,"context_line":"        if is_reserved and not allocs:"},{"line_number":170,"context_line":"            return inventory[0]"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    def pci_addr_for_rp(self, rp):"},{"line_number":173,"context_line":"        # This format is defined in the PCI-in-placement work as:"}],"source_content_type":"text/x-python","patch_set":4,"id":"a93fd2bc_49eb3414","line":170,"updated":"2025-05-05 12:27:08.000000000","message":"as far as I see this is just used as returning something not evaluated to false","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":167,"context_line":"        LOG.debug(\u0027Inventory for %s: %s\u0027, rp.id, inventory)"},{"line_number":168,"context_line":"        # A provider needs cleaning if it is reserved and has no allocations"},{"line_number":169,"context_line":"        if is_reserved and not allocs:"},{"line_number":170,"context_line":"            return inventory[0]"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    def pci_addr_for_rp(self, rp):"},{"line_number":173,"context_line":"        # This format is defined in the PCI-in-placement work as:"}],"source_content_type":"text/x-python","patch_set":4,"id":"955f84a3_55bd94d2","line":170,"in_reply_to":"a93fd2bc_49eb3414","updated":"2025-05-05 14:52:00.000000000","message":"Acknowledged","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":220,"context_line":"        cleaners \u003d [cleaner_cls() for cleaner_cls in self.cleaners]"},{"line_number":221,"context_line":"        for child in children:"},{"line_number":222,"context_line":"            is_otu \u003d \u0027HW_PCI_ONE_TIME_USE\u0027 in self.traits_for_rp(child)"},{"line_number":223,"context_line":"            needs_cleaning \u003d is_otu and self.rp_needs_cleaning(child)"},{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"}],"source_content_type":"text/x-python","patch_set":4,"id":"d1e0dd66_d008241b","line":223,"updated":"2025-05-05 12:27:08.000000000","message":"It took a while but I think I go it, needs_cleaning is not a boolean but the inventory dict that needs to be cleaned from rp_needs_cleaning. It is maybe a bit too smart. :)","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        cleaners \u003d [cleaner_cls() for cleaner_cls in self.cleaners]"},{"line_number":221,"context_line":"        for child in children:"},{"line_number":222,"context_line":"            is_otu \u003d \u0027HW_PCI_ONE_TIME_USE\u0027 in self.traits_for_rp(child)"},{"line_number":223,"context_line":"            needs_cleaning \u003d is_otu and self.rp_needs_cleaning(child)"},{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"}],"source_content_type":"text/x-python","patch_set":4,"id":"a1e0fbce_db087b51","line":223,"in_reply_to":"2d42b7a6_c9b786ee","updated":"2025-05-05 14:52:00.000000000","message":"Done","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":220,"context_line":"        cleaners \u003d [cleaner_cls() for cleaner_cls in self.cleaners]"},{"line_number":221,"context_line":"        for child in children:"},{"line_number":222,"context_line":"            is_otu \u003d \u0027HW_PCI_ONE_TIME_USE\u0027 in self.traits_for_rp(child)"},{"line_number":223,"context_line":"            needs_cleaning \u003d is_otu and self.rp_needs_cleaning(child)"},{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"}],"source_content_type":"text/x-python","patch_set":4,"id":"2d42b7a6_c9b786ee","line":223,"in_reply_to":"d1e0dd66_d008241b","updated":"2025-05-05 13:41:16.000000000","message":"Yeah, sorry, this evolved as well when I re-structured the cleaner to be per-device-type instead of per-pci-addr. I\u0027ll clean this up to be more obvious.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"23595b5b74086f0ff2c60ed36c9079bcfce7f00a","unresolved":true,"context_lines":[{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"},{"line_number":227,"context_line":"                continue"},{"line_number":228,"context_line":"            pci_addr \u003d self.pci_addr_for_rp(child)"},{"line_number":229,"context_line":"            matched_cleaners \u003d [cleaner for cleaner in cleaners"},{"line_number":230,"context_line":"                                if cleaner.match(pci_addr)]"}],"source_content_type":"text/x-python","patch_set":4,"id":"8916e155_f5c88d3b","line":227,"updated":"2025-05-05 12:27:08.000000000","message":"This LOG message is confusing here where we know that needs_cleaning is always False/None here either as is_out is False (and therefore rp_needs_cleaning is not even called) or is_out is true but rp_needs_cleaning returned None. Would it make more sense to move this log message out of the nested if?","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4846fa095bcd48a99b1c6d506934e3ef8ba7a3f8","unresolved":true,"context_lines":[{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"},{"line_number":227,"context_line":"                continue"},{"line_number":228,"context_line":"            pci_addr \u003d self.pci_addr_for_rp(child)"},{"line_number":229,"context_line":"            matched_cleaners \u003d [cleaner for cleaner in cleaners"},{"line_number":230,"context_line":"                                if cleaner.match(pci_addr)]"}],"source_content_type":"text/x-python","patch_set":4,"id":"b8bf81fb_c2539271","line":227,"in_reply_to":"8916e155_f5c88d3b","updated":"2025-05-05 13:41:16.000000000","message":"This is leftover from my own debugging wanting to see true/false for each, and ran regardless, yeah. I\u0027ll redo this as well.","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f628343825ac18597f7c6cc01c17319b904b25e","unresolved":false,"context_lines":[{"line_number":224,"context_line":"            if not needs_cleaning:"},{"line_number":225,"context_line":"                LOG.debug(\u0027Provider %s needs cleaning: %s (otu\u003d%s)\u0027,"},{"line_number":226,"context_line":"                          child.id, needs_cleaning, is_otu)"},{"line_number":227,"context_line":"                continue"},{"line_number":228,"context_line":"            pci_addr \u003d self.pci_addr_for_rp(child)"},{"line_number":229,"context_line":"            matched_cleaners \u003d [cleaner for cleaner in cleaners"},{"line_number":230,"context_line":"                                if cleaner.match(pci_addr)]"}],"source_content_type":"text/x-python","patch_set":4,"id":"d944b197_3d01472d","line":227,"in_reply_to":"b8bf81fb_c2539271","updated":"2025-05-05 14:52:00.000000000","message":"Done","commit_id":"2e7fa24c378bd679958d946ff34464c9bb65fc2c"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ccc43f7460d3e1346645824d8064299cadd89357","unresolved":true,"context_lines":[{"line_number":253,"context_line":"            if not matched_cleaners and needs_cleaning:"},{"line_number":254,"context_line":"                # Unsupported device type, don\u0027t clean"},{"line_number":255,"context_line":"                LOG.warning(\u0027Child provider %s for %s needs cleaning but no \u0027"},{"line_number":256,"context_line":"                            \u0027cleanining implementations matched!\u0027,"},{"line_number":257,"context_line":"                             child.id, pci_addr)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"016e50f9_0ec0816c","line":256,"range":{"start_line":256,"start_character":29,"end_line":256,"end_character":39},"updated":"2025-05-13 20:01:48.000000000","message":"cleaning","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d5e6724856936bcbfcfaf8db4e66e1e1e7f12d34","unresolved":true,"context_lines":[{"line_number":253,"context_line":"            if not matched_cleaners and needs_cleaning:"},{"line_number":254,"context_line":"                # Unsupported device type, don\u0027t clean"},{"line_number":255,"context_line":"                LOG.warning(\u0027Child provider %s for %s needs cleaning but no \u0027"},{"line_number":256,"context_line":"                            \u0027cleanining implementations matched!\u0027,"},{"line_number":257,"context_line":"                             child.id, pci_addr)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"73c14b21_792ba246","line":256,"range":{"start_line":256,"start_character":29,"end_line":256,"end_character":39},"in_reply_to":"016e50f9_0ec0816c","updated":"2025-05-13 20:03:54.000000000","message":"No, I meant \"really clean\" .. like \"really really clean\" like \"cleanining\"...\n\nEr, yeah, fixed, thanks. Funny how codespell will hate on me for \"OTU\" but not this.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"93aa3883b887096c7be0747294368321240540a6","unresolved":true,"context_lines":[{"line_number":253,"context_line":"            if not matched_cleaners and needs_cleaning:"},{"line_number":254,"context_line":"                # Unsupported device type, don\u0027t clean"},{"line_number":255,"context_line":"                LOG.warning(\u0027Child provider %s for %s needs cleaning but no \u0027"},{"line_number":256,"context_line":"                            \u0027cleanining implementations matched!\u0027,"},{"line_number":257,"context_line":"                             child.id, pci_addr)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"f6df72f4_7d1d4706","line":256,"range":{"start_line":256,"start_character":29,"end_line":256,"end_character":39},"in_reply_to":"73c14b21_792ba246","updated":"2025-05-13 20:17:54.000000000","message":"I thought that might be it ... like for example \"cleaninating the peasants\".\n\nAnd I wondered about that too, how codespell didn\u0027t find this? Odd.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c4b2980df49ee9f99e1824afcdffc27d353009df","unresolved":true,"context_lines":[{"line_number":253,"context_line":"            if not matched_cleaners and needs_cleaning:"},{"line_number":254,"context_line":"                # Unsupported device type, don\u0027t clean"},{"line_number":255,"context_line":"                LOG.warning(\u0027Child provider %s for %s needs cleaning but no \u0027"},{"line_number":256,"context_line":"                            \u0027cleanining implementations matched!\u0027,"},{"line_number":257,"context_line":"                             child.id, pci_addr)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"bea9b9c3_b1a2a387","line":256,"range":{"start_line":256,"start_character":29,"end_line":256,"end_character":39},"in_reply_to":"f6df72f4_7d1d4706","updated":"2025-05-14 08:01:51.000000000","message":"Thanks I learned a new term \"cleaninating\" today. :)","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7a442b5fb074c84e4530fa3514b98d0b2f3314e2","unresolved":true,"context_lines":[{"line_number":319,"context_line":"        # NOTE(danms): This should be supportable, but it complicates our"},{"line_number":320,"context_line":"        # \"when to unreserve\" logic, so just keep this simple at the moment."},{"line_number":321,"context_line":"        print(\u0027Only one type of cleaner may be enabled at a time\u0027)"},{"line_number":322,"context_line":"        return 1"},{"line_number":323,"context_line":"    c \u003d CleaningWatcher(placement, args.provider_name, cleaners,"},{"line_number":324,"context_line":"                        dry_run\u003dargs.dry_run)"},{"line_number":325,"context_line":"    # Trigger at least once at startup before we potentially start processing"}],"source_content_type":"text/x-python","patch_set":5,"id":"de7a8001_33f68b2c","line":322,"updated":"2025-05-08 15:04:18.000000000","message":"I agree to keep it simple.","commit_id":"270de36b85281a2424c70b24a000140c284fe1b5"}]}
