diff --git a/internal/slicer/slicer.go b/internal/slicer/slicer.go index 9a51b145..aaa38ef4 100644 --- a/internal/slicer/slicer.go +++ b/internal/slicer/slicer.go @@ -32,8 +32,9 @@ type RunOptions struct { } type pathData struct { - until setup.PathUntil - mutable bool + until setup.PathUntil + mutable bool + hardLink bool } type contentChecker struct { @@ -44,6 +45,9 @@ func (cc *contentChecker) checkMutable(path string) error { if !cc.knownPaths[path].mutable { return fmt.Errorf("cannot write file which is not mutable: %s", path) } + if cc.knownPaths[path].hardLink { + return fmt.Errorf("cannot mutate a hard link: %s", path) + } return nil } @@ -205,7 +209,11 @@ func Run(options *RunOptions) error { } if inSliceContents { - data := pathData{mutable: mutable, until: until} + data := pathData{ + mutable: mutable, + until: until, + hardLink: entry.LinkType == fsutil.TypeHardLink, + } addKnownPath(knownPaths, relPath, data) } return nil diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index 3615a188..8ca644ff 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -1737,6 +1737,94 @@ var slicerTests = []slicerTest{{ "/dir/file2": "file 0644 28121945 <2> {test-package2_myslice}", "/hardlink2": "file 0644 28121945 <2> {test-package2_myslice}", }, +}, { + summary: "Mutations for hard links are forbidden", + slices: []setup.SliceKey{ + {"test-package", "myslice"}}, + pkgs: []*testutil.TestPackage{{ + Name: "test-package", + Data: testutil.MustMakeDeb([]testutil.TarEntry{ + testutil.Dir(0755, "./"), + testutil.Dir(0755, "./dir/"), + testutil.Reg(0644, "./dir/file", "text for file"), + testutil.Hln(0644, "./hardlink", "./dir/file"), + }), + }}, + release: map[string]string{ + "slices/mydir/test-package.yaml": ` + package: test-package + slices: + myslice: + contents: + /dir/file: + /hardlink: {mutable: true} + mutate: | + content.write("/hardlink", "new content") + `, + }, + error: `slice test-package_myslice: cannot mutate a hard link: /hardlink`, +}, { + summary: "Hard links can be marked as mutable, but not mutated", + slices: []setup.SliceKey{ + {"test-package", "myslice"}}, + pkgs: []*testutil.TestPackage{{ + Name: "test-package", + Data: testutil.MustMakeDeb([]testutil.TarEntry{ + testutil.Dir(0755, "./"), + testutil.Dir(0755, "./dir/"), + testutil.Reg(0644, "./dir/file", "text for file"), + testutil.Hln(0644, "./hardlink", "./dir/file"), + }), + }}, + release: map[string]string{ + "slices/mydir/test-package.yaml": ` + package: test-package + slices: + myslice: + contents: + /dir/file: + /hardlink: {mutable: true} + `, + }, + filesystem: map[string]string{ + "/dir/": "dir 0755", + "/dir/file": "file 0644 28121945", + "/hardlink": "file 0644 28121945", + }, + manifestPaths: map[string]string{ + "/dir/file": "file 0644 28121945 <1> {test-package_myslice}", + "/hardlink": "file 0644 28121945 <1> {test-package_myslice}", + }, +}, { + summary: "UntilMutate for hard links are allowed", + slices: []setup.SliceKey{ + {"test-package", "myslice"}}, + pkgs: []*testutil.TestPackage{{ + Name: "test-package", + Data: testutil.MustMakeDeb([]testutil.TarEntry{ + testutil.Dir(0755, "./"), + testutil.Dir(0755, "./dir/"), + testutil.Reg(0644, "./dir/file", "text for file"), + testutil.Hln(0644, "./hardlink", "./dir/file"), + }), + }}, + release: map[string]string{ + "slices/mydir/test-package.yaml": ` + package: test-package + slices: + myslice: + contents: + /dir/file: + /hardlink: {until: mutate} + `, + }, + filesystem: map[string]string{ + "/dir/": "dir 0755", + "/dir/file": "file 0644 28121945", + }, + manifestPaths: map[string]string{ + "/dir/file": "file 0644 28121945 {test-package_myslice}", + }, }} var defaultChiselYaml = `