Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/anchore/import_package_sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func TestPackageSbomToModel(t *testing.T) {
FoundBy: "foundBy",
Locations: []source.Location{
{
Path: "path",
RealPath: "path",
FileSystemID: "layerID",
},
},
Expand Down Expand Up @@ -139,7 +139,7 @@ func TestPackageSbomImport(t *testing.T) {
FoundBy: "foundBy",
Locations: []source.Location{
{
Path: "path",
RealPath: "path",
FileSystemID: "layerID",
},
},
Expand Down
2 changes: 1 addition & 1 deletion syft/cataloger/common/generic_cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (c *GenericCataloger) catalog(contents map[source.Location]io.ReadCloser) (
continue
}

entries, err := parser(location.Path, content)
entries, err := parser(location.RealPath, content)
if err != nil {
// TODO: should we fail? or only log?
log.Warnf("cataloger '%s' failed to parse entries (location=%+v): %+v", c.upstreamCataloger, location, err)
Expand Down
2 changes: 1 addition & 1 deletion syft/cataloger/common/generic_cataloger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestGenericCataloger(t *testing.T) {

for _, p := range actualPkgs {
ref := p.Locations[0]
exP, ok := expectedPkgs[ref.Path]
exP, ok := expectedPkgs[ref.RealPath]
if !ok {
t.Errorf("missing expected pkg: ref=%+v", ref)
continue
Expand Down
4 changes: 2 additions & 2 deletions syft/cataloger/deb/cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c *Cataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {

pkgs, err = parseDpkgStatus(dbContents)
if err != nil {
return nil, fmt.Errorf("unable to catalog dpkg package=%+v: %w", dbLocation.Path, err)
return nil, fmt.Errorf("unable to catalog dpkg package=%+v: %w", dbLocation.RealPath, err)
}

md5ContentsByName, md5RefsByName, err := fetchMd5Contents(resolver, dbLocation, pkgs)
Expand Down Expand Up @@ -104,7 +104,7 @@ func fetchMd5Contents(resolver source.Resolver, dbLocation source.Location, pkgs

var md5FileMatches []source.Location
var nameByRef = make(map[source.Location]string)
parentPath := filepath.Dir(dbLocation.Path)
parentPath := filepath.Dir(dbLocation.RealPath)

for _, p := range pkgs {
// look for /var/lib/dpkg/info/NAME:ARCH.md5sums
Expand Down
2 changes: 1 addition & 1 deletion syft/cataloger/deb/cataloger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestDpkgCataloger(t *testing.T) {
// we will test the sources separately
var sourcesList = make([]string, len(a.Locations))
for i, s := range a.Locations {
sourcesList[i] = s.Path
sourcesList[i] = s.RealPath
}
a.Locations = nil

Expand Down
4 changes: 2 additions & 2 deletions syft/cataloger/python/package_cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (c *PackageCataloger) Catalog(resolver source.Resolver) ([]pkg.Package, err
for _, entry := range entries {
p, err := c.catalogEggOrWheel(entry)
if err != nil {
return nil, fmt.Errorf("unable to catalog python package=%+v: %w", entry.Metadata.Location.Path, err)
return nil, fmt.Errorf("unable to catalog python package=%+v: %w", entry.Metadata.Location.RealPath, err)
}
if p != nil {
packages = append(packages, *p)
Expand Down Expand Up @@ -118,7 +118,7 @@ func (c *PackageCataloger) catalogEggOrWheel(entry *packageEntry) (*pkg.Package,
func (c *PackageCataloger) assembleEggOrWheelMetadata(entry *packageEntry) (*pkg.PythonPackageMetadata, []source.Location, error) {
var sources = []source.Location{entry.Metadata.Location}

metadata, err := parseWheelOrEggMetadata(entry.Metadata.Location.Path, entry.Metadata.Contents)
metadata, err := parseWheelOrEggMetadata(entry.Metadata.Location.RealPath, entry.Metadata.Contents)
if err != nil {
return nil, nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions syft/cataloger/python/package_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ func newPackageEntry(resolver source.FileResolver, metadataLocation source.Locat
// to reconcile the RECORD path to the same layer (or a lower layer). The same is true with the top_level.txt file.

// lets find the RECORD file relative to the directory where the METADATA file resides (in path AND layer structure)
recordPath := filepath.Join(filepath.Dir(metadataLocation.Path), "RECORD")
recordPath := filepath.Join(filepath.Dir(metadataLocation.RealPath), "RECORD")
recordLocation := resolver.RelativeFileByPath(metadataLocation, recordPath)

// a top_level.txt file specifies the python top-level packages (provided by this python package) installed into site-packages
parentDir := filepath.Dir(metadataLocation.Path)
parentDir := filepath.Dir(metadataLocation.RealPath)
topLevelPath := filepath.Join(parentDir, "top_level.txt")
topLevelLocation := resolver.RelativeFileByPath(metadataLocation, topLevelPath)

Expand Down
2 changes: 1 addition & 1 deletion syft/cataloger/rpmdb/cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (c *Cataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {

pkgs, err = parseRpmDB(resolver, location, dbContentReader)
if err != nil {
return nil, fmt.Errorf("unable to catalog rpmdb package=%+v: %w", location.Path, err)
return nil, fmt.Errorf("unable to catalog rpmdb package=%+v: %w", location.RealPath, err)
}
}
return pkgs, nil
Expand Down
2 changes: 1 addition & 1 deletion syft/distro/identify.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ identifyLoop:

content, err := ioutil.ReadAll(contentReader)
if err != nil {
log.Errorf("unable to read %q: %+v", location.Path, err)
log.Errorf("unable to read %q: %+v", location.RealPath, err)
break
}

Expand Down
4 changes: 2 additions & 2 deletions syft/presenter/cyclonedx/presenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestCycloneDxDirsPresenter(t *testing.T) {
Type: pkg.DebPkg,
FoundBy: "the-cataloger-1",
Locations: []source.Location{
{Path: "/some/path/pkg1"},
{RealPath: "/some/path/pkg1"},
},
Metadata: pkg.DpkgMetadata{
Package: "package1",
Expand All @@ -44,7 +44,7 @@ func TestCycloneDxDirsPresenter(t *testing.T) {
Type: pkg.DebPkg,
FoundBy: "the-cataloger-2",
Locations: []source.Location{
{Path: "/some/path/pkg1"},
{RealPath: "/some/path/pkg1"},
},
Licenses: []string{
"MIT",
Expand Down
4 changes: 2 additions & 2 deletions syft/presenter/json/presenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestJsonDirsPresenter(t *testing.T) {
Type: pkg.PythonPkg,
FoundBy: "the-cataloger-1",
Locations: []source.Location{
{Path: "/some/path/pkg1"},
{RealPath: "/some/path/pkg1"},
},
Language: pkg.Python,
MetadataType: pkg.PythonPackageMetadataType,
Expand All @@ -56,7 +56,7 @@ func TestJsonDirsPresenter(t *testing.T) {
Type: pkg.DebPkg,
FoundBy: "the-cataloger-2",
Locations: []source.Location{
{Path: "/some/path/pkg1"},
{RealPath: "/some/path/pkg1"},
},
MetadataType: pkg.DpkgMetadataType,
Metadata: pkg.DpkgMetadata{
Expand Down
8 changes: 8 additions & 0 deletions syft/source/all_layers_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ func TestAllLayersResolver_FilesByPath(t *testing.T) {
t.Errorf("bad resolve path: '%s'!='%s'", string(actual.ref.RealPath), expected.path)
}

if expected.path != "" && string(actual.ref.RealPath) != actual.RealPath {
t.Errorf("we should always prefer real paths over ones with links")
}

entry, err := img.FileCatalog.Get(actual.ref)
if err != nil {
t.Fatalf("failed to get metadata: %+v", err)
Expand Down Expand Up @@ -221,6 +225,10 @@ func TestAllLayersResolver_FilesByGlob(t *testing.T) {
t.Errorf("bad resolve path: '%s'!='%s'", string(actual.ref.RealPath), expected.path)
}

if expected.path != "" && string(actual.ref.RealPath) != actual.RealPath {
t.Errorf("we should always prefer real paths over ones with links")
}

entry, err := img.FileCatalog.Get(actual.ref)
if err != nil {
t.Fatalf("failed to get metadata: %+v", err)
Expand Down
8 changes: 4 additions & 4 deletions syft/source/content_requester_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ func TestContentRequester(t *testing.T) {
}

for _, entry := range data {
if expected, ok := test.expectedContents[entry.Location.Path]; ok {
if expected, ok := test.expectedContents[entry.Location.RealPath]; ok {
actualBytes, err := ioutil.ReadAll(entry.Contents)
if err != nil {
t.Fatalf("could not read %q: %+v", entry.Location.Path, err)
t.Fatalf("could not read %q: %+v", entry.Location.RealPath, err)
}
for expected != string(actualBytes) {
t.Errorf("mismatched contents for %q", entry.Location.Path)
t.Errorf("mismatched contents for %q", entry.Location.RealPath)
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(expected, string(actualBytes), true)
t.Errorf("diff: %s", dmp.DiffPrettyText(diffs))
}
continue
}
t.Errorf("could not find %q", entry.Location.Path)
t.Errorf("could not find %q", entry.Location.RealPath)
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions syft/source/directory_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ func (r *DirectoryResolver) RelativeFileByPath(_ Location, path string) *Locatio
func (r DirectoryResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]io.ReadCloser, error) {
refContents := make(map[Location]io.ReadCloser)
for _, location := range locations {
refContents[location] = file.NewDeferredReadCloser(location.Path)
refContents[location] = file.NewDeferredReadCloser(location.RealPath)
}
return refContents, nil
}

// FileContentsByLocation fetches file contents for a single file reference relative to a directory.
// If the path does not exist an error is returned.
func (r DirectoryResolver) FileContentsByLocation(location Location) (io.ReadCloser, error) {
return file.NewDeferredReadCloser(location.Path), nil
return file.NewDeferredReadCloser(location.RealPath), nil
}
4 changes: 2 additions & 2 deletions syft/source/directory_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ func TestDirectoryResolver_FilesByPath(t *testing.T) {
}

for _, actual := range refs {
if actual.Path != c.expected {
t.Errorf("bad resolve path: '%s'!='%s'", actual.Path, c.expected)
if actual.RealPath != c.expected {
t.Errorf("bad resolve path: '%s'!='%s'", actual.RealPath, c.expected)
}
}
})
Expand Down
8 changes: 8 additions & 0 deletions syft/source/image_squash_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ func TestImageSquashResolver_FilesByPath(t *testing.T) {
t.Errorf("bad resolve path: '%s'!='%s'", string(actual.ref.RealPath), c.resolvePath)
}

if c.resolvePath != "" && string(actual.ref.RealPath) != actual.RealPath {
t.Errorf("we should always prefer real paths over ones with links")
}

entry, err := img.FileCatalog.Get(actual.ref)
if err != nil {
t.Fatalf("failed to get metadata: %+v", err)
Expand Down Expand Up @@ -208,6 +212,10 @@ func TestImageSquashResolver_FilesByGlob(t *testing.T) {
t.Errorf("bad resolve path: '%s'!='%s'", string(actual.ref.RealPath), c.resolvePath)
}

if c.resolvePath != "" && string(actual.ref.RealPath) != actual.RealPath {
t.Errorf("we should always prefer real paths over ones with links")
}

entry, err := img.FileCatalog.Get(actual.ref)
if err != nil {
t.Fatalf("failed to get metadata: %+v", err)
Expand Down
18 changes: 11 additions & 7 deletions syft/source/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,37 @@ import (
"github.com/anchore/stereoscope/pkg/image"
)

// Location represents a path relative to a particular filesystem.
// Location represents a path relative to a particular filesystem resolved to a specific file.Reference. This struct is used as a key
// in content fetching to uniquely identify a file relative to a request (the VirtualPath).
type Location struct {
Path string `json:"path"` // The string path of the location (e.g. /etc/hosts)
RealPath string `json:"path"` // The path where all path ancestors have no hardlinks / symlinks
VirtualPath string `json:"-"` // The path to the file which may or may not have hardlinks / symlinks
FileSystemID string `json:"layerID,omitempty"` // An ID representing the filesystem. For container images this is a layer digest, directories or root filesystem this is blank.
ref file.Reference // The file reference relative to the stereoscope.FileCatalog that has more information about this location.
}

// NewLocation creates a new Location representing a path without denoting a filesystem or FileCatalog reference.
func NewLocation(path string) Location {
return Location{
Path: path,
RealPath: path,
}
}

// NewLocationFromImage creates a new Location representing the given path (extracted from the ref) relative to the given image.
func NewLocationFromImage(path string, ref file.Reference, img *image.Image) Location {
func NewLocationFromImage(virtualPath string, 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: path,
ref: ref,
VirtualPath: virtualPath,
RealPath: string(ref.RealPath),
ref: ref,
}
}

return Location{
Path: path,
VirtualPath: virtualPath,
RealPath: string(ref.RealPath),
FileSystemID: entry.Layer.Metadata.Digest,
ref: ref,
}
Expand Down
10 changes: 5 additions & 5 deletions syft/source/mock_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewMockResolverForPaths(paths ...string) *MockResolver {
// HasPath indicates if the given path exists in the underlying source.
func (r MockResolver) HasPath(path string) bool {
for _, l := range r.Locations {
if l.Path == path {
if l.RealPath == path {
return true
}
}
Expand All @@ -40,15 +40,15 @@ func (r MockResolver) HasPath(path string) bool {

// String returns the string representation of the MockResolver.
func (r MockResolver) String() string {
return fmt.Sprintf("mock:(%s,...)", r.Locations[0].Path)
return fmt.Sprintf("mock:(%s,...)", r.Locations[0].RealPath)
}

// FileContentsByLocation fetches file contents for a single location. If the
// path does not exist, an error is returned.
func (r MockResolver) FileContentsByLocation(location Location) (io.ReadCloser, error) {
for _, l := range r.Locations {
if l == location {
return os.Open(location.Path)
return os.Open(location.RealPath)
}
}

Expand All @@ -74,7 +74,7 @@ func (r MockResolver) FilesByPath(paths ...string) ([]Location, error) {
var results []Location
for _, p := range paths {
for _, location := range r.Locations {
if p == location.Path {
if p == location.RealPath {
results = append(results, NewLocation(p))
}
}
Expand All @@ -88,7 +88,7 @@ func (r MockResolver) FilesByGlob(patterns ...string) ([]Location, error) {
var results []Location
for _, pattern := range patterns {
for _, location := range r.Locations {
if file.GlobMatch(pattern, location.Path) {
if file.GlobMatch(pattern, location.RealPath) {
results = append(results, location)
}
}
Expand Down
2 changes: 1 addition & 1 deletion syft/source/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ type Resolver interface {
// ContentResolver knows how to get file content for given file.References
type ContentResolver interface {
FileContentsByLocation(Location) (io.ReadCloser, error)
// TODO: it is possible to be given duplicate locations that will be overridden in the map (key), a subtle problem that coule easily be misued.
MultipleFileContentsByLocation([]Location) (map[Location]io.ReadCloser, 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).
}

// FileResolver knows how to get a Location for given string paths and globs
Expand Down
6 changes: 6 additions & 0 deletions test/integration/document_import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ func TestCatalogFromJSON(t *testing.T) {
e.Metadata = metadata
}

// ignore the virtual path on the location for now
for l := range a.Locations {
a.Locations[l].VirtualPath = ""
e.Locations[l].VirtualPath = ""
}

for _, d := range deep.Equal(a, e) {
// ignore errors for empty collections vs nil for select fields
// TODO: this is brittle, but not dangerously so. We should still find a better way to do this.
Expand Down