Skip to content

Commit 00b3d76

Browse files
dgershmanNoxsiosRacer159
authored
Fixes for manifest with symlink (#2256)
## 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 <[email protected]> Co-authored-by: Wayne Starr <[email protected]>
1 parent 7da5629 commit 00b3d76

File tree

6 files changed

+86
-8
lines changed

6 files changed

+86
-8
lines changed

src/pkg/packager/create_stages.go

+22-5
Original file line numberDiff line numberDiff line change
@@ -316,24 +316,41 @@ func (p *Packager) getFilesToSBOM(component types.ZarfComponent) (*layout.Compon
316316
Component: componentPaths,
317317
}
318318

319-
appendSBOMFiles := func(path string) {
319+
appendSBOMFiles := func(path string) error {
320320
if utils.IsDir(path) {
321-
files, _ := utils.RecursiveFileList(path, nil, false)
321+
files, err := utils.RecursiveFileList(path, nil, false)
322+
if err != nil {
323+
return err
324+
}
322325
componentSBOM.Files = append(componentSBOM.Files, files...)
323326
} else {
324-
componentSBOM.Files = append(componentSBOM.Files, path)
327+
info, err := os.Lstat(path)
328+
if err != nil {
329+
return err
330+
}
331+
if info.Mode().IsRegular() {
332+
componentSBOM.Files = append(componentSBOM.Files, path)
333+
}
325334
}
335+
336+
return nil
326337
}
327338

328339
for filesIdx, file := range component.Files {
329340
path := filepath.Join(componentPaths.Files, strconv.Itoa(filesIdx), filepath.Base(file.Target))
330-
appendSBOMFiles(path)
341+
err := appendSBOMFiles(path)
342+
if err != nil {
343+
return nil, err
344+
}
331345
}
332346

333347
for dataIdx, data := range component.DataInjections {
334348
path := filepath.Join(componentPaths.DataInjections, strconv.Itoa(dataIdx), filepath.Base(data.Target.Path))
335349

336-
appendSBOMFiles(path)
350+
err := appendSBOMFiles(path)
351+
if err != nil {
352+
return nil, err
353+
}
337354
}
338355

339356
return componentSBOM, nil

src/pkg/utils/io.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,13 @@ func RecursiveFileList(dir string, pattern *regexp.Regexp, skipHidden bool) (fil
218218
return err
219219
}
220220

221-
if !d.IsDir() {
221+
info, err := d.Info()
222+
223+
if err != nil {
224+
return err
225+
}
226+
227+
if info.Mode().IsRegular() {
222228
if pattern != nil {
223229
if len(pattern.FindStringIndex(path)) > 0 {
224230
files = append(files, path)
@@ -442,8 +448,16 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er
442448
return err
443449
}
444450

451+
link := ""
452+
if info.Mode().Type() == os.ModeSymlink {
453+
link, err = os.Readlink(filePath)
454+
if err != nil {
455+
return fmt.Errorf("error reading symlink: %w", err)
456+
}
457+
}
458+
445459
// Create a new header
446-
header, err := tar.FileInfoHeader(info, "")
460+
header, err := tar.FileInfoHeader(info, link)
447461
if err != nil {
448462
return fmt.Errorf("error creating tar header: %w", err)
449463
}
@@ -470,7 +484,7 @@ func CreateReproducibleTarballFromDir(dirPath, dirPrefix, tarballPath string) er
470484
}
471485

472486
// If it's a file, write its content
473-
if !info.IsDir() {
487+
if info.Mode().IsRegular() {
474488
file, err := os.Open(filePath)
475489
if err != nil {
476490
return fmt.Errorf("error opening file: %w", err)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors
3+
4+
// Package test provides e2e tests for Zarf.
5+
package test
6+
7+
import (
8+
"fmt"
9+
"path/filepath"
10+
"testing"
11+
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestManifestWithSymlink(t *testing.T) {
16+
t.Log("E2E: Manifest With Symlink")
17+
tmpdir := t.TempDir()
18+
cachePath := filepath.Join(tmpdir, ".cache-location")
19+
20+
// Build the package, should succeed, even though there is a symlink in the package.
21+
buildPath := filepath.Join("src", "test", "packages", "34-manifest-with-symlink")
22+
stdOut, stdErr, err := e2e.Zarf("package", "create", buildPath, "--zarf-cache", cachePath, "-o=build", "--confirm")
23+
require.NoError(t, err, stdOut, stdErr)
24+
25+
path := fmt.Sprintf("build/zarf-package-manifest-with-symlink-%s-0.0.1.tar.zst", e2e.Arch)
26+
require.FileExists(t, path)
27+
defer e2e.CleanFiles(path)
28+
29+
stdOut, stdErr, err = e2e.Zarf("package", "deploy", path, "--zarf-cache", cachePath, "--confirm")
30+
defer e2e.CleanFiles("temp/manifests")
31+
require.NoError(t, err, stdOut, stdErr)
32+
require.FileExists(t, "temp/manifests/resources/img", "Symlink does not exist in the package as expected.")
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../img
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
kind: ZarfPackageConfig
2+
metadata:
3+
name: manifest-with-symlink
4+
description: Example with a symbolic link embedded in it
5+
version: 0.0.1
6+
7+
components:
8+
- name: manifest-with-symlink
9+
required: true
10+
files:
11+
- source: manifests
12+
target: temp/manifests

0 commit comments

Comments
 (0)