)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9e8d3354c95011984de5fa3363af5455494b0f19","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"542055c2_85c815ec","updated":"2024-04-16 16:14:03.000000000","message":"rebased to get fresh CI results","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":6962,"name":"Kashyap Chamarthy","email":"kchamart@redhat.com","username":"kashyapc"},"change_message_id":"fe95f7f27770a2e43547951fc24b924278958a2f","unresolved":true,"context_lines":[{"line_number":10419,"context_line":"            cpu.cores \u003d info[\u0027topology\u0027][\u0027cores\u0027]"},{"line_number":10420,"context_line":"            cpu.threads \u003d info[\u0027topology\u0027][\u0027threads\u0027]"},{"line_number":10421,"context_line":"            for f in info[\u0027features\u0027]:"},{"line_number":10422,"context_line":"                cpu.add_feature(vconfig.LibvirtConfigCPUFeature(f))"},{"line_number":10423,"context_line":"        elif isinstance(guest_cpu, vconfig.LibvirtConfigGuestCPU):"},{"line_number":10424,"context_line":"            cpu \u003d guest_cpu"},{"line_number":10425,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"dc47b2d6_afc25559","side":"PARENT","line":10422,"updated":"2024-04-17 13:24:20.000000000","message":"Note to self: The above removal is not fully done.  However, we need to remove the above, and also the below two \u0027elif\u0027 and \u0027else\u0027 blocks and rework the code.\n\nWhy?  - I was told by libvirt maintainers that:\n\n- Nova is calling the libvirt\u0027s compareHypervisorCPU() API (via our wrapper methods) with a \"strange CPU definition\" rather than using the CPU definition from the domain XML.  The \"strange CPU definition\" is being created by this block that we\u0027re removing: https://github.com/openstack/nova/blob/a869ab17c095cbff2c942ab94247b0c30723b230/nova/virt/libvirt/driver.py#L9960-L9975\n\n- If Nova wants to compare CPU compatibility, fetch the CPU XML from the running guest, because that\u0027s what libvirt will actually use when migration is triggered","commit_id":"c199becf52267ba37c5191f6f82e29bb5232b607"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2f62dbf337a39e0863337b0603a4258b4e139b07","unresolved":true,"context_lines":[{"line_number":5589,"context_line":""},{"line_number":5590,"context_line":"        if not arch:"},{"line_number":5591,"context_line":"            caps \u003d self._host.get_domain_capabilities()"},{"line_number":5592,"context_line":"            arch \u003d caps.host.cpu.arch"},{"line_number":5593,"context_line":""},{"line_number":5594,"context_line":"        if ("},{"line_number":5595,"context_line":"            CONF.libvirt.virt_type \u003d\u003d \"kvm\" or"}],"source_content_type":"text/x-python","patch_set":3,"id":"361ab716_9aca8012","line":5592,"updated":"2024-04-17 07:00:47.000000000","message":"https://zuul.opendev.org/t/openstack/build/805040d3ce3b439cba4802c15c20f0c4/log/controller/logs/screen-n-cpu.txt#7986\n\n```\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager Traceback (most recent call last):\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/manager.py\", line 10581, in _update_available_resource_for_node\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     self.rt.update_available_resource(context, nodename,\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 935, in update_available_resource\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     self._update_available_resource(context, resources, startup\u003dstartup)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_concurrency/lockutils.py\", line 412, in inner\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     return f(*args, **kwargs)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1066, in _update_available_resource\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     self._update(context, cn, startup\u003dstartup)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1375, in _update\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     self._update_to_placement(context, compute_node, startup)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.10/site-packages/retrying.py\", line 56, in wrapped_f\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     return Retrying(*dargs, **dkw).call(f, *args, **kw)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.10/site-packages/retrying.py\", line 257, in call\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     return attempt.get(self._wrap_exception)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.10/site-packages/retrying.py\", line 301, in get\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     six.reraise(self.value[0], self.value[1], self.value[2])\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/usr/lib/python3/dist-packages/six.py\", line 719, in reraise\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     raise value\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/data/venv/lib/python3.10/site-packages/retrying.py\", line 251, in call\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     attempt \u003d Attempt(fn(*args, **kwargs), attempt_number, False)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/compute/resource_tracker.py\", line 1288, in _update_to_placement\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     self.driver.update_provider_tree(prov_tree, nodename)\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/virt/libvirt/driver.py\", line 9279, in update_provider_tree\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     t for t in self.static_traits if self.static_traits[t]\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/virt/libvirt/driver.py\", line 9346, in static_traits\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     traits.update(self._get_cpu_traits())\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/virt/libvirt/driver.py\", line 12889, in _get_cpu_traits\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     traits \u003d self._get_cpu_feature_traits()\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/virt/libvirt/driver.py\", line 12910, in _get_cpu_feature_traits\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     cpu \u003d self._get_guest_cpu_model_config()\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager   File \"/opt/stack/nova/nova/virt/libvirt/driver.py\", line 5592, in _get_guest_cpu_model_config\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager     arch \u003d caps.host.cpu.arch\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager AttributeError: \u0027collections.defaultdict\u0027 object has no attribute \u0027host\u0027\nApr 16 16:30:29.146817 np0037299212 nova-compute[74927]: ERROR nova.compute.manager\n```\n\nso the new function does not return the same data structure as the old.\n\n* get_domain_capabilities: https://github.com/openstack/nova/blob/c199becf52267ba37c5191f6f82e29bb5232b607/nova/virt/libvirt/host.py#L902-L905\n* get_capabilities: https://github.com/openstack/nova/blob/c199becf52267ba37c5191f6f82e29bb5232b607/nova/virt/libvirt/host.py#L790\n\nSo the old returned a single capability based on the host, the new one returns a capability for each architecture and machine type the hypervisor can emulate.","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"},{"author":{"_account_id":6962,"name":"Kashyap Chamarthy","email":"kchamart@redhat.com","username":"kashyapc"},"change_message_id":"fe95f7f27770a2e43547951fc24b924278958a2f","unresolved":true,"context_lines":[{"line_number":5589,"context_line":""},{"line_number":5590,"context_line":"        if not arch:"},{"line_number":5591,"context_line":"            caps \u003d self._host.get_domain_capabilities()"},{"line_number":5592,"context_line":"            arch \u003d caps.host.cpu.arch"},{"line_number":5593,"context_line":""},{"line_number":5594,"context_line":"        if ("},{"line_number":5595,"context_line":"            CONF.libvirt.virt_type \u003d\u003d \"kvm\" or"}],"source_content_type":"text/x-python","patch_set":3,"id":"68d0257f_ad8eb507","line":5592,"in_reply_to":"361ab716_9aca8012","updated":"2024-04-17 13:24:20.000000000","message":"Yeah, you\u0027re spot on.\n\n- get_capabilities() indeed returns a config.LibvirtConfigCaps object\n- while, get_domain_capabilities() returns \"a nested dict of dicts which maps architectures to machine types to instances of config.LibvirtConfigDomainCaps representing the domain capabilities of the host for that arch and machine type\": ``{arch:  machine_type: LibvirtConfigDomainCaps}{``\"\n\nSo, we need to figure out what exactly we want to fetch from the returned dict-of-dicts of get_domain_capabilities().","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a1971c9df86d2ddc5c64f0474329897c21019097","unresolved":true,"context_lines":[{"line_number":5589,"context_line":""},{"line_number":5590,"context_line":"        if not arch:"},{"line_number":5591,"context_line":"            caps \u003d self._host.get_domain_capabilities()"},{"line_number":5592,"context_line":"            arch \u003d caps.host.cpu.arch"},{"line_number":5593,"context_line":""},{"line_number":5594,"context_line":"        if ("},{"line_number":5595,"context_line":"            CONF.libvirt.virt_type \u003d\u003d \"kvm\" or"}],"source_content_type":"text/x-python","patch_set":3,"id":"f59c6aed_aac0a4d8","line":5592,"in_reply_to":"68d0257f_ad8eb507","updated":"2024-04-17 14:11:03.000000000","message":"I suggest to map out how this _get_guest_cpu_model_config() is called. Especially looking for why arch is optional. If we have an arch passed that can be used to filter the returned dict from get_domain_capabilities(). If that is done then you need to figure out what is the machine type to use. For start we have https://docs.openstack.org/nova/latest/configuration/config.html#libvirt.hw_machine_type as a default per arch, but the guest can override that via the an image property see https://docs.openstack.org/nova/latest/admin/hw-machine-type.html","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"a8e1f284afbb2c610435bfbf356bfd373f8fa3d7","unresolved":true,"context_lines":[{"line_number":10411,"context_line":"        else:"},{"line_number":10412,"context_line":"            cpu \u003d self._vcpu_model_to_cpu_config(guest_cpu)"},{"line_number":10413,"context_line":""},{"line_number":10414,"context_line":"        host_cpu \u003d self._host.get_domain_capabilities().host.cpu"},{"line_number":10415,"context_line":"        if host_cpu.arch \u003d\u003d fields.Architecture.AARCH64:"},{"line_number":10416,"context_line":"            LOG.debug(\"On AArch64 hosts, source and destination host \""},{"line_number":10417,"context_line":"                      \"CPUs are compared to check if they\u0027re compatible\""}],"source_content_type":"text/x-python","patch_set":3,"id":"f738b841_69dece79","line":10414,"updated":"2024-04-17 13:42:52.000000000","message":"As Gibi mentioned the output of get_domain_capabilities() is not the same as get_capabilities so it can not be used as is.\nAlso this needs to be transformed in a LibvirtConfigCPU object to be then serialized in XML for compare_hypervisor_cpu\n\n\nI think we have 2 possible options: either, as suggested by Kashyap, adapt all the methods that need get_capabilities() and change all related CPU information to info coming from get_domain_capabilities().\n\nOr \n\nMaybe we can change the get_cababilities() wrapper, keeping the same structure but replacing the CPU-related data with the ones coming from get_domain_capabilities().\nI think it could be less code-intensive; however, the blast radius will be larger as all methods using the wrapper will be impacted in one shot.\n\nWe need to discuss that. In the meantime, as discussed with Kashyap I will try to get the output of get_capabilities() and get_domain_capabilities() to have a better view of the data structure provided by these methods.","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3f3810a9068911f307eadc69149d375ce1946688","unresolved":true,"context_lines":[{"line_number":10411,"context_line":"        else:"},{"line_number":10412,"context_line":"            cpu \u003d self._vcpu_model_to_cpu_config(guest_cpu)"},{"line_number":10413,"context_line":""},{"line_number":10414,"context_line":"        host_cpu \u003d self._host.get_domain_capabilities().host.cpu"},{"line_number":10415,"context_line":"        if host_cpu.arch \u003d\u003d fields.Architecture.AARCH64:"},{"line_number":10416,"context_line":"            LOG.debug(\"On AArch64 hosts, source and destination host \""},{"line_number":10417,"context_line":"                      \"CPUs are compared to check if they\u0027re compatible\""}],"source_content_type":"text/x-python","patch_set":3,"id":"e310c438_58f296dc","line":10414,"in_reply_to":"f738b841_69dece79","updated":"2024-04-17 14:12:18.000000000","message":"the issue with option two is domain cap is like cap but for each supported arch and machine type, so the code need to select one cap out of a set of caps now.","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"a8e1f284afbb2c610435bfbf356bfd373f8fa3d7","unresolved":true,"context_lines":[{"line_number":10415,"context_line":"        if host_cpu.arch \u003d\u003d fields.Architecture.AARCH64:"},{"line_number":10416,"context_line":"            LOG.debug(\"On AArch64 hosts, source and destination host \""},{"line_number":10417,"context_line":"                      \"CPUs are compared to check if they\u0027re compatible\""},{"line_number":10418,"context_line":"                      \"(the only use-case supported by libvirt for \""},{"line_number":10419,"context_line":"                      \"Arm64/AArch64)\")"},{"line_number":10420,"context_line":"            cpu \u003d host_cpu"},{"line_number":10421,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"25ca5454_82fc2f04","line":10418,"updated":"2024-04-17 13:42:52.000000000","message":"Is this still true ? I guess not, so we may get rid of this code too.","commit_id":"00dabd3d39f7046daf921e09f041d95c7a8038fb"}]}
