Skip to content

Commit

Permalink
Fixes for manifest with symlink (#2256)
Browse files Browse the repository at this point in the history
## Description

Fixes the issue with symlinks inside of manifests, similar to that seen
in the [Big Bang Keycloak Helm
Chart](https://repo1.dso.mil/big-bang/product/packages/keycloak/-/blob/main/development/theme-custom/theme/custom-theme/account/resources?ref_type=heads).

## Related Issue

Fixes #2255

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Other (security config, docs update, etc)

## Checklist before merging

- [x] Test, docs, adr added or updated as needed
- [x] [Contributor Guide
Steps](https://github.com/defenseunicorns/zarf/blob/main/CONTRIBUTING.md#developer-workflow)
followed

---------

Co-authored-by: razzle <harry@razzle.cloud>
Co-authored-by: Wayne Starr <Racer159@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 6, 2024
1 parent 7da5629 commit 00b3d76
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 8 deletions.
27 changes: 22 additions & 5 deletions src/pkg/packager/create_stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 17 additions & 3 deletions src/pkg/utils/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -442,8 +448,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)
}
Expand All @@ -470,7 +484,7 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er
}

// If it's a file, write its content
if !info.IsDir() {
if info.Mode().IsRegular() {
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
Expand Down
33 changes: 33 additions & 0 deletions src/test/e2e/34_manifest_with_symlink_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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)

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.")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
12 changes: 12 additions & 0 deletions src/test/packages/34-manifest-with-symlink/zarf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
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
files:
- source: manifests
target: temp/manifests

0 comments on commit 00b3d76

Please sign in to comment.