)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"238a8b3cc17e801dd649b09855d8b7f5ec4a290a","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This blueprint proposes to specify forbidden aggregates in the `member_of`"},{"line_number":10,"context_line":"query parameter of the `GET /allocation_candidates` placement API."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Depends-On: https://review.openstack.org/#/c/603352"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I1a94f50d42e57ff9d746e2f160a89dfab1978894"},{"line_number":15,"context_line":"Implements: blueprint placement-req-filter-forbidden-aggregates"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"5fc1f717_362f4789","line":12,"range":{"start_line":12,"start_character":12,"end_line":12,"end_character":51},"updated":"2019-04-05 05:42:10.000000000","message":"This spec (and implementation) have been merged.\nSo this line can be removed.","commit_id":"9d53e3493e8eab6077cf3bf2af8724d7796ff6e5"}],"specs/stein/approved/placement-req-filter-forbidden-aggregates.rst":[{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"ab24e15a26c7b653e86a3d5c9f785a30298c33b5","unresolved":false,"context_lines":[{"line_number":217,"context_line":"References"},{"line_number":218,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":".. _negative-aggregate-membership: https://review.openstack.org/#/c/603352/4/specs/stein/approved/negative-aggregate-membership.rst"}],"source_content_type":"text/x-rst","patch_set":1,"id":"3f79a3b5_c1435810","line":220,"range":{"start_line":220,"start_character":0,"end_line":220,"end_character":131},"updated":"2018-10-15 01:40:59.000000000","message":"nit: I cannot see any references in this section. It should be fixed.\n\nhttp://logs.openstack.org/60/609960/1/check/openstack-tox-docs/49d8583/html/specs/stein/approved/placement-req-filter-forbidden-aggregates.html","commit_id":"0fa658045bc179df1ef8155320dd8452787e95f2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":11,"context_line":"https://blueprints.launchpad.net/nova/+spec/placement-req-filter-forbidden-aggregates"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This blueprint proposes to specify forbidden aggregates in the `member_of`"},{"line_number":14,"context_line":"query parameter of the `GET /allocation_candidates` placement API."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Problem description"},{"line_number":17,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_64083624","line":14,"range":{"start_line":14,"start_character":65,"end_line":14,"end_character":66},"updated":"2018-11-27 20:59:17.000000000","message":"nit: \"during scheduling.\"","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":11,"context_line":"https://blueprints.launchpad.net/nova/+spec/placement-req-filter-forbidden-aggregates"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This blueprint proposes to specify forbidden aggregates in the `member_of`"},{"line_number":14,"context_line":"query parameter of the `GET /allocation_candidates` placement API."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Problem description"},{"line_number":17,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_8e865a0e","line":14,"range":{"start_line":14,"start_character":65,"end_line":14,"end_character":66},"in_reply_to":"3f79a3b5_64083624","updated":"2018-12-05 02:35:43.000000000","message":"I will fix this in next PS.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":23,"context_line":"special ones like `Licensed Windows Compute Host`, meaning any VM booted on"},{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_e42526ae","line":26,"range":{"start_line":26,"start_character":62,"end_line":26,"end_character":63},"updated":"2018-11-27 20:59:17.000000000","message":"``","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":23,"context_line":"special ones like `Licensed Windows Compute Host`, meaning any VM booted on"},{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_4e904242","line":26,"range":{"start_line":26,"start_character":62,"end_line":26,"end_character":63},"in_reply_to":"3f79a3b5_e42526ae","updated":"2018-12-05 02:35:43.000000000","message":"I will fix this in next PS.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":19,"context_line":"If flavor or image doesn\u0027t contain any ``required`` or ``forbidden``"},{"line_number":20,"context_line":"traits, then all resource providers will be eligible to be returned in the"},{"line_number":21,"context_line":"``GET /allocation_candidates`` API call depending on the availability of the"},{"line_number":22,"context_line":"requested resources. Some of the resource providers (compute host) could be"},{"line_number":23,"context_line":"special ones like `Licensed Windows Compute Host`, meaning any VM booted on"},{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_598ac31d","line":27,"range":{"start_line":22,"start_character":21,"end_line":27,"end_character":56},"updated":"2018-11-27 20:59:17.000000000","message":"Can you confirm my assertion in the dependent spec on this use case and the limitations in existing filters today:\n\nhttps://review.openstack.org/#/c/603352/7/specs/stein/approved/negative-aggregate-membership.rst@156","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_042ce291","line":27,"range":{"start_line":27,"start_character":14,"end_line":27,"end_character":20},"updated":"2018-11-27 20:59:17.000000000","message":"Do you mean to say \"traits\" here or \"aggregates\" because this spec is really about forbidden aggregates, not traits.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_aca4654e","line":27,"range":{"start_line":27,"start_character":14,"end_line":27,"end_character":20},"in_reply_to":"3f79a3b5_042ce291","updated":"2018-12-05 02:35:43.000000000","message":"I meant to say avoid booting images/volumes without special custom `required`` or ``forbidden`` traits on aggregates which contains ``Licensed Windows Compute Hosts``.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":19,"context_line":"If flavor or image doesn\u0027t contain any ``required`` or ``forbidden``"},{"line_number":20,"context_line":"traits, then all resource providers will be eligible to be returned in the"},{"line_number":21,"context_line":"``GET /allocation_candidates`` API call depending on the availability of the"},{"line_number":22,"context_line":"requested resources. Some of the resource providers (compute host) could be"},{"line_number":23,"context_line":"special ones like `Licensed Windows Compute Host`, meaning any VM booted on"},{"line_number":24,"context_line":"this compute host will be considered as licensed Windows image and depending"},{"line_number":25,"context_line":"on the usage of VM operators will charge it to their end-users. As an operator,"},{"line_number":26,"context_line":"I want to avoid booting images/volumes without special custom `required`` or"},{"line_number":27,"context_line":"``forbidden`` traits on `Licensed Windows Compute Host`."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_4c7831c1","line":27,"range":{"start_line":22,"start_character":21,"end_line":27,"end_character":56},"in_reply_to":"3f79a3b5_598ac31d","updated":"2018-12-05 02:35:43.000000000","message":"Done","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"This feature is useful to save special resources for specific users"},{"line_number":33,"context_line":"as listed in specs `negative-aggregate-membership`_ `in Use Case 1`."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"Proposed change"},{"line_number":36,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_443bbac7","line":33,"range":{"start_line":32,"start_character":0,"end_line":33,"end_character":68},"updated":"2018-11-27 20:59:17.000000000","message":"nit: rather than link to another spec, just copy the use case here.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":29,"context_line":"Use Cases"},{"line_number":30,"context_line":"---------"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"This feature is useful to save special resources for specific users"},{"line_number":33,"context_line":"as listed in specs `negative-aggregate-membership`_ `in Use Case 1`."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"Proposed change"},{"line_number":36,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_aed796f3","line":33,"range":{"start_line":32,"start_character":0,"end_line":33,"end_character":68},"in_reply_to":"3f79a3b5_443bbac7","updated":"2018-12-05 02:35:43.000000000","message":"I will fix this in next PS.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":35,"context_line":"Proposed change"},{"line_number":36,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Add a new placement request filter ``forbidden_aggregates`` and a new config"},{"line_number":39,"context_line":"option of type list ``query_placement_special_traits``. Operator will set"},{"line_number":40,"context_line":"special custom traits to this config option which are assigned to the special"},{"line_number":41,"context_line":"resource providers like ``Licensed Windows Compute Host``. In the new"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_446e5a97","line":38,"updated":"2018-11-27 20:59:17.000000000","message":"This actually sounds very much like a variant of the existing IsolatedHostsFilter:\n\nhttps://docs.openstack.org/nova/latest/admin/configuration/schedulers.html#isolatedhostsfilter\n\nExcept it:\n\n1. Relies on aggregates rather than individual hosts (which won\u0027t scale in large environments like a public cloud).\n\n2. Relies on image properties rather than specific image IDs, which again won\u0027t scale.\n\nIt might be worth working in how this compares/contrasts to the IsolatedHostsFilter, at least in the Alternatives section, for completeness. It could even potentially supersede the IsolatedHostsFilter so we could eventually deprecate that filter (I\u0027m not sure who uses that filter anyway, I would think maybe only smaller private clouds).","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":36,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Add a new placement request filter ``forbidden_aggregates`` and a new config"},{"line_number":39,"context_line":"option of type list ``query_placement_special_traits``. Operator will set"},{"line_number":40,"context_line":"special custom traits to this config option which are assigned to the special"},{"line_number":41,"context_line":"resource providers like ``Licensed Windows Compute Host``. In the new"},{"line_number":42,"context_line":"request filter, it will get the required traits set in both flavor and images"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_84a1d2a9","line":39,"range":{"start_line":39,"start_character":38,"end_line":39,"end_character":45},"updated":"2018-11-27 20:59:17.000000000","message":"This seems too generic for how it\u0027s going to be used. If this is tied to some exclusion filtering with forbidden aggregates, I would expect the name to have something about forbidden aggregates in it.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":42,"context_line":"request filter, it will get the required traits set in both flavor and images"},{"line_number":43,"context_line":"from request_spec object and compare it with the"},{"line_number":44,"context_line":"``query_placement_special_traits`` to create a list of non-matching traits."},{"line_number":45,"context_line":"Then, it will create a list of aggregates which we want placement service to"},{"line_number":46,"context_line":"ignore by ``GET /allocation_candidates`` API by comparing non-matching traits"},{"line_number":47,"context_line":"with each aggregate metadata with key `required:traits`. This list of"},{"line_number":48,"context_line":"forbidden aggregates will be set in `Destination` object in a new attribute"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_44c09a7d","line":45,"range":{"start_line":45,"start_character":23,"end_line":45,"end_character":41},"updated":"2018-11-27 20:59:17.000000000","message":"So, the placement request filter itself is going to create nova host aggregates on the fly?","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"ignore by ``GET /allocation_candidates`` API by comparing non-matching traits"},{"line_number":47,"context_line":"with each aggregate metadata with key `required:traits`. This list of"},{"line_number":48,"context_line":"forbidden aggregates will be set in `Destination` object in a new attribute"},{"line_number":49,"context_line":"`forbidden_aggregates`."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"For example `query_placement_special_traits` would be set if operator wants to"},{"line_number":52,"context_line":"enable ``forbidden_aggregates`` placement request filter:"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_84c23287","line":49,"updated":"2018-11-27 20:59:17.000000000","message":"See below, but this is a lot of heavy text. If you want to leave it that\u0027s fine, but please replace the implementation details with an actual step through of the things that need to be done to solve the most basic scenario for the use case, i.e. what does the operator need to do to make this all work. The implementation will be driven off of that.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":54,"context_line":".. code::"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"  [scheduler]"},{"line_number":57,"context_line":"  query_placement_special_traits \u003d CUSTOM_WINDOWS_LICENSED_TRAITS, CUSTOM_XYZ"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"Changes to the Destination class:"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_24b79ed3","line":57,"updated":"2018-11-27 20:59:17.000000000","message":"So if I want to restrict my windows licensed image to a windows licensed host, I need to:\n\n* configure this option in nova.conf on the scheduler with CUSTOM_WINDOWS_LICENSED_TRAITS (the _TRAITS suffix is redundant here by the way)\n* add my windows licensed host to an aggregate with metadata key \"required:traits\" and value...CUSTOM_WINDOWS_LICENSED_TRAITS?\n* configure the windows licensed image to have trait:CUSTOM_WINDOWS_LICENSED_TRAITS\u003drequired?\n\nIf so, how is that any different from what we have today with using required traits? The aggregate wrinkle?\n\nAlso, how does that exclude non-windows licensed images from being selected for my windows licensed hosts in that aggregate?","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":56,"context_line":"  [scheduler]"},{"line_number":57,"context_line":"  query_placement_special_traits \u003d CUSTOM_WINDOWS_LICENSED_TRAITS, CUSTOM_XYZ"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"Changes to the Destination class:"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":".. code::"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"  class Destination(base.NovaObject):"},{"line_number":64,"context_line":"    ..."},{"line_number":65,"context_line":"    fields \u003d {"},{"line_number":66,"context_line":"        ..."},{"line_number":67,"context_line":"        \u0027aggregates\u0027: fields.ListOfStringsField(nullable\u003dTrue, default\u003dNone),"},{"line_number":68,"context_line":"      + \u0027forbidden_aggregates\u0027: fields.ListOfStringsField(nullable\u003dTrue,"},{"line_number":69,"context_line":"                                                          default\u003dNone)"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"Modify ``resources_from_request_spec`` method to add forbidden aggregates to"},{"line_number":73,"context_line":"the `nova.api.openstack.placement.RequestGroup` in a new attribute"},{"line_number":74,"context_line":"`forbidden_member_of`. Finally, modify `to_querystring` method of"},{"line_number":75,"context_line":"`RequestGroup` to generate query parameter `member_of` passing forbidden"},{"line_number":76,"context_line":"aggregates which will be supported in the `negative-aggregate-membership`_"},{"line_number":77,"context_line":"specs."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"Changes to the nova.api.openstack.placement.RequestGroup class"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":".. code::"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"  class RequestGroup(object):"},{"line_number":84,"context_line":"    def __init__(self, use_same_provider\u003dTrue, resources\u003dNone,"},{"line_number":85,"context_line":"                 required_traits\u003dNone, forbidden_traits\u003dNone, member_of\u003dNone,"},{"line_number":86,"context_line":"                 forbidden_member_of\u003dNone):"},{"line_number":87,"context_line":"        ...."},{"line_number":88,"context_line":"        :param member_of: A list of [ [aggregate_UUID],"},{"line_number":89,"context_line":"                                      [aggregate_UUID, aggregate_UUID] ... ]"},{"line_number":90,"context_line":"      + :param forbidden_member_of: A list of [ [aggregate_UUID],"},{"line_number":91,"context_line":"                                      [aggregate_UUID, aggregate_UUID] ... ]"},{"line_number":92,"context_line":"        self.member_of \u003d member_of or []"},{"line_number":93,"context_line":"      + self.forbidden_member_of \u003d forbidden_member_of or []"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"or"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":".. code::"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"  class RequestGroup(object):"},{"line_number":100,"context_line":"    def __init__(self, use_same_provider\u003dTrue, resources\u003dNone,"},{"line_number":101,"context_line":"                 required_traits\u003dNone, forbidden_traits\u003dNone, member_of\u003dNone):"},{"line_number":102,"context_line":"        ...."},{"line_number":103,"context_line":"        :param member_of: A Dict of list"},{"line_number":104,"context_line":"                           {"},{"line_number":105,"context_line":"                            \"required\" : [[aggregate1_UUID],"},{"line_number":106,"context_line":"                                [aggregate2_UUID, aggregate3_UUID]],"},{"line_number":107,"context_line":"                            \"forbidden\" : [[aggregate4_UUID],"},{"line_number":108,"context_line":"                                [aggregate5_UUID]]"},{"line_number":109,"context_line":"                           }"},{"line_number":110,"context_line":"        ..."},{"line_number":111,"context_line":"        self.member_of \u003d member_of or []"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":".. note:: Operator will need to synchronize nova host aggregates with"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_64d27661","line":111,"range":{"start_line":59,"start_character":0,"end_line":111,"end_character":40},"updated":"2018-11-27 20:59:17.000000000","message":"I don\u0027t really care to see this amount of low level implementation detail in the spec. What I would really like to see is a step by step walk through of a couple of scenarios in which this would be used. The initial paragraph in this section is hard for me to follow, especially while trying to keep the use case in mind. I would rather see that stepped through for the most basic case of restricting windows licensed images to windows licensed hosts while excluding non-windows licensed images from those hosts (since as I\u0027ve noted elsewhere in here I believe the problem with the existing AggregateImagePropertiesIsolation filter is that it doesn\u0027t exclude other images from landing on the restricted hosts).","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":56,"context_line":"  [scheduler]"},{"line_number":57,"context_line":"  query_placement_special_traits \u003d CUSTOM_WINDOWS_LICENSED_TRAITS, CUSTOM_XYZ"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"Changes to the Destination class:"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":".. code::"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"  class Destination(base.NovaObject):"},{"line_number":64,"context_line":"    ..."},{"line_number":65,"context_line":"    fields \u003d {"},{"line_number":66,"context_line":"        ..."},{"line_number":67,"context_line":"        \u0027aggregates\u0027: fields.ListOfStringsField(nullable\u003dTrue, default\u003dNone),"},{"line_number":68,"context_line":"      + \u0027forbidden_aggregates\u0027: fields.ListOfStringsField(nullable\u003dTrue,"},{"line_number":69,"context_line":"                                                          default\u003dNone)"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"Modify ``resources_from_request_spec`` method to add forbidden aggregates to"},{"line_number":73,"context_line":"the `nova.api.openstack.placement.RequestGroup` in a new attribute"},{"line_number":74,"context_line":"`forbidden_member_of`. Finally, modify `to_querystring` method of"},{"line_number":75,"context_line":"`RequestGroup` to generate query parameter `member_of` passing forbidden"},{"line_number":76,"context_line":"aggregates which will be supported in the `negative-aggregate-membership`_"},{"line_number":77,"context_line":"specs."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"Changes to the nova.api.openstack.placement.RequestGroup class"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":".. code::"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"  class RequestGroup(object):"},{"line_number":84,"context_line":"    def __init__(self, use_same_provider\u003dTrue, resources\u003dNone,"},{"line_number":85,"context_line":"                 required_traits\u003dNone, forbidden_traits\u003dNone, member_of\u003dNone,"},{"line_number":86,"context_line":"                 forbidden_member_of\u003dNone):"},{"line_number":87,"context_line":"        ...."},{"line_number":88,"context_line":"        :param member_of: A list of [ [aggregate_UUID],"},{"line_number":89,"context_line":"                                      [aggregate_UUID, aggregate_UUID] ... ]"},{"line_number":90,"context_line":"      + :param forbidden_member_of: A list of [ [aggregate_UUID],"},{"line_number":91,"context_line":"                                      [aggregate_UUID, aggregate_UUID] ... ]"},{"line_number":92,"context_line":"        self.member_of \u003d member_of or []"},{"line_number":93,"context_line":"      + self.forbidden_member_of \u003d forbidden_member_of or []"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"or"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":".. code::"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"  class RequestGroup(object):"},{"line_number":100,"context_line":"    def __init__(self, use_same_provider\u003dTrue, resources\u003dNone,"},{"line_number":101,"context_line":"                 required_traits\u003dNone, forbidden_traits\u003dNone, member_of\u003dNone):"},{"line_number":102,"context_line":"        ...."},{"line_number":103,"context_line":"        :param member_of: A Dict of list"},{"line_number":104,"context_line":"                           {"},{"line_number":105,"context_line":"                            \"required\" : [[aggregate1_UUID],"},{"line_number":106,"context_line":"                                [aggregate2_UUID, aggregate3_UUID]],"},{"line_number":107,"context_line":"                            \"forbidden\" : [[aggregate4_UUID],"},{"line_number":108,"context_line":"                                [aggregate5_UUID]]"},{"line_number":109,"context_line":"                           }"},{"line_number":110,"context_line":"        ..."},{"line_number":111,"context_line":"        self.member_of \u003d member_of or []"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":".. note:: Operator will need to synchronize nova host aggregates with"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_cc3d21e7","line":111,"range":{"start_line":59,"start_character":0,"end_line":111,"end_character":40},"in_reply_to":"3f79a3b5_64d27661","updated":"2018-12-05 02:35:43.000000000","message":"I will remove all low level implementation in the next PS.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":116,"context_line":"          `member_of` query parameter of the `GET /allocation_candidates`"},{"line_number":117,"context_line":"          API using below `nova-manage` command:"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"           ``nova-manage placement sync_aggregates``"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"          Also, operator will need to set aggregate metadata key"},{"line_number":122,"context_line":"          `required:traits` with comma separated values specifying multiple"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_e4b9a6ea","line":119,"updated":"2018-11-27 20:59:17.000000000","message":"Well, this is really more of an upgrade impact detail, because this is for synchronizing existing nova host aggregates to placement. Starting in Rocky, aggregate membership changes (add/remove hosts to/from aggregates) is mirrored in the compute API, see:\n\nhttps://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/placement-mirror-host-aggregates.html","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"           ``nova-manage placement sync_aggregates``"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"          Also, operator will need to set aggregate metadata key"},{"line_number":122,"context_line":"          `required:traits` with comma separated values specifying multiple"},{"line_number":123,"context_line":"          traits which they expect to match with the `required:traits` set"},{"line_number":124,"context_line":"          in the flavor and images of the create server request."},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"Alternatives"},{"line_number":127,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_04e70212","line":124,"range":{"start_line":121,"start_character":10,"end_line":124,"end_character":64},"updated":"2018-11-27 20:59:17.000000000","message":"This won\u0027t scale since the aggregate metadata row value is limited to 255 characters:\n\nhttps://github.com/openstack/nova/blob/8545ba2af7476e0884b5e7fb90965bef92d605bc/nova/db/sqlalchemy/api_models.py#L71\n\nThat\u0027s one of the main issues with the AggregateMultiTenancyIsolation filter:\n\nhttps://docs.openstack.org/nova/latest/admin/configuration/schedulers.html#aggregatemultitenancyisolation\n\nWhich was solved with this in Rocky:\n\nhttps://docs.openstack.org/nova/latest/admin/configuration/schedulers.html#tenant-isolation-with-placement\n\nNote the part about using a suffix on the metadata key to workaround the length restriction.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"d9074ddcbfe423acf7373afc8e4d768d0422817a","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"           ``nova-manage placement sync_aggregates``"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"          Also, operator will need to set aggregate metadata key"},{"line_number":122,"context_line":"          `required:traits` with comma separated values specifying multiple"},{"line_number":123,"context_line":"          traits which they expect to match with the `required:traits` set"},{"line_number":124,"context_line":"          in the flavor and images of the create server request."},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"Alternatives"},{"line_number":127,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_ac522536","line":124,"range":{"start_line":121,"start_character":10,"end_line":124,"end_character":64},"in_reply_to":"3f79a3b5_04e70212","updated":"2018-12-05 02:35:43.000000000","message":"Agree. Thank you for pointing it out.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"We can create nova scheduler filters to do post-processing of compute hosts"},{"line_number":130,"context_line":"by looking at host aggregate relationships. However, this is inefficient."},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"Data model impact"},{"line_number":133,"context_line":"-----------------"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_99e05bcc","line":131,"updated":"2018-11-27 20:59:17.000000000","message":"There have been at least a couple of other alternative specs for this same problem, right?\n\nhttps://review.openstack.org/#/c/593475/\n\nhttps://review.openstack.org/#/c/381912/\n\nI think it would be good to mention those and why this is a preferred solution using placement (being more generic and not relying on encoding exclusivity information in traits).\n\nI would also expect at least some mention of the AggregateImagePropertiesIsolation filter in this spec since that exists today for restricting window license images to windows license host aggregates, but the problem is it does not exclude other images from those same hosts, e.g. I could land a linux VM on one of those hosts and (1) waste licensing resources and (2) potentially charge a user more for where their VM is hosted even though it doesn\u0027t need to be hosted there.\n\nAlso a reminder about the mention of the IsolatedHostsFilter from above.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[{"line_number":180,"context_line":"Upgrade impact"},{"line_number":181,"context_line":"--------------"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"None."},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"Implementation"},{"line_number":186,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_e403e673","line":183,"updated":"2018-11-27 20:59:17.000000000","message":"This is likely where you need to call out the sync_aggregates command.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"daa5dd7e58e028a0e7955dbedcf173868e5b284c","unresolved":false,"context_lines":[{"line_number":222,"context_line":""},{"line_number":223,"context_line":"References"},{"line_number":224,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":".. _negative-aggregate-membership: https://review.openstack.org/#/c/603352/4/specs/stein/approved/negative-aggregate-membership.rst"}],"source_content_type":"text/x-rst","patch_set":2,"id":"3f79a3b5_05efd5fb","line":225,"updated":"2018-11-29 15:21:57.000000000","message":"Could probably also refer to bug 1677217.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b0d0055c98fd0fd00030a0e39b17f7298fb324b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"3f79a3b5_c4002a6c","line":227,"updated":"2018-11-27 20:59:17.000000000","message":"nit: missing the History section from the template.","commit_id":"b38eb982d448beff4aae935146f9db5998c25df7"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"725841498155c78d64008dbc7e39294a26c721a0","unresolved":false,"context_lines":[{"line_number":77,"context_line":"Operator will need to set aggregate metadata key `required:traits\u003cnumber\u003e`"},{"line_number":78,"context_line":"with traits which they expect to match with the `required:traits` set in the"},{"line_number":79,"context_line":"flavor and images of the create server request. If you want to add multiple"},{"line_number":80,"context_line":"traits keep incrementing the number in the metadata key."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"Example to set multiple required:traits in metadata of an aggregate."},{"line_number":83,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"1f769fc5_245f3b0f","line":80,"updated":"2019-01-02 16:29:12.000000000","message":"Can you explain in a bit more detail why traits are being used like this here? It makes me think of placement traits but that\u0027s not actually happening here is it?","commit_id":"985bf6718f0a015723473c2663095c6f05ffaea2"}],"specs/train/approved/placement-req-filter-forbidden-aggregates.rst":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9276527b53003e12201ee52a7361a05f67ffb00a","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"  openstack aggregate set --property required:traits1\u003dCUSTOM_WINDOWS_LICENSED \u003caggregate_uuid\u003e"},{"line_number":87,"context_line":"  openstack aggregate set --property required:traits2\u003dCUSTOM_XYZ \u003caggregate_uuid\u003e"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"Operator will need to set ``required:traits`` to images for windows OS"},{"line_number":90,"context_line":"images."},{"line_number":91,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_5824420d","line":88,"updated":"2019-04-09 11:27:46.000000000","message":"Why do we have different syntax for this in flavor and in aggregate? The flavor uses trait:\u003ctrait_name\u003e\u003drequired while this proposal proposes required:trait\u003d\u003ctrait_name\u003e for aggregates. Can we have the same syntax here as well?\n\nAlso please note that in the flavor \"trait1\" means a trait for the numbered request group 1 while \"trait1\" in the aggregate will have totally different meaning. This can be confusing for the user of these APIs.","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"08239f52bf45a09a3325505292b35a28037adcca","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"  openstack aggregate set --property required:traits1\u003dCUSTOM_WINDOWS_LICENSED \u003caggregate_uuid\u003e"},{"line_number":87,"context_line":"  openstack aggregate set --property required:traits2\u003dCUSTOM_XYZ \u003caggregate_uuid\u003e"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"Operator will need to set ``required:traits`` to images for windows OS"},{"line_number":90,"context_line":"images."},{"line_number":91,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_cc93904e","line":88,"in_reply_to":"5fc1f717_5824420d","updated":"2019-04-09 14:03:59.000000000","message":"I agree the syntax should be consistent to avoid user confusion. \nIt\u0027s possible to specify \u003ctrait_name\u003e\u003drequired  syntax in aggregate metadata.\n\nI will make this change in the next PS.","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9276527b53003e12201ee52a7361a05f67ffb00a","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_d8f4b25d","line":101,"updated":"2019-04-09 11:27:46.000000000","message":"Why we need the extra config? Isn\u0027t this information the same as the information proposed in the aggregate metadata ?","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"0eeef658438ff51b709b22a82b0263dbabdba740","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"3fce034c_a066ad28","line":101,"in_reply_to":"3fce034c_4e9e3664","updated":"2019-04-16 09:12:22.000000000","message":"Yes. If an aggregate has a required trait in the metadata then that aggregate will be forbidden for the requests that does not has the same required trait in the request.","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"518ba2901ef371bbbb5651a04543cd3587a23f75","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_a3516132","line":101,"in_reply_to":"5fc1f717_040f28e0","updated":"2019-04-10 02:10:50.000000000","message":"Maybe there is something that\u0027s not clear to me about RequestGroup.\n\nThis is how I\u0027m planning to get the list of aggregates which should be excluded by getallocationcandidates API.\n\n# based on the query_placement_forbidden_aggregates_traits config option value and the required traits set in flavor and image, prepare a list of traits which if found in aggregates should be set in the destination object of RequestSpec for exclusion.\n\n  special_traits \u003d CONF.scheduler.query_placement_forbidden_aggregates_traits\n  if not special_traits:\n      return\n  flavor_extra_spec \u003d request_spec.flavor.extra_specs\n  image_properties \u003d request_spec.image.properties\n\n  #  Get required traits set in flavor\n  flavor_required_traits \u003d \u003cGet required traits set in flavor\u003e\n\n  # Get required traits set in image\n  image_required_traits \u003d \u003cGet required traits set in image\u003e\n\n  # Prepare a list of traits from special_traits which are not present in the flavor and image.\n  aggregate_traits \u003d list(set(special_traits).difference(set(\n                        flavor_required_traits + image_required_traits)))\n\n  # get_by_metadata_key, we have modified this method to pass this extra parameter \u0027key_exact_match \u003dFalse\u0027.\n\n  aggregates \u003d objects.AggregateList.get_by_metadata_key(ctxt, key\u003d\u0027required:traits\u0027, key_exact_match\u003dFalse)\n\n  for agg in aggregates:\n       required_traits_list \u003d [value for key, value in agg.metadata.items()\n                                   if \"required:traits\" in key]\n\n       if list(set(aggregate_traits).intersection(set(require_traits_list))):\n           forbidden_aggregates.add(agg.uuid)\n\n\nforbidden_aggregates is the list of aggregates that will be set in the destination of RequestSpec object for exclusion.\n\n\nNow, If I change the syntax from \"required:trait\"\u003d\u003ctrait name\u003e to \u003ctrait name\u003e\u003d\"required\".\n\n\n  #all above code is same\n  # Prepare a list of traits from special_traits which are not present in the flavor and image.\n  aggregate_traits \u003d list(set(special_traits).difference(set(\n                        flavor_required_traits + image_required_traits)))\n\n  aggregates \u003d objects.AggregateList.get_by_metadata(..., value\u003d\u0027required\u0027)\n\n  for agg in aggregates:\n       required_traits_list \u003d [value for value in agg.metadata.values()\n                                   if \"required\" in value]\n\n       if len(list(set(aggregate_traits).intersection(set(require_traits_list))))\u003e 0:\n           forbidden_aggregates.add(agg.uuid)","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c6cb3904c16be3eca1d18856ba0230ca768afc19","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_040f28e0","line":101,"in_reply_to":"5fc1f717_2c3b34d1","updated":"2019-04-09 19:13:25.000000000","message":"I\u0027m going to agree with gibi (sort of) by saying you already have this information. This config option seems really confusing to me. How hard would it be to discover all the relevant traits dynamically by doing GET /os-aggregates and matching all metadata keys of a certain pattern?\n\n forbidden_aggs_traits \u003d []\n # GET /os-aggregates\n for agg in get_host_aggregates():\n     for key, value in agg.metadata.items():\n         m \u003d key.match(r\u0027/trait:([A-Z0-9_]+)$/\u0027)\n         if m and value \u003d\u003d \u0027required\u0027:\n             forbidden_aggs_traits.append(m.groups(1))","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"7b30419b10f428236a68f55a8aabe9b8df6709b2","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"3fce034c_f3493f32","line":101,"in_reply_to":"5fc1f717_a3516132","updated":"2019-04-11 05:37:23.000000000","message":"Correction in getting required_traits_list:\n\nNow, If I change the syntax from \"required:trait\"\u003d\u003ctrait name\u003e to \u003ctrait name\u003e\u003d\"required\".\n\n  #all above code is same\n  # Prepare a list of traits from special_traits which are not present in the flavor and image.\n  aggregate_traits \u003d list(set(special_traits).difference(set(\n                        flavor_required_traits + image_required_traits)))\n  aggregates \u003d objects.AggregateList.get_by_metadata(..., value\u003d\u0027required\u0027)\n  for agg in aggregates:\n       required_traits_list \u003d [key for key, value in agg.metadata.items()\n                                   if \"required\" in value]\n       if len(list(set(aggregate_traits).intersection(set(require_traits_list))))\u003e 0:\n           forbidden_aggregates.add(agg.uuid)","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"f9acad63b33265001113a874a53e54ba36887191","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"3fce034c_4e9e3664","line":101,"in_reply_to":"5fc1f717_d8f4b25d","updated":"2019-04-15 07:37:57.000000000","message":"I have understood your point. I will remove this new config option in the next PS.\n\nSo in the new request filter `forbidden_aggregates`, it will get the required traits set in both flavor and images from request_spec object and compare it with the required traits set in the aggregate metadata. If any of the traits are not matching with the aggregate metadata, it will include that aggregate as forbidden aggregate in the ``member_of`` query parameter of ``GET /allocation_candidates`` API.","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"08239f52bf45a09a3325505292b35a28037adcca","unresolved":false,"context_lines":[{"line_number":98,"context_line":".. code::"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"  [scheduler]"},{"line_number":101,"context_line":"  query_placement_forbidden_aggregates_traits \u003d CUSTOM_WINDOWS_LICENSED, CUSTOM_XYZ"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5fc1f717_2c3b34d1","line":101,"in_reply_to":"5fc1f717_d8f4b25d","updated":"2019-04-09 14:03:59.000000000","message":"If flavor and image doesn\u0027t include any required traits, then it\u0027s possible the VM could boot on compute node which it\u0027s not suppose to.\n\nTo cater to this problem, operator will need to set all such traits in this config option and the request filter will find out based on these traits which aggregates  should be excluded by get allocation candidates API.","commit_id":"ee11cd411cacd9f101b1f2734d7cd59bcb43de7f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":68,"context_line":"server request from request_spec object. In the new request filter, it will"},{"line_number":69,"context_line":"get the required traits set in both flavor and images from request_spec object"},{"line_number":70,"context_line":"and compare it with the required traits set in the aggregate metadata."},{"line_number":71,"context_line":"If any of the traits are not matching with the aggregate metadata, it will"},{"line_number":72,"context_line":"include that aggregate as forbidden aggregate in the ``member_of`` query"},{"line_number":73,"context_line":"parameter of ``GET /allocation_candidates`` API. If there are multiple"},{"line_number":74,"context_line":"forbidden aggregates, then the query parameter should be like:"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_60d3e839","line":71,"updated":"2019-04-24 16:51:34.000000000","message":"I *think* (but haven\u0027t confirmed) that this should also be able to work with volume-backed servers where the image metadata is pulled from the volume_image_metadata field on the volume used in the root BDM. I\u0027m pretty sure we have functional tests that make sure that required traits in volume-backed servers are honored during scheduling though (as part of https://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/glance-image-traits.html).","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":68,"context_line":"server request from request_spec object. In the new request filter, it will"},{"line_number":69,"context_line":"get the required traits set in both flavor and images from request_spec object"},{"line_number":70,"context_line":"and compare it with the required traits set in the aggregate metadata."},{"line_number":71,"context_line":"If any of the traits are not matching with the aggregate metadata, it will"},{"line_number":72,"context_line":"include that aggregate as forbidden aggregate in the ``member_of`` query"},{"line_number":73,"context_line":"parameter of ``GET /allocation_candidates`` API. If there are multiple"},{"line_number":74,"context_line":"forbidden aggregates, then the query parameter should be like:"}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_fdc10f82","line":71,"in_reply_to":"ffb9cba7_60d3e839","updated":"2019-05-02 20:11:36.000000000","message":"Yes, it will work as the volume_image_metadata is available in the request spec object.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"83a46b5c71fd86178faba59336ddf591393c110e","unresolved":false,"context_lines":[{"line_number":80,"context_line":".. code::"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"  openstack aggregate set --property trait:CUSTOM_WINDOWS_LICENSED\u003drequired 123"},{"line_number":83,"context_line":"  openstack aggregate set --property trait:CUSTOM_XYZ\u003drequired 123"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"Operator will need to set ``trait:\u003ctrait_name\u003e\u003drequired`` to images for"},{"line_number":86,"context_line":"windows OS images."}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_803d8a2c","line":83,"range":{"start_line":83,"start_character":37,"end_line":83,"end_character":62},"updated":"2019-04-27 02:51:34.000000000","message":"nit: This is just a question. Why is it not just \"trait\u003dCUSTOM_XYZ\", which I think is easier and understandable to SQL query? i.e. getting all aggregates that have `required` in its value is less intuitive than getting all aggregates that have `traits` in its key...","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":80,"context_line":".. code::"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"  openstack aggregate set --property trait:CUSTOM_WINDOWS_LICENSED\u003drequired 123"},{"line_number":83,"context_line":"  openstack aggregate set --property trait:CUSTOM_XYZ\u003drequired 123"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"Operator will need to set ``trait:\u003ctrait_name\u003e\u003drequired`` to images for"},{"line_number":86,"context_line":"windows OS images."}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_8fd9b923","line":83,"range":{"start_line":83,"start_character":37,"end_line":83,"end_character":62},"in_reply_to":"ffb9cba7_803d8a2c","updated":"2019-05-02 20:11:36.000000000","message":"I agree it\u0027s also a possible option. The earlier proposed syntax was \"required:traits\u003d\u003ctrait name\u003e\".\n\nBut I had received one comment to follow syntax \"trait:\u003ctrait_name\u003e\u003drequired\" same as we use to set required traits in the flavor and images. So I have made this change accordingly.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":99,"context_line":"This ``forbidden_aggregates`` placement request filter supersedes"},{"line_number":100,"context_line":"existing ``IsolatedHostsFilter`` except it:-"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"* Relies on aggregates rather than individual hosts (which won\u0027t scale in"},{"line_number":103,"context_line":"  large environments like a public cloud)."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"* Relies on image properties rather than specific image IDs, which again"},{"line_number":106,"context_line":"  won\u0027t scale."}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_6060c8a6","line":103,"range":{"start_line":102,"start_character":52,"end_line":103,"end_character":42},"updated":"2019-04-24 16:51:34.000000000","message":"yup noted below","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":107,"context_line":""},{"line_number":108,"context_line":"With this placement request filter in place, there is a possibility we can"},{"line_number":109,"context_line":"deprecate ``IsolatedHostsFilter`` scheduler filter for reasons as stated above."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"Alternatives"},{"line_number":112,"context_line":"------------"},{"line_number":113,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_c0689488","line":110,"updated":"2019-04-24 16:51:34.000000000","message":"OK so if there is an aggregate with metadata trait:CUSTOM_WINDOWS_LICENSED\u003drequired and a user creates a server with a flavor or image that does not have any required traits, then the aggregate would be forbidden. Got it.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":107,"context_line":""},{"line_number":108,"context_line":"With this placement request filter in place, there is a possibility we can"},{"line_number":109,"context_line":"deprecate ``IsolatedHostsFilter`` scheduler filter for reasons as stated above."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"Alternatives"},{"line_number":112,"context_line":"------------"},{"line_number":113,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_ef687522","line":110,"in_reply_to":"ffb9cba7_2348685a","updated":"2019-05-02 20:11:36.000000000","message":"Both the traits (CUSTOM_WINDOWS_LICENSED and CUSTOM_XYZ) should be present in the request (flavor and/or image) otherwise that aggregate will be forbidden.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"83a46b5c71fd86178faba59336ddf591393c110e","unresolved":false,"context_lines":[{"line_number":107,"context_line":""},{"line_number":108,"context_line":"With this placement request filter in place, there is a possibility we can"},{"line_number":109,"context_line":"deprecate ``IsolatedHostsFilter`` scheduler filter for reasons as stated above."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"Alternatives"},{"line_number":112,"context_line":"------------"},{"line_number":113,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_2348685a","line":110,"in_reply_to":"ffb9cba7_c0689488","updated":"2019-04-27 02:51:34.000000000","message":"Let me make it more clearer for the blazar\u0027s use case. What happens if several trait metadatas are provided in one aggregate? In this case, is that aggregate excluded unless all the traits are required, or if one of the traits are required, that aggregate is not forbidden?\n\nFor example,\n\n $ openstack aggregate show test-agg1\n+-------------------+-----------------------------------------------------------------------+\n| Field             | Value                                                                 |\n+-------------------+-----------------------------------------------------------------------+\n| availability_zone | None                                                                  |\n| created_at        | 2019-04-26T01:20:45.000000                                            |\n| deleted           | False                                                                 |\n| deleted_at        | None                                                                  |\n| hosts             | []                                                                    |\n| id                | 2                                                                     |\n| name              | test-agg1                                                             |\n| properties        | trait:CUSTOM_WINDOWS_LICENSED\u003d\u0027required\u0027, trait:CUSTOM_XYZ\u003d\u0027required\u0027 |\n| updated_at        | None                                                                  |\n+-------------------+-----------------------------------------------------------------------+\n\nTo use the hosts in test-agg1 above, should we set both CUSTOM_WINDOWS_LICENSED and CUSTOM_XYZ in the flavor/image or we can use them if set either of the traits?\n\nI\u0027d llike this to be the latter:\n\n\"If at least one of the aggregate\u0027s traits is required, that agg is not forbidden. If you want to forbidden unless the image/flavor have all of the traits, create another agg that has the same hosts inside and has its traits set\"\n\nThat said in instance reservation Blazar wants to set several reservation id as traits in one aggregate and a user should be able to use the hosts in the aggregate if they have at least one of the reservation id.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":111,"context_line":"Alternatives"},{"line_number":112,"context_line":"------------"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"Option 1: `Strict-isolation-group-hosts-images`_ specs"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_6084485f","line":114,"updated":"2019-04-24 16:51:34.000000000","message":"This may or may not align with something that GoDaddy proposed:\n\nhttps://review.opendev.org/#/c/593167/\n\nWhich is essentially AggregateImagePropertiesIsolation but tries to solve the exclusion problem, meaning images with an exact match property key\u003dvalue can land on a given aggregate of hosts (so kind of more like a mix of AggregateImagePropertiesIsolation and IsolatedHostsFilter).","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":111,"context_line":"Alternatives"},{"line_number":112,"context_line":"------------"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"Option 1: `Strict-isolation-group-hosts-images`_ specs"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_cf7571ce","line":114,"in_reply_to":"ffb9cba7_6084485f","updated":"2019-05-02 20:11:36.000000000","message":"The proposed patch will solve our specific use case but in Stein PTG the conclusion was to use placement service to exclude aggregates.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":114,"context_line":"Option 1: `Strict-isolation-group-hosts-images`_ specs"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"},{"line_number":118,"context_line":"host aggregates."},{"line_number":119,"context_line":"b) A compute node associated with multiple host aggregates. This is a"},{"line_number":120,"context_line":"fundamental problem with nova host aggregates that doesn\u0027t exist in placement"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_802b7c80","line":117,"updated":"2019-04-24 16:51:34.000000000","message":"nit: if you wanted to format this as a list, you\u0027d do:\n\n  The main issues with this spec are:\n\n  a) Adding a new scheduler filter which yet again depends on\n     metadata key for host aggregates.\n  b) A compute node associated with multiple host aggregates. \n     This is a ...","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":114,"context_line":"Option 1: `Strict-isolation-group-hosts-images`_ specs"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"},{"line_number":118,"context_line":"host aggregates."},{"line_number":119,"context_line":"b) A compute node associated with multiple host aggregates. This is a"},{"line_number":120,"context_line":"fundamental problem with nova host aggregates that doesn\u0027t exist in placement"}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_7803ed0e","line":117,"in_reply_to":"ffb9cba7_802b7c80","updated":"2019-05-02 20:11:36.000000000","message":"I will update this in the next PS.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"},{"line_number":118,"context_line":"host aggregates."},{"line_number":119,"context_line":"b) A compute node associated with multiple host aggregates. This is a"},{"line_number":120,"context_line":"fundamental problem with nova host aggregates that doesn\u0027t exist in placement"},{"line_number":121,"context_line":"aggregates."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"Option 2: `Bi-directional-enforcement-of-traits`_ specs"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_405a642a","line":121,"range":{"start_line":119,"start_character":60,"end_line":121,"end_character":11},"updated":"2019-04-24 16:51:34.000000000","message":"What is the fundamental problem with a compute host being in multiple nova host aggregates? Because you\u0027d have to set the same metadata key on all of the aggregates? Meaning it\u0027s a complexity/management problem?\n\nResource providers can be in multiple resource provider aggregates as well, so I\u0027m a bit lost on why the cardinality is an issue for nova host aggregates but not placement aggregates.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"ec08068cf5d19e1f168b64163a3bf6d1493bd555","unresolved":false,"context_lines":[{"line_number":116,"context_line":"The main issues with this specs are:"},{"line_number":117,"context_line":"a) Adding a new scheduler filter which yet again depends on metadata key for"},{"line_number":118,"context_line":"host aggregates."},{"line_number":119,"context_line":"b) A compute node associated with multiple host aggregates. This is a"},{"line_number":120,"context_line":"fundamental problem with nova host aggregates that doesn\u0027t exist in placement"},{"line_number":121,"context_line":"aggregates."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"Option 2: `Bi-directional-enforcement-of-traits`_ specs"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_8fabf973","line":121,"range":{"start_line":119,"start_character":60,"end_line":121,"end_character":11},"in_reply_to":"ffb9cba7_405a642a","updated":"2019-05-02 17:11:38.000000000","message":"The problem is because each aggregate can have conflicting metadata. For instance one aggregate might be a Windows licensed host. One might not be. The compute host belongs to both aggregates. So, which one takes precedence?","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"Option 3: Use `IsolatedHostsFilter`_ scheduler filter"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"The only drawback with this filter is it allows you to isolate images and"},{"line_number":135,"context_line":"hosts of one specific type. If you want OS of type1 to be launched on"},{"line_number":136,"context_line":"``HOSTA`` and another OS type2 on ``HOSTB``, then this filter is of no use."},{"line_number":137,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_c0b3b44c","line":134,"range":{"start_line":134,"start_character":4,"end_line":134,"end_character":8},"updated":"2019-04-24 16:51:34.000000000","message":"I\u0027m not sure that\u0027s the only drawback, it also doesn\u0027t support isolation for volume-backed servers (for whatever reason - maybe it was just never considered) and it also doesn\u0027t really scale in a large public cloud with thousands of hosts and potentially a lot of images (or especially if users can upload their own images).","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"Option 3: Use `IsolatedHostsFilter`_ scheduler filter"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"The only drawback with this filter is it allows you to isolate images and"},{"line_number":135,"context_line":"hosts of one specific type. If you want OS of type1 to be launched on"},{"line_number":136,"context_line":"``HOSTA`` and another OS type2 on ``HOSTB``, then this filter is of no use."},{"line_number":137,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_9847c1bd","line":134,"range":{"start_line":134,"start_character":4,"end_line":134,"end_character":8},"in_reply_to":"ffb9cba7_c0b3b44c","updated":"2019-05-02 20:11:36.000000000","message":"I will include these drawbacks in the next PS.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":163,"context_line":"Performance Impact"},{"line_number":164,"context_line":"------------------"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"DB call to fetch aggregates with value `required` in the"},{"line_number":167,"context_line":"``forbidden_aggregates`` placement request filter will marginally impact the"},{"line_number":168,"context_line":"overall processing time of each `select_destination` request."},{"line_number":169,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_4087c410","line":166,"updated":"2019-04-24 16:51:34.000000000","message":"Hmm, true, and the existing two request filters already do that as well, but they filter aggregates differently:\n\nhttps://github.com/openstack/nova/blob/a991980863f056323c1ee9fd6a46dbc4cb899eca/nova/scheduler/request_filter.py\n\nOne nice thing about the HostState object used in the legacy filters is each HostState has it\u0027s list of aggregates already loaded (and potentially cached) per scheduler worker, but that could also be racy if the aggregates are changing very often.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"81e062e22541758386df32f6ef67c87125377a7b","unresolved":false,"context_lines":[{"line_number":163,"context_line":"Performance Impact"},{"line_number":164,"context_line":"------------------"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"DB call to fetch aggregates with value `required` in the"},{"line_number":167,"context_line":"``forbidden_aggregates`` placement request filter will marginally impact the"},{"line_number":168,"context_line":"overall processing time of each `select_destination` request."},{"line_number":169,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_0fe629ea","line":166,"in_reply_to":"ffb9cba7_4087c410","updated":"2019-05-02 17:13:49.000000000","message":"Yup, that\u0027s fair to say and ideally document somewhere.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b72af8f2fbbae937310df5e5359808ce60868d1","unresolved":false,"context_lines":[{"line_number":194,"context_line":"problem in mirroring, operator can sync it manually with ``nova-manage``"},{"line_number":195,"context_line":"command:"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"``nova-manage placement sync_aggregates``"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"Implementation"},{"line_number":200,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_a0ac808c","line":197,"updated":"2019-04-24 16:51:34.000000000","message":"Note that this is not fool proof in that it only mirrors existing host aggregates in nova to placement, it does not remove any resource provider aggregates that nova doesn\u0027t know about (because aggregates could be modeled in placement by some external tool, for example on ironic node provider aggregates which aren\u0027t supported in nova).","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"83a46b5c71fd86178faba59336ddf591393c110e","unresolved":false,"context_lines":[{"line_number":194,"context_line":"problem in mirroring, operator can sync it manually with ``nova-manage``"},{"line_number":195,"context_line":"command:"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"``nova-manage placement sync_aggregates``"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"Implementation"},{"line_number":200,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ffb9cba7_c0baa26c","line":197,"range":{"start_line":197,"start_character":0,"end_line":197,"end_character":41},"updated":"2019-04-27 02:51:34.000000000","message":"Since we\u0027re going to use trait + aggregate, why not also change this command to synchronize the trait to placement if trait is set in the aggregate metadata in nova? That said, no one sets this trait aggregate metadata in nova without setting traits on compute nodes in the aggregate in placement. If operator misses the latter, NoValidHost could be returned.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":194,"context_line":"problem in mirroring, operator can sync it manually with ``nova-manage``"},{"line_number":195,"context_line":"command:"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"``nova-manage placement sync_aggregates``"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"Implementation"},{"line_number":200,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_58dce917","line":197,"in_reply_to":"ffb9cba7_a0ac808c","updated":"2019-05-02 20:11:36.000000000","message":"If the aggregates doesn\u0027t exist in nova, then the request filter will not include any forbidden aggregates in the allocation candidates API.\n\nIs anyone looking for solving same use case for Ironic?","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"2826e008e8f72e9c463537fb32cac7f77272ec2f","unresolved":false,"context_lines":[{"line_number":194,"context_line":"problem in mirroring, operator can sync it manually with ``nova-manage``"},{"line_number":195,"context_line":"command:"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"``nova-manage placement sync_aggregates``"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"Implementation"},{"line_number":200,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":6,"id":"dfbec78f_d8f8d97d","line":197,"range":{"start_line":197,"start_character":0,"end_line":197,"end_character":41},"in_reply_to":"ffb9cba7_c0baa26c","updated":"2019-05-02 20:11:36.000000000","message":"Good suggestion. I will update this in the next PS.","commit_id":"f5626f41434d84ec1ad7c89fbbba655e81ba4945"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"04cb4ccae907bf3d1f824e787f3b7368a6967b29","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"Option 2: `Bi-directional-enforcement-of-traits`_ specs"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"The main issue with this specs is:"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"It\u0027s not placement\u0027s job to make operators have an easy life. Operators"},{"line_number":130,"context_line":"should be required to set up their deployment\u0027s providers with an appropriate"}],"source_content_type":"text/x-rst","patch_set":7,"id":"dfbec78f_c0b76dd8","line":127,"range":{"start_line":127,"start_character":25,"end_line":127,"end_character":30},"updated":"2019-05-03 22:02:15.000000000","message":"spec","commit_id":"3b7fda1a8b672ed758fd38f8a086f346660cbf5d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"04cb4ccae907bf3d1f824e787f3b7368a6967b29","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"It doesn\u0027t really scale in a large public cloud with thousands of hosts and"},{"line_number":138,"context_line":"images. Also, if you add new hosts in the system, you will need to modify the"},{"line_number":139,"context_line":"config option `isolated_hosts` and restart nova scheduler services."},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"Data model impact"},{"line_number":142,"context_line":"-----------------"}],"source_content_type":"text/x-rst","patch_set":7,"id":"dfbec78f_a0eb59ae","line":139,"range":{"start_line":139,"start_character":14,"end_line":139,"end_character":30},"updated":"2019-05-03 22:02:15.000000000","message":"double backticks for literal: ``isolated_hosts``. This is in the [scheduler] section, right? Would be nice to include that.","commit_id":"3b7fda1a8b672ed758fd38f8a086f346660cbf5d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"be2349a2eb3c05b4db5f2f1e17d9dfe1d4734481","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"It doesn\u0027t really scale in a large public cloud with thousands of hosts and"},{"line_number":138,"context_line":"images. Also, if you add new hosts in the system, you will need to modify the"},{"line_number":139,"context_line":"config option `isolated_hosts` and restart nova scheduler services."},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"Data model impact"},{"line_number":142,"context_line":"-----------------"}],"source_content_type":"text/x-rst","patch_set":7,"id":"dfbec78f_4ac87454","line":139,"range":{"start_line":139,"start_character":14,"end_line":139,"end_character":30},"in_reply_to":"dfbec78f_2f6c3235","updated":"2019-05-04 16:28:27.000000000","message":"Okay. These things can be fixed in a followon change. Or not at all - they\u0027re not a big deal.","commit_id":"3b7fda1a8b672ed758fd38f8a086f346660cbf5d"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"7d963c1b0806822f0b3bd3dad35d4531ac72059a","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"It doesn\u0027t really scale in a large public cloud with thousands of hosts and"},{"line_number":138,"context_line":"images. Also, if you add new hosts in the system, you will need to modify the"},{"line_number":139,"context_line":"config option `isolated_hosts` and restart nova scheduler services."},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"Data model impact"},{"line_number":142,"context_line":"-----------------"}],"source_content_type":"text/x-rst","patch_set":7,"id":"dfbec78f_e534fbe0","line":139,"range":{"start_line":139,"start_character":14,"end_line":139,"end_character":30},"in_reply_to":"dfbec78f_4ac87454","updated":"2019-05-04 17:12:34.000000000","message":"I will fix these things now and push a next PS soon.","commit_id":"3b7fda1a8b672ed758fd38f8a086f346660cbf5d"},{"author":{"_account_id":1011,"name":"Tushar Patil","email":"tushar.vitthal.patil@gmail.com","username":"tpatil"},"change_message_id":"879681d6ee91b7431ea49df9ef5f7266e5dbca88","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"It doesn\u0027t really scale in a large public cloud with thousands of hosts and"},{"line_number":138,"context_line":"images. Also, if you add new hosts in the system, you will need to modify the"},{"line_number":139,"context_line":"config option `isolated_hosts` and restart nova scheduler services."},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"Data model impact"},{"line_number":142,"context_line":"-----------------"}],"source_content_type":"text/x-rst","patch_set":7,"id":"dfbec78f_2f6c3235","line":139,"range":{"start_line":139,"start_character":14,"end_line":139,"end_character":30},"in_reply_to":"dfbec78f_a0eb59ae","updated":"2019-05-04 15:25:30.000000000","message":"This config option is part of \"filter_scheduler\" section.","commit_id":"3b7fda1a8b672ed758fd38f8a086f346660cbf5d"}]}
