From daa5add33ae7808d71ffcd7f76c7bd636875c71b Mon Sep 17 00:00:00 2001 From: yongxiu Date: Wed, 21 Apr 2021 08:42:12 -0700 Subject: [PATCH] Add support for symbol link inside docker tar file (#987) * Add support for symbol link inside docker tar file * docker tar file containing multiple images will have symbol link for layer files to save space, this will read from the target file instead of the symbol link file * Add unit test for symbol link inside tar file * Fix format --- pkg/v1/tarball/image.go | 6 +++++ pkg/v1/tarball/image_test.go | 32 ++++++++++++++++++++++++++ pkg/v1/tarball/testdata/test_link.tar | Bin 0 -> 29696 bytes 3 files changed, 38 insertions(+) create mode 100644 pkg/v1/tarball/testdata/test_link.tar diff --git a/pkg/v1/tarball/image.go b/pkg/v1/tarball/image.go index 2ffa7a6ac..980842d23 100644 --- a/pkg/v1/tarball/image.go +++ b/pkg/v1/tarball/image.go @@ -23,6 +23,8 @@ import ( "io" "io/ioutil" "os" + "path" + "path/filepath" "sync" "github.com/google/go-containerregistry/internal/gzip" @@ -216,6 +218,10 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) { return nil, err } if hdr.Name == filePath { + if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink { + currentDir := filepath.Dir(filePath) + return extractFileFromTar(opener, path.Join(currentDir, hdr.Linkname)) + } close = false return tarFile{ Reader: tf, diff --git a/pkg/v1/tarball/image_test.go b/pkg/v1/tarball/image_test.go index a600a7d61..e76ac5d9f 100644 --- a/pkg/v1/tarball/image_test.go +++ b/pkg/v1/tarball/image_test.go @@ -15,9 +15,11 @@ package tarball import ( + "io/ioutil" "testing" "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/validate" ) @@ -95,3 +97,33 @@ func TestBundleMultiple(t *testing.T) { }) } } + +func TestLayerLink(t *testing.T) { + tag, err := name.NewTag("bazel/v1/tarball:test_image_3", name.WeakValidation) + if err != nil { + t.Fatalf("Error creating tag: %v", err) + } + img, err := ImageFromPath("testdata/test_link.tar", &tag) + if err != nil { + t.Fatalf("Error loading image: %v", img) + } + hash := v1.Hash{ + Algorithm: "sha256", + Hex: "8897395fd26dc44ad0e2a834335b33198cb41ac4d98dfddf58eced3853fa7b17", + } + layer, err := img.LayerByDiffID(hash) + if err != nil { + t.Fatalf("Error getting layer by diff ID: %v, %v", hash, err) + } + rc, err := layer.Uncompressed() + if err != nil { + t.Fatal(err) + } + bs, err := ioutil.ReadAll(rc) + if err != nil { + t.Fatal(err) + } + if len(bs) == 0 { + t.Errorf("layer.Uncompressed() returned a link file") + } +} diff --git a/pkg/v1/tarball/testdata/test_link.tar b/pkg/v1/tarball/testdata/test_link.tar new file mode 100644 index 0000000000000000000000000000000000000000..e83064fed7467a4fee54b7f5aae3cfc25b704bc3 GIT binary patch literal 29696 zcmeHQTW{Mo6!!Ceg`mA`fMfF}QZlfI-hdVumZHr%U_lU2yd+u`DUju2S&;v}!`QN8 zCykRzc9WVy(U=l-M1F^)&N(DMQERY}f)kl?sbisyh*ca@!VTtJq||U3Cxl64(u7FL zBuTAF8L}*i3Dd*g`U4?`L=^SV^jQ7t&h{`vR0zZ=Aw5J8p|lr7>qWQEF&Wpgf+Dq* zv|72g^0st8ZL9xJZ$5l{xBtg|#YGq)&e*Enn=~LtSM-mGz`dZgPVOsIb8W}p zxk20iePRf-?*IRc%VJHP*7ScuC|~XWFaY@ezXsM$E?cl%fc+#OOp}p%F1yMv;k;=24R9)GB3!WtOFg z5JMFgU`WQ1h!e#GGEmk}Wj;AG<8V|=^1L7ZRaT#~;^cKUQ_Y*At}f2Y%(bX#j{V~0 zB+H@N)8y~akn-8>SN%|z>NB)~FQyu2C1?{G&H$qUfhX-;yO;v>r`r5UkAO$OBj6GE zfe~oy$qm}ae^7)W=D#=~{tp4;$iM%$(d;h6Wj8En{4n@2sZUFA$Aj>t{LkcJKbX7H z!R3`pHBp)%#EC$A2qHBQra`0Ye-NAr!qaSAmlecGfOlC(0;| zQc7_WtCV3E4M}2cwYE`gl+iSfAYdg@EFc~dg!RQaIIZwd=l+bttE*>fLvbSn6Pz=u zD2}2OySNY%T1S$pn8b0aQwZrGg(+5qkW@%&iGX=Rg$?1ntNFi0_Xj@#3qhg(`}x1k zj{vRp-_iWvlKu&T2H?m4&1=8c^Yee(K>6uDqjmppZ~wuY1+UnDh{G}vAOG1xvzg8R zwQUA&nx!%2zG4hMx0$->EXwsn+wz1;_mfwRVcZznb36MKp|PNC$8SIX zL$2q4mhC_AMEv-_A&oDK9X!N=TfXJdDW}_Y>pz$Dj|4@a|LysILGb8Gt==%JKx4?P zUVf_S!7#mV>b8?&J7}VN*ZPtrn&P%218qx8%E*L z{U5^ruq1qo{@?EQf6%_~{~K=qUc5)ZBj6G62zUfM0v-X6fJeY1;1Tc$cmzBG9s!Sl zN5CWC5%36j1Uv#B0gr%3z$4%h@CbMWHjO}AvZjYDAAAh|BL^-B;D2Nk)_-kp{U0nj zYYVhnZzbW_j-&SmnRsNTT{^faWLG6-FcX^ZVlO?+Ke8-;e82FACyY1I9 zWZy%LJf~*@cBX~IyUCp9^i7Lh>eC(n*UU_}iJAI0MXoL6O_ryI);icz!G=LWGXtl9rU9I8uovNqBVCjwJa^7MTSO*oVBwzx9Q*hW{61_sy5Z0sK$cnFL$h z|FygRA9VazGv55L6D~mT1V5Pb@<5&d>Du9RSQvi6LtuzbWuA{5;qYJ}X^x*?Im a_Z`{}W6zgxa|wN)@CbMWJObYjf&T%Z-Ao<; literal 0 HcmV?d00001