示例#1
0
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)

    # read layer files and cache them
    try:
        files_json = json.dumps(layers.get_image_files_from_fobj(tmp))
        layers.set_image_files_cache(image_id, files_json)
    except Exception as e:
        logger.debug('put_image_layer: Error when caching layer file-tree:'
                     '{0}'.format(e))

    csums.append('sha256:{0}'.format(h.hexdigest()))
    try:
        tmp.seek(0)
        csums.append(checksums.compute_tarsum(tmp, json_data))
    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')

    tmp.close()

    # Checksum is ok, we remove the marker
    store.remove(mark_path)
    return toolkit.response()
 def test_layer_cache(self):
     layer_id = rndstr(16)
     layers.set_image_files_cache(layer_id, "{}")
     fetched_json = layers.get_image_files_cache(layer_id)
     self.assertTrue(fetched_json == "{}")
 def test_get_image_files_json_cached(self):
     layer_id = rndstr(16)
     layers.set_image_files_cache(layer_id, "{}")
     files_json = layers.get_image_files_json(layer_id)
     self.assertTrue(files_json, "{}")
示例#4
0
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()
示例#5
0
 def test_layer_cache(self):
     layer_id = rndstr(16)
     layers.set_image_files_cache(layer_id, "{}")
     fetched_json = layers.get_image_files_cache(layer_id)
     self.assertTrue(fetched_json == "{}")
示例#6
0
 def test_get_image_files_json_cached(self):
     layer_id = rndstr(16)
     layers.set_image_files_cache(layer_id, "{}")
     files_json = layers.get_image_files_json(layer_id)
     self.assertTrue(files_json, "{}")
示例#7
0
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()