diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index 9454478767..1945f96748 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -88,37 +88,37 @@ func RequiredFilenames() []string { type Config struct { Extractor extractor.Extractor - Cache cache.ImageCache + Cache cache.ArtifactCache } -func New(ext extractor.Extractor, c cache.ImageCache) Config { +func New(ext extractor.Extractor, c cache.ArtifactCache) Config { return Config{Extractor: ext, Cache: c} } -func (ac Config) Analyze(ctx context.Context) (types.ImageReference, error) { +func (ac Config) Analyze(ctx context.Context) (types.ArtifactReference, error) { imageID, err := ac.Extractor.ImageID() if err != nil { - return types.ImageReference{}, xerrors.Errorf("unable to get the image ID: %w", err) + return types.ArtifactReference{}, xerrors.Errorf("unable to get the image ID: %w", err) } diffIDs, err := ac.Extractor.LayerIDs() if err != nil { - return types.ImageReference{}, xerrors.Errorf("unable to get layer IDs: %w", err) + return types.ArtifactReference{}, xerrors.Errorf("unable to get layer IDs: %w", err) } - missingImage, missingLayers, err := ac.Cache.MissingLayers(imageID, diffIDs) + missingImage, missingLayers, err := ac.Cache.MissingBlobs(imageID, diffIDs) if err != nil { - return types.ImageReference{}, xerrors.Errorf("unable to get missing layers: %w", err) + return types.ArtifactReference{}, xerrors.Errorf("unable to get missing layers: %w", err) } if err := ac.analyze(ctx, imageID, missingImage, missingLayers); err != nil { - return types.ImageReference{}, xerrors.Errorf("analyze error: %w", err) + return types.ArtifactReference{}, xerrors.Errorf("analyze error: %w", err) } - return types.ImageReference{ - Name: ac.Extractor.ImageName(), - ID: imageID, - LayerIDs: diffIDs, + return types.ArtifactReference{ + Name: ac.Extractor.ImageName(), + ID: imageID, + BlobIDs: diffIDs, }, nil } @@ -134,7 +134,7 @@ func (ac Config) analyze(ctx context.Context, imageID string, missingImage bool, errCh <- xerrors.Errorf("failed to analyze layer: %s : %w", diffID, err) return } - if err = ac.Cache.PutLayer(diffID, layerInfo); err != nil { + if err = ac.Cache.PutBlob(diffID, layerInfo); err != nil { errCh <- xerrors.Errorf("failed to store layer: %s in cache: %w", diffID, err) return } @@ -164,26 +164,26 @@ func (ac Config) analyze(ctx context.Context, imageID string, missingImage bool, return nil } -func (ac Config) analyzeLayer(diffID string) (types.LayerInfo, error) { +func (ac Config) analyzeLayer(diffID string) (types.BlobInfo, error) { layerDigest, files, opqDirs, whFiles, err := ac.Extractor.ExtractLayerFiles(diffID, RequiredFilenames()) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("unable to extract files from layer %s: %w", diffID, err) + return types.BlobInfo{}, xerrors.Errorf("unable to extract files from layer %s: %w", diffID, err) } os := GetOS(files) pkgs, err := GetPackages(files) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("failed to get packages: %w", err) + return types.BlobInfo{}, xerrors.Errorf("failed to get packages: %w", err) } apps, err := GetLibraries(files) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("failed to get libraries: %w", err) + return types.BlobInfo{}, xerrors.Errorf("failed to get libraries: %w", err) } - layerInfo := types.LayerInfo{ + layerInfo := types.BlobInfo{ Digest: layerDigest, DiffID: diffID, - SchemaVersion: types.LayerJSONSchemaVersion, + SchemaVersion: types.BlobJSONSchemaVersion, OS: os, PackageInfos: pkgs, Applications: apps, @@ -210,8 +210,8 @@ func (ac Config) analyzeConfig(imageID string, osFound types.OS) error { return xerrors.Errorf("json marshal error: %w", err) } - info := types.ImageInfo{ - SchemaVersion: types.ImageJSONSchemaVersion, + info := types.ArtifactInfo{ + SchemaVersion: types.ArtifactJSONSchemaVersion, Architecture: s1.Architecture, Created: s1.Created.Time, DockerVersion: s1.DockerVersion, @@ -219,7 +219,7 @@ func (ac Config) analyzeConfig(imageID string, osFound types.OS) error { HistoryPackages: pkgs, } - if err := ac.Cache.PutImage(imageID, info); err != nil { + if err := ac.Cache.PutArtifact(imageID, info); err != nil { return xerrors.Errorf("failed to put image info into the cache: %w", err) } @@ -227,19 +227,19 @@ func (ac Config) analyzeConfig(imageID string, osFound types.OS) error { } type Applier struct { - cache cache.LocalImageCache + cache cache.LocalArtifactCache } -func NewApplier(c cache.LocalImageCache) Applier { +func NewApplier(c cache.LocalArtifactCache) Applier { return Applier{cache: c} } -func (a Applier) ApplyLayers(imageID string, diffIDs []string) (types.ImageDetail, error) { - var layers []types.LayerInfo +func (a Applier) ApplyLayers(imageID string, diffIDs []string) (types.ArtifactDetail, error) { + var layers []types.BlobInfo for _, diffID := range diffIDs { - layer, _ := a.cache.GetLayer(diffID) + layer, _ := a.cache.GetBlob(diffID) if layer.SchemaVersion == 0 { - return types.ImageDetail{}, xerrors.Errorf("layer cache missing: %s", diffID) + return types.ArtifactDetail{}, xerrors.Errorf("layer cache missing: %s", diffID) } layers = append(layers, layer) } @@ -251,7 +251,7 @@ func (a Applier) ApplyLayers(imageID string, diffIDs []string) (types.ImageDetai return mergedLayer, ErrNoPkgsDetected // send back package and apps info regardless } - imageInfo, _ := a.cache.GetImage(imageID) + imageInfo, _ := a.cache.GetArtifact(imageID) mergedLayer.HistoryPackages = imageInfo.HistoryPackages return mergedLayer, nil diff --git a/analyzer/analyzer_test.go b/analyzer/analyzer_test.go index 2563b2370d..81294e7652 100644 --- a/analyzer/analyzer_test.go +++ b/analyzer/analyzer_test.go @@ -29,7 +29,7 @@ import ( func TestConfig_Analyze(t *testing.T) { type fields struct { Extractor extractor.Extractor - Cache cache.ImageCache + Cache cache.ArtifactCache } type args struct { ctx context.Context @@ -39,30 +39,30 @@ func TestConfig_Analyze(t *testing.T) { imagePath string fields fields args args - missingLayerExpectation cache.ImageCacheMissingLayersExpectation - putLayerExpectations []cache.ImageCachePutLayerExpectation - putImageExpectations []cache.ImageCachePutImageExpectation - want types.ImageReference + missingLayerExpectation cache.ArtifactCacheMissingBlobsExpectation + putLayerExpectations []cache.ArtifactCachePutBlobExpectation + putImageExpectations []cache.ArtifactCachePutArtifactExpectation + want types.ArtifactReference wantErr string }{ { name: "happy path", imagePath: "testdata/alpine.tar.gz", - missingLayerExpectation: cache.ImageCacheMissingLayersExpectation{ - Args: cache.ImageCacheMissingLayersArgs{ - ImageID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", - LayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + missingLayerExpectation: cache.ArtifactCacheMissingBlobsExpectation{ + Args: cache.ArtifactCacheMissingBlobsArgs{ + ArtifactID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", + BlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, - Returns: cache.ImageCacheMissingLayersReturns{ - MissingImage: true, - MissingLayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + Returns: cache.ArtifactCacheMissingBlobsReturns{ + MissingArtifact: true, + MissingBlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, }, - putLayerExpectations: []cache.ImageCachePutLayerExpectation{ + putLayerExpectations: []cache.ArtifactCachePutBlobExpectation{ { - Args: cache.ImageCachePutLayerArgs{ - DiffID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", - LayerInfo: types.LayerInfo{ + Args: cache.ArtifactCachePutBlobArgs{ + BlobID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "", DiffID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", @@ -76,14 +76,14 @@ func TestConfig_Analyze(t *testing.T) { WhiteoutFiles: []string(nil), }, }, - Returns: cache.ImageCachePutLayerReturns{}, + Returns: cache.ArtifactCachePutBlobReturns{}, }, }, - putImageExpectations: []cache.ImageCachePutImageExpectation{ + putImageExpectations: []cache.ArtifactCachePutArtifactExpectation{ { - Args: cache.ImageCachePutImageArgs{ - ImageID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", - ImageInfo: types.ImageInfo{ + Args: cache.ArtifactCachePutArtifactArgs{ + ArtifactID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", + ArtifactInfo: types.ArtifactInfo{ SchemaVersion: 1, Architecture: "amd64", Created: time.Date(2019, 10, 21, 17, 21, 42, 387111039, time.UTC), @@ -93,38 +93,38 @@ func TestConfig_Analyze(t *testing.T) { }, }, }, - want: types.ImageReference{ - Name: "testdata/alpine.tar.gz", - ID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", - LayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + want: types.ArtifactReference{ + Name: "testdata/alpine.tar.gz", + ID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", + BlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, }, { name: "happy path: include lock files", imagePath: "testdata/vuln-image.tar.gz", - missingLayerExpectation: cache.ImageCacheMissingLayersExpectation{ - Args: cache.ImageCacheMissingLayersArgs{ - ImageID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", - LayerIDs: []string{ + missingLayerExpectation: cache.ArtifactCacheMissingBlobsExpectation{ + Args: cache.ArtifactCacheMissingBlobsArgs{ + ArtifactID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", + BlobIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", "sha256:a4595c43a874856bf95f3bfc4fbf78bbaa04c92c726276d4f64193a47ced0566", }, }, - Returns: cache.ImageCacheMissingLayersReturns{ - MissingLayerIDs: []string{ + Returns: cache.ArtifactCacheMissingBlobsReturns{ + MissingBlobIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, }, }, - putLayerExpectations: []cache.ImageCachePutLayerExpectation{ + putLayerExpectations: []cache.ArtifactCachePutBlobExpectation{ { - Args: cache.ImageCachePutLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", - LayerInfo: types.LayerInfo{ + Args: cache.ArtifactCachePutBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "", DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", @@ -134,9 +134,9 @@ func TestConfig_Analyze(t *testing.T) { }, }, { - Args: cache.ImageCachePutLayerArgs{ - DiffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", - LayerInfo: types.LayerInfo{ + Args: cache.ArtifactCachePutBlobArgs{ + BlobID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "", DiffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", @@ -145,9 +145,9 @@ func TestConfig_Analyze(t *testing.T) { }, }, { - Args: cache.ImageCachePutLayerArgs{ - DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", - LayerInfo: types.LayerInfo{ + Args: cache.ArtifactCachePutBlobArgs{ + BlobID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", @@ -174,10 +174,10 @@ func TestConfig_Analyze(t *testing.T) { }, }, }, - want: types.ImageReference{ + want: types.ArtifactReference{ Name: "testdata/vuln-image.tar.gz", ID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", - LayerIDs: []string{ + BlobIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", @@ -186,36 +186,36 @@ func TestConfig_Analyze(t *testing.T) { }, }, { - name: "sad path, MissingLayers returns an error", + name: "sad path, MissingBlobs returns an error", imagePath: "testdata/alpine.tar.gz", - missingLayerExpectation: cache.ImageCacheMissingLayersExpectation{ - Args: cache.ImageCacheMissingLayersArgs{ - ImageID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", - LayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + missingLayerExpectation: cache.ArtifactCacheMissingBlobsExpectation{ + Args: cache.ArtifactCacheMissingBlobsArgs{ + ArtifactID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", + BlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, - Returns: cache.ImageCacheMissingLayersReturns{ - Err: xerrors.New("MissingLayers failed"), + Returns: cache.ArtifactCacheMissingBlobsReturns{ + Err: xerrors.New("MissingBlobs failed"), }, }, - wantErr: "MissingLayers failed", + wantErr: "MissingBlobs failed", }, { - name: "sad path, PutLayer returns an error", + name: "sad path, PutBlob returns an error", imagePath: "testdata/alpine.tar.gz", - missingLayerExpectation: cache.ImageCacheMissingLayersExpectation{ - Args: cache.ImageCacheMissingLayersArgs{ - ImageID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", - LayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + missingLayerExpectation: cache.ArtifactCacheMissingBlobsExpectation{ + Args: cache.ArtifactCacheMissingBlobsArgs{ + ArtifactID: "sha256:965ea09ff2ebd2b9eeec88cd822ce156f6674c7e99be082c7efac3c62f3ff652", + BlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, - Returns: cache.ImageCacheMissingLayersReturns{ - MissingLayerIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, + Returns: cache.ArtifactCacheMissingBlobsReturns{ + MissingBlobIDs: []string{"sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0"}, }, }, - putLayerExpectations: []cache.ImageCachePutLayerExpectation{ + putLayerExpectations: []cache.ArtifactCachePutBlobExpectation{ { - Args: cache.ImageCachePutLayerArgs{ - DiffID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", - LayerInfo: types.LayerInfo{ + Args: cache.ArtifactCachePutBlobArgs{ + BlobID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "", DiffID: "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0", @@ -229,7 +229,7 @@ func TestConfig_Analyze(t *testing.T) { WhiteoutFiles: []string(nil), }, }, - Returns: cache.ImageCachePutLayerReturns{ + Returns: cache.ArtifactCachePutBlobReturns{ Err: errors.New("put layer failed"), }, }, @@ -239,10 +239,10 @@ func TestConfig_Analyze(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mockCache := new(cache.MockImageCache) - mockCache.ApplyMissingLayersExpectation(tt.missingLayerExpectation) - mockCache.ApplyPutLayerExpectations(tt.putLayerExpectations) - mockCache.ApplyPutImageExpectations(tt.putImageExpectations) + mockCache := new(cache.MockArtifactCache) + mockCache.ApplyMissingBlobsExpectation(tt.missingLayerExpectation) + mockCache.ApplyPutBlobExpectations(tt.putLayerExpectations) + mockCache.ApplyPutArtifactExpectations(tt.putImageExpectations) d, err := docker.NewArchiveImageExtractor(tt.imagePath) require.NoError(t, err, tt.name) @@ -268,9 +268,9 @@ func TestApplier_ApplyLayers(t *testing.T) { tests := []struct { name string args args - getLayerExpectations []cache.LocalImageCacheGetLayerExpectation - getImageExpectations []cache.LocalImageCacheGetImageExpectation - want types.ImageDetail + getLayerExpectations []cache.LocalArtifactCacheGetBlobExpectation + getImageExpectations []cache.LocalArtifactCacheGetArtifactExpectation + want types.ArtifactDetail wantErr string }{ { @@ -283,13 +283,13 @@ func TestApplier_ApplyLayers(t *testing.T) { "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -314,11 +314,11 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", @@ -342,11 +342,11 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", @@ -374,19 +374,19 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, }, - getImageExpectations: []cache.LocalImageCacheGetImageExpectation{ + getImageExpectations: []cache.LocalArtifactCacheGetArtifactExpectation{ { - Args: cache.LocalImageCacheGetImageArgs{ - ImageID: "sha256:4791503518dff090d6a82f7a5c1fd71c41146920e2562fb64308e17ab6834b7e", + Args: cache.LocalArtifactCacheGetArtifactArgs{ + ArtifactID: "sha256:4791503518dff090d6a82f7a5c1fd71c41146920e2562fb64308e17ab6834b7e", }, - Returns: cache.LocalImageCacheGetImageReturns{ - ImageInfo: types.ImageInfo{ + Returns: cache.LocalArtifactCacheGetArtifactReturns{ + ArtifactInfo: types.ArtifactInfo{ SchemaVersion: 1, }, }, }, }, - want: types.ImageDetail{ + want: types.ArtifactDetail{ OS: &types.OS{ Family: "debian", Name: "9.9", @@ -444,13 +444,13 @@ func TestApplier_ApplyLayers(t *testing.T) { "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -474,13 +474,13 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, }, - getImageExpectations: []cache.LocalImageCacheGetImageExpectation{ + getImageExpectations: []cache.LocalArtifactCacheGetArtifactExpectation{ { - Args: cache.LocalImageCacheGetImageArgs{ - ImageID: "sha256:3bb70bd5fb37e05b8ecaaace5d6a6b5ec7834037c07ecb5907355c23ab70352d", + Args: cache.LocalArtifactCacheGetArtifactArgs{ + ArtifactID: "sha256:3bb70bd5fb37e05b8ecaaace5d6a6b5ec7834037c07ecb5907355c23ab70352d", }, - Returns: cache.LocalImageCacheGetImageReturns{ - ImageInfo: types.ImageInfo{ + Returns: cache.LocalArtifactCacheGetArtifactReturns{ + ArtifactInfo: types.ArtifactInfo{ SchemaVersion: 1, HistoryPackages: []types.Package{ {Name: "musl", Version: "1.1.23"}, @@ -496,7 +496,7 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, }, - want: types.ImageDetail{ + want: types.ArtifactDetail{ OS: &types.OS{ Family: "alpine", Name: "3.10.4", @@ -556,35 +556,35 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, { - name: "sad path GetLayer returns an error", + name: "sad path GetBlob returns an error", args: args{ layerIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, - Returns: cache.LocalImageCacheGetLayerReturns{LayerInfo: types.LayerInfo{}}, + Returns: cache.LocalArtifactCacheGetBlobReturns{BlobInfo: types.BlobInfo{}}, }, }, wantErr: "layer cache missing", }, { - name: "sad path GetLayer returns empty layer info", + name: "sad path GetBlob returns empty layer info", args: args{ layerIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, - Returns: cache.LocalImageCacheGetLayerReturns{LayerInfo: types.LayerInfo{}}, + Returns: cache.LocalArtifactCacheGetBlobReturns{BlobInfo: types.BlobInfo{}}, }, }, wantErr: "layer cache missing", @@ -599,13 +599,13 @@ func TestApplier_ApplyLayers(t *testing.T) { "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -626,11 +626,11 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", @@ -654,11 +654,11 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", @@ -686,7 +686,7 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, }, - want: types.ImageDetail{ + want: types.ArtifactDetail{ Packages: []types.Package{ { Name: "libc6", Version: "2.24-11+deb9u4", SrcName: "glibc", SrcVersion: "2.24-11+deb9u4", @@ -740,13 +740,13 @@ func TestApplier_ApplyLayers(t *testing.T) { "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, }, - getLayerExpectations: []cache.LocalImageCacheGetLayerExpectation{ + getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{ { - Args: cache.LocalImageCacheGetLayerArgs{ - DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + Args: cache.LocalArtifactCacheGetBlobArgs{ + BlobID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", }, - Returns: cache.LocalImageCacheGetLayerReturns{ - LayerInfo: types.LayerInfo{ + Returns: cache.LocalArtifactCacheGetBlobReturns{ + BlobInfo: types.BlobInfo{ SchemaVersion: 1, OS: &types.OS{ Family: "debian", @@ -756,7 +756,7 @@ func TestApplier_ApplyLayers(t *testing.T) { }, }, }, - want: types.ImageDetail{ + want: types.ArtifactDetail{ OS: &types.OS{ Family: "debian", Name: "9.9", @@ -767,9 +767,9 @@ func TestApplier_ApplyLayers(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := new(cache.MockLocalImageCache) - c.ApplyGetLayerExpectations(tt.getLayerExpectations) - c.ApplyGetImageExpectations(tt.getImageExpectations) + c := new(cache.MockLocalArtifactCache) + c.ApplyGetBlobExpectations(tt.getLayerExpectations) + c.ApplyGetArtifactExpectations(tt.getImageExpectations) a := analyzer.NewApplier(c) diff --git a/cache/cache.go b/cache/cache.go index 5766ac5b5e..d66f43318e 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -13,29 +13,41 @@ import ( const ( cacheDirName = "fanal" - // imageBucket stores image information with image ID - imageBucket = "image" - // layerBucket stores os, package and library information per layer ID - layerBucket = "layer" + // artifactBucket stores artifact information with artifact ID such as image ID + artifactBucket = "artifact" + // blobBucket stores os, package and library information per blob ID such as layer ID + blobBucket = "blob" ) type Cache interface { - ImageCache - LocalImageCache + ArtifactCache + LocalArtifactCache } -// ImageCache uses local or remote cache -type ImageCache interface { - MissingLayers(imageID string, layerIDs []string) (missingImage bool, missingLayerIDs []string, err error) - PutImage(imageID string, imageInfo types.ImageInfo) (err error) - PutLayer(diffID string, layerInfo types.LayerInfo) (err error) +// ArtifactCache uses local or remote cache +type ArtifactCache interface { + // MissingBlobs returns missing blob IDs such as layer IDs in cache + MissingBlobs(artifactID string, blobIDs []string) (missingArtifact bool, missingBlobIDs []string, err error) + + // PutArtifact stores artifact information such as image metadata in cache + PutArtifact(artifactID string, artifactInfo types.ArtifactInfo) (err error) + + // PutBlob stores blob information such as layer information in local cache + PutBlob(blobID string, blobInfo types.BlobInfo) (err error) } -// LocalImageCache always uses local cache -type LocalImageCache interface { - GetImage(imageID string) (imageInfo types.ImageInfo, err error) - GetLayer(diffID string) (layerInfo types.LayerInfo, err error) +// LocalArtifactCache always uses local cache +type LocalArtifactCache interface { + // GetArtifact gets artifact information such as image metadata from local cache + GetArtifact(artifactID string) (artifactInfo types.ArtifactInfo, err error) + + // GetBlob gets blob information such as layer data from local cache + GetBlob(blobID string) (blobInfo types.BlobInfo, err error) + + // Close closes the local database Close() (err error) + + // Clear deletes the local database Clear() (err error) } @@ -56,7 +68,7 @@ func NewFSCache(cacheDir string) (FSCache, error) { } err = db.Update(func(tx *bolt.Tx) error { - for _, bucket := range []string{imageBucket, layerBucket} { + for _, bucket := range []string{artifactBucket, blobBucket} { if _, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { return xerrors.Errorf("unable to create %s bucket: %w", err) } @@ -73,47 +85,49 @@ func NewFSCache(cacheDir string) (FSCache, error) { }, nil } -func (fs FSCache) GetLayer(diffID string) (types.LayerInfo, error) { - var layerInfo types.LayerInfo +// GetBlob gets blob information such as layer data from local cache +func (fs FSCache) GetBlob(blobID string) (types.BlobInfo, error) { + var blobInfo types.BlobInfo err := fs.db.View(func(tx *bolt.Tx) error { var err error - layerBucket := tx.Bucket([]byte(layerBucket)) - layerInfo, err = fs.getLayer(layerBucket, diffID) + blobBucket := tx.Bucket([]byte(blobBucket)) + blobInfo, err = fs.getBlob(blobBucket, blobID) if err != nil { - return xerrors.Errorf("failed to get layer from the cache: %w", err) + return xerrors.Errorf("failed to get blob from the cache: %w", err) } return nil }) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("DB error: %w", err) + return types.BlobInfo{}, xerrors.Errorf("DB error: %w", err) } - return layerInfo, nil + return blobInfo, nil } -func (fs FSCache) getLayer(layerBucket *bolt.Bucket, diffID string) (types.LayerInfo, error) { - b := layerBucket.Get([]byte(diffID)) +func (fs FSCache) getBlob(blobBucket *bolt.Bucket, diffID string) (types.BlobInfo, error) { + b := blobBucket.Get([]byte(diffID)) - var l types.LayerInfo + var l types.BlobInfo if err := json.Unmarshal(b, &l); err != nil { - return types.LayerInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) + return types.BlobInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) } return l, nil } -func (fs FSCache) PutLayer(diffID string, layerInfo types.LayerInfo) error { - if _, err := v1.NewHash(diffID); err != nil { - return xerrors.Errorf("invalid diffID (%s): %w", diffID, err) +// PutBlob stores blob information such as layer information in local cache +func (fs FSCache) PutBlob(blobID string, blobInfo types.BlobInfo) error { + if _, err := v1.NewHash(blobID); err != nil { + return xerrors.Errorf("invalid diffID (%s): %w", blobID, err) } - b, err := json.Marshal(layerInfo) + b, err := json.Marshal(blobInfo) if err != nil { - return xerrors.Errorf("unable to marshal layer JSON (%s): %w", diffID, err) + return xerrors.Errorf("unable to marshal blob JSON (%s): %w", blobID, err) } err = fs.db.Update(func(tx *bolt.Tx) error { - layerBucket := tx.Bucket([]byte(layerBucket)) - err = layerBucket.Put([]byte(diffID), b) + blobBucket := tx.Bucket([]byte(blobBucket)) + err = blobBucket.Put([]byte(blobID), b) if err != nil { - return xerrors.Errorf("unable to store layer information in cache (%s): %w", diffID, err) + return xerrors.Errorf("unable to store blob information in cache (%s): %w", blobID, err) } return nil }) @@ -123,35 +137,37 @@ func (fs FSCache) PutLayer(diffID string, layerInfo types.LayerInfo) error { return nil } -func (fs FSCache) GetImage(imageID string) (types.ImageInfo, error) { +// GetArtifact gets artifact information such as image metadata from local cache +func (fs FSCache) GetArtifact(artifactID string) (types.ArtifactInfo, error) { var blob []byte err := fs.db.View(func(tx *bolt.Tx) error { - imageBucket := tx.Bucket([]byte(imageBucket)) - blob = imageBucket.Get([]byte(imageID)) + artifactBucket := tx.Bucket([]byte(artifactBucket)) + blob = artifactBucket.Get([]byte(artifactID)) return nil }) if err != nil { - return types.ImageInfo{}, xerrors.Errorf("DB error: %w", err) + return types.ArtifactInfo{}, xerrors.Errorf("DB error: %w", err) } - var info types.ImageInfo + var info types.ArtifactInfo if err := json.Unmarshal(blob, &info); err != nil { - return types.ImageInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) + return types.ArtifactInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) } return info, nil } -func (fs FSCache) PutImage(imageID string, imageConfig types.ImageInfo) (err error) { - b, err := json.Marshal(imageConfig) +// PutArtifact stores artifact information such as image metadata in local cache +func (fs FSCache) PutArtifact(artifactID string, artifactInfo types.ArtifactInfo) (err error) { + b, err := json.Marshal(artifactInfo) if err != nil { - return xerrors.Errorf("unable to marshal image JSON (%s): %w", imageID, err) + return xerrors.Errorf("unable to marshal artifact JSON (%s): %w", artifactID, err) } err = fs.db.Update(func(tx *bolt.Tx) error { - imageBucket := tx.Bucket([]byte(imageBucket)) - err = imageBucket.Put([]byte(imageID), b) + artifactBucket := tx.Bucket([]byte(artifactBucket)) + err = artifactBucket.Put([]byte(artifactID), b) if err != nil { - return xerrors.Errorf("unable to store image information in cache (%s): %w", imageID, err) + return xerrors.Errorf("unable to store artifact information in cache (%s): %w", artifactID, err) } return nil }) @@ -161,20 +177,21 @@ func (fs FSCache) PutImage(imageID string, imageConfig types.ImageInfo) (err err return nil } -func (fs FSCache) MissingLayers(imageID string, layerIDs []string) (bool, []string, error) { - var missingImage bool - var missingLayerIDs []string +// MissingBlobs returns missing blob IDs such as layer IDs +func (fs FSCache) MissingBlobs(artifactID string, blobIDs []string) (bool, []string, error) { + var missingArtifact bool + var missingBlobIDs []string err := fs.db.View(func(tx *bolt.Tx) error { - layerBucket := tx.Bucket([]byte(layerBucket)) - for _, layerID := range layerIDs { - layerInfo, err := fs.getLayer(layerBucket, layerID) + blobBucket := tx.Bucket([]byte(blobBucket)) + for _, blobID := range blobIDs { + blobInfo, err := fs.getBlob(blobBucket, blobID) if err != nil { - // error means cache missed layer info - missingLayerIDs = append(missingLayerIDs, layerID) + // error means cache missed blob info + missingBlobIDs = append(missingBlobIDs, blobID) continue } - if layerInfo.SchemaVersion != types.LayerJSONSchemaVersion { - missingLayerIDs = append(missingLayerIDs, layerID) + if blobInfo.SchemaVersion != types.BlobJSONSchemaVersion { + missingBlobIDs = append(missingBlobIDs, blobID) } } return nil @@ -183,18 +200,19 @@ func (fs FSCache) MissingLayers(imageID string, layerIDs []string) (bool, []stri return false, nil, xerrors.Errorf("DB error: %w", err) } - // get image info - imageInfo, err := fs.GetImage(imageID) + // get artifact info + artifactInfo, err := fs.GetArtifact(artifactID) if err != nil { - // error means cache missed image info - return true, missingLayerIDs, nil + // error means cache missed artifact info + return true, missingBlobIDs, nil } - if imageInfo.SchemaVersion != types.ImageJSONSchemaVersion { - missingImage = true + if artifactInfo.SchemaVersion != types.ArtifactJSONSchemaVersion { + missingArtifact = true } - return missingImage, missingLayerIDs, nil + return missingArtifact, missingBlobIDs, nil } +// Close closes the database func (fs FSCache) Close() error { if err := fs.db.Close(); err != nil { return xerrors.Errorf("unable to close DB: %w", err) @@ -202,6 +220,7 @@ func (fs FSCache) Close() error { return nil } +// Clear removes the database func (fs FSCache) Clear() error { if err := fs.Close(); err != nil { return err diff --git a/cache/cache_test.go b/cache/cache_test.go index 9fd332d8ed..08382f4683 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -71,7 +71,7 @@ func TestFSCache_GetLayer(t *testing.T) { name string dbPath string args args - want types.LayerInfo + want types.BlobInfo wantErr bool }{ { @@ -80,7 +80,7 @@ func TestFSCache_GetLayer(t *testing.T) { args: args{ layerID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, - want: types.LayerInfo{ + want: types.BlobInfo{ SchemaVersion: 2, OS: &types.OS{ Family: "alpine", @@ -107,7 +107,7 @@ func TestFSCache_GetLayer(t *testing.T) { require.NoError(t, err) defer fs.Clear() - got, err := fs.GetLayer(tt.args.layerID) + got, err := fs.GetBlob(tt.args.layerID) assert.Equal(t, tt.wantErr, err != nil, err) assert.Equal(t, tt.want, got) }) @@ -121,7 +121,7 @@ func TestFSCache_PutLayer(t *testing.T) { } type args struct { diffID string - layerInfo types.LayerInfo + layerInfo types.BlobInfo } tests := []struct { name string @@ -135,7 +135,7 @@ func TestFSCache_PutLayer(t *testing.T) { name: "happy path", args: args{ diffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", - layerInfo: types.LayerInfo{ + layerInfo: types.BlobInfo{ SchemaVersion: 1, OS: &types.OS{ Family: "alpine", @@ -157,7 +157,7 @@ func TestFSCache_PutLayer(t *testing.T) { name: "happy path: different decompressed layer ID", args: args{ diffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", - layerInfo: types.LayerInfo{ + layerInfo: types.BlobInfo{ SchemaVersion: 1, Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:dab15cac9ebd43beceeeda3ce95c574d6714ed3d3969071caead678c065813ec", @@ -270,7 +270,7 @@ func TestFSCache_PutLayer(t *testing.T) { require.NoError(t, err) defer fs.Clear() - err = fs.PutLayer(tt.args.diffID, tt.args.layerInfo) + err = fs.PutBlob(tt.args.diffID, tt.args.layerInfo) if tt.wantErr != "" { require.NotNil(t, err) assert.Contains(t, err.Error(), tt.wantErr, tt.name) @@ -280,7 +280,7 @@ func TestFSCache_PutLayer(t *testing.T) { } fs.db.View(func(tx *bolt.Tx) error { - layerBucket := tx.Bucket([]byte(layerBucket)) + layerBucket := tx.Bucket([]byte(blobBucket)) b := layerBucket.Get([]byte(tt.args.diffID)) assert.JSONEq(t, tt.want, string(b)) @@ -293,7 +293,7 @@ func TestFSCache_PutLayer(t *testing.T) { func TestFSCache_PutImage(t *testing.T) { type args struct { imageID string - imageConfig types.ImageInfo + imageConfig types.ArtifactInfo } tests := []struct { name string @@ -305,7 +305,7 @@ func TestFSCache_PutImage(t *testing.T) { name: "happy path", args: args{ imageID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", - imageConfig: types.ImageInfo{ + imageConfig: types.ArtifactInfo{ SchemaVersion: 1, Architecture: "amd64", Created: time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC), @@ -347,7 +347,7 @@ func TestFSCache_PutImage(t *testing.T) { require.NoError(t, err) //defer fs.Clear() - err = fs.PutImage(tt.args.imageID, tt.args.imageConfig) + err = fs.PutArtifact(tt.args.imageID, tt.args.imageConfig) if tt.wantErr != "" { require.NotNil(t, err) assert.Contains(t, err.Error(), tt.wantErr, tt.name) @@ -358,7 +358,7 @@ func TestFSCache_PutImage(t *testing.T) { fs.db.View(func(tx *bolt.Tx) error { // check decompressedDigestBucket - imageBucket := tx.Bucket([]byte(imageBucket)) + imageBucket := tx.Bucket([]byte(artifactBucket)) b := imageBucket.Get([]byte(tt.args.imageID)) assert.JSONEq(t, tt.want, string(b)) @@ -452,7 +452,7 @@ func TestFSCache_MissingLayers(t *testing.T) { require.NoError(t, err) defer fs.Clear() - gotMissingImage, gotMissingLayerIDs, err := fs.MissingLayers(tt.args.imageID, tt.args.layerIDs) + gotMissingImage, gotMissingLayerIDs, err := fs.MissingBlobs(tt.args.imageID, tt.args.layerIDs) if tt.wantErr != "" { require.NotNil(t, err, tt.name) assert.Contains(t, err.Error(), tt.wantErr, tt.name) diff --git a/cache/mock_artifact_cache.go b/cache/mock_artifact_cache.go new file mode 100644 index 0000000000..90ba35d461 --- /dev/null +++ b/cache/mock_artifact_cache.go @@ -0,0 +1,184 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package cache + +import ( + types "github.com/aquasecurity/fanal/types" + mock "github.com/stretchr/testify/mock" +) + +// MockArtifactCache is an autogenerated mock type for the ArtifactCache type +type MockArtifactCache struct { + mock.Mock +} + +type ArtifactCacheMissingBlobsArgs struct { + ArtifactID string + ArtifactIDAnything bool + BlobIDs []string + BlobIDsAnything bool +} + +type ArtifactCacheMissingBlobsReturns struct { + MissingArtifact bool + MissingBlobIDs []string + Err error +} + +type ArtifactCacheMissingBlobsExpectation struct { + Args ArtifactCacheMissingBlobsArgs + Returns ArtifactCacheMissingBlobsReturns +} + +func (_m *MockArtifactCache) ApplyMissingBlobsExpectation(e ArtifactCacheMissingBlobsExpectation) { + var args []interface{} + if e.Args.ArtifactIDAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.ArtifactID) + } + if e.Args.BlobIDsAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.BlobIDs) + } + _m.On("MissingBlobs", args...).Return(e.Returns.MissingArtifact, e.Returns.MissingBlobIDs, e.Returns.Err) +} + +func (_m *MockArtifactCache) ApplyMissingBlobsExpectations(expectations []ArtifactCacheMissingBlobsExpectation) { + for _, e := range expectations { + _m.ApplyMissingBlobsExpectation(e) + } +} + +// MissingBlobs provides a mock function with given fields: artifactID, blobIDs +func (_m *MockArtifactCache) MissingBlobs(artifactID string, blobIDs []string) (bool, []string, error) { + ret := _m.Called(artifactID, blobIDs) + + var r0 bool + if rf, ok := ret.Get(0).(func(string, []string) bool); ok { + r0 = rf(artifactID, blobIDs) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 []string + if rf, ok := ret.Get(1).(func(string, []string) []string); ok { + r1 = rf(artifactID, blobIDs) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]string) + } + } + + var r2 error + if rf, ok := ret.Get(2).(func(string, []string) error); ok { + r2 = rf(artifactID, blobIDs) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +type ArtifactCachePutArtifactArgs struct { + ArtifactID string + ArtifactIDAnything bool + ArtifactInfo types.ArtifactInfo + ArtifactInfoAnything bool +} + +type ArtifactCachePutArtifactReturns struct { + Err error +} + +type ArtifactCachePutArtifactExpectation struct { + Args ArtifactCachePutArtifactArgs + Returns ArtifactCachePutArtifactReturns +} + +func (_m *MockArtifactCache) ApplyPutArtifactExpectation(e ArtifactCachePutArtifactExpectation) { + var args []interface{} + if e.Args.ArtifactIDAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.ArtifactID) + } + if e.Args.ArtifactInfoAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.ArtifactInfo) + } + _m.On("PutArtifact", args...).Return(e.Returns.Err) +} + +func (_m *MockArtifactCache) ApplyPutArtifactExpectations(expectations []ArtifactCachePutArtifactExpectation) { + for _, e := range expectations { + _m.ApplyPutArtifactExpectation(e) + } +} + +// PutArtifact provides a mock function with given fields: artifactID, artifactInfo +func (_m *MockArtifactCache) PutArtifact(artifactID string, artifactInfo types.ArtifactInfo) error { + ret := _m.Called(artifactID, artifactInfo) + + var r0 error + if rf, ok := ret.Get(0).(func(string, types.ArtifactInfo) error); ok { + r0 = rf(artifactID, artifactInfo) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type ArtifactCachePutBlobArgs struct { + BlobID string + BlobIDAnything bool + BlobInfo types.BlobInfo + BlobInfoAnything bool +} + +type ArtifactCachePutBlobReturns struct { + Err error +} + +type ArtifactCachePutBlobExpectation struct { + Args ArtifactCachePutBlobArgs + Returns ArtifactCachePutBlobReturns +} + +func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpectation) { + var args []interface{} + if e.Args.BlobIDAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.BlobID) + } + if e.Args.BlobInfoAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.BlobInfo) + } + _m.On("PutBlob", args...).Return(e.Returns.Err) +} + +func (_m *MockArtifactCache) ApplyPutBlobExpectations(expectations []ArtifactCachePutBlobExpectation) { + for _, e := range expectations { + _m.ApplyPutBlobExpectation(e) + } +} + +// PutBlob provides a mock function with given fields: blobID, blobInfo +func (_m *MockArtifactCache) PutBlob(blobID string, blobInfo types.BlobInfo) error { + ret := _m.Called(blobID, blobInfo) + + var r0 error + if rf, ok := ret.Get(0).(func(string, types.BlobInfo) error); ok { + r0 = rf(blobID, blobInfo) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/cache/mock_cache.go b/cache/mock_cache.go index df525fa3d5..cd5d62bb5f 100644 --- a/cache/mock_cache.go +++ b/cache/mock_cache.go @@ -2,8 +2,10 @@ package cache -import mock "github.com/stretchr/testify/mock" -import types "github.com/aquasecurity/fanal/types" +import ( + types "github.com/aquasecurity/fanal/types" + mock "github.com/stretchr/testify/mock" +) // MockCache is an autogenerated mock type for the Cache type type MockCache struct { @@ -43,51 +45,84 @@ func (_m *MockCache) Clear() error { return r0 } -type CacheGetImageArgs struct { - ImageID string - ImageIDAnything bool +type CacheCloseReturns struct { + Err error } -type CacheGetImageReturns struct { - ImageConfig types.ImageInfo - Err error +type CacheCloseExpectation struct { + Returns CacheCloseReturns } -type CacheGetImageExpectation struct { - Args CacheGetImageArgs - Returns CacheGetImageReturns -} - -func (_m *MockCache) ApplyGetImageExpectation(e CacheGetImageExpectation) { +func (_m *MockCache) ApplyCloseExpectation(e CacheCloseExpectation) { var args []interface{} - if e.Args.ImageIDAnything { + _m.On("Close", args...).Return(e.Returns.Err) +} + +func (_m *MockCache) ApplyCloseExpectations(expectations []CacheCloseExpectation) { + for _, e := range expectations { + _m.ApplyCloseExpectation(e) + } +} + +// Close provides a mock function with given fields: +func (_m *MockCache) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type CacheGetArtifactArgs struct { + ArtifactID string + ArtifactIDAnything bool +} + +type CacheGetArtifactReturns struct { + ArtifactInfo types.ArtifactInfo + Err error +} + +type CacheGetArtifactExpectation struct { + Args CacheGetArtifactArgs + Returns CacheGetArtifactReturns +} + +func (_m *MockCache) ApplyGetArtifactExpectation(e CacheGetArtifactExpectation) { + var args []interface{} + if e.Args.ArtifactIDAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.ImageID) + args = append(args, e.Args.ArtifactID) } - _m.On("GetImage", args...).Return(e.Returns.ImageConfig, e.Returns.Err) + _m.On("GetArtifact", args...).Return(e.Returns.ArtifactInfo, e.Returns.Err) } -func (_m *MockCache) ApplyGetImageExpectations(expectations []CacheGetImageExpectation) { +func (_m *MockCache) ApplyGetArtifactExpectations(expectations []CacheGetArtifactExpectation) { for _, e := range expectations { - _m.ApplyGetImageExpectation(e) + _m.ApplyGetArtifactExpectation(e) } } -// GetImage provides a mock function with given fields: imageID -func (_m *MockCache) GetImage(imageID string) (types.ImageInfo, error) { - ret := _m.Called(imageID) +// GetArtifact provides a mock function with given fields: artifactID +func (_m *MockCache) GetArtifact(artifactID string) (types.ArtifactInfo, error) { + ret := _m.Called(artifactID) - var r0 types.ImageInfo - if rf, ok := ret.Get(0).(func(string) types.ImageInfo); ok { - r0 = rf(imageID) + var r0 types.ArtifactInfo + if rf, ok := ret.Get(0).(func(string) types.ArtifactInfo); ok { + r0 = rf(artifactID) } else { - r0 = ret.Get(0).(types.ImageInfo) + r0 = ret.Get(0).(types.ArtifactInfo) } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(imageID) + r1 = rf(artifactID) } else { r1 = ret.Error(1) } @@ -95,103 +130,111 @@ func (_m *MockCache) GetImage(imageID string) (types.ImageInfo, error) { return r0, r1 } -type CacheGetLayerArgs struct { - LayerID string - LayerIDAnything bool +type CacheGetBlobArgs struct { + BlobID string + BlobIDAnything bool } -type CacheGetLayerReturns struct { - LayerInfo types.LayerInfo +type CacheGetBlobReturns struct { + BlobInfo types.BlobInfo + Err error } -type CacheGetLayerExpectation struct { - Args CacheGetLayerArgs - Returns CacheGetLayerReturns +type CacheGetBlobExpectation struct { + Args CacheGetBlobArgs + Returns CacheGetBlobReturns } -func (_m *MockCache) ApplyGetLayerExpectation(e CacheGetLayerExpectation) { +func (_m *MockCache) ApplyGetBlobExpectation(e CacheGetBlobExpectation) { var args []interface{} - if e.Args.LayerIDAnything { + if e.Args.BlobIDAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.LayerID) + args = append(args, e.Args.BlobID) } - _m.On("GetLayer", args...).Return(e.Returns.LayerInfo) + _m.On("GetBlob", args...).Return(e.Returns.BlobInfo, e.Returns.Err) } -func (_m *MockCache) ApplyGetLayerExpectations(expectations []CacheGetLayerExpectation) { +func (_m *MockCache) ApplyGetBlobExpectations(expectations []CacheGetBlobExpectation) { for _, e := range expectations { - _m.ApplyGetLayerExpectation(e) + _m.ApplyGetBlobExpectation(e) } } -// GetLayer provides a mock function with given fields: layerID -func (_m *MockCache) GetLayer(layerID string) types.LayerInfo { - ret := _m.Called(layerID) +// GetBlob provides a mock function with given fields: blobID +func (_m *MockCache) GetBlob(blobID string) (types.BlobInfo, error) { + ret := _m.Called(blobID) - var r0 types.LayerInfo - if rf, ok := ret.Get(0).(func(string) types.LayerInfo); ok { - r0 = rf(layerID) + var r0 types.BlobInfo + if rf, ok := ret.Get(0).(func(string) types.BlobInfo); ok { + r0 = rf(blobID) } else { - r0 = ret.Get(0).(types.LayerInfo) + r0 = ret.Get(0).(types.BlobInfo) } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(blobID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -type CacheMissingLayersArgs struct { - ImageID string - ImageIDAnything bool - LayerIDs []string - LayerIDsAnything bool +type CacheMissingBlobsArgs struct { + ArtifactID string + ArtifactIDAnything bool + BlobIDs []string + BlobIDsAnything bool } -type CacheMissingLayersReturns struct { - MissingImage bool - MissingLayerIDs []string +type CacheMissingBlobsReturns struct { + MissingArtifact bool + MissingBlobIDs []string Err error } -type CacheMissingLayersExpectation struct { - Args CacheMissingLayersArgs - Returns CacheMissingLayersReturns +type CacheMissingBlobsExpectation struct { + Args CacheMissingBlobsArgs + Returns CacheMissingBlobsReturns } -func (_m *MockCache) ApplyMissingLayersExpectation(e CacheMissingLayersExpectation) { +func (_m *MockCache) ApplyMissingBlobsExpectation(e CacheMissingBlobsExpectation) { var args []interface{} - if e.Args.ImageIDAnything { + if e.Args.ArtifactIDAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.ImageID) + args = append(args, e.Args.ArtifactID) } - if e.Args.LayerIDsAnything { + if e.Args.BlobIDsAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.LayerIDs) + args = append(args, e.Args.BlobIDs) } - _m.On("MissingLayers", args...).Return(e.Returns.MissingImage, e.Returns.MissingLayerIDs, e.Returns.Err) + _m.On("MissingBlobs", args...).Return(e.Returns.MissingArtifact, e.Returns.MissingBlobIDs, e.Returns.Err) } -func (_m *MockCache) ApplyMissingLayersExpectations(expectations []CacheMissingLayersExpectation) { +func (_m *MockCache) ApplyMissingBlobsExpectations(expectations []CacheMissingBlobsExpectation) { for _, e := range expectations { - _m.ApplyMissingLayersExpectation(e) + _m.ApplyMissingBlobsExpectation(e) } } -// MissingLayers provides a mock function with given fields: imageID, layerIDs -func (_m *MockCache) MissingLayers(imageID string, layerIDs []string) (bool, []string, error) { - ret := _m.Called(imageID, layerIDs) +// MissingBlobs provides a mock function with given fields: artifactID, blobIDs +func (_m *MockCache) MissingBlobs(artifactID string, blobIDs []string) (bool, []string, error) { + ret := _m.Called(artifactID, blobIDs) var r0 bool if rf, ok := ret.Get(0).(func(string, []string) bool); ok { - r0 = rf(imageID, layerIDs) + r0 = rf(artifactID, blobIDs) } else { r0 = ret.Get(0).(bool) } var r1 []string if rf, ok := ret.Get(1).(func(string, []string) []string); ok { - r1 = rf(imageID, layerIDs) + r1 = rf(artifactID, blobIDs) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]string) @@ -200,7 +243,7 @@ func (_m *MockCache) MissingLayers(imageID string, layerIDs []string) (bool, []s var r2 error if rf, ok := ret.Get(2).(func(string, []string) error); ok { - r2 = rf(imageID, layerIDs) + r2 = rf(artifactID, blobIDs) } else { r2 = ret.Error(2) } @@ -208,50 +251,50 @@ func (_m *MockCache) MissingLayers(imageID string, layerIDs []string) (bool, []s return r0, r1, r2 } -type CachePutImageArgs struct { - ImageID string - ImageIDAnything bool - ImageConfig types.ImageInfo - ImageConfigAnything bool +type CachePutArtifactArgs struct { + ArtifactID string + ArtifactIDAnything bool + ArtifactInfo types.ArtifactInfo + ArtifactInfoAnything bool } -type CachePutImageReturns struct { +type CachePutArtifactReturns struct { Err error } -type CachePutImageExpectation struct { - Args CachePutImageArgs - Returns CachePutImageReturns +type CachePutArtifactExpectation struct { + Args CachePutArtifactArgs + Returns CachePutArtifactReturns } -func (_m *MockCache) ApplyPutImageExpectation(e CachePutImageExpectation) { +func (_m *MockCache) ApplyPutArtifactExpectation(e CachePutArtifactExpectation) { var args []interface{} - if e.Args.ImageIDAnything { + if e.Args.ArtifactIDAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.ImageID) + args = append(args, e.Args.ArtifactID) } - if e.Args.ImageConfigAnything { + if e.Args.ArtifactInfoAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.ImageConfig) + args = append(args, e.Args.ArtifactInfo) } - _m.On("PutImage", args...).Return(e.Returns.Err) + _m.On("PutArtifact", args...).Return(e.Returns.Err) } -func (_m *MockCache) ApplyPutImageExpectations(expectations []CachePutImageExpectation) { +func (_m *MockCache) ApplyPutArtifactExpectations(expectations []CachePutArtifactExpectation) { for _, e := range expectations { - _m.ApplyPutImageExpectation(e) + _m.ApplyPutArtifactExpectation(e) } } -// PutImage provides a mock function with given fields: imageID, imageConfig -func (_m *MockCache) PutImage(imageID string, imageConfig types.ImageInfo) error { - ret := _m.Called(imageID, imageConfig) +// PutArtifact provides a mock function with given fields: artifactID, artifactInfo +func (_m *MockCache) PutArtifact(artifactID string, artifactInfo types.ArtifactInfo) error { + ret := _m.Called(artifactID, artifactInfo) var r0 error - if rf, ok := ret.Get(0).(func(string, types.ImageInfo) error); ok { - r0 = rf(imageID, imageConfig) + if rf, ok := ret.Get(0).(func(string, types.ArtifactInfo) error); ok { + r0 = rf(artifactID, artifactInfo) } else { r0 = ret.Error(0) } @@ -259,57 +302,50 @@ func (_m *MockCache) PutImage(imageID string, imageConfig types.ImageInfo) error return r0 } -type CachePutLayerArgs struct { - LayerID string - LayerIDAnything bool - DecompressedLayerID string - DecompressedLayerIDAnything bool - LayerInfo types.LayerInfo - LayerInfoAnything bool +type CachePutBlobArgs struct { + BlobID string + BlobIDAnything bool + BlobInfo types.BlobInfo + BlobInfoAnything bool } -type CachePutLayerReturns struct { +type CachePutBlobReturns struct { Err error } -type CachePutLayerExpectation struct { - Args CachePutLayerArgs - Returns CachePutLayerReturns +type CachePutBlobExpectation struct { + Args CachePutBlobArgs + Returns CachePutBlobReturns } -func (_m *MockCache) ApplyPutLayerExpectation(e CachePutLayerExpectation) { +func (_m *MockCache) ApplyPutBlobExpectation(e CachePutBlobExpectation) { var args []interface{} - if e.Args.LayerIDAnything { + if e.Args.BlobIDAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.LayerID) + args = append(args, e.Args.BlobID) } - if e.Args.DecompressedLayerIDAnything { + if e.Args.BlobInfoAnything { args = append(args, mock.Anything) } else { - args = append(args, e.Args.DecompressedLayerID) + args = append(args, e.Args.BlobInfo) } - if e.Args.LayerInfoAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.LayerInfo) - } - _m.On("PutLayer", args...).Return(e.Returns.Err) + _m.On("PutBlob", args...).Return(e.Returns.Err) } -func (_m *MockCache) ApplyPutLayerExpectations(expectations []CachePutLayerExpectation) { +func (_m *MockCache) ApplyPutBlobExpectations(expectations []CachePutBlobExpectation) { for _, e := range expectations { - _m.ApplyPutLayerExpectation(e) + _m.ApplyPutBlobExpectation(e) } } -// PutLayer provides a mock function with given fields: layerID, decompressedLayerID, layerInfo -func (_m *MockCache) PutLayer(layerID string, decompressedLayerID string, layerInfo types.LayerInfo) error { - ret := _m.Called(layerID, decompressedLayerID, layerInfo) +// PutBlob provides a mock function with given fields: blobID, blobInfo +func (_m *MockCache) PutBlob(blobID string, blobInfo types.BlobInfo) error { + ret := _m.Called(blobID, blobInfo) var r0 error - if rf, ok := ret.Get(0).(func(string, string, types.LayerInfo) error); ok { - r0 = rf(layerID, decompressedLayerID, layerInfo) + if rf, ok := ret.Get(0).(func(string, types.BlobInfo) error); ok { + r0 = rf(blobID, blobInfo) } else { r0 = ret.Error(0) } diff --git a/cache/mock_image_cache.go b/cache/mock_image_cache.go deleted file mode 100644 index cf0e30e997..0000000000 --- a/cache/mock_image_cache.go +++ /dev/null @@ -1,184 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package cache - -import ( - types "github.com/aquasecurity/fanal/types" - mock "github.com/stretchr/testify/mock" -) - -// MockImageCache is an autogenerated mock type for the ImageCache type -type MockImageCache struct { - mock.Mock -} - -type ImageCacheMissingLayersArgs struct { - ImageID string - ImageIDAnything bool - LayerIDs []string - LayerIDsAnything bool -} - -type ImageCacheMissingLayersReturns struct { - MissingImage bool - MissingLayerIDs []string - Err error -} - -type ImageCacheMissingLayersExpectation struct { - Args ImageCacheMissingLayersArgs - Returns ImageCacheMissingLayersReturns -} - -func (_m *MockImageCache) ApplyMissingLayersExpectation(e ImageCacheMissingLayersExpectation) { - var args []interface{} - if e.Args.ImageIDAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.ImageID) - } - if e.Args.LayerIDsAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.LayerIDs) - } - _m.On("MissingLayers", args...).Return(e.Returns.MissingImage, e.Returns.MissingLayerIDs, e.Returns.Err) -} - -func (_m *MockImageCache) ApplyMissingLayersExpectations(expectations []ImageCacheMissingLayersExpectation) { - for _, e := range expectations { - _m.ApplyMissingLayersExpectation(e) - } -} - -// MissingLayers provides a mock function with given fields: imageID, layerIDs -func (_m *MockImageCache) MissingLayers(imageID string, layerIDs []string) (bool, []string, error) { - ret := _m.Called(imageID, layerIDs) - - var r0 bool - if rf, ok := ret.Get(0).(func(string, []string) bool); ok { - r0 = rf(imageID, layerIDs) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 []string - if rf, ok := ret.Get(1).(func(string, []string) []string); ok { - r1 = rf(imageID, layerIDs) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).([]string) - } - } - - var r2 error - if rf, ok := ret.Get(2).(func(string, []string) error); ok { - r2 = rf(imageID, layerIDs) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -type ImageCachePutImageArgs struct { - ImageID string - ImageIDAnything bool - ImageInfo types.ImageInfo - ImageInfoAnything bool -} - -type ImageCachePutImageReturns struct { - Err error -} - -type ImageCachePutImageExpectation struct { - Args ImageCachePutImageArgs - Returns ImageCachePutImageReturns -} - -func (_m *MockImageCache) ApplyPutImageExpectation(e ImageCachePutImageExpectation) { - var args []interface{} - if e.Args.ImageIDAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.ImageID) - } - if e.Args.ImageInfoAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.ImageInfo) - } - _m.On("PutImage", args...).Return(e.Returns.Err) -} - -func (_m *MockImageCache) ApplyPutImageExpectations(expectations []ImageCachePutImageExpectation) { - for _, e := range expectations { - _m.ApplyPutImageExpectation(e) - } -} - -// PutImage provides a mock function with given fields: imageID, imageInfo -func (_m *MockImageCache) PutImage(imageID string, imageInfo types.ImageInfo) error { - ret := _m.Called(imageID, imageInfo) - - var r0 error - if rf, ok := ret.Get(0).(func(string, types.ImageInfo) error); ok { - r0 = rf(imageID, imageInfo) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -type ImageCachePutLayerArgs struct { - DiffID string - DiffIDAnything bool - LayerInfo types.LayerInfo - LayerInfoAnything bool -} - -type ImageCachePutLayerReturns struct { - Err error -} - -type ImageCachePutLayerExpectation struct { - Args ImageCachePutLayerArgs - Returns ImageCachePutLayerReturns -} - -func (_m *MockImageCache) ApplyPutLayerExpectation(e ImageCachePutLayerExpectation) { - var args []interface{} - if e.Args.DiffIDAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.DiffID) - } - if e.Args.LayerInfoAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.LayerInfo) - } - _m.On("PutLayer", args...).Return(e.Returns.Err) -} - -func (_m *MockImageCache) ApplyPutLayerExpectations(expectations []ImageCachePutLayerExpectation) { - for _, e := range expectations { - _m.ApplyPutLayerExpectation(e) - } -} - -// PutLayer provides a mock function with given fields: diffID, layerInfo -func (_m *MockImageCache) PutLayer(diffID string, layerInfo types.LayerInfo) error { - ret := _m.Called(diffID, layerInfo) - - var r0 error - if rf, ok := ret.Get(0).(func(string, types.LayerInfo) error); ok { - r0 = rf(diffID, layerInfo) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/cache/mock_local_artifact_cache.go b/cache/mock_local_artifact_cache.go new file mode 100644 index 0000000000..917ca31d74 --- /dev/null +++ b/cache/mock_local_artifact_cache.go @@ -0,0 +1,183 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package cache + +import ( + types "github.com/aquasecurity/fanal/types" + mock "github.com/stretchr/testify/mock" +) + +// MockLocalArtifactCache is an autogenerated mock type for the LocalArtifactCache type +type MockLocalArtifactCache struct { + mock.Mock +} + +type LocalArtifactCacheClearReturns struct { + Err error +} + +type LocalArtifactCacheClearExpectation struct { + Returns LocalArtifactCacheClearReturns +} + +func (_m *MockLocalArtifactCache) ApplyClearExpectation(e LocalArtifactCacheClearExpectation) { + var args []interface{} + _m.On("Clear", args...).Return(e.Returns.Err) +} + +func (_m *MockLocalArtifactCache) ApplyClearExpectations(expectations []LocalArtifactCacheClearExpectation) { + for _, e := range expectations { + _m.ApplyClearExpectation(e) + } +} + +// Clear provides a mock function with given fields: +func (_m *MockLocalArtifactCache) Clear() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type LocalArtifactCacheCloseReturns struct { + Err error +} + +type LocalArtifactCacheCloseExpectation struct { + Returns LocalArtifactCacheCloseReturns +} + +func (_m *MockLocalArtifactCache) ApplyCloseExpectation(e LocalArtifactCacheCloseExpectation) { + var args []interface{} + _m.On("Close", args...).Return(e.Returns.Err) +} + +func (_m *MockLocalArtifactCache) ApplyCloseExpectations(expectations []LocalArtifactCacheCloseExpectation) { + for _, e := range expectations { + _m.ApplyCloseExpectation(e) + } +} + +// Close provides a mock function with given fields: +func (_m *MockLocalArtifactCache) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type LocalArtifactCacheGetArtifactArgs struct { + ArtifactID string + ArtifactIDAnything bool +} + +type LocalArtifactCacheGetArtifactReturns struct { + ArtifactInfo types.ArtifactInfo + Err error +} + +type LocalArtifactCacheGetArtifactExpectation struct { + Args LocalArtifactCacheGetArtifactArgs + Returns LocalArtifactCacheGetArtifactReturns +} + +func (_m *MockLocalArtifactCache) ApplyGetArtifactExpectation(e LocalArtifactCacheGetArtifactExpectation) { + var args []interface{} + if e.Args.ArtifactIDAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.ArtifactID) + } + _m.On("GetArtifact", args...).Return(e.Returns.ArtifactInfo, e.Returns.Err) +} + +func (_m *MockLocalArtifactCache) ApplyGetArtifactExpectations(expectations []LocalArtifactCacheGetArtifactExpectation) { + for _, e := range expectations { + _m.ApplyGetArtifactExpectation(e) + } +} + +// GetArtifact provides a mock function with given fields: artifactID +func (_m *MockLocalArtifactCache) GetArtifact(artifactID string) (types.ArtifactInfo, error) { + ret := _m.Called(artifactID) + + var r0 types.ArtifactInfo + if rf, ok := ret.Get(0).(func(string) types.ArtifactInfo); ok { + r0 = rf(artifactID) + } else { + r0 = ret.Get(0).(types.ArtifactInfo) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(artifactID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type LocalArtifactCacheGetBlobArgs struct { + BlobID string + BlobIDAnything bool +} + +type LocalArtifactCacheGetBlobReturns struct { + BlobInfo types.BlobInfo + Err error +} + +type LocalArtifactCacheGetBlobExpectation struct { + Args LocalArtifactCacheGetBlobArgs + Returns LocalArtifactCacheGetBlobReturns +} + +func (_m *MockLocalArtifactCache) ApplyGetBlobExpectation(e LocalArtifactCacheGetBlobExpectation) { + var args []interface{} + if e.Args.BlobIDAnything { + args = append(args, mock.Anything) + } else { + args = append(args, e.Args.BlobID) + } + _m.On("GetBlob", args...).Return(e.Returns.BlobInfo, e.Returns.Err) +} + +func (_m *MockLocalArtifactCache) ApplyGetBlobExpectations(expectations []LocalArtifactCacheGetBlobExpectation) { + for _, e := range expectations { + _m.ApplyGetBlobExpectation(e) + } +} + +// GetBlob provides a mock function with given fields: blobID +func (_m *MockLocalArtifactCache) GetBlob(blobID string) (types.BlobInfo, error) { + ret := _m.Called(blobID) + + var r0 types.BlobInfo + if rf, ok := ret.Get(0).(func(string) types.BlobInfo); ok { + r0 = rf(blobID) + } else { + r0 = ret.Get(0).(types.BlobInfo) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(blobID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/cache/mock_local_image_cache.go b/cache/mock_local_image_cache.go deleted file mode 100644 index f6a2ab111e..0000000000 --- a/cache/mock_local_image_cache.go +++ /dev/null @@ -1,183 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package cache - -import ( - types "github.com/aquasecurity/fanal/types" - mock "github.com/stretchr/testify/mock" -) - -// MockLocalImageCache is an autogenerated mock type for the LocalImageCache type -type MockLocalImageCache struct { - mock.Mock -} - -type LocalImageCacheClearReturns struct { - Err error -} - -type LocalImageCacheClearExpectation struct { - Returns LocalImageCacheClearReturns -} - -func (_m *MockLocalImageCache) ApplyClearExpectation(e LocalImageCacheClearExpectation) { - var args []interface{} - _m.On("Clear", args...).Return(e.Returns.Err) -} - -func (_m *MockLocalImageCache) ApplyClearExpectations(expectations []LocalImageCacheClearExpectation) { - for _, e := range expectations { - _m.ApplyClearExpectation(e) - } -} - -// Clear provides a mock function with given fields: -func (_m *MockLocalImageCache) Clear() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -type LocalImageCacheCloseReturns struct { - Err error -} - -type LocalImageCacheCloseExpectation struct { - Returns LocalImageCacheCloseReturns -} - -func (_m *MockLocalImageCache) ApplyCloseExpectation(e LocalImageCacheCloseExpectation) { - var args []interface{} - _m.On("Close", args...).Return(e.Returns.Err) -} - -func (_m *MockLocalImageCache) ApplyCloseExpectations(expectations []LocalImageCacheCloseExpectation) { - for _, e := range expectations { - _m.ApplyCloseExpectation(e) - } -} - -// Close provides a mock function with given fields: -func (_m *MockLocalImageCache) Close() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -type LocalImageCacheGetImageArgs struct { - ImageID string - ImageIDAnything bool -} - -type LocalImageCacheGetImageReturns struct { - ImageInfo types.ImageInfo - Err error -} - -type LocalImageCacheGetImageExpectation struct { - Args LocalImageCacheGetImageArgs - Returns LocalImageCacheGetImageReturns -} - -func (_m *MockLocalImageCache) ApplyGetImageExpectation(e LocalImageCacheGetImageExpectation) { - var args []interface{} - if e.Args.ImageIDAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.ImageID) - } - _m.On("GetImage", args...).Return(e.Returns.ImageInfo, e.Returns.Err) -} - -func (_m *MockLocalImageCache) ApplyGetImageExpectations(expectations []LocalImageCacheGetImageExpectation) { - for _, e := range expectations { - _m.ApplyGetImageExpectation(e) - } -} - -// GetImage provides a mock function with given fields: imageID -func (_m *MockLocalImageCache) GetImage(imageID string) (types.ImageInfo, error) { - ret := _m.Called(imageID) - - var r0 types.ImageInfo - if rf, ok := ret.Get(0).(func(string) types.ImageInfo); ok { - r0 = rf(imageID) - } else { - r0 = ret.Get(0).(types.ImageInfo) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(imageID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type LocalImageCacheGetLayerArgs struct { - DiffID string - DiffIDAnything bool -} - -type LocalImageCacheGetLayerReturns struct { - LayerInfo types.LayerInfo - Err error -} - -type LocalImageCacheGetLayerExpectation struct { - Args LocalImageCacheGetLayerArgs - Returns LocalImageCacheGetLayerReturns -} - -func (_m *MockLocalImageCache) ApplyGetLayerExpectation(e LocalImageCacheGetLayerExpectation) { - var args []interface{} - if e.Args.DiffIDAnything { - args = append(args, mock.Anything) - } else { - args = append(args, e.Args.DiffID) - } - _m.On("GetLayer", args...).Return(e.Returns.LayerInfo, e.Returns.Err) -} - -func (_m *MockLocalImageCache) ApplyGetLayerExpectations(expectations []LocalImageCacheGetLayerExpectation) { - for _, e := range expectations { - _m.ApplyGetLayerExpectation(e) - } -} - -// GetLayer provides a mock function with given fields: diffID -func (_m *MockLocalImageCache) GetLayer(diffID string) (types.LayerInfo, error) { - ret := _m.Called(diffID) - - var r0 types.LayerInfo - if rf, ok := ret.Get(0).(func(string) types.LayerInfo); ok { - r0 = rf(diffID) - } else { - r0 = ret.Get(0).(types.LayerInfo) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(diffID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} diff --git a/cache/s3.go b/cache/s3.go index 4baa653375..9245757fb9 100644 --- a/cache/s3.go +++ b/cache/s3.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "github.com/aquasecurity/fanal/types" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" @@ -36,19 +37,19 @@ func NewS3Cache(region string, bucketName string) (S3Cache, error) { }, nil } -func (cache S3Cache) PutLayer(diffID string, layerInfo types.LayerInfo) error { +func (cache S3Cache) PutLayer(diffID string, layerInfo types.BlobInfo) error { if _, err := v1.NewHash(diffID); err != nil { return xerrors.Errorf("invalid diffID (%s): %w", diffID, err) } - key := fmt.Sprintf("%s/%s", layerBucket, diffID) + key := fmt.Sprintf("%s/%s", blobBucket, diffID) if err := cache.put(key, layerInfo); err != nil { return xerrors.Errorf("unable to store layer information in cache (%s): %w", diffID, err) } return nil } -func (cache S3Cache) PutImage(imageID string, imageConfig types.ImageInfo) (err error) { - key := fmt.Sprintf("%s/%s", imageBucket, imageID) +func (cache S3Cache) PutImage(imageID string, imageConfig types.ArtifactInfo) (err error) { + key := fmt.Sprintf("%s/%s", artifactBucket, imageID) if err := cache.put(key, imageConfig); err != nil { return xerrors.Errorf("unable to store image information in cache (%s): %w", imageID, err) } @@ -79,39 +80,39 @@ func (cache S3Cache) put(key string, body interface{}) (err error) { return nil } -func (cache S3Cache) GetLayer(diffID string) (types.LayerInfo, error) { - var layerInfo types.LayerInfo +func (cache S3Cache) GetLayer(diffID string) (types.BlobInfo, error) { + var layerInfo types.BlobInfo buf := aws.NewWriteAtBuffer([]byte{}) _, err := cache.downloader.Download(buf, &s3.GetObjectInput{ Bucket: aws.String(cache.bucketName), - Key: aws.String(fmt.Sprintf("%s/%s", layerBucket, diffID)), //TODO add prefix + Key: aws.String(fmt.Sprintf("%s/%s", blobBucket, diffID)), //TODO add prefix }) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("failed to get layer from the cache: %w", err) + return types.BlobInfo{}, xerrors.Errorf("failed to get layer from the cache: %w", err) } err = json.Unmarshal(buf.Bytes(), &layerInfo) if err != nil { - return types.LayerInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) + return types.BlobInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) } return layerInfo, nil } -func (cache S3Cache) GetImage(imageID string) (types.ImageInfo, error) { - var info types.ImageInfo +func (cache S3Cache) GetImage(imageID string) (types.ArtifactInfo, error) { + var info types.ArtifactInfo buf := aws.NewWriteAtBuffer([]byte{}) _, err := cache.downloader.Download(buf, &s3.GetObjectInput{ Bucket: aws.String(cache.bucketName), - Key: aws.String(fmt.Sprintf("%s/%s", imageBucket, imageID)), //TODO add prefix + Key: aws.String(fmt.Sprintf("%s/%s", artifactBucket, imageID)), //TODO add prefix }) if err != nil { - return types.ImageInfo{}, xerrors.Errorf("failed to get image from the cache: %w", err) + return types.ArtifactInfo{}, xerrors.Errorf("failed to get image from the cache: %w", err) } err = json.Unmarshal(buf.Bytes(), &info) if err != nil { - return types.ImageInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) + return types.ArtifactInfo{}, xerrors.Errorf("JSON unmarshal error: %w", err) } return info, nil @@ -127,7 +128,7 @@ func (cache S3Cache) MissingLayers(imageID string, layerIDs []string) (bool, []s missingLayerIDs = append(missingLayerIDs, layerID) continue } - if layerInfo.SchemaVersion != types.LayerJSONSchemaVersion { + if layerInfo.SchemaVersion != types.BlobJSONSchemaVersion { missingLayerIDs = append(missingLayerIDs, layerID) } } @@ -137,7 +138,7 @@ func (cache S3Cache) MissingLayers(imageID string, layerIDs []string) (bool, []s // error means cache missed image info return true, missingLayerIDs, nil } - if imageInfo.SchemaVersion != types.ImageJSONSchemaVersion { + if imageInfo.SchemaVersion != types.ArtifactJSONSchemaVersion { missingImage = true } diff --git a/cache/s3_test.go b/cache/s3_test.go index 97a1c53a07..13c1555aaf 100644 --- a/cache/s3_test.go +++ b/cache/s3_test.go @@ -33,7 +33,7 @@ func TestS3Cache_PutLayer(t *testing.T) { } type args struct { diffID string - layerInfo types.LayerInfo + layerInfo types.BlobInfo } tests := []struct { name string @@ -45,7 +45,7 @@ func TestS3Cache_PutLayer(t *testing.T) { name: "PutLayer", fields: fields{S3: mockSvc, BucketName: "test"}, args: args{diffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", - layerInfo: types.LayerInfo{ + layerInfo: types.BlobInfo{ SchemaVersion: 1, OS: &types.OS{ Family: "alpine", @@ -78,7 +78,7 @@ func TestS3Cache_PutImage(t *testing.T) { } type args struct { imageID string - imageConfig types.ImageInfo + imageConfig types.ArtifactInfo } tests := []struct { name string @@ -90,7 +90,7 @@ func TestS3Cache_PutImage(t *testing.T) { name: "Happy path", fields: fields{S3: mockSvc, BucketName: "test"}, args: args{imageID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", - imageConfig: types.ImageInfo{ + imageConfig: types.ArtifactInfo{ SchemaVersion: 1, Architecture: "amd64", Created: time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC), diff --git a/cache/testdata/broken-image.db b/cache/testdata/broken-image.db index 1e1874eb60..e2f2c84bf2 100644 Binary files a/cache/testdata/broken-image.db and b/cache/testdata/broken-image.db differ diff --git a/cache/testdata/broken-layer.db b/cache/testdata/broken-layer.db index c252987228..434a88d281 100644 Binary files a/cache/testdata/broken-layer.db and b/cache/testdata/broken-layer.db differ diff --git a/cache/testdata/different-image-schema.db b/cache/testdata/different-image-schema.db index 07e0f2fb91..6dfa95f3ba 100644 Binary files a/cache/testdata/different-image-schema.db and b/cache/testdata/different-image-schema.db differ diff --git a/cache/testdata/fanal.db b/cache/testdata/fanal.db index e739cef749..c2125756df 100644 Binary files a/cache/testdata/fanal.db and b/cache/testdata/fanal.db differ diff --git a/cmd/fanal/main.go b/cmd/fanal/main.go index bfbe0fd93a..2297c4fe45 100644 --- a/cmd/fanal/main.go +++ b/cmd/fanal/main.go @@ -89,7 +89,7 @@ func run() (err error) { } a := analyzer.NewApplier(c) - mergedLayer, err := a.ApplyLayers(imageInfo.ID, imageInfo.LayerIDs) + mergedLayer, err := a.ApplyLayers(imageInfo.ID, imageInfo.BlobIDs) if err != nil { switch err { case analyzer.ErrUnknownOS, analyzer.ErrNoPkgsDetected: diff --git a/extractor/docker/docker.go b/extractor/docker/docker.go index 255cf67a27..baec04c21b 100644 --- a/extractor/docker/docker.go +++ b/extractor/docker/docker.go @@ -98,7 +98,7 @@ func containsLibrary(e godeptypes.Library, s []types.LibraryInfo) bool { return false } -func lookupOriginLayerForPkg(pkg types.Package, layers []types.LayerInfo) (string, string) { +func lookupOriginLayerForPkg(pkg types.Package, layers []types.BlobInfo) (string, string) { for _, layer := range layers { for _, info := range layer.PackageInfos { if containsPackage(pkg, info.Packages) { @@ -109,7 +109,7 @@ func lookupOriginLayerForPkg(pkg types.Package, layers []types.LayerInfo) (strin return "", "" } -func lookupOriginLayerForLib(filePath string, lib godeptypes.Library, layers []types.LayerInfo) (string, string) { +func lookupOriginLayerForLib(filePath string, lib godeptypes.Library, layers []types.BlobInfo) (string, string) { for _, layer := range layers { for _, layerApp := range layer.Applications { if filePath != layerApp.FilePath { @@ -123,10 +123,10 @@ func lookupOriginLayerForLib(filePath string, lib godeptypes.Library, layers []t return "", "" } -func ApplyLayers(layers []types.LayerInfo) types.ImageDetail { +func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { sep := "/" nestedMap := nested.Nested{} - var mergedLayer types.ImageDetail + var mergedLayer types.ArtifactDetail for _, layer := range layers { for _, opqDir := range layer.OpaqueDirs { diff --git a/extractor/docker/docker_test.go b/extractor/docker/docker_test.go index 520e5fcca1..ed9c0636c7 100644 --- a/extractor/docker/docker_test.go +++ b/extractor/docker/docker_test.go @@ -21,13 +21,13 @@ import ( func TestApplyLayers(t *testing.T) { testCases := []struct { - name string - inputLayers []types.LayerInfo - expectedImageDetail types.ImageDetail + name string + inputLayers []types.BlobInfo + expectedArtifactDetail types.ArtifactDetail }{ { name: "happy path", - inputLayers: []types.LayerInfo{ + inputLayers: []types.BlobInfo{ { SchemaVersion: 1, Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", @@ -121,7 +121,7 @@ func TestApplyLayers(t *testing.T) { }, }, }, - expectedImageDetail: types.ImageDetail{ + expectedArtifactDetail: types.ArtifactDetail{ OS: &types.OS{ Family: "alpine", Name: "3.10", @@ -168,7 +168,7 @@ func TestApplyLayers(t *testing.T) { }, { name: "happy path with removed and updated lockfile", - inputLayers: []types.LayerInfo{ + inputLayers: []types.BlobInfo{ { SchemaVersion: 1, Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", @@ -249,7 +249,7 @@ func TestApplyLayers(t *testing.T) { WhiteoutFiles: []string{"app/composer.lock"}, }, }, - expectedImageDetail: types.ImageDetail{ + expectedArtifactDetail: types.ArtifactDetail{ OS: &types.OS{ Family: "alpine", Name: "3.10", @@ -302,7 +302,7 @@ func TestApplyLayers(t *testing.T) { }, { name: "happy path with status.d", - inputLayers: []types.LayerInfo{ + inputLayers: []types.BlobInfo{ { SchemaVersion: 1, Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", @@ -357,7 +357,7 @@ func TestApplyLayers(t *testing.T) { OpaqueDirs: []string{"app"}, }, }, - expectedImageDetail: types.ImageDetail{ + expectedArtifactDetail: types.ArtifactDetail{ OS: &types.OS{ Family: "debian", Name: "8", @@ -388,19 +388,19 @@ func TestApplyLayers(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - gotImageDetail := ApplyLayers(tc.inputLayers) - sort.Slice(gotImageDetail.Packages, func(i, j int) bool { - return gotImageDetail.Packages[i].Name < gotImageDetail.Packages[j].Name + gotArtifactDetail := ApplyLayers(tc.inputLayers) + sort.Slice(gotArtifactDetail.Packages, func(i, j int) bool { + return gotArtifactDetail.Packages[i].Name < gotArtifactDetail.Packages[j].Name }) - sort.Slice(gotImageDetail.Applications, func(i, j int) bool { - return gotImageDetail.Applications[i].FilePath < gotImageDetail.Applications[j].FilePath + sort.Slice(gotArtifactDetail.Applications, func(i, j int) bool { + return gotArtifactDetail.Applications[i].FilePath < gotArtifactDetail.Applications[j].FilePath }) - for _, app := range gotImageDetail.Applications { + for _, app := range gotArtifactDetail.Applications { sort.Slice(app.Libraries, func(i, j int) bool { return app.Libraries[i].Library.Name < app.Libraries[j].Library.Name }) } - assert.Equal(t, tc.expectedImageDetail, gotImageDetail, tc.name) + assert.Equal(t, tc.expectedArtifactDetail, gotArtifactDetail, tc.name) }) } } diff --git a/integration/library_test.go b/integration/library_test.go index 4b385391d7..93a20cd029 100644 --- a/integration/library_test.go +++ b/integration/library_test.go @@ -242,19 +242,19 @@ func TestFanal_Library_TarMode(t *testing.T) { func runChecks(t *testing.T, ctx context.Context, ac analyzer.Config, applier analyzer.Applier, tc testCase) { imageInfo, err := ac.Analyze(ctx) require.NoError(t, err, tc.name) - imageDetail, err := applier.ApplyLayers(imageInfo.ID, imageInfo.LayerIDs) + imageDetail, err := applier.ApplyLayers(imageInfo.ID, imageInfo.BlobIDs) require.NoError(t, err, tc.name) commonChecks(t, imageDetail, tc) } -func commonChecks(t *testing.T, detail types.ImageDetail, tc testCase) { +func commonChecks(t *testing.T, detail types.ArtifactDetail, tc testCase) { assert.Equal(t, tc.expectedOS, *detail.OS, tc.name) checkPackages(t, detail, tc) checkPackageFromCommands(t, detail, tc) checkLibraries(detail, t, tc) } -func checkPackages(t *testing.T, detail types.ImageDetail, tc testCase) { +func checkPackages(t *testing.T, detail types.ArtifactDetail, tc testCase) { r := strings.NewReplacer("/", "-", ":", "-") goldenFile := fmt.Sprintf("testdata/goldens/packages/%s.json.golden", r.Replace(tc.imageName)) data, err := ioutil.ReadFile(goldenFile) @@ -274,7 +274,7 @@ func checkPackages(t *testing.T, detail types.ImageDetail, tc testCase) { } } -func checkLibraries(detail types.ImageDetail, t *testing.T, tc testCase) { +func checkLibraries(detail types.ArtifactDetail, t *testing.T, tc testCase) { if tc.expectedLibraries != "" { data, _ := ioutil.ReadFile(tc.expectedLibraries) var expectedLibraries map[types.FilePath][]godeptypes.Library @@ -286,7 +286,7 @@ func checkLibraries(detail types.ImageDetail, t *testing.T, tc testCase) { } } -func checkPackageFromCommands(t *testing.T, detail types.ImageDetail, tc testCase) { +func checkPackageFromCommands(t *testing.T, detail types.ArtifactDetail, tc testCase) { if tc.expectedPkgsFromCmds != "" { data, _ := ioutil.ReadFile(tc.expectedPkgsFromCmds) var expectedPkgsFromCmds []types.Package diff --git a/integration/registry_test.go b/integration/registry_test.go index 70a7b5d6c5..7bd8379447 100644 --- a/integration/registry_test.go +++ b/integration/registry_test.go @@ -177,7 +177,7 @@ func getRegistryURL(ctx context.Context, registryC testcontainers.Container, exp return url.Parse(urlStr) } -func analyze(ctx context.Context, imageRef string, opt types.DockerOption) (*types.ImageDetail, error) { +func analyze(ctx context.Context, imageRef string, opt types.DockerOption) (*types.ArtifactDetail, error) { d, err := ioutil.TempDir("", "TestRegistry-*") if err != nil { return nil, err @@ -209,7 +209,7 @@ func analyze(ctx context.Context, imageRef string, opt types.DockerOption) (*typ return nil, err } - imageDetail, err := applier.ApplyLayers(imageInfo.ID, imageInfo.LayerIDs) + imageDetail, err := applier.ApplyLayers(imageInfo.ID, imageInfo.BlobIDs) if err != nil { return nil, err } diff --git a/types/const.go b/types/const.go index 8ee6e4ae68..51cafe1baf 100644 --- a/types/const.go +++ b/types/const.go @@ -1,6 +1,6 @@ package types const ( - ImageJSONSchemaVersion = 1 - LayerJSONSchemaVersion = 1 + ArtifactJSONSchemaVersion = 1 + BlobJSONSchemaVersion = 1 ) diff --git a/types/image.go b/types/image.go index 4af3ba205b..82a65ff6ef 100644 --- a/types/image.go +++ b/types/image.go @@ -53,23 +53,15 @@ type Application struct { Libraries []LibraryInfo } -type ImageReference struct { - Name string // image name or tar file name - ID string - LayerIDs []string +// ArtifactReference represents a reference of container image, local filesystem and repository +type ArtifactReference struct { + Name string // image name, tar file name, directory or repository name + ID string + BlobIDs []string } -type ImageDetail struct { - OS *OS `json:",omitempty"` - Packages []Package `json:",omitempty"` - Applications []Application `json:",omitempty"` - - // HistoryPackages are packages extracted from RUN instructions - HistoryPackages []Package `json:",omitempty"` -} - -// ImageInfo is stored in cache -type ImageInfo struct { +// ArtifactInfo is stored in cache +type ArtifactInfo struct { SchemaVersion int Architecture string Created time.Time @@ -77,11 +69,11 @@ type ImageInfo struct { OS string // HistoryPackages are packages extracted from RUN instructions - HistoryPackages []Package + HistoryPackages []Package `json:",omitempty"` } -// LayerInfo is stored in cache -type LayerInfo struct { +// BlobInfo is stored in cache +type BlobInfo struct { SchemaVersion int Digest string `json:",omitempty"` DiffID string `json:",omitempty"` @@ -91,3 +83,13 @@ type LayerInfo struct { OpaqueDirs []string `json:",omitempty"` WhiteoutFiles []string `json:",omitempty"` } + +// ArtifactDetail is generated by applying blobs +type ArtifactDetail struct { + OS *OS `json:",omitempty"` + Packages []Package `json:",omitempty"` + Applications []Application `json:",omitempty"` + + // HistoryPackages are packages extracted from RUN instructions + HistoryPackages []Package `json:",omitempty"` +}