Exemple #1
0
def test_derived_image(registry_model):
    # Clear all existing derived storage.
    DerivedStorageForImage.delete().execute()

    repository_ref = registry_model.lookup_repository('devtable', 'simple')
    tag = registry_model.get_repo_tag(repository_ref, 'latest')
    manifest = registry_model.get_manifest_for_tag(tag)

    # Ensure the squashed image doesn't exist.
    assert registry_model.lookup_derived_image(manifest, 'squash', storage,
                                               {}) is None

    # Create a new one.
    squashed = registry_model.lookup_or_create_derived_image(
        manifest, 'squash', 'local_us', storage, {})
    assert registry_model.lookup_or_create_derived_image(
        manifest, 'squash', 'local_us', storage, {}) == squashed
    assert squashed.unique_id

    # Check and set the size.
    assert squashed.blob.compressed_size is None
    registry_model.set_derived_image_size(squashed, 1234)

    found = registry_model.lookup_derived_image(manifest, 'squash', storage,
                                                {})
    assert found.blob.compressed_size == 1234
    assert found.unique_id == squashed.unique_id

    # Ensure its returned now.
    assert found == squashed

    # Ensure different metadata results in a different derived image.
    found = registry_model.lookup_derived_image(manifest, 'squash', storage,
                                                {'foo': 'bar'})
    assert found is None

    squashed_foo = registry_model.lookup_or_create_derived_image(
        manifest, 'squash', 'local_us', storage, {'foo': 'bar'})
    assert squashed_foo != squashed

    found = registry_model.lookup_derived_image(manifest, 'squash', storage,
                                                {'foo': 'bar'})
    assert found == squashed_foo

    assert squashed.unique_id != squashed_foo.unique_id

    # Lookup with placements.
    squashed = registry_model.lookup_or_create_derived_image(
        manifest, 'squash', 'local_us', storage, {}, include_placements=True)
    assert squashed.blob.placements

    # Delete the derived image.
    registry_model.delete_derived_image(squashed)
    assert registry_model.lookup_derived_image(manifest, 'squash', storage,
                                               {}) is None
Exemple #2
0
def _garbage_collect_legacy_image(legacy_image_id, context):
    assert legacy_image_id is not None

    # Check if the image is referenced.
    if _check_image_used(legacy_image_id):
        return False

    # We have an unreferenced image. We can now delete it.
    # Grab any derived storage for the image.
    for derived in DerivedStorageForImage.select().where(
            DerivedStorageForImage.source_image == legacy_image_id):
        context.add_blob_id(derived.derivative_id)

    try:
        image = Image.select().where(Image.id == legacy_image_id).get()
    except Image.DoesNotExist:
        return False

    assert image.repository_id == context.repository.id

    # Add the image's blob to be GCed.
    context.add_blob_id(image.storage_id)

    # If the image has a parent ID, add the parent for GC.
    if image.parent_id is not None:
        context.add_legacy_image_id(image.parent_id)

    # Delete the image.
    with db_transaction():
        if _check_image_used(legacy_image_id):
            return False

        try:
            image = Image.select().where(Image.id == legacy_image_id).get()
        except Image.DoesNotExist:
            return False

        assert image.id == legacy_image_id
        assert image.repository_id == context.repository.id

        # Delete any derived storage for the image.
        deleted_derived_storage = (DerivedStorageForImage.delete().where(
            DerivedStorageForImage.source_image == legacy_image_id).execute())

        # Delete the image itself.
        image.delete_instance()

    context.mark_legacy_image_removed(image)

    gc_table_rows_deleted.labels(table="Image").inc()
    gc_table_rows_deleted.labels(
        table="DerivedStorageForImage").inc(deleted_derived_storage)

    if config.image_cleanup_callbacks:
        for callback in config.image_cleanup_callbacks:
            callback([image])

    return True
