From 6708d9cf2299feba11de81d1015e1db2873f1f49 Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Wed, 24 Jan 2024 14:28:43 -0500 Subject: [PATCH 1/6] fixes for manifest with symlink --- src/pkg/utils/io.go | 2 +- src/test/e2e/34_manifest_with_symlink_test.go | 28 +++++++++++++++++++ .../manifests/resources/img | 1 + .../34-manifest-with-symlink/zarf.yaml | 14 ++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/test/e2e/34_manifest_with_symlink_test.go create mode 120000 src/test/packages/34-manifest-with-symlink/manifests/resources/img create mode 100644 src/test/packages/34-manifest-with-symlink/zarf.yaml diff --git a/src/pkg/utils/io.go b/src/pkg/utils/io.go index c02ce6b55e..5b81797b47 100755 --- a/src/pkg/utils/io.go +++ b/src/pkg/utils/io.go @@ -470,7 +470,7 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er } // If it's a file, write its content - if !info.IsDir() { + if !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink { file, err := os.Open(filePath) if err != nil { return fmt.Errorf("error opening file: %w", err) diff --git a/src/test/e2e/34_manifest_with_symlink_test.go b/src/test/e2e/34_manifest_with_symlink_test.go new file mode 100644 index 0000000000..5ebff31f16 --- /dev/null +++ b/src/test/e2e/34_manifest_with_symlink_test.go @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package test provides e2e tests for Zarf. +package test + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestManifestWithSymlink(t *testing.T) { + t.Log("E2E: Manifest With Symlink") + tmpdir := t.TempDir() + cachePath := filepath.Join(tmpdir, ".cache-location") + + // Build the package, should succeed, even though there is a symlink in the package. + buildPath := filepath.Join("src", "test", "packages", "34-manifest-with-symlink") + stdOut, stdErr, err := e2e.Zarf("package", "create", buildPath, "--zarf-cache", cachePath, "-o=build", "--confirm") + require.NoError(t, err, stdOut, stdErr) + + path := fmt.Sprintf("build/zarf-package-manifest-with-symlink-%s-0.0.1.tar.zst", e2e.Arch) + require.FileExists(t, path) + defer e2e.CleanFiles(path) +} diff --git a/src/test/packages/34-manifest-with-symlink/manifests/resources/img b/src/test/packages/34-manifest-with-symlink/manifests/resources/img new file mode 120000 index 0000000000..6ffc6ca9fc --- /dev/null +++ b/src/test/packages/34-manifest-with-symlink/manifests/resources/img @@ -0,0 +1 @@ +../img \ No newline at end of file diff --git a/src/test/packages/34-manifest-with-symlink/zarf.yaml b/src/test/packages/34-manifest-with-symlink/zarf.yaml new file mode 100644 index 0000000000..aa7219f9bd --- /dev/null +++ b/src/test/packages/34-manifest-with-symlink/zarf.yaml @@ -0,0 +1,14 @@ +kind: ZarfPackageConfig +metadata: + name: manifest-with-symlink + description: Example with a symbolic link embedded in it + version: 0.0.1 + +components: + - name: manifest-with-symlink + required: true + manifests: + - name: manifest-with-symlink + namespace: manifest-symlink + files: + - manifests From d9738830aa0fd60f9a0c4dbe71538ac160eb5061 Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Wed, 24 Jan 2024 15:18:13 -0500 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: razzle --- src/pkg/utils/io.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/utils/io.go b/src/pkg/utils/io.go index 5b81797b47..4a8bad5bb4 100755 --- a/src/pkg/utils/io.go +++ b/src/pkg/utils/io.go @@ -470,7 +470,7 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er } // If it's a file, write its content - if !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink { + if info.Mode().IsRegular() { file, err := os.Open(filePath) if err != nil { return fmt.Errorf("error opening file: %w", err) From f11d6aa41a50d701e1dec313edf0ee09f4d4e1d4 Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Wed, 24 Jan 2024 15:29:33 -0500 Subject: [PATCH 3/6] use recommendations to deep copy symlinks --- src/pkg/utils/io.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pkg/utils/io.go b/src/pkg/utils/io.go index 4a8bad5bb4..c9d023dfe8 100755 --- a/src/pkg/utils/io.go +++ b/src/pkg/utils/io.go @@ -249,7 +249,11 @@ func CreatePathAndCopy(source string, destination string) error { } // Copy all the source data into the destination location - if err := copy.Copy(source, destination); err != nil { + if err := copy.Copy(source, destination, copy.Options{ + OnSymlink: func(_ string) copy.SymlinkAction { + return copy.Deep + }, + }); err != nil { return err } From d7b8b25c98c02c8b92ee00b3d4315e67315a7d79 Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Wed, 24 Jan 2024 18:20:41 -0500 Subject: [PATCH 4/6] adding a simple file --- .../packages/34-manifest-with-symlink/manifests/img/test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/test/packages/34-manifest-with-symlink/manifests/img/test.txt diff --git a/src/test/packages/34-manifest-with-symlink/manifests/img/test.txt b/src/test/packages/34-manifest-with-symlink/manifests/img/test.txt new file mode 100644 index 0000000000..30d74d2584 --- /dev/null +++ b/src/test/packages/34-manifest-with-symlink/manifests/img/test.txt @@ -0,0 +1 @@ +test \ No newline at end of file From 7da55789a717b1e1018854e611a23a42134f07bb Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Fri, 2 Feb 2024 17:19:22 -0500 Subject: [PATCH 5/6] changes thus far --- src/pkg/utils/io.go | 16 ++++++++++------ .../packages/34-manifest-with-symlink/zarf.yaml | 8 +++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/pkg/utils/io.go b/src/pkg/utils/io.go index c9d023dfe8..278111e9dd 100755 --- a/src/pkg/utils/io.go +++ b/src/pkg/utils/io.go @@ -249,11 +249,7 @@ func CreatePathAndCopy(source string, destination string) error { } // Copy all the source data into the destination location - if err := copy.Copy(source, destination, copy.Options{ - OnSymlink: func(_ string) copy.SymlinkAction { - return copy.Deep - }, - }); err != nil { + if err := copy.Copy(source, destination); err != nil { return err } @@ -446,8 +442,16 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er return err } + link := "" + if info.Mode().Type() == os.ModeSymlink { + link, err = os.Readlink(filePath) + if err != nil { + return fmt.Errorf("error reading symlink: %w", err) + } + } + // Create a new header - header, err := tar.FileInfoHeader(info, "") + header, err := tar.FileInfoHeader(info, link) if err != nil { return fmt.Errorf("error creating tar header: %w", err) } diff --git a/src/test/packages/34-manifest-with-symlink/zarf.yaml b/src/test/packages/34-manifest-with-symlink/zarf.yaml index aa7219f9bd..41d21b48e6 100644 --- a/src/test/packages/34-manifest-with-symlink/zarf.yaml +++ b/src/test/packages/34-manifest-with-symlink/zarf.yaml @@ -7,8 +7,6 @@ metadata: components: - name: manifest-with-symlink required: true - manifests: - - name: manifest-with-symlink - namespace: manifest-symlink - files: - - manifests + files: + - source: manifests + target: temp/manifests From 7554a6a4131255db6c6dc98427040d584e7ec8d9 Mon Sep 17 00:00:00 2001 From: Danny Gershman Date: Fri, 2 Feb 2024 17:42:30 -0500 Subject: [PATCH 6/6] changes that seem to support better testing, sboms --- src/pkg/packager/create_stages.go | 27 +++++++++++++++---- src/pkg/utils/io.go | 8 +++++- src/test/e2e/34_manifest_with_symlink_test.go | 5 ++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/pkg/packager/create_stages.go b/src/pkg/packager/create_stages.go index 07d5116b68..bf4dffedfe 100644 --- a/src/pkg/packager/create_stages.go +++ b/src/pkg/packager/create_stages.go @@ -316,24 +316,41 @@ func (p *Packager) getFilesToSBOM(component types.ZarfComponent) (*layout.Compon Component: componentPaths, } - appendSBOMFiles := func(path string) { + appendSBOMFiles := func(path string) error { if utils.IsDir(path) { - files, _ := utils.RecursiveFileList(path, nil, false) + files, err := utils.RecursiveFileList(path, nil, false) + if err != nil { + return err + } componentSBOM.Files = append(componentSBOM.Files, files...) } else { - componentSBOM.Files = append(componentSBOM.Files, path) + info, err := os.Lstat(path) + if err != nil { + return err + } + if info.Mode().IsRegular() { + componentSBOM.Files = append(componentSBOM.Files, path) + } } + + return nil } for filesIdx, file := range component.Files { path := filepath.Join(componentPaths.Files, strconv.Itoa(filesIdx), filepath.Base(file.Target)) - appendSBOMFiles(path) + err := appendSBOMFiles(path) + if err != nil { + return nil, err + } } for dataIdx, data := range component.DataInjections { path := filepath.Join(componentPaths.DataInjections, strconv.Itoa(dataIdx), filepath.Base(data.Target.Path)) - appendSBOMFiles(path) + err := appendSBOMFiles(path) + if err != nil { + return nil, err + } } return componentSBOM, nil diff --git a/src/pkg/utils/io.go b/src/pkg/utils/io.go index 278111e9dd..290fc25d6b 100755 --- a/src/pkg/utils/io.go +++ b/src/pkg/utils/io.go @@ -218,7 +218,13 @@ func RecursiveFileList(dir string, pattern *regexp.Regexp, skipHidden bool) (fil return err } - if !d.IsDir() { + info, err := d.Info() + + if err != nil { + return err + } + + if info.Mode().IsRegular() { if pattern != nil { if len(pattern.FindStringIndex(path)) > 0 { files = append(files, path) diff --git a/src/test/e2e/34_manifest_with_symlink_test.go b/src/test/e2e/34_manifest_with_symlink_test.go index 5ebff31f16..e725ed4516 100644 --- a/src/test/e2e/34_manifest_with_symlink_test.go +++ b/src/test/e2e/34_manifest_with_symlink_test.go @@ -25,4 +25,9 @@ func TestManifestWithSymlink(t *testing.T) { path := fmt.Sprintf("build/zarf-package-manifest-with-symlink-%s-0.0.1.tar.zst", e2e.Arch) require.FileExists(t, path) defer e2e.CleanFiles(path) + + stdOut, stdErr, err = e2e.Zarf("package", "deploy", path, "--zarf-cache", cachePath, "--confirm") + defer e2e.CleanFiles("temp/manifests") + require.NoError(t, err, stdOut, stdErr) + require.FileExists(t, "temp/manifests/resources/img", "Symlink does not exist in the package as expected.") }