From 124b8759d91b43acc642b5ee58128401ccd0cab9 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 10 Dec 2021 13:18:01 +0100 Subject: [PATCH] laod: support buildkit archives Archives generated with buildkit have some kind of "hybrid" layout which is the same for OCI and Docker archives. OCI ones ship with a manifest.json but set the image's reference in the index.json but in a custom annotation and not the one the OCI image spec wants. Archives in the Docker format set the reference in `RepoTags` of the manifest.json. To support these archives, simply look for the custom containerd annotation *and* change the order back to give OCI archives precedence. Fixes: containers/podman/issues/12560 Signed-off-by: Valentin Rothberg --- libimage/load.go | 22 +++++++++++----------- libimage/load_test.go | 2 ++ libimage/pull.go | 25 +++++++++++++++++++++---- libimage/testdata/buildkit-docker.tar | Bin 0 -> 7168 bytes libimage/testdata/buildkit-oci.tar | Bin 0 -> 7168 bytes 5 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 libimage/testdata/buildkit-docker.tar create mode 100644 libimage/testdata/buildkit-oci.tar diff --git a/libimage/load.go b/libimage/load.go index 74a1870e0f..1d53903662 100644 --- a/libimage/load.go +++ b/libimage/load.go @@ -35,17 +35,6 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) ( var loadErrors []error for _, f := range []func() ([]string, string, error){ - // DOCKER-ARCHIVE - must be first (see containers/podman/issues/10809) - func() ([]string, string, error) { - logrus.Debugf("-> Attempting to load %q as a Docker archive", path) - ref, err := dockerArchiveTransport.ParseReference(path) - if err != nil { - return nil, dockerArchiveTransport.Transport.Name(), err - } - images, err := r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions) - return images, dockerArchiveTransport.Transport.Name(), err - }, - // OCI func() ([]string, string, error) { logrus.Debugf("-> Attempting to load %q as an OCI directory", path) @@ -68,6 +57,17 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) ( return images, ociArchiveTransport.Transport.Name(), err }, + // DOCKER-ARCHIVE - must be first (see containers/podman/issues/10809) + func() ([]string, string, error) { + logrus.Debugf("-> Attempting to load %q as a Docker archive", path) + ref, err := dockerArchiveTransport.ParseReference(path) + if err != nil { + return nil, dockerArchiveTransport.Transport.Name(), err + } + images, err := r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions) + return images, dockerArchiveTransport.Transport.Name(), err + }, + // DIR func() ([]string, string, error) { logrus.Debugf("-> Attempting to load %q as a Docker dir", path) diff --git a/libimage/load_test.go b/libimage/load_test.go index 8464a36554..92842824a2 100644 --- a/libimage/load_test.go +++ b/libimage/load_test.go @@ -27,12 +27,14 @@ func TestLoad(t *testing.T) { {"testdata/docker-two-names.tar.xz", false, 1, []string{"localhost/pretty-empty:latest", "example.com/empty:latest"}}, {"testdata/docker-two-images.tar.xz", false, 2, []string{"example.com/empty:latest", "example.com/empty/but:different"}}, {"testdata/docker-unnamed.tar.xz", false, 1, []string{"sha256:ec9293436c2e66da44edb9efb8d41f6b13baf62283ebe846468bc992d76d7951"}}, + {"testdata/buildkit-docker.tar", false, 1, []string{"github.com/buildkit/archive:docker"}}, // OCI ARCHIVE {"testdata/oci-name-only.tar.gz", false, 1, []string{"localhost/pretty-empty:latest"}}, {"testdata/oci-non-docker-name.tar.gz", true, 0, nil}, {"testdata/oci-registry-name.tar.gz", false, 1, []string{"example.com/empty:latest"}}, {"testdata/oci-unnamed.tar.gz", false, 1, []string{"sha256:5c8aca8137ac47e84c69ae93ce650ce967917cc001ba7aad5494073fac75b8b6"}}, + {"testdata/buildkit-oci.tar", false, 1, []string{"github.com/buildkit/archive:oci"}}, } { loadedImages, err := runtime.Load(ctx, test.input, loadOptions) if test.expectError { diff --git a/libimage/pull.go b/libimage/pull.go index 59221d935c..e6bb084785 100644 --- a/libimage/pull.go +++ b/libimage/pull.go @@ -21,6 +21,7 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage" digest "github.com/opencontainers/go-digest" + ociSpec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -169,6 +170,20 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP return localImages, pullError } +// nameFromAnnotations returns a reference string to be used as an image name, +// or an empty string. The annotations map may be nil. +func nameFromAnnotations(annotations map[string]string) string { + if annotations == nil { + return "" + } + // buildkit/containerd are using a custom annotation see + // containers/podman/issues/12560. + if annotations["io.containerd.image.name"] != "" { + return annotations["io.containerd.image.name"] + } + return annotations[ociSpec.AnnotationRefName] +} + // copyFromDefault is the default copier for a number of transports. Other // transports require some specific dancing, sometimes Yoga. func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, options *CopyOptions) ([]string, error) { @@ -201,15 +216,17 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, if err != nil { return nil, err } - // if index.json has no reference name, compute the image ID instead - if manifestDescriptor.Annotations == nil || manifestDescriptor.Annotations["org.opencontainers.image.ref.name"] == "" { + storageName = nameFromAnnotations(manifestDescriptor.Annotations) + logrus.Errorf("STORAGE NAME: %q", storageName) + switch len(storageName) { + case 0: + // If there's no reference name in the annotations, compute an ID. storageName, err = getImageID(ctx, ref, nil) if err != nil { return nil, err } imageName = "sha256:" + storageName[1:] - } else { - storageName = manifestDescriptor.Annotations["org.opencontainers.image.ref.name"] + default: named, err := NormalizeName(storageName) if err != nil { return nil, err diff --git a/libimage/testdata/buildkit-docker.tar b/libimage/testdata/buildkit-docker.tar new file mode 100644 index 0000000000000000000000000000000000000000..3b95183f55b269e0c71481f1c8181260791e6cbb GIT binary patch literal 7168 zcmeHKON-ku5YBmjh0(QHN0MK$p@+VpheAsUEp%CmY{`kbjuiX|-G==4j_kynEF|4F z@v>~Ki#?JxGn&!&%{b0t4h$pkyn%Vbxc}UpYu*WVus^W8PQBVFuZoi8;L@qK zjOQ@g!=0+{k@m-R{)-u-p5N6qFmd_2{1b=t`G1rfu$TXUa6yPWcAOw}IT^cNEHDwV zo3NC4JQxdC#KdES#i0)v9pi9JeLoyCFAjur2ty|SuIskYFfxp-j2*Y-hGw1;KY;un z(s$Ot{O9;zA(kgIS&F2ra)Bbm=G=GD5G7ira*CoAdZ(5sxA$gOy{P){`?yrSzN`l|CAsitpb4yHz6=A(LD$&8~&Rav$Mv$&x{VqAI)mqnQy)e&9*&hDmBnY_> zVM5)I_zn*^_dMbFVIa~Fa~uSeQk-(;U_nzSOcX-tG#6a5NsS^4vBe^j2`i;mqov|D*U62@Z4OY(Wn7tgd(M8iZXXlL}1BIhzW5Np?&bC0tIy z1u%n}{v|rKel@2sstfrG7{#JAH0N43$Jp>oWEobucpj`G6&F8klftuJt371~|NfEs z@7>2gA(Xg1{`Z2|k+4GdFiVGM3vQ^NSF2ra_(y7Jfx5-%sdWZQd;?I2ctgaL(q&Co zbu%Ef-7*K?P={i3(;!S`Ijdq=o{wVFb==5uRJT7%5j89ansq+4^+KptNwHDVwkC*T zN-hb#BzQt-L`dX$-;V9fMQU$c*qB+bub&2gY;)Zu1^fyB)M@_>%%=lPNPxW_{~bYo zPb~oa&8E{wd%fW4wG@383q4^|Ln9A?9{e7BXgc_&ZNJ`gv==&wfKKEk^fkIFJ5gUN zHK0D$|6|AB@BdBxr#=3=%gCMP6{?$S03KX{wsA+q#x_PzqeR^~+rRY@=p)cappU@W GBJdkB=nORg literal 0 HcmV?d00001 diff --git a/libimage/testdata/buildkit-oci.tar b/libimage/testdata/buildkit-oci.tar new file mode 100644 index 0000000000000000000000000000000000000000..8f7455078ec6a51f743a33a0f9a3a52e5c59bb63 GIT binary patch literal 7168 zcmeHKTWi}e6z+3>h0*I$$C7-B4SU!P_AuBOVS|-2WJ^x8I#RHm&@SY^@5pw%IFO7k zNmn|HKzt<5#pmez&T*XSxENlXbvdvC&$}@Huy+5q_v&ZtP{+Tpyt78t7+(}6%ORv= zeVNE%wJ&$9y+_iItNIsHMm+yq*TCfEVfDup_w|328_=nLfVsff9Z?#jF2^I+i-m(l z>?SP59uG#s6*2Z0W^w2PMn_IKBEBDvm=_0v?!%C&zw5d!G>i;uBRkY>xuM=C*bkuo z`|O=GG5oaJa%~CQko`&hHmV09@B*5fVq@0ng*B&k1#i2G^8HelNtl+L-=<++Hyg~ z3xrTYd;IT7=SjC$mzHIrnc$L*D->CX&F7g+SShs{E)}BC zD6~R@O1ns=V#dAz_CN(i7OA&43}RJ29^j@{>^d>(Tu#6_I6(Eh5*^#G>iCW6LjD8> zu?Pvx8?EaXX!s+KhXcZUHoHAFzNB%N#dD=71}{B z8K4c!p?_Ylwz=U!)X>7UMeC8>1sZz|Qxb*)#FWxyMN-uWAhiv&Q8KAS&KtT?Y-YxS zi7cm!7>;Md*vuNYvK&@J&r(FdZD3aC6I;)PYAqCvg?1W2#3A?!lPm0uF^S;kjJ_Sx z%tdN9{*90I`sQi!$EMcjq<}x+9|xq{|1l2C_kTbCp9%C^W&z-Dnn@pZXTc-C1pyqN z#axfsq#45p=tDi9*F*WuRuKK;Kg$4+(-q7)dQqM)1cU!W^S?v=UHtd`|9s`>SYDxO kv*Lo%nm9&p@AnJ_CIQ{w@Q*0CD~D@&Et; literal 0 HcmV?d00001