Skip to content

Commit 1a35003

Browse files
authored
Merge pull request moby#5511 from tonistiigi/sbom-release-fix
fix leaving unreleased references behind after SBOM generation
2 parents 972e31a + 6211e77 commit 1a35003

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

client/client_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9879,6 +9879,8 @@ func testSBOMSupplements(t *testing.T, sb integration.Sandbox) {
98799879
require.Regexp(t, "^layerID: sha256:", attest.Predicate.Files[0].FileComment)
98809880
require.Equal(t, "/bar", attest.Predicate.Files[1].FileName)
98819881
require.Empty(t, attest.Predicate.Files[1].FileComment)
9882+
9883+
checkAllReleasable(t, c, sb, false)
98829884
}
98839885

98849886
func testMultipleCacheExports(t *testing.T, sb integration.Sandbox) {

exporter/containerimage/attestations.go

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io/fs"
88
"path/filepath"
9+
"slices"
910
"strings"
1011

1112
intoto "github.com/in-toto/in-toto-golang/in_toto"
@@ -63,6 +64,7 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable
6364
if err != nil {
6465
return att, err
6566
}
67+
defer layers.release(context.WithoutCancel(ctx))
6668
modifyFile := func(f *spdx.File) error {
6769
if f == nil {
6870
// Skip over nil entries - this is likely a bug in the SPDX parser,
@@ -77,7 +79,7 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable
7779
return nil
7880
}
7981

80-
_, desc, err := layers.find(ctx, s, f.FileName)
82+
desc, err := layers.find(ctx, s, f.FileName)
8183
if err != nil {
8284
if !errors.Is(err, fs.ErrNotExist) {
8385
return err
@@ -144,13 +146,9 @@ func encodeSPDX(s *spdx.Document) (dt []byte, err error) {
144146
// fileLayerFinder finds the layer that contains a file, with caching to avoid
145147
// repeated FileList lookups.
146148
type fileLayerFinder struct {
147-
pending []fileLayerEntry
148-
cache map[string]fileLayerEntry
149-
}
150-
151-
type fileLayerEntry struct {
152-
ref cache.ImmutableRef
153-
desc ocispecs.Descriptor
149+
refs []cache.ImmutableRef
150+
pending []ocispecs.Descriptor
151+
cache map[string]ocispecs.Descriptor
154152
}
155153

156154
func newFileLayerFinder(target cache.ImmutableRef, remote *solver.Remote) (fileLayerFinder, error) {
@@ -159,14 +157,10 @@ func newFileLayerFinder(target cache.ImmutableRef, remote *solver.Remote) (fileL
159157
if len(chain) != len(descs) {
160158
return fileLayerFinder{}, errors.New("layer chain and descriptor list are not the same length")
161159
}
162-
163-
pending := make([]fileLayerEntry, len(chain))
164-
for i, ref := range chain {
165-
pending[i] = fileLayerEntry{ref: ref, desc: descs[i]}
166-
}
167160
return fileLayerFinder{
168-
pending: pending,
169-
cache: map[string]fileLayerEntry{},
161+
pending: slices.Clone(descs),
162+
refs: chain,
163+
cache: map[string]ocispecs.Descriptor{},
170164
}, nil
171165
}
172166

@@ -175,20 +169,21 @@ func newFileLayerFinder(target cache.ImmutableRef, remote *solver.Remote) (fileL
175169
// the layer that created the file, not the one that deleted it.
176170
//
177171
// find is not concurrency-safe.
178-
func (c *fileLayerFinder) find(ctx context.Context, s session.Group, filename string) (cache.ImmutableRef, *ocispecs.Descriptor, error) {
172+
func (c *fileLayerFinder) find(ctx context.Context, s session.Group, filename string) (*ocispecs.Descriptor, error) {
179173
filename = filepath.Join("/", filename)
180174

181175
// return immediately if we've already found the layer containing filename
182176
if cache, ok := c.cache[filename]; ok {
183-
return cache.ref, &cache.desc, nil
177+
return &cache, nil
184178
}
185179

186180
for len(c.pending) > 0 {
187181
// pop the last entry off the pending list (we traverse the layers backwards)
188-
pending := c.pending[len(c.pending)-1]
189-
files, err := pending.ref.FileList(ctx, s)
182+
idx := len(c.pending) - 1
183+
pending := c.pending[idx]
184+
files, err := c.refs[idx].FileList(ctx, s)
190185
if err != nil {
191-
return nil, nil, err
186+
return nil, err
192187
}
193188
c.pending = c.pending[:len(c.pending)-1]
194189

@@ -213,8 +208,18 @@ func (c *fileLayerFinder) find(ctx context.Context, s session.Group, filename st
213208
}
214209
}
215210
if found {
216-
return pending.ref, &pending.desc, nil
211+
return &pending, nil
212+
}
213+
}
214+
return nil, fs.ErrNotExist
215+
}
216+
217+
func (c *fileLayerFinder) release(ctx context.Context) error {
218+
var err error
219+
for _, ref := range c.refs {
220+
if err1 := ref.Release(ctx); err1 != nil && err == nil {
221+
err = err1
217222
}
218223
}
219-
return nil, nil, fs.ErrNotExist
224+
return err
220225
}

0 commit comments

Comments
 (0)