)]}'
{"etc/nova/api-paste.ini":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e6d0780135f06ba28e0e7ff040ce99b38b20ad88","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1af94dfe_a2b0dcde","updated":"2016-03-15 20:03:17.000000000","message":"It\u0027s distressing that we use paste in this way. I considered not doing so, but that meant that I would have to figure out some other way to manage the middleware, and currently my purpose is to flesh out the ResourcePool interface.","commit_id":"6571da453ac88d7a915fcb38accc61f8108d8ac3"}],"nova/api/openstack/placement/handler.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e6d0780135f06ba28e0e7ff040ce99b38b20ad88","unresolved":false,"context_lines":[{"line_number":27,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"RESOURCE_POOL_SCHEMA \u003d {"},{"line_number":31,"context_line":"    \"type\": \"object\","},{"line_number":32,"context_line":"    \"properties\": {"},{"line_number":33,"context_line":"        \"name\": {"}],"source_content_type":"text/x-python","patch_set":1,"id":"1af94dfe_02c27033","line":30,"updated":"2016-03-15 20:03:17.000000000","message":"This ought to live somewhere else.","commit_id":"6571da453ac88d7a915fcb38accc61f8108d8ac3"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e6d0780135f06ba28e0e7ff040ce99b38b20ad88","unresolved":false,"context_lines":[{"line_number":113,"context_line":"    return req.response"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class PlacementHomeRequestHandler(wsgi.Application):"},{"line_number":117,"context_line":"    \"\"\"Serve Placement Root.\"\"\""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    @webob.dec.wsgify(RequestClass\u003dwsgi.Request)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1af94dfe_42091895","line":116,"updated":"2016-03-15 20:03:17.000000000","message":"unauthed","commit_id":"6571da453ac88d7a915fcb38accc61f8108d8ac3"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e6d0780135f06ba28e0e7ff040ce99b38b20ad88","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        return req.response"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"class ResourcePoolsHandler(wsgi.Application):"},{"line_number":126,"context_line":"    \"\"\"Serve Resource Pools.\"\"\""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def __init__(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"1af94dfe_82032073","line":125,"updated":"2016-03-15 20:03:17.000000000","message":"authed","commit_id":"6571da453ac88d7a915fcb38accc61f8108d8ac3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.api.openstack.placement.handlers import resource_provider"},{"line_number":20,"context_line":"from nova.api.openstack.placement.handlers import usages"},{"line_number":21,"context_line":"from nova import exception"},{"line_number":22,"context_line":"from nova import wsgi"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class PlacementHomeRequestHandler(wsgi.Application):"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_0553413a","line":22,"updated":"2016-06-13 03:48:06.000000000","message":"This is fine to use nova.wsgi for right now, but IMHO, better to use only the least you need to so that extraction isn\u0027t a giant pain in the ass...","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.api.openstack.placement.handlers import resource_provider"},{"line_number":20,"context_line":"from nova.api.openstack.placement.handlers import usages"},{"line_number":21,"context_line":"from nova import exception"},{"line_number":22,"context_line":"from nova import wsgi"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class PlacementHomeRequestHandler(wsgi.Application):"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_8f00e702","line":22,"in_reply_to":"7aa08908_0553413a","updated":"2016-06-13 09:31:49.000000000","message":"Yeah, it\u0027s just a holder for. Initially I was most interested in exploring the mechanics of the API and then once we had some reasonable \"this approach is not insane\" the tune-for-real can begin.","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"}],"nova/api/openstack/placement/handlers/aggregate.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":23,"context_line":"@util.check_accept(\u0027application/json\u0027)"},{"line_number":24,"context_line":"def get_aggregates(req):"},{"line_number":25,"context_line":"    context \u003d req.environ[\u0027nova.context\u0027]"},{"line_number":26,"context_line":"    uuid \u003d req.environ[\u0027wsgiorg.routing_args\u0027][1][\u0027uuid\u0027]"},{"line_number":27,"context_line":"    resource_provider \u003d objects.ResourceProvider.get_by_uuid("},{"line_number":28,"context_line":"        context, uuid)"},{"line_number":29,"context_line":"    response \u003d req.response"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_a5418d65","line":26,"updated":"2016-06-13 03:48:06.000000000","message":"Long-term, might be nice to have some utility methods for extracting common things out of the WSGI environ.","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":23,"context_line":"@util.check_accept(\u0027application/json\u0027)"},{"line_number":24,"context_line":"def get_aggregates(req):"},{"line_number":25,"context_line":"    context \u003d req.environ[\u0027nova.context\u0027]"},{"line_number":26,"context_line":"    uuid \u003d req.environ[\u0027wsgiorg.routing_args\u0027][1][\u0027uuid\u0027]"},{"line_number":27,"context_line":"    resource_provider \u003d objects.ResourceProvider.get_by_uuid("},{"line_number":28,"context_line":"        context, uuid)"},{"line_number":29,"context_line":"    response \u003d req.response"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_ef11ab53","line":26,"in_reply_to":"7aa08908_a5418d65","updated":"2016-06-13 09:31:49.000000000","message":"Yeah, that\u0027s in the works too. This, again, was to make the use of the strategy (rather plain and normal WSGI) as visible as possible.","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    try:"},{"line_number":58,"context_line":"        aggregate_list \u003d ["},{"line_number":59,"context_line":"            objects.Aggregate.get_by_uuid(context, aggregate_uuid)"},{"line_number":60,"context_line":"            for aggregate_uuid in aggregate_data]"},{"line_number":61,"context_line":"    except exception.NotFound as exc:"},{"line_number":62,"context_line":"        raise webob.exc.HTTPBadRequest("},{"line_number":63,"context_line":"            \u0027Invalid Aggregate information: %s\u0027 % exc)"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_85461179","line":60,"updated":"2016-06-13 03:48:06.000000000","message":"This should all be done in a batch, IMHO. The above will issue N number of database queries, one for each aggregate UUID specified. We could have an AggregateList.get_by_uuids() method that accepts a list of UUIDs and then here, return a 400 if len(uuids) !\u003d len(AggregateList.get_by_uuids().objects)","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    try:"},{"line_number":58,"context_line":"        aggregate_list \u003d ["},{"line_number":59,"context_line":"            objects.Aggregate.get_by_uuid(context, aggregate_uuid)"},{"line_number":60,"context_line":"            for aggregate_uuid in aggregate_data]"},{"line_number":61,"context_line":"    except exception.NotFound as exc:"},{"line_number":62,"context_line":"        raise webob.exc.HTTPBadRequest("},{"line_number":63,"context_line":"            \u0027Invalid Aggregate information: %s\u0027 % exc)"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_aff5e3ed","line":60,"in_reply_to":"7aa08908_85461179","updated":"2016-06-13 09:31:49.000000000","message":"Another idea I had was that maybe we shouldn\u0027t build aggregate objects on the resource provider object, just aggregate uuids.\n\nBecause aggregates don\u0027t live in the same data domain (eventually) we don\u0027t want to go around willy nilly validating them.\n\nWe _could_ just accept the ids and save them and that\u0027s it. When the resource provider is used an invalid aggregate could warn or error. That may not be the correct compromise, but we are going to have some compromises like that at some point because of the boundaries we are trying to create.","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"}],"nova/api/openstack/placement/handlers/inventory.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":61,"context_line":"POST_INVENTORY_SCHEMA[\u0027required\u0027].append(\u0027resource_class\u0027)"},{"line_number":62,"context_line":"POST_INVENTORY_SCHEMA[\u0027required\u0027].remove(\u0027resource_provider_generation\u0027)"},{"line_number":63,"context_line":"INVENTORY_FIELDS \u003d [\u0027total\u0027, \u0027reserved\u0027, \u0027min_unit\u0027, \u0027max_unit\u0027,"},{"line_number":64,"context_line":"                    \u0027step_size\u0027, \u0027allocation_ratio\u0027]"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"@webob.dec.wsgify"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_e55f153f","line":64,"updated":"2016-06-13 03:48:06.000000000","message":"These you can get from nova.objects.Inventory.fields instead of duplicating that data here...","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":61,"context_line":"POST_INVENTORY_SCHEMA[\u0027required\u0027].append(\u0027resource_class\u0027)"},{"line_number":62,"context_line":"POST_INVENTORY_SCHEMA[\u0027required\u0027].remove(\u0027resource_provider_generation\u0027)"},{"line_number":63,"context_line":"INVENTORY_FIELDS \u003d [\u0027total\u0027, \u0027reserved\u0027, \u0027min_unit\u0027, \u0027max_unit\u0027,"},{"line_number":64,"context_line":"                    \u0027step_size\u0027, \u0027allocation_ratio\u0027]"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"@webob.dec.wsgify"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_2fe2932f","line":64,"in_reply_to":"7aa08908_e55f153f","updated":"2016-06-13 09:31:49.000000000","message":"/me nods, wip","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    inventory_list.objects.append(inventory)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    try:"},{"line_number":90,"context_line":"        resource_provider.set_inventory(inventory_list)"},{"line_number":91,"context_line":"    except exception.ConcurrentUpdateDetected as exc:"},{"line_number":92,"context_line":"        raise webob.exc.HTTPConflict(\u0027update conflict: %s\u0027 % exc)"},{"line_number":93,"context_line":"    except exception.ObjectActionError as exc:"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_c55c994d","line":90,"updated":"2016-06-13 03:48:06.000000000","message":"set_inventory() was intended for replace operations (i.e. PUT /resource_providers/{uuid}/inventory). But this method was clearly intended for adding a single resource class to a resource provider\u0027s inventory (as evidenced by the check on lines 76-80. We should create an add_inventory() method on ResourceProvider that only adds a single resource class (and does the existence check itself).","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    inventory_list.objects.append(inventory)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    try:"},{"line_number":90,"context_line":"        resource_provider.set_inventory(inventory_list)"},{"line_number":91,"context_line":"    except exception.ConcurrentUpdateDetected as exc:"},{"line_number":92,"context_line":"        raise webob.exc.HTTPConflict(\u0027update conflict: %s\u0027 % exc)"},{"line_number":93,"context_line":"    except exception.ObjectActionError as exc:"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_8f5f47e4","line":90,"in_reply_to":"7aa08908_c55c994d","updated":"2016-06-13 09:31:49.000000000","message":"✔","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    inventory_list.replace(to_update_inv)"},{"line_number":185,"context_line":"    try:"},{"line_number":186,"context_line":"        resource_provider.set_inventory(inventory_list)"},{"line_number":187,"context_line":"    except exception.ConcurrentUpdateDetected as exc:"},{"line_number":188,"context_line":"        raise webob.exc.HTTPConflict(\u0027update conflict: %s\u0027 % exc)"},{"line_number":189,"context_line":"    except exception.ObjectActionError as exc:"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_25563d2a","line":186,"updated":"2016-06-13 03:48:06.000000000","message":"Same comment as above. The set_inventory() method is intended to replace all inventories. We should add a separate update_inventory() method to ResourceProvider for updating a single resource class in a provider\u0027s inventory. Then there would be no reason to have lines 177-184. Instead, you would just do:\n\n inv \u003d objects.Inventory(resource_provider\u003dresource_provider,\n                         resource_class\u003dresource_class,\n                         **data)\n inv.obj_set_defaults()\n try:\n     resource_provider.update_inventory(inv)\n ...","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ffcc7f6b2283d9a630c3b4694dee3cf254b7f82b","unresolved":false,"context_lines":[{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    inventory_list.replace(to_update_inv)"},{"line_number":185,"context_line":"    try:"},{"line_number":186,"context_line":"        resource_provider.set_inventory(inventory_list)"},{"line_number":187,"context_line":"    except exception.ConcurrentUpdateDetected as exc:"},{"line_number":188,"context_line":"        raise webob.exc.HTTPConflict(\u0027update conflict: %s\u0027 % exc)"},{"line_number":189,"context_line":"    except exception.ObjectActionError as exc:"}],"source_content_type":"text/x-python","patch_set":55,"id":"7aa08908_0f74f765","line":186,"in_reply_to":"7aa08908_25563d2a","updated":"2016-06-13 09:31:49.000000000","message":"✔","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"}],"nova/tests/functional/gabbi/fixtures.py":[{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"0ee129bdf67ac1d44842473d9de18e71d8fbee13","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        os.environ[\u0027AGG_1_UUID\u0027] \u003d aggregate1.uuid"},{"line_number":75,"context_line":"        os.environ[\u0027AGG_2_UUID\u0027] \u003d aggregate2.uuid"},{"line_number":76,"context_line":"        os.environ[\u0027RP_UUID\u0027] \u003d uuidutils.generate_uuid()"},{"line_number":77,"context_line":"        os.environ[\u0027RP_NAME\u0027] \u003d uuidutils.generate_uuid()"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def stop_fixture(self):"},{"line_number":80,"context_line":"        rpc.cleanup()"}],"source_content_type":"text/x-python","patch_set":47,"id":"bab6814e_21f3f59f","line":77,"updated":"2016-05-25 13:28:15.000000000","message":"nit: maybe you should split ConfigFixture because in the first part of this fixture you configure your env, and in the second part you create some resources and environment variables.  As I understand we need not the second part in microversion.yaml and usages.yaml. Or maybe you should just rename it because I thought that ConfigFixture should just *initialise* the config somehow. without the creation of resources. But it\u0027s just a nit.","commit_id":"b178bb6fac740802f3c9f8a1cac1bd0a6616ef68"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"7aa08908_453709ff","updated":"2016-06-13 03:48:06.000000000","message":"As Sean Dague mentioned in Austin, go ahead and change this directory to /nova/tests/functional/api/openstack/placement/","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"}],"placement.yaml":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e6d0780135f06ba28e0e7ff040ce99b38b20ad88","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1af94dfe_8287a00e","updated":"2016-03-15 20:03:17.000000000","message":"This is a gabbi yaml file that I\u0027m using to do some simple TDD, it won\u0027t remain, at least not in the form, just wanted to keep it with the WIP","commit_id":"6571da453ac88d7a915fcb38accc61f8108d8ac3"}],"setup.cfg":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"47ff906be736907c22cdcda4eae3b5c28498d773","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    nova-api \u003d nova.cmd.api:main"},{"line_number":49,"context_line":"    nova-api-metadata \u003d nova.cmd.api_metadata:main"},{"line_number":50,"context_line":"    nova-api-os-compute \u003d nova.cmd.api_os_compute:main"},{"line_number":51,"context_line":"    nova-placement-api \u003d nova.cmd.placement_api:main"},{"line_number":52,"context_line":"    nova-cells \u003d nova.cmd.cells:main"},{"line_number":53,"context_line":"    nova-cert \u003d nova.cmd.cert:main"},{"line_number":54,"context_line":"    nova-compute \u003d nova.cmd.compute:main"}],"source_content_type":"text/x-ttcn-cfg","patch_set":55,"id":"7aa08908_65320512","line":51,"updated":"2016-06-13 03:48:06.000000000","message":"Should just be placement-api.","commit_id":"0b15765242dcec758fb6915c7a7ca1dafa15d5b8"}]}
