Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

duffle build followed by duffle export should work #828

Open
itowlson opened this issue Aug 6, 2019 · 11 comments
Open

duffle build followed by duffle export should work #828

itowlson opened this issue Aug 6, 2019 · 11 comments
Milestone

Comments

@itowlson
Copy link
Contributor

itowlson commented Aug 6, 2019

If you do a duffle build followed by a (full-bundle) duffle export then you get a baffling error (per #824), the significance of which is "you need to push the invocation image first," even though you may already have the invocation image in your local Docker registry as a result of duffle build.

The reason that Duffle always attempts an image pull is so that it can work in environments where there is no local Docker daemon (thanks @glyn for the explanation). But this makes for a non-smooth build-then-export experience, not made easier by the cryptic error.

Some possible solutions:

  1. duffle build could always push the invocation image. @glyn has pointed out that this avoids problems where the user does a duffle build followed by duffle export -t (manifest only bundle). At the moment, the exported thin bundle will Work On My Machine TM, but fail when I give it to someone else because I haven't published the image. Downside is that maybe I don't want to put my invocation image up in public just yet; it also makes it harder to test locally, e.g. using Kind - these problems could be mitigated by a duffle build --push-image=false option.

  2. duffle export could check whether there is a local Docker daemon, and if so check that before resorting to a pull.

Or something else of course!

@itowlson
Copy link
Contributor Author

itowlson commented Aug 6, 2019

Another idea: duffle export -t could perform the push - this would address the 'exported thin bundle fails on consumers' machines' problem, and makes some kind of sense because export implies an intent to distribute/publish more than build does.

This would still require duffle export without the -t to check the local Docker daemon if there was one, as conceptually there's no need to push in the full bundle scenario - your images are included in the export and don't need to be placed in a separate registry.

@glyn
Copy link
Contributor

glyn commented Aug 7, 2019

... these problems could be mitigated by a duffle build --push-image=false option

Agreed, it's not always appropriate for duffle build to push the image.

duffle export could check whether there is a local Docker daemon, and if so check that before resorting to a pull.

That feels like a clean solution, but it's non-trivial. We would need to extend pivotal/image-relocation to support that (or, if that's not feasible, see if there is a different library for writing the OCI image layout).

Another idea: duffle export -t could perform the push

I think that behaviour would be rather surprising. Also, the user can issue duffle build -o to get a thin bundle without using duffle export -t and then we are back to the same issue - if they give that thin bundle to someone using a different docker daemon, the other person can fall foul of the missing invocation image.

@glyn
Copy link
Contributor

glyn commented Aug 7, 2019

duffle export could check whether there is a local Docker daemon, and if so check that before resorting to a pull.

That feels like a clean solution, but it's non-trivial. We would need to extend pivotal/image-relocation to support that (or, if that's not feasible, see if there is a different library for writing the OCI image layout).

Looking into this solution.

@glyn
Copy link
Contributor

glyn commented Aug 7, 2019

@itowlson Would you care to review vmware-archive/image-relocation#18?

@itowlson
Copy link
Contributor Author

itowlson commented Aug 7, 2019

@glyn I don't feel qualified to review it at a code level, but the approach looks good and I agree with your comment about error reporting. Thanks!

glyn added a commit to vmware-archive/image-relocation that referenced this issue Aug 12, 2019
See cnabio/duffle#828 (comment).

Bump the go-containerregistry dependency and use a corresponding version of
docker.

Handle an empty image name more gracefully (than panicking).
glyn added a commit to glyn/duffle that referenced this issue Aug 12, 2019
This is implemented by bumping pivotal/image-relocation to pick up the docker
daemon support.

Fixes cnabio#828
@jeremyrickard jeremyrickard added this to the Duffle 1.0 milestone Aug 12, 2019
@glyn
Copy link
Contributor

glyn commented Aug 14, 2019

It turns out that the option of exporting images from the docker daemon is unsound because the docker daemon makes no guarantee to create the same content digest for an image as the image's repository (which belongs to a specific registry with specific compression algorithms etc.). So we are back to the drawing board with this issue. The remaining options appear to be:

  • duffle build to provide an option, possibly even the default, to push the invocation image
  • do nothing and leave it up to the user to docker push the invocation image after duffle build
  • duffle export to push all images to ensure that some updates are not "stuck" in the daemon.

@radu-matei
Copy link
Member

I think a combination of 1 and 3:

  • add a flag to build to allow users to opt out of pushing by default
  • export to push all of them anyway.

@glyn
Copy link
Contributor

glyn commented Aug 14, 2019

Compare cnab-to-oci behaviour, which is analogous to export:

Note: cnab-to-oci does not push images from your docker daemon image store. Make sure all your invocation images are already present on a registry before pushing your bundle.

So I'm not sure about making export push all images. Suppose some images cannot be pushed because they are read-only for the current user - the push will fail. Also, I'm a little nervous about the time period between duffle build and duffle export - there is the opportunity for the docker daemon to be given a version of the image that duffle build didn't create, which seems like a security exposure.

@glyn
Copy link
Contributor

glyn commented Aug 14, 2019

Unassigning so someone else can take this. I won't be able to get round to it for some time.

@glyn glyn removed their assignment Aug 14, 2019
glyn added a commit to vmware-archive/image-relocation that referenced this issue Aug 16, 2019
@squarism
Copy link

Sorry to be naive here but why are layers coupled to a registry store? If I don't have a registry, I have an image (made up of layers which are SHA'd). Layers have to be transportable and cryptographically the same (otherwise, what's the point of docker?). Is there something else that is coupling an image that isn't even pushed to a registry?

Let's say I pull down hello-world and tag is without a registry prefix. Now I duffle up hello-world. Can't duffle just write the tars from the image I have? Easier said than done I know. 🌻

@glyn
Copy link
Contributor

glyn commented Jan 30, 2020

@squarism maybe a bit of background will help. Each image has two digests. The so-called repository digest depends on the compressed form of the image and compression can vary by registry. Then there is an image id which is a digest of the uncompressed form of the image and so is registry independent. If you include a digest in an image reference, it's a repository digest.

Some tools don't preserve the repo digest. For instance, if you docker pull/tag/push, the repo digest can change even though the uncompressed image stays the same. (Tools based on https://github.com/google/go-containerregistry, which is ultimately what duffle relocate uses, preserve the repo digest when copying images between registries.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants