From a763b1c866fea4a3c82828fe7312f0c7fb69ac9f Mon Sep 17 00:00:00 2001 From: Francis Laniel Date: Tue, 21 Nov 2023 19:03:09 +0100 Subject: [PATCH] Add Untag() to oci.Store. Signed-off-by: Francis Laniel --- content/oci/oci.go | 27 +++++++++++++++++++++++++++ content/oci/oci_test.go | 27 +++++++++++++++++++++++++++ content/resolver.go | 6 ++++++ 3 files changed, 60 insertions(+) diff --git a/content/oci/oci.go b/content/oci/oci.go index 5d4699a1f..94201946a 100644 --- a/content/oci/oci.go +++ b/content/oci/oci.go @@ -238,6 +238,33 @@ func (s *Store) Resolve(ctx context.Context, reference string) (ocispec.Descript return desc, nil } +func (s *Store) Untag(ctx context.Context, reference string) error { + s.sync.RLock() + defer s.sync.RUnlock() + + if reference == "" { + return errdef.ErrMissingReference + } + + desc, err := s.tagResolver.Resolve(ctx, reference) + if err != nil { + return fmt.Errorf("reference %q does not point to a descriptor: %w", reference, err) + } + if reference == desc.Digest.String() { + return fmt.Errorf("reference %q is a digest and not a tag", reference) + } + + return s.untag(reference) +} + +func (s *Store) untag(reference string) error { + s.tagResolver.Untag(reference) + if s.AutoSaveIndex { + return s.saveIndex() + } + return nil +} + // Predecessors returns the nodes directly pointing to the current node. // Predecessors returns nil without error if the node does not exists in the // store. diff --git a/content/oci/oci_test.go b/content/oci/oci_test.go index 01028b1a4..8f83ba058 100644 --- a/content/oci/oci_test.go +++ b/content/oci/oci_test.go @@ -204,6 +204,15 @@ func TestStore_Success(t *testing.T) { if !bytes.Equal(got, manifest) { t.Errorf("Store.Fetch() = %v, want %v", got, manifest) } + + // test untag + err = s.Untag(ctx, ref) + if err != nil { + t.Fatal("Store.Untag() error =", err) + } + if got, want := len(internalResolver.Map()), 1; got != want { + t.Errorf("resolver.Map() = %v, want %v", got, want) + } } func TestStore_RelativeRoot_Success(t *testing.T) { @@ -333,6 +342,15 @@ func TestStore_RelativeRoot_Success(t *testing.T) { if !bytes.Equal(got, manifest) { t.Errorf("Store.Fetch() = %v, want %v", got, manifest) } + + // test untag + err = s.Untag(ctx, ref) + if err != nil { + t.Fatal("Store.Untag() error =", err) + } + if got, want := len(internalResolver.Map()), 1; got != want { + t.Errorf("resolver.Map() = %v, want %v", got, want) + } } func TestStore_NotExistingRoot(t *testing.T) { @@ -654,6 +672,15 @@ func TestStore_DisableAutoSaveIndex(t *testing.T) { if _, err := os.Stat(s.indexPath); err != nil { t.Errorf("error: %s does not exist", s.indexPath) } + + // test untag + err = s.Untag(ctx, ref) + if err != nil { + t.Fatal("Store.Untag() error =", err) + } + if got, want := len(internalResolver.Map()), 1; got != want { + t.Errorf("resolver.Map() = %v, want %v", got, want) + } } func TestStore_RepeatTag(t *testing.T) { diff --git a/content/resolver.go b/content/resolver.go index b536b5ddc..fafaa24fb 100644 --- a/content/resolver.go +++ b/content/resolver.go @@ -39,3 +39,9 @@ type TagResolver interface { Tagger Resolver } + +// Untagger untags reference tags. +type Untagger interface { + // Untag untags the given reference string. + Untag(ctx context.Context, reference string) error +} \ No newline at end of file