Skip to content

Commit 011ea60

Browse files
authored
refactor(misconf): simplify policy filesystem (#3875)
1 parent 6445309 commit 011ea60

File tree

3 files changed

+23
-185
lines changed

3 files changed

+23
-185
lines changed

pkg/mapfs/fs.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ func (m *FS) RemoveAll(path string) error {
187187
}
188188

189189
func cleanPath(path string) string {
190+
// Return if the file path is a volume name only.
191+
// Otherwise, `filepath.Clean` changes "C:" to "C:." and
192+
// it will no longer match the pathname held by mapfs.
193+
if path == filepath.VolumeName(path) {
194+
return path
195+
}
190196
path = filepath.Clean(path)
191197
path = filepath.ToSlash(path)
192198
path = strings.TrimLeft(path, "/") // Remove the leading slash

pkg/misconf/scanner.go

Lines changed: 10 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -131,99 +131,26 @@ func addHelmOpts(opts []options.ScannerOption, scannerOption config.ScannerOptio
131131
return opts
132132
}
133133

134-
// for a given set of paths, find the most specific filesystem path that contains all the descendants
135-
// the function also returns a filtered version of the input paths that are compatible with a fs.FS
136-
// using the resultant target path. This means they will always use "/" as a separator
137-
func findFSTarget(paths []string) (string, []string, error) {
138-
if len(paths) == 0 {
139-
return "", nil, xerrors.New("must specify at least one path")
140-
}
141-
142-
var absPaths []string
143-
var minSegmentCount int
144-
for _, relPath := range paths {
145-
abs, err := filepath.Abs(relPath)
146-
if err != nil {
147-
return "", nil, xerrors.Errorf("failed to derive absolute path from '%s': %w", relPath, err)
148-
}
149-
count := len(strings.Split(filepath.ToSlash(abs), "/"))
150-
if count < minSegmentCount || minSegmentCount == 0 {
151-
minSegmentCount = count
152-
}
153-
absPaths = append(absPaths, abs)
154-
}
155-
156-
var outputSegments []string
157-
for i := 0; i < minSegmentCount; i++ {
158-
required := strings.Split(absPaths[0], string(filepath.Separator))[i]
159-
match := true
160-
for _, path := range absPaths[1:] {
161-
actual := strings.Split(path, string(filepath.Separator))[i]
162-
if required != actual {
163-
match = false
164-
break
165-
}
166-
}
167-
if !match {
168-
break
169-
}
170-
outputSegments = append(outputSegments, required)
171-
}
172-
173-
slashTarget := strings.Join(outputSegments, "/")
174-
if slashTarget == "" {
175-
slashTarget = string(filepath.Separator)
176-
}
177-
178-
var cleanPaths []string
179-
for _, path := range absPaths {
180-
path := filepath.ToSlash(path)
181-
path = strings.TrimPrefix(path, slashTarget)
182-
path = strings.TrimPrefix(path, "/")
183-
if path == "" {
184-
path = "."
185-
}
186-
cleanPaths = append(cleanPaths, path)
187-
}
188-
189-
// we don't use filepath.Join here as we need to maintain the root "/"
190-
target := strings.Join(outputSegments, string(filepath.Separator))
191-
if target == "" || filepath.VolumeName(target) == target {
192-
target += string(filepath.Separator)
193-
}
194-
return target, cleanPaths, nil
195-
}
196-
197134
func createPolicyFS(policyPaths []string) (fs.FS, []string, error) {
198135
if len(policyPaths) == 0 {
199136
return nil, nil, nil
200137
}
201-
var outsideCWD bool
202-
for _, path := range policyPaths {
203-
if strings.Contains(path, "..") || strings.HasPrefix(path, "/") || (len(path) > 1 && path[1] == ':') {
204-
outsideCWD = true
205-
break
206-
}
207-
}
208-
// all policy paths are inside the CWD, so create a filesystem from CWD to load from
209-
if !outsideCWD {
210-
cwd, err := os.Getwd()
138+
139+
mfs := mapfs.New()
140+
for _, p := range policyPaths {
141+
abs, err := filepath.Abs(p)
211142
if err != nil {
212-
return nil, nil, err
143+
return nil, nil, xerrors.Errorf("failed to derive absolute path from '%s': %w", p, err)
213144
}
214-
var cleanPaths []string
215-
for _, path := range policyPaths {
216-
cleanPaths = append(cleanPaths, filepath.Clean(path))
145+
if err = mfs.CopyFilesUnder(abs); err != nil {
146+
return nil, nil, xerrors.Errorf("mapfs file copy error: %w", err)
217147
}
218-
return os.DirFS(cwd), cleanPaths, nil
219148
}
220149

221-
target, cleanPaths, err := findFSTarget(policyPaths)
222-
if err != nil {
223-
return nil, nil, err
224-
}
150+
// policy paths are no longer needed as fs.FS contains only needed files now.
151+
policyPaths = []string{"."}
225152

226-
return os.DirFS(target), cleanPaths, nil
153+
return mfs, policyPaths, nil
227154
}
228155

229156
func createDataFS(dataPaths []string, k8sVersion string) (fs.FS, []string, error) {

pkg/misconf/scanner_test.go

Lines changed: 7 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package misconf
22

33
import (
44
"context"
5-
"fmt"
65
"os"
76
"path/filepath"
8-
"runtime"
97
"testing"
108

119
"github.com/stretchr/testify/assert"
@@ -63,111 +61,18 @@ func TestScanner_Scan(t *testing.T) {
6361
}
6462
}
6563

66-
func Test_FindingFSTarget(t *testing.T) {
67-
tests := []struct {
68-
input []string
69-
wantTarget string
70-
wantPaths []string
71-
wantErr bool
72-
}{
73-
{
74-
input: nil,
75-
wantErr: true,
76-
},
77-
{
78-
input: []string{string(os.PathSeparator)},
79-
wantTarget: string(os.PathSeparator),
80-
wantPaths: []string{"."},
81-
},
82-
{
83-
input: []string{filepath.Join(string(os.PathSeparator), "home", "user")},
84-
wantTarget: filepath.Join(string(os.PathSeparator), "home", "user"),
85-
wantPaths: []string{"."},
86-
},
87-
{
88-
input: []string{
89-
filepath.Join(string(os.PathSeparator), "home", "user"),
90-
filepath.Join(string(os.PathSeparator), "home", "user", "something"),
91-
},
92-
wantTarget: filepath.Join(string(os.PathSeparator), "home", "user"),
93-
wantPaths: []string{".", "something"},
94-
},
95-
{
96-
input: []string{
97-
filepath.Join(string(os.PathSeparator), "home", "user"),
98-
filepath.Join(string(os.PathSeparator), "home", "user", "something", "else"),
99-
},
100-
wantTarget: filepath.Join(string(os.PathSeparator), "home", "user"),
101-
wantPaths: []string{".", "something/else"},
102-
},
103-
{
104-
input: []string{
105-
filepath.Join(string(os.PathSeparator), "home", "user"),
106-
filepath.Join(string(os.PathSeparator), "home", "user2", "something", "else"),
107-
},
108-
wantTarget: filepath.Join(string(os.PathSeparator), "home"),
109-
wantPaths: []string{"user", "user2/something/else"},
110-
},
111-
{
112-
input: []string{
113-
filepath.Join(string(os.PathSeparator), "foo"),
114-
filepath.Join(string(os.PathSeparator), "bar"),
115-
},
116-
wantTarget: string(os.PathSeparator),
117-
wantPaths: []string{"foo", "bar"},
118-
},
119-
{
120-
input: []string{string(os.PathSeparator), filepath.Join(string(os.PathSeparator), "bar")},
121-
wantTarget: string(os.PathSeparator),
122-
wantPaths: []string{".", "bar"},
123-
},
124-
}
125-
126-
for _, test := range tests {
127-
t.Run(fmt.Sprintf("%#v", test.input), func(t *testing.T) {
128-
if runtime.GOOS == "windows" {
129-
wantTarget, err := filepath.Abs(test.wantTarget)
130-
require.NoError(t, err)
131-
test.wantTarget = filepath.Clean(wantTarget)
132-
}
133-
134-
target, paths, err := findFSTarget(test.input)
135-
if test.wantErr {
136-
require.Error(t, err)
137-
} else {
138-
assert.Equal(t, test.wantTarget, target)
139-
assert.Equal(t, test.wantPaths, paths)
140-
}
141-
})
142-
}
143-
}
144-
14564
func Test_createPolicyFS(t *testing.T) {
146-
t.Run("inside cwd", func(t *testing.T) {
147-
cwd, err := os.Getwd()
148-
require.NoError(t, err)
149-
require.NoError(t, os.MkdirAll(filepath.Join(cwd, "testdir"), 0750))
150-
require.NoError(t, os.MkdirAll(filepath.Join(cwd, ".testdir"), 0750))
151-
defer func() {
152-
os.RemoveAll(filepath.Join(cwd, "testdir"))
153-
os.RemoveAll(filepath.Join(cwd, ".testdir"))
154-
}()
155-
156-
_, got1, err := createPolicyFS([]string{"testdir"})
157-
require.NoError(t, err)
158-
159-
_, got2, err := createPolicyFS([]string{".testdir"})
160-
require.NoError(t, err)
161-
162-
assert.NotEqual(t, got1, got2, "testdir and .testdir are different dirs and should not be equal")
163-
})
164-
165-
t.Run("outside cwd", func(t *testing.T) {
65+
t.Run("outside pwd", func(t *testing.T) {
16666
tmpDir := t.TempDir()
16767
require.NoError(t, os.MkdirAll(filepath.Join(tmpDir, "subdir/testdir"), 0750))
16868
f, got, err := createPolicyFS([]string{filepath.Join(tmpDir, "subdir/testdir")})
16969
require.NoError(t, err)
17070
assert.Equal(t, []string{"."}, got)
171-
assert.Contains(t, f, "testdir")
71+
72+
d, err := f.Open(tmpDir)
73+
require.NoError(t, err)
74+
stat, err := d.Stat()
75+
require.NoError(t, err)
76+
assert.True(t, stat.IsDir())
17277
})
17378
}

0 commit comments

Comments
 (0)