Summary
In pkg/backend/push.go, blob content is opened with src.PullBlob(...) and then passed to dst.Blobs().Push(...) as io.NopCloser(reader).
This prevents the original io.ReadCloser from being closed. After the upload starts reading, the underlying distribution file reader may keep its file descriptor open until process exit.
Impact
Pushing many blobs can accumulate open file descriptors and may eventually hit the OS limit.
Why this happens
PullBlob() returns an io.ReadCloser
pb.Add(...) wraps it for progress reporting
io.NopCloser(...) replaces the real Close() with a no-op
- the original blob reader is never explicitly closed
Suggested fix
Close the original content returned by PullBlob() in pushIfNotExist(), for example with:
defer func() { _ = content.Close() }()