2020-10-30 19:47:06 +00:00
|
|
|
package images
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/containerd/containerd/content"
|
|
|
|
"github.com/containerd/containerd/content/local"
|
2023-04-08 17:30:33 +00:00
|
|
|
cerrdefs "github.com/containerd/containerd/errdefs"
|
2020-10-30 19:47:06 +00:00
|
|
|
"github.com/containerd/containerd/leases"
|
|
|
|
"github.com/containerd/containerd/metadata"
|
|
|
|
"github.com/containerd/containerd/namespaces"
|
|
|
|
"github.com/docker/docker/image"
|
2022-03-04 13:49:42 +00:00
|
|
|
"github.com/opencontainers/go-digest"
|
2023-05-08 09:57:52 +00:00
|
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
2020-10-30 19:47:06 +00:00
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
"gotest.tools/v3/assert"
|
2022-07-26 12:12:44 +00:00
|
|
|
is "gotest.tools/v3/assert/cmp"
|
2020-10-30 19:47:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func setupTestStores(t *testing.T) (context.Context, content.Store, *imageStoreWithLease, func(t *testing.T)) {
|
2021-08-24 10:10:50 +00:00
|
|
|
dir, err := os.MkdirTemp("", t.Name())
|
2020-10-30 19:47:06 +00:00
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
backend, err := image.NewFSStoreBackend(filepath.Join(dir, "images"))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
is, err := image.NewImageStore(backend, nil)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
2022-01-20 12:52:42 +00:00
|
|
|
db, err := bbolt.Open(filepath.Join(dir, "metadata.db"), 0o600, nil)
|
2020-10-30 19:47:06 +00:00
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
cs, err := local.NewStore(filepath.Join(dir, "content"))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
mdb := metadata.NewDB(db, cs, nil)
|
|
|
|
|
|
|
|
cleanup := func(t *testing.T) {
|
|
|
|
assert.Check(t, db.Close())
|
|
|
|
assert.Check(t, os.RemoveAll(dir))
|
|
|
|
}
|
|
|
|
ctx := namespaces.WithNamespace(context.Background(), t.Name())
|
|
|
|
images := &imageStoreWithLease{Store: is, ns: t.Name(), leases: metadata.NewLeaseManager(mdb)}
|
|
|
|
|
|
|
|
return ctx, cs, images, cleanup
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestImageDelete(t *testing.T) {
|
|
|
|
ctx, _, images, cleanup := setupTestStores(t)
|
|
|
|
defer cleanup(t)
|
|
|
|
|
|
|
|
t.Run("no lease", func(t *testing.T) {
|
|
|
|
id, err := images.Create([]byte(`{"rootFS": {}}`))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.Delete(id)
|
|
|
|
|
|
|
|
ls, err := images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Equal(t, len(ls), 0, ls)
|
|
|
|
|
|
|
|
_, err = images.Delete(id)
|
|
|
|
assert.NilError(t, err, "should not error when there is no lease")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("lease exists", func(t *testing.T) {
|
|
|
|
id, err := images.Create([]byte(`{"rootFS": {}}`))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.Delete(id)
|
|
|
|
|
2022-11-08 11:41:12 +00:00
|
|
|
leaseID := imageKey(id.String())
|
2020-10-30 19:47:06 +00:00
|
|
|
_, err = images.leases.Create(ctx, leases.WithID(leaseID))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.leases.Delete(ctx, leases.Lease{ID: leaseID})
|
|
|
|
|
|
|
|
ls, err := images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
2022-07-26 12:12:44 +00:00
|
|
|
assert.Check(t, is.Equal(len(ls), 1), ls)
|
2020-10-30 19:47:06 +00:00
|
|
|
|
|
|
|
_, err = images.Delete(id)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
ls, err = images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
2022-07-26 12:12:44 +00:00
|
|
|
assert.Check(t, is.Equal(len(ls), 0), ls)
|
2020-10-30 19:47:06 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestContentStoreForPull(t *testing.T) {
|
2022-07-26 12:12:44 +00:00
|
|
|
ctx, cs, imgStore, cleanup := setupTestStores(t)
|
2020-10-30 19:47:06 +00:00
|
|
|
defer cleanup(t)
|
|
|
|
|
|
|
|
csP := &contentStoreForPull{
|
|
|
|
ContentStore: cs,
|
2022-07-26 12:12:44 +00:00
|
|
|
leases: imgStore.leases,
|
2020-10-30 19:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data := []byte(`{}`)
|
2023-05-08 09:57:52 +00:00
|
|
|
desc := ocispec.Descriptor{
|
2020-10-30 19:47:06 +00:00
|
|
|
Digest: digest.Canonical.FromBytes(data),
|
|
|
|
Size: int64(len(data)),
|
|
|
|
}
|
|
|
|
|
|
|
|
w, err := csP.Writer(ctx, content.WithRef(t.Name()), content.WithDescriptor(desc))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
_, err = w.Write(data)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer w.Close()
|
|
|
|
|
|
|
|
err = w.Commit(ctx, desc.Size, desc.Digest)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, len(csP.digested), 1)
|
2022-07-26 12:12:44 +00:00
|
|
|
assert.Check(t, is.Equal(csP.digested[0], desc.Digest))
|
2020-10-30 19:47:06 +00:00
|
|
|
|
|
|
|
// Test already exists
|
|
|
|
csP.digested = nil
|
|
|
|
_, err = csP.Writer(ctx, content.WithRef(t.Name()), content.WithDescriptor(desc))
|
2023-04-08 17:30:33 +00:00
|
|
|
assert.Check(t, cerrdefs.IsAlreadyExists(err))
|
2020-10-30 19:47:06 +00:00
|
|
|
assert.Equal(t, len(csP.digested), 1)
|
2022-07-26 12:12:44 +00:00
|
|
|
assert.Check(t, is.Equal(csP.digested[0], desc.Digest))
|
2020-10-30 19:47:06 +00:00
|
|
|
}
|