)]}'
{"nova/objects/fields.py":[{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b5f249757e6a3261b41dae0a4b76fc3a217a079b","unresolved":false,"context_lines":[{"line_number":418,"context_line":"class CIDR(FieldType):"},{"line_number":419,"context_line":"    @staticmethod"},{"line_number":420,"context_line":"    def coerce(obj, attr, value):"},{"line_number":421,"context_line":"        if re.match(\u0027^\\/[0-9a-f.:]+$\u0027, value):"},{"line_number":422,"context_line":"            return value"},{"line_number":423,"context_line":"        raise ValueError(_(\u0027A CIDR-compatible string is required in field\u0027"},{"line_number":424,"context_line":"                           \u0027 %(attr)s\u0027) % {\u0027attr\u0027: attr})"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_51a41a07","line":421,"updated":"2015-07-06 13:16:11.000000000","message":"Why not use a stricter regex like those listed here: http://blog.markhatton.co.uk/2011/03/15/regular-expressions-for-ip-addresses-cidr-ranges-and-hostnames/ ?\n\nGranted they\u0027re a bit fat but it seems a slim price to pay for correctness.","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":418,"context_line":"class CIDR(FieldType):"},{"line_number":419,"context_line":"    @staticmethod"},{"line_number":420,"context_line":"    def coerce(obj, attr, value):"},{"line_number":421,"context_line":"        if re.match(\u0027^\\/[0-9a-f.:]+$\u0027, value):"},{"line_number":422,"context_line":"            return value"},{"line_number":423,"context_line":"        raise ValueError(_(\u0027A CIDR-compatible string is required in field\u0027"},{"line_number":424,"context_line":"                           \u0027 %(attr)s\u0027) % {\u0027attr\u0027: attr})"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_8ee6f9e6","line":421,"in_reply_to":"ba3cc151_51a41a07","updated":"2015-07-06 15:46:23.000000000","message":"My recommended alternative would be to just use the (already-in-global-requirements) netaddr library. Example usage from nova.network.models.Subnet:\n\nhttps://github.com/openstack/nova/blob/master/nova/network/model.py#L257","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":418,"context_line":"class CIDR(FieldType):"},{"line_number":419,"context_line":"    @staticmethod"},{"line_number":420,"context_line":"    def coerce(obj, attr, value):"},{"line_number":421,"context_line":"        if re.match(\u0027^\\/[0-9a-f.:]+$\u0027, value):"},{"line_number":422,"context_line":"            return value"},{"line_number":423,"context_line":"        raise ValueError(_(\u0027A CIDR-compatible string is required in field\u0027"},{"line_number":424,"context_line":"                           \u0027 %(attr)s\u0027) % {\u0027attr\u0027: attr})"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_c3dcd21a","line":421,"in_reply_to":"ba3cc151_8ee6f9e6","updated":"2015-07-06 17:23:19.000000000","message":"To be clear, I provided the same regex as for the API validation here https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/schemas/v3/scheduler_hints.py\n\nI can see if using netaddr is better, for sure","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":458,"context_line":"            raise ValueError(six.text_type(e))"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":""},{"line_number":461,"context_line":"class CIDR(FieldType):"},{"line_number":462,"context_line":"    @staticmethod"},{"line_number":463,"context_line":"    def coerce(obj, attr, value):"},{"line_number":464,"context_line":"        # NOTE(sbauza): Since we don\u0027t know if the value can be either a v6 or"}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_a0e73811","line":461,"updated":"2015-07-17 16:16:10.000000000","message":"This should really be IPNetwork to mirror the version-specific ones, right?","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2b77a4db72df4e1ecba5eb208ec4e2f884b60363","unresolved":false,"context_lines":[{"line_number":458,"context_line":"            raise ValueError(six.text_type(e))"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":""},{"line_number":461,"context_line":"class CIDR(FieldType):"},{"line_number":462,"context_line":"    @staticmethod"},{"line_number":463,"context_line":"    def coerce(obj, attr, value):"},{"line_number":464,"context_line":"        # NOTE(sbauza): Since we don\u0027t know if the value can be either a v6 or"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a50d1a3_e46fb590","line":461,"in_reply_to":"9a41bdd9_a0e73811","updated":"2015-07-20 10:40:49.000000000","message":"No sorry, the IPNetwork type of field is for mentioning a full network with a CIDR (eg. 1.2.3.4/24) while here we only mention a CIDR (eg /24). See the tests for further details","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"}],"nova/objects/request_spec.py":[{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"0340a29d299aa1af6eca8faa56767dff180e872f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Copyright 2014 Red Hat, Inc."},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_dbb043de","line":1,"updated":"2015-01-08 13:26:39.000000000","message":"2015","commit_id":"69326d9d766150d031ffdba8c1bc6a371fdee563"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"0340a29d299aa1af6eca8faa56767dff180e872f","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from nova.openstack.common import log as logging"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class RequestSpec(base.NovaObject):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_3bef87b2","line":21,"updated":"2015-01-08 13:26:39.000000000","message":"question: why need LOG here?","commit_id":"69326d9d766150d031ffdba8c1bc6a371fdee563"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"97cd9b706464927b0ea9bc4ad7e0cd24022774d1","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        \u0027image\u0027: fields.DictOfStringsField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":31,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":33,"context_line":"        }"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_0ea0e7f2","line":32,"updated":"2015-01-07 17:12:04.000000000","message":"Super-picky: the closing brace should be out-dented the same way as in obj_relationships below.","commit_id":"69326d9d766150d031ffdba8c1bc6a371fdee563"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ae336c6484d9a175e5f491eea6fa85272f2d7ef5","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    fields \u003d {"},{"line_number":25,"context_line":"        \u0027image\u0027: fields.DictOfStringsField(nullable\u003dFalse),"},{"line_number":26,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":27,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":28,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":29,"context_line":"    }"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a961159_d1c9ed79","line":27,"updated":"2015-01-09 04:52:22.000000000","message":"the default value of nullable is False, so may needn\u0027t explicitly set at here","commit_id":"a2b3386eafa99553d4f5058173ace1a7f3f8142d"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"432b46032eb1caaa5199436d3a934a4dc57979b3","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from nova.objects import fields"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"# TODO(bauzas): Remove NovaObjectDictCompat"},{"line_number":21,"context_line":"class RequestSpec(base.NovaObject, base.NovaObjectDictCompat):"},{"line_number":22,"context_line":"    # Version 1.0: Initial version"},{"line_number":23,"context_line":"    VERSION \u003d \u00271.0\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a930d6b_42e004fa","line":20,"updated":"2015-01-27 00:06:54.000000000","message":"Since this is a new object I don\u0027t see why it should start with dict compatibility.","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"ad6613a708a54696a7a27cd7d60daf117b6b6a04","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from nova.objects import fields"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"# TODO(bauzas): Remove NovaObjectDictCompat"},{"line_number":21,"context_line":"class RequestSpec(base.NovaObject, base.NovaObjectDictCompat):"},{"line_number":22,"context_line":"    # Version 1.0: Initial version"},{"line_number":23,"context_line":"    VERSION \u003d \u00271.0\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba7be1f8_7c643622","line":20,"in_reply_to":"1a930d6b_42e004fa","updated":"2015-02-23 11:31:05.000000000","message":"Agreed.","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"648efeddc6905504973c3002d0433887f3a1e38e","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027Image\u0027),"},{"line_number":27,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":28,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":30,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a930d6b_7a0160ae","line":27,"updated":"2015-01-24 01:27:37.000000000","message":"Can we just get rid of this field entirely please? Yes, I know that on the spec review I said let\u0027s just keep the fields of the new object the same as the dict keys in the original request_spec, but honestly, let\u0027s just fix this cruft now and be done with it.\n\nThe only items in the instance_properties dictionary that are not already in the Flavor and Image object fields are project_id and numa_topology. The project_id string is already in the context so that\u0027s an easy one to grab. The InstanceNUMATopology object can be grabbed from the DB (in case of migrations) or constructed from the flavor and image (using nova.virt.hardware.numa_get_constraints() method).\n\nSo, I think we should just add a project_id and numa_topology field to the RequestSpec object and populate them appropriately. No need for a giant Instance object field, IMO.","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"432b46032eb1caaa5199436d3a934a4dc57979b3","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027Image\u0027),"},{"line_number":27,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":28,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":30,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a930d6b_a219a823","line":27,"in_reply_to":"1a930d6b_7a0160ae","updated":"2015-01-27 00:06:54.000000000","message":"+1.  Ultimately the scheduler doesn\u0027t need info about the instance being created, just resources being requested, so breaking the dependence on instance being in the request spec is a big win.","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"2f7b8d9d7fdd40d19f5b67cab3be71d433ed5211","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027Image\u0027),"},{"line_number":27,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":28,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":30,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba7be1f8_9cd48a48","line":27,"in_reply_to":"1a930d6b_7a0160ae","updated":"2015-02-23 11:21:44.000000000","message":"Actually I am not really sure I agree with making us calculate everything from flavor if it\u0027s not changed instance is a natural place to stash it and re-calculate it only when needed.\n\nHaving the same stuff on the request_spec field means just one more place to get it out of sync and create bugs. Before dropping the instance from it fully - I\u0027d like to see some deeper discussion of what the consequences would be.\n\nThe only thing I am not opposed to is not sending it twice (as instance arg and then as part of request_spec).","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"ad6613a708a54696a7a27cd7d60daf117b6b6a04","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027Image\u0027),"},{"line_number":27,"context_line":"        \u0027instance_properties\u0027: fields.ObjectField(\u0027Instance\u0027),"},{"line_number":28,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":30,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba7be1f8_3c59de5a","line":27,"in_reply_to":"ba7be1f8_9cd48a48","updated":"2015-02-23 11:31:05.000000000","message":"@ndipanov: I\u0027m not entirely sure what you\u0027re saying here... what is being \"calculated from flavor\" in the scheduler?","commit_id":"39e7abbfb755cca39a3b80cb608faa1c9396f023"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"e0c1f69fad1b67caeb1ea879edbe8f93f0f5ed68","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027os_type\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":39,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a016987_c99038ef","line":36,"updated":"2015-05-15 11:19:48.000000000","message":"What is os_type in this context ? Is it the same as the os_type you can set on glance images (ie linux vs windows) ?  If so, then you can use the  OSTypeField()  enum class I added in the commits you are depending on.","commit_id":"57b4bfe4d01b815849226a115d2e56887b04118b"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"835bb2a768e7afa8665e266960e67c87f1df84b1","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027os_type\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":39,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a016987_0d1db565","line":36,"in_reply_to":"7a016987_c99038ef","updated":"2015-05-21 17:53:00.000000000","message":"I can actually get rid of it since it\u0027s coming from the instance but could be checked against the ImageMeta you provided","commit_id":"57b4bfe4d01b815849226a115d2e56887b04118b"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"5df547bd2680cd421cd2f8d4eb8d76f94c8c19b0","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a016987_ccd6c6c2","line":34,"updated":"2015-05-28 16:16:23.000000000","message":"So reading this - I actually worry that we will now have this information in: 1) flavor 2) instance 3) request spec. that\u0027s a lot of places to keep track \n\nit makes it very confusing, and really easy to mess up especially in cases of a migration etc. on the compute node - my gut feeling is that we should move all of this functionality to the Instance object - and by that I mean: Instance object should expose _all_ of the API that is needed to deal with migrate/evacuate/live_migrate which require 2 diferent versions of some of this data (flavor, NUMA stuff etc)\n\nI would really like to see some drafts of how we can build some of the API around using the request spec to update the instance (and migration) objects on compute nodes, or alternatively drop all of this stuff from here and just link to the actual Instance object which then holds potentially 2 of any of the attributes that need 2 for migrate/resize etc.","commit_id":"20c151f0ec46a842b1165247e08c1709a0aafbd3"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"c89147f467bfae64746df1d8a1a4963faaebf766","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a016987_fc5ff13e","line":34,"in_reply_to":"7a016987_ccd6c6c2","updated":"2015-05-28 16:48:45.000000000","message":"Erm, the whole discussed happened a couple of PS before (I was providing an Instance object first) and the consensus was to split the object into smaller chunks so I also updated the spec with that and it was approved.\n\nSee the diff between :\nhttp://specs.openstack.org/openstack/nova-specs/specs/kilo/approved/request-spec-object.html\nand \nhttp://specs.openstack.org/openstack/nova-specs/specs/liberty/approved/request-spec-object.html\n\n\nSo, since it\u0027s a priority I would like to merge on the first milestone, could we maybe discuss on that for the next Nova meeting (and before that, on IRC ?)","commit_id":"20c151f0ec46a842b1165247e08c1709a0aafbd3"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"3cbae784a0b675e6b5a9267e394aa4b056faeb03","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a016987_703d47dc","line":34,"in_reply_to":"7a016987_fc5ff13e","updated":"2015-05-29 10:10:21.000000000","message":"So after a brief discussion on IRC it seems that we agree that we should look into this a bit more. I will try to word my general concern as a comment on the next PS for the sake of  clarity","commit_id":"20c151f0ec46a842b1165247e08c1709a0aafbd3"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"5df547bd2680cd421cd2f8d4eb8d76f94c8c19b0","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":38,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":39,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":40,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a016987_1da892da","line":37,"updated":"2015-05-28 16:16:23.000000000","message":"So without knowing the flavor of the instance being requested - we can\u0027t tell if this is a resize request or not. Actually I think we likely want to have a \"type\" field somewhere in there to make these things more explicit.","commit_id":"20c151f0ec46a842b1165247e08c1709a0aafbd3"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"1b0001f2e1042218f905e1198078241ba4efe4a3","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a016987_dd53f314","line":34,"updated":"2015-05-29 10:50:01.000000000","message":"My concern is about duplicating this information, since we will be using the request spec outside of the scheduler (ti gets sent over to coompute hosts, and they update it).\n\nI think we should either leave this stuff on an instance and just always link the instance here, or provide a clear and unambiguous API for getting/setting the right information on the instance object from the request spec object.","commit_id":"17f980133c5b95658d57e560e0ca42c3e2968f15"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"1270a641e83a1b5a61cd70cccab8f5b787d4aa60","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":27,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":28,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a016987_ddabb673","line":27,"updated":"2015-06-01 14:36:13.000000000","message":"So, @ndipanov was having some concerns about having an Instance object here instead of all the needed fields (see the previous PS), leaving the comment here since I want to discuss about it on IRC (but Irish people are on holiday today)","commit_id":"c4b6051c22c780ff6ca43abf5b4d9805aeb72b8f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f270fd3930287153aae26e31ee06cc0707a10b45","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    fields \u003d {"},{"line_number":26,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":27,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":28,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":13,"id":"5afe65bd_eae7643e","line":27,"in_reply_to":"7a016987_ddabb673","updated":"2015-06-02 20:38:21.000000000","message":"I think this is primarily providing an interface that the scheduler can use, so that what\u0027s here seems reasonable.  Rather than embedding an instance object what about populating this data from the instance table where appropriate, so we\u0027re not duplicating it in the database?","commit_id":"c4b6051c22c780ff6ca43abf5b4d9805aeb72b8f"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"976bf113cd5cea477c0b7c772dac5ee6c988d5ca","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        return limits"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"class GroupInfo(base.NovaObject):"},{"line_number":169,"context_line":"    # Version 1.0: Initial version"},{"line_number":170,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":171,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"5afe65bd_4c13dc5b","line":168,"updated":"2015-06-04 16:39:48.000000000","message":"eek, just rediscovered the InstanceGroup object...","commit_id":"d6de893425e20de6a466d3bc8069e74846d77423"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"7897d33239373e7f70917951a16f084e7163f70c","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from nova.objects import fields"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class RequestSpec(base.NovaObject):"},{"line_number":22,"context_line":"    # Version 1.0: Initial version"},{"line_number":23,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"fa32b979_f33445df","line":21,"updated":"2015-06-15 15:16:32.000000000","message":"Why is this a RequestSpec not simply a Request or ResourceRequest please?","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8f38484da571aeb94285c600779f065b42f43ee1","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from nova.objects import fields"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class RequestSpec(base.NovaObject):"},{"line_number":22,"context_line":"    # Version 1.0: Initial version"},{"line_number":23,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"fa32b979_935ff971","line":21,"in_reply_to":"fa32b979_f33445df","updated":"2015-06-15 15:29:05.000000000","message":"because the spec was approved that way :-)\n\nI\u0027m very bad at naming, but nobody really said no to my spec so I assumed it handy :-)","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"005fce41537116839f184821bad900e1baf4f6d6","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027Retry\u0027, nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027Limits\u0027, nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfStringsField(nullable\u003dTrue)"},{"line_number":45,"context_line":"    }"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":16,"id":"3afb71cf_88c7fb11","line":44,"updated":"2015-06-05 14:18:48.000000000","message":"This is should be like ImageMeta object https://github.com/openstack/nova/blob/master/nova/objects/image_meta.py#L24 \n\nOr this is next step plan?","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8f38484da571aeb94285c600779f065b42f43ee1","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027Retry\u0027, nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027Limits\u0027, nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfStringsField(nullable\u003dTrue)"},{"line_number":45,"context_line":"    }"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":16,"id":"fa32b979_73e8357d","line":44,"in_reply_to":"3afb71cf_88c7fb11","updated":"2015-06-15 15:29:05.000000000","message":"Because hints are just strings over strings with no validation on the API side, right ?\n\nOf course, a next step would consist on exposing a correct way to pass hints to the scheduler but for the moment, we can only assume that.","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ed416a110cf9592b8b5636d81baa36b12a41bd3a","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027Retry\u0027, nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027Limits\u0027, nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfStringsField(nullable\u003dTrue)"},{"line_number":45,"context_line":"    }"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":16,"id":"fa32b979_ebcbbd1c","line":44,"in_reply_to":"fa32b979_73e8357d","updated":"2015-06-16 12:35:59.000000000","message":"actually we have validation at v2.1 api ....https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/schemas/v3/scheduler_hints.py","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"1e3b6375c0701b42b9cfb1308aab013e620d282e","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027Retry\u0027, nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027Limits\u0027, nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfStringsField(nullable\u003dTrue)"},{"line_number":45,"context_line":"    }"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":16,"id":"fa32b979_f8013939","line":44,"in_reply_to":"fa32b979_ebcbbd1c","updated":"2015-06-16 21:48:07.000000000","message":"Oh good catch, dammit, I should definitely write a new Object then.","commit_id":"4b9f3b115e449637c5ef2715ccf921f176bfc676"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"2b2f22185476e24a768efc0d996e16a70c02da8a","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        \u0027num_attempts\u0027: fields.IntegerField(),"},{"line_number":147,"context_line":"        # NOTE(sbauza): Even if we are only using host/node strings, we need to"},{"line_number":148,"context_line":"        # know which compute nodes were tried"},{"line_number":149,"context_line":"        \u0027hosts\u0027: fields.ObjectField(\u0027ComputeNodeList\u0027),"},{"line_number":150,"context_line":"    }"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":20,"id":"fa32b979_a3011c3a","line":149,"updated":"2015-06-17 15:16:17.000000000","message":"You sure we need to send a list of whole compute nodes when we really only check the hostname and nodename combination here?","commit_id":"d298bfd5ec84927e32406f1ab49c09b6a34c88fe"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"776efbfbf3566fdf64faa5acde1f5bd6f6701636","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        \u0027num_attempts\u0027: fields.IntegerField(),"},{"line_number":147,"context_line":"        # NOTE(sbauza): Even if we are only using host/node strings, we need to"},{"line_number":148,"context_line":"        # know which compute nodes were tried"},{"line_number":149,"context_line":"        \u0027hosts\u0027: fields.ObjectField(\u0027ComputeNodeList\u0027),"},{"line_number":150,"context_line":"    }"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":20,"id":"fa32b979_149a616e","line":149,"in_reply_to":"fa32b979_a3011c3a","updated":"2015-06-18 08:41:11.000000000","message":"Yeah, I know it\u0027s maybe overthought about that, but I disliked the list of lists [host, node] which was meaning that it was needing to be modified if for example we were removing the node stuff (or the host stuff).\n\nThinking up about that, the retries are there for knowing which Compute Nodes were checked, right? So, that\u0027s why I\u0027m thinking it would be far better to leave a list of ComputeNodes.","commit_id":"d298bfd5ec84927e32406f1ab49c09b6a34c88fe"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"2b2f22185476e24a768efc0d996e16a70c02da8a","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        for host in hosts:"},{"line_number":167,"context_line":"            # NOTE(sbauza): Yeah that\u0027s ugly, but the list is [host, node]..."},{"line_number":168,"context_line":"            cn \u003d objects.ComputeNode(host\u003dhost[0],"},{"line_number":169,"context_line":"                                     hypervisor_hostname\u003dhost[1])"},{"line_number":170,"context_line":"            computes.append(cn)"},{"line_number":171,"context_line":"        retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dcomputes)"},{"line_number":172,"context_line":"        return retry_obj"}],"source_content_type":"text/x-python","patch_set":20,"id":"fa32b979_d575f797","line":169,"updated":"2015-06-17 15:16:17.000000000","message":"very interested in why you chose to send an incomplete object like this. We really should not be doing this - it\u0027s either an acutal object with an identity, or should not use objects. Versioning makes no sense for this etc. bizarre imho","commit_id":"d298bfd5ec84927e32406f1ab49c09b6a34c88fe"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"776efbfbf3566fdf64faa5acde1f5bd6f6701636","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        for host in hosts:"},{"line_number":167,"context_line":"            # NOTE(sbauza): Yeah that\u0027s ugly, but the list is [host, node]..."},{"line_number":168,"context_line":"            cn \u003d objects.ComputeNode(host\u003dhost[0],"},{"line_number":169,"context_line":"                                     hypervisor_hostname\u003dhost[1])"},{"line_number":170,"context_line":"            computes.append(cn)"},{"line_number":171,"context_line":"        retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dcomputes)"},{"line_number":172,"context_line":"        return retry_obj"}],"source_content_type":"text/x-python","patch_set":20,"id":"fa32b979_74988d6a","line":169,"in_reply_to":"fa32b979_d575f797","updated":"2015-06-18 08:41:11.000000000","message":"Well, a better implementation would query the ComputeNode classmethod get_by_host_and_nodename() to get the right full ComputeNode object.\nI can modify that.","commit_id":"d298bfd5ec84927e32406f1ab49c09b6a34c88fe"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b52f3d044c8d88e3dfb1aba5cf1c3d8375440b92","unresolved":false,"context_lines":[{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":226,"context_line":"class Hints(base.NovaObject):"},{"line_number":227,"context_line":"    # Version 1.0: Initial version"},{"line_number":228,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":229,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"fa32b979_d5f61a8e","line":226,"updated":"2015-06-18 17:08:40.000000000","message":"I\u0027m a bit concerned about this.  This shuts the door for any out of tree filters, and I don\u0027t think we should do that.\n\nScheduling hints are a terrible API experience but it\u0027s also an API that I don\u0027t think we have any ability to modify in a structured way.  So I\u0027m not sure what benefit we get from allowing only a set of predefined hints.  This applies to the API schema validation as well really.","commit_id":"38d87b4d7f10368247b51884d5f7a55e88f2996b"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8174c7ddf09226b96cb9eaac896ec0a5631a4fcf","unresolved":false,"context_lines":[{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":226,"context_line":"class Hints(base.NovaObject):"},{"line_number":227,"context_line":"    # Version 1.0: Initial version"},{"line_number":228,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":229,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"fa32b979_f15c72f2","line":226,"in_reply_to":"fa32b979_d5f61a8e","updated":"2015-06-19 10:04:51.000000000","message":"Let me consider some way to add free-form extra hints that we could add without impacting the validation of the existing in-tree filters.","commit_id":"38d87b4d7f10368247b51884d5f7a55e88f2996b"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b5f249757e6a3261b41dae0a4b76fc3a217a079b","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":39,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":40,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":41,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_311dd60f","line":40,"updated":"2015-07-06 13:16:11.000000000","message":"hmm nova-client offers min-count and max-count now. I think num-instances is still supported but it\u0027s deprecated. Maybe (not necessarily in this review) we need to make that change here too?","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":39,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":40,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":41,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_c3493290","line":40,"in_reply_to":"ba3cc151_0e066920","updated":"2015-07-06 17:23:19.000000000","message":"Well, min/max_count are only an API stuff, not going down to the conductor neither to the scheduler. It only serves for checking what the user wants vs. what he can have (thru quotas) at the API level before deciding how many instances can be created.\n\nHere is where the translation is done https://github.com/openstack/nova/blob/master/nova/compute/api.py#L927-L928","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":38,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":39,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":40,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":41,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":42,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_0e066920","line":40,"in_reply_to":"ba3cc151_311dd60f","updated":"2015-07-06 15:46:23.000000000","message":"Yeah, Alexis is correct. We should change that in this review.","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b5f249757e6a3261b41dae0a4b76fc3a217a079b","unresolved":false,"context_lines":[{"line_number":69,"context_line":"            self.image \u003d image"},{"line_number":70,"context_line":"        elif isinstance(image, dict):"},{"line_number":71,"context_line":"            # NOTE(sbauza): Until Nova is fully providing an ImageMeta object"},{"line_number":72,"context_line":"            # for getting properties, we still need to hydrade it here"},{"line_number":73,"context_line":"            # TODO(sbauza): To be removed once all RequestSpec hydrations are"},{"line_number":74,"context_line":"            # done on the conductor side and if the image is an ImageMeta"},{"line_number":75,"context_line":"            self.image \u003d objects.ImageMeta.from_dict(image)"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_319396a5","line":72,"updated":"2015-07-06 13:16:11.000000000","message":"nit: hydrate","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b5f249757e6a3261b41dae0a4b76fc3a217a079b","unresolved":false,"context_lines":[{"line_number":193,"context_line":"                context\u003dcontext,"},{"line_number":194,"context_line":"                host\u003dhost[0],"},{"line_number":195,"context_line":"                nodename\u003dhost[1])"},{"line_number":196,"context_line":"            computes.append(cn)"},{"line_number":197,"context_line":"        retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dcomputes)"},{"line_number":198,"context_line":"        return retry_obj"},{"line_number":199,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_31f5d682","line":196,"updated":"2015-07-06 13:16:11.000000000","message":"you could do the whole thing in a list comprehension:\n\n    objs \u003d [objects.ComputeNode.get_by_host_and_nodename(context, host, node)\n            for host, node in retry_dict.get(\u0027hosts\u0027)]\n    retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dobjs)","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":193,"context_line":"                context\u003dcontext,"},{"line_number":194,"context_line":"                host\u003dhost[0],"},{"line_number":195,"context_line":"                nodename\u003dhost[1])"},{"line_number":196,"context_line":"            computes.append(cn)"},{"line_number":197,"context_line":"        retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dcomputes)"},{"line_number":198,"context_line":"        return retry_obj"},{"line_number":199,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_b5fea103","line":196,"in_reply_to":"ba3cc151_31f5d682","updated":"2015-07-06 17:23:19.000000000","message":"Done","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027NUMATopologyLimits\u0027,"},{"line_number":208,"context_line":"                                            nullable\u003dTrue,"},{"line_number":209,"context_line":"                                            default\u003dNone),"},{"line_number":210,"context_line":"        \u0027vcpu\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":211,"context_line":"        \u0027disk_gb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":212,"context_line":"        \u0027memory_mb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":213,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_5195f03d","line":210,"updated":"2015-07-06 15:46:23.000000000","message":"Should be an IntegerField. There is no such thing as a half a vCPU.","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027NUMATopologyLimits\u0027,"},{"line_number":208,"context_line":"                                            nullable\u003dTrue,"},{"line_number":209,"context_line":"                                            default\u003dNone),"},{"line_number":210,"context_line":"        \u0027vcpu\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":211,"context_line":"        \u0027disk_gb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":212,"context_line":"        \u0027memory_mb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":213,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_75081929","line":210,"in_reply_to":"ba3cc151_5195f03d","updated":"2015-07-06 17:23:19.000000000","message":"Done","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":208,"context_line":"                                            nullable\u003dTrue,"},{"line_number":209,"context_line":"                                            default\u003dNone),"},{"line_number":210,"context_line":"        \u0027vcpu\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":211,"context_line":"        \u0027disk_gb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":212,"context_line":"        \u0027memory_mb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":213,"context_line":"    }"},{"line_number":214,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_31738c4f","line":211,"updated":"2015-07-06 15:46:23.000000000","message":"ditto.","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":209,"context_line":"                                            default\u003dNone),"},{"line_number":210,"context_line":"        \u0027vcpu\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":211,"context_line":"        \u0027disk_gb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":212,"context_line":"        \u0027memory_mb\u0027: fields.FloatField(nullable\u003dTrue, default\u003dNone),"},{"line_number":213,"context_line":"    }"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_517c1020","line":212,"updated":"2015-07-06 15:46:23.000000000","message":"ditto.","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f9a6f818dd53c5b77128682f41e4ad95108072c2","unresolved":false,"context_lines":[{"line_number":220,"context_line":"    def from_dict(cls, limits_dict):"},{"line_number":221,"context_line":"        limits \u003d cls(**limits_dict)"},{"line_number":222,"context_line":"        # NOTE(sbauza): Since the limits can be set for each field or not, we"},{"line_number":223,"context_line":"        # prefer to have the fields nullable but having None at least"},{"line_number":224,"context_line":"        limits.obj_set_defaults()"},{"line_number":225,"context_line":"        return limits"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_11dbe81c","line":223,"updated":"2015-07-06 15:46:23.000000000","message":"s/nullable but having None at least/nullable, but default the value to None/","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":220,"context_line":"    def from_dict(cls, limits_dict):"},{"line_number":221,"context_line":"        limits \u003d cls(**limits_dict)"},{"line_number":222,"context_line":"        # NOTE(sbauza): Since the limits can be set for each field or not, we"},{"line_number":223,"context_line":"        # prefer to have the fields nullable but having None at least"},{"line_number":224,"context_line":"        limits.obj_set_defaults()"},{"line_number":225,"context_line":"        return limits"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_5510754e","line":223,"in_reply_to":"ba3cc151_11dbe81c","updated":"2015-07-06 17:23:19.000000000","message":"Done","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b5f249757e6a3261b41dae0a4b76fc3a217a079b","unresolved":false,"context_lines":[{"line_number":254,"context_line":"    def from_dict(cls, hints_dict):"},{"line_number":255,"context_line":"        hints \u003d cls()"},{"line_number":256,"context_line":"        if hints_dict:"},{"line_number":257,"context_line":"            for hint in hints_dict:"},{"line_number":258,"context_line":"                if hint in [\u0027different_host\u0027, \u0027same_host\u0027]:"},{"line_number":259,"context_line":"                    if isinstance(hints_dict[hint], six.string_types):"},{"line_number":260,"context_line":"                        # NOTE(sbauza): The filter accepts to pass either a"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_c3baa10a","line":257,"updated":"2015-07-06 13:16:11.000000000","message":"nit: you can eliminate a layer of nesting by using: hints_dict or []","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8682c038e00add7d8eb9277f889b01642f0eb5c8","unresolved":false,"context_lines":[{"line_number":254,"context_line":"    def from_dict(cls, hints_dict):"},{"line_number":255,"context_line":"        hints \u003d cls()"},{"line_number":256,"context_line":"        if hints_dict:"},{"line_number":257,"context_line":"            for hint in hints_dict:"},{"line_number":258,"context_line":"                if hint in [\u0027different_host\u0027, \u0027same_host\u0027]:"},{"line_number":259,"context_line":"                    if isinstance(hints_dict[hint], six.string_types):"},{"line_number":260,"context_line":"                        # NOTE(sbauza): The filter accepts to pass either a"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba3cc151_756d79cb","line":257,"in_reply_to":"ba3cc151_c3baa10a","updated":"2015-07-06 17:23:19.000000000","message":"Done","commit_id":"70e07fc54ee39c7e9e964930783e0f4cccdbe340"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"c170cc31f689e06520d8186ccad802f62d4ded31","unresolved":false,"context_lines":[{"line_number":186,"context_line":"        retry_obj \u003d cls()"},{"line_number":187,"context_line":"        retry_obj.num_attempts \u003d retry_dict.get(\u0027num_attempts\u0027)"},{"line_number":188,"context_line":"        # NOTE(sbauza): each retry_dict[\u0027hosts\u0027] item is a list of [host, node]"},{"line_number":189,"context_line":"        computes \u003d [objects.ComputeNode.get_by_host_and_nodename("},{"line_number":190,"context_line":"            context\u003dcontext,"},{"line_number":191,"context_line":"            host\u003dhost,"},{"line_number":192,"context_line":"            nodename\u003dnode) for host, node in retry_dict.get(\u0027hosts\u0027)]"}],"source_content_type":"text/x-python","patch_set":26,"id":"9a41bdd9_8dfbbb46","line":189,"updated":"2015-07-15 20:02:02.000000000","message":"I\u0027m working on adding persistence and this lookup makes testing more troublesome.  And it makes me question the idea of doing a db call in a from_dict method.  Does this really need to be a ComputeNode object?  That\u0027s a whole lot of baggage to carry around just to get a (host, node) tuple.  If this really needs to be an object I would suggest adding a new object just to store this information, and populate it based on the retry_dict passed in here.","commit_id":"3d2a5c93242fa4b2cf2c9b7ff5e271e9bd9be1b4"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":34,"context_line":"                                            nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_40b98cca","line":32,"updated":"2015-07-17 16:16:10.000000000","message":"Seems like a request spec should include the flavor we\u0027re targetting. Why not just include a Flavor here and not these attributes? I feel like we\u0027re just going to have to chase new attributes here  over time.","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"885fea017323930cc97731bcfdf42d911c5508b7","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":34,"context_line":"                                            nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a50d1a3_84c83176","line":32,"in_reply_to":"9a41bdd9_40b98cca","updated":"2015-07-20 10:55:23.000000000","message":"We already have an instance_type field which refers to a Flavor.\nHere, I added those fields because they were hydrated by the instance properties (see the from_primitives() method) but I don\u0027t know really if we can just leave the Flavor here...","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        self.scheduler_hints \u003d Hints.from_dict(hints_dict)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @classmethod"},{"line_number":138,"context_line":"    def from_primitives(cls, context, request_spec, filter_properties):"},{"line_number":139,"context_line":"        num_instances \u003d request_spec.get(\u0027num_instances\u0027, 1)"},{"line_number":140,"context_line":"        spec \u003d cls(context, num_instances\u003dnum_instances)"},{"line_number":141,"context_line":"        # Hydrate from request_spec first"}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_80ed54b9","line":138,"range":{"start_line":138,"start_character":38,"end_line":138,"end_character":50},"updated":"2015-07-17 16:16:10.000000000","message":"This is a conventional request spec dict?\n\nI think a docstring for this method is probably (very) warranted.","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"885fea017323930cc97731bcfdf42d911c5508b7","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        self.scheduler_hints \u003d Hints.from_dict(hints_dict)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @classmethod"},{"line_number":138,"context_line":"    def from_primitives(cls, context, request_spec, filter_properties):"},{"line_number":139,"context_line":"        num_instances \u003d request_spec.get(\u0027num_instances\u0027, 1)"},{"line_number":140,"context_line":"        spec \u003d cls(context, num_instances\u003dnum_instances)"},{"line_number":141,"context_line":"        # Hydrate from request_spec first"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a50d1a3_24b03df4","line":138,"range":{"start_line":138,"start_character":38,"end_line":138,"end_character":50},"in_reply_to":"9a41bdd9_80ed54b9","updated":"2015-07-20 10:55:23.000000000","message":"Oh yeah, definitely.","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":163,"context_line":"class Retry(base.NovaObject):"},{"line_number":164,"context_line":"    # Version 1.0: Initial version"},{"line_number":165,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_2079e8fc","line":163,"range":{"start_line":163,"start_character":6,"end_line":163,"end_character":11},"updated":"2015-07-17 16:16:10.000000000","message":"Can we call this RetryContext or something similar? Just calling a retry is not very descriptive and has the potential to clash with other things we retry. Maybe even SchedulerRetry or something.","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":194,"context_line":""},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":197,"context_line":"class Limits(base.NovaObject):"},{"line_number":198,"context_line":"    # Version 1.0: Initial version"},{"line_number":199,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":200,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_40f18c69","line":197,"range":{"start_line":197,"start_character":6,"end_line":197,"end_character":12},"updated":"2015-07-17 16:16:10.000000000","message":"Same here. This seems very scheduler specific, but could be interpreted as many other types of limits elsewhere. I think clarity could be improved with a more specific name.","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":224,"context_line":"class Hints(base.NovaObject):"},{"line_number":225,"context_line":"    # Version 1.0: Initial version"},{"line_number":226,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":227,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_c0fd9c3c","line":224,"range":{"start_line":224,"start_character":6,"end_line":224,"end_character":11},"updated":"2015-07-17 16:16:10.000000000","message":"These are clearly scheduler hints, so we should name it appropriately :)","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"98411692cfad27cf8b45246fb6c8605d8b72ea1c","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        \u0027different_host\u0027: fields.ListOfUUIDsField(nullable\u003dTrue, default\u003dNone),"},{"line_number":232,"context_line":"        \u0027same_host\u0027: fields.ListOfUUIDsField(nullable\u003dTrue, default\u003dNone),"},{"line_number":233,"context_line":"        # NOTE(sbauza): This is unfortunately a free-form JSON string"},{"line_number":234,"context_line":"        \u0027query\u0027: fields.StringField(nullable\u003dTrue, default\u003dNone),"},{"line_number":235,"context_line":"        \u0027target_cell\u0027: fields.StringField(nullable\u003dTrue, default\u003dNone),"},{"line_number":236,"context_line":"        \u0027build_near_host_ip\u0027: fields.IPV4AndV6AddressField(nullable\u003dTrue,"},{"line_number":237,"context_line":"                                                           default\u003dNone),"}],"source_content_type":"text/x-python","patch_set":28,"id":"9a41bdd9_e0b5407e","line":234,"updated":"2015-07-17 16:16:10.000000000","message":"Hmm, what string is it specifically?","commit_id":"fc3d1aeda03270e04de448796add7e0db18e42e1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7ec5ee150ef56e41e2e14c664b291d5ad77b65af","unresolved":false,"context_lines":[{"line_number":240,"context_line":"        \u0027target_cell\u0027: fields.StringField(nullable\u003dTrue, default\u003dNone),"},{"line_number":241,"context_line":"        \u0027build_near_host_ip\u0027: fields.IPV4AndV6AddressField(nullable\u003dTrue,"},{"line_number":242,"context_line":"                                                           default\u003dNone),"},{"line_number":243,"context_line":"        \u0027cidr\u0027: fields.CIDRField(nullable\u003dTrue, default\u003dNone),"},{"line_number":244,"context_line":"        # NOTE(sbauza): In order to support out-of-tree filters, we need to"},{"line_number":245,"context_line":"        # provide a way to still support external hints"},{"line_number":246,"context_line":"        \u0027extra_hints\u0027: fields.DictOfStringsField(default\u003d{})"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a50d1a3_f17dd91c","line":243,"updated":"2015-07-21 18:48:03.000000000","message":"So I\u0027m not sure how this works or what this means. It\u0027s just a CIDR mask like /24, right? So does that mean \"boot me 5 instances that are all on the same /24\" or something? If so, just storing 24 here works fine, right?","commit_id":"992c80e2107ad95eafe5c0c5e4058598f48c2087"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"d0fcac250556c49fd1f8e7d113871d82fe7efea7","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027SchedulerRetries\u0027, nullable\u003dTrue),"},{"line_number":46,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027SchedulerLimits\u0027, nullable\u003dTrue),"},{"line_number":47,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.ObjectField(\u0027SchedulerHints\u0027, nullable\u003dTrue)"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":33,"id":"3a50d1a3_457612a5","line":48,"updated":"2015-07-22 15:55:20.000000000","message":"Here, we just discussed in the meetup. We\u0027d like to have scheduler_hints be a DictOfStringsField, instead of the SchedulerHints object.","commit_id":"091d988ddccaf77852793ccf2742f42a11ccb754"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"f0b9fa96640a047b8729ef27394ddc2bc12c827d","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027SchedulerRetries\u0027, nullable\u003dTrue),"},{"line_number":46,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027SchedulerLimits\u0027, nullable\u003dTrue),"},{"line_number":47,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.ObjectField(\u0027SchedulerHints\u0027, nullable\u003dTrue)"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":33,"id":"3a50d1a3_b79864c1","line":48,"in_reply_to":"3a50d1a3_457612a5","updated":"2015-07-22 18:12:58.000000000","message":"Fair enough","commit_id":"091d988ddccaf77852793ccf2742f42a11ccb754"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"d0fcac250556c49fd1f8e7d113871d82fe7efea7","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        # NOTE(sbauza): In order to support out-of-tree filters, we need to"},{"line_number":250,"context_line":"        # provide a way to still support external hints"},{"line_number":251,"context_line":"        \u0027extra_hints\u0027: fields.DictOfStringsField(default\u003d{})"},{"line_number":252,"context_line":"    }"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":255,"context_line":"        super(SchedulerHints, self).__init__(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":33,"id":"3a50d1a3_c598e2c2","line":252,"updated":"2015-07-22 15:55:20.000000000","message":"We will just use a DictOfStrings field in the main RequestSpec object for the time being, and enforce the validation of custom scheduler hints via a REST API JSONSchema that alaski will work on separately.","commit_id":"091d988ddccaf77852793ccf2742f42a11ccb754"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"f0b9fa96640a047b8729ef27394ddc2bc12c827d","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        # NOTE(sbauza): In order to support out-of-tree filters, we need to"},{"line_number":250,"context_line":"        # provide a way to still support external hints"},{"line_number":251,"context_line":"        \u0027extra_hints\u0027: fields.DictOfStringsField(default\u003d{})"},{"line_number":252,"context_line":"    }"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":255,"context_line":"        super(SchedulerHints, self).__init__(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":33,"id":"3a50d1a3_57f000fe","line":252,"in_reply_to":"3a50d1a3_c598e2c2","updated":"2015-07-22 18:12:58.000000000","message":"Sounds good, just maybe adding a big fat comment for the field.","commit_id":"091d988ddccaf77852793ccf2742f42a11ccb754"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"2eeaba67b9fba85fd624cf7af686a108aa372ce0","unresolved":false,"context_lines":[{"line_number":264,"context_line":"                    # NOTE(sbauza): The filter accepts to pass either a"},{"line_number":265,"context_line":"                    # string or a list, passing a list anyway"},{"line_number":266,"context_line":"                    hints_dict[hint] \u003d [hints_dict[hint]]"},{"line_number":267,"context_line":"            if hint \u003d\u003d \u0027cidr\u0027:"},{"line_number":268,"context_line":"                cidr \u003d hints_dict[hint]"},{"line_number":269,"context_line":"                try:"},{"line_number":270,"context_line":"                    netmask \u003d cidr.split(\u0027/\u0027)[1]"}],"source_content_type":"text/x-python","patch_set":33,"id":"3a50d1a3_305d4915","line":267,"updated":"2015-07-22 14:37:42.000000000","message":"nit: can this be factored out to a separate private staticmethod please? It\u0027s a bit bulkier than the {different,same}_host special case","commit_id":"091d988ddccaf77852793ccf2742f42a11ccb754"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"},{"line_number":46,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":47,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue)"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_a54356ae","line":48,"range":{"start_line":48,"start_character":71,"end_line":48,"end_character":73},"updated":"2015-07-28 16:51:00.000000000","message":"This needs a trailing comma. For the next guy.","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":58,"context_line":"        \u0027instance_group\u0027: [(\u00271.0\u0027, \u00271.9\u0027)],"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def _from_image(self, image):"},{"line_number":62,"context_line":"        if isinstance(image, objects.ImageMeta):"},{"line_number":63,"context_line":"            self.image \u003d image"},{"line_number":64,"context_line":"        elif isinstance(image, dict):"}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_45329211","line":61,"updated":"2015-07-28 16:51:00.000000000","message":"This just sets self.image, which confuses me because it seems like it means \"request_spec_from_image\". Maybe making this named _image_meta_from_image() would make that clearer...","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        if not retry_dict:"},{"line_number":208,"context_line":"            # NOTE(sbauza) We consider all the fields needed to present or the"},{"line_number":209,"context_line":"            # whole object has to be null"},{"line_number":210,"context_line":"            return"},{"line_number":211,"context_line":"        retry_obj \u003d cls()"},{"line_number":212,"context_line":"        retry_obj.num_attempts \u003d retry_dict.get(\u0027num_attempts\u0027)"},{"line_number":213,"context_line":"        # NOTE(sbauza): each retry_dict[\u0027hosts\u0027] item is a list of [host, node]"}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_3600da00","line":210,"updated":"2015-07-28 16:51:00.000000000","message":"I don\u0027t really understand this. It\u0027s a param that is not optional, but if they pass in something empty then we return None? Seems like we should raise something here, right?","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":209,"context_line":"            # whole object has to be null"},{"line_number":210,"context_line":"            return"},{"line_number":211,"context_line":"        retry_obj \u003d cls()"},{"line_number":212,"context_line":"        retry_obj.num_attempts \u003d retry_dict.get(\u0027num_attempts\u0027)"},{"line_number":213,"context_line":"        # NOTE(sbauza): each retry_dict[\u0027hosts\u0027] item is a list of [host, node]"},{"line_number":214,"context_line":"        computes \u003d [objects.ComputeNode(context\u003dcontext, host\u003dhost,"},{"line_number":215,"context_line":"                                        hypervisor_hostname\u003dnode)"}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_16a7de0b","line":212,"updated":"2015-07-28 16:51:00.000000000","message":"num_attempts is not nullable, but .get() can return None. So either you should use [] and catch that, or provide a default here. The ValueError from the field will probably be confusing, right?","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        # NOTE(sbauza): each retry_dict[\u0027hosts\u0027] item is a list of [host, node]"},{"line_number":214,"context_line":"        computes \u003d [objects.ComputeNode(context\u003dcontext, host\u003dhost,"},{"line_number":215,"context_line":"                                        hypervisor_hostname\u003dnode)"},{"line_number":216,"context_line":"                    for host, node in retry_dict.get(\u0027hosts\u0027)]"},{"line_number":217,"context_line":"        retry_obj.hosts \u003d objects.ComputeNodeList(objects\u003dcomputes)"},{"line_number":218,"context_line":"        return retry_obj"},{"line_number":219,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_d694168c","line":216,"updated":"2015-07-28 16:51:00.000000000","message":"if retry_dict  has no hosts, this will fail confusingly with \"Failed to unpack None\" or something, right?","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"601ecf3b41fadafdb2c224f906864bef8c5bf9bf","unresolved":false,"context_lines":[{"line_number":241,"context_line":"        limits \u003d cls(**limits_dict)"},{"line_number":242,"context_line":"        # NOTE(sbauza): Since the limits can be set for each field or not, we"},{"line_number":243,"context_line":"        # prefer to have the fields nullable, but default the value to None"},{"line_number":244,"context_line":"        limits.obj_set_defaults()"},{"line_number":245,"context_line":"        return limits"}],"source_content_type":"text/x-python","patch_set":36,"id":"3a50d1a3_b6270a11","line":244,"updated":"2015-07-28 16:51:00.000000000","message":"I think this is an okay usage of set_defaults(). We\u0027re doing it because we (presumably) received the entire thing in primitive form and we have little worry of overwriting something because we\u0027re storing this (eventually) as a blob in the DB (right?).","commit_id":"cdedd0cc1bb3481a5c8f027d1c36d6ddf7ee1d74"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"c566f2e667f4464e0ad5bb0127eb1b9288546e68","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_09075c19","line":31,"updated":"2015-07-30 13:12:24.000000000","message":"An InstanceNUMATopology has already been fitted to specific CPUs and cells. Shouldn\u0027t we store the abstract request instead? Equivalently to the ImageMetaProps today.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"d28bf74e70cacc6bb8e6a0a0d19943d6f0cd0417","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_9ab40836","line":31,"in_reply_to":"3a50d1a3_09075c19","updated":"2015-07-30 13:17:56.000000000","message":"No, we should still continue to pass the same object given in the request_spec[\u0027instance_properties\u0027][\u0027numa_topology\u0027] dict as given in _from_instance()...","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"d4b51be9e78f9b291ff8bb5b9cce8c2fb1374b45","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":29,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":32,"context_line":"                                            nullable\u003dTrue),"},{"line_number":33,"context_line":"        \u0027pci_requests\u0027: fields.ObjectField(\u0027InstancePCIRequests\u0027,"},{"line_number":34,"context_line":"                                           nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_e3d6c8f0","line":31,"in_reply_to":"3a50d1a3_09075c19","updated":"2015-07-30 14:22:00.000000000","message":"OK, I see from numa_fit_instance_to_host that InstanceNUMATopology objects can be either fitted or unfitted. My mistake, apologies.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"1de2421d9d7f8bf4011fd1ed27dd0588488dffda","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":38,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":39,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":40,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_fc33e911","line":37,"updated":"2015-07-30 03:09:13.000000000","message":"Just a thought: do we want to keep calling this \"instance_type\"? I thought we were calling everything \"flavor\" now","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a923379ced86f38b7bb616c7717632928f5ec0b5","unresolved":false,"context_lines":[{"line_number":34,"context_line":"                                           nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":37,"context_line":"        \u0027instance_type\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":38,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":39,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":40,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_c2ab941d","line":37,"in_reply_to":"3a50d1a3_fc33e911","updated":"2015-07-30 09:53:29.000000000","message":"uh, excellent question. Leaving that off for the moment","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"635e6ce730c60381c04850aded1d22194c5849e6","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"},{"line_number":46,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":47,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_af3c5e2f","line":47,"updated":"2015-07-29 15:10:20.000000000","message":"How about we remove this comment and change it with something more sincere - it\u0027s clear that we want a away to standardize/define scheduler hints but we can\u0027t just yet because of reasons.\n\nHow about we just say that instead of this obvious lie here?\n\nOr am I missunderstandig what this is saying?","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a4ddf39a5e95aec45fa1fd47e90cc6b8592d00b9","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"},{"line_number":46,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":47,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_8f1045ad","line":47,"in_reply_to":"3a50d1a3_a8e4540c","updated":"2015-07-30 15:17:51.000000000","message":"Yeah, I think not codifying this in the RPC layer is reasonable. They\u0027re hints. Let\u0027s make them discoverable and enforceable (eventually) at the API layer.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2829f72b521f56af1e847e537c2236bfdae6625d","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"},{"line_number":46,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":47,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":48,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_a8e4540c","line":47,"in_reply_to":"3a50d1a3_af3c5e2f","updated":"2015-07-29 15:35:13.000000000","message":"I actually provided this comment for explaining why I\u0027m no longer providing a SchedulerHints object - because we discussed that during the last midcycle and agreed on not having coercing for the hints outside of the API\n\nSee https://etherpad.openstack.org/p/liberty-nova-midcycle L63 and below","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"1de2421d9d7f8bf4011fd1ed27dd0588488dffda","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    obj_relationships \u003d {"},{"line_number":52,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":53,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":54,"context_line":"        \u0027instance_type\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":55,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":56,"context_line":"        \u0027retry\u0027: [(\u00271.0\u0027, \u00271.0\u0027)],"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_3ca5d146","line":53,"updated":"2015-07-30 03:09:13.000000000","message":"Shouldn\u0027t this be [(\u00271.0\u0027, \u00271.1\u0027)]? The class InstanceNUMATopology in nova/objects/instance_numa_topology.py has version \u00271.1\u0027 right now, although I do see \u00271.2\u0027 for InstanceNUMACell.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"5ca014ac40a1ee4ce3eb68ff0b5172574de88f3c","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    obj_relationships \u003d {"},{"line_number":52,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":53,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":54,"context_line":"        \u0027instance_type\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":55,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":56,"context_line":"        \u0027retry\u0027: [(\u00271.0\u0027, \u00271.0\u0027)],"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_8244acb7","line":53,"in_reply_to":"3a50d1a3_3ca5d146","updated":"2015-07-30 09:50:59.000000000","message":"You\u0027re totally right, this is a miss","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"1de2421d9d7f8bf4011fd1ed27dd0588488dffda","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            policies \u003d list(filter_properties.get(\u0027group_policies\u0027))"},{"line_number":119,"context_line":"            members \u003d list(filter_properties.get(\u0027group_hosts\u0027))"},{"line_number":120,"context_line":"            self.instance_group \u003d objects.InstanceGroup(policies\u003dpolicies,"},{"line_number":121,"context_line":"                                                        members\u003dmembers)"},{"line_number":122,"context_line":"        else:"},{"line_number":123,"context_line":"            # Set the value anyway to avoid any call to obj_attr_is_set for it"},{"line_number":124,"context_line":"            self.instance_group \u003d None"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_ff33db11","line":121,"updated":"2015-07-30 03:09:13.000000000","message":"Does this object not need to be initialized with a context? (You are initializing self.instance_type with context at L104)","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a4ddf39a5e95aec45fa1fd47e90cc6b8592d00b9","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            policies \u003d list(filter_properties.get(\u0027group_policies\u0027))"},{"line_number":119,"context_line":"            members \u003d list(filter_properties.get(\u0027group_hosts\u0027))"},{"line_number":120,"context_line":"            self.instance_group \u003d objects.InstanceGroup(policies\u003dpolicies,"},{"line_number":121,"context_line":"                                                        members\u003dmembers)"},{"line_number":122,"context_line":"        else:"},{"line_number":123,"context_line":"            # Set the value anyway to avoid any call to obj_attr_is_set for it"},{"line_number":124,"context_line":"            self.instance_group \u003d None"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_2f69f125","line":121,"in_reply_to":"3a50d1a3_e20fb037","updated":"2015-07-30 15:17:51.000000000","message":"You only need to do that if you want instance_group to be able to lazy-load things. If that doesn\u0027t make sense, then leaving it orphaned (no context) makes it fail faster if something happens unexpectedly. Same for the Flavor.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"f1c82df70909dcaff7df3316f5456ad6fac4b2bb","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            policies \u003d list(filter_properties.get(\u0027group_policies\u0027))"},{"line_number":119,"context_line":"            members \u003d list(filter_properties.get(\u0027group_hosts\u0027))"},{"line_number":120,"context_line":"            self.instance_group \u003d objects.InstanceGroup(policies\u003dpolicies,"},{"line_number":121,"context_line":"                                                        members\u003dmembers)"},{"line_number":122,"context_line":"        else:"},{"line_number":123,"context_line":"            # Set the value anyway to avoid any call to obj_attr_is_set for it"},{"line_number":124,"context_line":"            self.instance_group \u003d None"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_e20fb037","line":121,"in_reply_to":"3a50d1a3_ff33db11","updated":"2015-07-30 09:55:40.000000000","message":"that would make sense","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":5511,"name":"Nikola Dipanov","email":"ndipanov@redhat.com","username":"ndipanov"},"change_message_id":"635e6ce730c60381c04850aded1d22194c5849e6","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.scheduler_hints \u003d {hint: [hints_dict[hint]]"},{"line_number":134,"context_line":"                                if not isinstance(hints_dict[hint], list)"},{"line_number":135,"context_line":"                                else hints_dict[hint]"},{"line_number":136,"context_line":"                                for hint in hints_dict}"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @classmethod"},{"line_number":139,"context_line":"    def from_primitives(cls, context, request_spec, filter_properties):"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_2fbfeed0","line":136,"updated":"2015-07-29 15:10:20.000000000","message":"ugh!","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2829f72b521f56af1e847e537c2236bfdae6625d","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.scheduler_hints \u003d {hint: [hints_dict[hint]]"},{"line_number":134,"context_line":"                                if not isinstance(hints_dict[hint], list)"},{"line_number":135,"context_line":"                                else hints_dict[hint]"},{"line_number":136,"context_line":"                                for hint in hints_dict}"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @classmethod"},{"line_number":139,"context_line":"    def from_primitives(cls, context, request_spec, filter_properties):"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_68c16c4d","line":136,"in_reply_to":"3a50d1a3_2fbfeed0","updated":"2015-07-29 15:35:13.000000000","message":"Yeah, I know... But since we can have some hints being a list, we need to provide for each a list of them, even if there is only one item.","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"d4b51be9e78f9b291ff8bb5b9cce8c2fb1374b45","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.scheduler_hints \u003d {hint: [hints_dict[hint]]"},{"line_number":134,"context_line":"                                if not isinstance(hints_dict[hint], list)"},{"line_number":135,"context_line":"                                else hints_dict[hint]"},{"line_number":136,"context_line":"                                for hint in hints_dict}"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @classmethod"},{"line_number":139,"context_line":"    def from_primitives(cls, context, request_spec, filter_properties):"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_863592a9","line":136,"in_reply_to":"3a50d1a3_68c16c4d","updated":"2015-07-30 14:22:00.000000000","message":"This would be much nicer as:\n\n    hints if isinstance(hints, list) else [hints]\n    for hints in hints_dict.values()\n\nNote that produces a generator unless you wrap it in [], which may not be what you want. Or you can do:\n\n    ensure_list \u003d lambda x: x if isinstance(x, list) else [x]\n    map(ensure_list, hints_dict.values())","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"e6867325126bd4a38790a3e9c819ca61571bbbfe","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    # Version 1.0: Initial version"},{"line_number":25,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":29,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":30,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":38,"id":"1a4dcd0f_6895853e","line":27,"updated":"2015-08-10 18:02:34.000000000","message":"There should be an \u0027id\u0027 field here.  This object is being created from the start with the idea of persistence which benefits from having an \u0027id\u0027 here.  It could be added in with the persistence patch but that version bump seems unnecessary.","commit_id":"b61187639da9cee91617ddd9c679e2476129b1e6"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a107dc1ef0820f6a40f8c55835e5d7c6c1b6aad2","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    obj_relationships \u003d {"},{"line_number":54,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.3\u0027)],"},{"line_number":55,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":56,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":57,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":38,"id":"1a4dcd0f_e728db35","line":54,"range":{"start_line":54,"start_character":27,"end_line":54,"end_character":30},"updated":"2015-08-10 23:25:15.000000000","message":"Looks like ImageMeta is up to version 1.5 now","commit_id":"b61187639da9cee91617ddd9c679e2476129b1e6"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a107dc1ef0820f6a40f8c55835e5d7c6c1b6aad2","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    obj_relationships \u003d {"},{"line_number":54,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.3\u0027)],"},{"line_number":55,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":56,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":57,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":58,"context_line":"        \u0027retry\u0027: [(\u00271.0\u0027, \u00271.0\u0027)],"}],"source_content_type":"text/x-python","patch_set":38,"id":"1a4dcd0f_27a483b7","line":55,"range":{"start_line":55,"start_character":35,"end_line":55,"end_character":38},"updated":"2015-08-10 23:25:15.000000000","message":"Now this is 1.2","commit_id":"b61187639da9cee91617ddd9c679e2476129b1e6"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f67791385bb51beb3ed5e97b5afe6a3b94b0e3e1","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"1a4dcd0f_064940d0","line":30,"updated":"2015-08-17 02:20:41.000000000","message":"root_gb, ephemeral_gb, memory_mb and vcpus are all in the flavor. why do we need to redefine these?","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e9da7b6cdab120b8cd01857ea45d132b041a035","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_b56a5719","line":30,"in_reply_to":"1a4dcd0f_064940d0","updated":"2015-08-17 14:40:54.000000000","message":"I believe this is done to maintain compatibility with what the filters/weighers are expecting to find in the request spec.  Although I think what we want to keep are these separate fields and remove Flavor if it is duplicative.","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5af2b8f911ab86741e94d25a6e59f66d7d81465f","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_f8cac66d","line":30,"in_reply_to":"fa1b9901_225e00ea","updated":"2015-08-18 17:15:44.000000000","message":"I don\u0027t want to get stuck on this, but I would prefer to have the individual fields and not the Flavor object.\n\nFlavor is currently the way that we group the items above into a common concept in Nova, but from the scheduling pov a flavor doesn\u0027t matter at all.  All that matters the resource requirements.  And given that the concept of a Flavor is under discussion right now I don\u0027t want to have to keep compatibility code around for consumers of this object when they could just consume root_gb which shouldn\u0027t be affected even as Flavor changes.","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4f22c7d98e384a63498c377912fb135c81cee76d","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_abce7381","line":30,"in_reply_to":"fa1b9901_8869358e","updated":"2015-08-17 16:05:54.000000000","message":"Right, flavor has a lot more in it than these things. I think we have this because this is kindof a copy of an instance template. I don\u0027t think we need to have these fields on instance in the database either, as they\u0027re duplicating what is in flavor as well.\n\nPersonally, I\u0027d like to see these fields not be here, and also not be in instance itself (eventually). Could we remove these if we put them back into the legacy dict until we get everything converted over to use this object?\n\nI don\u0027t want to delay this in the pursuit of perfection, so we might should just go forward with it as is. However, removing fields later is hard/ugly.","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"39d7d35c587c69cad623ed50361c2da943dce2e7","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_225e00ea","line":30,"in_reply_to":"fa1b9901_abce7381","updated":"2015-08-17 18:01:28.000000000","message":"Okay, we can remove those fields for sure, lemme work on it","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"416868e4d92c5ac9f6c3b86306d94286141975fe","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027image\u0027: fields.ObjectField(\u0027ImageMeta\u0027, nullable\u003dTrue),"},{"line_number":30,"context_line":"        \u0027root_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":31,"context_line":"        \u0027ephemeral_gb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":32,"context_line":"        \u0027memory_mb\u0027: fields.IntegerField(nullable\u003dFalse),"},{"line_number":33,"context_line":"        \u0027vcpus\u0027: fields.IntegerField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_8869358e","line":30,"in_reply_to":"fa1b9901_b56a5719","updated":"2015-08-17 15:44:18.000000000","message":"Yeah, I preferred to explicitely mention that because that\u0027s part of the contract. On the other hand, we need a Flavor because of the extra specs stuff.","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f67791385bb51beb3ed5e97b5afe6a3b94b0e3e1","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027SchedulerRetries\u0027, nullable\u003dTrue),"},{"line_number":46,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027SchedulerLimits\u0027, nullable\u003dTrue),"},{"line_number":47,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":48,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"}],"source_content_type":"text/x-python","patch_set":43,"id":"1a4dcd0f_8634704a","line":45,"updated":"2015-08-17 02:20:41.000000000","message":"why is this not called retries?","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"416868e4d92c5ac9f6c3b86306d94286141975fe","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":44,"context_line":"        \u0027force_nodes\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        \u0027retry\u0027: fields.ObjectField(\u0027SchedulerRetries\u0027, nullable\u003dTrue),"},{"line_number":46,"context_line":"        \u0027limits\u0027: fields.ObjectField(\u0027SchedulerLimits\u0027, nullable\u003dTrue),"},{"line_number":47,"context_line":"        \u0027instance_group\u0027: fields.ObjectField(\u0027InstanceGroup\u0027, nullable\u003dTrue),"},{"line_number":48,"context_line":"        # NOTE(sbauza): Since hints are depending on running filters, we prefer"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_081445f3","line":45,"in_reply_to":"1a4dcd0f_8634704a","updated":"2015-08-17 15:44:18.000000000","message":"well, no real good reason behind that except that\u0027s because it\u0027s an object and the current dict key is called \u0027retry\u0027 too","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f67791385bb51beb3ed5e97b5afe6a3b94b0e3e1","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":50,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":51,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027instance_uuid\u0027: fields.UUIDField(),"},{"line_number":53,"context_line":"    }"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"1a4dcd0f_e61454a0","line":52,"updated":"2015-08-17 02:20:41.000000000","message":"why not just have the instance object here?","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e9da7b6cdab120b8cd01857ea45d132b041a035","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        # to leave the API correctly validating the hints per the filters and"},{"line_number":50,"context_line":"        # just provide to the RequestSpec object a free-form dictionary"},{"line_number":51,"context_line":"        \u0027scheduler_hints\u0027: fields.DictOfListOfStringsField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027instance_uuid\u0027: fields.UUIDField(),"},{"line_number":53,"context_line":"    }"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    obj_relationships \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa1b9901_b5ced758","line":52,"in_reply_to":"1a4dcd0f_e61454a0","updated":"2015-08-17 14:40:54.000000000","message":"Two reasons:\n\n1. We don\u0027t need the instance object.  Everything of interest in that object is already enumerated separately.\n\n2. The request spec is going to be persisted before the instance has been created.  This is an important part of the cellsv2 effort where we need to store the build request before we have called the scheduler which means we don\u0027t have a cell to create an instance in.  And it would be a duplication of effort to create an instance object here with data that\u0027s already in the request spec.","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f67791385bb51beb3ed5e97b5afe6a3b94b0e3e1","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def _from_hints(self, hints_dict):"},{"line_number":137,"context_line":"        if hints_dict is None:"},{"line_number":138,"context_line":"            self.scheduler_hints \u003d None"},{"line_number":139,"context_line":"            return"},{"line_number":140,"context_line":"        self.scheduler_hints \u003d {"},{"line_number":141,"context_line":"            hint: value if isinstance(value, list) else [value]"}],"source_content_type":"text/x-python","patch_set":43,"id":"1a4dcd0f_06770003","line":138,"updated":"2015-08-17 02:20:41.000000000","message":"when not\n    else:\n        self.scheduler_hints \u003d ...","commit_id":"aac4350b286ce74d9bb67f1cc5718404686136f3"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0cee6a3d804bf30d892d674ebf3e0dc4dc5e6d4d","unresolved":false,"context_lines":[{"line_number":33,"context_line":"                                           nullable\u003dTrue),"},{"line_number":34,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027flavor\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":37,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":38,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":39,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":44,"id":"fa1b9901_42eced8e","line":36,"updated":"2015-08-19 14:27:34.000000000","message":"So after thinking on this a bit I have a few thoughts:\n\n1. I would prefer to avoid using Flavor here and pass around the constituent parts to avoid the dependency relationship.  As Flavor changes over time, and potentially splits off a new object with the extra specs stuff, we\u0027ll need to updates the relationships and deal with backwards compatibility when it\u0027s extremely likely that if we just had root/ephemeral_gb, memory, and vcpus here we would not need to care at all that the Flavor object is changing.  Just populate this with whatever object has that info when it\u0027s created/updated.  I\u0027m not -1 on this but I think it adds needless complexity in the long run.\n\n2. What I do care about is that users of RequestSpec can access root_gb, ephemeral_gb, etc... without needing to know that it\u0027s the flavor providing them.  That\u0027s an implementation detail from the resource tracker and scheduler pov.  So I would like to see the individual components as properties of the RequestSpec object even if they\u0027re backed by a Flavor.","commit_id":"3566623008e1f33dbbd35dbd183eb96e25cade84"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"45dd15d56d8e3c15d95777c9546d8b3aad91777b","unresolved":false,"context_lines":[{"line_number":33,"context_line":"                                           nullable\u003dTrue),"},{"line_number":34,"context_line":"        \u0027project_id\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":35,"context_line":"        \u0027availability_zone\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":36,"context_line":"        \u0027flavor\u0027: fields.ObjectField(\u0027Flavor\u0027, nullable\u003dFalse),"},{"line_number":37,"context_line":"        \u0027num_instances\u0027: fields.IntegerField(default\u003d1),"},{"line_number":38,"context_line":"        \u0027ignore_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":39,"context_line":"        \u0027force_hosts\u0027: fields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":44,"id":"fa1b9901_e40e663a","line":36,"in_reply_to":"fa1b9901_42eced8e","updated":"2015-08-19 16:51:37.000000000","message":"I\u0027m actually pretty worried by the inflation of fields it creates if we get rid of the Flavor object mainly because of the type_filter.py filters in there.\nIt wouldn\u0027t only need vcpus, memory_mb, eph_gb and root_gb but also extra_specs, name, id and swap.\n\nSo, I would end up writing something like \n\n \u0027flavor_id\u0027: fields.IntegerField(),\n \u0027flavor_name\u0027: fields.StringField(),\n \u0027swap\u0027: fields.IntegerField(),\n \u0027extra_specs\u0027: fields.DictOfStringsField()","commit_id":"3566623008e1f33dbbd35dbd183eb96e25cade84"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"ea2fb1d513df9b5e66f36b38417a0e914637aa59","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    def _from_hints(self, hints_dict):"},{"line_number":132,"context_line":"        if hints_dict is None:"},{"line_number":133,"context_line":"            self.scheduler_hints \u003d None"},{"line_number":134,"context_line":"            return"},{"line_number":135,"context_line":"        self.scheduler_hints \u003d {"},{"line_number":136,"context_line":"            hint: value if isinstance(value, list) else [value]"},{"line_number":137,"context_line":"            for hint, value in six.iteritems(hints_dict)}"}],"source_content_type":"text/x-python","patch_set":44,"id":"fa1b9901_59942d8a","line":134,"updated":"2015-08-18 10:00:54.000000000","message":"this is real nitpicking but why the return here?\n\nself.scheduler_hints \u003d (None if hints_dict is None else\n    {hint: value if isinstance(value, list) else [value]\n            for hint, value in six.iteritems(hints_dict)})","commit_id":"3566623008e1f33dbbd35dbd183eb96e25cade84"}],"nova/scheduler/host_manager.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8174c7ddf09226b96cb9eaac896ec0a5631a4fcf","unresolved":false,"context_lines":[{"line_number":496,"context_line":"            filters \u003d self.default_filters"},{"line_number":497,"context_line":"        else:"},{"line_number":498,"context_line":"            filters \u003d self._choose_host_filters(filter_class_names)"},{"line_number":499,"context_line":"        ignore_hosts \u003d filter_properties.get(\u0027ignore_hosts\u0027, [])"},{"line_number":500,"context_line":"        force_hosts \u003d filter_properties.get(\u0027force_hosts\u0027, [])"},{"line_number":501,"context_line":"        force_nodes \u003d filter_properties.get(\u0027force_nodes\u0027, [])"},{"line_number":502,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"fa32b979_31f09ac9","line":499,"updated":"2015-06-19 10:04:51.000000000","message":"*facepalm* Not seen when code-reviewing for the spec, I need to add that field too :(","commit_id":"38d87b4d7f10368247b51884d5f7a55e88f2996b"}],"nova/tests/unit/objects/test_objects.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"1de2421d9d7f8bf4011fd1ed27dd0588488dffda","unresolved":false,"context_lines":[{"line_number":1220,"context_line":"    \u0027RequestSpec\u0027: {\u0027Flavor\u0027: \u00271.1\u0027,"},{"line_number":1221,"context_line":"                    \u0027InstanceGroup\u0027: \u00271.9\u0027,"},{"line_number":1222,"context_line":"                    \u0027ImageMeta\u0027: \u00271.2\u0027,"},{"line_number":1223,"context_line":"                    \u0027InstanceNUMATopology\u0027: \u00271.1\u0027,"},{"line_number":1224,"context_line":"                    \u0027InstancePCIRequests\u0027: \u00271.1\u0027,"},{"line_number":1225,"context_line":"                    \u0027SchedulerLimits\u0027: \u00271.0\u0027,"},{"line_number":1226,"context_line":"                    \u0027SchedulerRetries\u0027: \u00271.0\u0027},"}],"source_content_type":"text/x-python","patch_set":37,"id":"3a50d1a3_65e5fc08","line":1223,"updated":"2015-07-30 03:09:13.000000000","message":"Looks like we can also use this to know what obj_relationships versions we should have (\u00271.1\u0027 here)","commit_id":"68f271b706bab532a321eb94c858655552a3f2ca"}],"nova/tests/unit/objects/test_request_spec.py":[{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"0340a29d299aa1af6eca8faa56767dff180e872f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Copyright 2014 Red Hat, Inc."},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":5,"context_line":"#    a copy of the License at"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_5b41b3a4","line":2,"updated":"2015-01-08 13:26:39.000000000","message":"2015","commit_id":"69326d9d766150d031ffdba8c1bc6a371fdee563"}]}
