use .Buffer() for layer contents

This commit is contained in:
Motiejus Jakštys 2021-05-24 00:11:58 +03:00
parent c3be4bdb35
commit 81db130c94
3 changed files with 43 additions and 42 deletions

View File

@ -55,8 +55,8 @@ func TestRootFS(t *testing.T) {
{ {
name: "basic file overwrite, layer order mixed", name: "basic file overwrite, layer order mixed",
image: tarball{ image: tarball{
file{Name: "layer1/layer.tar", Contents: layer1}, file{Name: "layer1/layer.tar", Contents: layer1.Buffer()},
file{Name: "layer0/layer.tar", Contents: layer0}, file{Name: "layer0/layer.tar", Contents: layer0.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -69,10 +69,10 @@ func TestRootFS(t *testing.T) {
image: tarball{ image: tarball{
file{Name: "layer0/layer.tar", Contents: tarball{ file{Name: "layer0/layer.tar", Contents: tarball{
file{Name: "a"}, file{Name: "a"},
}}, }.Buffer()},
file{Name: "layer1/layer.tar", Contents: tarball{ file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: "a"}, hardlink{Name: "a"},
}}, }.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -82,9 +82,9 @@ func TestRootFS(t *testing.T) {
{ {
name: "directory overwrite retains original dir", name: "directory overwrite retains original dir",
image: tarball{ image: tarball{
file{Name: "layer2/layer.tar", Contents: layer2}, file{Name: "layer2/layer.tar", Contents: layer2.Buffer()},
file{Name: "layer0/layer.tar", Contents: layer0}, file{Name: "layer0/layer.tar", Contents: layer0.Buffer()},
file{Name: "layer1/layer.tar", Contents: layer1}, file{Name: "layer1/layer.tar", Contents: layer1.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar", "layer2/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar", "layer2/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -101,11 +101,11 @@ func TestRootFS(t *testing.T) {
file{Name: "fileb"}, file{Name: "fileb"},
dir{Name: "dira"}, dir{Name: "dira"},
dir{Name: "dirb"}, dir{Name: "dirb"},
}}, }.Buffer()},
file{Name: "layer1/layer.tar", Contents: tarball{ file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: ".wh.filea"}, hardlink{Name: ".wh.filea"},
hardlink{Name: ".wh.dira"}, hardlink{Name: ".wh.dira"},
}}, }.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -118,13 +118,13 @@ func TestRootFS(t *testing.T) {
image: tarball{ image: tarball{
file{Name: "layer0/layer.tar", Contents: tarball{ file{Name: "layer0/layer.tar", Contents: tarball{
file{Name: "file", Contents: bytes.NewBufferString("from 0")}, file{Name: "file", Contents: bytes.NewBufferString("from 0")},
}}, }.Buffer()},
file{Name: "layer1/layer.tar", Contents: tarball{ file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: ".wh.file"}, hardlink{Name: ".wh.file"},
}}, }.Buffer()},
file{Name: "layer2/layer.tar", Contents: tarball{ file{Name: "layer2/layer.tar", Contents: tarball{
file{Name: "file", Contents: bytes.NewBufferString("from 3")}, file{Name: "file", Contents: bytes.NewBufferString("from 3")},
}}, }.Buffer()},
manifest{ manifest{
"layer0/layer.tar", "layer0/layer.tar",
"layer1/layer.tar", "layer1/layer.tar",
@ -140,10 +140,10 @@ func TestRootFS(t *testing.T) {
image: tarball{ image: tarball{
file{Name: "layer0/layer.tar", Contents: tarball{ file{Name: "layer0/layer.tar", Contents: tarball{
dir{Name: "dir"}, dir{Name: "dir"},
}}, }.Buffer()},
file{Name: "layer1/layer.tar", Contents: tarball{ file{Name: "layer1/layer.tar", Contents: tarball{
dir{Name: ".wh.dir"}, dir{Name: ".wh.dir"},
}}, }.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -157,12 +157,12 @@ func TestRootFS(t *testing.T) {
file{Name: "layer0/layer.tar", Contents: tarball{ file{Name: "layer0/layer.tar", Contents: tarball{
dir{Name: "a"}, dir{Name: "a"},
file{Name: "a/filea"}, file{Name: "a/filea"},
}}, }.Buffer()},
file{Name: "layer1/layer.tar", Contents: tarball{ file{Name: "layer1/layer.tar", Contents: tarball{
dir{Name: "a"}, dir{Name: "a"},
file{Name: "a/fileb"}, file{Name: "a/fileb"},
hardlink{Name: "a/.wh..wh..opq"}, hardlink{Name: "a/.wh..wh..opq"},
}}, }.Buffer()},
manifest{"layer0/layer.tar", "layer1/layer.tar"}, manifest{"layer0/layer.tar", "layer1/layer.tar"},
}, },
want: []extractable{ want: []extractable{
@ -174,7 +174,7 @@ func TestRootFS(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
in := bytes.NewReader(tt.image.Bytes()) in := bytes.NewReader(tt.image.Buffer().Bytes())
out := bytes.Buffer{} out := bytes.Buffer{}
err := New(in).WriteTo(&out) err := New(in).WriteTo(&out)

View File

@ -12,11 +12,7 @@ import (
type ( type (
Tarrer interface { Tarrer interface {
Tar(*tar.Writer) Tar(*tar.Writer) error
}
Byter interface {
Bytes() []byte
} }
Tarball []Tarrer Tarball []Tarrer
@ -33,7 +29,7 @@ type (
File struct { File struct {
Name string Name string
Uid int Uid int
Contents Byter Contents *bytes.Buffer
} }
Manifest []string Manifest []string
@ -48,55 +44,60 @@ type (
} }
) )
func (tb Tarball) Bytes() []byte { func (tb Tarball) Buffer() *bytes.Buffer {
buf := bytes.Buffer{} var buf bytes.Buffer
tw := tar.NewWriter(&buf) tw := tar.NewWriter(&buf)
for _, member := range tb { for _, member := range tb {
member.Tar(tw) member.Tar(tw)
} }
tw.Close() tw.Close()
return buf.Bytes() return &buf
} }
func (d Dir) Tar(tw *tar.Writer) { func (d Dir) Tar(tw *tar.Writer) error {
hdr := &tar.Header{ hdr := &tar.Header{
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
Name: d.Name, Name: d.Name,
Mode: 0644, Mode: 0644,
Uid: d.Uid, Uid: d.Uid,
} }
tw.WriteHeader(hdr) return tw.WriteHeader(hdr)
} }
func (f File) Tar(tw *tar.Writer) { func (f File) Tar(tw *tar.Writer) error {
var contentbytes []byte var contents []byte
if f.Contents != nil { if f.Contents != nil {
contentbytes = f.Contents.Bytes() contents = f.Contents.Bytes()
} }
hdr := &tar.Header{ hdr := &tar.Header{
Typeflag: tar.TypeReg, Typeflag: tar.TypeReg,
Name: f.Name, Name: f.Name,
Mode: 0644, Mode: 0644,
Uid: f.Uid, Uid: f.Uid,
Size: int64(len(contentbytes)), Size: int64(len(contents)),
} }
tw.WriteHeader(hdr) if err := tw.WriteHeader(hdr); err != nil {
tw.Write(contentbytes) return err
}
if _, err := tw.Write(contents); err != nil {
return err
}
return nil
} }
func (m Manifest) Tar(tw *tar.Writer) { func (m Manifest) Tar(tw *tar.Writer) error {
b, err := json.Marshal(dockerManifestJSON{{Layers: m}}) b, err := json.Marshal(dockerManifestJSON{{Layers: m}})
if err != nil { if err != nil {
panic("testerr") return err
} }
File{ return File{
Name: "manifest.json", Name: "manifest.json",
Contents: bytes.NewBuffer(b), Contents: bytes.NewBuffer(b),
}.Tar(tw) }.Tar(tw)
} }
func (h Hardlink) Tar(tw *tar.Writer) { func (h Hardlink) Tar(tw *tar.Writer) error {
tw.WriteHeader(&tar.Header{ return tw.WriteHeader(&tar.Header{
Typeflag: tar.TypeLink, Typeflag: tar.TypeLink,
Name: h.Name, Name: h.Name,
Mode: 0644, Mode: 0644,

View File

@ -10,15 +10,15 @@ import (
func TestTarball(t *testing.T) { func TestTarball(t *testing.T) {
bk := Tarball{File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("hello")}} bk := Tarball{File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("hello")}}
img := Tarball{ img := Tarball{
File{Name: "backup.tar", Contents: bk}, File{Name: "backup.tar", Contents: bk.Buffer()},
File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("bye")}, File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("bye")},
Dir{Name: "bin"}, Dir{Name: "bin"},
Hardlink{Name: "entrypoint2"}, Hardlink{Name: "entrypoint2"},
} }
got := Extract(t, bytes.NewBuffer(img.Bytes())) got := Extract(t, img.Buffer())
want := []Extractable{ want := []Extractable{
File{Name: "backup.tar", Contents: bytes.NewBuffer(bk.Bytes())}, File{Name: "backup.tar", Contents: bk.Buffer()},
File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("bye")}, File{Name: "entrypoint.sh", Contents: bytes.NewBufferString("bye")},
Dir{Name: "bin"}, Dir{Name: "bin"},
Hardlink{Name: "entrypoint2"}, Hardlink{Name: "entrypoint2"},