)]}'
{"placement/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"752e034ff984f276e75639c97878e354657eb905","unresolved":false,"context_lines":[{"line_number":609,"context_line":"        an exception."},{"line_number":610,"context_line":"        \"\"\""},{"line_number":611,"context_line":"        rp \u003d self._create_provider(\u0027compute-host\u0027)"},{"line_number":612,"context_line":"        inv \u003d inv_obj.Inventory("},{"line_number":613,"context_line":"            rp._context, resource_provider\u003drp,"},{"line_number":614,"context_line":"            resource_class\u003d\u0027UNKNOWN\u0027,"},{"line_number":615,"context_line":"            total\u003d1024,"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfbec78f_bb51f664","line":612,"updated":"2019-05-09 20:02:49.000000000","message":"note to reviewers: Because I added ensure_rc to add_inventory, this was throwing a different error, so I peeled it apart to get the intended effect.","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"}],"placement/tests/functional/fixtures/gabbits.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2ea82f7b92965fccff7e6d5b00c2b77e42ea7706","unresolved":false,"context_lines":[{"line_number":390,"context_line":"    +---------+--------+ +---------+--------+      |                   |"},{"line_number":391,"context_line":"    | numa0            | | numa1            |      |       +-----------+------+"},{"line_number":392,"context_line":"    | HW_NUMA_ROOT     | | HW_NUMA_ROOT     |      |       | ovs_agent        |"},{"line_number":393,"context_line":"    | VCPU: 4 (2 used) | | VCPU: 4          |      |       | VNIC_TYPE_NORMAL |"},{"line_number":394,"context_line":"    | MEMORY_MB: 2048  | | MEMORY_MB: 2048  |      |       +-----------+------+"},{"line_number":395,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":396,"context_line":"        |          |         |          |      | sriov_agent      |    |"}],"source_content_type":"text/x-python","patch_set":1,"id":"dfbec78f_f526d1b7","line":393,"range":{"start_line":393,"start_character":61,"end_line":393,"end_character":77},"updated":"2019-05-07 06:13:41.000000000","message":"I don\u0027t know if what is the intention here. Do we want to simulate how bandwidth is modeled today? VNIC_TYPE_* traits are on the device RP today because a numbered group is generated from a port and a numbered group will be match to exactly one RP today.","commit_id":"89d65734614cf0aedb47af204c5ca00ace6f46f3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"89ea9b4c0990d81c135cd4fb73d83a5074565ee9","unresolved":false,"context_lines":[{"line_number":390,"context_line":"    +---------+--------+ +---------+--------+      |                   |"},{"line_number":391,"context_line":"    | numa0            | | numa1            |      |       +-----------+------+"},{"line_number":392,"context_line":"    | HW_NUMA_ROOT     | | HW_NUMA_ROOT     |      |       | ovs_agent        |"},{"line_number":393,"context_line":"    | VCPU: 4 (2 used) | | VCPU: 4          |      |       | VNIC_TYPE_NORMAL |"},{"line_number":394,"context_line":"    | MEMORY_MB: 2048  | | MEMORY_MB: 2048  |      |       +-----------+------+"},{"line_number":395,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":396,"context_line":"        |          |         |          |      | sriov_agent      |    |"}],"source_content_type":"text/x-python","patch_set":1,"id":"dfbec78f_14358c46","line":393,"range":{"start_line":393,"start_character":61,"end_line":393,"end_character":77},"in_reply_to":"dfbec78f_ab7316e7","updated":"2019-05-08 16:29:44.000000000","message":"\u003e I took this from one of your emails in the \"resourceless providers\"\n \u003e thread (can find the link when I\u0027m back at my desk).\n\nhttp://lists.openstack.org/pipermail/openstack-discuss/2019-April/005111.html (about halfway down).","commit_id":"89d65734614cf0aedb47af204c5ca00ace6f46f3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"6bab76e43b40999f0c516182ceb85c77f96cf862","unresolved":false,"context_lines":[{"line_number":390,"context_line":"    +---------+--------+ +---------+--------+      |                   |"},{"line_number":391,"context_line":"    | numa0            | | numa1            |      |       +-----------+------+"},{"line_number":392,"context_line":"    | HW_NUMA_ROOT     | | HW_NUMA_ROOT     |      |       | ovs_agent        |"},{"line_number":393,"context_line":"    | VCPU: 4 (2 used) | | VCPU: 4          |      |       | VNIC_TYPE_NORMAL |"},{"line_number":394,"context_line":"    | MEMORY_MB: 2048  | | MEMORY_MB: 2048  |      |       +-----------+------+"},{"line_number":395,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":396,"context_line":"        |          |         |          |      | sriov_agent      |    |"}],"source_content_type":"text/x-python","patch_set":1,"id":"dfbec78f_ab7316e7","line":393,"range":{"start_line":393,"start_character":61,"end_line":393,"end_character":77},"in_reply_to":"dfbec78f_f526d1b7","updated":"2019-05-07 10:49:52.000000000","message":"I took this from one of your emails in the \"resourceless providers\" thread (can find the link when I\u0027m back at my desk). If there\u0027s some other shape that makes sense, let me know. But the point is really to be able to test something like direct+physnet0+bw landing on esn1, and a) not on br-int because not vnic type normal; and b) succeeds even though the agent rp doesn\u0027t provide any resources.","commit_id":"89d65734614cf0aedb47af204c5ca00ace6f46f3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f5f415bb8f4846e9f84144fd0f3cc0547fade794","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    | numa0            | | numa1            |      |       +-----------+------+"},{"line_number":392,"context_line":"    | HW_NUMA_ROOT     | | HW_NUMA_ROOT     |      |       | ovs_agent        |"},{"line_number":393,"context_line":"    | VCPU: 4 (2 used) | | VCPU: 4          |      |       | VNIC_TYPE_NORMAL |"},{"line_number":394,"context_line":"    | MEMORY_MB: 2048  | | MEMORY_MB: 2048  |      |       +-----------+------+"},{"line_number":395,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":396,"context_line":"        |          |         |          |      | sriov_agent      |    |"},{"line_number":397,"context_line":"    +---+---+  +---+---+ +---+---+  +---+---+  | VNIC_TYPE_DIRECT |    |"}],"source_content_type":"text/x-python","patch_set":1,"id":"dfbec78f_0b31020c","line":394,"range":{"start_line":394,"start_character":38,"end_line":394,"end_character":42},"updated":"2019-05-07 10:51:26.000000000","message":"Note to self: add step sizes etc to make can_split more interesting","commit_id":"89d65734614cf0aedb47af204c5ca00ace6f46f3"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"580cbe44cd3374ee1ccacc0cb067db26f10c2f22","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    | numa0            | | numa1            |      |       +-----------+------+"},{"line_number":392,"context_line":"    | HW_NUMA_ROOT     | | HW_NUMA_ROOT     |      |       | ovs_agent        |"},{"line_number":393,"context_line":"    | VCPU: 4 (2 used) | | VCPU: 4          |      |       | VNIC_TYPE_NORMAL |"},{"line_number":394,"context_line":"    | MEMORY_MB: 2048  | | MEMORY_MB: 2048  |      |       +-----------+------+"},{"line_number":395,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":396,"context_line":"        |          |         |          |      | sriov_agent      |    |"},{"line_number":397,"context_line":"    +---+---+  +---+---+ +---+---+  +---+---+  | VNIC_TYPE_DIRECT |    |"}],"source_content_type":"text/x-python","patch_set":1,"id":"dfbec78f_57878110","line":394,"range":{"start_line":394,"start_character":38,"end_line":394,"end_character":42},"in_reply_to":"dfbec78f_0b31020c","updated":"2019-05-08 23:19:50.000000000","message":"Done","commit_id":"89d65734614cf0aedb47af204c5ca00ace6f46f3"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e694cb971cad2e505169fab3b38fdf3c586a592c","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfbec78f_fe4d1b72","line":471,"updated":"2019-05-09 21:19:41.000000000","message":"This one raises an interesting point. The defaults for step_size and min_unit are 1.  When we can_split, we\u0027ll need to split on the max of min_unit, step_size and some arbitrary lower limit that we set.\n\nWhich is computationally possible, but that arbitrary lower limit has different reasonable numbers from one resource class to another.\n\nDo we:\n\n* make sure (in nova) that nova does the right thing when creating inventory that can be split\n* have some kind of placement side static set of default step_sizes (or secondary limits)\n* same, but in conf (noooooo !)\n* something else\n\nAt the moment this only has a pressing use case for VCPU and MEMORY_MB so I\u0027m inclined to think that it is up to the client to manage the protections as best it can. Putting that kind of protection logic in placement itself (except for max(min_unit, step_size)) is an endless game.","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"7aa6c752acb944c34a53aa62afa6ecb3e71f0514","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"9fb8cfa7_0894d143","line":471,"in_reply_to":"bfb3d3c7_32f2a69b","updated":"2019-06-03 12:26:03.000000000","message":"Based on the email thread, it looks like Option 0 has legs\n\nhttp://lists.openstack.org/pipermail/openstack-discuss/2019-May/006726.html","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"2b43eb0b8f1712591d33acf57183c5d0d80c7a8e","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfb3d3c7_ed7b1378","line":471,"in_reply_to":"bfb3d3c7_7ffa70bd","updated":"2019-05-24 23:19:22.000000000","message":"\u003e The issue with limiting things at the time of inventory create\n\nAgree we should not enforce anything at inventory create.\n\n \u003e However, when can_split is called we can know that we don\u0027t want an\n \u003e explosion so we should control it then\n\nThis.\n\n \u003e Another option is to let the explosion happen and write a warning\n\n+1\n\n \u003e Presumably when can_split is implemented on the nova_side it will a\n \u003e request filter and have a config setting?\n\nI\u0027m thinking initially we\u0027ll just add can_split\u003dVCPU,MEMORY_MB automatically to any request whose flavor doesn\u0027t specify a numa topology. Can\u0027t think of a reason to make it any more complex than that.\n\n \u003e \"hey if you\u0027re gonna\n \u003e can_split you need to manage your step_size on resource class X\n \u003e better\".\n\nA quick look reveals that we should manage our step_size on resource class MEMORY_MB better, immediately. Ironic is okay because they just use their single-unit custom resource class, but:\n\n- libvirt [1], vmware [2], and xenapi [3] have 1s explicitly.\n- powervm [4] has 1s implicitly (unspecified therefore defaults). (IIRC Power actually has the equivalent of a real min_unit/step_size that it could expose. [Later] Yes, there\u0027s a min and max; and step_size is called \"logical memory block size\" [5]. But today it\u0027s just checking this and failing during spawn.)\n- hyperv and zvm still use the get_available_resource path, which hits compute_node_to_inventory_dict, which uses 1s [6].\n\nOther than powervm, I have no idea how to figure a reasonable step_size.\n\n[1] https://opendev.org/openstack/nova/src/branch/master/nova/virt/libvirt/driver.py#L6738-L6740\n[2] https://opendev.org/openstack/nova/src/branch/master/nova/virt/vmwareapi/driver.py#L505-L507\n[3] https://opendev.org/openstack/nova/src/branch/master/nova/virt/xenapi/driver.py#L504-L506\n[4] https://opendev.org/openstack/nova/src/branch/master/nova/virt/powervm/driver.py#L225-L229\n[5] https://github.com/powervm/pypowervm/blob/master/pypowervm/utils/lpar_builder.py#L659-L671\n[6] https://opendev.org/openstack/nova/src/branch/master/nova/compute/utils.py#L1401-L1403","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"9d7f6b0d9b0e0e3eab7b94ab5b9a25a1bad5ae89","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfb3d3c7_32f2a69b","line":471,"in_reply_to":"bfb3d3c7_8061f1d5","updated":"2019-05-29 22:15:27.000000000","message":"For the sake of completeness, another idea is to punt the \"what is an appropriate chunk size\" problem to the caller by allowing an optional :$chunk_size syntax on can_split, like:\n\n ...\u0026can_split\u003dVCPU,MEMORY_MB:1024\n\nbecause it seems to me like there will be more opportunities for the caller to be able to figure this out in a way that makes sense to it.\n\n(FTR, my current order of preference is 0) don\u0027t implement can_split.)","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"1b6f8b74a9931b7a527f40f46f540a74c999a974","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfb3d3c7_7ffa70bd","line":471,"in_reply_to":"bfb3d3c7_d29b5463","updated":"2019-05-24 13:58:28.000000000","message":"The issue with limiting things at the time of inventory create is that we cannot predict (nor should we limit) what a client of placement wants with regard to min_unit etc. Some client which is not nova could very reasonably create something with an inventory of 1 million and a min_unit and step_size of 1. We can\u0027t and don\u0027t want to know.\n\nHowever, when can_split is called we can know that we don\u0027t want an explosion so we should control it then, either by magic algorithms (eric\u0027s idea), or by rejecting the query if we encounter poorly managed inventory (gibi\u0027s latter idea).\n\nAnother option is to let the explosion happen and write a warning log while it is in progress of the form \"hey if you\u0027re gonna can_split you need to manage your step_size on resource class X better\".\n\nPresumably when can_split is implemented on the nova_side it will a request filter and have a config setting?","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f8a250ee51633d9cc9e90a2b42c0e6eaeaa7d752","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfb3d3c7_8061f1d5","line":471,"in_reply_to":"bfb3d3c7_ed7b1378","updated":"2019-05-27 10:04:36.000000000","message":"My current order of preference of possible solutions:\n1) cdent\u0027s log a warning and allow placement to blow up solution - as a first iteration as this is the easiest to add\n2) gibi\u0027s reject can_split if it would lead to explosion due to poorly managed min_unit / step_size in inventories\n3) efried\u0027s algorithm to select a reasonable min_unit / step_size on placement side it is is poorly managed on the inventory client side","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"a553154e668078c2120a75dc46bd4bd10abac7ba","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfbec78f_e15d7ce9","line":471,"in_reply_to":"dfbec78f_de3e17d9","updated":"2019-05-09 22:24:34.000000000","message":"\u003e  Due to carefully-selected min_unit,\n \u003e step_size, and max_unit values in the fixture, it only yields four\n \u003e permutations instead of thousands.\n\nThis captures the main point I was trying to make. If people are careful, things work fine but history suggests that people are not always careful.\n\nI agree that doing some factoring based on size (independent of resource class) is a reasonable guard.\n\nSo yeah, pretty much agree with everything else you say, just felt obliged to get the concern down before it escaped.\n\n \u003e of chunks we\u0027d like to shoot for. 16 seems non-crazy. (And in fact\n \u003e *this* number could be presented as a conf-able.)\n\nCould be, but mostly meh until someone comes along to say whatever good number we have chosen is terrible. I\u0027m wed to the idea of placement working well in nearly all contexts with effectively no config, except for the database string. Until it doesn\u0027t.","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9e380907ce7f35fa98bb560fb6ae3d17d61a04b0","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"bfb3d3c7_d29b5463","line":471,"in_reply_to":"dfbec78f_e15d7ce9","updated":"2019-05-24 12:47:14.000000000","message":"I think placement should not invent a magic calculation to guess a good step_size and min_unit. But I agree that placement should not explode when unreasonable step_size and min_unit is in the inventory. I think we have to guard placement at the point when the inventory is set. If the inventory resource amount is a bigger than like 100 (or 1000) but the step_size and the min_unit is not specified (or defaulted to 1) then placement can simply reject the inventory creation as such an inventory causes allocation candidate explosion.\n\nMore precisely if possible_steps(amount, steps_size, min_unit) \u003e explosion_level (explosion level can be hardcoded to like 1000 or configured in placement.conf) then reject the inventory creation.\n\nAlternatively we can accept such inventory creation as if can_split is never used in the allocaton_candidate queries then there is no explosion. BUT we can outright reject the allocaton_candidate query that has can_split on a resource class that has unreasonable inventory present. (This alternative is more complex to implement in placement)","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"434a0eb0e4af6f0f3f078a14c778898b45b8d234","unresolved":false,"context_lines":[{"line_number":468,"context_line":"        tb.add_inventory("},{"line_number":469,"context_line":"            numas[0], orc.MEMORY_MB, 2048, min_unit\u003d512, step_size\u003d256)"},{"line_number":470,"context_line":"        tb.add_inventory("},{"line_number":471,"context_line":"            numas[1], orc.MEMORY_MB, 2048, min_unit\u003d256, max_unit\u003d1024)"},{"line_number":472,"context_line":"        user, proj \u003d tb.create_user_and_project(self.context, prefix\u003d\u0027numafx\u0027)"},{"line_number":473,"context_line":"        consumer \u003d tb.ensure_consumer(self.context, user, proj)"},{"line_number":474,"context_line":"        tb.set_allocation(self.context, numas[0], consumer, {orc.VCPU: 2})"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfbec78f_de3e17d9","line":471,"in_reply_to":"dfbec78f_fe4d1b72","updated":"2019-05-09 22:14:17.000000000","message":"\u003e When we can_split, we\u0027ll need to split on the\n\u003e max of min_unit, step_size and some arbitrary lower limit that we\n\u003e set.\n\nNot exactly. Putting aside \"arbitrary lower limit\" for a sec, in the general case we need to split on:\n\n min_unit + (N*step_size)] for N\u003d0..*\n\nuntil that computation reaches/exceeds the amount requested or available for the particular inventory. More completely:\n\n # Allow for getting all from elsewhere\n chunk_sizes \u003d [0]\n chunk_size \u003d min_unit\n while chunk_size \u003c min(requested_size, available_amount):\n     chunk_sizes.append(chunk_size)\n     chunk_size +\u003d step_size\n\n...and then we need to find all permutations where those add up to exactly requested_size for groupings of providers that otherwise meet the necessary criteria.\n\nIf you look at the next patch, I have an example that demonstrates what the *result* of this should look like given the fixture\u0027s inventory settings [1]. Due to carefully-selected min_unit, step_size, and max_unit values in the fixture, it only yields four permutations instead of thousands.\n\n \u003e Which is computationally possible, but that arbitrary lower limit\n \u003e has different reasonable numbers from one resource class to\n \u003e another.\n\nYeah, just so. And it feels pretty wrong for placement to be in the business of trying to ascertain that lower limit based on the resource class. Because that means placement is in the business of knowing things about resource classes other than what it\u0027s told. Like, today there\u0027s no significance or difference to placement between MEMORY_MB, VCPU, and CUSTOM_WIDGET when it comes to inventory. And I would really, really like it to stay that way.\n\n \u003e * make sure (in nova) that nova does the right thing when creating\n \u003e inventory that can be split\n\nYes, and...\n\n \u003e * have some kind of placement side static set of default step_sizes\n \u003e (or secondary limits)\n\n-1 to static, but see below\n\n \u003e * same, but in conf (noooooo !)\n\n-0.5, but see below\n\n \u003e * something else\n\nSo I\u0027m thinking this boils down to us choosing \"reasonable\" values for min_unit and step_size in the above algorithm when they\u0027re not otherwise specified. For purposes of keeping can_split sane while preserving blissful ignorance of resource class semantics, I think we ought to try to do it algorithmically based on the size of the inventory and/or requested amount. Something like:\n\n- Find the range we\u0027re dealing with: requested_amount - (real_min_unit or 0)\n- Factor that number ^\n- Pick the smaller factor closest to some arbitrary maximum number of chunks we\u0027d like to shoot for. 16 seems non-crazy. (And in fact *this* number could be presented as a conf-able.)\n- Divide the range by that factor. Use this for step_size, and also for min_unit if that was unset\n\nTheoretically the factoring could go crazy, but in realistic scenarios we\u0027re either going to be talking about small numbers (like for VCPU) where we actually do want the factor to be 1; or MEMORY_MB amounts which tend to be nice even numbers, if not actual powers of two, and quite likely to be divisible by 16.\n\n \u003e At the moment this only has a pressing use case for VCPU and\n \u003e MEMORY_MB so I\u0027m inclined to think that it is up to the client to\n \u003e manage the protections as best it can. Putting that kind of\n \u003e protection logic in placement itself (except for max(min_unit,\n \u003e step_size)) is an endless game.\n\nAgree completely. There are some obvious simple optimizations we can put in before we start splitting (such as excluding hosts right away if their total available across all RPs is too low), but I\u0027d be on board with punting on the above craziness until it proves to be an actual problem.\n\n[1] https://review.opendev.org/#/c/658192/1/placement/tests/functional/gabbits/allocation-candidates-can-split.yaml@66","commit_id":"bb36ad195580ffc95b79b371f5478065684d0c60"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"40ad403880192665a6202631f153e019443d76e6","unresolved":false,"context_lines":[{"line_number":390,"context_line":"                          | COMPUTE_VOLUME_MULTI_ATTACH |"},{"line_number":391,"context_line":"                          |      (no inventory)         |"},{"line_number":392,"context_line":"                          |        agg: [aggA]          |"},{"line_number":393,"context_line":"                          +---------------+-------------+"},{"line_number":394,"context_line":"                                          |"},{"line_number":395,"context_line":"              +--------------------+------+--------+-------------------+"},{"line_number":396,"context_line":"              |                    |               |                   |"}],"source_content_type":"text/x-python","patch_set":4,"id":"bfb3d3c7_a462623d","line":393,"updated":"2019-05-21 16:13:02.000000000","message":"I\u0027m doing some experimenting on making https://review.opendev.org/#/c/657510/ go, using this fixture as the starting point. While confirming things I absently wanted to use the following query:\n\n          GET: /allocation_candidates?resources\u003dVCPU:1\u0026required\u003dCOMPUTE_VOLUME_MULTI_ATTACH\n\nThis currently returns no results because traits don\u0027t flow down. Remove the required, we get the expected 3 different allocation_requests because inventory flows up.\n\nI think I recall Eric suggesting that we could avoid \"flow down\" in some fashion, but I\u0027m failing to see what the incantation would be here unless we are saying \"can_split\" should a) be always used in a case like this, b) means traits flow down. I don\u0027t know that we want that.\n\nPresumably we want the above query to work without modification (by nova-scheduler or any other caller). That\u0027s a fairly \"normal\" request \"give me some cpu from a host that supports multi attach\".\n\nThoughts?","commit_id":"dd28e5f02fc15afaa8a30353b5db8784b1b0fcf4"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"6dfff7861d246c919176e1a8cc51a3a62814514c","unresolved":false,"context_lines":[{"line_number":390,"context_line":"                          | COMPUTE_VOLUME_MULTI_ATTACH |"},{"line_number":391,"context_line":"                          |      (no inventory)         |"},{"line_number":392,"context_line":"                          |        agg: [aggA]          |"},{"line_number":393,"context_line":"                          +---------------+-------------+"},{"line_number":394,"context_line":"                                          |"},{"line_number":395,"context_line":"              +--------------------+------+--------+-------------------+"},{"line_number":396,"context_line":"              |                    |               |                   |"}],"source_content_type":"text/x-python","patch_set":4,"id":"bfb3d3c7_85cf18af","line":393,"in_reply_to":"bfb3d3c7_a462623d","updated":"2019-05-21 18:13:31.000000000","message":"\u003e GET: /allocation_candidates?resources\u003dVCPU:1\u0026required\u003dCOMPUTE_VOLUME_MULTI_ATTACH\n\nMy take was that this comes for free as part of \"resourceless providers\". The only reason it doesn\u0027t work today is because we insist that the provider satisfying the trait *also* be providing some resource.\n\nClearly you\u0027ve done the right thing (however absently) by adding this as a test case :)\n\nNote that the same is not true for\n\n GET: /allocation_candidates?resources_FOO\u003dVCPU:1\u0026required_FOO\u003dCOMPUTE_VOLUME_MULTI_ATTACH\n\nbecause granular groups have to be satisfied by one provider. (can_split_FOO intentionally omitted from this example.)","commit_id":"dd28e5f02fc15afaa8a30353b5db8784b1b0fcf4"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ff31885314e4d37a031a4a534c171cd2ef07451a","unresolved":false,"context_lines":[{"line_number":461,"context_line":"        for i in (0, 1):"},{"line_number":462,"context_line":"            numa \u003d tb.create_provider("},{"line_number":463,"context_line":"                self.context, \u0027numa%d\u0027 % i, parent\u003dcn1.uuid)"},{"line_number":464,"context_line":"            traits \u003d ot.HW_NUMA_ROOT"},{"line_number":465,"context_line":"            if i \u003d\u003d 1:"},{"line_number":466,"context_line":"                traits.append(\u0027CUSTOM_FOO\u0027)"},{"line_number":467,"context_line":"            tb.set_traits(numa, *traits)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fb8cfa7_b2b270e5","line":464,"updated":"2019-06-07 16:02:08.000000000","message":"This should be [ot.HW_NUMA_ROOT]","commit_id":"3578c8c54f5b938ec472586cdb298451b83a538d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"3a9c20f9327ca879344c0f5f2b92c3cdd8182bfa","unresolved":false,"context_lines":[{"line_number":461,"context_line":"        for i in (0, 1):"},{"line_number":462,"context_line":"            numa \u003d tb.create_provider("},{"line_number":463,"context_line":"                self.context, \u0027numa%d\u0027 % i, parent\u003dcn1.uuid)"},{"line_number":464,"context_line":"            traits \u003d ot.HW_NUMA_ROOT"},{"line_number":465,"context_line":"            if i \u003d\u003d 1:"},{"line_number":466,"context_line":"                traits.append(\u0027CUSTOM_FOO\u0027)"},{"line_number":467,"context_line":"            tb.set_traits(numa, *traits)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fb8cfa7_b544951c","line":464,"in_reply_to":"9fb8cfa7_b2b270e5","updated":"2019-06-07 20:40:45.000000000","message":"whoops, yah, thanks.","commit_id":"3578c8c54f5b938ec472586cdb298451b83a538d"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f9e9778a884593dc09f5a94692d3302898bfea67","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    |   step_size: 256 | |   max_unit: 1024 |      |                   |"},{"line_number":404,"context_line":"    +---+----------+---+ +---+----------+---+  +---+--------------+    |"},{"line_number":405,"context_line":"        |          |         |          |      | sriov_agent      |    |"},{"line_number":406,"context_line":"    +---+---+  +---+---+ +---+---+  +---+---+  | VNIC_TYPE_DIRECT |    |"},{"line_number":407,"context_line":"    |fpga0  |  |pgpu0  | |fpga1_0|  |fpga1_1|  +---+--------------+    |"},{"line_number":408,"context_line":"    |FPGA:1 |  |VGPU:8 | |FPGA:1 |  |FPGA:1 |      |                   |"},{"line_number":409,"context_line":"    +-------+  +-------+ +-------+  +-------+      |              +----+------+"}],"source_content_type":"text/x-python","patch_set":14,"id":"9fb8cfa7_dd6010d2","line":406,"range":{"start_line":406,"start_character":48,"end_line":406,"end_character":65},"updated":"2019-06-12 12:45:40.000000000","message":"Just a note: today the vnic_type trait is pushed down to the device RPs to simplify the port resource request.","commit_id":"88b6c816a846276e2476a4d5594499cd303d26ad"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f9e9778a884593dc09f5a94692d3302898bfea67","unresolved":false,"context_lines":[{"line_number":440,"context_line":"    |NET1 |   |NET2 |      |NET1 |   |NET2 |   |NET1 |   |NET2 |     |NET1 |"},{"line_number":441,"context_line":"    |VF:4 |   |VF:4 |      |VF:2 |   |VF:2 |   |VF:2 |   |VF:2 |     |VF:8 |"},{"line_number":442,"context_line":"    +-----+   +-----+      +-----+   +-----+   +-----+   +-----+     +-----+"},{"line_number":443,"context_line":"    \"\"\""},{"line_number":444,"context_line":"    def start_fixture(self):"},{"line_number":445,"context_line":"        super(NUMANetworkFixture, self).start_fixture()"},{"line_number":446,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"9fb8cfa7_b8cd2a32","line":443,"updated":"2019-06-12 12:45:40.000000000","message":"I dumped the generated trees to dot [1] [2] and crosschecked this description with the generated content. As far as I see it matches.\n\n[1] https://ibb.co/MkcTh5X\n[2] https://review.opendev.org/#/c/664878","commit_id":"88b6c816a846276e2476a4d5594499cd303d26ad"}]}
