...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ocifilter
18
19 import (
20 "context"
21 "fmt"
22
23 "cuelabs.dev/go/oci/ociregistry"
24 "github.com/opencontainers/go-digest"
25 )
26
27
28
29
30 func Immutable(r ociregistry.Interface) ociregistry.Interface {
31 return immutable{r}
32 }
33
34 type immutable struct {
35 ociregistry.Interface
36 }
37
38 func (r immutable) PushManifest(ctx context.Context, repo string, tag string, contents []byte, mediaType string) (ociregistry.Descriptor, error) {
39 if tag == "" {
40 return r.Interface.PushManifest(ctx, repo, tag, contents, mediaType)
41 }
42 dig := digest.FromBytes(contents)
43
44 if desc, err := r.ResolveTag(ctx, repo, tag); err == nil {
45 if desc.Digest == dig {
46
47 return desc, nil
48 }
49 return ociregistry.Descriptor{}, fmt.Errorf("this store is immutable: %w", ociregistry.ErrDenied)
50 }
51 desc, err := r.Interface.PushManifest(ctx, repo, tag, contents, mediaType)
52 if err != nil {
53 return ociregistry.Descriptor{}, err
54 }
55
56
57
58 desc, err = r.ResolveTag(ctx, repo, tag)
59 if err != nil {
60 return ociregistry.Descriptor{}, fmt.Errorf("cannot resolve tag that's just been pushed: %v", err)
61 }
62 if desc.Digest != dig {
63
64 return ociregistry.Descriptor{}, fmt.Errorf("this store is immutable: %w", ociregistry.ErrDenied)
65 }
66 return desc, nil
67 }
68
69 func (r immutable) DeleteBlob(ctx context.Context, repo string, digest ociregistry.Digest) error {
70 return ociregistry.ErrDenied
71 }
72
73 func (r immutable) DeleteManifest(ctx context.Context, repo string, digest ociregistry.Digest) error {
74 return ociregistry.ErrDenied
75 }
76
77 func (r immutable) DeleteTag(ctx context.Context, repo string, name string) error {
78 return ociregistry.ErrDenied
79 }
80
View as plain text