tests: pull image before running

This commit is contained in:
Ettore Di Giacinto 2021-10-23 23:12:04 +02:00
parent 454a560f4c
commit ad489c2157
6 changed files with 83 additions and 50 deletions

View File

@ -16,7 +16,6 @@
package image_test package image_test
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -31,9 +30,9 @@ import (
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )
var _ = Describe("DeltaInfo", func() { var _ = Describe("Delta", func() {
Context("Generates deltas of images", func() { Context("Generates deltas of images", func() {
It("Correctly detect packages", func() { It("computes delta", func() {
ref, err := name.ParseReference("alpine") ref, err := name.ParseReference("alpine")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -78,7 +77,7 @@ var _ = Describe("DeltaInfo", func() {
Expect(len(diff.Additions) > 0).To(BeTrue()) Expect(len(diff.Additions) > 0).To(BeTrue())
Expect(len(diff.Changes) > 0).To(BeTrue()) Expect(len(diff.Changes) > 0).To(BeTrue())
Expect(len(diff.Deletions) > 0).To(BeTrue()) Expect(len(diff.Deletions) == 0).To(BeTrue())
}) })
It("Extract all deltas", func() { It("Extract all deltas", func() {
@ -90,14 +89,13 @@ var _ = Describe("DeltaInfo", func() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up defer os.RemoveAll(tmpdir) // clean up
fmt.Println(file.ListDir(tmpdir))
Expect(file.Exists(filepath.Join(tmpdir, "root", ".cache"))).To(BeTrue()) Expect(file.Exists(filepath.Join(tmpdir, "root", ".cache"))).To(BeTrue())
Expect(file.Exists(filepath.Join(tmpdir, "bin", "sh"))).To(BeFalse()) Expect(file.Exists(filepath.Join(tmpdir, "bin", "sh"))).To(BeFalse())
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go"))).To(BeTrue()) Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go"))).To(BeTrue())
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go", "bin"))).To(BeTrue()) Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go", "bin"))).To(BeTrue())
}) })
It("Extract deltas and excludes stuff", func() { It("Extract deltas and excludes /usr/local/go", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img2, img2,
@ -107,7 +105,7 @@ var _ = Describe("DeltaInfo", func() {
defer os.RemoveAll(tmpdir) // clean up defer os.RemoveAll(tmpdir) // clean up
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go"))).To(BeFalse()) Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go"))).To(BeFalse())
}) })
It("Extract deltas and excludes stuff", func() { It("Extract deltas and excludes /usr/local/go/bin, but includes /usr/local/go", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img2, img2,
@ -119,7 +117,7 @@ var _ = Describe("DeltaInfo", func() {
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go", "bin"))).To(BeFalse()) Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go", "bin"))).To(BeFalse())
}) })
It("Extract deltas and excludes stuff", func() { It("Extract deltas and includes /usr/local/go", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img2, img2,

View File

@ -18,11 +18,14 @@ package image
import ( import (
"archive/tar" "archive/tar"
"context" "context"
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
containerdarchive "github.com/containerd/containerd/archive" containerdarchive "github.com/containerd/containerd/archive"
"github.com/docker/docker/pkg/system"
v1 "github.com/google/go-containerregistry/pkg/v1" v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types"
@ -100,42 +103,6 @@ func ExtractDeltaFiles(
} }
} }
func Extract(ctx *types.Context, img v1.Image, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (string, error) {
src := mutate.Extract(img)
defer src.Close()
tmpdiffs, err := ctx.Config.GetSystem().TempDir("extraction")
if err != nil {
return "", errors.Wrap(err, "Error met while creating tempdir for rootfs")
}
perms := map[string][]int{}
f := func(h *tar.Header) (bool, error) {
perms[h.Name] = []int{h.Gid, h.Uid}
return filter(h)
}
if filter != nil {
opts = append(opts, containerdarchive.WithFilter(f))
}
_, err = containerdarchive.Apply(context.Background(), tmpdiffs, src, opts...)
if err != nil {
return "", err
}
for f, p := range perms {
ff := filepath.Join(tmpdiffs, f)
if _, err := os.Lstat(ff); err == nil {
if err := os.Chown(ff, p[0], p[1]); err != nil {
ctx.Warning(err, "failed chowning file")
}
}
}
return tmpdiffs, nil
}
func ExtractFiles( func ExtractFiles(
ctx *types.Context, ctx *types.Context,
prefixPath string, prefixPath string,
@ -164,7 +131,7 @@ func ExtractFiles(
for _, i := range includeRegexp { for _, i := range includeRegexp {
if i.MatchString(filepath.Join(prefixPath, fileName)) { if i.MatchString(filepath.Join(prefixPath, fileName)) {
if prefixPath != "" { if prefixPath != "" {
return strings.HasPrefix(h.Name, prefixPath), nil return strings.HasPrefix(fileName, prefixPath), nil
} }
ctx.Debug("Adding name", fileName) ctx.Debug("Adding name", fileName)
@ -198,3 +165,64 @@ func ExtractFiles(
} }
} }
} }
func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (string, error) {
defer reader.Close()
perms := map[string][]int{}
xattrs := map[string]map[string]string{}
paxrecords := map[string]map[string]string{}
f := func(h *tar.Header) (bool, error) {
perms[h.Name] = []int{h.Gid, h.Uid}
xattrs[h.Name] = h.Xattrs
paxrecords[h.Name] = h.PAXRecords
return filter(h)
}
if filter != nil {
opts = append(opts, containerdarchive.WithFilter(f))
}
_, err := containerdarchive.Apply(context.Background(), output, reader, opts...)
if err != nil {
return "", err
}
for f, p := range perms {
ff := filepath.Join(output, f)
if _, err := os.Lstat(ff); err == nil {
if err := os.Lchown(ff, p[1], p[0]); err != nil {
ctx.Warning(err, "failed chowning file")
}
}
}
for _, m := range []map[string]map[string]string{xattrs, paxrecords} {
for key, attrs := range m {
ff := filepath.Join(output, key)
for k, attr := range attrs {
if err := system.Lsetxattr(ff, k, []byte(attr), 0); err != nil {
if errors.Is(err, syscall.ENOTSUP) {
ctx.Debug("ignored xattr %s in archive", key)
}
}
}
}
}
return output, nil
}
func Extract(ctx *types.Context, img v1.Image, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (string, error) {
tmpdiffs, err := ctx.Config.GetSystem().TempDir("extraction")
if err != nil {
return "", errors.Wrap(err, "Error met while creating tempdir for rootfs")
}
return ExtractReader(ctx, mutate.Extract(img), tmpdiffs, filter, opts...)
}
func ExtractTo(ctx *types.Context, img v1.Image, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (string, error) {
return ExtractReader(ctx, mutate.Extract(img), output, filter, opts...)
}

View File

@ -31,6 +31,7 @@ import (
) )
var _ = Describe("Extract", func() { var _ = Describe("Extract", func() {
Context("extract files from images", func() { Context("extract files from images", func() {
Context("ExtractFiles", func() { Context("ExtractFiles", func() {
ctx := types.NewContext() ctx := types.NewContext()
@ -70,7 +71,7 @@ var _ = Describe("Extract", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img, img,
ExtractFiles(ctx, "usr", []string{}, []string{}), ExtractFiles(ctx, "/usr", []string{}, []string{}),
) )
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up defer os.RemoveAll(tmpdir) // clean up
@ -83,7 +84,7 @@ var _ = Describe("Extract", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img, img,
ExtractFiles(ctx, "usr", []string{"bin"}, []string{"sbin"}), ExtractFiles(ctx, "/usr", []string{"bin"}, []string{"sbin"}),
) )
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up defer os.RemoveAll(tmpdir) // clean up
@ -97,7 +98,7 @@ var _ = Describe("Extract", func() {
tmpdir, err := Extract( tmpdir, err := Extract(
ctx, ctx,
img, img,
ExtractFiles(ctx, "", []string{"usr", "usr/bin"}, []string{"^bin"}), ExtractFiles(ctx, "", []string{"/usr|/usr/bin"}, []string{"^/bin"}),
) )
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up defer os.RemoveAll(tmpdir) // clean up

View File

@ -18,11 +18,17 @@ package image_test
import ( import (
"testing" "testing"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/compiler/backend"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )
func TestMutator(t *testing.T) { func TestMutator(t *testing.T) {
RegisterFailHandler(Fail) RegisterFailHandler(Fail)
b := backend.NewSimpleDockerBackend(types.NewContext())
b.DownloadImage(backend.Options{ImageName: "alpine"})
b.DownloadImage(backend.Options{ImageName: "golang:alpine"})
RunSpecs(t, "Mutator API Suite") RunSpecs(t, "Mutator API Suite")
} }

View File

@ -238,7 +238,7 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p *compi
img, img,
image.ExtractFiles( image.ExtractFiles(
cs.Options.Context, cs.Options.Context,
strings.TrimLeft(p.GetPackageDir(), "/"), p.GetPackageDir(),
p.GetIncludes(), p.GetIncludes(),
p.GetExcludes(), p.GetExcludes(),
), ),

View File

@ -12,7 +12,7 @@ oneTimeTearDown() {
testBuild() { testBuild() {
mkdir $tmpdir/testbuild mkdir $tmpdir/testbuild
luet build --tree "$ROOT_DIR/tests/fixtures/docker" --destination $tmpdir/testbuild --compression gzip --all > /dev/null luet build --tree "$ROOT_DIR/tests/fixtures/docker" --destination $tmpdir/testbuild --compression gzip --all
buildst=$? buildst=$?
assertEquals 'builds successfully' "$buildst" "0" assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package' "[ -e '$tmpdir/testbuild/alpine-seed-1.0.package.tar.gz' ]" assertTrue 'create package' "[ -e '$tmpdir/testbuild/alpine-seed-1.0.package.tar.gz' ]"