)]}'
{"nova/tests/virt/xenapi/image/test_utils.py":[{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"751516ac7039657d20a9b628df7e1cd35a7fea1b","unresolved":false,"context_lines":[{"line_number":172,"context_line":"class RawTGZTestCase(test.TestCase):"},{"line_number":173,"context_line":"    def test_as_tarfile(self):"},{"line_number":174,"context_line":"        image \u003d utils.RawTGZImage(None)"},{"line_number":175,"context_line":"        self.mox.StubOutWithMock(image, \u0027_as_file\u0027)"},{"line_number":176,"context_line":"        self.mox.StubOutWithMock(utils.tarfile, \u0027open\u0027)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        image._as_file().AndReturn(\u0027the_file\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAASn%2F%2F0EM%3D","line":175,"updated":"2013-08-29 08:33:32.000000000","message":"please do not use mox. use mock instead","commit_id":"70d3d9afd75dfd4a33d004f5f6ac27aec51c1c93"}],"nova/virt/xenapi/image/utils.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"acfb261bfb8254027743b8ee0586207a8d2939f3","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        return return_value"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class RawTGZImage(object):"},{"line_number":86,"context_line":"    def __init__(self, glance_image):"},{"line_number":87,"context_line":"        self.glance_image \u003d glance_image"},{"line_number":88,"context_line":"        self._tar_info \u003d None"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAASn%2F%2FlCU%3D","line":85,"updated":"2013-09-03 09:25:20.000000000","message":"It seems like this should be added in the common code:\nhttps://github.com/openstack/nova/blob/master/nova/image/glance.py\n\nSomething like a download_and_extract_tar_to() that triggers on the appropriate container format? This way all hypervisors can download tgz raw images.","commit_id":"bf3c74563bdb6e0019db2af14c3df629d429f56b"}],"nova/virt/xenapi/vm_utils.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"e8393d421ef5be72410aa1c63eb15f610c470fc0","unresolved":false,"context_lines":[{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":""},{"line_number":1211,"context_line":"def get_stream_funct_for(context, image_service, image_id):"},{"line_number":1212,"context_line":"    meta \u003d image_service.show(context, image_id)"},{"line_number":1213,"context_line":"    if meta.get(\u0027container_format\u0027) \u003d\u003d \u0027ovf\u0027:"},{"line_number":1214,"context_line":"        return raw_tgz_create_streamer(context, image_service, image_id)"},{"line_number":1215,"context_line":"    return create_raw_image_streamer(context, image_service, image_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FvwU%3D","line":1212,"updated":"2013-08-22 11:59:00.000000000","message":"This is an HTTP call, it seems wasteful to do it more than once.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9948e37da32714f2d3475ad4e4f3fef55fce341a","unresolved":false,"context_lines":[{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":""},{"line_number":1211,"context_line":"def get_stream_funct_for(context, image_service, image_id):"},{"line_number":1212,"context_line":"    meta \u003d image_service.show(context, image_id)"},{"line_number":1213,"context_line":"    if meta.get(\u0027container_format\u0027) \u003d\u003d \u0027ovf\u0027:"},{"line_number":1214,"context_line":"        return raw_tgz_create_streamer(context, image_service, image_id)"},{"line_number":1215,"context_line":"    return create_raw_image_streamer(context, image_service, image_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FumM%3D","line":1212,"in_reply_to":"AAAARn%2F%2Fvsk%3D","updated":"2013-08-22 16:34:09.000000000","message":"Yeah, passing the metadata makes sense, or pass around that object and store the metadata in it, and it only fetches that once?","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"aac00068024d3206d4613aeeb9bebdf83f7dbbb0","unresolved":false,"context_lines":[{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":""},{"line_number":1211,"context_line":"def get_stream_funct_for(context, image_service, image_id):"},{"line_number":1212,"context_line":"    meta \u003d image_service.show(context, image_id)"},{"line_number":1213,"context_line":"    if meta.get(\u0027container_format\u0027) \u003d\u003d \u0027ovf\u0027:"},{"line_number":1214,"context_line":"        return raw_tgz_create_streamer(context, image_service, image_id)"},{"line_number":1215,"context_line":"    return create_raw_image_streamer(context, image_service, image_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2Fvsk%3D","line":1212,"in_reply_to":"AAAARn%2F%2FvwU%3D","updated":"2013-08-22 12:09:49.000000000","message":"I am not too worried about the cost of this http call.\n\nWhat would be your preference:\n- Create a caching image service\n- pass around metadata?\n\nFor me passing around meta seems to be the easiest.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"aac00068024d3206d4613aeeb9bebdf83f7dbbb0","unresolved":false,"context_lines":[{"line_number":1210,"context_line":""},{"line_number":1211,"context_line":"def get_stream_funct_for(context, image_service, image_id):"},{"line_number":1212,"context_line":"    meta \u003d image_service.show(context, image_id)"},{"line_number":1213,"context_line":"    if meta.get(\u0027container_format\u0027) \u003d\u003d \u0027ovf\u0027:"},{"line_number":1214,"context_line":"        return raw_tgz_create_streamer(context, image_service, image_id)"},{"line_number":1215,"context_line":"    return create_raw_image_streamer(context, image_service, image_id)"},{"line_number":1216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FvsU%3D","line":1213,"updated":"2013-08-22 12:09:49.000000000","message":"I think we need to investigate for the rawness at this point as well.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9948e37da32714f2d3475ad4e4f3fef55fce341a","unresolved":false,"context_lines":[{"line_number":1210,"context_line":""},{"line_number":1211,"context_line":"def get_stream_funct_for(context, image_service, image_id):"},{"line_number":1212,"context_line":"    meta \u003d image_service.show(context, image_id)"},{"line_number":1213,"context_line":"    if meta.get(\u0027container_format\u0027) \u003d\u003d \u0027ovf\u0027:"},{"line_number":1214,"context_line":"        return raw_tgz_create_streamer(context, image_service, image_id)"},{"line_number":1215,"context_line":"    return create_raw_image_streamer(context, image_service, image_id)"},{"line_number":1216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2Fumo%3D","line":1213,"in_reply_to":"AAAARn%2F%2FvsU%3D","updated":"2013-08-22 16:34:09.000000000","message":"Yeah, that makes sense.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"e8393d421ef5be72410aa1c63eb15f610c470fc0","unresolved":false,"context_lines":[{"line_number":1268,"context_line":"        return tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        tarfile \u003d self.as_tarfile()"},{"line_number":1272,"context_line":"        tar_info \u003d tarfile.next()"},{"line_number":1273,"context_line":"        source_file \u003d tarfile.extractfile(tar_info)"},{"line_number":1274,"context_line":"        shutil.copyfileobj(source_file, target_file)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FvwI%3D","line":1271,"updated":"2013-08-22 11:59:00.000000000","message":"Seems odd to download the first bit of the image twice when just checking for the size and the streaming.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"308d88d06dd93b78cf063dcfe9c296b71ecccf4e","unresolved":false,"context_lines":[{"line_number":1268,"context_line":"        return tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        tarfile \u003d self.as_tarfile()"},{"line_number":1272,"context_line":"        tar_info \u003d tarfile.next()"},{"line_number":1273,"context_line":"        source_file \u003d tarfile.extractfile(tar_info)"},{"line_number":1274,"context_line":"        shutil.copyfileobj(source_file, target_file)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAASX%2F%2F%2F%2BI%3D","line":1271,"in_reply_to":"AAAARn%2F%2FumE%3D","updated":"2013-08-22 18:22:44.000000000","message":"I will look at how to close the resource provided by glance client.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9948e37da32714f2d3475ad4e4f3fef55fce341a","unresolved":false,"context_lines":[{"line_number":1268,"context_line":"        return tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        tarfile \u003d self.as_tarfile()"},{"line_number":1272,"context_line":"        tar_info \u003d tarfile.next()"},{"line_number":1273,"context_line":"        source_file \u003d tarfile.extractfile(tar_info)"},{"line_number":1274,"context_line":"        shutil.copyfileobj(source_file, target_file)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FumE%3D","line":1271,"in_reply_to":"AAAARn%2F%2FvtQ%3D","updated":"2013-08-22 16:34:09.000000000","message":"cool, sounds good.\n\nJust made me think about clearing up resources if the whole stream is not used up, not sure how safe all those utils are in that way, should you close the tarfile?","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"aac00068024d3206d4613aeeb9bebdf83f7dbbb0","unresolved":false,"context_lines":[{"line_number":1268,"context_line":"        return tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        tarfile \u003d self.as_tarfile()"},{"line_number":1272,"context_line":"        tar_info \u003d tarfile.next()"},{"line_number":1273,"context_line":"        source_file \u003d tarfile.extractfile(tar_info)"},{"line_number":1274,"context_line":"        shutil.copyfileobj(source_file, target_file)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARn%2F%2FvtQ%3D","line":1271,"in_reply_to":"AAAARn%2F%2FvwI%3D","updated":"2013-08-22 12:09:49.000000000","message":"I will try to start reading the stream, get the size, and carry on with reading the rest later.","commit_id":"7e9d4cdc960ebd67ecb38549047e7388fbbe3dc5"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"        return return_value"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":""},{"line_number":1230,"context_line":"class _RawTGZState(object):"},{"line_number":1231,"context_line":"    def __init__(self, raw_tgz_context):"},{"line_number":1232,"context_line":"        self.raw_tgz_context \u003d raw_tgz_context"},{"line_number":1233,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8II%3D","line":1230,"updated":"2013-08-23 13:53:11.000000000","message":"This doesn\u0027t seem very pythonic, just use duck typing maybe?","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"        return return_value"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":""},{"line_number":1230,"context_line":"class _RawTGZState(object):"},{"line_number":1231,"context_line":"    def __init__(self, raw_tgz_context):"},{"line_number":1232,"context_line":"        self.raw_tgz_context \u003d raw_tgz_context"},{"line_number":1233,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7qU%3D","line":1230,"in_reply_to":"AAAASX%2F%2F8II%3D","updated":"2013-08-23 15:29:26.000000000","message":"It was quite useful during the development - it was throwing the NotImplementedErrors to my face, shouting for implementation, but it\u0027s really not used anywhere. It could go to the bin.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1238,"context_line":"        raise NotImplementedError()"},{"line_number":1239,"context_line":""},{"line_number":1240,"context_line":""},{"line_number":1241,"context_line":"class _RawTGZFinishedState(_RawTGZState):"},{"line_number":1242,"context_line":"    def get_size(self):"},{"line_number":1243,"context_line":"        raise ValueError(\"End of stream\")"},{"line_number":1244,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8H4%3D","line":1241,"updated":"2013-08-23 13:53:11.000000000","message":"Not sure about all the _, but it does help you see the class that gets used.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1238,"context_line":"        raise NotImplementedError()"},{"line_number":1239,"context_line":""},{"line_number":1240,"context_line":""},{"line_number":1241,"context_line":"class _RawTGZFinishedState(_RawTGZState):"},{"line_number":1242,"context_line":"    def get_size(self):"},{"line_number":1243,"context_line":"        raise ValueError(\"End of stream\")"},{"line_number":1244,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vU%3D","line":1241,"in_reply_to":"AAAASX%2F%2F8H4%3D","updated":"2013-08-23 15:29:26.000000000","message":"This communicates, that it is an internal class, representing the states of the RawTGZImage I think you are right, these underscores are","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1247,"context_line":""},{"line_number":1248,"context_line":""},{"line_number":1249,"context_line":"class _RawTGZInitialState(_RawTGZState):"},{"line_number":1250,"context_line":"    def get_size(self):"},{"line_number":1251,"context_line":"        ctx \u003d self.raw_tgz_context"},{"line_number":1252,"context_line":"        ctx._tar_file \u003d ctx._as_tarfile()"},{"line_number":1253,"context_line":"        ctx._tar_info \u003d ctx._tar_file.next()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vw%3D","line":1250,"updated":"2013-08-23 15:29:26.000000000","message":"In the initial state, we need to open the stream, and read the first tarinfo","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1251,"context_line":"        ctx \u003d self.raw_tgz_context"},{"line_number":1252,"context_line":"        ctx._tar_file \u003d ctx._as_tarfile()"},{"line_number":1253,"context_line":"        ctx._tar_info \u003d ctx._tar_file.next()"},{"line_number":1254,"context_line":"        ctx.state \u003d ctx.state_info_processed"},{"line_number":1255,"context_line":"        return ctx._tar_info.size"},{"line_number":1256,"context_line":""},{"line_number":1257,"context_line":"    def stream_to(self, target_file):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vs%3D","line":1254,"updated":"2013-08-23 15:29:26.000000000","message":"And we change the state to info_processed.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1254,"context_line":"        ctx.state \u003d ctx.state_info_processed"},{"line_number":1255,"context_line":"        return ctx._tar_info.size"},{"line_number":1256,"context_line":""},{"line_number":1257,"context_line":"    def stream_to(self, target_file):"},{"line_number":1258,"context_line":"        ctx \u003d self.raw_tgz_context"},{"line_number":1259,"context_line":"        tarfile \u003d ctx._as_tarfile()"},{"line_number":1260,"context_line":"        tar_info \u003d tarfile.next()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vg%3D","line":1257,"updated":"2013-08-23 15:29:26.000000000","message":"In the initial state, if we want to get the stream, we have to read one tarinfo, skip it, and copy the contents to the given file","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1259,"context_line":"        tarfile \u003d ctx._as_tarfile()"},{"line_number":1260,"context_line":"        tar_info \u003d tarfile.next()"},{"line_number":1261,"context_line":"        source_file \u003d tarfile.extractfile(tar_info)"},{"line_number":1262,"context_line":"        shutil.copyfileobj(source_file, target_file)"},{"line_number":1263,"context_line":"        ctx.state \u003d ctx.state_finished"},{"line_number":1264,"context_line":""},{"line_number":1265,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vY%3D","line":1262,"updated":"2013-08-23 15:29:26.000000000","message":"We change the state to finished, as we cannot read the stream again.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1263,"context_line":"        ctx.state \u003d ctx.state_finished"},{"line_number":1264,"context_line":""},{"line_number":1265,"context_line":""},{"line_number":1266,"context_line":"class _RawTGZInfoReadState(_RawTGZState):"},{"line_number":1267,"context_line":"    def get_size(self):"},{"line_number":1268,"context_line":"        return self.raw_tgz_context._tar_info.size"},{"line_number":1269,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vQ%3D","line":1266,"updated":"2013-08-23 15:29:26.000000000","message":"We already read the tar info in this state.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1264,"context_line":""},{"line_number":1265,"context_line":""},{"line_number":1266,"context_line":"class _RawTGZInfoReadState(_RawTGZState):"},{"line_number":1267,"context_line":"    def get_size(self):"},{"line_number":1268,"context_line":"        return self.raw_tgz_context._tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7vI%3D","line":1267,"updated":"2013-08-23 15:29:26.000000000","message":"So a request for the size is as easy to get the tar_info from the context. It also does not read the stream, thus no change in state.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1267,"context_line":"    def get_size(self):"},{"line_number":1268,"context_line":"        return self.raw_tgz_context._tar_info.size"},{"line_number":1269,"context_line":""},{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        ctx \u003d self.raw_tgz_context"},{"line_number":1272,"context_line":"        source_file \u003d ctx._tar_file.extractfile(ctx._tar_info)"},{"line_number":1273,"context_line":"        shutil.copyfileobj(source_file, target_file)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7u8%3D","line":1270,"updated":"2013-08-23 15:29:26.000000000","message":"If someone is interested in the data, the tar stream\u0027s position is at the right place, all we need to do is copy.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1270,"context_line":"    def stream_to(self, target_file):"},{"line_number":1271,"context_line":"        ctx \u003d self.raw_tgz_context"},{"line_number":1272,"context_line":"        source_file \u003d ctx._tar_file.extractfile(ctx._tar_info)"},{"line_number":1273,"context_line":"        shutil.copyfileobj(source_file, target_file)"},{"line_number":1274,"context_line":"        ctx.state \u003d ctx.state_finished"},{"line_number":1275,"context_line":""},{"line_number":1276,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7uo%3D","line":1273,"updated":"2013-08-23 15:29:26.000000000","message":"And change the state to finished.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"68d4e673c0bd22297348cc94cd8c663a63f15f7f","unresolved":false,"context_lines":[{"line_number":1274,"context_line":"        ctx.state \u003d ctx.state_finished"},{"line_number":1275,"context_line":""},{"line_number":1276,"context_line":""},{"line_number":1277,"context_line":"class GlanceImage(object):"},{"line_number":1278,"context_line":"    def __init__(self, context, image_href_or_id):"},{"line_number":1279,"context_line":"        self.context \u003d context"},{"line_number":1280,"context_line":"        self.image_href_or_id \u003d image_href_or_id"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8ew%3D","line":1277,"updated":"2013-08-23 12:09:13.000000000","message":"Maybe we should start an image_utils file?","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"a6bd74ac05ff387945e68093f6a8177a9bcdcfd7","unresolved":false,"context_lines":[{"line_number":1274,"context_line":"        ctx.state \u003d ctx.state_finished"},{"line_number":1275,"context_line":""},{"line_number":1276,"context_line":""},{"line_number":1277,"context_line":"class GlanceImage(object):"},{"line_number":1278,"context_line":"    def __init__(self, context, image_href_or_id):"},{"line_number":1279,"context_line":"        self.context \u003d context"},{"line_number":1280,"context_line":"        self.image_href_or_id \u003d image_href_or_id"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8Y8%3D","line":1277,"in_reply_to":"AAAASX%2F%2F8ew%3D","updated":"2013-08-23 12:26:47.000000000","message":"Sounds good, could we do it in another change?","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1318,"context_line":"        return int(self.glance_image.meta[\u0027size\u0027])"},{"line_number":1319,"context_line":""},{"line_number":1320,"context_line":"    def get_stream_func(self):"},{"line_number":1321,"context_line":"        return create_raw_image_streamer("},{"line_number":1322,"context_line":"            self.glance_image.context,"},{"line_number":1323,"context_line":"            self.glance_image.image_service,"},{"line_number":1324,"context_line":"            self.glance_image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8HQ%3D","line":1321,"updated":"2013-08-23 13:53:11.000000000","message":"I think its easier to read if you include the implementation here. Can do good old DI to test it.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1318,"context_line":"        return int(self.glance_image.meta[\u0027size\u0027])"},{"line_number":1319,"context_line":""},{"line_number":1320,"context_line":"    def get_stream_func(self):"},{"line_number":1321,"context_line":"        return create_raw_image_streamer("},{"line_number":1322,"context_line":"            self.glance_image.context,"},{"line_number":1323,"context_line":"            self.glance_image.image_service,"},{"line_number":1324,"context_line":"            self.glance_image.image_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7xU%3D","line":1321,"in_reply_to":"AAAASX%2F%2F8HQ%3D","updated":"2013-08-23 15:29:26.000000000","message":"sure","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1331,"context_line":"        self._tar_file \u003d None"},{"line_number":1332,"context_line":"        self.state_initial \u003d _RawTGZInitialState(self)"},{"line_number":1333,"context_line":"        self.state_info_processed \u003d _RawTGZInfoReadState(self)"},{"line_number":1334,"context_line":"        self.state_finished \u003d _RawTGZFinishedState(self)"},{"line_number":1335,"context_line":"        self.state \u003d self.state_initial"},{"line_number":1336,"context_line":""},{"line_number":1337,"context_line":"    def _as_file(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7v0%3D","line":1334,"updated":"2013-08-23 15:29:26.000000000","message":"By default, we start with the initial state.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1332,"context_line":"        self.state_initial \u003d _RawTGZInitialState(self)"},{"line_number":1333,"context_line":"        self.state_info_processed \u003d _RawTGZInfoReadState(self)"},{"line_number":1334,"context_line":"        self.state_finished \u003d _RawTGZFinishedState(self)"},{"line_number":1335,"context_line":"        self.state \u003d self.state_initial"},{"line_number":1336,"context_line":""},{"line_number":1337,"context_line":"    def _as_file(self):"},{"line_number":1338,"context_line":"        return IterableBasedFile("}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8Ec%3D","line":1335,"updated":"2013-08-23 13:53:11.000000000","message":"how does the state change? its very hard to understand the flow here.\n\nI think this would be simpler if the state was stored in this class, and callbacks were used to report the updates from a \"StreamGenerator\" or something like that?","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1332,"context_line":"        self.state_initial \u003d _RawTGZInitialState(self)"},{"line_number":1333,"context_line":"        self.state_info_processed \u003d _RawTGZInfoReadState(self)"},{"line_number":1334,"context_line":"        self.state_finished \u003d _RawTGZFinishedState(self)"},{"line_number":1335,"context_line":"        self.state \u003d self.state_initial"},{"line_number":1336,"context_line":""},{"line_number":1337,"context_line":"    def _as_file(self):"},{"line_number":1338,"context_line":"        return IterableBasedFile("}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F74w%3D","line":1335,"in_reply_to":"AAAASX%2F%2F8Ec%3D","updated":"2013-08-23 15:29:26.000000000","message":"I used the state pattern here, something like this:\n\n https://github.com/gennad/Design-Patterns-in-Python/blob/master/state.py\n\nThis object is the context. Calls are delegated to the actual state, and they do the transitions as well (modify the context)","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1342,"context_line":"    def _as_tarfile(self):"},{"line_number":1343,"context_line":"        return tarfile.open(mode\u003d\u0027r|gz\u0027, fileobj\u003dself._as_file())"},{"line_number":1344,"context_line":""},{"line_number":1345,"context_line":"    def get_size(self):"},{"line_number":1346,"context_line":"        return self.state.get_size()"},{"line_number":1347,"context_line":""},{"line_number":1348,"context_line":"    def stream_to(self, target_file):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7v8%3D","line":1345,"updated":"2013-08-23 15:29:26.000000000","message":"You can see, get_size is delegated to the actual state.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1346,"context_line":"        return self.state.get_size()"},{"line_number":1347,"context_line":""},{"line_number":1348,"context_line":"    def stream_to(self, target_file):"},{"line_number":1349,"context_line":"        return self.state.stream_to(target_file)"},{"line_number":1350,"context_line":""},{"line_number":1351,"context_line":"    def get_virtual_size(self):"},{"line_number":1352,"context_line":"        return self.get_size()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7v4%3D","line":1349,"updated":"2013-08-23 15:29:26.000000000","message":"And stream_to is delegated to the actual state as well","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1351,"context_line":"    def get_virtual_size(self):"},{"line_number":1352,"context_line":"        return self.get_size()"},{"line_number":1353,"context_line":""},{"line_number":1354,"context_line":"    def get_stream_func(self):"},{"line_number":1355,"context_line":"        return self.stream_to"},{"line_number":1356,"context_line":""},{"line_number":1357,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7%2F4%3D","line":1354,"updated":"2013-08-23 13:53:11.000000000","message":"I am finding it hard to see what the public interface of this class is different to the RawImage.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1380,"context_line":"    else:"},{"line_number":1381,"context_line":"        sr_ref \u003d safe_find_sr(session)"},{"line_number":1382,"context_line":""},{"line_number":1383,"context_line":"    glance_image \u003d GlanceImage(context, image_id)"},{"line_number":1384,"context_line":"    if glance_image.is_raw_tgz_image():"},{"line_number":1385,"context_line":"        image \u003d RawTGZImage(glance_image)"},{"line_number":1386,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8FI%3D","line":1383,"updated":"2013-08-23 13:53:11.000000000","message":"Could you not just fetch everything up front, then pass it into the object below. its much simpler, and in keep with local style.\n\nI don\u0027t like how we already have a glance abstraction, and we are creating a brand new one just for this little code path, just feels like overkill.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1380,"context_line":"    else:"},{"line_number":1381,"context_line":"        sr_ref \u003d safe_find_sr(session)"},{"line_number":1382,"context_line":""},{"line_number":1383,"context_line":"    glance_image \u003d GlanceImage(context, image_id)"},{"line_number":1384,"context_line":"    if glance_image.is_raw_tgz_image():"},{"line_number":1385,"context_line":"        image \u003d RawTGZImage(glance_image)"},{"line_number":1386,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7sY%3D","line":1383,"in_reply_to":"AAAASX%2F%2F8FI%3D","updated":"2013-08-23 15:29:26.000000000","message":"This thing is representing an image instance. I didn\u0027t know that we already have an abstraction for that. I will look at the code and use that abstraction.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1382,"context_line":""},{"line_number":1383,"context_line":"    glance_image \u003d GlanceImage(context, image_id)"},{"line_number":1384,"context_line":"    if glance_image.is_raw_tgz_image():"},{"line_number":1385,"context_line":"        image \u003d RawTGZImage(glance_image)"},{"line_number":1386,"context_line":"    else:"},{"line_number":1387,"context_line":"        image \u003d RawImage(glance_image)"},{"line_number":1388,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8A4%3D","line":1385,"updated":"2013-08-23 13:53:11.000000000","message":"I do like this encapsulation","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1383,"context_line":"    glance_image \u003d GlanceImage(context, image_id)"},{"line_number":1384,"context_line":"    if glance_image.is_raw_tgz_image():"},{"line_number":1385,"context_line":"        image \u003d RawTGZImage(glance_image)"},{"line_number":1386,"context_line":"    else:"},{"line_number":1387,"context_line":"        image \u003d RawImage(glance_image)"},{"line_number":1388,"context_line":""},{"line_number":1389,"context_line":"    virtual_size \u003d image.get_virtual_size()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8Fc%3D","line":1386,"updated":"2013-08-23 13:53:11.000000000","message":"I know this is the bug we previously spoke about, but this just looks wrong.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1383,"context_line":"    glance_image \u003d GlanceImage(context, image_id)"},{"line_number":1384,"context_line":"    if glance_image.is_raw_tgz_image():"},{"line_number":1385,"context_line":"        image \u003d RawTGZImage(glance_image)"},{"line_number":1386,"context_line":"    else:"},{"line_number":1387,"context_line":"        image \u003d RawImage(glance_image)"},{"line_number":1388,"context_line":""},{"line_number":1389,"context_line":"    virtual_size \u003d image.get_virtual_size()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7sA%3D","line":1386,"in_reply_to":"AAAASX%2F%2F8Fc%3D","updated":"2013-08-23 15:29:26.000000000","message":"Yes, it\u0027s shouting: I am doing the wrong thing! - it wasn\u0027t this obvious with the previous code. I think that\u0027s the real value here.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a3ff6e08e39161cc343704ff15ece220a532f398","unresolved":false,"context_lines":[{"line_number":1386,"context_line":"    else:"},{"line_number":1387,"context_line":"        image \u003d RawImage(glance_image)"},{"line_number":1388,"context_line":""},{"line_number":1389,"context_line":"    virtual_size \u003d image.get_virtual_size()"},{"line_number":1390,"context_line":"    vdi_size \u003d virtual_size"},{"line_number":1391,"context_line":"    LOG.debug(_(\"Size for image %(image_id)s: %(virtual_size)d\"),"},{"line_number":1392,"context_line":"              {\u0027image_id\u0027: image_id, \u0027virtual_size\u0027: virtual_size},"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F8F8%3D","line":1389,"updated":"2013-08-23 13:53:11.000000000","message":"I think this would be better as get_size(), given virtual size doesn\u0027t really come into it here.","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"},{"author":{"_account_id":5044,"name":"Mate Lakat","email":"mlakat@suse.com","username":"mate-lakat"},"change_message_id":"0fa3e613290af6c5bc8641702f96ed5a19e51ce4","unresolved":false,"context_lines":[{"line_number":1386,"context_line":"    else:"},{"line_number":1387,"context_line":"        image \u003d RawImage(glance_image)"},{"line_number":1388,"context_line":""},{"line_number":1389,"context_line":"    virtual_size \u003d image.get_virtual_size()"},{"line_number":1390,"context_line":"    vdi_size \u003d virtual_size"},{"line_number":1391,"context_line":"    LOG.debug(_(\"Size for image %(image_id)s: %(virtual_size)d\"),"},{"line_number":1392,"context_line":"              {\u0027image_id\u0027: image_id, \u0027virtual_size\u0027: virtual_size},"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAASX%2F%2F7qo%3D","line":1389,"in_reply_to":"AAAASX%2F%2F8F8%3D","updated":"2013-08-23 15:29:26.000000000","message":"I used the existing terminology. It\u0027s really not the size of the image, it\u0027s the size of the disk image contained by the image. What about:\n\n get_disk_size()","commit_id":"8ff8715b59b1a8b8ed5a59b931f518ba9f37307f"}]}
