diff --git a/pkg/content/local.go b/pkg/content/local.go index a6e8f0bd..6320f22d 100644 --- a/pkg/content/local.go +++ b/pkg/content/local.go @@ -22,7 +22,6 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/content" - "github.com/containerd/containerd/content/local" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/platforms" @@ -52,7 +51,7 @@ func NewLocalProvider( if err := os.MkdirAll(contentDir, 0755); err != nil { return nil, nil, errors.Wrap(err, "create local provider work directory") } - store, err := local.NewLabeledStore(contentDir, newMemoryLabelStore()) + store, err := newStore(contentDir) if err != nil { return nil, nil, errors.Wrap(err, "create local provider content store") } @@ -68,6 +67,7 @@ func NewLocalProvider( if err != nil { return nil, nil, errors.Wrap(err, "create local provider content") } + store.Init(content) return &LocalProvider{ content: content, images: make(map[string]*ocispec.Descriptor), @@ -100,7 +100,7 @@ func (pvd *LocalProvider) Pull(ctx context.Context, ref string) error { PlatformMatcher: pvd.platformMC, } - img, err := fetch(ctx, pvd.ContentStore(), rc, ref, 0, pvd.content) + img, err := fetch(ctx, pvd.ContentStore(), rc, ref, 0) if err != nil { return errors.Wrap(err, "pull source image") } diff --git a/pkg/content/ported.go b/pkg/content/ported.go index 56752af8..3b833690 100644 --- a/pkg/content/ported.go +++ b/pkg/content/ported.go @@ -42,7 +42,7 @@ var fetchSingleflight = &singleflight.Group{} // Ported from containerd project, copyright The containerd Authors. // github.com/containerd/containerd/blob/main/pull.go -func fetch(ctx context.Context, store content.Store, rCtx *containerd.RemoteContext, ref string, limit int, content *Content) (images.Image, error) { +func fetch(ctx context.Context, store content.Store, rCtx *containerd.RemoteContext, ref string, limit int) (images.Image, error) { name, desc, err := rCtx.Resolver.Resolve(ctx, ref) if err != nil { return images.Image{}, fmt.Errorf("failed to resolve reference %q: %w", ref, err) @@ -107,7 +107,7 @@ func fetch(ctx context.Context, store content.Store, rCtx *containerd.RemoteCont } handlers := append(rCtx.BaseHandlers, - fetchHandler(store, fetcher, content), + fetchHandler(store, fetcher), convertibleHandler, childrenHandler, appendDistSrcLabelHandler, @@ -147,7 +147,7 @@ func fetch(ctx context.Context, store content.Store, rCtx *containerd.RemoteCont // Ported from containerd project, copyright The containerd Authors. // https://github.com/containerd/containerd/blob/main/remotes/handlers.go -func fetchHandler(ingester content.Ingester, fetcher remotes.Fetcher, content *Content) images.HandlerFunc { +func fetchHandler(ingester content.Ingester, fetcher remotes.Fetcher) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) { ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{ "digest": desc.Digest, @@ -163,7 +163,7 @@ func fetchHandler(ingester content.Ingester, fetcher remotes.Fetcher, content *C return nil, remotes.Fetch(ctx, ingester, fetcher, desc) }) if errdefs.IsAlreadyExists(err) { - return nil, content.UpdateTime(&desc.Digest) + return nil, nil } return nil, err } diff --git a/pkg/content/store.go b/pkg/content/store.go new file mode 100644 index 00000000..fe751d50 --- /dev/null +++ b/pkg/content/store.go @@ -0,0 +1,83 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package content + +import ( + "context" + + containerdContent "github.com/containerd/containerd/content" + "github.com/containerd/containerd/content/local" + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// Store wrap the content store to complete custom feature +type Store struct { + // store is content store + store containerdContent.Store + // content is related to database + content *Content +} + +// newStore returns a content store +func newStore(contentDir string) (*Store, error) { + store, err := local.NewLabeledStore(contentDir, newMemoryLabelStore()) + return &Store{ + store: store, + }, err +} + +func (store *Store) Init(content *Content) { + store.content = content +} + +func (store *Store) Info(ctx context.Context, dgst digest.Digest) (containerdContent.Info, error) { + return store.store.Info(ctx, dgst) +} + +func (store *Store) Update(ctx context.Context, info containerdContent.Info, fieldpaths ...string) (containerdContent.Info, error) { + return store.store.Update(ctx, info, fieldpaths...) +} + +func (store *Store) Walk(ctx context.Context, fn containerdContent.WalkFunc, filters ...string) error { + return store.store.Walk(ctx, fn, filters...) +} + +func (store *Store) Delete(ctx context.Context, dgst digest.Digest) error { + return store.store.Delete(ctx, dgst) +} + +func (store *Store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (containerdContent.ReaderAt, error) { + if err := store.content.UpdateTime(&desc.Digest); err != nil { + return nil, err + } + return store.store.ReaderAt(ctx, desc) +} + +func (store *Store) Status(ctx context.Context, ref string) (containerdContent.Status, error) { + return store.store.Status(ctx, ref) +} + +func (store *Store) ListStatuses(ctx context.Context, filters ...string) ([]containerdContent.Status, error) { + return store.store.ListStatuses(ctx, filters...) +} + +func (store *Store) Abort(ctx context.Context, ref string) error { + return store.store.Abort(ctx, ref) +} + +func (store *Store) Writer(ctx context.Context, opts ...containerdContent.WriterOpt) (containerdContent.Writer, error) { + return store.store.Writer(ctx, opts...) +}