From 6c3bce80c8347bd52b54d0faec20b9eb65d22330 Mon Sep 17 00:00:00 2001 From: Aditya Rajan Date: Wed, 1 Sep 2021 12:44:58 +0530 Subject: [PATCH] remove-image: Add optional LookupManifest to RemoveImagesOptions. Following flag allows user to configure RemoveImages in a manner so that remove func becomes exclusive to removing manifests when needed and not removing underlying referenced images. Signed-off-by: Aditya Rajan --- libimage/.manifest_list.go.swp | Bin 0 -> 16384 bytes libimage/manifest_list_test.go | 49 +++++++++++++++++++++++++++++++++ libimage/runtime.go | 16 ++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 libimage/.manifest_list.go.swp diff --git a/libimage/.manifest_list.go.swp b/libimage/.manifest_list.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..6adfad071c1221c9001b0297a95d7db68bdab354 GIT binary patch literal 16384 zcmeHNU5I2y6|R_7(@AzByN~)%+lia*NqakPh{l$ASZ4-o-T856vI-h@Yi?I}-^}e> zH+64MPiNRf4CDu4)krXcPl2dGL_tstJ_$ilL^NPF`YZ(eNid-J;Lmre>fXLR(=!%rF43rEU zmw}V)o^$WNo1|~Ap5doY-GAJQrCiBC$w0|K$w0|K$w0|K$w0|K$-w^r18IDMJ&JL> z&5h+@_kF{@?|->Z>YnfIEB~h}CtdV;-F~r5&yDW)9qv1F1zEX!Tz-`dlnj&%lnj&% zlnj&%lnj&%lnj&%lnj&%lnneA7!V!CZh_w0C;@=`|Lpw#`fZH;8TdW$Ti|8j=fKZ^ zuK-4*`EcM_vG) z1}*{j180EKz$xI3n;H8Z@G5W}_%`q)kN^(>G4NjCJ;1Lj&;>jTJPtetd=BUWf4_;b z*MQ#uF9W{@z79MCJO+FgcoYbM2Y~>1H*f;@;X4_73fKj@fDd>;1Go!#0IzJY)4(5K%h!NcftP?E11|ud2c86;06q$k&F6r^r=rDZ#l3{l;MwaK zo8wqExYU}r7Wlw3?`n9NSj|s&>#Wjj@>MnBp;Fsiq&)3QKA+W}=OXIxM26B&xq#Z# z?*~zj2T_uW$d?}c;VP?Cl5yf)5;_o3y4Y8NFZlxBvA>2SJ~q-(mH#;A~u zVaD8MTy>3+GaGYyWoKeq*q<@jR7)5u;%AFA>=_4Y@t|QUwankE4ITxdwWh0t-)4x$ zBIJEAIi8Wtsj=K61Ft93Vgot<0k=%m`KFo{0Efi~(^P^G@?Xg}mEYfGLj9@^I7$i)Dp@VZu`o5(p1E0U>yq4~{d51I22ESTH>& z_$WyG#`!0Kh>VMXK~IY=KCr~X?Ofb1x)Me{W4^m8IW05BO1!t1>c>`T<#V^BpWcSp zk(;V*JX3qb1e~*4ZSYS&U}NuIgt#ig;9=SEHcT|G)e*TepYfKIzb*Bpb2P#g*$D(K zop5N&z;MHtsyjFKkOiBkuS7V%fA`kOhq=98|)6 zGlB#WE|Md=c;rNwSU1BZrrf}7B-%@PygsmAQkk2gc9m-{aqBHM(BkK;bqE^@gb+h| zW*R%4%|3+|#bMNuIvmq3B$IHV9o|RwcPq!N3bx$(^~{-LDz#IrwSsR2SQX(%oZfon zqrSv+7{}D^)-W{;DSV5;R?r&;wEWUeDr=!5cX@4Xv0b;1^PXbNSc;YI1d-5VC%$%( zPp>!gM8G_+S*NT+9s)+cS@vz4YM6v$E_|&LOR4mg-OynB(54lA492^X>YC|Y``E_X zs@w3bZ7w4)(^iihex4`8Za3Jag)P8l2)iQ{Ve28R;#BGZuV!PYLW+S2$yeN*AQfcm zAvTF-M?;G3=H-y^G*wf}Sjz;B66;wj)(?ve&=$tnH-HB?cF|kLu+ikpTCb|~{FL4W zyILpSsvOm-t}g8f>{hn0wpZ&EGY|IFSQ>6%b`l3_5j|QyG{kGq2r8suRxi-oz(>F! zDzUxJM=?U}u7WqaIBN-Gq~^+j*Q%2%WEV9lxnkN|&CMvbz`yX#GHmwj=hxc_?@PF^ zAnt zOGg7lyoMvP@V6K{QnP} zm+9P1=l?t0VeqFo*Z%C1Q0P5Q}f$~!_P%=<5P%=<5P%=<5 zP%=<5@PEU=B$wVXDH>KmO4a^r? zvYFTXPG_aPvP|X3w^lC7f!dK9K`#uX+S1nEdm34{%E$%MQ^EAM3cK$+=g@zTci0B5g2BJWo$GP0Bi z%zEj%kzIr3mp~?2$SMWKrxSi;8fOZ;JYDISoQiAF4^=|Bz+!5i(vCPj&q#*aN_iG= ze@~E&TQmcyoy{1<@3Cv!W^R1dk-RgELz7f6Cw!Y?GUsP+qsV}VTO_0|kX_j^*_9zO z4q6R(U+hpC3#kZm%7=i8q)9K?gu+PPiJZYOAt9T}=>NvephiU=w8J(KrS`gDJHEzHH literal 0 HcmV?d00001 diff --git a/libimage/manifest_list_test.go b/libimage/manifest_list_test.go index 68779bf6a..d839237db 100644 --- a/libimage/manifest_list_test.go +++ b/libimage/manifest_list_test.go @@ -75,3 +75,52 @@ func TestCreateAndTagManifestList(t *testing.T) { // Both origin list and newly tagged list should point to same image id require.Equal(t, image.ID(), taggedImage.ID()) } + +// Following test ensure that we test Removing a manifestList +// Test tags two manifestlist and deletes one of them and +// confirms if other one is not deleted. +func TestCreateAndRemoveManifestList(t *testing.T) { + + tagName := "manifestlisttagged" + listName := "manifestlist" + runtime, cleanup := testNewRuntime(t) + defer cleanup() + ctx := context.Background() + + list, err := runtime.CreateManifestList(listName) + require.NoError(t, err) + require.NotNil(t, list) + + manifestListOpts := &ManifestListAddOptions{All: true} + _, err = list.Add(ctx, "docker://busybox", manifestListOpts) + require.NoError(t, err) + + list, err = runtime.LookupManifestList(listName) + require.NoError(t, err) + require.NotNil(t, list) + + lookupOptions := &LookupImageOptions{ManifestList: true} + image, _, err := runtime.LookupImage(listName, lookupOptions) + require.NoError(t, err) + require.NotNil(t, image) + err = image.Tag(tagName) + require.NoError(t, err, "tag should have succeeded: %s", tagName) + + taggedImage, _, err := runtime.LookupImage(tagName, lookupOptions) + require.NoError(t, err) + require.NotNil(t, taggedImage) + // Both origin list and newly tagged list should point to same image id + require.Equal(t, image.ID(), taggedImage.ID()) + + // Try deleting the manifestList with tag + rmReports, rmErrors := runtime.RemoveImages(ctx, []string{"manifestlisttagged"}, &RemoveImagesOptions{Force: true, LookupManifest: true}) + require.Nil(t, rmErrors) + require.Equal(t, []string{"localhost/manifestlisttagged:latest"}, rmReports[0].Untagged) + + // Original tag should still exists + imageRe, _, err := runtime.LookupImage(listName, lookupOptions) + require.NoError(t, err) + require.NotNil(t, imageRe) + require.Equal(t, image.ID(), imageRe.ID()) + +} diff --git a/libimage/runtime.go b/libimage/runtime.go index 7d3fbf3f2..42461014d 100644 --- a/libimage/runtime.go +++ b/libimage/runtime.go @@ -541,6 +541,11 @@ type RemoveImagesOptions struct { // using a removed image. Use RemoveContainerFunc for a custom logic. // If set, all child images will be removed as well. Force bool + // LookupManifest will expect all specified names to be manifest lists (no instance look up). + // This allows for removing manifest lists. + // By default, RemoveImages will attempt to resolve to a manifest instance matching + // the local platform (i.e., os, architecture, variant). + LookupManifest bool // RemoveContainerFunc allows for a custom logic for removing // containers using a specific image. By default, all containers in // the local containers storage will be removed (if Force is set). @@ -600,13 +605,22 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem toDelete := []string{} // Look up images in the local containers storage and fill out // toDelete and the deleteMap. + switch { case len(names) > 0: + // prepare lookupOptions + var lookupOptions *LookupImageOptions + if options.LookupManifest { + // LookupManifest configured as true make sure we only remove manifests and no referenced images. + lookupOptions = &LookupImageOptions{lookupManifest: true} + } else { + lookupOptions = &LookupImageOptions{returnManifestIfNoInstance: true} + } // Look up the images one-by-one. That allows for removing // images that have been looked up successfully while reporting // lookup errors at the end. for _, name := range names { - img, resolvedName, err := r.LookupImage(name, &LookupImageOptions{returnManifestIfNoInstance: true}) + img, resolvedName, err := r.LookupImage(name, lookupOptions) if err != nil { appendError(err) continue