mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
add source.Location + reorient Resolvers to use it
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
9668341a14
commit
b694dacb21
@ -8,6 +8,8 @@ import (
|
|||||||
"github.com/anchore/stereoscope/pkg/image"
|
"github.com/anchore/stereoscope/pkg/image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ Resolver = &AllLayersResolver{}
|
||||||
|
|
||||||
// AllLayersResolver implements path and content access for the AllLayers source option for container image data sources.
|
// AllLayersResolver implements path and content access for the AllLayers source option for container image data sources.
|
||||||
type AllLayersResolver struct {
|
type AllLayersResolver struct {
|
||||||
img *image.Image
|
img *image.Image
|
||||||
@ -61,14 +63,14 @@ func (r *AllLayersResolver) fileByRef(ref file.Reference, uniqueFileIDs file.Ref
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FilesByPath returns all file.References that match the given paths from any layer in the image.
|
// FilesByPath returns all file.References that match the given paths from any layer in the image.
|
||||||
func (r *AllLayersResolver) FilesByPath(paths ...file.Path) ([]file.Reference, error) {
|
func (r *AllLayersResolver) FilesByPath(paths ...string) ([]Location, error) {
|
||||||
uniqueFileIDs := file.NewFileReferenceSet()
|
uniqueFileIDs := file.NewFileReferenceSet()
|
||||||
uniqueFiles := make([]file.Reference, 0)
|
uniqueLocations := make([]Location, 0)
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
for idx, layerIdx := range r.layers {
|
for idx, layerIdx := range r.layers {
|
||||||
tree := r.img.Layers[layerIdx].Tree
|
tree := r.img.Layers[layerIdx].Tree
|
||||||
ref := tree.File(path)
|
ref := tree.File(file.Path(path))
|
||||||
if ref == nil {
|
if ref == nil {
|
||||||
// no file found, keep looking through layers
|
// no file found, keep looking through layers
|
||||||
continue
|
continue
|
||||||
@ -91,17 +93,18 @@ func (r *AllLayersResolver) FilesByPath(paths ...file.Path) ([]file.Reference, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uniqueFiles = append(uniqueFiles, results...)
|
for _, result := range results {
|
||||||
|
uniqueLocations = append(uniqueLocations, newLocationFromImage(result, r.img))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return uniqueLocations, nil
|
||||||
return uniqueFiles, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
|
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
|
||||||
func (r *AllLayersResolver) FilesByGlob(patterns ...string) ([]file.Reference, error) {
|
func (r *AllLayersResolver) FilesByGlob(patterns ...string) ([]Location, error) {
|
||||||
uniqueFileIDs := file.NewFileReferenceSet()
|
uniqueFileIDs := file.NewFileReferenceSet()
|
||||||
uniqueFiles := make([]file.Reference, 0)
|
uniqueLocations := make([]Location, 0)
|
||||||
|
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
for idx, layerIdx := range r.layers {
|
for idx, layerIdx := range r.layers {
|
||||||
@ -128,31 +131,63 @@ func (r *AllLayersResolver) FilesByGlob(patterns ...string) ([]file.Reference, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uniqueFiles = append(uniqueFiles, results...)
|
for _, result := range results {
|
||||||
|
uniqueLocations = append(uniqueLocations, newLocationFromImage(result, r.img))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uniqueFiles, nil
|
return uniqueLocations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AllLayersResolver) RelativeFileByPath(reference file.Reference, path string) (*file.Reference, error) {
|
func (r *AllLayersResolver) RelativeFileByPath(location Location, path string) *Location {
|
||||||
entry, err := r.img.FileCatalog.Get(reference)
|
entry, err := r.img.FileCatalog.Get(location.ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.Source.SquashedTree.File(file.Path(path)), nil
|
relativeRef := entry.Source.SquashedTree.File(file.Path(path))
|
||||||
|
if relativeRef == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
relativeLocation := newLocationFromImage(*relativeRef, r.img)
|
||||||
|
|
||||||
|
return &relativeLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultipleFileContentsByRef returns the file contents for all file.References relative to the image. Note that a
|
// MultipleFileContentsByRef returns the file contents for all file.References relative to the image. Note that a
|
||||||
// file.Reference is a path relative to a particular layer.
|
// file.Reference is a path relative to a particular layer.
|
||||||
func (r *AllLayersResolver) MultipleFileContentsByRef(f ...file.Reference) (map[file.Reference]string, error) {
|
func (r *AllLayersResolver) MultipleFileContentsByRef(locations []Location) (map[Location]string, error) {
|
||||||
return r.img.MultipleFileContentsByRef(f...)
|
return mapLocationRefs(r.img.MultipleFileContentsByRef, locations)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileContentsByRef fetches file contents for a single file reference, irregardless of the source layer.
|
// FileContentsByRef fetches file contents for a single file reference, irregardless of the source layer.
|
||||||
// If the path does not exist an error is returned.
|
// If the path does not exist an error is returned.
|
||||||
func (r *AllLayersResolver) FileContentsByRef(ref file.Reference) (string, error) {
|
func (r *AllLayersResolver) FileContentsByRef(location Location) (string, error) {
|
||||||
return r.img.FileContentsByRef(ref)
|
return r.img.FileContentsByRef(location.ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
type multiContentFetcher func(refs ...file.Reference) (map[file.Reference]string, error)
|
||||||
|
|
||||||
|
func mapLocationRefs(callback multiContentFetcher, locations []Location) (map[Location]string, error) {
|
||||||
|
var fileRefs = make([]file.Reference, len(locations))
|
||||||
|
var locationByRefs = make(map[file.Reference]Location)
|
||||||
|
var results = make(map[Location]string)
|
||||||
|
|
||||||
|
for i, location := range locations {
|
||||||
|
locationByRefs[location.ref] = location
|
||||||
|
fileRefs[i] = location.ref
|
||||||
|
}
|
||||||
|
|
||||||
|
contentsByRef, err := callback(fileRefs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for ref, content := range contentsByRef {
|
||||||
|
results[locationByRefs[ref]] = content
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,14 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
"github.com/docker/distribution/reference"
|
||||||
|
|
||||||
"github.com/anchore/syft/internal/log"
|
"github.com/anchore/syft/internal/log"
|
||||||
"github.com/bmatcuk/doublestar"
|
"github.com/bmatcuk/doublestar"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ Resolver = &DirectoryResolver{}
|
||||||
|
|
||||||
// DirectoryResolver implements path and content access for the directory data source.
|
// DirectoryResolver implements path and content access for the directory data source.
|
||||||
type DirectoryResolver struct {
|
type DirectoryResolver struct {
|
||||||
Path string
|
Path string
|
||||||
@ -23,11 +26,11 @@ func (s DirectoryResolver) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FilesByPath returns all file.References that match the given paths from the directory.
|
// FilesByPath returns all file.References that match the given paths from the directory.
|
||||||
func (s DirectoryResolver) FilesByPath(userPaths ...file.Path) ([]file.Reference, error) {
|
func (s DirectoryResolver) FilesByPath(userPaths ...string) ([]Location, error) {
|
||||||
var references = make([]file.Reference, 0)
|
var references = make([]Location, 0)
|
||||||
|
|
||||||
for _, userPath := range userPaths {
|
for _, userPath := range userPaths {
|
||||||
userStrPath := string(userPath)
|
userStrPath := userPath
|
||||||
|
|
||||||
if filepath.IsAbs(userStrPath) {
|
if filepath.IsAbs(userStrPath) {
|
||||||
// a path relative to root should be prefixed with the resolvers directory path, otherwise it should be left as is
|
// a path relative to root should be prefixed with the resolvers directory path, otherwise it should be left as is
|
||||||
@ -45,33 +48,24 @@ func (s DirectoryResolver) FilesByPath(userPaths ...file.Path) ([]file.Reference
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
references = append(references, file.NewFileReference(file.Path(userStrPath)))
|
references = append(references, newLocation(userStrPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
return references, nil
|
return references, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileContents(path file.Path) ([]byte, error) {
|
|
||||||
contents, err := ioutil.ReadFile(string(path))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return contents, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
|
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
|
||||||
func (s DirectoryResolver) FilesByGlob(patterns ...string) ([]file.Reference, error) {
|
func (s DirectoryResolver) FilesByGlob(patterns ...string) ([]Location, error) {
|
||||||
result := make([]file.Reference, 0)
|
result := make([]Location, 0)
|
||||||
|
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
pathPattern := path.Join(s.Path, pattern)
|
pathPattern := path.Join(s.Path, pattern)
|
||||||
matches, err := doublestar.Glob(pathPattern)
|
pathMatches, err := doublestar.Glob(pathPattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, match := range matches {
|
for _, matchedPath := range pathMatches {
|
||||||
fileMeta, err := os.Stat(match)
|
fileMeta, err := os.Stat(matchedPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -81,47 +75,55 @@ func (s DirectoryResolver) FilesByGlob(patterns ...string) ([]file.Reference, er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
matchedPath := file.Path(match)
|
result = append(result, newLocation(matchedPath))
|
||||||
result = append(result, file.NewFileReference(matchedPath))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DirectoryResolver) RelativeFileByPath(_ file.Reference, path string) (*file.Reference, error) {
|
func (s *DirectoryResolver) RelativeFileByPath(_ Location, path string) *Location {
|
||||||
paths, err := s.FilesByPath(file.Path(path))
|
paths, err := s.FilesByPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil
|
||||||
}
|
}
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &paths[0], nil
|
return &paths[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultipleFileContentsByRef returns the file contents for all file.References relative a directory.
|
// MultipleFileContentsByRef returns the file contents for all file.References relative a directory.
|
||||||
func (s DirectoryResolver) MultipleFileContentsByRef(f ...file.Reference) (map[file.Reference]string, error) {
|
func (s DirectoryResolver) MultipleFileContentsByRef(locations []Location) (map[Location]string, error) {
|
||||||
refContents := make(map[file.Reference]string)
|
refContents := make(map[Location]string)
|
||||||
for _, fileRef := range f {
|
for _, location := range locations {
|
||||||
contents, err := fileContents(fileRef.Path)
|
contents, err := fileContents(location.Path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not read contents of file: %s", fileRef.Path)
|
return nil, fmt.Errorf("could not read contents of file: %s", location.Path)
|
||||||
}
|
}
|
||||||
refContents[fileRef] = string(contents)
|
refContents[location] = string(contents)
|
||||||
}
|
}
|
||||||
return refContents, nil
|
return refContents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileContentsByRef fetches file contents for a single file reference relative to a directory.
|
// FileContentsByRef fetches file contents for a single file reference relative to a directory.
|
||||||
// If the path does not exist an error is returned.
|
// If the path does not exist an error is returned.
|
||||||
func (s DirectoryResolver) FileContentsByRef(reference file.Reference) (string, error) {
|
func (s DirectoryResolver) FileContentsByRef(location Location) (string, error) {
|
||||||
contents, err := fileContents(reference.Path)
|
contents, err := fileContents(location.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not read contents of file: %s", reference.Path)
|
return "", fmt.Errorf("could not read contents of file: %s", reference.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(contents), nil
|
return string(contents), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fileContents(path string) ([]byte, error) {
|
||||||
|
contents, err := ioutil.ReadFile(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return contents, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import (
|
|||||||
"github.com/anchore/stereoscope/pkg/image"
|
"github.com/anchore/stereoscope/pkg/image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ Resolver = &ImageSquashResolver{}
|
||||||
|
|
||||||
// ImageSquashResolver implements path and content access for the Squashed source option for container image data sources.
|
// ImageSquashResolver implements path and content access for the Squashed source option for container image data sources.
|
||||||
type ImageSquashResolver struct {
|
type ImageSquashResolver struct {
|
||||||
img *image.Image
|
img *image.Image
|
||||||
@ -21,13 +23,13 @@ func NewImageSquashResolver(img *image.Image) (*ImageSquashResolver, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FilesByPath returns all file.References that match the given paths within the squashed representation of the image.
|
// FilesByPath returns all file.References that match the given paths within the squashed representation of the image.
|
||||||
func (r *ImageSquashResolver) FilesByPath(paths ...file.Path) ([]file.Reference, error) {
|
func (r *ImageSquashResolver) FilesByPath(paths ...string) ([]Location, error) {
|
||||||
uniqueFileIDs := file.NewFileReferenceSet()
|
uniqueFileIDs := file.NewFileReferenceSet()
|
||||||
uniqueFiles := make([]file.Reference, 0)
|
uniqueLocations := make([]Location, 0)
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
tree := r.img.SquashedTree()
|
tree := r.img.SquashedTree()
|
||||||
ref := tree.File(path)
|
ref := tree.File(file.Path(path))
|
||||||
if ref == nil {
|
if ref == nil {
|
||||||
// no file found, keep looking through layers
|
// no file found, keep looking through layers
|
||||||
continue
|
continue
|
||||||
@ -54,17 +56,17 @@ func (r *ImageSquashResolver) FilesByPath(paths ...file.Path) ([]file.Reference,
|
|||||||
|
|
||||||
if resolvedRef != nil && !uniqueFileIDs.Contains(*resolvedRef) {
|
if resolvedRef != nil && !uniqueFileIDs.Contains(*resolvedRef) {
|
||||||
uniqueFileIDs.Add(*resolvedRef)
|
uniqueFileIDs.Add(*resolvedRef)
|
||||||
uniqueFiles = append(uniqueFiles, *resolvedRef)
|
uniqueLocations = append(uniqueLocations, newLocationFromImage(*resolvedRef, r.img))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uniqueFiles, nil
|
return uniqueLocations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilesByGlob returns all file.References that match the given path glob pattern within the squashed representation of the image.
|
// FilesByGlob returns all file.References that match the given path glob pattern within the squashed representation of the image.
|
||||||
func (r *ImageSquashResolver) FilesByGlob(patterns ...string) ([]file.Reference, error) {
|
func (r *ImageSquashResolver) FilesByGlob(patterns ...string) ([]Location, error) {
|
||||||
uniqueFileIDs := file.NewFileReferenceSet()
|
uniqueFileIDs := file.NewFileReferenceSet()
|
||||||
uniqueFiles := make([]file.Reference, 0)
|
uniqueLocations := make([]Location, 0)
|
||||||
|
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
refs, err := r.img.SquashedTree().FilesByGlob(pattern)
|
refs, err := r.img.SquashedTree().FilesByGlob(pattern)
|
||||||
@ -86,42 +88,42 @@ func (r *ImageSquashResolver) FilesByGlob(patterns ...string) ([]file.Reference,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedRefs, err := r.FilesByPath(ref.Path)
|
resolvedLocations, err := r.FilesByPath(string(ref.Path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find files by path (ref=%+v): %w", ref, err)
|
return nil, fmt.Errorf("failed to find files by path (ref=%+v): %w", ref, err)
|
||||||
}
|
}
|
||||||
for _, resolvedRef := range resolvedRefs {
|
for _, resolvedLocation := range resolvedLocations {
|
||||||
if !uniqueFileIDs.Contains(resolvedRef) {
|
if !uniqueFileIDs.Contains(resolvedLocation.ref) {
|
||||||
uniqueFileIDs.Add(resolvedRef)
|
uniqueFileIDs.Add(resolvedLocation.ref)
|
||||||
uniqueFiles = append(uniqueFiles, resolvedRef)
|
uniqueLocations = append(uniqueLocations, resolvedLocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uniqueFiles, nil
|
return uniqueLocations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ImageSquashResolver) RelativeFileByPath(reference file.Reference, path string) (*file.Reference, error) {
|
func (r *ImageSquashResolver) RelativeFileByPath(_ Location, path string) *Location {
|
||||||
paths, err := r.FilesByPath(file.Path(path))
|
paths, err := r.FilesByPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil
|
||||||
}
|
}
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &paths[0], nil
|
return &paths[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultipleFileContentsByRef returns the file contents for all file.References relative to the image. Note that a
|
// MultipleFileContentsByRef returns the file contents for all file.References relative to the image. Note that a
|
||||||
// file.Reference is a path relative to a particular layer, in this case only from the squashed representation.
|
// file.Reference is a path relative to a particular layer, in this case only from the squashed representation.
|
||||||
func (r *ImageSquashResolver) MultipleFileContentsByRef(f ...file.Reference) (map[file.Reference]string, error) {
|
func (r *ImageSquashResolver) MultipleFileContentsByRef(locations []Location) (map[Location]string, error) {
|
||||||
return r.img.MultipleFileContentsByRef(f...)
|
return mapLocationRefs(r.img.MultipleFileContentsByRef, locations)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileContentsByRef fetches file contents for a single file reference, irregardless of the source layer.
|
// FileContentsByRef fetches file contents for a single file reference, irregardless of the source layer.
|
||||||
// If the path does not exist an error is returned.
|
// If the path does not exist an error is returned.
|
||||||
func (r *ImageSquashResolver) FileContentsByRef(ref file.Reference) (string, error) {
|
func (r *ImageSquashResolver) FileContentsByRef(location Location) (string, error) {
|
||||||
return r.img.FileContentsByRef(ref)
|
return r.img.FileContentsByRef(location.ref)
|
||||||
}
|
}
|
||||||
|
|||||||
46
syft/source/location.go
Normal file
46
syft/source/location.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package source
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
|
|
||||||
|
"github.com/anchore/stereoscope/pkg/file"
|
||||||
|
"github.com/anchore/stereoscope/pkg/image"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
LayerIndex uint `json:"layerIndex"`
|
||||||
|
LayerID string `json:"layerID"`
|
||||||
|
ref file.Reference
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLocation(path string) Location {
|
||||||
|
return Location{
|
||||||
|
Path: path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLocationFromRef(ref file.Reference) Location {
|
||||||
|
return Location{
|
||||||
|
Path: string(ref.Path),
|
||||||
|
ref: ref,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLocationFromImage(ref file.Reference, img *image.Image) Location {
|
||||||
|
entry, err := img.FileCatalog.Get(ref)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("unable to find file catalog entry for ref=%+v", ref)
|
||||||
|
return Location{
|
||||||
|
Path: string(ref.Path),
|
||||||
|
ref: ref,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Location{
|
||||||
|
Path: string(ref.Path),
|
||||||
|
LayerIndex: entry.Source.Metadata.Index,
|
||||||
|
LayerID: entry.Source.Metadata.Digest,
|
||||||
|
ref: ref,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,7 +3,6 @@ package source
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
|
||||||
"github.com/anchore/stereoscope/pkg/image"
|
"github.com/anchore/stereoscope/pkg/image"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,30 +14,30 @@ type Resolver interface {
|
|||||||
|
|
||||||
// ContentResolver knows how to get file content for given file.References
|
// ContentResolver knows how to get file content for given file.References
|
||||||
type ContentResolver interface {
|
type ContentResolver interface {
|
||||||
FileContentsByRef(ref file.Reference) (string, error)
|
FileContentsByRef(Location) (string, error)
|
||||||
MultipleFileContentsByRef(f ...file.Reference) (map[file.Reference]string, error)
|
MultipleFileContentsByRef([]Location) (map[Location]string, error)
|
||||||
// TODO: we should consider refactoring to return a set of io.Readers or file.Openers instead of the full contents themselves (allow for optional buffering).
|
// TODO: we should consider refactoring to return a set of io.Readers or file.Openers instead of the full contents themselves (allow for optional buffering).
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileResolver knows how to get file.References for given string paths and globs
|
// FileResolver knows how to get file.References for given string paths and globs
|
||||||
type FileResolver interface {
|
type FileResolver interface {
|
||||||
// FilesByPath fetches a set of file references which have the given path (for an image, there may be multiple matches)
|
// FilesByPath fetches a set of file references which have the given path (for an image, there may be multiple matches)
|
||||||
FilesByPath(paths ...file.Path) ([]file.Reference, error)
|
FilesByPath(paths ...string) ([]Location, error)
|
||||||
// FilesByGlob fetches a set of file references which the given glob matches
|
// FilesByGlob fetches a set of file references which the given glob matches
|
||||||
FilesByGlob(patterns ...string) ([]file.Reference, error)
|
FilesByGlob(patterns ...string) ([]Location, error)
|
||||||
// RelativeFileByPath fetches a single file at the given path relative to the layer squash of the given reference.
|
// RelativeFileByPath fetches a single file at the given path relative to the layer squash of the given reference.
|
||||||
// This is helpful when attempting to find a file that is in the same layer or lower as another file.
|
// This is helpful when attempting to find a file that is in the same layer or lower as another file.
|
||||||
RelativeFileByPath(reference file.Reference, path string) (*file.Reference, error)
|
RelativeFileByPath(_ Location, path string) *Location
|
||||||
}
|
}
|
||||||
|
|
||||||
// getImageResolver returns the appropriate resolve for a container image given the source option
|
// getImageResolver returns the appropriate resolve for a container image given the source option
|
||||||
func getImageResolver(img *image.Image, option Scope) (Resolver, error) {
|
func getImageResolver(img *image.Image, scope Scope) (Resolver, error) {
|
||||||
switch option {
|
switch scope {
|
||||||
case SquashedScope:
|
case SquashedScope:
|
||||||
return NewImageSquashResolver(img)
|
return NewImageSquashResolver(img)
|
||||||
case AllLayersScope:
|
case AllLayersScope:
|
||||||
return NewAllLayersResolver(img)
|
return NewAllLayersResolver(img)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("bad option provided: %+v", option)
|
return nil, fmt.Errorf("bad scope provided: %+v", scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user