def put_image_layer(image_id): try: json_data = store.get_content(store.image_json_path(image_id)) except IOError: return toolkit.api_error('Image not found', 404) layer_path = store.image_layer_path(image_id) mark_path = store.image_mark_path(image_id) if store.exists(layer_path) and not store.exists(mark_path): return toolkit.api_error('Image already exists', 409) input_stream = flask.request.stream if flask.request.headers.get('transfer-encoding') == 'chunked': # Careful, might work only with WSGI servers supporting chunked # encoding (Gunicorn) input_stream = flask.request.environ['wsgi.input'] # compute checksums csums = [] sr = toolkit.SocketReader(input_stream) tmp, store_hndlr = storage.temp_store_handler() sr.add_handler(store_hndlr) h, sum_hndlr = checksums.simple_checksum_handler(json_data) sr.add_handler(sum_hndlr) store.stream_write(layer_path, sr) csums.append('sha256:{0}'.format(h.hexdigest())) try: tmp.seek(0) csums.append(checksums.compute_tarsum(tmp, json_data)) tmp.close() except (IOError, checksums.TarError) as e: logger.debug('put_image_layer: Error when computing tarsum ' '{0}'.format(e)) try: checksum = store.get_content(store.image_checksum_path(image_id)) except IOError: # We don't have a checksum stored yet, that's fine skipping the check. # Not removing the mark though, image is not downloadable yet. flask.session['checksum'] = csums return toolkit.response() # We check if the checksums provided matches one the one we computed if checksum not in csums: logger.debug('put_image_layer: Wrong checksum') return toolkit.api_error('Checksum mismatch, ignoring the layer') # Checksum is ok, we remove the marker store.remove(mark_path) return toolkit.response()
def put_image_layer(image_id): try: json_data = store.get_content(store.image_json_path(image_id)) except IOError: return toolkit.api_error('Image not found', 404) layer_path = store.image_layer_path(image_id) mark_path = store.image_mark_path(image_id) if store.exists(layer_path) and not store.exists(mark_path): return toolkit.api_error('Image already exists', 409) input_stream = flask.request.stream if flask.request.headers.get('transfer-encoding') == 'chunked': # Careful, might work only with WSGI servers supporting chunked # encoding (Gunicorn) input_stream = flask.request.environ['wsgi.input'] # compute checksums sr = toolkit.SocketReader(input_stream) tmp, store_hndlr = storage.temp_store_handler() sr.add_handler(store_hndlr) h, sum_hndlr = checksums.simple_checksum_handler(json_data) sr.add_handler(sum_hndlr) store.stream_write(layer_path, sr) # Read tar data from the tempfile csums = [] tar = None tarsum = checksums.TarSum(json_data) try: tmp.seek(0) tar = tarfile.open(mode='r|*', fileobj=tmp) tarfilesinfo = layers.TarFilesInfo() for member in tar: tarsum.append(member, tar) tarfilesinfo.append(member) layers.set_image_files_cache(image_id, tarfilesinfo.json()) except (IOError, tarfile.TarError) as e: logger.debug('put_image_layer: Error when reading Tar stream tarsum. ' 'Disabling TarSum, TarFilesInfo. Error: {0}'.format(e)) finally: if tar: tar.close() tmp.close() # All data have been consumed from the tempfile csums.append('sha256:{0}'.format(h.hexdigest())) csums.append(tarsum.compute()) try: checksum = store.get_content(store.image_checksum_path(image_id)) except IOError: # We don't have a checksum stored yet, that's fine skipping the check. # Not removing the mark though, image is not downloadable yet. flask.session['checksum'] = csums return toolkit.response() # We check if the checksums provided matches one the one we computed if checksum not in csums: logger.debug('put_image_layer: Wrong checksum') return toolkit.api_error('Checksum mismatch, ignoring the layer') # Checksum is ok, we remove the marker store.remove(mark_path) return toolkit.response()