Skip to content

Commit dc0dd05

Browse files
Mab879crozzy
andcommitted
scan: improve functionality with locally saved images
Previously the locally saved image flow was at best confusing and at worst just wrong for some cases. This change simplified the handling of local images and reduces resources that were previously allocated for no good reason. Tests were also added to verify both docker and podman saved images work as expected. The application now expects all saved images to follow the OCI spec https://github.com/opencontainers/image-spec/blob/v1.1.1/image-layout.md This code was backported by Claude Code. Co-authored-by: crozzy <joseph.crosland@gmail.com>
1 parent 9c594f9 commit dc0dd05

10 files changed

Lines changed: 495 additions & 376 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
/feeds
44
/reports
55
/vendor
6-
/cvetool
6+
/cvetool
7+
*db*
8+
*.patch

cmd/cvetool/scan.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313
"time"
1414

15+
"github.com/quay/claircore"
1516
"github.com/quay/claircore/enricher/cvss"
1617
"github.com/quay/claircore/indexer"
1718
"github.com/quay/claircore/libindex"
@@ -127,8 +128,8 @@ func scan(c *cli.Context) error {
127128
)
128129

129130
var (
130-
img image.Image
131-
fa indexer.FetchArena
131+
mf *claircore.Manifest
132+
fa indexer.FetchArena
132133
)
133134
switch {
134135
case imgRef != "":
@@ -138,24 +139,32 @@ func scan(c *cli.Context) error {
138139
if err != nil {
139140
return fmt.Errorf("error setting DOCKER_CONFIG env var")
140141
}
141-
img = image.NewDockerRemoteImage(ctx, imgRef)
142+
mf, err = image.ManifestFromRemote(ctx, imgRef)
143+
if err != nil {
144+
return fmt.Errorf("error getting image information: %v", err)
145+
}
142146
case imgPath != "":
143147
fa = &LocalFetchArena{}
144148
var err error
145-
img, err = image.NewDockerLocalImage(ctx, imgPath, os.TempDir())
149+
mf, err = image.ManifestFromLocal(ctx, imgPath, os.TempDir())
146150
if err != nil {
147151
return fmt.Errorf("error getting image information: %v", err)
148152
}
149153
case rootPath != "":
150154
fa = &LocalFetchArena{}
151155
var err error
152-
img, err = image.NewFileSystemImage(ctx, rootPath)
156+
mf, err = image.ManifestFromFilesystem(ctx, rootPath)
153157
if err != nil {
154158
return fmt.Errorf("error getting filesystem information: %v", err)
155159
}
156160
default:
157161
return fmt.Errorf("no --image-path ($IMAGE_PATH), --image-ref ($IMAGE_REF) or --root-path ($ROOT_PATH) set")
158162
}
163+
defer func() {
164+
for _, l := range mf.Layers {
165+
l.Close()
166+
}
167+
}()
159168

160169
switch {
161170
case dbPath != "":
@@ -204,11 +213,6 @@ func scan(c *cli.Context) error {
204213
return fmt.Errorf("error creating Libvuln: %v", err)
205214
}
206215

207-
mf, err := img.GetManifest(ctx)
208-
if err != nil {
209-
return fmt.Errorf("error creating manifest: %v", err)
210-
}
211-
212216
indexerOpts := &libindex.Options{
213217
Store: datastore.NewLocalIndexerStore(),
214218
Locker: NewLocalLockSource(),

image/docker.go

Lines changed: 0 additions & 172 deletions
This file was deleted.

image/docker_test.go

Lines changed: 0 additions & 28 deletions
This file was deleted.

image/filesystem.go

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,27 @@ import (
88
"github.com/quay/claircore"
99
)
1010

11-
type fileSystemImage struct {
12-
imageDigest string
13-
layerPaths []string
14-
rootDir string
15-
}
16-
17-
func NewFileSystemImage(ctx context.Context, rootDir string) (*fileSystemImage, error) {
18-
fsi := &fileSystemImage{}
19-
fsi.rootDir = rootDir
20-
return fsi, nil
21-
}
22-
23-
func (i *fileSystemImage) getLayers(ctx context.Context) ([]*claircore.Layer, error) {
24-
layers := []*claircore.Layer{}
11+
func ManifestFromFilesystem(ctx context.Context, rootDir string) (*claircore.Manifest, error) {
12+
digest, err := claircore.ParseDigest(fmt.Sprintf("sha256:%s", strings.Repeat("0", 64)))
13+
if err != nil {
14+
return nil, err
15+
}
2516

2617
desc := &claircore.LayerDescription{
2718
Digest: fmt.Sprintf("sha256:%s", strings.Repeat("1", 64)),
28-
URI: "file://" + i.rootDir,
19+
URI: "file://" + rootDir,
2920
MediaType: "application/vnd.claircore.filesystem",
3021
}
3122

3223
l := &claircore.Layer{}
33-
err := l.Init(ctx, desc, nil)
34-
24+
err = l.Init(ctx, desc, nil)
3525
if err != nil {
3626
return nil, err
3727
}
38-
3928
l.Close()
4029

41-
layers = append(layers, l)
42-
43-
return layers, nil
44-
}
45-
46-
func (i *fileSystemImage) GetManifest(ctx context.Context) (*claircore.Manifest, error) {
47-
digest, err := claircore.ParseDigest(fmt.Sprintf("sha256:%s", strings.Repeat("0", 64)))
48-
if err != nil {
49-
return nil, err
50-
}
51-
52-
layers, err := i.getLayers(ctx)
53-
if err != nil {
54-
return nil, err
55-
}
56-
5730
return &claircore.Manifest{
5831
Hash: digest,
59-
Layers: layers,
32+
Layers: []*claircore.Layer{l},
6033
}, nil
6134
}

0 commit comments

Comments
 (0)