Consider filesystem types for mount points when ignoring system paths (#2675)

* consider fs types for mount points when ignoring system paths

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2024-02-28 15:37:17 -05:00
committed by GitHub
parent 63171b55dd
commit 48e5672a87
6 changed files with 215 additions and 113 deletions
+59 -37
View File
@@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"
"github.com/moby/sys/mountinfo"
"github.com/wagoodman/go-partybus"
"github.com/wagoodman/go-progress"
@@ -34,12 +35,18 @@ type directoryIndexer struct {
func newDirectoryIndexer(path, base string, visitors ...PathIndexVisitor) *directoryIndexer {
i := &directoryIndexer{
path: path,
base: base,
tree: filetree.New(),
index: filetree.NewIndex(),
pathIndexVisitors: append([]PathIndexVisitor{requireFileInfo, disallowByFileType, disallowUnixSystemRuntimePath}, visitors...),
errPaths: make(map[string]error),
path: path,
base: base,
tree: filetree.New(),
index: filetree.NewIndex(),
pathIndexVisitors: append(
[]PathIndexVisitor{
requireFileInfo,
disallowByFileType,
newUnixSystemMountFinder().disallowUnixSystemRuntimePath},
visitors...,
),
errPaths: make(map[string]error),
}
// these additional stateful visitors should be the first thing considered when walking / indexing
@@ -443,11 +450,52 @@ func (r *directoryIndexer) disallowRevisitingVisitor(_, path string, _ os.FileIn
return nil
}
func disallowUnixSystemRuntimePath(base, path string, _ os.FileInfo, _ error) error {
// note: we need to consider all paths relative to the base when being filtered, which is how they would appear
// when the resolver is being used. Then something like /some/mountpoint/dev with a base of /some/mountpoint
// would be considered as /dev when being filtered.
if internal.HasAnyOfPrefixes(relativePath(base, path), unixSystemRuntimePrefixes...) {
type unixSystemMountFinder struct {
disallowedMountPaths []string
}
func newUnixSystemMountFinder() unixSystemMountFinder {
infos, err := mountinfo.GetMounts(nil)
if err != nil {
log.WithFields("error", err).Warnf("unable to get system mounts")
return unixSystemMountFinder{}
}
return unixSystemMountFinder{
disallowedMountPaths: keepUnixSystemMountPaths(infos),
}
}
func keepUnixSystemMountPaths(infos []*mountinfo.Info) []string {
var mountPaths []string
for _, info := range infos {
if info == nil {
continue
}
// we're only interested in ignoring the logical filesystems typically found at these mount points:
// - /proc
// - procfs
// - proc
// - /sys
// - sysfs
// - /dev
// - devfs - BSD/darwin flavored systems and old linux systems
// - devtmpfs - driver core maintained /dev tmpfs
// - udev - userspace implementation that replaced devfs
// - tmpfs - used for /dev in special instances (within a container)
switch info.FSType {
case "proc", "procfs", "sysfs", "devfs", "devtmpfs", "udev", "tmpfs":
log.WithFields("mountpoint", info.Mountpoint).Debug("ignoring system mountpoint")
mountPaths = append(mountPaths, info.Mountpoint)
}
}
return mountPaths
}
func (f unixSystemMountFinder) disallowUnixSystemRuntimePath(_, path string, _ os.FileInfo, _ error) error {
if internal.HasAnyOfPrefixes(path, f.disallowedMountPaths...) {
return fs.SkipDir
}
return nil
@@ -475,32 +523,6 @@ func requireFileInfo(_, _ string, info os.FileInfo, _ error) error {
return nil
}
func relativePath(basePath, givenPath string) string {
var relPath string
var relErr error
if basePath != "" {
relPath, relErr = filepath.Rel(basePath, givenPath)
cleanPath := filepath.Clean(relPath)
if relErr == nil {
if cleanPath == "." {
relPath = string(filepath.Separator)
} else {
relPath = cleanPath
}
}
if !filepath.IsAbs(relPath) {
relPath = string(filepath.Separator) + relPath
}
}
if relErr != nil || basePath == "" {
relPath = givenPath
}
return relPath
}
func indexingProgress(path string) (*progress.Stage, *progress.Manual) {
stage := &progress.Stage{}
prog := progress.NewManual(-1)