Exemple #3
0
def test_derived_image_for_manifest_list(oci_model):
    # Clear all existing derived storage.
    DerivedStorageForImage.delete().execute()

    # Create a config blob for testing.
    config_json = json.dumps({
        'config': {},
        "rootfs": {
            "type": "layers",
            "diff_ids": []
        },
        "history": [
            {
                "created": "2018-04-03T18:37:09.284840891Z",
                "created_by": "do something",
            },
        ],
    })

    app_config = {'TESTING': True}
    repository_ref = oci_model.lookup_repository('devtable', 'simple')
    with upload_blob(repository_ref, storage,
                     BlobUploadSettings(500, 500, 500)) as upload:
        upload.upload_chunk(app_config, BytesIO(config_json))
        blob = upload.commit_to_blob(app_config)

    # Create the manifest in the repo.
    builder = DockerSchema2ManifestBuilder()
    builder.set_config_digest(blob.digest, blob.compressed_size)
    builder.add_layer(blob.digest, blob.compressed_size)
    amd64_manifest = builder.build()

    oci_model.create_manifest_and_retarget_tag(repository_ref, amd64_manifest,
                                               'submanifest', storage)

    # Create a manifest list, pointing to at least one amd64+linux manifest.
    builder = DockerSchema2ManifestListBuilder()
    builder.add_manifest(amd64_manifest, 'amd64', 'linux')
    manifestlist = builder.build()

    oci_model.create_manifest_and_retarget_tag(repository_ref, manifestlist,
                                               'listtag', storage)
    manifest = oci_model.get_manifest_for_tag(
        oci_model.get_repo_tag(repository_ref, 'listtag'))
    assert manifest
    assert manifest.get_parsed_manifest().is_manifest_list

    # Ensure the squashed image doesn't exist.
    assert oci_model.lookup_derived_image(manifest, 'squash', storage,
                                          {}) is None

    # Create a new one.
    squashed = oci_model.lookup_or_create_derived_image(
        manifest, 'squash', 'local_us', storage, {})
    assert squashed.unique_id
    assert oci_model.lookup_or_create_derived_image(manifest, 'squash',
                                                    'local_us', storage,
                                                    {}) == squashed

    # Perform lookup.
    assert oci_model.lookup_derived_image(manifest, 'squash', storage,
                                          {}) == squashed
Exemple #4
0
 def clear_derived_cache():
     DerivedStorageForImage.delete().execute()
     return "OK"
Exemple #5
0
def test_derived_image_for_manifest_list(manifest_builder, list_builder,
                                         oci_model):
    # Clear all existing derived storage.
    DerivedStorageForImage.delete().execute()

    # Create a config blob for testing.
    config_json = json.dumps({
        "config": {},
        "architecture":
        "amd64",
        "os":
        "linux",
        "rootfs": {
            "type": "layers",
            "diff_ids": []
        },
        "history": [
            {
                "created": "2018-04-03T18:37:09.284840891Z",
                "created_by": "do something",
            },
        ],
    })

    app_config = {"TESTING": True}
    repository_ref = oci_model.lookup_repository("devtable", "simple")
    with upload_blob(repository_ref, storage,
                     BlobUploadSettings(500, 500)) as upload:
        upload.upload_chunk(app_config, BytesIO(config_json))
        blob = upload.commit_to_blob(app_config)

    # Create the manifest in the repo.
    builder = manifest_builder()
    builder.set_config_digest(blob.digest, blob.compressed_size)
    builder.add_layer(blob.digest, blob.compressed_size)
    amd64_manifest = builder.build()

    oci_model.create_manifest_and_retarget_tag(repository_ref,
                                               amd64_manifest,
                                               "submanifest",
                                               storage,
                                               raise_on_error=True)

    # Create a manifest list, pointing to at least one amd64+linux manifest.
    builder = list_builder()
    builder.add_manifest(amd64_manifest, "amd64", "linux")
    manifestlist = builder.build()

    oci_model.create_manifest_and_retarget_tag(repository_ref,
                                               manifestlist,
                                               "listtag",
                                               storage,
                                               raise_on_error=True)

    manifest = oci_model.get_manifest_for_tag(
        oci_model.get_repo_tag(repository_ref, "listtag"))
    assert manifest
    assert manifest.get_parsed_manifest().is_manifest_list

    # Ensure the squashed image doesn't exist.
    assert oci_model.lookup_derived_image(manifest, "squash", storage,
                                          {}) is None

    # Create a new one.
    squashed = oci_model.lookup_or_create_derived_image(
        manifest, "squash", "local_us", storage, {})
    assert squashed.unique_id
    assert (oci_model.lookup_or_create_derived_image(manifest, "squash",
                                                     "local_us", storage,
                                                     {}) == squashed)

    # Perform lookup.
    assert oci_model.lookup_derived_image(manifest, "squash", storage,
                                          {}) == squashed