cnabio / cnab-to-oci

Tool to convert CNAB bundle.json to OCI index
Apache License 2.0
54 stars 41 forks source link

Store the whole Bundle.json and generate a Relocation map #58

Closed silvin-lubecki closed 5 years ago

silvin-lubecki commented 5 years ago

Context

During CNAB discussions about storing bundles into registry, some comments were raised about cnab-to-oci not storing the whole bundle.json in the registry but only a subset, reconstructing it during a pull.

Discussion around storing the complete bundle.json file (and duplicate the information about the reference images) vs. reconstructing it based on a configuration file (parameters, credentials, metadata - all other fields in bundle.json) and the referenced images. Whatever path we choose, the proposed changes to the OCI specification should allow both options. Same goes for signing - whether we choose to sign the complete bundle.json that is stored in the registry, or we sign the manifest generated by the registry, the proposed changes to the specification and the current CNAB security spec should allow for for both approaches.

Current behavior

When pushing a CNAB Bundle to a registry, cnab-to-oci produces the following:

During the pull, we can reconstruct the bundle.json from the config object, the annotations and the images:

{
        "schemaVersion": "v1.0.0-WD",
        "name": "hello-world",
        "version": "0.1.0",
        "description": "Hello, World!",
        "maintainers": [
                {
                        "name": "user",
                        "email": "user@email.com"
                }
        ],
        "invocationImages": [
                {
                        "imageType": "docker",
                        "image": "slubecki/test1@sha256:720d8fa437af27e98a76ade5395b92c32a8e39721c62a6b4d8c3e4e1967d0caa",
                        "size": 1363,
                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json"
                }
        ],
        "images": {
                "hello": {
                        "imageType": "docker",
                        "image": "slubecki/test1@sha256:ba27d460cd1f22a1a4331bdf74f4fccbc025552357e8a3249c40ae216275de96",
                        "size": 528,
                        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
                        "description": ""
                }
        },
        "actions": {
                "com.docker.app.inspect": {
                        "stateless": true
                },
                "com.docker.app.render": {
                        "stateless": true
                },
                "io.cnab.status": {}
        },
        "parameters": {
                "fields": {
                        "port": {
                                "definition": "port",
                                "destination": {
                                        "env": "docker_param1"
                                }
                        },
                        "text": {
                                "definition": "text",
                                "destination": {
                                        "env": "docker_param2"
                                }
                        }
                }
        },
        "credentials": {
                "docker.context": {
                        "path": "/cnab/app/context.dockercontext"
                }
        },
        "definitions": {
                "port": {
                        "default": "8080",
                        "type": "string"
                },
                "text": {
                        "default": "Hello, World!",
                        "type": "string"
                }
        }
}

This reconstruction was designed to tackle 2 things:

Proposal

Since this design was implemented, the Image Relocation has been added to the CNAB specifications.

We propose to leverage this new feature in the Bundle Runtime so:

Ex of Relocation map:

{
 "hashicorp/http-echo": "slubecki/test1@sha256:ba27d460cd1f22a1a4331bdf74f4fccbc025552357e8a3249c40ae216275de96"
}

This new design does not avoid annotation/metadata replication, but we think it is a minor issue, regarding the concern of storing a subset of the bundle.json.

silvin-lubecki commented 5 years ago

cc @jcsirot @radu-matei @glyn @caervs @chris-crone WDYT?

caervs commented 5 years ago

@silvin-lubecki neat! To be clear, the annotations that we have today would continue to exist, correct?

Maybe this is a separate conversation for us @chris-crone and @simonferquel (and maybe I need to re-read the spec), but I'd like to better understand the motivation for referencing images in external repos in the bundle.json in the first place. IMHO this is akin to referencing external resources in a website's HTML and something we could avoid by always mounting blobs into the target repo for a CNAB and referencing them in the bundle.json just by digest.

silvin-lubecki commented 5 years ago

To be clear, the annotations that we have today would continue to exist, correct?

@caervs absolutely, we don't change that part at all. The pushed OCI index is still the same with this proposal, only the config object changes.

glyn commented 5 years ago

I've been thinking about this and I'm not sure how the original image name would be obtained when pulling from or relocating from a bundle stored in a repository unless it is captured when pushing the bundle to the repository (and stored in the repository).

This issue crops up in the example above: where did "hashicorp/http-echo" come from in the relocation map?

silvin-lubecki commented 5 years ago

@glyn I think we have everything we need in the OCI index, we have an annotation with the component name, so we can link it to the original component in the bundle.json and get back the original image name to produce the relocation map.

Does that make sense? Am I missing something?

glyn commented 5 years ago

@silvin-lubecki Thanks. I understand now. I incorrectly assumed you were treating the original bundle.json as completely opaque, but of course you can get the original image names from it.

radu-matei commented 5 years ago

@caervs - the usage of annotations is still required, since an OCI index does not currently support a config object (where a concrete mediaType would be passed) - there have been proposals to add this to the OCI specification, but following that entire discussion is... let's say consuming.

As to the second part of your question, it has to do the following workflow:

Constructing an image map that is used by runtimes (with the restriction that all images referenced in the image map must have the same digest with the original images) allows us to move bundles across registries (OCI compliant registries, that generate the same image digest for the same image) without invalidating the trust data generated when first building the bundle.

Does that make sense?

@silvin-lubecki, @glyn, @chris-crone - LGTM, I'm happy to pair sometime this / next week and go through the requirements and workflows one more time.

silvin-lubecki commented 5 years ago

@radu-matei happy to pair with you on this, let's schedule that on slack 👍