338 lines
12 KiB
Go
338 lines
12 KiB
Go
package manifests
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/containers/common/pkg/manifests"
|
|
cp "github.com/containers/image/v5/copy"
|
|
"github.com/containers/image/v5/manifest"
|
|
"github.com/containers/image/v5/transports/alltransports"
|
|
"github.com/containers/image/v5/types"
|
|
"github.com/containers/storage"
|
|
"github.com/containers/storage/pkg/unshare"
|
|
digest "github.com/opencontainers/go-digest"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var (
|
|
_ List = &list{}
|
|
|
|
sys = &types.SystemContext{
|
|
SystemRegistriesConfPath: "../../tests/registries.conf",
|
|
SignaturePolicyPath: "../../tests/policy.json",
|
|
}
|
|
amd64sys = &types.SystemContext{ArchitectureChoice: "amd64"}
|
|
arm64sys = &types.SystemContext{ArchitectureChoice: "arm64"}
|
|
ppc64sys = &types.SystemContext{ArchitectureChoice: "ppc64le"}
|
|
)
|
|
|
|
const (
|
|
listImageName = "foo"
|
|
|
|
otherListImage = "docker://k8s.gcr.io/pause:3.1"
|
|
otherListDigest = "sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea"
|
|
otherListAmd64Digest = "sha256:59eec8837a4d942cc19a52b8c09ea75121acc38114a2c68b98983ce9356b8610"
|
|
otherListArm64Digest = "sha256:f365626a556e58189fc21d099fc64603db0f440bff07f77c740989515c544a39"
|
|
otherListPpc64Digest = "sha256:bcf9771c0b505e68c65440474179592ffdfa98790eb54ffbf129969c5e429990"
|
|
otherListInstanceDigest = "docker://k8s.gcr.io/pause@sha256:f365626a556e58189fc21d099fc64603db0f440bff07f77c740989515c544a39"
|
|
)
|
|
|
|
func TestSaveLoad(t *testing.T) {
|
|
if unshare.IsRootless() {
|
|
t.Skip("Test can only run as root")
|
|
}
|
|
|
|
dir, err := ioutil.TempDir("", "manifests")
|
|
assert.Nilf(t, err, "error creating temporary directory")
|
|
defer os.RemoveAll(dir)
|
|
|
|
storeOptions := storage.StoreOptions{
|
|
GraphRoot: filepath.Join(dir, "root"),
|
|
RunRoot: filepath.Join(dir, "runroot"),
|
|
GraphDriverName: "vfs",
|
|
}
|
|
store, err := storage.GetStore(storeOptions)
|
|
assert.Nilf(t, err, "error opening store")
|
|
if store == nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
if _, err := store.Shutdown(true); err != nil {
|
|
assert.Nilf(t, err, "error closing store")
|
|
}
|
|
}()
|
|
|
|
list := Create()
|
|
assert.NotNil(t, list, "Create() returned nil?")
|
|
|
|
image, err := list.SaveToImage(store, "", []string{listImageName}, manifest.DockerV2ListMediaType)
|
|
assert.Nilf(t, err, "SaveToImage(1)")
|
|
locker, err := LockerForImage(store, image)
|
|
assert.Nilf(t, err, "LockerForImage()")
|
|
locker.Lock()
|
|
defer locker.Unlock()
|
|
imageReused, err := list.SaveToImage(store, image, nil, manifest.DockerV2ListMediaType)
|
|
assert.Nilf(t, err, "SaveToImage(2)")
|
|
|
|
_, list, err = LoadFromImage(store, image)
|
|
assert.Nilf(t, err, "LoadFromImage(1)")
|
|
assert.NotNilf(t, list, "LoadFromImage(1)")
|
|
_, list, err = LoadFromImage(store, imageReused)
|
|
assert.Nilf(t, err, "LoadFromImage(2)")
|
|
assert.NotNilf(t, list, "LoadFromImage(2)")
|
|
_, list, err = LoadFromImage(store, listImageName)
|
|
assert.Nilf(t, err, "LoadFromImage(3)")
|
|
assert.NotNilf(t, list, "LoadFromImage(3)")
|
|
}
|
|
|
|
func TestAddRemove(t *testing.T) {
|
|
if unshare.IsRootless() {
|
|
t.Skip("Test can only run as root")
|
|
}
|
|
ctx := context.TODO()
|
|
|
|
ref, err := alltransports.ParseImageName(otherListImage)
|
|
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
|
|
src, err := ref.NewImageSource(ctx, sys)
|
|
assert.Nilf(t, err, "NewImageSource(%q)", otherListImage)
|
|
defer assert.Nilf(t, src.Close(), "ImageSource.Close()")
|
|
m, _, err := src.GetManifest(ctx, nil)
|
|
assert.Nilf(t, err, "ImageSource.GetManifest()")
|
|
assert.Nilf(t, src.Close(), "ImageSource.GetManifest()")
|
|
listDigest, err := manifest.Digest(m)
|
|
assert.Nilf(t, err, "manifest.Digest()")
|
|
assert.Equalf(t, listDigest.String(), otherListDigest, "digest for image %q changed?", otherListImage)
|
|
|
|
l, err := manifests.FromBlob(m)
|
|
assert.Nilf(t, err, "manifests.FromBlob()")
|
|
assert.NotNilf(t, l, "manifests.FromBlob()")
|
|
assert.Equalf(t, len(l.Instances()), 5, "image %q had an arch added?", otherListImage)
|
|
|
|
list := Create()
|
|
instanceDigest, err := list.Add(ctx, amd64sys, ref, false)
|
|
assert.Nilf(t, err, "list.Add(all=false)")
|
|
assert.Equal(t, instanceDigest.String(), otherListAmd64Digest)
|
|
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
|
|
|
|
list = Create()
|
|
instanceDigest, err = list.Add(ctx, arm64sys, ref, false)
|
|
assert.Nilf(t, err, "list.Add(all=false)")
|
|
assert.Equal(t, instanceDigest.String(), otherListArm64Digest)
|
|
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
|
|
|
|
list = Create()
|
|
instanceDigest, err = list.Add(ctx, ppc64sys, ref, false)
|
|
assert.Nilf(t, err, "list.Add(all=false)")
|
|
assert.Equal(t, instanceDigest.String(), otherListPpc64Digest)
|
|
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
|
|
|
|
_, err = list.Add(ctx, sys, ref, true)
|
|
assert.Nilf(t, err, "list.Add(all=true)")
|
|
assert.Equalf(t, len(list.Instances()), 5, "too many instances added")
|
|
|
|
list = Create()
|
|
_, err = list.Add(ctx, sys, ref, true)
|
|
assert.Nilf(t, err, "list.Add(all=true)")
|
|
assert.Equalf(t, len(list.Instances()), 5, "too many instances added", otherListImage)
|
|
|
|
for _, instance := range list.Instances() {
|
|
assert.Nilf(t, list.Remove(instance), "error removing instance %q", instance)
|
|
}
|
|
assert.Equalf(t, len(list.Instances()), 0, "should have removed all instances")
|
|
|
|
ref, err = alltransports.ParseImageName(otherListInstanceDigest)
|
|
assert.Nilf(t, err, "ParseImageName(%q)", otherListInstanceDigest)
|
|
|
|
list = Create()
|
|
_, err = list.Add(ctx, sys, ref, false)
|
|
assert.Nilf(t, err, "list.Add(all=false)")
|
|
assert.Equalf(t, len(list.Instances()), 1, "too many instances added", otherListInstanceDigest)
|
|
|
|
list = Create()
|
|
_, err = list.Add(ctx, sys, ref, true)
|
|
assert.Nilf(t, err, "list.Add(all=true)")
|
|
assert.Equalf(t, len(list.Instances()), 1, "too many instances added", otherListInstanceDigest)
|
|
}
|
|
|
|
func TestReference(t *testing.T) {
|
|
if unshare.IsRootless() {
|
|
t.Skip("Test can only run as root")
|
|
}
|
|
ctx := context.TODO()
|
|
|
|
dir, err := ioutil.TempDir("", "manifests")
|
|
assert.Nilf(t, err, "error creating temporary directory")
|
|
defer os.RemoveAll(dir)
|
|
|
|
storeOptions := storage.StoreOptions{
|
|
GraphRoot: filepath.Join(dir, "root"),
|
|
RunRoot: filepath.Join(dir, "runroot"),
|
|
GraphDriverName: "vfs",
|
|
}
|
|
store, err := storage.GetStore(storeOptions)
|
|
assert.Nilf(t, err, "error opening store")
|
|
if store == nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
if _, err := store.Shutdown(true); err != nil {
|
|
assert.Nilf(t, err, "error closing store")
|
|
}
|
|
}()
|
|
|
|
ref, err := alltransports.ParseImageName(otherListImage)
|
|
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
|
|
|
|
list := Create()
|
|
_, err = list.Add(ctx, ppc64sys, ref, false)
|
|
assert.Nilf(t, err, "list.Add(all=false)")
|
|
|
|
listRef, err := list.Reference(store, cp.CopyAllImages, nil)
|
|
assert.NotNilf(t, err, "list.Reference(never saved)")
|
|
assert.Nilf(t, listRef, "list.Reference(never saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
|
|
assert.NotNilf(t, err, "list.Reference(never saved)")
|
|
assert.Nilf(t, listRef, "list.Reference(never saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
|
|
assert.NotNilf(t, err, "list.Reference(never saved)")
|
|
assert.Nilf(t, listRef, "list.Reference(never saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
|
|
assert.NotNilf(t, err, "list.Reference(never saved)")
|
|
assert.Nilf(t, listRef, "list.Reference(never saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
|
|
assert.NotNilf(t, err, "list.Reference(never saved)")
|
|
assert.Nilf(t, listRef, "list.Reference(never saved)")
|
|
|
|
_, err = list.SaveToImage(store, "", []string{listImageName}, "")
|
|
assert.Nilf(t, err, "SaveToImage")
|
|
|
|
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
_, err = list.Add(ctx, sys, ref, true)
|
|
assert.Nilf(t, err, "list.Add(all=true)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, nil)
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
|
|
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
|
|
assert.Nilf(t, err, "list.Reference(saved)")
|
|
assert.NotNilf(t, listRef, "list.Reference(saved)")
|
|
}
|
|
|
|
func TestPush(t *testing.T) {
|
|
if unshare.IsRootless() {
|
|
t.Skip("Test can only run as root")
|
|
}
|
|
ctx := context.TODO()
|
|
|
|
dir, err := ioutil.TempDir("", "manifests")
|
|
assert.Nilf(t, err, "error creating temporary directory")
|
|
defer os.RemoveAll(dir)
|
|
|
|
storeOptions := storage.StoreOptions{
|
|
GraphRoot: filepath.Join(dir, "root"),
|
|
RunRoot: filepath.Join(dir, "runroot"),
|
|
GraphDriverName: "vfs",
|
|
}
|
|
store, err := storage.GetStore(storeOptions)
|
|
assert.Nilf(t, err, "error opening store")
|
|
if store == nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
if _, err := store.Shutdown(true); err != nil {
|
|
assert.Nilf(t, err, "error closing store")
|
|
}
|
|
}()
|
|
|
|
dest, err := ioutil.TempDir("", "manifests")
|
|
assert.Nilf(t, err, "error creating temporary directory")
|
|
defer os.RemoveAll(dest)
|
|
|
|
destRef, err := alltransports.ParseImageName(fmt.Sprintf("dir:%s", dest))
|
|
assert.Nilf(t, err, "ParseImageName()")
|
|
|
|
ref, err := alltransports.ParseImageName(otherListImage)
|
|
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
|
|
|
|
list := Create()
|
|
_, err = list.Add(ctx, sys, ref, true)
|
|
assert.Nilf(t, err, "list.Add(all=true)")
|
|
|
|
_, err = list.SaveToImage(store, "", []string{listImageName}, "")
|
|
assert.Nilf(t, err, "SaveToImage")
|
|
|
|
options := PushOptions{
|
|
Store: store,
|
|
SystemContext: sys,
|
|
ImageListSelection: cp.CopyAllImages,
|
|
Instances: nil,
|
|
}
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(all)")
|
|
|
|
options.ImageListSelection = cp.CopySystemImage
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(local)")
|
|
|
|
options.ImageListSelection = cp.CopySpecificImages
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(none specified)")
|
|
|
|
options.Instances = []digest.Digest{otherListAmd64Digest}
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(one specified)")
|
|
|
|
options.Instances = append(options.Instances, otherListArm64Digest)
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(two specified)")
|
|
|
|
options.Instances = append(options.Instances, otherListPpc64Digest)
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(three specified)")
|
|
|
|
options.Instances = append(options.Instances, otherListDigest)
|
|
_, _, err = list.Push(ctx, destRef, options)
|
|
assert.Nilf(t, err, "list.Push(four specified)")
|
|
}
|