)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"be4b1c653725f2a45927a7da9c23f128ab8b477b","unresolved":false,"context_lines":[{"line_number":10,"context_line":"scheduler into an object that is cleaner to pass over RPC, and which"},{"line_number":11,"context_line":"allows versioning of any changes to this data."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Blueprint: return-selection-objects"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ic135752bcee73f8b5fc73a8df785c698c16ac324"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"7f515b1d_357c7a71","line":13,"range":{"start_line":13,"start_character":11,"end_line":13,"end_character":35},"updated":"2017-10-03 16:34:02.000000000","message":"blueprint return-alternate-hosts is covering this work now","commit_id":"70d8f8a7b91799e12ef1c178ca311f5853f9bc4f"}],"nova/objects/selection.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"13020f0c32f39dda112f0eff52e3d24a47699d50","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \"host_uuid\": fields.UUIDField(default\u003d\"\"),"},{"line_number":34,"context_line":"        \"host_name\": fields.StringField(default\u003d\"\"),"},{"line_number":35,"context_line":"        \"node_name\": fields.StringField(default\u003d\"\"),"},{"line_number":36,"context_line":"        \"limits\": fields.DictOfIntegersField(default\u003d{}),"},{"line_number":37,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":38,"context_line":"        # complex nested structure of dicts, tuples, and lists, so store the"},{"line_number":39,"context_line":"        # JSON representation of that value."}],"source_content_type":"text/x-python","patch_set":2,"id":"5f2577a7_5502d70c","line":36,"updated":"2017-09-25 11:09:41.000000000","message":"good thinking. I totally forgot about the limits thing. That said, I don\u0027t think it can be a dict of integers, because numa_topology limits is a complex object.. :(","commit_id":"bce379bfbc28a3708355960694a3f60df637f095"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"host_uuid\": fields.UUIDField(default\u003d\"\"),"},{"line_number":34,"context_line":"        \"host_name\": fields.StringField(default\u003d\"\"),"},{"line_number":35,"context_line":"        \"node_name\": fields.StringField(default\u003d\"\"),"},{"line_number":36,"context_line":"        \"limits\": fields.DictOfIntegersField(default\u003d{}),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_b19f49b3","line":33,"range":{"start_line":33,"start_character":38,"end_line":33,"end_character":48},"updated":"2017-09-21 16:22:02.000000000","message":"Why? A selection object with any of these things as empty strings makes no sense right? I would expect none of these to have defaults.\n\nAlso, same comment here as in the spec about naming these to be clearer about whether they apply to the service or compute node.","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \"host_uuid\": fields.UUIDField(default\u003d\"\"),"},{"line_number":34,"context_line":"        \"host_name\": fields.StringField(default\u003d\"\"),"},{"line_number":35,"context_line":"        \"node_name\": fields.StringField(default\u003d\"\"),"},{"line_number":36,"context_line":"        \"limits\": fields.DictOfIntegersField(default\u003d{}),"},{"line_number":37,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":38,"context_line":"        # complex nested structure of dicts, tuples, and lists, so store the"},{"line_number":39,"context_line":"        # JSON representation of that value."}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_71a9d1dd","line":36,"updated":"2017-09-21 16:22:02.000000000","message":"You won\u0027t want this default to be mutable as it may get shared (and polluted) across scheduling loops right?","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        \"allocation_json\": fields.StringField(default\u003d\"\"),"},{"line_number":41,"context_line":"    }"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def __init__(self, host_state\u003dNone, *args, **kwargs):"},{"line_number":44,"context_line":"        \"\"\"The allocation requires separate handling.\"\"\""},{"line_number":45,"context_line":"        alloc \u003d kwargs.pop(\"allocation\", \"\")"},{"line_number":46,"context_line":"        super(Selection, self).__init__(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_b1d6294f","line":43,"updated":"2017-09-21 16:22:02.000000000","message":"I don\u0027t think you should override __init__ at all. We try to never do that in the other objects, and because you\u0027ve broken several of the conventions here. We should build these objects like any other, passing in the json. If we need a helper to jsonify an allocations dict, then make a classmethod to do that (again, like all the other object).","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def __init__(self, host_state\u003dNone, *args, **kwargs):"},{"line_number":44,"context_line":"        \"\"\"The allocation requires separate handling.\"\"\""},{"line_number":45,"context_line":"        alloc \u003d kwargs.pop(\"allocation\", \"\")"},{"line_number":46,"context_line":"        super(Selection, self).__init__(*args, **kwargs)"},{"line_number":47,"context_line":"        # Also manually set the fields to avoid the \"Cannot load...\" error"},{"line_number":48,"context_line":"        for field in self.fields:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_715e71e7","line":45,"updated":"2017-09-21 16:22:02.000000000","message":"Why default things to empty? If we don\u0027t end up setting them, they should remain unset. If they\u0027re set, we should be able to assume they\u0027re valid, and this will not be valid.","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            val \u003d kwargs.get(field, default)"},{"line_number":51,"context_line":"            setattr(self, field, val)"},{"line_number":52,"context_line":"        if alloc:"},{"line_number":53,"context_line":"            if isinstance(alloc, six.string_types):"},{"line_number":54,"context_line":"                self.allocation_json \u003d alloc"},{"line_number":55,"context_line":"            else:"},{"line_number":56,"context_line":"                self.allocation_json \u003d jsonutils.dumps(alloc)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_31c23987","line":53,"updated":"2017-09-21 16:22:02.000000000","message":"Boo for inconsistent behavior.","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":54,"context_line":"                self.allocation_json \u003d alloc"},{"line_number":55,"context_line":"            else:"},{"line_number":56,"context_line":"                self.allocation_json \u003d jsonutils.dumps(alloc)"},{"line_number":57,"context_line":"        if host_state:"},{"line_number":58,"context_line":"            self.from_host_state(host_state)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def from_host_state(self, host_state):"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_b13bc99a","line":57,"updated":"2017-09-21 16:22:02.000000000","message":"So you\u0027re depending this having been ignored by the super() call? You popped allocation out.\n\nPassing non-field kwargs to this init method is another odd unconventional anti-pattern introduced by this code.","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ba3d9c38d5fb6b6964040a9ed51ee687f3097b8e","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        if host_state:"},{"line_number":58,"context_line":"            self.from_host_state(host_state)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def from_host_state(self, host_state):"},{"line_number":61,"context_line":"        \"\"\"Populates the object from the passed host state value. This can be"},{"line_number":62,"context_line":"        either a HostState object, or a dict-ified representation of that"},{"line_number":63,"context_line":"        object."}],"source_content_type":"text/x-python","patch_set":4,"id":"9f5c4f37_b10989de","line":60,"updated":"2017-09-21 16:22:02.000000000","message":"IMHO, just make this a classmethod and let it take the allocation. Do all your special handling here to jsonify the allocation and populate the attributes from the host state.\n\nTBH, I don\u0027t really think the special HostState handling should be in here, since it\u0027s extremely scheduler-specific, but  I\u0027m okay with it if you really want to keep it here.","commit_id":"462cc07876ba2e6868bc8038fc1f84f0ee95a0a1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fddc1b36becf2ad021ed22afcbbfbc0df01ad980","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        if isinstance(other, self.__class__):"},{"line_number":44,"context_line":"            return self.__dict__ \u003d\u003d other.__dict__"},{"line_number":45,"context_line":"        else:"},{"line_number":46,"context_line":"            return False"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def __ne__(self, other):"},{"line_number":49,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_8082b1c7","line":46,"updated":"2017-09-22 16:27:34.000000000","message":"This is probably okay for this, although I think I\u0027d rather be more explicit just so we don\u0027t end up with untracked state confusing this. Maybe something like this?\n\n return all(getattr(self, k) \u003d\u003d getattr(other, k) for k in self.fields)\n\n?\n\nJust going on previous experience where things like the local context in the object could cause this to fail. Maybe just keep this in mind as you go forward in case what you have here seems flaky.","commit_id":"243db0141241b3affa79e8f9c028fc61c677549d"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"b6abfbfe3e8a504be280576e37358167c47a0281","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        if isinstance(other, self.__class__):"},{"line_number":44,"context_line":"            return self.__dict__ \u003d\u003d other.__dict__"},{"line_number":45,"context_line":"        else:"},{"line_number":46,"context_line":"            return False"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def __ne__(self, other):"},{"line_number":49,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_80451173","line":46,"in_reply_to":"7f515b1d_8082b1c7","updated":"2017-09-22 16:35:26.000000000","message":"Done","commit_id":"243db0141241b3affa79e8f9c028fc61c677549d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"770a828c60624c61908f5070dfe7cffd37402272","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_69bf84fb","line":34,"updated":"2017-09-25 11:10:35.000000000","message":"This won\u0027t work because NUMA limit isn\u0027t an integer. It\u0027s a NUMATopologyLimits object :(","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9a980b7e06cf1e8b07b923160921733f8182dfe6","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_f4b8e82a","line":34,"in_reply_to":"7f515b1d_69bf84fb","updated":"2017-09-25 13:43:15.000000000","message":"This object replaces the thing returned here:\n\nhttps://github.com/openstack/nova/blob/master/nova/scheduler/manager.py#L105-L112\n\nInstead of a list of dicts, it will return a list of Selection objects. Is there any reason this NUMATopologyLimits object can\u0027t be dictified as it currently is here?\n\nhttps://github.com/openstack/nova/blob/master/nova/scheduler/manager.py#L48-L61\n\nDo you have a suggestion for the correct field type?","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fc6941c4da185178f4670e7d085f5f28855f7c68","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_fd632bdb","line":34,"in_reply_to":"7f515b1d_7722baa6","updated":"2017-09-25 14:43:25.000000000","message":"It\u0027s not just that, it\u0027s any out of tree filter that shoves shit into the host state limits. Those all get thrown into HostState.limits which are passed through conductor to the compute service, which are then used in the resource tracker. So if we codify the entries of the limits dict here in this object, we\u0027re going to possibly break any custom scheduler filters.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9df8a9d6e3f5758a6048f1bb9580359912e1565c","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_10737eb3","line":34,"in_reply_to":"7f515b1d_a568ea86","updated":"2017-09-25 22:21:29.000000000","message":"I\u0027m okay with out of tree scheduler filters, but not really concerned about ones that inject stuff into what is really an internal interface. Aside from the NUMA limits, I think we\u0027re getting to the point of not needing these limits anyway. If we\u0027re evolving the interface away from the legacy limits stuff, then people shouldn\u0027t expect filters to continue to work, unmodified, forever.\n\nSo in summary, I think we steam ahead here, regardless of what custom filters we might break.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"00ddf64d6dcb49d6effe057ae6b6f479e5585504","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_7722baa6","line":34,"in_reply_to":"7f515b1d_f4b8e82a","updated":"2017-09-25 14:01:12.000000000","message":"As always, NUMA messes everything up :( The best suggestion I have is to have a separate numa_topology_limits field, nullable, that stores the specific NUMA limit topology.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"7244d5bddddff195ab130f84403de851027fe219","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \"host_uuid\": fields.UUIDField(),"},{"line_number":32,"context_line":"        \"host_name\": fields.StringField(),"},{"line_number":33,"context_line":"        \"node_name\": fields.StringField(),"},{"line_number":34,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_a568ea86","line":34,"in_reply_to":"7f515b1d_fd632bdb","updated":"2017-09-25 22:16:44.000000000","message":"@mriedem: what do you suggest for this, then?","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"13020f0c32f39dda112f0eff52e3d24a47699d50","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"},{"line_number":38,"context_line":"        # JSON-ified version of the dict."},{"line_number":39,"context_line":"        \"allocation\": fields.StringField(),"},{"line_number":40,"context_line":"    }"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_e956d406","line":38,"updated":"2017-09-25 11:09:41.000000000","message":"Remember that the allocation_request is *intended* to be opaque to everything other than the scheduler. So, it\u0027s intentional that the field is just a BLOB. It\u0027s not germane that it\u0027s even JSON. It could be anything.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"00ddf64d6dcb49d6effe057ae6b6f479e5585504","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"},{"line_number":38,"context_line":"        # JSON-ified version of the dict."},{"line_number":39,"context_line":"        \"allocation\": fields.StringField(),"},{"line_number":40,"context_line":"    }"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_f7910a9b","line":38,"in_reply_to":"7f515b1d_54cfbcaf","updated":"2017-09-25 14:01:12.000000000","message":"The comment as it is is misleading. There\u0027s zero reason to talk about complex nested structure of dicts, tuples and lists (which is incorrect, BTW, there\u0027s no tuples in the allocation_request. it\u0027s just dicts and lists.)\n\nJust make the comment say \"this represents the opaque thing that may be used by the cell conductor to claim resources for an alternate host\"","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9a980b7e06cf1e8b07b923160921733f8182dfe6","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        # There isn\u0027t a good field type for the allocation dict, as it has a"},{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"},{"line_number":38,"context_line":"        # JSON-ified version of the dict."},{"line_number":39,"context_line":"        \"allocation\": fields.StringField(),"},{"line_number":40,"context_line":"    }"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_54cfbcaf","line":38,"in_reply_to":"7f515b1d_e956d406","updated":"2017-09-25 13:43:15.000000000","message":"This is here for the benefit of future developers to whom that might not be obvious. I\u0027ll add a comment about the opaqueness.\n\nI actually wanted to have this object handle the conversion of an allocation_request dict to a JSON string, but adding that sort of behavior was nixed.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"13020f0c32f39dda112f0eff52e3d24a47699d50","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"},{"line_number":38,"context_line":"        # JSON-ified version of the dict."},{"line_number":39,"context_line":"        \"allocation\": fields.StringField(),"},{"line_number":40,"context_line":"    }"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_c95b182c","line":39,"updated":"2017-09-25 11:09:41.000000000","message":"allocation_request please, to be consistent with the naming from placement.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9a980b7e06cf1e8b07b923160921733f8182dfe6","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        # complex nested structure of dicts, tuples, and lists, so the code"},{"line_number":37,"context_line":"        # that uses these objects will be responsible for passing in a"},{"line_number":38,"context_line":"        # JSON-ified version of the dict."},{"line_number":39,"context_line":"        \"allocation\": fields.StringField(),"},{"line_number":40,"context_line":"    }"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_74dd1841","line":39,"in_reply_to":"7f515b1d_c95b182c","updated":"2017-09-25 13:43:15.000000000","message":"Done","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"13020f0c32f39dda112f0eff52e3d24a47699d50","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            return False"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __ne__(self, other):"},{"line_number":50,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_89abe0d4","line":50,"updated":"2017-09-25 11:09:41.000000000","message":"Neither of the above methods are necessary. Please use ComparableVersionedObject from ovo:\n\nhttps://github.com/openstack/oslo.versionedobjects/blob/master/oslo_versionedobjects/base.py#L696","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"9a980b7e06cf1e8b07b923160921733f8182dfe6","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            return False"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __ne__(self, other):"},{"line_number":50,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_d4ebacd9","line":50,"in_reply_to":"7f515b1d_89abe0d4","updated":"2017-09-25 13:43:15.000000000","message":"Done","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6a02358f1987aea042268a4ecde145796041a845","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            return False"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __ne__(self, other):"},{"line_number":50,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_3028ba32","line":50,"in_reply_to":"7f515b1d_b0bf0afa","updated":"2017-09-25 22:37:31.000000000","message":"Fair point, but for consistency purposes, I think it\u0027s better to just use the upstream functionality. The only place these objects are compared is in unit tests anyway, so I\u0027m not all that concerned about optimization.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2baa2db9061d39634ef40486b2e9aecac2a07066","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            return False"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __ne__(self, other):"},{"line_number":50,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f515b1d_b0bf0afa","line":50,"in_reply_to":"7f515b1d_d4ebacd9","updated":"2017-09-25 22:30:05.000000000","message":"That\u0027s not the same thing as what he\u0027s doing here. It will compare things like changed field counts. It also requires serializing the whole object, which won\u0027t be as efficient as this, given all the fields are simple to compare.","commit_id":"b226df10be2b7b5fb94ebf543a15cae7d45be70a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0f335d5ed5c0d909151c702176887a9b3b732cdf","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":23,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":24,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":25,"context_line":"    that these objects are not persisted to the database."},{"line_number":26,"context_line":"    \"\"\""},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7f515b1d_c80b6f8b","line":24,"updated":"2017-10-01 19:20:15.000000000","message":"It would be friendly to explain what is in the object, briefly, and that it is a convenience encapsulation of all the stuff a thing (conductor) would need to make use of it.","commit_id":"70d8f8a7b91799e12ef1c178ca311f5853f9bc4f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"668706538a81f6e40176bd84a997a783277a489d","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":34,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":35,"context_line":"        # Both limits and allocation_request are non-trivial dicts, and so they"},{"line_number":36,"context_line":"        # will be stored as encoded strings."},{"line_number":37,"context_line":"        \"limits\": fields.StringField(),"},{"line_number":38,"context_line":"        \"allocation_request\": fields.StringField(),"},{"line_number":39,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f515b1d_73a0e342","line":36,"updated":"2017-10-02 16:45:59.000000000","message":"I\u0027m not really okay with this for limits. Limits is a nova structure that will be consumed by nova services that may be backlevel. I distinguish this from allocation_request because that is not a nova structure and is already versioned by the placement service and can be sent at any version without breaking nova services downstream from us.\n\nI need to brush up on all the details with limits to have a suggested solution here, but I don\u0027t think I can get on board with this as it is.","commit_id":"70d8f8a7b91799e12ef1c178ca311f5853f9bc4f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6f3aa0343ff4705ad7f637d272ef40a2b6ecf54a","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":34,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":35,"context_line":"        # Both limits and allocation_request are non-trivial dicts, and so they"},{"line_number":36,"context_line":"        # will be stored as encoded strings."},{"line_number":37,"context_line":"        \"limits\": fields.StringField(),"},{"line_number":38,"context_line":"        \"allocation_request\": fields.StringField(),"},{"line_number":39,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f515b1d_4e765c72","line":36,"in_reply_to":"7f515b1d_73a0e342","updated":"2017-10-02 17:07:52.000000000","message":"Reading back to Jay\u0027s comments earlier, I think the solution here is pretty much what he said. Either throw a numa limit object in here, or add another object that represents the limit.","commit_id":"70d8f8a7b91799e12ef1c178ca311f5853f9bc4f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06a7cbc52421798eaf71d5b34d68d1e068f281a1","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    fields \u003d {"},{"line_number":32,"context_line":"        \"compute_node_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":33,"context_line":"        \"service_host\": fields.StringField(nullable\u003dTrue),"},{"line_number":34,"context_line":"        \"nodename\": fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":37,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_585fea40","line":34,"updated":"2017-10-05 15:16:02.000000000","message":"Thank you for the sane names here.","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06a7cbc52421798eaf71d5b34d68d1e068f281a1","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":37,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":38,"context_line":"        # as an encoded string."},{"line_number":39,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"},{"line_number":40,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_d8307a0a","line":38,"updated":"2017-10-05 15:16:02.000000000","message":"We need a version to go with this.. remind me how we\u0027re communicating that to the recipients of this?","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"3176bf7b0bcf52d565b8a7afd371f7650b0c3bab","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":37,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":38,"context_line":"        # as an encoded string."},{"line_number":39,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"},{"line_number":40,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_e5d4a2bd","line":38,"in_reply_to":"7f515b1d_bad48e48","updated":"2017-10-05 19:19:57.000000000","message":"The consumer of this is going to throw it at placement with a specific microversion in the headers right? Not just \"assume the latest\"\n\nRelated, are you saying that even if a consumer specifies 1.2, placement will try to decode the body at 1.10 if anything goes wrong, just in case? Because that is highly broken behavior if so.","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"f7abd0dc5423c17ed3b6b44e42f666746dbe198b","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":37,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":38,"context_line":"        # as an encoded string."},{"line_number":39,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"},{"line_number":40,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_bad48e48","line":38,"in_reply_to":"7f515b1d_d8307a0a","updated":"2017-10-05 17:34:21.000000000","message":"I still feel that this is not needed, and is a bit of over-engineering. There should be next to zero chance of a mismatch, since placement would have created this immediately before. And in the event of a mismatch, we have agreed that Placement will always try its most recent schema if there is a problem.","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"95bf202863ba8bf25ece88e4c180f6b15404b956","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":38,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":39,"context_line":"        # as an encoded string."}],"source_content_type":"text/x-python","patch_set":17,"id":"5f4e5783_3f618eaa","line":36,"range":{"start_line":33,"start_character":8,"end_line":36,"end_character":53},"updated":"2017-10-13 00:39:32.000000000","message":"Maybe you talked about this already, but should these be nullable? Shouldn\u0027t we always except these to be set?","commit_id":"d82ba2fa8a09c6d616fe8a58ebe7a053ee748433"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4af37c071d4f3fdab21f166c8a4e779995f1584c","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    VERSION \u003d \"1.0\""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":38,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":39,"context_line":"        # as an encoded string."}],"source_content_type":"text/x-python","patch_set":17,"id":"5f4e5783_f5b9c8cb","line":36,"range":{"start_line":33,"start_character":8,"end_line":36,"end_character":53},"in_reply_to":"5f4e5783_3f618eaa","updated":"2017-10-13 13:27:26.000000000","message":"It was for initial testing, where it was handy to be able to do something like: fake_sel \u003d objects.Selection(). But I can replace those with a standard fake selection.","commit_id":"d82ba2fa8a09c6d616fe8a58ebe7a053ee748433"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"10e2a29f5ee74501d298e69ae7658cdf415dde89","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \"service_host\": fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":38,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":39,"context_line":"        # as an encoded string."},{"line_number":40,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f4e5783_1fedb224","line":37,"updated":"2017-10-13 00:36:12.000000000","message":"OK, so if you still have the CoreFilter, RamFilter or DiskFilter enabled the HostState.limits dict could have limits for those filters as well and we wouldn\u0027t pass them down to the compute. Given we\u0027re already filtering vcpu/ram/disk via Placement I think that\u0027s OK, and why we removed those from the default enabled filters list. Just making sure we aren\u0027t missing something. Like....doesn\u0027t that break the CachingScheduler, which is not yet deprecated and I know people are using it (like the Huawei public cloud for one).\n\nIn other words, I think this effectively makes the CachingScheduler stop enabling claims for vcpu/ram/disk in the compute, which is probably bad.","commit_id":"d82ba2fa8a09c6d616fe8a58ebe7a053ee748433"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4af37c071d4f3fdab21f166c8a4e779995f1584c","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \"service_host\": fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":38,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":39,"context_line":"        # as an encoded string."},{"line_number":40,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":17,"id":"5f4e5783_b50b507b","line":37,"in_reply_to":"5f4e5783_1fedb224","updated":"2017-10-13 13:27:26.000000000","message":"Well, we\u0027ve discussed this earlier, and the consensus was to get rid of limits, as they aren\u0027t used (in-tree, at least). I\u0027m not clear on how you think this affects the CachingScheduler specifically.","commit_id":"d82ba2fa8a09c6d616fe8a58ebe7a053ee748433"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"df96ca29c231d9aed055e054127d7ed681253e8c","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":39,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":40,"context_line":"        # as an encoded string."}],"source_content_type":"text/x-python","patch_set":21,"id":"3f4b6375_7b928e4d","line":37,"range":{"start_line":37,"start_character":25,"end_line":37,"end_character":44},"updated":"2017-10-21 04:01:30.000000000","message":"We talked about this a few times before, but limits are populated by any out of tree filters so I\u0027m not sure we can consider this is just going to be integer values for vcpu/ram/disk filters, right?\n\nI realize people don\u0027t like out of tree filters, but that\u0027s one plug point we\u0027ve allowed people to do (in addition to scheduler hints), so I don\u0027t think we should be intentionally breaking them here.\n\nThing is, I\u0027m not sure what the field type would be, just DictField?","commit_id":"d6cd80d8ed888d7092eee04cbc484dbf5cc0b861"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2017 IBM Corp."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_00de02d9","line":2,"range":{"start_line":2,"start_character":2,"end_line":2,"end_character":22},"updated":"2017-10-26 15:03:00.000000000","message":"When I was with IBM I remember our copyright guidelines said to explicitly *not* include this line, but maybe it\u0027s different in the LTC.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2017 IBM Corp."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_540b9828","line":2,"range":{"start_line":2,"start_character":2,"end_line":2,"end_character":22},"in_reply_to":"3f4b6375_00de02d9","updated":"2017-10-26 17:39:54.000000000","message":"I just copy/pasted from another file. I\u0027ll remove it.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_03716c44","line":24,"range":{"start_line":24,"start_character":42,"end_line":24,"end_character":67},"updated":"2017-10-26 15:03:00.000000000","message":"Not sure why we need the ComparableVersionedObject mixin - there is no test for making sure it works anyway.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_a3261867","line":24,"updated":"2017-10-26 15:03:00.000000000","message":"Random thought, but why don\u0027t we use the SchedulerLimits object here for encapsulating the limits and numa_limits fields?\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/objects/request_spec.py#L674\n\nThat\u0027s basically the same thing and it\u0027s what the RequestSpec uses. Seems like it would be good to not have this stuff done differently everywhere, as noted at the bottom of this page in another comment.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_2f3449dd","line":24,"range":{"start_line":24,"start_character":42,"end_line":24,"end_character":67},"in_reply_to":"3f4b6375_03716c44","updated":"2017-10-26 17:39:54.000000000","message":"The discussion in earlier days was to check for duplicates. Since we do that before the Selection object is created now, I think we can remove it.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_ef4f5168","line":24,"in_reply_to":"3f4b6375_a3261867","updated":"2017-10-26 17:39:54.000000000","message":"Done","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_40019a37","line":34,"range":{"start_line":34,"start_character":9,"end_line":34,"end_character":21},"updated":"2017-10-26 15:03:00.000000000","message":"This is ComputeNode.host?","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a69a6e3d1f002dc030fd95d016af53aed8e24c0a","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_4322c4ba","line":34,"range":{"start_line":34,"start_character":9,"end_line":34,"end_character":21},"in_reply_to":"3f4b6375_40019a37","updated":"2017-10-26 15:26:41.000000000","message":"No, it\u0027s service.host. Which technically should always be the same as compute_nodes.host.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_6006d654","line":35,"range":{"start_line":35,"start_character":9,"end_line":35,"end_character":17},"updated":"2017-10-26 15:03:00.000000000","message":"And this is ComputeNode.hypervisor_hostname?\n\nYup:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/scheduler/host_manager.py#L685-L686","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a69a6e3d1f002dc030fd95d016af53aed8e24c0a","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    fields \u003d {"},{"line_number":33,"context_line":"        \"compute_node_uuid\": fields.UUIDField(),"},{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_83155c4b","line":35,"range":{"start_line":35,"start_character":9,"end_line":35,"end_character":17},"in_reply_to":"3f4b6375_6006d654","updated":"2017-10-26 15:26:41.000000000","message":"yes.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \"service_host\": fields.StringField(),"},{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":39,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":40,"context_line":"        # as an encoded string."}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_4074face","line":37,"updated":"2017-10-26 15:03:00.000000000","message":"OK and these are:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/compute/claims.py#L142-L144\n\nWhich are the simple int limits from the Ram/Core/Disk filters if those filters are enabled, which they aren\u0027t by default if you\u0027re using the FilterScheduler (which is the default scheduler driver), but they are probably enabled if you\u0027re using the CachingScheduler, since that doesn\u0027t use Placement for filtering on VCPU/MEMORY_MB/DISK_GB.\n\nLooks good.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        \"nodename\": fields.StringField(),"},{"line_number":36,"context_line":"        \"cell_uuid\": fields.UUIDField(),"},{"line_number":37,"context_line":"        \"limits\": fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":39,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":40,"context_line":"        # as an encoded string."},{"line_number":41,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_c0510a38","line":38,"updated":"2017-10-26 15:03:00.000000000","message":"And this is the other known entry in the limits dict:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/compute/claims.py#L145\n\nHandled separately here because it\u0027s not a simple int type.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":39,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":40,"context_line":"        # as an encoded string."},{"line_number":41,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"},{"line_number":42,"context_line":"        \"allocation_request_version\": fields.StringField(nullable\u003dTrue),"},{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_4022baba","line":42,"range":{"start_line":41,"start_character":8,"end_line":42,"end_character":72},"updated":"2017-10-26 15:03:00.000000000","message":"And these are nullable\u003dTrue because if you\u0027re using the CachingScheduler, you won\u0027t have allocation requests since we wouldn\u0027t be using Placement.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        \"numa_limits\": fields.ObjectField(\"NUMATopologyLimits\", nullable\u003dTrue),"},{"line_number":39,"context_line":"        # An allocation_request is a non-trivial dict, and so it will be stored"},{"line_number":40,"context_line":"        # as an encoded string."},{"line_number":41,"context_line":"        \"allocation_request\": fields.StringField(nullable\u003dTrue),"},{"line_number":42,"context_line":"        \"allocation_request_version\": fields.StringField(nullable\u003dTrue),"},{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_54d838ed","line":42,"range":{"start_line":41,"start_character":8,"end_line":42,"end_character":72},"in_reply_to":"3f4b6375_4022baba","updated":"2017-10-26 17:39:54.000000000","message":"Yes, or in the case where the Placement service is unreachable.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @classmethod"},{"line_number":46,"context_line":"    def create_from_host_state(cls, host_state, allocation_request\u003dNone,"},{"line_number":47,"context_line":"            allocation_request_version\u003dNone):"},{"line_number":48,"context_line":"        \"\"\"A convenience method for converting a HostState, an"},{"line_number":49,"context_line":"        allocation_request, and an allocation_request_version into a Selection"},{"line_number":50,"context_line":"        object. Note that allocation_request and allocation_request_version"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_2376a83f","line":47,"range":{"start_line":46,"start_character":48,"end_line":47,"end_character":43},"updated":"2017-10-26 15:03:00.000000000","message":"nit: you don\u0027t have any tests for passing None here (or just leaving the defaults and only passing host_state).","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @classmethod"},{"line_number":46,"context_line":"    def create_from_host_state(cls, host_state, allocation_request\u003dNone,"},{"line_number":47,"context_line":"            allocation_request_version\u003dNone):"},{"line_number":48,"context_line":"        \"\"\"A convenience method for converting a HostState, an"},{"line_number":49,"context_line":"        allocation_request, and an allocation_request_version into a Selection"},{"line_number":50,"context_line":"        object. Note that allocation_request and allocation_request_version"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_cfd7f54a","line":47,"range":{"start_line":46,"start_character":48,"end_line":47,"end_character":43},"in_reply_to":"3f4b6375_2376a83f","updated":"2017-10-26 17:39:54.000000000","message":"Added.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                   service_host\u003dhost_state.host,"},{"line_number":58,"context_line":"                   nodename\u003dhost_state.nodename,"},{"line_number":59,"context_line":"                   cell_uuid\u003dhost_state.cell_uuid,"},{"line_number":60,"context_line":"                   limits\u003dlimits,"},{"line_number":61,"context_line":"                   numa_limits\u003dnuma_limits,"},{"line_number":62,"context_line":"                   allocation_request\u003dallocation_request_json,"},{"line_number":63,"context_line":"                   allocation_request_version\u003dallocation_request_version)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_4371a475","line":61,"range":{"start_line":60,"start_character":19,"end_line":61,"end_character":43},"updated":"2017-10-26 15:03:00.000000000","message":"As discussed with Dan a bit in IRC a week or two ago, this does now mean that we\u0027ll be storing limits in 3 places:\n\n1. RequestSpec: https://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/objects/request_spec.py#L70\n\n2. Legacy filter properties: https://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/scheduler/utils.py#L386\n\n3. And now this Selection object.\n\n1 and 2 are already passed to the compute service during a build operation today:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/conductor/manager.py#L1136-L1137\n\nBut down in the compute build_and_run_instance code, the request_spec is totally ignored and only filter_properties are used for calculating if we should be doing retries:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/compute/manager.py#L1853\n\nI guess the legacy filter_properties are also used for the server group affinity check:\n\nhttps://github.com/openstack/nova/blob/d36dcd52c24c32418fd358d245688c86664025d5/nova/compute/manager.py#L1297\n\n--\n\nNot that really means a whole lot here, it\u0027s just that we\u0027re now going to have this stuff in a 3rd location and we should be aware of that, and this one is going to be per-host, so if we\u0027re passing requestspec + filterproperties + (default max_attempts) at least 3 selection objects, we have this information going to compute in 5 forms. :)\n\nEventually we want to burn out the filterproperties from the compute and replace it\u0027s usage with the request spec, that work just hasn\u0027t been completed yet:\n\nhttps://blueprints.launchpad.net/nova/+spec/request-spec-use-by-compute","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a69a6e3d1f002dc030fd95d016af53aed8e24c0a","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                   service_host\u003dhost_state.host,"},{"line_number":58,"context_line":"                   nodename\u003dhost_state.nodename,"},{"line_number":59,"context_line":"                   cell_uuid\u003dhost_state.cell_uuid,"},{"line_number":60,"context_line":"                   limits\u003dlimits,"},{"line_number":61,"context_line":"                   numa_limits\u003dnuma_limits,"},{"line_number":62,"context_line":"                   allocation_request\u003dallocation_request_json,"},{"line_number":63,"context_line":"                   allocation_request_version\u003dallocation_request_version)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_8671eaaa","line":61,"range":{"start_line":60,"start_character":19,"end_line":61,"end_character":43},"in_reply_to":"3f4b6375_4371a475","updated":"2017-10-26 15:26:41.000000000","message":"Reasons we need to pass limits in Selection object even though RequestSpec and legacy filter properties contains them:\n\n1) We need to pass limits information for alternate hosts\n\n2) The RequestSpec object is not passed to the cell conductor in rescheduling\n\nJust noting for future archivist/historians/archeologists.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"244869b1b028148d1cbcfa2cc67292bca1975285","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"3f4b6375_6f06c154","line":24,"range":{"start_line":24,"start_character":42,"end_line":24,"end_character":67},"updated":"2017-10-26 17:47:39.000000000","message":"Were you going to remove this?","commit_id":"31650ec901d38753d480c5e20953d0b3469860b7"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"f7972991f67559fce60752ba009324b3040330e2","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"3f4b6375_273c6d2d","line":24,"range":{"start_line":24,"start_character":42,"end_line":24,"end_character":67},"in_reply_to":"3f4b6375_5548322b","updated":"2017-10-26 20:02:24.000000000","message":"Actually, it\u0027s needed for the unit tests in later patches, which check that the selection object created in the scheduler matches the expected selection object. So I\u0027ve put it back.","commit_id":"31650ec901d38753d480c5e20953d0b3469860b7"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6a7ab7125f455a593b0c44264000bab0ed9cce84","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":24,"context_line":"class Selection(base.NovaObject, ovo_base.ComparableVersionedObject):"},{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"3f4b6375_5548322b","line":24,"range":{"start_line":24,"start_character":42,"end_line":24,"end_character":67},"in_reply_to":"3f4b6375_6f06c154","updated":"2017-10-26 18:48:55.000000000","message":"Done","commit_id":"31650ec901d38753d480c5e20953d0b3469860b7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"244869b1b028148d1cbcfa2cc67292bca1975285","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Noting for future archivist/historians/archeologists: these are the reasons"},{"line_number":29,"context_line":"    we need to pass limits in Selection object, even though RequestSpec and"},{"line_number":30,"context_line":"    legacy filter properties contain them:"},{"line_number":31,"context_line":"        1) We need to pass limits information for alternate hosts"},{"line_number":32,"context_line":"        2) The RequestSpec object is not passed to the cell conductor in"},{"line_number":33,"context_line":"           rescheduling"},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    # Version 1.0: Initial version"}],"source_content_type":"text/x-python","patch_set":24,"id":"3f4b6375_4f8665bb","line":33,"range":{"start_line":28,"start_character":4,"end_line":33,"end_character":23},"updated":"2017-10-26 17:47:39.000000000","message":"I\u0027d remove this because I\u0027m actually in the process of implementing #2 so we can get the scheduler_hints from the request_spec during reschedules rather than filter_properties. Comments like this tend to bitrot once we change things elsewhere.","commit_id":"31650ec901d38753d480c5e20953d0b3469860b7"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6a7ab7125f455a593b0c44264000bab0ed9cce84","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    \"\"\"Represents a destination that has been selected by the Scheduler. Note"},{"line_number":26,"context_line":"    that these objects are not persisted to the database."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Noting for future archivist/historians/archeologists: these are the reasons"},{"line_number":29,"context_line":"    we need to pass limits in Selection object, even though RequestSpec and"},{"line_number":30,"context_line":"    legacy filter properties contain them:"},{"line_number":31,"context_line":"        1) We need to pass limits information for alternate hosts"},{"line_number":32,"context_line":"        2) The RequestSpec object is not passed to the cell conductor in"},{"line_number":33,"context_line":"           rescheduling"},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    # Version 1.0: Initial version"}],"source_content_type":"text/x-python","patch_set":24,"id":"3f4b6375_355376e4","line":33,"range":{"start_line":28,"start_character":4,"end_line":33,"end_character":23},"in_reply_to":"3f4b6375_4f8665bb","updated":"2017-10-26 18:48:55.000000000","message":"Removed","commit_id":"31650ec901d38753d480c5e20953d0b3469860b7"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f095a717227e6b6fe18f743b5f7e6da0cd6029e3","unresolved":false,"context_lines":[{"line_number":42,"context_line":"    }"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @classmethod"},{"line_number":45,"context_line":"    def create_from_host_state(cls, host_state, allocation_request\u003dNone,"},{"line_number":46,"context_line":"            allocation_request_version\u003dNone):"},{"line_number":47,"context_line":"        \"\"\"A convenience method for converting a HostState, an"},{"line_number":48,"context_line":"        allocation_request, and an allocation_request_version into a Selection"}],"source_content_type":"text/x-python","patch_set":31,"id":"1f485f77_34597534","line":45,"range":{"start_line":45,"start_character":8,"end_line":45,"end_character":30},"updated":"2017-11-16 16:14:03.000000000","message":"in all other objects, the pattern has been just \"from_XXX\", not \"create_from_XXX\". Making this just from_host_state() will enable shorter code and in following patches, enable you to not have to use parentheses-enclosed multi-line code when you can instead use a single line.","commit_id":"9b79c934988584140dd692aeefa87554ee6878c9"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"a11308f1f93381b2eaaadb500d34356d6aa1ff61","unresolved":false,"context_lines":[{"line_number":42,"context_line":"    }"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @classmethod"},{"line_number":45,"context_line":"    def create_from_host_state(cls, host_state, allocation_request\u003dNone,"},{"line_number":46,"context_line":"            allocation_request_version\u003dNone):"},{"line_number":47,"context_line":"        \"\"\"A convenience method for converting a HostState, an"},{"line_number":48,"context_line":"        allocation_request, and an allocation_request_version into a Selection"}],"source_content_type":"text/x-python","patch_set":31,"id":"1f485f77_4f6d7cca","line":45,"range":{"start_line":45,"start_character":8,"end_line":45,"end_character":30},"in_reply_to":"1f485f77_34597534","updated":"2017-11-16 16:52:30.000000000","message":"Done","commit_id":"9b79c934988584140dd692aeefa87554ee6878c9"}],"nova/scheduler/filter_scheduler.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0f335d5ed5c0d909151c702176887a9b3b732cdf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"7f515b1d_88e8d7b2","updated":"2017-10-01 19:20:15.000000000","message":"Can we forego all off these changes by recognizing that allocation requests and allocations_requests are the same thing?","commit_id":"70d8f8a7b91799e12ef1c178ca311f5853f9bc4f"}],"nova/tests/unit/objects/test_selection.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06a7cbc52421798eaf71d5b34d68d1e068f281a1","unresolved":false,"context_lines":[{"line_number":54,"context_line":"         \"resources\": {\"VCPU\": 1,"},{"line_number":55,"context_line":"                       \"MEMORY_MB\": 1024,"},{"line_number":56,"context_line":"                       \"DISK_GB\": 100}"},{"line_number":57,"context_line":"        }]}"},{"line_number":58,"context_line":"fake_limits \u003d {\"key1\": 17, \"key2\": 88}"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_eb5d9e15","line":57,"updated":"2017-10-05 15:16:02.000000000","message":"fake_alloc2 isn\u0027t used for anything, nor is fake_host2. They\u0027re identical other than the uuid. Are these setup for other tests you have planned here or later?","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"f7abd0dc5423c17ed3b6b44e42f666746dbe198b","unresolved":false,"context_lines":[{"line_number":54,"context_line":"         \"resources\": {\"VCPU\": 1,"},{"line_number":55,"context_line":"                       \"MEMORY_MB\": 1024,"},{"line_number":56,"context_line":"                       \"DISK_GB\": 100}"},{"line_number":57,"context_line":"        }]}"},{"line_number":58,"context_line":"fake_limits \u003d {\"key1\": 17, \"key2\": 88}"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_faea06d6","line":57,"in_reply_to":"7f515b1d_eb5d9e15","updated":"2017-10-05 17:34:21.000000000","message":"I had some tests that used them, but later versions of the object don\u0027t need them, so I\u0027ll remove them.","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"06a7cbc52421798eaf71d5b34d68d1e068f281a1","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        self.assertEqual(\"node\", dest.nodename)"},{"line_number":70,"context_line":"        self.assertEqual(uuids.cell, dest.cell_uuid)"},{"line_number":71,"context_line":"        self.assertEqual(fake_limit1, dest.numa_limits)"},{"line_number":72,"context_line":"        self.assertEqual(json_alloc, dest.allocation_request)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_passing_dict_allocation_fails(self):"},{"line_number":75,"context_line":"        self.assertRaises(ValueError, selection.Selection, service_host\u003d\"host\","}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_8ba4ea09","line":72,"updated":"2017-10-05 15:16:02.000000000","message":"I\u0027m not sure this test is particularly useful, FWIW :)","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"f7abd0dc5423c17ed3b6b44e42f666746dbe198b","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        self.assertEqual(\"node\", dest.nodename)"},{"line_number":70,"context_line":"        self.assertEqual(uuids.cell, dest.cell_uuid)"},{"line_number":71,"context_line":"        self.assertEqual(fake_limit1, dest.numa_limits)"},{"line_number":72,"context_line":"        self.assertEqual(json_alloc, dest.allocation_request)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_passing_dict_allocation_fails(self):"},{"line_number":75,"context_line":"        self.assertRaises(ValueError, selection.Selection, service_host\u003d\"host\","}],"source_content_type":"text/x-python","patch_set":13,"id":"7f515b1d_5a7d9a1a","line":72,"in_reply_to":"7f515b1d_8ba4ea09","updated":"2017-10-05 17:34:21.000000000","message":"Old habits, I guess. I\u0027ve been conditioned that we need to add tests like this to ensure that Python actually works. :)","commit_id":"5c9110e4c2aaa18ced74746a03fe5867870db1a3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6c3aaf37896d561a58de8346a40408d707970807","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    def test_create_with_values(self):"},{"line_number":48,"context_line":"        json_alloc \u003d jsonutils.dumps(fake_alloc1)"},{"line_number":49,"context_line":"        dest \u003d objects.Selection(service_host\u003d\"host\", nodename\u003d\"node\","},{"line_number":50,"context_line":"                compute_node_uuid\u003duuids.cn, cell_uuid\u003duuids.cell,"},{"line_number":51,"context_line":"                limits\u003dfake_limit1, numa_limits\u003dfake_numa_limit1,"},{"line_number":52,"context_line":"                allocation_request\u003djson_alloc,"},{"line_number":53,"context_line":"                allocation_request_version\u003dfake_alloc_version)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_c3a6b4c1","line":50,"range":{"start_line":50,"start_character":34,"end_line":50,"end_character":42},"updated":"2017-10-26 15:03:00.000000000","message":"Shouldn\u0027t this be uuids.host1 to be consistent with your fakes above? Doesn\u0027t really matter for the result of the test I guess.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"6f8920c39b5d653d1481f388b6fdaac4ef03b54a","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    def test_create_with_values(self):"},{"line_number":48,"context_line":"        json_alloc \u003d jsonutils.dumps(fake_alloc1)"},{"line_number":49,"context_line":"        dest \u003d objects.Selection(service_host\u003d\"host\", nodename\u003d\"node\","},{"line_number":50,"context_line":"                compute_node_uuid\u003duuids.cn, cell_uuid\u003duuids.cell,"},{"line_number":51,"context_line":"                limits\u003dfake_limit1, numa_limits\u003dfake_numa_limit1,"},{"line_number":52,"context_line":"                allocation_request\u003djson_alloc,"},{"line_number":53,"context_line":"                allocation_request_version\u003dfake_alloc_version)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_ef7bd1f1","line":50,"range":{"start_line":50,"start_character":34,"end_line":50,"end_character":42},"in_reply_to":"3f4b6375_26b7d63c","updated":"2017-10-26 17:39:54.000000000","message":"Done","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a69a6e3d1f002dc030fd95d016af53aed8e24c0a","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    def test_create_with_values(self):"},{"line_number":48,"context_line":"        json_alloc \u003d jsonutils.dumps(fake_alloc1)"},{"line_number":49,"context_line":"        dest \u003d objects.Selection(service_host\u003d\"host\", nodename\u003d\"node\","},{"line_number":50,"context_line":"                compute_node_uuid\u003duuids.cn, cell_uuid\u003duuids.cell,"},{"line_number":51,"context_line":"                limits\u003dfake_limit1, numa_limits\u003dfake_numa_limit1,"},{"line_number":52,"context_line":"                allocation_request\u003djson_alloc,"},{"line_number":53,"context_line":"                allocation_request_version\u003dfake_alloc_version)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3f4b6375_26b7d63c","line":50,"range":{"start_line":50,"start_character":34,"end_line":50,"end_character":42},"in_reply_to":"3f4b6375_c3a6b4c1","updated":"2017-10-26 15:26:41.000000000","message":"Yes, it should be consistent.","commit_id":"755381e09ccdea3085d40d3cd874f6ea11e8347f"}]}
