Merge pull request #5933 from claudiubelu/integration/import-multilayer

integration: Adds test for multilayer image import
This commit is contained in:
Phil Estes 2021-10-07 14:09:25 -04:00 committed by GitHub
commit e648fa2e81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 10 deletions

View File

@ -33,9 +33,10 @@ const (
) )
var ( var (
testImage = "ghcr.io/containerd/busybox:1.32" testImage = "ghcr.io/containerd/busybox:1.32"
shortCommand = withProcessArgs("true") testMultiLayeredImage = "gcr.io/k8s-cri-containerd/volume-copy-up:2.1"
longCommand = withProcessArgs("/bin/sh", "-c", "while true; do sleep 1; done") shortCommand = withProcessArgs("true")
longCommand = withProcessArgs("/bin/sh", "-c", "while true; do sleep 1; done")
) )
func TestImagePullSchema1WithEmptyLayers(t *testing.T) { func TestImagePullSchema1WithEmptyLayers(t *testing.T) {

View File

@ -30,11 +30,12 @@ const (
) )
var ( var (
defaultRoot = filepath.Join(os.Getenv("programfiles"), "containerd", "root-test") defaultRoot = filepath.Join(os.Getenv("programfiles"), "containerd", "root-test")
defaultState = filepath.Join(os.Getenv("programfiles"), "containerd", "state-test") defaultState = filepath.Join(os.Getenv("programfiles"), "containerd", "state-test")
testImage string testImage string
shortCommand = withTrue() testMultiLayeredImage = "gcr.io/k8s-cri-containerd/volume-copy-up:2.1"
longCommand = withProcessArgs("ping", "-t", "localhost") shortCommand = withTrue()
longCommand = withProcessArgs("ping", "-t", "localhost")
) )
func init() { func init() {

View File

@ -26,12 +26,17 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"testing" "testing"
"time"
. "github.com/containerd/containerd" . "github.com/containerd/containerd"
"github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/archive/compression"
"github.com/containerd/containerd/archive/tartest" "github.com/containerd/containerd/archive/tartest"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/images/archive" "github.com/containerd/containerd/images/archive"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/platforms"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go" specs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -40,6 +45,18 @@ import (
// TestExportAndImport exports testImage as a tar stream, // TestExportAndImport exports testImage as a tar stream,
// and import the tar stream as a new image. // and import the tar stream as a new image.
func TestExportAndImport(t *testing.T) { func TestExportAndImport(t *testing.T) {
testExportImport(t, testImage)
}
// TestExportAndImportMultiLayer exports testMultiLayeredImage as a tar stream,
// and import the tar stream as a new image. This should ensure that imported
// images remain sane, and that the Garbage Collector won't delete part of its
// content.
func TestExportAndImportMultiLayer(t *testing.T) {
testExportImport(t, testMultiLayeredImage)
}
func testExportImport(t *testing.T, imageName string) {
if testing.Short() { if testing.Short() {
t.Skip() t.Skip()
} }
@ -52,17 +69,19 @@ func TestExportAndImport(t *testing.T) {
} }
defer client.Close() defer client.Close()
_, err = client.Fetch(ctx, testImage) _, err = client.Fetch(ctx, imageName)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
wb := bytes.NewBuffer(nil) wb := bytes.NewBuffer(nil)
err = client.Export(ctx, wb, archive.WithAllPlatforms(), archive.WithImage(client.ImageService(), testImage)) err = client.Export(ctx, wb, archive.WithPlatform(platforms.Default()), archive.WithImage(client.ImageService(), imageName))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
client.ImageService().Delete(ctx, imageName)
opts := []ImportOpt{ opts := []ImportOpt{
WithImageRefTranslator(archive.AddRefPrefix("foo/bar")), WithImageRefTranslator(archive.AddRefPrefix("foo/bar")),
} }
@ -71,6 +90,41 @@ func TestExportAndImport(t *testing.T) {
t.Fatalf("Import failed: %+v", err) t.Fatalf("Import failed: %+v", err)
} }
// We need to unpack the image, especially if it's multilayered.
for _, img := range imgrecs {
image := NewImage(client, img)
// TODO: Show unpack status
t.Logf("unpacking %s (%s)...", img.Name, img.Target.Digest)
err = image.Unpack(ctx, "")
if err != nil {
t.Fatalf("Error while unpacking image: %+v", err)
}
t.Log("done")
}
// we're triggering the Garbage Collector to do its job.
ls := client.LeasesService()
l, err := ls.Create(ctx, leases.WithRandomID(), leases.WithExpiration(time.Hour))
if err != nil {
t.Fatalf("Error while creating lease: %+v", err)
}
if err = ls.Delete(ctx, l, leases.SynchronousDelete); err != nil {
t.Fatalf("Error while deleting lease: %+v", err)
}
image, err := client.GetImage(ctx, imageName)
if err != nil {
t.Fatal(err)
}
id := t.Name()
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image)))
if err != nil {
t.Fatalf("Error while creating container: %+v", err)
}
container.Delete(ctx, WithSnapshotCleanup)
for _, imgrec := range imgrecs { for _, imgrec := range imgrecs {
if imgrec.Name == testImage { if imgrec.Name == testImage {
continue continue