Conversation
Opening a layer's compressed reader starts a registry request even when its digest is already stored locally. Delay that request until the store has checked its existing blob so repeated pulls can reuse a verified layer without reopening its source.
| return v1.Descriptor{}, err | ||
| } | ||
| if err := s.writeBlob(ctx, v1.Descriptor{MediaType: types.OCIConfigJSON, Digest: configHash, Size: int64(len(config))}, io.NopCloser(bytes.NewReader(config))); err != nil { | ||
| if err := s.writeBlob(ctx, v1.Descriptor{MediaType: types.OCIConfigJSON, Digest: configHash, Size: int64(len(config))}, func() (io.ReadCloser, error) { |
There was a problem hiding this comment.
img.RawConfigFile() still runs before this cache check, and on a remote.Image that is a registry blob GET: remoteImage.RawConfigFile falls through to fetchBlob unless the manifest carries Config.Data. A repeated pull of an already-cached image therefore still costs one request for the config, so the layers are lazy but the config is not. Taking Digest and Size from img.Manifest().Config and moving RawConfigFile() into the closure applies the same deferral here, reasonable as a follow-up if you want to keep this change to layers.
There was a problem hiding this comment.
The config cache follow-up is in #394 . It reuses the cached config for platform checks and defers source reads until a cache miss.
There was a problem hiding this comment.
Update: The follow-up is merged right here now.
Platform selection reads the config before publication, so deferring only the config write still issues a blob GET on every pull. Use verified cached config bytes for platform checks and defer source reads during publication until the manifest descriptor misses the cache. Exercise repeated pulls against a local registry with config downloads disabled. Keep platform mismatches and corrupt cached blobs rejected.
A declared index with a matching platform must reject a mismatched config. Accepting the platformless index's no-match error can hide a fallthrough that skips that rejection. Require each mode's expected error for both cached and uncached configs.
Repeated pulls open layer sources before checking the local blob cache and fetch the config during platform selection even when it is cached. Reuse verified layers and config blobs before opening their sources, including the config read used for platform checks.
Cached blobs still undergo digest and size verification. Platform mismatches and corrupt cached configs remain errors; missing blobs still require their sources. Pulls still fetch manifests from the registry.
Local tests cover cached layers with unavailable sources and full pulls of single images and indexes with and without declared platforms. A cold pull makes one config GET; a repeated pull makes none even when that endpoint is configured to return 404. Platform mismatch tests require the expected error for each selection path.
Validation on macOS arm64 with Go 1.25.3:
make oci-lint(formatting and Darwin/Linux vet)GOFLAGS=-count=1 make oci-test(race tests with local fixtures)make elfuse-ociand./build/elfuse-oci --helpgit diff --check origin/mainSupersedes #394.