)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"f2258946_a7d539b5","updated":"2026-01-08 19:07:52.000000000","message":"Two things it would need to run downstream would be the addition of sudo in some of the ssh commands and the ability to configure where the provider.yaml is set on the computes.  I was able to confirm with those changes the tests can run downstream.  The other comments are not as critical for me and more suggestions.","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"}],"whitebox_tempest_plugin/api/compute/test_provider_yaml.py":[{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":true,"context_lines":[{"line_number":53,"context_line":"        # saving provider.yaml to any other location and updating"},{"line_number":54,"context_line":"        # the path to nova.conf or nova-cpu.conf should work."},{"line_number":55,"context_line":"        # but it does not work as of now."},{"line_number":56,"context_line":"        self.provider_config_location \u003d \"/etc/nova/provider_config\""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"        # Trait names for testing provider.yaml functionality"},{"line_number":59,"context_line":"        # These are just identifiers - the actual host assignment"}],"source_content_type":"text/x-python","patch_set":4,"id":"1c393618_b33b5990","line":56,"updated":"2026-01-08 19:07:52.000000000","message":"Downstream this is stored in a different directory so this would need to be a whitebox configurable parameter (I was able to test this downstream and confirm changing the path works)","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"795d149c61581126f786f4a42cbd5bf2a4fa9baf","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        # saving provider.yaml to any other location and updating"},{"line_number":54,"context_line":"        # the path to nova.conf or nova-cpu.conf should work."},{"line_number":55,"context_line":"        # but it does not work as of now."},{"line_number":56,"context_line":"        self.provider_config_location \u003d \"/etc/nova/provider_config\""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"        # Trait names for testing provider.yaml functionality"},{"line_number":59,"context_line":"        # These are just identifiers - the actual host assignment"}],"source_content_type":"text/x-python","patch_set":4,"id":"34f123a7_6dc77a4f","line":56,"in_reply_to":"1c393618_b33b5990","updated":"2026-01-13 04:07:15.000000000","message":"Done","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":true,"context_lines":[{"line_number":101,"context_line":"        template \u003d template.replace(\"CUSTOM_trait_placeholder\", trait)"},{"line_number":102,"context_line":"        template \u003d yaml.dump(yaml.safe_load(template))"},{"line_number":103,"context_line":"        ssh_client \u003d clients.SSHClient(target_host)"},{"line_number":104,"context_line":"        cmd \u003d f\"mkdir -p {self.provider_config_location}\""},{"line_number":105,"context_line":"        ssh_client.execute(cmd)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        cmd \u003d f\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5e445b4f_e5a0f9e2","line":104,"updated":"2026-01-08 19:07:52.000000000","message":"Downstream we can\u0027t access the computes as a root user so we would need a sudo here to preform the command.","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"bb4208e9a81109331670368714467f8c0919d52f","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        template \u003d template.replace(\"CUSTOM_trait_placeholder\", trait)"},{"line_number":102,"context_line":"        template \u003d yaml.dump(yaml.safe_load(template))"},{"line_number":103,"context_line":"        ssh_client \u003d clients.SSHClient(target_host)"},{"line_number":104,"context_line":"        cmd \u003d f\"mkdir -p {self.provider_config_location}\""},{"line_number":105,"context_line":"        ssh_client.execute(cmd)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        cmd \u003d f\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"100a36a1_13bbe334","line":104,"in_reply_to":"5e445b4f_e5a0f9e2","updated":"2026-01-13 17:22:42.000000000","message":"Done","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":true,"context_lines":[{"line_number":104,"context_line":"        cmd \u003d f\"mkdir -p {self.provider_config_location}\""},{"line_number":105,"context_line":"        ssh_client.execute(cmd)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        cmd \u003d f\"\"\""},{"line_number":108,"context_line":"        echo \"{template}\" \u003e {self.provider_config_location}/provider.yaml\"\"\""},{"line_number":109,"context_line":"        ssh_client.execute(cmd.strip())"},{"line_number":110,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"885adefd_e6e344fd","line":107,"updated":"2026-01-08 19:07:52.000000000","message":"Same as above this would need sudo e.g.:\ncmd \u003d f\"\"\"\n        echo \"{template}\" | sudo tee {self.provider_config_location}/provider.yaml\"\"\"","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"795d149c61581126f786f4a42cbd5bf2a4fa9baf","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        cmd \u003d f\"mkdir -p {self.provider_config_location}\""},{"line_number":105,"context_line":"        ssh_client.execute(cmd)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        cmd \u003d f\"\"\""},{"line_number":108,"context_line":"        echo \"{template}\" \u003e {self.provider_config_location}/provider.yaml\"\"\""},{"line_number":109,"context_line":"        ssh_client.execute(cmd.strip())"},{"line_number":110,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"50d40e92_811593c3","line":107,"in_reply_to":"885adefd_e6e344fd","updated":"2026-01-13 04:07:15.000000000","message":"Done","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        echo \"{template}\" \u003e {self.provider_config_location}/provider.yaml\"\"\""},{"line_number":109,"context_line":"        ssh_client.execute(cmd.strip())"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _create_custom_trait_flavor(self, trait):"},{"line_number":112,"context_line":"        \"\"\"Creates a flavor that has given trait"},{"line_number":113,"context_line":"        \"\"\""},{"line_number":114,"context_line":"        specs \u003d {f\"trait: {trait}\": \"required\"}"}],"source_content_type":"text/x-python","patch_set":4,"id":"10a8fe34_f6bb8aca","line":111,"updated":"2026-01-08 19:07:52.000000000","message":"I don\u0027t have a strong preference one way or another but normally we are able to create unique flavors just leveraging the base flavor method instead of creating a new method e.g.: \nhttps://opendev.org/openstack/whitebox-tempest-plugin/src/branch/master/whitebox_tempest_plugin/api/compute/test_sriov.py#L108 -\u003e\nhttps://opendev.org/openstack/whitebox-tempest-plugin/src/branch/master/whitebox_tempest_plugin/api/compute/test_sriov.py#L290","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"795d149c61581126f786f4a42cbd5bf2a4fa9baf","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        echo \"{template}\" \u003e {self.provider_config_location}/provider.yaml\"\"\""},{"line_number":109,"context_line":"        ssh_client.execute(cmd.strip())"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _create_custom_trait_flavor(self, trait):"},{"line_number":112,"context_line":"        \"\"\"Creates a flavor that has given trait"},{"line_number":113,"context_line":"        \"\"\""},{"line_number":114,"context_line":"        specs \u003d {f\"trait: {trait}\": \"required\"}"}],"source_content_type":"text/x-python","patch_set":4,"id":"a73b93a9_3de2bc2e","line":111,"in_reply_to":"10a8fe34_f6bb8aca","updated":"2026-01-13 04:07:15.000000000","message":"yesh, initially I thought of using in many places in same test it was in 3 places only - so can be inlined.\n\ndone.","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":31033,"name":"James Parker","email":"jparker@redhat.com","username":"jparker"},"change_message_id":"ad1fc2c3f310394d4c29fb29772f204bba25a74d","unresolved":true,"context_lines":[{"line_number":124,"context_line":"        flavor_a \u003d self._create_custom_trait_flavor(self.trait_a)"},{"line_number":125,"context_line":"        server1 \u003d self.create_test_server("},{"line_number":126,"context_line":"            flavor\u003dflavor_a[\u0027id\u0027], wait_until\u003d\"ACTIVE\")"},{"line_number":127,"context_line":"        self.assertEqual(self.get_host_for_server(server1[\u0027id\u0027]), self.host2)"},{"line_number":128,"context_line":"        # create second guest for same trait,"},{"line_number":129,"context_line":"        # and it should be spawned in same host"},{"line_number":130,"context_line":"        server2 \u003d self.create_test_server("}],"source_content_type":"text/x-python","patch_set":4,"id":"703c4779_a4ad037c","line":127,"updated":"2026-01-08 19:07:52.000000000","message":"I think it would be nice to have a check to verify the trait is present and correct in the guest metadata \u003cnova:extraSpecs\u003e XML:\n  \u003cmetadata\u003e\n    \u003cnova:instance xmlns:nova\u003d\"http://openstack.org/xmlns/libvirt/nova/1.1\"\u003e\n      \u003cnova:package version\u003d\"27.5.2-18.0.20251210234725.c1c6d67.el9osttrunk\"/\u003e\n      ...\n      \u003cnova:flavor name\u003d\"tempest-TestProviderYamlViaTraits-flavor-1982732635\" id\u003d\"391845834\"\u003e\n        \u003cnova:memory\u003e64\u003c/nova:memory\u003e\n        \u003cnova:disk\u003e1\u003c/nova:disk\u003e\n        \u003cnova:swap\u003e0\u003c/nova:swap\u003e\n        \u003cnova:ephemeral\u003e0\u003c/nova:ephemeral\u003e\n        \u003cnova:vcpus\u003e2\u003c/nova:vcpus\u003e\n        \u003cnova:extraSpecs\u003e\n          \u003cnova:extraSpec name\u003d\"trait: CUSTOM_WB_TRAIT_A\"\u003erequired\u003c/nova:extraSpec\u003e\n        \u003c/nova:extraSpecs\u003e\n      \u003c/nova:flavor\u003e\nI know the scheduling helps confirm this, but I always like to trust but verify. We do this currently here as well for generic flavor metadata: https://opendev.org/openstack/whitebox-tempest-plugin/src/branch/master/whitebox_tempest_plugin/api/compute/test_flavor_metadata.py#L27","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"795d149c61581126f786f4a42cbd5bf2a4fa9baf","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        flavor_a \u003d self._create_custom_trait_flavor(self.trait_a)"},{"line_number":125,"context_line":"        server1 \u003d self.create_test_server("},{"line_number":126,"context_line":"            flavor\u003dflavor_a[\u0027id\u0027], wait_until\u003d\"ACTIVE\")"},{"line_number":127,"context_line":"        self.assertEqual(self.get_host_for_server(server1[\u0027id\u0027]), self.host2)"},{"line_number":128,"context_line":"        # create second guest for same trait,"},{"line_number":129,"context_line":"        # and it should be spawned in same host"},{"line_number":130,"context_line":"        server2 \u003d self.create_test_server("}],"source_content_type":"text/x-python","patch_set":4,"id":"e6770de3_e9928b9b","line":127,"in_reply_to":"703c4779_a4ad037c","updated":"2026-01-13 04:07:15.000000000","message":"Done","commit_id":"16181fb8764977fd5698dc25cc85bc79f7b4156b"},{"author":{"_account_id":34860,"name":"Amit Uniyal","email":"auniyal@redhat.com","username":"auniyal"},"change_message_id":"bb4208e9a81109331670368714467f8c0919d52f","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        cmd \u003d f\u0027echo \"{template}\" \u003e {temp_file}\u0027"},{"line_number":137,"context_line":"        ssh_client.execute(cmd)"},{"line_number":138,"context_line":"        # Move temp file to final location with sudo"},{"line_number":139,"context_line":"        cmd \u003d f\"mv {temp_file} {self.provider_config_location}/provider.yaml\""},{"line_number":140,"context_line":"        ssh_client.execute(cmd, sudo\u003dTrue)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def test_valid_trait_with_provider_yaml(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"c21e0982_98b57c5f","line":139,"updated":"2026-01-13 17:22:42.000000000","message":"was getting permission denied in local test with direct redirection - went with buffer var, this is not harmful.","commit_id":"c42c0a6fe555e45d8bad4dd567a652453513d713"}]}
