mirror of
https://github.com/k3s-io/k3s.git
synced 2026-05-28 04:34:19 -04:00
fix: preserve paths for symlinked manifests
Signed-off-by: Immanuel Tikhonov <122638311+immanuwell@users.noreply.github.com>
This commit is contained in:
parent
c6dd4c8f74
commit
5228e97c4a
2 changed files with 92 additions and 28 deletions
|
|
@ -114,34 +114,8 @@ func (w *watcher) listFiles(force bool) error {
|
|||
// listFilesIn recursively processes all files within a path, and checks them against the disable and skip lists. Files found that
|
||||
// are not on either list are loaded as Addons and applied to the cluster.
|
||||
func (w *watcher) listFilesIn(base string, force bool) error {
|
||||
files := map[string]os.FileInfo{}
|
||||
if err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Descend into symlinked directories, however, only top-level links are followed
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
linkInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if linkInfo.IsDir() {
|
||||
evalPath, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filepath.Walk(evalPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files[path] = info
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
files[path] = info
|
||||
return nil
|
||||
}); err != nil {
|
||||
files, err := walkFiles(base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +136,9 @@ func (w *watcher) listFilesIn(base string, force bool) error {
|
|||
|
||||
var errs []error
|
||||
for _, path := range keys {
|
||||
if files[path].IsDir() {
|
||||
continue
|
||||
}
|
||||
// Disabled files are not just skipped, but actively deleted from the filesystem
|
||||
if shouldDisableFile(base, path, w.disables) {
|
||||
if err := w.delete(path); err != nil {
|
||||
|
|
@ -187,6 +164,44 @@ func (w *watcher) listFilesIn(base string, force bool) error {
|
|||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func walkFiles(base string) (map[string]os.FileInfo, error) {
|
||||
files := map[string]os.FileInfo{}
|
||||
if err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Descend into symlinked directories, however, only top-level links are followed
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
linkInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if linkInfo.IsDir() {
|
||||
evalPath, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return filepath.Walk(evalPath, func(linkPath string, linkInfo os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel, err := filepath.Rel(evalPath, linkPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files[filepath.Join(path, rel)] = linkInfo
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
files[path] = info
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// deploy loads yaml from a manifest on disk, creates an AddOn resource to track its application, and then applies
|
||||
// all resources contained within to the cluster.
|
||||
func (w *watcher) deploy(path string, compareChecksum bool) error {
|
||||
|
|
|
|||
49
pkg/deploy/controller_test.go
Normal file
49
pkg/deploy/controller_test.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_UnitWalkFilesSymlinkedDirectoryUsesLogicalPaths(t *testing.T) {
|
||||
base := t.TempDir()
|
||||
target := t.TempDir()
|
||||
|
||||
manifest := filepath.Join(target, "nested", "manifest.yaml")
|
||||
if err := os.MkdirAll(filepath.Dir(manifest), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(manifest, []byte("apiVersion: v1\nkind: Namespace\nmetadata:\n name: test\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link := filepath.Join(base, "linked")
|
||||
if err := os.Symlink(target, link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
files, err := walkFiles(base)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
logicalPath := filepath.Join(link, "nested", "manifest.yaml")
|
||||
if _, ok := files[logicalPath]; !ok {
|
||||
t.Fatalf("expected symlinked manifest to use logical path %q; got %v", logicalPath, fileKeys(files))
|
||||
}
|
||||
if _, ok := files[manifest]; ok {
|
||||
t.Fatalf("expected resolved target path %q to be hidden by logical symlink path", manifest)
|
||||
}
|
||||
if !shouldDisableFile(base, logicalPath, map[string]bool{"linked": true}) {
|
||||
t.Fatalf("expected logical path %q to match disabled symlink directory", logicalPath)
|
||||
}
|
||||
}
|
||||
|
||||
func fileKeys(files map[string]os.FileInfo) []string {
|
||||
keys := make([]string, 0, len(files))
|
||||
for key := range files {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
Loading…
Reference in a new issue