Skip to content

Commit 8cdd62c

Browse files
authored
Merge pull request #3217 from robnester-rh/EC-1706
EC-1706: Remove filesystem image layer cache
2 parents d16e3a0 + ad6f61e commit 8cdd62c

6 files changed

Lines changed: 28 additions & 113 deletions

File tree

benchmark/simple/simple.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,6 @@ func ec(dir string) func() {
9797
}`, dir)
9898

9999
return func() {
100-
101-
os.Setenv("EC_CACHE", "false")
102-
103100
if err := suite.Execute([]string{
104101
"validate",
105102
"image",

internal/utils/oci/client.go

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,11 @@ import (
2020
"context"
2121
"fmt"
2222
"net/http"
23-
"os"
24-
"path"
2523
"runtime/trace"
26-
"strconv"
27-
"sync"
2824

2925
"github.com/google/go-containerregistry/pkg/authn"
3026
"github.com/google/go-containerregistry/pkg/name"
3127
v1 "github.com/google/go-containerregistry/pkg/v1"
32-
"github.com/google/go-containerregistry/pkg/v1/cache"
3328
"github.com/google/go-containerregistry/pkg/v1/remote"
3429
"github.com/sigstore/cosign/v3/pkg/cosign"
3530
"github.com/sigstore/cosign/v3/pkg/oci"
@@ -43,28 +38,6 @@ type contextKey string
4338

4439
const clientContextKey contextKey = "ec.oci.client"
4540

46-
var imgCache = sync.OnceValue(initCache)
47-
48-
func initCache() cache.Cache {
49-
// if a value was set and it is parsed as false, turn the cache off
50-
if v, err := strconv.ParseBool(os.Getenv("EC_CACHE")); err == nil && !v {
51-
return nil
52-
}
53-
54-
if userCache, err := os.UserCacheDir(); err != nil {
55-
log.Debug("unable to find user cache directory")
56-
return nil
57-
} else {
58-
imgCacheDir := path.Join(userCache, "ec", "images")
59-
if err := os.MkdirAll(imgCacheDir, 0700); err != nil {
60-
log.Debugf("unable to create temporary directory for image cache in %q: %v", imgCacheDir, err)
61-
return nil
62-
}
63-
log.Debugf("using %q directory to store image cache", imgCacheDir)
64-
return cache.NewFilesystemCache(imgCacheDir)
65-
}
66-
}
67-
6841
func CreateRemoteOptions(ctx context.Context) []remote.Option {
6942
backoff := remote.Backoff{
7043
Duration: echttp.DefaultBackoff.Duration,
@@ -217,16 +190,7 @@ func (c *defaultClient) Image(ref name.Reference) (v1.Image, error) {
217190
trace.Logf(c.ctx, "", "image=%q", ref)
218191
}
219192

220-
img, err := remote.Image(ref, c.opts...)
221-
if err != nil {
222-
return nil, err
223-
}
224-
225-
if c := imgCache(); c != nil {
226-
img = cache.Image(img, c)
227-
}
228-
229-
return img, nil
193+
return remote.Image(ref, c.opts...)
230194
}
231195

232196
func (c *defaultClient) Layer(ref name.Digest) (v1.Layer, error) {
@@ -236,8 +200,6 @@ func (c *defaultClient) Layer(ref name.Digest) (v1.Layer, error) {
236200
trace.Logf(c.ctx, "", "image=%q", ref)
237201
}
238202

239-
// TODO: Caching a layer directly is difficult and may not be possible, see:
240-
// https://github.com/google/go-containerregistry/issues/1821
241203
layer, err := remote.Layer(ref, c.opts...)
242204
if err != nil {
243205
return nil, fmt.Errorf("fetching layer: %w", err)

internal/utils/oci/client_test.go

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,19 @@
1919
package oci
2020

2121
import (
22-
"bytes"
2322
"context"
2423
"fmt"
2524
"io"
2625
"log"
2726
"net/http"
2827
"net/http/httptest"
2928
"net/url"
30-
"strings"
3129
"testing"
3230

3331
"github.com/google/go-containerregistry/pkg/authn"
3432
"github.com/google/go-containerregistry/pkg/name"
3533
"github.com/google/go-containerregistry/pkg/registry"
34+
v1 "github.com/google/go-containerregistry/pkg/v1"
3635
"github.com/google/go-containerregistry/pkg/v1/random"
3736
"github.com/google/go-containerregistry/pkg/v1/remote"
3837
"github.com/google/go-containerregistry/pkg/v1/types"
@@ -101,25 +100,21 @@ func TestCreateRemoteOptions(t *testing.T) {
101100
}
102101
}
103102

104-
func TestCacheInit(t *testing.T) {
105-
// by default the cache should be on
106-
assert.NotNil(t, initCache())
107-
108-
t.Setenv("EC_CACHE", "false")
109-
assert.Nil(t, initCache())
110-
111-
t.Cleanup(func() {
112-
t.Setenv("EC_CACHE", "true")
113-
assert.NotNil(t, initCache())
114-
})
103+
func readAndVerifyLayer(t *testing.T, l v1.Layer) {
104+
t.Helper()
105+
r, err := l.Uncompressed()
106+
require.NoError(t, err)
107+
defer r.Close()
108+
_, err = io.ReadAll(r)
109+
require.NoError(t, err)
115110
}
116111

117112
func TestImage(t *testing.T) {
118-
img, err := random.Image(4096, 2)
113+
const numLayers = 2
114+
img, err := random.Image(4096, numLayers)
119115
require.NoError(t, err)
120116

121-
l := &bytes.Buffer{}
122-
registry := httptest.NewServer(registry.New(registry.Logger(log.New(l, "", 0))))
117+
registry := httptest.NewServer(registry.New(registry.Logger(log.New(io.Discard, "", 0))))
123118
t.Cleanup(registry.Close)
124119

125120
u, err := url.Parse(registry.URL)
@@ -130,35 +125,24 @@ func TestImage(t *testing.T) {
130125

131126
require.NoError(t, remote.Push(ref, img))
132127

133-
fetchFully := func() {
134-
client := defaultClient{}
135-
136-
img, err := client.Image(ref)
137-
require.NoError(t, err)
138-
layers, err := img.Layers()
139-
require.NoError(t, err)
140-
for _, l := range layers {
141-
r, err := l.Uncompressed()
142-
require.NoError(t, err)
143-
_, err = io.ReadAll(r)
144-
require.NoError(t, err)
145-
}
146-
}
128+
client := defaultClient{ctx: context.Background()}
129+
fetched, err := client.Image(ref)
130+
require.NoError(t, err)
147131

148-
fetchFully()
149-
fetchFully()
150-
fetchFully()
132+
layers, err := fetched.Layers()
133+
require.NoError(t, err)
134+
assert.Len(t, layers, numLayers)
151135

152-
blobDownloadCount := strings.Count(l.String(), "GET /v2/repository/image/blobs/sha256:")
153-
assert.Equal(t, 5, blobDownloadCount) // three configs fetched each time and two layers fetched only once
136+
for _, l := range layers {
137+
readAndVerifyLayer(t, l)
138+
}
154139
}
155140

156141
func TestLayer(t *testing.T) {
157142
layer, err := random.Layer(1024, types.OCIUncompressedLayer)
158143
require.NoError(t, err)
159144

160-
l := &bytes.Buffer{}
161-
registry := httptest.NewServer(registry.New(registry.Logger(log.New(l, "", 0))))
145+
registry := httptest.NewServer(registry.New(registry.Logger(log.New(io.Discard, "", 0))))
162146
t.Cleanup(registry.Close)
163147

164148
u, err := url.Parse(registry.URL)
@@ -174,24 +158,14 @@ func TestLayer(t *testing.T) {
174158
require.NoError(t, err)
175159
layerURI := fmt.Sprintf("%s@%s", uri, digest)
176160

177-
fetchCount := 5
178-
for i := 0; i < fetchCount; i++ {
179-
d, err := name.NewDigest(layerURI)
180-
require.NoError(t, err)
181-
182-
client := defaultClient{}
183-
l, err := client.Layer(d)
161+
d, err := name.NewDigest(layerURI)
162+
require.NoError(t, err)
184163

185-
require.NoError(t, err)
186-
r, err := l.Uncompressed()
187-
require.NoError(t, err)
188-
_, err = io.ReadAll(r)
189-
require.NoError(t, err)
190-
}
164+
client := defaultClient{ctx: context.Background()}
165+
fetched, err := client.Layer(d)
166+
require.NoError(t, err)
191167

192-
msg := fmt.Sprintf("GET /v2/repository/image/blobs/%s", digest)
193-
blobDownloadCount := strings.Count(l.String(), msg)
194-
assert.Equal(t, fetchCount, blobDownloadCount)
168+
readAndVerifyLayer(t, fetched)
195169
}
196170

197171
func TestScopedAuth(t *testing.T) {

tasks/verify-conforma-konflux-ta/0.1/verify-conforma-konflux-ta.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,6 @@ spec:
505505
# value expected by Tekton Pipelines. NOTE: If params.SSL_CERT_DIR is empty, the value
506506
# will contain a trailing ":" - this is ok.
507507
value: "/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts:$(params.SSL_CERT_DIR)"
508-
# The EC cache is used to avoid fetching the same image layers from the registry more than
509-
# once. However, this is not thread safe. This results in inconsistencies when extracting
510-
# files from an image, see https://github.com/conforma/cli/issues/1109
511-
- name: EC_CACHE
512-
value: "false"
513508
computeResources:
514509
requests:
515510
cpu: 250m

tasks/verify-conforma-konflux-vsa-ta/0.1/verify-conforma-konflux-vsa-ta.yaml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,6 @@ spec:
290290
- name: SSL_CERT_DIR
291291
value: >-
292292
/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts:$(params.SSL_CERT_DIR)
293-
- name: EC_CACHE
294-
value: "false"
295293
computeResources:
296294
requests:
297295
cpu: 100m
@@ -371,12 +369,6 @@ spec:
371369
# trailing ":" - this is ok.
372370
value: >-
373371
/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts:$(params.SSL_CERT_DIR)
374-
# The EC cache is used to avoid fetching the same image layers
375-
# from the registry more than once. However, this is not thread
376-
# safe. This results in inconsistencies when extracting files from
377-
# an image, see https://github.com/conforma/cli/issues/1109
378-
- name: EC_CACHE
379-
value: "false"
380372
computeResources:
381373
requests:
382374
cpu: 100m

tasks/verify-enterprise-contract/0.1/verify-enterprise-contract.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,6 @@ spec:
396396
# value expected by Tekton Pipelines. NOTE: If params.SSL_CERT_DIR is empty, the value
397397
# will contain a trailing ":" - this is ok.
398398
value: "/tekton-custom-certs:/etc/ssl/certs:/etc/pki/tls/certs:/system/etc/security/cacerts:$(params.SSL_CERT_DIR)"
399-
# The EC cache is used to avoid fetching the same image layers from the registry more than
400-
# once. However, this is not thread safe. This results in inconsistencies when extracting
401-
# files from an image, see https://github.com/conforma/cli/issues/1109
402-
- name: EC_CACHE
403-
value: "false"
404399
computeResources:
405400
requests:
406401
cpu: 1800m

0 commit comments

Comments
 (0)