mirror of
https://github.com/imjasonh/snoop
synced 2026-07-18 14:45:09 +00:00
Add processor package with path normalization and deduplication
This commit is contained in:
parent
23d94e3049
commit
d8c904c3da
7 changed files with 850 additions and 2 deletions
93
pkg/processor/normalize.go
Normal file
93
pkg/processor/normalize.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
package processor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NormalizePath normalizes a file path by:
|
||||
// - Resolving . and .. components
|
||||
// - Converting relative paths to absolute using the provided working directory
|
||||
// - Preserving symlinks (not following them)
|
||||
//
|
||||
// The pid parameter is used to look up the process's working directory
|
||||
// via /proc/<pid>/cwd when the path is relative and cwd is empty.
|
||||
func NormalizePath(path string, pid uint32, cwd string) string {
|
||||
if path == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Handle absolute paths: just clean them
|
||||
if filepath.IsAbs(path) {
|
||||
return cleanPath(path)
|
||||
}
|
||||
|
||||
// For relative paths, we need a working directory
|
||||
workDir := cwd
|
||||
if workDir == "" && pid > 0 {
|
||||
// Try to read the process's cwd from /proc
|
||||
workDir = getProcessCwd(pid)
|
||||
}
|
||||
if workDir == "" {
|
||||
// Fallback: return cleaned relative path prefixed with /
|
||||
// This is a best-effort when we can't determine the cwd
|
||||
return "/" + cleanPath(path)
|
||||
}
|
||||
|
||||
// Join with working directory and clean
|
||||
return cleanPath(filepath.Join(workDir, path))
|
||||
}
|
||||
|
||||
// cleanPath removes . and .. components without following symlinks.
|
||||
// Unlike filepath.Clean, this preserves trailing slashes and handles
|
||||
// edge cases more carefully for our use case.
|
||||
func cleanPath(path string) string {
|
||||
if path == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// filepath.Clean handles ., .., and multiple slashes
|
||||
cleaned := filepath.Clean(path)
|
||||
|
||||
// Ensure absolute paths start with /
|
||||
if !strings.HasPrefix(cleaned, "/") && strings.HasPrefix(path, "/") {
|
||||
cleaned = "/" + cleaned
|
||||
}
|
||||
|
||||
return cleaned
|
||||
}
|
||||
|
||||
// getProcessCwd reads the working directory of a process from /proc.
|
||||
// Returns empty string if the process doesn't exist or cwd can't be read.
|
||||
func getProcessCwd(pid uint32) string {
|
||||
// Read the symlink target of /proc/<pid>/cwd
|
||||
cwdPath := fmt.Sprintf("/proc/%d/cwd", pid)
|
||||
cwd, err := os.Readlink(cwdPath)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cwd
|
||||
}
|
||||
|
||||
// IsExcluded checks if a path should be excluded based on the provided prefixes.
|
||||
// Paths starting with any prefix in the exclusion list are excluded.
|
||||
func IsExcluded(path string, excludePrefixes []string) bool {
|
||||
for _, prefix := range excludePrefixes {
|
||||
if strings.HasPrefix(path, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// DefaultExclusions returns the default path prefixes to exclude from tracing.
|
||||
// These are system paths that are not relevant for image slimming.
|
||||
func DefaultExclusions() []string {
|
||||
return []string{
|
||||
"/proc/",
|
||||
"/sys/",
|
||||
"/dev/",
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue