1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ocidebug
18
19 import (
20 "context"
21 "fmt"
22 "io"
23 "log"
24 "sync/atomic"
25
26 "cuelabs.dev/go/oci/ociregistry"
27 )
28
29 func New(r ociregistry.Interface, logf func(f string, a ...any)) ociregistry.Interface {
30 if logf == nil {
31 logf = log.Printf
32 }
33 return &logger{
34 logf: logf,
35 r: r,
36 }
37 }
38
39 var blobWriterID int32
40
41 type logger struct {
42 logf func(f string, a ...any)
43 r ociregistry.Interface
44 *ociregistry.Funcs
45 }
46
47 func (r *logger) DeleteBlob(ctx context.Context, repoName string, digest ociregistry.Digest) error {
48 r.logf("DeleteBlob %s %s {", repoName, digest)
49 err := r.r.DeleteBlob(ctx, repoName, digest)
50 r.logf("} -> %v", err)
51 return err
52 }
53
54 func (r *logger) DeleteManifest(ctx context.Context, repoName string, digest ociregistry.Digest) error {
55 r.logf("DeleteManifest %s %s {", repoName, digest)
56 err := r.r.DeleteManifest(ctx, repoName, digest)
57 r.logf("} -> %v", err)
58 return err
59 }
60
61 func (r *logger) DeleteTag(ctx context.Context, repoName string, tagName string) error {
62 r.logf("DeleteTag %s %s {", repoName, tagName)
63 err := r.r.DeleteTag(ctx, repoName, tagName)
64 r.logf("} -> %v", err)
65 return err
66 }
67
68 func (r *logger) GetBlob(ctx context.Context, repoName string, dig ociregistry.Digest) (ociregistry.BlobReader, error) {
69 r.logf("GetBlob %s %s {", repoName, dig)
70 rd, err := r.r.GetBlob(ctx, repoName, dig)
71 r.logf("} -> %T, %v", rd, err)
72 return rd, err
73 }
74
75 func (r *logger) GetBlobRange(ctx context.Context, repoName string, dig ociregistry.Digest, o0, o1 int64) (ociregistry.BlobReader, error) {
76 r.logf("GetBlob %s %s [%d, %d] {", repoName, dig, o0, o1)
77 rd, err := r.r.GetBlobRange(ctx, repoName, dig, o0, o1)
78 r.logf("} -> %T, %v", rd, err)
79 return rd, err
80 }
81
82 func (r *logger) GetManifest(ctx context.Context, repoName string, dig ociregistry.Digest) (ociregistry.BlobReader, error) {
83 r.logf("GetManifest %s %s {", repoName, dig)
84 rd, err := r.r.GetManifest(ctx, repoName, dig)
85 r.logf("} -> %T, %v", rd, err)
86 return rd, err
87 }
88
89 func (r *logger) GetTag(ctx context.Context, repoName string, tagName string) (ociregistry.BlobReader, error) {
90 r.logf("GetTag %s %s {", repoName, tagName)
91 rd, err := r.r.GetTag(ctx, repoName, tagName)
92 r.logf("} -> %T, %v", rd, err)
93 return rd, err
94 }
95
96 func (r *logger) MountBlob(ctx context.Context, fromRepo, toRepo string, dig ociregistry.Digest) (ociregistry.Descriptor, error) {
97 r.logf("MountBlob from=%s to=%s digest=%s {", fromRepo, toRepo, dig)
98 desc, err := r.r.MountBlob(ctx, fromRepo, toRepo, dig)
99 r.logf("} -> %#v, %v", desc, err)
100 return desc, err
101 }
102
103 func (r *logger) PushBlob(ctx context.Context, repoName string, desc ociregistry.Descriptor, content io.Reader) (ociregistry.Descriptor, error) {
104 r.logf("PushBlob %s %#v %T {", repoName, desc, content)
105 desc, err := r.r.PushBlob(ctx, repoName, desc, content)
106 if err != nil {
107 r.logf("} -> %v", err)
108 } else {
109 r.logf("} -> %#v", desc)
110 }
111 return desc, err
112 }
113
114 func (r *logger) PushBlobChunked(ctx context.Context, repoName string, chunkSize int) (ociregistry.BlobWriter, error) {
115 bwid := fmt.Sprintf("bw%d", atomic.AddInt32(&blobWriterID, 1))
116 r.logf("PushBlobChunked %s chunkSize=%d {", repoName, chunkSize)
117 w, err := r.r.PushBlobChunked(ctx, repoName, chunkSize)
118 r.logf("} -> %T(%s), %v", w, bwid, err)
119 return blobWriter{
120 id: bwid,
121 w: w,
122 r: r,
123 }, err
124 }
125
126 func (r *logger) PushBlobChunkedResume(ctx context.Context, repoName, id string, offset int64, chunkSize int) (ociregistry.BlobWriter, error) {
127 bwid := fmt.Sprintf("bw%d", atomic.AddInt32(&blobWriterID, 1))
128 r.logf("PushBlobChunkedResume %s id=%q offset=%d chunkSize=%d {", repoName, id, offset, chunkSize)
129 w, err := r.r.PushBlobChunkedResume(ctx, repoName, id, offset, chunkSize)
130 r.logf("} -> %T(%s), %v", w, bwid, err)
131 return blobWriter{
132 id: bwid,
133 w: w,
134 r: r,
135 }, err
136 }
137
138 func (r *logger) PushManifest(ctx context.Context, repoName string, tag string, data []byte, mediaType string) (ociregistry.Descriptor, error) {
139 r.logf("PushManifest %s tag=%q mediaType=%q data=%q {", repoName, tag, mediaType, data)
140 desc, err := r.r.PushManifest(ctx, repoName, tag, data, mediaType)
141 if err != nil {
142 r.logf("} -> %v", err)
143 } else {
144 r.logf("} -> %#v", desc)
145 }
146 return desc, err
147 }
148
149 func (r *logger) Referrers(ctx context.Context, repoName string, digest ociregistry.Digest, artifactType string) ociregistry.Seq[ociregistry.Descriptor] {
150 return logIterReturn(
151 r,
152 fmt.Sprintf("Referrers %s %s %q", repoName, digest, artifactType),
153 r.r.Referrers(ctx, repoName, digest, artifactType),
154 )
155 }
156
157 func (r *logger) Repositories(ctx context.Context, startAfter string) ociregistry.Seq[string] {
158 return logIterReturn(
159 r,
160 fmt.Sprintf("Repositories startAfter: %q", startAfter),
161 r.r.Repositories(ctx, startAfter),
162 )
163 }
164
165 func (r *logger) Tags(ctx context.Context, repoName string, startAfter string) ociregistry.Seq[string] {
166 return logIterReturn(
167 r,
168 fmt.Sprintf("Tags %s startAfter: %q", repoName, startAfter),
169 r.r.Tags(ctx, repoName, startAfter),
170 )
171 }
172
173 func (r *logger) ResolveBlob(ctx context.Context, repoName string, digest ociregistry.Digest) (ociregistry.Descriptor, error) {
174 r.logf("ResolveBlob %s %s {", repoName, digest)
175 desc, err := r.r.ResolveBlob(ctx, repoName, digest)
176 if err != nil {
177 r.logf("} -> %v", err)
178 } else {
179 r.logf("} -> %#v", desc)
180 }
181 return desc, err
182 }
183
184 func (r *logger) ResolveManifest(ctx context.Context, repoName string, digest ociregistry.Digest) (ociregistry.Descriptor, error) {
185 r.logf("ResolveManifest %s %s {", repoName, digest)
186 desc, err := r.r.ResolveManifest(ctx, repoName, digest)
187 if err != nil {
188 r.logf("} -> %v", err)
189 } else {
190 r.logf("} -> %#v", desc)
191 }
192 return desc, err
193 }
194
195 func (r *logger) ResolveTag(ctx context.Context, repoName string, tagName string) (ociregistry.Descriptor, error) {
196 r.logf("ResolveTag %s %s {", repoName, tagName)
197 desc, err := r.r.ResolveTag(ctx, repoName, tagName)
198 if err != nil {
199 r.logf("} -> %v", err)
200 } else {
201 r.logf("} -> %#v", desc)
202 }
203 return desc, err
204 }
205
206 type blobWriter struct {
207 id string
208 r *logger
209 w ociregistry.BlobWriter
210 }
211
212 func (w blobWriter) logf(f string, a ...any) {
213 w.r.logf("%s: %s", w.id, fmt.Sprintf(f, a...))
214 }
215
216 func (w blobWriter) Write(buf []byte) (int, error) {
217 w.logf("Write %q {", buf)
218 n, err := w.w.Write(buf)
219 w.logf("} -> %v, %v", n, err)
220 return n, err
221 }
222
223 func (w blobWriter) ID() string {
224 return w.w.ID()
225 }
226
227 func (w blobWriter) Size() int64 {
228 size := w.w.Size()
229 w.logf("Size -> %v", size)
230 return size
231 }
232
233 func (w blobWriter) ChunkSize() int {
234 chunkSize := w.w.ChunkSize()
235 w.logf("ChunkSize -> %v", chunkSize)
236 return chunkSize
237 }
238
239 func (w blobWriter) Close() error {
240 w.logf("Close {")
241 err := w.w.Close()
242 w.logf("} -> %v", err)
243 return err
244 }
245
246 func (w blobWriter) Commit(digest ociregistry.Digest) (ociregistry.Descriptor, error) {
247 w.logf("Commit %q {", digest)
248 desc, err := w.w.Commit(digest)
249 w.logf("} -> %#v, %v", desc, err)
250 return desc, err
251 }
252
253 func (w blobWriter) Cancel() error {
254 w.logf("Cancel {")
255 err := w.w.Cancel()
256 w.logf("} -> %v", err)
257 return err
258 }
259
260 func logIterReturn[T any](r *logger, initialMsg string, it ociregistry.Seq[T]) ociregistry.Seq[T] {
261 return func(yield func(T, error) bool) {
262 r.logf("%s {", initialMsg)
263 items := []T{}
264 var _err error
265 it(func(item T, err error) bool {
266 if err != nil {
267 yield(*new(T), err)
268 _err = err
269 return false
270 }
271 ok := yield(item, err)
272 if ok {
273 items = append(items, item)
274 }
275 return ok
276 })
277 if _err != nil {
278 if len(items) > 0 {
279 r.logf("} -> %#v, %v", items, _err)
280 } else {
281 r.logf("} -> %v", _err)
282 }
283 } else {
284 r.logf("} -> %#v", items)
285 }
286 }
287 }
288
View as plain text