)]}'
{"osc_placement/resources/allocation.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"36393efc86a151e52dcdad2d4c65eea23360702f","unresolved":false,"context_lines":[{"line_number":20,"context_line":"FIELDS \u003d (\u0027generation\u0027, \u0027resources\u0027)"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class CreateAllocation(command.Lister):"},{"line_number":24,"context_line":"    \"\"\"Create resource allocation(s) for a given consumer\"\"\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":1,"id":"7ffa3b31_43645fe4","line":23,"updated":"2017-04-19 12:13:58.000000000","message":"Since it\u0027s possible to replace existing allocations with this command, maybe Set?","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a36fa447b4603086cf62729572ea538fd94e2969","unresolved":false,"context_lines":[{"line_number":20,"context_line":"FIELDS \u003d (\u0027generation\u0027, \u0027resources\u0027)"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class CreateAllocation(command.Lister):"},{"line_number":24,"context_line":"    \"\"\"Create resource allocation(s) for a given consumer\"\"\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":1,"id":"7ffa3b31_065e3e43","line":23,"in_reply_to":"7ffa3b31_43645fe4","updated":"2017-04-20 13:36:08.000000000","message":"Done","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c020d5104e00abc3e48e0491a4f0b2cdf9875ed3","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        )"},{"line_number":33,"context_line":"        parser.add_argument("},{"line_number":34,"context_line":"            \u0027--allocation\u0027,"},{"line_number":35,"context_line":"            metavar\u003d\u0027\u003crp\u003dresource-provider-id,\u0027"},{"line_number":36,"context_line":"                    \u0027resource-class-name\u003damount-of-resource-used\u003e\u0027,"},{"line_number":37,"context_line":"            action\u003d\u0027append\u0027,"},{"line_number":38,"context_line":"            default\u003d[],"},{"line_number":39,"context_line":"            help\u003d\u0027Create (or update) an allocation of a resource class. \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_fe7e33e2","line":36,"range":{"start_line":35,"start_character":21,"end_line":36,"end_character":65},"updated":"2017-11-28 21:18:55.000000000","message":"Given this confusing format, we should probably provide an example in the help string, e.g.:\n\n\"Create (or update) an allocation of a resource class. Specify option multiple times to set multiple allocations. For example: --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,VCPU\u003d4\"","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"424fb4ae8d401ef8b8b629ac4ca7c492dc040adf","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        for allocation_str in parsed_args.allocation:"},{"line_number":50,"context_line":"            parsed \u003d dict(kv.split(\u0027\u003d\u0027) for kv in allocation_str.split(\u0027,\u0027))"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"            allocations.append({"},{"line_number":53,"context_line":"                \u0027resource_provider\u0027: {"},{"line_number":54,"context_line":"                    \u0027uuid\u0027: parsed[\u0027rp\u0027]"},{"line_number":55,"context_line":"                },"},{"line_number":56,"context_line":"                \u0027resources\u0027: {k: int(v)"},{"line_number":57,"context_line":"                              for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":58,"context_line":"            })"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        if not allocations:"},{"line_number":61,"context_line":"            raise exceptions.CommandError("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_3e2fbb88","line":58,"range":{"start_line":52,"start_character":12,"end_line":58,"end_character":14},"updated":"2017-11-28 20:47:22.000000000","message":"Hmm, doesn\u0027t this mean we could end up with a request like this, where the resource provider uuid is duplicated but split across multiple entries in the allocations list?\n\n{\n\t\"resource_provider\": {\n\t\t\"uuid\": \"844ac34d-620e-474c-833c-4c9921251353\"\n\t},\n\t\"resources\": {\n\t\t\"MEMORY_MB\": 512,\n\t\t\"VCPU\": 2\n\t}\n},\n{\n\t\"resource_provider\": {\n\t\t\"uuid\": \"844ac34d-620e-474c-833c-4c9921251353\"\n\t},\n\t\"resources\": {\n\t\t\"DISK_GB\": 5\n\t}\n}\n\nso:\n\nopenstack resource provider set-allocation \u003cconsumer_uuid\u003e --allocation rp\u003d844ac34d-620e-474c-833c-4c9921251353,VCPU\u003d2 --allocation rp\u003d844ac34d-620e-474c-833c-4c9921251353,MEMORY_MB\u003d512 --allocation rp\u003d844ac34d-620e-474c-833c-4c9921251353,DISK_GB\u003d5\n\n?\n\nThat would actually result in an allocations list with 3 entries, right?\n\nAnd looking at the server side code, it looks like we\u0027d only get the last resource class entry processed since it\u0027s not appending:\n\nhttps://github.com/openstack/nova/blob/master/nova/api/openstack/placement/handlers/allocation.py#L341-L349","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d41d9f46e84574a67e6542d4490a048e16266b72","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        for allocation_str in parsed_args.allocation:"},{"line_number":50,"context_line":"            parsed \u003d dict(kv.split(\u0027\u003d\u0027) for kv in allocation_str.split(\u0027,\u0027))"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"            allocations.append({"},{"line_number":53,"context_line":"                \u0027resource_provider\u0027: {"},{"line_number":54,"context_line":"                    \u0027uuid\u0027: parsed[\u0027rp\u0027]"},{"line_number":55,"context_line":"                },"},{"line_number":56,"context_line":"                \u0027resources\u0027: {k: int(v)"},{"line_number":57,"context_line":"                              for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":58,"context_line":"            })"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        if not allocations:"},{"line_number":61,"context_line":"            raise exceptions.CommandError("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_7e954386","line":58,"range":{"start_line":52,"start_character":12,"end_line":58,"end_character":14},"in_reply_to":"ff82abbf_3e2fbb88","updated":"2017-11-28 20:49:24.000000000","message":"So either we\u0027d need to keep track of rp uuids we\u0027ve already processed and append those resource classes per rp uuid, or allow setting multiple resource class values per rp uuid on the --allocation option, but even that seems like we\u0027d need to track the rp uuids as singletons.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2a64f34a32f0bcd5dc8be217495802d0c67f9f20","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        for allocation_str in parsed_args.allocation:"},{"line_number":50,"context_line":"            parsed \u003d dict(kv.split(\u0027\u003d\u0027) for kv in allocation_str.split(\u0027,\u0027))"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"            allocations.append({"},{"line_number":53,"context_line":"                \u0027resource_provider\u0027: {"},{"line_number":54,"context_line":"                    \u0027uuid\u0027: parsed[\u0027rp\u0027]"},{"line_number":55,"context_line":"                },"},{"line_number":56,"context_line":"                \u0027resources\u0027: {k: int(v)"},{"line_number":57,"context_line":"                              for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":58,"context_line":"            })"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        if not allocations:"},{"line_number":61,"context_line":"            raise exceptions.CommandError("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_fef5d357","line":58,"range":{"start_line":52,"start_character":12,"end_line":58,"end_character":14},"in_reply_to":"ff82abbf_7e6a231a","updated":"2017-11-28 21:21:59.000000000","message":"This is what we have for setting rp inventory:\n\nopenstack resource provider inventory set \u003cuuid\u003e \\\n                 --resource VCPU\u003d16 \\\n                 --resource MEMORY_MB\u003d2048 \\\n                 --resource MEMORY_MB:step_size\u003d128\n\nSo doing something like:\n\nopenstack resource provider allocation set \u003cuuid\u003e \\\n                 --allocation \u003crp_uuid\u003e:VCPU\u003d16,MEMORY_MB\u003d2048,DISK_GB\u003d128\n\nmight work. It\u0027s not exactly the same but it might be nicer to namespace the resource class values per provider rather than make you enter each provider / class combination every time, especially for a consumer that has allocations on more than one provider, that could get really cumbersome.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c020d5104e00abc3e48e0491a4f0b2cdf9875ed3","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        for allocation_str in parsed_args.allocation:"},{"line_number":50,"context_line":"            parsed \u003d dict(kv.split(\u0027\u003d\u0027) for kv in allocation_str.split(\u0027,\u0027))"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"            allocations.append({"},{"line_number":53,"context_line":"                \u0027resource_provider\u0027: {"},{"line_number":54,"context_line":"                    \u0027uuid\u0027: parsed[\u0027rp\u0027]"},{"line_number":55,"context_line":"                },"},{"line_number":56,"context_line":"                \u0027resources\u0027: {k: int(v)"},{"line_number":57,"context_line":"                              for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":58,"context_line":"            })"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        if not allocations:"},{"line_number":61,"context_line":"            raise exceptions.CommandError("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_7e6a231a","line":58,"range":{"start_line":52,"start_character":12,"end_line":58,"end_character":14},"in_reply_to":"ff82abbf_7e954386","updated":"2017-11-28 21:18:55.000000000","message":"What if we changed the --allocation option format to something like this?\n\n--allocation \u003crp_uuid\u003e:\u003cresource_class\u003e\u003d\u003cvalue\u003e,\u003crc2\u003e\u003d\u003cv2\u003e,...\n\nThen we\u0027d split on the : to get the rp uuid and then split on the , to get the resource class / value pairs.\n\nDidn\u0027t we do some fancy splitting for the provider inventories CLI?","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"96af2b0cc521963a71b3da8227c9a76d4a94e36a","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        for allocation_str in parsed_args.allocation:"},{"line_number":50,"context_line":"            parsed \u003d dict(kv.split(\u0027\u003d\u0027) for kv in allocation_str.split(\u0027,\u0027))"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"            allocations.append({"},{"line_number":53,"context_line":"                \u0027resource_provider\u0027: {"},{"line_number":54,"context_line":"                    \u0027uuid\u0027: parsed[\u0027rp\u0027]"},{"line_number":55,"context_line":"                },"},{"line_number":56,"context_line":"                \u0027resources\u0027: {k: int(v)"},{"line_number":57,"context_line":"                              for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":58,"context_line":"            })"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        if not allocations:"},{"line_number":61,"context_line":"            raise exceptions.CommandError("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_5e8b9fc1","line":58,"range":{"start_line":52,"start_character":12,"end_line":58,"end_character":14},"in_reply_to":"ff82abbf_fef5d357","updated":"2017-11-28 21:23:54.000000000","message":"BTW, this shows the problem I was talking about, we only save the last resource class value specified per provider:\n\nstack@queens:~/osc-placement$ openstack resource provider allocation set c07d8dab-5f02-44e1-a190-f6ca3eb4f99c --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,VCPU\u003d4 --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,MEMORY_MB\u003d1024 --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,DISK_GB\u003d100\n+--------------------------------------+------------+-------------------+\n| resource_provider                    | generation | resources         |\n+--------------------------------------+------------+-------------------+\n| f3496844-76c5-439a-99d3-678efd159cf3 |          4 | {u\u0027DISK_GB\u0027: 100} |\n+--------------------------------------+------------+-------------------+\n\nSo even though I\u0027m specifying 3 allocations for the same consumer and provider, it\u0027s only saving the last one. We should have a test for this.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c020d5104e00abc3e48e0491a4f0b2cdf9875ed3","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        http \u003d self.app.client_manager.placement"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        url \u003d BASE_URL + \u0027/\u0027 + parsed_args.uuid"},{"line_number":92,"context_line":"        per_provider \u003d http.request(\u0027GET\u0027, url).json()[\u0027allocations\u0027].items()"},{"line_number":93,"context_line":"        allocs \u003d [dict(resource_provider\u003dk, **v) for k, v in per_provider]"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        fields_ext \u003d (\u0027resource_provider\u0027, ) + FIELDS"},{"line_number":96,"context_line":"        rows \u003d (utils.get_dict_properties(a, fields_ext) for a in allocs)"},{"line_number":97,"context_line":"        return fields_ext, rows"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"class DeleteAllocation(command.Command):"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_9e0da7e9","line":97,"range":{"start_line":92,"start_character":8,"end_line":97,"end_character":31},"updated":"2017-11-28 21:18:55.000000000","message":"nit: you could move this common code into a helper method so it can be shared between SetAllocation and ShowAllocation.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        if \u0027rp\u0027 not in parsed:"},{"line_number":29,"context_line":"            raise ValueError(\u0027Resource provider parameter is required \u0027"},{"line_number":30,"context_line":"                             \u0027for allocation string\u0027)"},{"line_number":31,"context_line":"        resources \u003d {k: int(v) for k, v in parsed.items() if k !\u003d \u0027rp\u0027}"},{"line_number":32,"context_line":"        if parsed[\u0027rp\u0027] not in allocations:"},{"line_number":33,"context_line":"            allocations[parsed[\u0027rp\u0027]] \u003d resources"},{"line_number":34,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_9310cbaa","line":31,"range":{"start_line":31,"start_character":21,"end_line":31,"end_character":30},"updated":"2018-01-23 00:06:34.000000000","message":"See below, I can do this:\n\nopenstack resource provider allocation set 45f4ccf9-36e3-4d13-8c6b-80fd6c66a195 --allocation rp\u003ddc43b86a-1261-4f8b-8330-28289fe754e3,DISK_GB\u003d5,VCPU\u003d1,MEMORY_MB\u003d512,MEMORY_MB\u003d1024\n\nAnd this doesn\u0027t catch that I\u0027ve specified a resource class value more than once. It\u0027s not a huge deal since I would expect it to take the last one specified.","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        else:"},{"line_number":35,"context_line":"            prev_rp \u003d allocations[parsed[\u0027rp\u0027]]"},{"line_number":36,"context_line":"            for resource, value in resources.items():"},{"line_number":37,"context_line":"                if resource in prev_rp and prev_rp[resource] !\u003d value:"},{"line_number":38,"context_line":"                    raise exceptions.CommandError("},{"line_number":39,"context_line":"                        \u0027Conflict detected for \u0027"},{"line_number":40,"context_line":"                        \u0027resource provider {} resource class {}\u0027.format("},{"line_number":41,"context_line":"                            parsed[\u0027rp\u0027], resource))"},{"line_number":42,"context_line":"            allocations[parsed[\u0027rp\u0027]].update(resources)"},{"line_number":43,"context_line":"    return allocations"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_730dff8e","line":41,"range":{"start_line":37,"start_character":16,"end_line":41,"end_character":52},"updated":"2018-01-23 00:06:34.000000000","message":"This works if you specify the duplicate with multiple --allocation options, but isn\u0027t caught if you specify the same resource class multiple times within a single --allocation option:\n\nstack@queens:~/osc-placement$ openstack resource provider allocation set 45f4ccf9-36e3-4d13-8c6b-80fd6c66a195 --allocation rp\u003ddc43b86a-1261-4f8b-8330-28289fe754e3,DISK_GB\u003d5,VCPU\u003d1,MEMORY_MB\u003d512,MEMORY_MB\u003d1024\n+--------------------------------------+------------+-------------------------------------------------+\n| resource_provider                    | generation | resources                                       |\n+--------------------------------------+------------+-------------------------------------------------+\n| dc43b86a-1261-4f8b-8330-28289fe754e3 |          9 | {u\u0027VCPU\u0027: 1, u\u0027MEMORY_MB\u0027: 1024, u\u0027DISK_GB\u0027: 5} |\n+--------------------------------------+------------+-------------------------------------------------+\nstack@queens:~/osc-placement$ openstack resource provider allocation set 45f4ccf9-36e3-4d13-8c6b-80fd6c66a195 --allocation rp\u003ddc43b86a-1261-4f8b-8330-28289fe754e3,DISK_GB\u003d5,VCPU\u003d1,MEMORY_MB\u003d512 --allocation rp\u003ddc43b86a-1261-4f8b-8330-28289fe754e3,MEMORY_MB\u003d1024\nConflict detected for resource provider dc43b86a-1261-4f8b-8330-28289fe754e3 resource class MEMORY_MB\nstack@queens:~/osc-placement$\n\nI\u0027m not really worried about this though, definitely not worth holding this change up.","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"225f3e48714ece0e49cb1e300c214819a3d8e075","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class SetAllocation(command.Lister):"},{"line_number":47,"context_line":"    \"\"\"Set resource allocation(s) for a given consumer\"\"\""},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def get_parser(self, prog_name):"},{"line_number":50,"context_line":"        parser \u003d super(SetAllocation, self).get_parser(prog_name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_693175a2","line":47,"updated":"2018-01-23 15:51:29.000000000","message":"Updated the wording for this here:\n\nhttps://review.openstack.org/#/c/536871/","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            metavar\u003d\u0027\u003cuuid\u003e\u0027,"},{"line_number":55,"context_line":"            help\u003d\u0027UUID of the consumer\u0027"},{"line_number":56,"context_line":"        )"},{"line_number":57,"context_line":"        parser.add_argument("},{"line_number":58,"context_line":"            \u0027--allocation\u0027,"},{"line_number":59,"context_line":"            metavar\u003d\u0027\u003crp\u003dresource-provider-id,\u0027"},{"line_number":60,"context_line":"                    \u0027resource-class-name\u003damount-of-resource-used\u003e\u0027,"},{"line_number":61,"context_line":"            action\u003d\u0027append\u0027,"},{"line_number":62,"context_line":"            default\u003d[],"},{"line_number":63,"context_line":"            help\u003d\u0027Create (or update) an allocation of a resource class. \u0027"},{"line_number":64,"context_line":"                 \u0027Specify option multiple times to set multiple allocations.\u0027"},{"line_number":65,"context_line":"        )"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        return parser"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_f3f26f9a","line":65,"range":{"start_line":57,"start_character":8,"end_line":65,"end_character":9},"updated":"2018-01-23 00:06:34.000000000","message":"In playing around with this, it threw me again with the overwrite behavior:\n\nhttp://paste.openstack.org/show/650654/\n\nThis is single node devstack so there is 1 compute node resource provider and I created 1 server instance, so I had a set of allocations on VCPU, MEMORY_MB and DISK_GB. I wanted to change just the DISK_GB and forgot that if I don\u0027t specify the VCPU and MEMORY_MB, those are lost as the \u0027set\u0027 command overwrites the allocations for that consumer based on what you\u0027ve specified.\n\nI don\u0027t know if there is a better way to word this to point out that you have to specify all existing resource class allocations for the ones you don\u0027t want to change if you don\u0027t want to remove them.\n\nMaybe something like, \"Note that this command will overwrite the allocations based on what is provided, so any existing resource class amounts that are not specified will be removed.\"\n\nI also noticed that I could specify a single --allocation parameter with a single resource provider uuid but multiple resource class amounts, which is nice so I don\u0027t have to specify --allocation for each resource class on the same provider. It\u0027s not immediately obvious you can do that, but again I don\u0027t have any great suggestions on how to make this more clear aside from examples, but those don\u0027t render very well in the help text output.\n\nMaybe the answer is some actual ReST docs for command samples, but that could be a TODO.","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1cd2cbf4243f4526780263ef7775160faeb45c56","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            metavar\u003d\u0027\u003cuuid\u003e\u0027,"},{"line_number":55,"context_line":"            help\u003d\u0027UUID of the consumer\u0027"},{"line_number":56,"context_line":"        )"},{"line_number":57,"context_line":"        parser.add_argument("},{"line_number":58,"context_line":"            \u0027--allocation\u0027,"},{"line_number":59,"context_line":"            metavar\u003d\u0027\u003crp\u003dresource-provider-id,\u0027"},{"line_number":60,"context_line":"                    \u0027resource-class-name\u003damount-of-resource-used\u003e\u0027,"},{"line_number":61,"context_line":"            action\u003d\u0027append\u0027,"},{"line_number":62,"context_line":"            default\u003d[],"},{"line_number":63,"context_line":"            help\u003d\u0027Create (or update) an allocation of a resource class. \u0027"},{"line_number":64,"context_line":"                 \u0027Specify option multiple times to set multiple allocations.\u0027"},{"line_number":65,"context_line":"        )"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        return parser"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_634f5492","line":65,"range":{"start_line":57,"start_character":8,"end_line":65,"end_character":9},"in_reply_to":"7f96bb07_33b1b790","updated":"2018-01-23 15:15:15.000000000","message":"\u003e \u003e Maybe the answer is some actual ReST docs for command samples,\n \u003e but that could be a TODO.\n \u003e \n \u003e Looks like we could build something into the \"Usage\" docs:\n \u003e \n \u003e http://logs.openstack.org/34/457534/11/check/build-openstack-sphinx-docs/5d90584/html/usage.html\n\nDone in this change:\n\nhttps://review.openstack.org/#/c/536858/","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fd749cc26708c4b1504486a5139d39293839d7d0","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            metavar\u003d\u0027\u003cuuid\u003e\u0027,"},{"line_number":55,"context_line":"            help\u003d\u0027UUID of the consumer\u0027"},{"line_number":56,"context_line":"        )"},{"line_number":57,"context_line":"        parser.add_argument("},{"line_number":58,"context_line":"            \u0027--allocation\u0027,"},{"line_number":59,"context_line":"            metavar\u003d\u0027\u003crp\u003dresource-provider-id,\u0027"},{"line_number":60,"context_line":"                    \u0027resource-class-name\u003damount-of-resource-used\u003e\u0027,"},{"line_number":61,"context_line":"            action\u003d\u0027append\u0027,"},{"line_number":62,"context_line":"            default\u003d[],"},{"line_number":63,"context_line":"            help\u003d\u0027Create (or update) an allocation of a resource class. \u0027"},{"line_number":64,"context_line":"                 \u0027Specify option multiple times to set multiple allocations.\u0027"},{"line_number":65,"context_line":"        )"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        return parser"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_33b1b790","line":65,"range":{"start_line":57,"start_character":8,"end_line":65,"end_character":9},"in_reply_to":"7f96bb07_f3f26f9a","updated":"2018-01-23 00:09:51.000000000","message":"\u003e Maybe the answer is some actual ReST docs for command samples, but that could be a TODO.\n\nLooks like we could build something into the \"Usage\" docs:\n\nhttp://logs.openstack.org/34/457534/11/check/build-openstack-sphinx-docs/5d90584/html/usage.html","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"}],"osc_placement/resources/resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"36393efc86a151e52dcdad2d4c65eea23360702f","unresolved":false,"context_lines":[{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        if parsed_args.allocations:"},{"line_number":115,"context_line":"            allocs_url \u003d ALLOCATIONS_URL.format(uuid\u003dparsed_args.uuid)"},{"line_number":116,"context_line":"            allocs \u003d http.request(\u0027GET\u0027, allocs_url).json()[\u0027allocations\u0027]"},{"line_number":117,"context_line":"            resource[\u0027allocations\u0027] \u003d allocs"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"            return common.repr_one(FIELDS + (\u0027allocations\u0027, ), resource)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7ffa3b31_e32b6b7f","line":116,"updated":"2017-04-19 12:13:58.000000000","message":"could be a lot of results, but that\u0027s okay, I guess.","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a36fa447b4603086cf62729572ea538fd94e2969","unresolved":false,"context_lines":[{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        if parsed_args.allocations:"},{"line_number":115,"context_line":"            allocs_url \u003d ALLOCATIONS_URL.format(uuid\u003dparsed_args.uuid)"},{"line_number":116,"context_line":"            allocs \u003d http.request(\u0027GET\u0027, allocs_url).json()[\u0027allocations\u0027]"},{"line_number":117,"context_line":"            resource[\u0027allocations\u0027] \u003d allocs"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"            return common.repr_one(FIELDS + (\u0027allocations\u0027, ), resource)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7ffa3b31_6611825d","line":116,"in_reply_to":"7ffa3b31_e32b6b7f","updated":"2017-04-20 13:36:08.000000000","message":"Hmm, good point. I\u0027m not sure if OSC allows conditional output based on the format user requested. If it does, we may explore that option in the future and only return all allocations if the requested format is CSV or JSON.","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c020d5104e00abc3e48e0491a4f0b2cdf9875ed3","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        parser.add_argument("},{"line_number":97,"context_line":"            \u0027--allocations\u0027,"},{"line_number":98,"context_line":"            action\u003d\u0027store_true\u0027,"},{"line_number":99,"context_line":"            help\u003d\u0027include the info on allocations of the provider resources\u0027"},{"line_number":100,"context_line":"        )"},{"line_number":101,"context_line":"        parser.add_argument("},{"line_number":102,"context_line":"            \u0027uuid\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_9e260768","line":99,"range":{"start_line":99,"start_character":18,"end_line":99,"end_character":25},"updated":"2017-11-28 21:18:55.000000000","message":"Include\n\nThis is how this ends up looking:\n\nstack@queens:~/osc-placement$ openstack resource provider show f3496844-76c5-439a-99d3-678efd159cf3 --allocations\n+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Field       | Value                                                                                                                                                                                                              |\n+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| uuid        | f3496844-76c5-439a-99d3-678efd159cf3                                                                                                                                                                               |\n| name        | queens                                                                                                                                                                                                             |\n| generation  | 3                                                                                                                                                                                                                  |\n| allocations | {u\u00279f1f7054-f54e-463c-acc2-a3b5c59815fd\u0027: {u\u0027resources\u0027: {u\u0027VCPU\u0027: 1, u\u0027MEMORY_MB\u0027: 512, u\u0027DISK_GB\u0027: 1}}, u\u002781bf6cc5-f06c-4e03-9162-7758e42bd09b\u0027: {u\u0027resources\u0027: {u\u0027VCPU\u0027: 1, u\u0027MEMORY_MB\u0027: 512, u\u0027DISK_GB\u0027: 1}}} |\n+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n\nMaybe we should mention something in the help that it\u0027s a dict of allocation records keyed by consumer UUID, just so people know what that UUID is in the allocations dict.\n\nNote that this also gets pretty ugly once you have more than one consumer for this provider. I\u0027m not sure if there is a better way to format the allocations value though.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"}],"osc_placement/tests/functional/test_allocation.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2c6bee6b80719981ef7337d5d743bb8dc70dec0d","unresolved":false,"context_lines":[{"line_number":27,"context_line":"            \u0027VCPU:max_unit\u003d4\u0027,"},{"line_number":28,"context_line":"            \u0027MEMORY_MB\u003d1024\u0027,"},{"line_number":29,"context_line":"            \u0027MEMORY_MB:max_unit\u003d1024\u0027)"},{"line_number":30,"context_line":"        self.rp2 \u003d self.resource_provider_create()"},{"line_number":31,"context_line":"        self.inv_disk2 \u003d self.resource_inventory_set("},{"line_number":32,"context_line":"            self.rp2[\u0027uuid\u0027],"},{"line_number":33,"context_line":"            \u0027DISK_GB\u003d100\u0027,"},{"line_number":34,"context_line":"            \u0027DISK_GB:max_unit\u003d100\u0027)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def test_allocation_show(self):"},{"line_number":37,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_e14f7268","line":34,"range":{"start_line":30,"start_character":8,"end_line":34,"end_character":35},"updated":"2017-11-28 21:32:00.000000000","message":"This is never used.","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2c6bee6b80719981ef7337d5d743bb8dc70dec0d","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    def test_allocation_show(self):"},{"line_number":37,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        self.resource_allocation_set("},{"line_number":40,"context_line":"            consumer_uuid,"},{"line_number":41,"context_line":"            [\u0027rp\u003d{},VCPU\u003d2\u0027.format(self.rp1[\u0027uuid\u0027]),"},{"line_number":42,"context_line":"             \u0027rp\u003d{},MEMORY_MB\u003d512\u0027.format(self.rp1[\u0027uuid\u0027])]"},{"line_number":43,"context_line":"        )"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"        allocations \u003d self.resource_allocation_show(consumer_uuid)"},{"line_number":46,"context_line":"        self.assertEqual([{\u0027resource_provider\u0027: self.rp1[\u0027uuid\u0027],"},{"line_number":47,"context_line":"                           \u0027generation\u0027: 2,"},{"line_number":48,"context_line":"                           \u0027resources\u0027: {\u0027VCPU\u0027: 2, \u0027MEMORY_MB\u0027: 512}}],"},{"line_number":49,"context_line":"                         allocations)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def test_allocation_show_not_found(self):"},{"line_number":52,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_012e1691","line":49,"range":{"start_line":39,"start_character":8,"end_line":49,"end_character":37},"updated":"2017-11-28 21:32:00.000000000","message":"I\u0027m not sure how this is working because from the way the code looks and what I\u0027m seeing in the CLI, it only saves the last resource class entry for a given consumer and provider:\n\nstack@queens:~/osc-placement$ openstack resource provider allocation set c07d8dab-5f02-44e1-a190-f6ca3eb4f99c --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,VCPU\u003d4 --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,MEMORY_MB\u003d1024 --allocation rp\u003df3496844-76c5-439a-99d3-678efd159cf3,DISK_GB\u003d100\n+--------------------------------------+------------+-------------------+\n| resource_provider                    | generation | resources         |\n+--------------------------------------+------------+-------------------+\n| f3496844-76c5-439a-99d3-678efd159cf3 |          4 | {u\u0027DISK_GB\u0027: 100} |\n+--------------------------------------+------------+-------------------+","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2c6bee6b80719981ef7337d5d743bb8dc70dec0d","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        result \u003d self.resource_allocation_show(consumer_uuid)"},{"line_number":55,"context_line":"        self.assertEqual([], result)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_allocation_create(self):"},{"line_number":58,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_be150b4b","line":55,"range":{"start_line":55,"start_character":8,"end_line":55,"end_character":36},"updated":"2017-11-28 21:32:00.000000000","message":"I expected this to fail but I guess we can\u0027t verify the consumer uuid:\n\nhttps://github.com/openstack/nova/blob/master/nova/api/openstack/placement/handlers/allocation.py#L251","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2c6bee6b80719981ef7337d5d743bb8dc70dec0d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        result \u003d self.resource_allocation_show(consumer_uuid)"},{"line_number":55,"context_line":"        self.assertEqual([], result)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def test_allocation_create(self):"},{"line_number":58,"context_line":"        consumer_uuid \u003d str(uuid.uuid4())"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        created_alloc \u003d self.resource_allocation_set("}],"source_content_type":"text/x-python","patch_set":10,"id":"ff82abbf_412f3e87","line":57,"range":{"start_line":57,"start_character":8,"end_line":57,"end_character":30},"updated":"2017-11-28 21:32:00.000000000","message":"How is this test any different than test_allocation_show?","commit_id":"f7a5b6ff9a58527ef1fbdaaaf06aec24a40eaa71"}],"osc_placement/tests/unit/test_allocation.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            rp1: {\u0027VCPU\u0027: 4, \u0027MEMORY_MB\u0027: 16324},"},{"line_number":29,"context_line":"            rp2: {\u0027VCPU\u0027: 4, \u0027DISK_GB\u0027: 4096},"},{"line_number":30,"context_line":"        }"},{"line_number":31,"context_line":"        self.assertEqual(expected, allocation.parse_allocations(allocations))"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    def test_merge_allocations(self):"},{"line_number":34,"context_line":"        rp1 \u003d str(uuid.uuid4())"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_33553751","line":31,"range":{"start_line":31,"start_character":13,"end_line":31,"end_character":24},"updated":"2018-01-23 00:06:34.000000000","message":"Use assertDictEqual? I worry about the python hashseed here making this sometimes work and sometimes fail.","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"225f3e48714ece0e49cb1e300c214819a3d8e075","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            rp1: {\u0027VCPU\u0027: 4, \u0027MEMORY_MB\u0027: 16324},"},{"line_number":29,"context_line":"            rp2: {\u0027VCPU\u0027: 4, \u0027DISK_GB\u0027: 4096},"},{"line_number":30,"context_line":"        }"},{"line_number":31,"context_line":"        self.assertEqual(expected, allocation.parse_allocations(allocations))"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    def test_merge_allocations(self):"},{"line_number":34,"context_line":"        rp1 \u003d str(uuid.uuid4())"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_0928f131","line":31,"range":{"start_line":31,"start_character":13,"end_line":31,"end_character":24},"in_reply_to":"7f96bb07_33553751","updated":"2018-01-23 15:51:29.000000000","message":"Done in https://review.openstack.org/#/c/536871/","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":45,"context_line":"            \u0027rp\u003d{},VCPU\u003d4,MEMORY_MB\u003d16324\u0027.format(rp1),"},{"line_number":46,"context_line":"            \u0027rp\u003d{},VCPU\u003d8,DISK_GB\u003d4096\u0027.format(rp1)]"},{"line_number":47,"context_line":"        self.assertRaises("},{"line_number":48,"context_line":"            exceptions.CommandError, allocation.parse_allocations, allocations)"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def test_fail_if_incorect_format(self):"},{"line_number":51,"context_line":"        allocations \u003d [\u0027incorrect_format\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_d3c97325","line":48,"updated":"2018-01-23 00:06:34.000000000","message":"nit: assert that it fails for the reason you expect, e.g.:\n\nex \u003d self.assertRaises(...)\nself.assertEqual(\u0027Conflict detected...\u0027, six.text_type(ex))","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c68dac76514df76f5719583ed2f0218f1b1f2697","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        self.assertRaises("},{"line_number":48,"context_line":"            exceptions.CommandError, allocation.parse_allocations, allocations)"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def test_fail_if_incorect_format(self):"},{"line_number":51,"context_line":"        allocations \u003d [\u0027incorrect_format\u0027]"},{"line_number":52,"context_line":"        self.assertRaisesRegexp("},{"line_number":53,"context_line":"            ValueError,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7f96bb07_33da17e9","line":50,"range":{"start_line":50,"start_character":21,"end_line":50,"end_character":29},"updated":"2018-01-23 00:06:34.000000000","message":"nit: incorrect","commit_id":"5c65e7978301e944861a2620ddb393c0da8f0e38"}],"setup.cfg":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"36393efc86a151e52dcdad2d4c65eea23360702f","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    placement \u003d osc_placement.plugin"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"openstack.placement.v1 \u003d"},{"line_number":30,"context_line":"    resource-provider_allocation_create \u003d osc_placement.resources.allocation:CreateAllocation"},{"line_number":31,"context_line":"    resource-provider_allocation_show   \u003d osc_placement.resources.allocation:ShowAllocation"},{"line_number":32,"context_line":"    resource-provider_allocation_delete \u003d osc_placement.resources.allocation:DeleteAllocation"},{"line_number":33,"context_line":"    resource-provider_create \u003d osc_placement.resources.resource_provider:CreateResourceProvider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":1,"id":"7ffa3b31_037777a2","line":30,"updated":"2017-04-19 12:13:58.000000000","message":"maybe set, as it\u0027s a PUT","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a36fa447b4603086cf62729572ea538fd94e2969","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    placement \u003d osc_placement.plugin"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"openstack.placement.v1 \u003d"},{"line_number":30,"context_line":"    resource-provider_allocation_create \u003d osc_placement.resources.allocation:CreateAllocation"},{"line_number":31,"context_line":"    resource-provider_allocation_show   \u003d osc_placement.resources.allocation:ShowAllocation"},{"line_number":32,"context_line":"    resource-provider_allocation_delete \u003d osc_placement.resources.allocation:DeleteAllocation"},{"line_number":33,"context_line":"    resource-provider_create \u003d osc_placement.resources.resource_provider:CreateResourceProvider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":1,"id":"7ffa3b31_81059813","line":30,"in_reply_to":"7ffa3b31_037777a2","updated":"2017-04-20 13:36:08.000000000","message":"Done","commit_id":"90dd2a3dcc7f5fed4fbb3607d16cbdcbd7bb9252"}]}
