)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"c76eb7669633cec411506026eae27fc6e812f034","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"ecfe462d_48784607","updated":"2025-04-28 07:46:06.000000000","message":"I would appreciate it if you could review the current code regarding the changes to the behavior of additional.traits in provider.yaml that were discussed at the PTG.","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"e963a19e507adb01d53393f331bc00c3832a6364","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"44d98ccc_cf1fbf42","updated":"2025-04-28 03:07:01.000000000","message":"This is the first implementation commit for the following nova-spec:\nhttps://review.opendev.org/c/openstack/nova-specs/+/937587\nThe implementation follows the approach decided during the PTG discussions. (Thank you for the discussions!)\nhttps://etherpad.opendev.org/p/nova-2025.2-ptg\n\nWhile the functional tests and documentation additions are not yet complete, I would appreciate reviews of the current code. If there are any tests needed beyond the functional test in nova/tests/functional/compute/test_resource_tracker.py, please let me know.\nAdditionally, the nova-spec will be updated according to the changes in this code.","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"951ee0a3a7037f6914226374eae76a2ab761fe8e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"bb77c245_b8204f66","updated":"2025-04-28 05:38:10.000000000","message":"recheck","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":8878,"name":"Masahito Muroi","email":"masahito.muroi@linecorp.com","username":"masa"},"change_message_id":"b3d6e6d4df17194cd88e70f30a6b8b0a58f60a7b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"07b41208_61e40c93","updated":"2025-05-12 18:25:56.000000000","message":"recheck nova-next","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"997ba439bc0d149e0bfa05272d0aba8eb9fb7bea","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"4f40a015_b6d5a549","in_reply_to":"44d98ccc_cf1fbf42","updated":"2025-04-28 07:36:32.000000000","message":"\u003e This is the first implementation commit for the following nova-spec:\n\u003e https://review.opendev.org/c/openstack/nova-specs/+/937587\n\u003e The implementation follows the approach decided during the PTG discussions. (Thank you for the discussions!)\n\u003e https://etherpad.opendev.org/p/nova-2025.2-ptg\n\u003e \n\u003e While the functional tests and documentation additions are not yet complete, I would appreciate reviews of the current code. If there are any tests needed beyond the functional test in nova/tests/functional/compute/test_resource_tracker.py, please let me know.\n\u003e Additionally, the nova-spec will be updated according to the changes in this code.\n\nOther than cyborg-tempest and barbican-tempest-plugin-simple-crypto, the failures seem to be flaky.","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"692740cc2af4a832c0de17c771c40dab27cd6709","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"be033b81_7b976063","updated":"2025-08-12 07:41:33.000000000","message":"@gibizer@gmail.com @seanmooney8202@yahoo.ie\nI would appreciate your review of this patch!\nI have added a specification that is not mentioned in the original spec, and I would like to hear your thoughts on it.\nThe added specification is: If there are no previously applied provider config files, only the custom traits defined in the provider config file to be applied will be added to the resource provider.\n\n[Status Share] The following is not implemented now, I\u0027ll do it from now on:\n- Handling cases where the provider config file is deleted or renamed.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9719d30dda286e289b9062254c0fcd019135e8cd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"f68cc4e8_cce19f4b","updated":"2025-08-27 11:05:59.000000000","message":"looks good but I don\u0027t want those applied files to be modifiable.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"5a7a6df123dc98c52461c439225fa2264e2e758c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"6bf95fb5_4aa1c4e0","updated":"2025-08-12 06:09:33.000000000","message":"recheck","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"1baf22de0d6347030ba3c1ab4e40a80fcd9eebbd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"5f42dd07_93199073","updated":"2025-08-12 04:41:32.000000000","message":"recheck nova-ceph-multistore","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"cecefdc94a90607d9d0b89e3587d6c0b1834af83","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"82e881bc_d7d3de33","updated":"2025-10-31 11:51:21.000000000","message":"Thank you for the review.\nI’ve addressed your comments and added the corresponding release note.","commit_id":"a7ccf9187c96f751aaadd8cc6daa22bdf86cc39b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"38bfc4c2c9342bd0bf93456d1127be0d520d55df","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":8,"id":"8b7e17ae_76c4606c","updated":"2025-11-05 08:58:12.000000000","message":"I also added a fix to delete the applied files when the provider config files are removed/renamed.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"add912033d94d0ea027de019500a56fb2a5d9426","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"a60c8198_2b116f21","updated":"2025-11-05 09:59:46.000000000","message":"Just a procedural hold, could you please provide another spec file for the 2026.1 directory so we could accept it again ?\n\nhttps://review.opendev.org/c/openstack/nova-specs/+/937587 was the 2025.2 accepted spec, just recreate the file for 2026.1 in a new change.\n\nPing me once this is done (IRC : bauzas) so I could reapprove it.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"bbb1ee981c7d48971e53bbf047df4c2b87a7ed21","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"f24bcb7c_6117bb04","in_reply_to":"a60c8198_2b116f21","updated":"2025-11-06 00:33:49.000000000","message":"The 2026.1 spec: https://review.opendev.org/c/openstack/nova-specs/+/966151\n(Already reapproved and merged, thank you!)","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"0406dbfa_f430a9d7","updated":"2026-01-16 14:12:36.000000000","message":"Thank you very much for the thorough review.\nI now have a much better understanding of the different scenarios.\nI’ll add the additional functional tests next. Thank you also for sharing the detailed examples — they were extremely helpful.\n\nI’ll also update doc/source/admin/managing-resource-providers.rst later on.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a98cb62782acc04f34637616aa90c4468a97f473","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"4d68d64a_4f8f1e00","updated":"2026-02-25 19:29:16.000000000","message":"-1 mainly to highlight gibis comment","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"7021a6810ac96a3a0571dc024a6cbc07078a2403","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"de67529b_42a04a36","updated":"2026-01-22 12:35:55.000000000","message":"@gibizer@gmail.com Thanks again for the review.\nI’ve addressed your review comments. I’d appreciate it if you could take another look when you have time.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":12,"id":"3485d171_5455e5b9","updated":"2026-02-25 17:23:24.000000000","message":"I did some local testing and I see an error.\n1. created provider.yaml with an additional trait and restarted nova-compute\n2. observed that the trait was added\n3. observed that the provider.yaml was copied\n4. deleted the provider yaml under /etc/nova/provider_config and restarted the nova-compute\n5. observed that the trait was removed and the copied provider.yaml was removed too.\nSo far this is OK. \n```\nFeb 25 17:18:32 aio nova-compute[279831]: INFO nova.compute.resource_tracker [None req-555555bb-1a7f-4b82-9ae7-772c7de3e5ea None None] Removing applied provider config file /opt/stack/data/nova/applied_provider_config/provider.yaml as it no longer exists in /etc/nova/provider_config/\n```\nBut then during the periodic update_available_resource task I see the following stack trace logged:\n```\nFeb 25 17:19:27 aio nova-compute[279831]: INFO nova.compute.resource_tracker [None req-4a304dfe-164d-48b2-851d-2b2c4e8f9a6d None None] Removing applied provider config file /opt/stack/data/nova/applied_provider_config/provider.yaml as it no longer exists in /etc/nova/provider_config/\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager [None req-4a304dfe-164d-48b2-851d-2b2c4e8f9a6d None None] Error updating resources for node aio.: FileNotFoundError: [Errno 2] No such file or directory: \u0027/opt/stack/data/nova/applied_provider_config/provider.yaml\u0027\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager Traceback (most recent call last):\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/manager.py\", line 11412, in _update_available_resource_for_node\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self.rt.update_available_resource(context, nodename,\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 975, in update_available_resource\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self._update_available_resource(context, resources, startup\u003dstartup)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.12/site-packages/oslo_concurrency/lockutils.py\", line 528, in inner\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     return f(*args, **kwargs)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager            ^^^^^^^^^^^^^^^^^^\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1106, in _update_available_resource\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self._update(context, cn, startup\u003dstartup)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1420, in _update\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self._update_to_placement(context, compute_node, startup)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.12/site-packages/retrying.py\", line 55, in wrapped_f\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     return Retrying(*dargs, **dkw).call(f, *args, **kw)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.12/site-packages/retrying.py\", line 279, in call\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     return attempt.get(self._wrap_exception)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.12/site-packages/retrying.py\", line 326, in get\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     raise exc.with_traceback(tb)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.12/site-packages/retrying.py\", line 273, in call\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     attempt \u003d Attempt(fn(*args, **kwargs), attempt_number, False)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager                       ^^^^^^^^^^^^^^^^^^^\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1396, in _update_to_placement\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self._merge_provider_configs(self.provider_configs,\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 2082, in _merge_provider_configs\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     self._cleanup_removed_provider_configs(\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 2133, in _cleanup_removed_provider_configs\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     applied_file.unlink()\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager   File \"/usr/lib/python3.12/pathlib.py\", line 1344, in unlink\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager     os.unlink(self)\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager FileNotFoundError: [Errno 2] No such file or directory: \u0027/opt/stack/data/nova/applied_provider_config/provider.yaml\u0027\nFeb 25 17:19:27 aio nova-compute[279831]: ERROR nova.compute.manager \n```","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"267a6944_623b80de","updated":"2026-02-25 19:26:25.000000000","message":"i have not had time to go though all the tests so -0 but ohte rhtne some minor nits i dont really hav emuch to add that gibi didnt already raise\n\nhttps://review.opendev.org/c/openstack/nova/+/948304/comments/3485d171_5455e5b9","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"b4265277191bff92b91c1b856230bc94fc63dd1b","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":12,"id":"9cb4f995_90e8676d","in_reply_to":"3485d171_5455e5b9","updated":"2026-02-25 17:50:42.000000000","message":"I probably see another bug.\n1. add the trait CUSTOM_EXAMPLE_TRAIT to the compute RP via the provider.yaml and restart the nova-compute\n2. observer that the trait is added\n3. change the provider.yaml file in a way that the additional trait is now not targeting the compute RP but a child RP and the name of the trait is changed to CUSTOM_EXAMPLE_TRAIT_2 and restart the nova-compute\n4. observer that CUSTOM_EXAMPLE_TRAIT_2 added to the child RP\n5. but also noticed that the CUSTOM_EXAMPLE_TRAIT was not removed from the compute RP which seems like a bug\n\nThen if I do this again just to the other direction I see the following\n\n6. change the provider.yaml in way that now the additional trait targets the compute RP and the name CUSTOM_EXAMPLE_TRAIT_3 and restart the nova-compute\n7. observer that the CUSTOM_EXAMPLE_TRAIT_3 added to the compute RP (the CUSTOM_EXAMPLE_TRAIT is kept) but also the CUSTOM_EXAMPLE_TRAIT_2 is removed from the child RP.\n\nSo it seems that the behavior is not symmetric between the compute RP and the child RP. It might be related to ways how nova handles the traits on the compute RP and the child RP (in my case that was a PCI RP). But I\u0027m not sure.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a98cb62782acc04f34637616aa90c4468a97f473","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":12,"id":"cd1797ea_a2d10bfd","in_reply_to":"9cb4f995_90e8676d","updated":"2026-02-25 19:29:16.000000000","message":"i wonder if restarting it tiwice woudl have fixed it i.e. a seocnd restart after step 5\n\nbut ya the behvior on the root rp need to be adressed.\n\nthe chile rp behvior seams correct.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"b1a7610cbcfe4b9a5b437b5ac5fbe8fd31076a08","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":12,"id":"115487d0_7c7f47ef","in_reply_to":"cd1797ea_a2d10bfd","updated":"2026-02-26 00:30:09.000000000","message":"Thank you so much for the thorough review.\nI hadn’t considered the case where the target RP is changed later.\nI’ll check and fix it together with the update_available_resource error.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"}],"doc/source/admin/managing-resource-providers.rst":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9719d30dda286e289b9062254c0fcd019135e8cd","unresolved":true,"context_lines":[{"line_number":35,"context_line":"Saving Applied Configuration Files and Diff Detection"},{"line_number":36,"context_line":"-----------------------------------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"As an enhancement, nova-compute saves the contents of the applied"},{"line_number":39,"context_line":"``*.yaml`` to separate files after it has been successfully processed"},{"line_number":40,"context_line":"and custom inventory and traits have been added."},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"These applied files are written to the location defined in"}],"source_content_type":"text/x-rst","patch_set":5,"id":"8104c372_ce8ac13a","line":39,"range":{"start_line":38,"start_character":58,"end_line":39,"end_character":29},"updated":"2025-08-27 11:05:59.000000000","message":"nit : please change to \"applied ``*.yaml`` file(s)\"","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"cecefdc94a90607d9d0b89e3587d6c0b1834af83","unresolved":true,"context_lines":[{"line_number":35,"context_line":"Saving Applied Configuration Files and Diff Detection"},{"line_number":36,"context_line":"-----------------------------------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"As an enhancement, nova-compute saves the contents of the applied"},{"line_number":39,"context_line":"``*.yaml`` to separate files after it has been successfully processed"},{"line_number":40,"context_line":"and custom inventory and traits have been added."},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"These applied files are written to the location defined in"}],"source_content_type":"text/x-rst","patch_set":5,"id":"23b8d97d_fc43d754","line":39,"range":{"start_line":38,"start_character":58,"end_line":39,"end_character":29},"in_reply_to":"8104c372_ce8ac13a","updated":"2025-10-31 11:51:21.000000000","message":"Thanks for your comment! I fixed the text.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  nova-compute will only add all the traits defined in the current ``*.yaml``"},{"line_number":56,"context_line":"  configuration files under"},{"line_number":57,"context_line":"  :oslo.config:option:`compute.provider_config_location`. This means that"},{"line_number":58,"context_line":"  custom traits added from the placement API, etc., will be deleted."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":".. note::"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"d785e693_b52b1b13","line":58,"updated":"2026-01-15 15:57:11.000000000","message":"Yeah the user should not try to manage custom traits on the compute providers via both the Placement API and provider.yamls at the same time. However nova by itself might add custom traits to providers if so configured. Those traist should never be removed by this feature. This feature should only remove traits that was added by the a previous provider.yaml file. (see specific example in my comment in the functional coverage)","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":55,"context_line":"  nova-compute will only add all the traits defined in the current ``*.yaml``"},{"line_number":56,"context_line":"  configuration files under"},{"line_number":57,"context_line":"  :oslo.config:option:`compute.provider_config_location`. This means that"},{"line_number":58,"context_line":"  custom traits added from the placement API, etc., will be deleted."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":".. note::"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"7aad0b5a_e62f45f5","line":58,"in_reply_to":"cfc62da6_f2c106c2","updated":"2026-02-25 17:23:24.000000000","message":"Done","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"7021a6810ac96a3a0571dc024a6cbc07078a2403","unresolved":true,"context_lines":[{"line_number":55,"context_line":"  nova-compute will only add all the traits defined in the current ``*.yaml``"},{"line_number":56,"context_line":"  configuration files under"},{"line_number":57,"context_line":"  :oslo.config:option:`compute.provider_config_location`. This means that"},{"line_number":58,"context_line":"  custom traits added from the placement API, etc., will be deleted."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":".. note::"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"cfc62da6_f2c106c2","line":58,"in_reply_to":"d785e693_b52b1b13","updated":"2026-01-22 12:35:55.000000000","message":"I\u0027ve revised the wording in the document.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":true,"context_lines":[{"line_number":32,"context_line":"    The files are loaded once at nova-compute startup and any changes or new"},{"line_number":33,"context_line":"    files will not be recognized until the next nova-compute startup."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"Saving Applied Configuration Files and Diff Detection"},{"line_number":36,"context_line":"-----------------------------------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"As an enhancement, nova-compute saves the contents of the applied"},{"line_number":39,"context_line":"``*.yaml`` file(s) after it has been successfully processed"},{"line_number":40,"context_line":"and custom inventory and traits have been added."},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"These applied files are written to the location defined in"},{"line_number":43,"context_line":":oslo.config:option:`compute.applied_provider_config_location`."},{"line_number":44,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"462d3c2e_3de63557","line":41,"range":{"start_line":35,"start_character":0,"end_line":41,"end_character":1},"updated":"2026-02-25 19:26:25.000000000","message":"this read stragnly as is almost a temporal statment\n\nif you want to do that you shoudl use the \"Changed in version\"\nberofe the section like this\n\nhttps://github.com/openstack/nova/blob/master/doc/source/admin/virtual-gpu.rst?plain\u003d1#L363\n\nadd \n\n\n```suggestion\n\n.. versionchanged:: 33.0.0\n\nSaving Applied Configuration Files and Diff Detection\n-----------------------------------------------------\n\nnova-compute saves the contents of the applied``*.yaml`` file(s)\nafter it has been successfully processed and custom inventory and\ntraits have been added.\n\n```","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"b1a7610cbcfe4b9a5b437b5ac5fbe8fd31076a08","unresolved":true,"context_lines":[{"line_number":32,"context_line":"    The files are loaded once at nova-compute startup and any changes or new"},{"line_number":33,"context_line":"    files will not be recognized until the next nova-compute startup."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"Saving Applied Configuration Files and Diff Detection"},{"line_number":36,"context_line":"-----------------------------------------------------"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"As an enhancement, nova-compute saves the contents of the applied"},{"line_number":39,"context_line":"``*.yaml`` file(s) after it has been successfully processed"},{"line_number":40,"context_line":"and custom inventory and traits have been added."},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"These applied files are written to the location defined in"},{"line_number":43,"context_line":":oslo.config:option:`compute.applied_provider_config_location`."},{"line_number":44,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"ed52a40a_ddbb26f0","line":41,"range":{"start_line":35,"start_character":0,"end_line":41,"end_character":1},"in_reply_to":"462d3c2e_3de63557","updated":"2026-02-26 00:30:09.000000000","message":"I see, thanks for the comment.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"}],"nova/compute/resource_tracker.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"33bd2fff314f524fe322c26b6472c96a079fedb2","unresolved":true,"context_lines":[{"line_number":2071,"context_line":"            fileutils.ensure_tree(self.applied_provider_config_location)"},{"line_number":2072,"context_line":"            for processed_file in processed_files:"},{"line_number":2073,"context_line":"                shutil.copy("},{"line_number":2074,"context_line":"                    os.path.join(self.provider_config_location,"},{"line_number":2075,"context_line":"                                 processed_file),"},{"line_number":2076,"context_line":"                    os.path.join(self.applied_provider_config_location,"},{"line_number":2077,"context_line":"                                 processed_file))"}],"source_content_type":"text/x-python","patch_set":2,"id":"ff69f870_4c2b58e9","line":2074,"updated":"2025-11-19 13:13:58.000000000","message":"nit: I would use pathlib[1] for new code like this as it has a bit more readable interface.\n\n[1]https://docs.python.org/3/library/pathlib.html","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"f17d7caace94d660dc04dc3d35b0c5cd12f00166","unresolved":true,"context_lines":[{"line_number":2071,"context_line":"            fileutils.ensure_tree(self.applied_provider_config_location)"},{"line_number":2072,"context_line":"            for processed_file in processed_files:"},{"line_number":2073,"context_line":"                shutil.copy("},{"line_number":2074,"context_line":"                    os.path.join(self.provider_config_location,"},{"line_number":2075,"context_line":"                                 processed_file),"},{"line_number":2076,"context_line":"                    os.path.join(self.applied_provider_config_location,"},{"line_number":2077,"context_line":"                                 processed_file))"}],"source_content_type":"text/x-python","patch_set":2,"id":"f13e17df_3d74cb90","line":2074,"in_reply_to":"453e3cf8_eafef031","updated":"2026-01-13 02:01:54.000000000","message":"Updated.","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":false,"context_lines":[{"line_number":2071,"context_line":"            fileutils.ensure_tree(self.applied_provider_config_location)"},{"line_number":2072,"context_line":"            for processed_file in processed_files:"},{"line_number":2073,"context_line":"                shutil.copy("},{"line_number":2074,"context_line":"                    os.path.join(self.provider_config_location,"},{"line_number":2075,"context_line":"                                 processed_file),"},{"line_number":2076,"context_line":"                    os.path.join(self.applied_provider_config_location,"},{"line_number":2077,"context_line":"                                 processed_file))"}],"source_content_type":"text/x-python","patch_set":2,"id":"7b881bf0_5b6d7e09","line":2074,"in_reply_to":"f13e17df_3d74cb90","updated":"2026-01-15 15:57:11.000000000","message":"Acknowledged","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"44c1f778410baf87b94071f06cbd6c6d91c59815","unresolved":true,"context_lines":[{"line_number":2071,"context_line":"            fileutils.ensure_tree(self.applied_provider_config_location)"},{"line_number":2072,"context_line":"            for processed_file in processed_files:"},{"line_number":2073,"context_line":"                shutil.copy("},{"line_number":2074,"context_line":"                    os.path.join(self.provider_config_location,"},{"line_number":2075,"context_line":"                                 processed_file),"},{"line_number":2076,"context_line":"                    os.path.join(self.applied_provider_config_location,"},{"line_number":2077,"context_line":"                                 processed_file))"}],"source_content_type":"text/x-python","patch_set":2,"id":"453e3cf8_eafef031","line":2074,"in_reply_to":"ff69f870_4c2b58e9","updated":"2025-11-20 12:09:00.000000000","message":"Thanks, I’ll update to use pathlib.","commit_id":"eec685c87b7e392c16255c924fef3285313734cf"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9719d30dda286e289b9062254c0fcd019135e8cd","unresolved":true,"context_lines":[{"line_number":2089,"context_line":"        for name in filenames:"},{"line_number":2090,"context_line":"            src \u003d os.path.join(self.provider_config_location, name)"},{"line_number":2091,"context_line":"            dst \u003d os.path.join(self.applied_provider_config_location, name)"},{"line_number":2092,"context_line":"            shutil.copy(src, dst)"},{"line_number":2093,"context_line":""},{"line_number":2094,"context_line":"    def _get_providers_to_update(self, uuid_or_name, provider_tree,"},{"line_number":2095,"context_line":"                                 source_file):"}],"source_content_type":"text/x-python","patch_set":5,"id":"b3c6a334_15bbeaf4","line":2092,"updated":"2025-08-27 11:05:59.000000000","message":"nit: we could set permissions to readonly to prevent operators mistakenly touching them.\n\nIdeally, we should even put those files immutable but that would require too much efforts for a slight detail.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":false,"context_lines":[{"line_number":2089,"context_line":"        for name in filenames:"},{"line_number":2090,"context_line":"            src \u003d os.path.join(self.provider_config_location, name)"},{"line_number":2091,"context_line":"            dst \u003d os.path.join(self.applied_provider_config_location, name)"},{"line_number":2092,"context_line":"            shutil.copy(src, dst)"},{"line_number":2093,"context_line":""},{"line_number":2094,"context_line":"    def _get_providers_to_update(self, uuid_or_name, provider_tree,"},{"line_number":2095,"context_line":"                                 source_file):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9fec05e1_4c05bea2","line":2092,"in_reply_to":"071e6eeb_62b26027","updated":"2026-02-25 19:26:25.000000000","message":"Done","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"cecefdc94a90607d9d0b89e3587d6c0b1834af83","unresolved":true,"context_lines":[{"line_number":2089,"context_line":"        for name in filenames:"},{"line_number":2090,"context_line":"            src \u003d os.path.join(self.provider_config_location, name)"},{"line_number":2091,"context_line":"            dst \u003d os.path.join(self.applied_provider_config_location, name)"},{"line_number":2092,"context_line":"            shutil.copy(src, dst)"},{"line_number":2093,"context_line":""},{"line_number":2094,"context_line":"    def _get_providers_to_update(self, uuid_or_name, provider_tree,"},{"line_number":2095,"context_line":"                                 source_file):"}],"source_content_type":"text/x-python","patch_set":5,"id":"071e6eeb_62b26027","line":2092,"in_reply_to":"b3c6a334_15bbeaf4","updated":"2025-10-31 11:51:21.000000000","message":"Thanks, they should be read-only. I added to set the file permissions to 444.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"33bd2fff314f524fe322c26b6472c96a079fedb2","unresolved":true,"context_lines":[{"line_number":2041,"context_line":"                    traits_to_remove \u003d set(applied_additional_traits) - set("},{"line_number":2042,"context_line":"                        additional_traits)"},{"line_number":2043,"context_line":"                else:"},{"line_number":2044,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2045,"context_line":"                    # time nova-compute has been started, and all custom traits"},{"line_number":2046,"context_line":"                    # will be deleted."},{"line_number":2047,"context_line":"                    traits_to_remove \u003d set(existing_custom_traits) - set("},{"line_number":2048,"context_line":"                        additional_traits)"},{"line_number":2049,"context_line":""},{"line_number":2050,"context_line":"                if traits_to_remove:"},{"line_number":2051,"context_line":"                    provider_tree.remove_traits("}],"source_content_type":"text/x-python","patch_set":8,"id":"33e04d05_8257f943","line":2048,"range":{"start_line":2044,"start_character":0,"end_line":2048,"end_character":42},"updated":"2025-11-19 13:13:58.000000000","message":"As far as I see this was not part of the spec so I would like to discuss it here. \nFor me this seems pretty drastic. I don\u0027t think we should blindly remove any custom traits that might set outside of the provider.yaml logic.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"44c1f778410baf87b94071f06cbd6c6d91c59815","unresolved":true,"context_lines":[{"line_number":2041,"context_line":"                    traits_to_remove \u003d set(applied_additional_traits) - set("},{"line_number":2042,"context_line":"                        additional_traits)"},{"line_number":2043,"context_line":"                else:"},{"line_number":2044,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2045,"context_line":"                    # time nova-compute has been started, and all custom traits"},{"line_number":2046,"context_line":"                    # will be deleted."},{"line_number":2047,"context_line":"                    traits_to_remove \u003d set(existing_custom_traits) - set("},{"line_number":2048,"context_line":"                        additional_traits)"},{"line_number":2049,"context_line":""},{"line_number":2050,"context_line":"                if traits_to_remove:"},{"line_number":2051,"context_line":"                    provider_tree.remove_traits("}],"source_content_type":"text/x-python","patch_set":8,"id":"e1e3b010_e78cd545","line":2048,"range":{"start_line":2044,"start_character":0,"end_line":2048,"end_character":42},"in_reply_to":"33e04d05_8257f943","updated":"2025-11-20 12:09:00.000000000","message":"Thanks for the review!\nAs you pointed out, this wasn’t covered in the spec, so I’d like to discuss it here as well. \n(I had mistakenly marked the previous comment as resolved, I mentioned this here: https://review.opendev.org/c/openstack/nova/+/948304/comments/be033b81_7b976063\n)\n\nThanks for sharing your thoughts.\nSince the custom traits are not always deleted, I think the impact would be somewhat limited.\nHow about introducing a config option to control whether the custom traits should be removed or not? (default: false)","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"f17d7caace94d660dc04dc3d35b0c5cd12f00166","unresolved":true,"context_lines":[{"line_number":2041,"context_line":"                    traits_to_remove \u003d set(applied_additional_traits) - set("},{"line_number":2042,"context_line":"                        additional_traits)"},{"line_number":2043,"context_line":"                else:"},{"line_number":2044,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2045,"context_line":"                    # time nova-compute has been started, and all custom traits"},{"line_number":2046,"context_line":"                    # will be deleted."},{"line_number":2047,"context_line":"                    traits_to_remove \u003d set(existing_custom_traits) - set("},{"line_number":2048,"context_line":"                        additional_traits)"},{"line_number":2049,"context_line":""},{"line_number":2050,"context_line":"                if traits_to_remove:"},{"line_number":2051,"context_line":"                    provider_tree.remove_traits("}],"source_content_type":"text/x-python","patch_set":8,"id":"7cac2776_c2b78c5d","line":2048,"range":{"start_line":2044,"start_character":0,"end_line":2048,"end_character":42},"in_reply_to":"e1e3b010_e78cd545","updated":"2026-01-13 02:01:54.000000000","message":"@gibizer@gmail.com I’ve added a configuration variable to control the removal of custom traits that are set externally.\nIf this approach is acceptable, I plan to update the spec accordingly.\nPlease review when you have time.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"33bd2fff314f524fe322c26b6472c96a079fedb2","unresolved":true,"context_lines":[{"line_number":2078,"context_line":"        # to the applied config location and remove any applied files that"},{"line_number":2079,"context_line":"        # no longer exist in the provider config location"},{"line_number":2080,"context_line":"        processed_files \u003d set(processed_providers.values())"},{"line_number":2081,"context_line":"        if processed_files:"},{"line_number":2082,"context_line":"            # Clean up applied files that no longer exist"},{"line_number":2083,"context_line":"            # in provider config location"},{"line_number":2084,"context_line":"            self._cleanup_removed_provider_configs(processed_files)"}],"source_content_type":"text/x-python","patch_set":8,"id":"96ff5a55_4d4f5747","line":2081,"updated":"2025-11-19 13:13:58.000000000","message":"hm I think if the processed files list is empty it means that now there is no provider.yaml files for nova to apply, but there still can be files saved as previously applied.\n\nI guess the scenario is:\n* at T1 there were some provider.yamls, nova applied them, and nova saved them\n* at T2 the original files were removed. \n\nHow do we handle the traits that was applied at T1? As we have the applied file saved, we can remove those traits at T2 as they are no longer present in the input.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"44c1f778410baf87b94071f06cbd6c6d91c59815","unresolved":true,"context_lines":[{"line_number":2078,"context_line":"        # to the applied config location and remove any applied files that"},{"line_number":2079,"context_line":"        # no longer exist in the provider config location"},{"line_number":2080,"context_line":"        processed_files \u003d set(processed_providers.values())"},{"line_number":2081,"context_line":"        if processed_files:"},{"line_number":2082,"context_line":"            # Clean up applied files that no longer exist"},{"line_number":2083,"context_line":"            # in provider config location"},{"line_number":2084,"context_line":"            self._cleanup_removed_provider_configs(processed_files)"}],"source_content_type":"text/x-python","patch_set":8,"id":"9e9c76d8_a45847de","line":2081,"in_reply_to":"96ff5a55_4d4f5747","updated":"2025-11-20 12:09:00.000000000","message":"Ah you\u0027re right, the applied file would remain.\n\nIf the original files are deleted while the applied files still exist, you’re suggesting that we should additionally remove the custom traits defined in the applied file as well, correct?","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"f17d7caace94d660dc04dc3d35b0c5cd12f00166","unresolved":true,"context_lines":[{"line_number":2078,"context_line":"        # to the applied config location and remove any applied files that"},{"line_number":2079,"context_line":"        # no longer exist in the provider config location"},{"line_number":2080,"context_line":"        processed_files \u003d set(processed_providers.values())"},{"line_number":2081,"context_line":"        if processed_files:"},{"line_number":2082,"context_line":"            # Clean up applied files that no longer exist"},{"line_number":2083,"context_line":"            # in provider config location"},{"line_number":2084,"context_line":"            self._cleanup_removed_provider_configs(processed_files)"}],"source_content_type":"text/x-python","patch_set":8,"id":"e547bcba_d537f452","line":2081,"in_reply_to":"9e9c76d8_a45847de","updated":"2026-01-13 02:01:54.000000000","message":"@gibizer@gmail.com I’ve updated the code to handle the case you pointed out.","commit_id":"32f029869387014308adb58b3bc21ee85896564b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":128,"context_line":"        # used to identify any traits that need to be removed if they are not"},{"line_number":129,"context_line":"        # present in the new config."},{"line_number":130,"context_line":"        self.applied_provider_config_location \u003d \\"},{"line_number":131,"context_line":"            CONF.compute.applied_provider_config_location"},{"line_number":132,"context_line":"        self.applied_provider_configs \u003d provider_config.get_provider_configs("},{"line_number":133,"context_line":"            self.applied_provider_config_location)"},{"line_number":134,"context_line":"        # Set of ids for providers identified in provider config files that"}],"source_content_type":"text/x-python","patch_set":10,"id":"8d23c612_7bd0eb60","line":131,"updated":"2026-01-15 15:57:11.000000000","message":"nit: We tend to use () instead of \\ to warp long lines\n```\n    self.applied_provider_config_location \u003d (\n            CONF.compute.applied_provider_config_location)\n```","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":128,"context_line":"        # used to identify any traits that need to be removed if they are not"},{"line_number":129,"context_line":"        # present in the new config."},{"line_number":130,"context_line":"        self.applied_provider_config_location \u003d \\"},{"line_number":131,"context_line":"            CONF.compute.applied_provider_config_location"},{"line_number":132,"context_line":"        self.applied_provider_configs \u003d provider_config.get_provider_configs("},{"line_number":133,"context_line":"            self.applied_provider_config_location)"},{"line_number":134,"context_line":"        # Set of ids for providers identified in provider config files that"}],"source_content_type":"text/x-python","patch_set":10,"id":"8f1b28f3_819703b8","line":131,"in_reply_to":"8d23c612_7bd0eb60","updated":"2026-01-16 14:12:36.000000000","message":"I see, thank you I updated.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":128,"context_line":"        # used to identify any traits that need to be removed if they are not"},{"line_number":129,"context_line":"        # present in the new config."},{"line_number":130,"context_line":"        self.applied_provider_config_location \u003d \\"},{"line_number":131,"context_line":"            CONF.compute.applied_provider_config_location"},{"line_number":132,"context_line":"        self.applied_provider_configs \u003d provider_config.get_provider_configs("},{"line_number":133,"context_line":"            self.applied_provider_config_location)"},{"line_number":134,"context_line":"        # Set of ids for providers identified in provider config files that"}],"source_content_type":"text/x-python","patch_set":10,"id":"8fc19ea9_a1c81daa","line":131,"in_reply_to":"8f1b28f3_819703b8","updated":"2026-02-25 17:23:24.000000000","message":"Done","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":2043,"context_line":"                        additional_traits)"},{"line_number":2044,"context_line":"                else:"},{"line_number":2045,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2046,"context_line":"                    # time nova-compute has been started,"},{"line_number":2047,"context_line":"                    # and all custom traits will be deleted if"},{"line_number":2048,"context_line":"                    # CONF.compute.remove_externally_set_traits is True."},{"line_number":2049,"context_line":"                    if CONF.compute.remove_externally_set_traits:"}],"source_content_type":"text/x-python","patch_set":10,"id":"ffe4b8d0_6edf5b08","line":2046,"updated":"2026-01-15 15:57:11.000000000","message":"To be more precise this is the first time nova-compute is started with a provider.yaml configuration.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":2043,"context_line":"                        additional_traits)"},{"line_number":2044,"context_line":"                else:"},{"line_number":2045,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2046,"context_line":"                    # time nova-compute has been started,"},{"line_number":2047,"context_line":"                    # and all custom traits will be deleted if"},{"line_number":2048,"context_line":"                    # CONF.compute.remove_externally_set_traits is True."},{"line_number":2049,"context_line":"                    if CONF.compute.remove_externally_set_traits:"}],"source_content_type":"text/x-python","patch_set":10,"id":"b871c2be_77e8eea4","line":2046,"in_reply_to":"421be0ce_0cea0d1e","updated":"2026-02-25 17:23:24.000000000","message":"Done","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":2043,"context_line":"                        additional_traits)"},{"line_number":2044,"context_line":"                else:"},{"line_number":2045,"context_line":"                    # If applied_provider_configs is empty, this is the first"},{"line_number":2046,"context_line":"                    # time nova-compute has been started,"},{"line_number":2047,"context_line":"                    # and all custom traits will be deleted if"},{"line_number":2048,"context_line":"                    # CONF.compute.remove_externally_set_traits is True."},{"line_number":2049,"context_line":"                    if CONF.compute.remove_externally_set_traits:"}],"source_content_type":"text/x-python","patch_set":10,"id":"421be0ce_0cea0d1e","line":2046,"in_reply_to":"ffe4b8d0_6edf5b08","updated":"2026-01-16 14:12:36.000000000","message":"Fixed the comment.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":true,"context_lines":[{"line_number":2154,"context_line":"            shutil.copy(src, dst)"},{"line_number":2155,"context_line":""},{"line_number":2156,"context_line":"            # Make the copied file read-only"},{"line_number":2157,"context_line":"            dst.chmod(0o444)"},{"line_number":2158,"context_line":""},{"line_number":2159,"context_line":"    def _get_providers_to_update(self, uuid_or_name, provider_tree,"},{"line_number":2160,"context_line":"                                 source_file):"}],"source_content_type":"text/x-python","patch_set":12,"id":"0cf0d878_4cd4afcf","line":2157,"range":{"start_line":2157,"start_character":22,"end_line":2157,"end_character":27},"updated":"2026-02-25 19:26:25.000000000","message":"nit: 400 or 440 would be better\nas this does not need to be world readable","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"b1a7610cbcfe4b9a5b437b5ac5fbe8fd31076a08","unresolved":true,"context_lines":[{"line_number":2154,"context_line":"            shutil.copy(src, dst)"},{"line_number":2155,"context_line":""},{"line_number":2156,"context_line":"            # Make the copied file read-only"},{"line_number":2157,"context_line":"            dst.chmod(0o444)"},{"line_number":2158,"context_line":""},{"line_number":2159,"context_line":"    def _get_providers_to_update(self, uuid_or_name, provider_tree,"},{"line_number":2160,"context_line":"                                 source_file):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3c4e31ce_94177b68","line":2157,"range":{"start_line":2157,"start_character":22,"end_line":2157,"end_character":27},"in_reply_to":"0cf0d878_4cd4afcf","updated":"2026-02-26 00:30:09.000000000","message":"Good point. I’ll update it to 400.","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"}],"nova/conf/compute.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9719d30dda286e289b9062254c0fcd019135e8cd","unresolved":true,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted."},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"Additional documentation is available here:"},{"line_number":1023,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"33ae3990_9f69a560","line":1020,"updated":"2025-08-27 11:05:59.000000000","message":"maybe just add that those YAML files should not be modified and ideally write-restricted.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"cecefdc94a90607d9d0b89e3587d6c0b1834af83","unresolved":true,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted."},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"Additional documentation is available here:"},{"line_number":1023,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"480690b9_ce6ff544","line":1020,"in_reply_to":"33ae3990_9f69a560","updated":"2025-10-31 11:51:21.000000000","message":"Added text.","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":false,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted."},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"Additional documentation is available here:"},{"line_number":1023,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3813ffff_9a5ddcfb","line":1020,"in_reply_to":"480690b9_ce6ff544","updated":"2026-02-25 19:26:25.000000000","message":"Done","commit_id":"988e82d23c1e8c6f9350218b171929cb45996457"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted. Files stored in this directory should not be modified and should be"},{"line_number":1021,"context_line":"write-restricted."},{"line_number":1022,"context_line":""},{"line_number":1023,"context_line":"Additional documentation is available here:"},{"line_number":1024,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"184bde86_6bceeba0","line":1021,"range":{"start_line":1020,"start_character":70,"end_line":1021,"end_character":16},"updated":"2026-01-15 15:57:11.000000000","message":"nit: made read-only by nova.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted. Files stored in this directory should not be modified and should be"},{"line_number":1021,"context_line":"write-restricted."},{"line_number":1022,"context_line":""},{"line_number":1023,"context_line":"Additional documentation is available here:"},{"line_number":1024,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"e1754942_8a65bce5","line":1021,"range":{"start_line":1020,"start_character":70,"end_line":1021,"end_character":16},"in_reply_to":"184bde86_6bceeba0","updated":"2026-01-16 14:12:36.000000000","message":"Updated the wording.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"The differences between these files and the files in"},{"line_number":1019,"context_line":"``provider_config_location`` are compared to detect custom traits that need to"},{"line_number":1020,"context_line":"be deleted. Files stored in this directory should not be modified and should be"},{"line_number":1021,"context_line":"write-restricted."},{"line_number":1022,"context_line":""},{"line_number":1023,"context_line":"Additional documentation is available here:"},{"line_number":1024,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"f084d1b3_b7111ea8","line":1021,"range":{"start_line":1020,"start_character":70,"end_line":1021,"end_character":16},"in_reply_to":"e1754942_8a65bce5","updated":"2026-02-25 17:23:24.000000000","message":"Done","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"}],"nova/tests/functional/compute/test_resource_tracker.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":656,"context_line":""},{"line_number":657,"context_line":"        # create a config file with additional traits: CUSTOM_FAKE_HOST and"},{"line_number":658,"context_line":"        # CUSTOM_TRAIT_A"},{"line_number":659,"context_line":"        config \u003d self._create_config_entry(host, id_method\u003d\"name\")"},{"line_number":660,"context_line":"        config[\"providers\"][0][\"traits\"][\"additional\"].append(\"CUSTOM_TRAIT_A\")"},{"line_number":661,"context_line":"        self._place_config_file(\"provider_config1.yaml\", config)"},{"line_number":662,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"b288a71d_831fe83c","line":659,"updated":"2026-01-15 15:57:11.000000000","message":"not to myself: _create_config_entry automatically adds CUSTOM_FAKE_HOST inventory and trait to the single compute RP.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":690,"context_line":"        # ensure that only CUSTOM_FAKE_HOST exists"},{"line_number":691,"context_line":"        self._assert_inventory_and_traits(provider, modified_config)"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"        # ensure that applied yaml is read-only and includes CUSTOM_TRAIT_A and"},{"line_number":694,"context_line":"        # CUSTOM_FAKE_HOST"},{"line_number":695,"context_line":"        filemode \u003d os.stat(applied_filepath).st_mode"},{"line_number":696,"context_line":"        self.assertEqual(stat.S_IMODE(filemode), 0o444)"},{"line_number":697,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5eb52603_d4eaaa41","line":694,"range":{"start_line":693,"start_character":0,"end_line":694,"end_character":26},"updated":"2026-01-15 15:57:11.000000000","message":"I think what you mean here is that we need to ensure that the saved yaml only has CUSTOM_FAKE_HOST as CUSTOM_TRAIT_A was removed and such removal is now applied.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":690,"context_line":"        # ensure that only CUSTOM_FAKE_HOST exists"},{"line_number":691,"context_line":"        self._assert_inventory_and_traits(provider, modified_config)"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"        # ensure that applied yaml is read-only and includes CUSTOM_TRAIT_A and"},{"line_number":694,"context_line":"        # CUSTOM_FAKE_HOST"},{"line_number":695,"context_line":"        filemode \u003d os.stat(applied_filepath).st_mode"},{"line_number":696,"context_line":"        self.assertEqual(stat.S_IMODE(filemode), 0o444)"},{"line_number":697,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"d15aa3f8_2c2e1ccd","line":694,"range":{"start_line":693,"start_character":0,"end_line":694,"end_character":26},"in_reply_to":"1eb59a97_26c55538","updated":"2026-02-25 17:23:24.000000000","message":"Acknowledged","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":690,"context_line":"        # ensure that only CUSTOM_FAKE_HOST exists"},{"line_number":691,"context_line":"        self._assert_inventory_and_traits(provider, modified_config)"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"        # ensure that applied yaml is read-only and includes CUSTOM_TRAIT_A and"},{"line_number":694,"context_line":"        # CUSTOM_FAKE_HOST"},{"line_number":695,"context_line":"        filemode \u003d os.stat(applied_filepath).st_mode"},{"line_number":696,"context_line":"        self.assertEqual(stat.S_IMODE(filemode), 0o444)"},{"line_number":697,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1eb59a97_26c55538","line":694,"range":{"start_line":693,"start_character":0,"end_line":694,"end_character":26},"in_reply_to":"5eb52603_d4eaaa41","updated":"2026-01-16 14:12:36.000000000","message":"Thank you, that’s correct. I’ve updated the comment accordingly.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":698,"context_line":"        with open(applied_filepath, \u0027r\u0027) as f:"},{"line_number":699,"context_line":"            applied_content \u003d yaml.safe_load(f)"},{"line_number":700,"context_line":"        self.assertIn(\"CUSTOM_FAKE_HOST\","},{"line_number":701,"context_line":"                      applied_content[\"providers\"][0][\"traits\"][\"additional\"])"},{"line_number":702,"context_line":""},{"line_number":703,"context_line":"    def test_config_file_remove(self):"},{"line_number":704,"context_line":"        \"\"\"Tests that when a provider config file is deleted, the custom traits"}],"source_content_type":"text/x-python","patch_set":10,"id":"2d671262_ae0cd7fa","line":701,"updated":"2026-01-15 15:57:11.000000000","message":"This is correct but you should also assert that CUSTOM_TRAIT_A is not in the saved yaml any more.\n\n```\n        self.assertNotIn(\n            \"CUSTOM_TRAIT_A\",\n            applied_content[\"providers\"][0][\"traits\"][\"additional\"])\n```","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":698,"context_line":"        with open(applied_filepath, \u0027r\u0027) as f:"},{"line_number":699,"context_line":"            applied_content \u003d yaml.safe_load(f)"},{"line_number":700,"context_line":"        self.assertIn(\"CUSTOM_FAKE_HOST\","},{"line_number":701,"context_line":"                      applied_content[\"providers\"][0][\"traits\"][\"additional\"])"},{"line_number":702,"context_line":""},{"line_number":703,"context_line":"    def test_config_file_remove(self):"},{"line_number":704,"context_line":"        \"\"\"Tests that when a provider config file is deleted, the custom traits"}],"source_content_type":"text/x-python","patch_set":10,"id":"0311e001_9685d17b","line":701,"in_reply_to":"05825f6a_e4b89f9f","updated":"2026-02-25 17:23:24.000000000","message":"Acknowledged","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":698,"context_line":"        with open(applied_filepath, \u0027r\u0027) as f:"},{"line_number":699,"context_line":"            applied_content \u003d yaml.safe_load(f)"},{"line_number":700,"context_line":"        self.assertIn(\"CUSTOM_FAKE_HOST\","},{"line_number":701,"context_line":"                      applied_content[\"providers\"][0][\"traits\"][\"additional\"])"},{"line_number":702,"context_line":""},{"line_number":703,"context_line":"    def test_config_file_remove(self):"},{"line_number":704,"context_line":"        \"\"\"Tests that when a provider config file is deleted, the custom traits"}],"source_content_type":"text/x-python","patch_set":10,"id":"05825f6a_e4b89f9f","line":701,"in_reply_to":"2d671262_ae0cd7fa","updated":"2026-01-16 14:12:36.000000000","message":"Thank you! I added the assertNotIn.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":721,"context_line":"            self._get_provider_uuid_by_host(host))"},{"line_number":722,"context_line":"        self._assert_inventory_and_traits(provider, config)"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":"        # ensure that applied yaml has CUSTOM_TRAIT_A and CUSTOM_FAKE_HOST"},{"line_number":725,"context_line":"        applied_filepath \u003d os.path.join(self.applied_pconf_loc,"},{"line_number":726,"context_line":"                                        \"provider_config1.yaml\")"},{"line_number":727,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"880e453d_c76706dd","line":724,"updated":"2026-01-15 15:57:11.000000000","message":"the code below only assert that the file exists","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0053777f9a5cd3d3206c3bd45869027392724f72","unresolved":false,"context_lines":[{"line_number":721,"context_line":"            self._get_provider_uuid_by_host(host))"},{"line_number":722,"context_line":"        self._assert_inventory_and_traits(provider, config)"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":"        # ensure that applied yaml has CUSTOM_TRAIT_A and CUSTOM_FAKE_HOST"},{"line_number":725,"context_line":"        applied_filepath \u003d os.path.join(self.applied_pconf_loc,"},{"line_number":726,"context_line":"                                        \"provider_config1.yaml\")"},{"line_number":727,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7173d051_737cf4b8","line":724,"in_reply_to":"0286fd7b_ca14780d","updated":"2026-02-25 19:26:25.000000000","message":"Done","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":721,"context_line":"            self._get_provider_uuid_by_host(host))"},{"line_number":722,"context_line":"        self._assert_inventory_and_traits(provider, config)"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":"        # ensure that applied yaml has CUSTOM_TRAIT_A and CUSTOM_FAKE_HOST"},{"line_number":725,"context_line":"        applied_filepath \u003d os.path.join(self.applied_pconf_loc,"},{"line_number":726,"context_line":"                                        \"provider_config1.yaml\")"},{"line_number":727,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"0286fd7b_ca14780d","line":724,"in_reply_to":"880e453d_c76706dd","updated":"2026-01-16 14:12:36.000000000","message":"I’ve added checks for the existence of CUSTOM_FAKE_HOST and CUSTOM_TRAIT_A.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":753,"context_line":"        \"\"\""},{"line_number":754,"context_line":"        host \u003d \"fake-host\""},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"        # start nova-compute without provider config and with"},{"line_number":757,"context_line":"        # remove_externally_set_traits\u003dFalse"},{"line_number":758,"context_line":"        self.flags(remove_externally_set_traits\u003dFalse, group\u003d\u0027compute\u0027)"},{"line_number":759,"context_line":"        compute_service \u003d self._start_compute(host)"},{"line_number":760,"context_line":""},{"line_number":761,"context_line":"        # get the provider UUID"},{"line_number":762,"context_line":"        rp_uuid \u003d self._get_provider_uuid_by_host(host)"}],"source_content_type":"text/x-python","patch_set":10,"id":"bbd50f0e_51773079","line":759,"range":{"start_line":756,"start_character":0,"end_line":759,"end_character":51},"updated":"2026-01-15 15:57:11.000000000","message":"Isn\u0027t it the default?","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":753,"context_line":"        \"\"\""},{"line_number":754,"context_line":"        host \u003d \"fake-host\""},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"        # start nova-compute without provider config and with"},{"line_number":757,"context_line":"        # remove_externally_set_traits\u003dFalse"},{"line_number":758,"context_line":"        self.flags(remove_externally_set_traits\u003dFalse, group\u003d\u0027compute\u0027)"},{"line_number":759,"context_line":"        compute_service \u003d self._start_compute(host)"},{"line_number":760,"context_line":""},{"line_number":761,"context_line":"        # get the provider UUID"},{"line_number":762,"context_line":"        rp_uuid \u003d self._get_provider_uuid_by_host(host)"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba6ce72a_4c841f0b","line":759,"range":{"start_line":756,"start_character":0,"end_line":759,"end_character":51},"in_reply_to":"922eb8c7_09f2f501","updated":"2026-02-25 17:23:24.000000000","message":"Acknowledged","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":753,"context_line":"        \"\"\""},{"line_number":754,"context_line":"        host \u003d \"fake-host\""},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"        # start nova-compute without provider config and with"},{"line_number":757,"context_line":"        # remove_externally_set_traits\u003dFalse"},{"line_number":758,"context_line":"        self.flags(remove_externally_set_traits\u003dFalse, group\u003d\u0027compute\u0027)"},{"line_number":759,"context_line":"        compute_service \u003d self._start_compute(host)"},{"line_number":760,"context_line":""},{"line_number":761,"context_line":"        # get the provider UUID"},{"line_number":762,"context_line":"        rp_uuid \u003d self._get_provider_uuid_by_host(host)"}],"source_content_type":"text/x-python","patch_set":10,"id":"922eb8c7_09f2f501","line":759,"range":{"start_line":756,"start_character":0,"end_line":759,"end_character":51},"in_reply_to":"bbd50f0e_51773079","updated":"2026-01-16 14:12:36.000000000","message":"I had explicitly specified it for clarity, but since it is the default, I removed self.flags().","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":765,"context_line":"        compute_service.stop()"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"        # create and set an external custom trait via placement API"},{"line_number":768,"context_line":"        external_trait \u003d \"CUSTOM_EXTERNAL_TRAIT\""},{"line_number":769,"context_line":"        self._create_trait(external_trait)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        existing_traits \u003d self._get_provider_traits(rp_uuid)"}],"source_content_type":"text/x-python","patch_set":10,"id":"168a8e58_8c323ff3","line":768,"updated":"2026-01-15 15:57:11.000000000","message":"It would be nice to add this to the tests above as well and assert that it is not changed during the reconfigurations.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"8c8227d894a4789859c011fda1ccc99c579700d5","unresolved":true,"context_lines":[{"line_number":765,"context_line":"        compute_service.stop()"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"        # create and set an external custom trait via placement API"},{"line_number":768,"context_line":"        external_trait \u003d \"CUSTOM_EXTERNAL_TRAIT\""},{"line_number":769,"context_line":"        self._create_trait(external_trait)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        existing_traits \u003d self._get_provider_traits(rp_uuid)"}],"source_content_type":"text/x-python","patch_set":10,"id":"8f39d52a_4aaf20c1","line":768,"in_reply_to":"168a8e58_8c323ff3","updated":"2026-01-16 14:12:36.000000000","message":"You’re right.\nI’ve also added external trait test to test_single_config_file_with_applied_config() and test_config_file_remove().","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":false,"context_lines":[{"line_number":765,"context_line":"        compute_service.stop()"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"        # create and set an external custom trait via placement API"},{"line_number":768,"context_line":"        external_trait \u003d \"CUSTOM_EXTERNAL_TRAIT\""},{"line_number":769,"context_line":"        self._create_trait(external_trait)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        existing_traits \u003d self._get_provider_traits(rp_uuid)"}],"source_content_type":"text/x-python","patch_set":10,"id":"369a0079_6d479429","line":768,"in_reply_to":"8f39d52a_4aaf20c1","updated":"2026-02-25 17:23:24.000000000","message":"Acknowledged","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"71d48ffa6038ce2b6ca5af5bfb7f970b09eb8e94","unresolved":true,"context_lines":[{"line_number":798,"context_line":"        self.assertIn(config_trait, actual_traits)"},{"line_number":799,"context_line":"        # CUSTOM_FAKE_HOST should also be present from config"},{"line_number":800,"context_line":"        self.assertIn(\"CUSTOM_FAKE_HOST\", actual_traits)"},{"line_number":801,"context_line":""},{"line_number":802,"context_line":"    def test_multiple_config_files(self):"},{"line_number":803,"context_line":"        \"\"\"This performs the same test as test_single_config_file but splits"},{"line_number":804,"context_line":"        the configurations into separate files."}],"source_content_type":"text/x-python","patch_set":10,"id":"a12ad2ab_22da5a44","line":801,"updated":"2026-01-15 15:57:11.000000000","message":"As a compute node can have more than one RP, e.g. it can have child RPs, could you add the following test scenarios?\n* compute has an additional child RP which has traits but the RP is not identified by any of the provider yamls. Therefore it is not changed.\n* compute has an additional child RP which is also managed by a provider.yaml file along with the compute node RP. Traits are correctly manged on both RPs\n* the compute has an additional child RP where **nova** placed traits (even CUSTOM traits) automatically (see a real example below). These traits that are applied by nova should never be removed by the new feature as the new feature should only remove traits that was added by provider yaml and then later removed from the provider yaml.\n\nExample of a complex provider tree is when nova handle PCI devices in placement (but also mdev GPUs are handled as child RPs in placement):\n* here is a functional test case that gives an example when nova creates children RPs with traits https://github.com/openstack/nova/blob/48cb769856e5eeea6d6fd906dd0053c667f92ab1/nova/tests/functional/libvirt/test_pci_in_placement.py#L208\n* here is a dump from my devstack env with PCI device managed in placement by nova: https://paste.opendev.org/show/bzwCibNxIWLCgNFp4jJM/","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":37390,"name":"Masanori Kuroha","display_name":"Masanori Kuroha","email":"mkuroha@lycorp.co.jp","username":"mkuroha"},"change_message_id":"7021a6810ac96a3a0571dc024a6cbc07078a2403","unresolved":true,"context_lines":[{"line_number":798,"context_line":"        self.assertIn(config_trait, actual_traits)"},{"line_number":799,"context_line":"        # CUSTOM_FAKE_HOST should also be present from config"},{"line_number":800,"context_line":"        self.assertIn(\"CUSTOM_FAKE_HOST\", actual_traits)"},{"line_number":801,"context_line":""},{"line_number":802,"context_line":"    def test_multiple_config_files(self):"},{"line_number":803,"context_line":"        \"\"\"This performs the same test as test_single_config_file but splits"},{"line_number":804,"context_line":"        the configurations into separate files."}],"source_content_type":"text/x-python","patch_set":10,"id":"38a93195_12e5d4ed","line":801,"in_reply_to":"a12ad2ab_22da5a44","updated":"2026-01-22 12:35:55.000000000","message":"I’ve added the test you suggested: `TestProviderConfigWithChildRP`.\nIf it doesn’t match what you had in mind, please let me know.","commit_id":"2251a67e4a33c5029b87f316569452f13d191c68"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f79ea5a3e0a419510d6e1a226447edac62b83394","unresolved":true,"context_lines":[{"line_number":509,"context_line":"        self.pconf_loc \u003d self.useFixture(fixtures.TempDir()).path"},{"line_number":510,"context_line":"        self.flags(provider_config_location\u003dself.pconf_loc, group\u003d\u0027compute\u0027)"},{"line_number":511,"context_line":"        self.applied_pconf_loc \u003d self.useFixture(fixtures.TempDir()).path"},{"line_number":512,"context_line":"        self.flags(applied_provider_config_location\u003dself.applied_pconf_loc,"},{"line_number":513,"context_line":"                    group\u003d\u0027compute\u0027)"},{"line_number":514,"context_line":"        self.flags(remove_externally_set_traits\u003dFalse, group\u003d\u0027compute\u0027)"},{"line_number":515,"context_line":""},{"line_number":516,"context_line":"    def _create_config_entry(self, id_value, id_method\u003d\"uuid\", cfg_file\u003dNone):"}],"source_content_type":"text/x-python","patch_set":12,"id":"17c24f3b_21717e16","line":513,"range":{"start_line":512,"start_character":0,"end_line":513,"end_character":36},"updated":"2026-02-25 17:23:24.000000000","message":"```suggestion\n        self.flags(applied_provider_config_location\u003dself.applied_pconf_loc,\n                   group\u003d\u0027compute\u0027)\n```","commit_id":"7fbe9e24478ce785409fd905d23f057adb4b0671"}]}
