mirror of
https://github.com/mudler/luet.git
synced 2025-08-13 13:06:37 +00:00
tests: pull image before running
This commit is contained in:
parent
454a560f4c
commit
ad489c2157
@ -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,
|
||||||
|
@ -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...)
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
),
|
),
|
||||||
|
@ -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' ]"
|
||||||
|
Loading…
Reference in New Issue
Block a user