Compare commits
1 Commits
main
...
refactor/m
Author | SHA1 | Date | |
---|---|---|---|
|
4694b53177 |
@ -5,10 +5,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
iofs "io/fs"
|
iofs "io/fs"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/content"
|
||||||
|
"github.com/containerd/containerd/content/local"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/metadata"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
bolt "go.etcd.io/bbolt"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -384,3 +393,47 @@ func stringListToUrlList(t *testing.T, list []string) []url.URL {
|
|||||||
}
|
}
|
||||||
return urls
|
return urls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createTestContainerd(t *testing.T, ctx context.Context, imgs []map[string]string, blobs map[digest.Digest][]byte, enableLocalStore bool) *Containerd {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
contentPath := t.TempDir()
|
||||||
|
contentStore, err := local.NewStore(contentPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
boltDB, err := bolt.Open(path.Join(t.TempDir(), "bolt.db"), 0o644, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
db := metadata.NewDB(boltDB, contentStore, nil)
|
||||||
|
imageStore := metadata.NewImageStore(db)
|
||||||
|
for _, img := range imgs {
|
||||||
|
dgst, err := digest.Parse(img["digest"])
|
||||||
|
require.NoError(t, err)
|
||||||
|
cImg := images.Image{
|
||||||
|
Name: img["name"],
|
||||||
|
Target: ocispec.Descriptor{
|
||||||
|
MediaType: img["mediaType"],
|
||||||
|
Digest: dgst,
|
||||||
|
Size: int64(len(blobs[dgst])),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = imageStore.Create(ctx, cImg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
for k, v := range blobs {
|
||||||
|
writer, err := contentStore.Writer(ctx, content.WithRef(k.String()))
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, err = writer.Write(v)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = writer.Commit(ctx, int64(len(v)), k)
|
||||||
|
require.NoError(t, err)
|
||||||
|
writer.Close()
|
||||||
|
}
|
||||||
|
containerdClient, err := containerd.New("", containerd.WithServices(containerd.WithImageStore(imageStore), containerd.WithContentStore(contentStore)))
|
||||||
|
require.NoError(t, err)
|
||||||
|
if !enableLocalStore {
|
||||||
|
contentPath = ""
|
||||||
|
}
|
||||||
|
return &Containerd{
|
||||||
|
contentPath: contentPath,
|
||||||
|
client: containerdClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
60
pkg/oci/memory.go
Normal file
60
pkg/oci/memory.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package oci
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Client = &MemoryClient{}
|
||||||
|
|
||||||
|
type MemoryClient struct {
|
||||||
|
images []Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMemoryClient(images []Image) *MemoryClient {
|
||||||
|
return &MemoryClient{
|
||||||
|
images: images,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) Name() string {
|
||||||
|
return "memory"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) Verify(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) Subscribe(ctx context.Context) (<-chan ImageEvent, <-chan error, error) {
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) ListImages(ctx context.Context) ([]Image, error) {
|
||||||
|
return m.images, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) AllIdentifiers(ctx context.Context, img Image) ([]string, error) {
|
||||||
|
return []string{img.Digest.String()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) Resolve(ctx context.Context, ref string) (digest.Digest, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) Size(ctx context.Context, dgst digest.Digest) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) GetManifest(ctx context.Context, dgst digest.Digest) ([]byte, string, error) {
|
||||||
|
return nil, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) GetBlob(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryClient) CopyLayer(ctx context.Context, dgst digest.Digest, dst io.Writer) error {
|
||||||
|
return nil
|
||||||
|
}
|
12
pkg/oci/memory_test.go
Normal file
12
pkg/oci/memory_test.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package oci
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createTestMemory(t *testing.T, imgs []map[string]string, blobs map[digest.Digest][]byte) *MemoryClient {
|
||||||
|
images := []Images{}
|
||||||
|
return NewMemoryClient(images)
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
package oci
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/opencontainers/go-digest"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Client = &MockClient{}
|
|
||||||
|
|
||||||
type MockClient struct {
|
|
||||||
images []Image
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMockClient(images []Image) *MockClient {
|
|
||||||
return &MockClient{
|
|
||||||
images: images,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) Name() string {
|
|
||||||
return "mock"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) Verify(ctx context.Context) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) Subscribe(ctx context.Context) (<-chan ImageEvent, <-chan error, error) {
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) ListImages(ctx context.Context) ([]Image, error) {
|
|
||||||
return m.images, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) AllIdentifiers(ctx context.Context, img Image) ([]string, error) {
|
|
||||||
return []string{img.Digest.String()}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) Resolve(ctx context.Context, ref string) (digest.Digest, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) Size(ctx context.Context, dgst digest.Digest) (int64, error) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) GetManifest(ctx context.Context, dgst digest.Digest) ([]byte, string, error) {
|
|
||||||
return nil, "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) GetBlob(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockClient) CopyLayer(ctx context.Context, dgst digest.Digest, dst io.Writer) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -9,21 +9,16 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
|
||||||
"github.com/containerd/containerd/content"
|
|
||||||
"github.com/containerd/containerd/content/local"
|
|
||||||
"github.com/containerd/containerd/images"
|
|
||||||
"github.com/containerd/containerd/metadata"
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
bolt "go.etcd.io/bbolt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOCIClient(t *testing.T) {
|
func TestOCIClient(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
// Load the test images
|
||||||
b, err := os.ReadFile("./testdata/images.json")
|
b, err := os.ReadFile("./testdata/images.json")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
imgs := []map[string]string{}
|
imgs := []map[string]string{}
|
||||||
@ -43,67 +38,31 @@ func TestOCIClient(t *testing.T) {
|
|||||||
blobs[dgst] = b
|
blobs[dgst] = b
|
||||||
}
|
}
|
||||||
|
|
||||||
contentPath := t.TempDir()
|
ctx := namespaces.WithNamespace(context.Background(), "k8s.io")
|
||||||
contentStore, err := local.NewStore(contentPath)
|
clients := []Client{}
|
||||||
require.NoError(t, err)
|
clients = append(clients, createTestMemory(t, imgs, blobs))
|
||||||
boltDB, err := bolt.Open(path.Join(t.TempDir(), "bolt.db"), 0o644, nil)
|
clients = append(clients, createTestContainerd(t, ctx, imgs, blobs, false))
|
||||||
require.NoError(t, err)
|
clients = append(clients, createTestContainerd(t, ctx, imgs, blobs, true))
|
||||||
db := metadata.NewDB(boltDB, contentStore, nil)
|
for _, client := range clients {
|
||||||
imageStore := metadata.NewImageStore(db)
|
t.Run(client.Name(), func(t *testing.T) {
|
||||||
ctx := namespaces.WithNamespace(context.TODO(), "k8s.io")
|
|
||||||
for _, img := range imgs {
|
|
||||||
dgst, err := digest.Parse(img["digest"])
|
|
||||||
require.NoError(t, err)
|
|
||||||
cImg := images.Image{
|
|
||||||
Name: img["name"],
|
|
||||||
Target: ocispec.Descriptor{
|
|
||||||
MediaType: img["mediaType"],
|
|
||||||
Digest: dgst,
|
|
||||||
Size: int64(len(blobs[dgst])),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_, err = imageStore.Create(ctx, cImg)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
for k, v := range blobs {
|
|
||||||
writer, err := contentStore.Writer(ctx, content.WithRef(k.String()))
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, err = writer.Write(v)
|
|
||||||
require.NoError(t, err)
|
|
||||||
err = writer.Commit(ctx, int64(len(v)), k)
|
|
||||||
require.NoError(t, err)
|
|
||||||
writer.Close()
|
|
||||||
}
|
|
||||||
containerdClient, err := containerd.New("", containerd.WithServices(containerd.WithImageStore(imageStore), containerd.WithContentStore(contentStore)))
|
|
||||||
require.NoError(t, err)
|
|
||||||
remoteContainerd := &Containerd{
|
|
||||||
client: containerdClient,
|
|
||||||
}
|
|
||||||
localContainerd := &Containerd{
|
|
||||||
contentPath: contentPath,
|
|
||||||
client: containerdClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ociClient := range []Client{remoteContainerd, localContainerd} {
|
|
||||||
t.Run(ociClient.Name(), func(t *testing.T) {
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
imgs, err := ociClient.ListImages(ctx)
|
imgs, err := client.ListImages(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, imgs, 5)
|
require.Len(t, imgs, 5)
|
||||||
for _, img := range imgs {
|
for _, img := range imgs {
|
||||||
_, err := ociClient.Resolve(ctx, img.Name)
|
_, err := client.Resolve(ctx, img.Name)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
noPlatformName := "example.com/org/no-platform:test"
|
noPlatformName := "example.com/org/no-platform:test"
|
||||||
dgst, err := ociClient.Resolve(ctx, noPlatformName)
|
dgst, err := client.Resolve(ctx, noPlatformName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
img := Image{
|
img := Image{
|
||||||
Name: noPlatformName,
|
Name: noPlatformName,
|
||||||
Digest: dgst,
|
Digest: dgst,
|
||||||
}
|
}
|
||||||
_, err = ociClient.AllIdentifiers(ctx, img)
|
_, err = client.AllIdentifiers(ctx, img)
|
||||||
require.EqualError(t, err, "failed to walk image manifests: could not find any platforms with local content in manifest list: sha256:addc990c58744bdf96364fe89bd4aab38b1e824d51c688edb36c75247cd45fa9")
|
require.EqualError(t, err, "failed to walk image manifests: could not find any platforms with local content in manifest list: sha256:addc990c58744bdf96364fe89bd4aab38b1e824d51c688edb36c75247cd45fa9")
|
||||||
|
|
||||||
contentTests := []struct {
|
contentTests := []struct {
|
||||||
@ -136,16 +95,16 @@ func TestOCIClient(t *testing.T) {
|
|||||||
t.Run(tt.mediaType, func(t *testing.T) {
|
t.Run(tt.mediaType, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
size, err := ociClient.Size(ctx, tt.dgst)
|
size, err := client.Size(ctx, tt.dgst)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tt.size, size)
|
require.Equal(t, tt.size, size)
|
||||||
if tt.mediaType != ocispec.MediaTypeImageLayer {
|
if tt.mediaType != ocispec.MediaTypeImageLayer {
|
||||||
b, mediaType, err := ociClient.GetManifest(ctx, tt.dgst)
|
b, mediaType, err := client.GetManifest(ctx, tt.dgst)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tt.mediaType, mediaType)
|
require.Equal(t, tt.mediaType, mediaType)
|
||||||
require.Equal(t, blobs[tt.dgst], b)
|
require.Equal(t, blobs[tt.dgst], b)
|
||||||
} else {
|
} else {
|
||||||
rc, err := ociClient.GetBlob(ctx, tt.dgst)
|
rc, err := client.GetBlob(ctx, tt.dgst)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
b, err := io.ReadAll(rc)
|
b, err := io.ReadAll(rc)
|
||||||
@ -259,7 +218,7 @@ func TestOCIClient(t *testing.T) {
|
|||||||
|
|
||||||
img, err := Parse(tt.imageName, digest.Digest(tt.imageDigest))
|
img, err := Parse(tt.imageName, digest.Digest(tt.imageDigest))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
keys, err := ociClient.AllIdentifiers(ctx, img)
|
keys, err := client.AllIdentifiers(ctx, img)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tt.expectedKeys, keys)
|
require.Equal(t, tt.expectedKeys, keys)
|
||||||
})
|
})
|
||||||
|
@ -45,7 +45,7 @@ func TestBasic(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
imgs = append(imgs, img)
|
imgs = append(imgs, img)
|
||||||
}
|
}
|
||||||
ociClient := oci.NewMockClient(imgs)
|
ociClient := oci.NewMemoryClient(imgs)
|
||||||
router := routing.NewMemoryRouter(map[string][]netip.AddrPort{}, netip.MustParseAddrPort("127.0.0.1:5000"))
|
router := routing.NewMemoryRouter(map[string][]netip.AddrPort{}, netip.MustParseAddrPort("127.0.0.1:5000"))
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.TODO())
|
ctx, cancel := context.WithCancel(context.TODO())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user