From 11d8e2e08b0b4fc70cff6fa275c24d6b34c7c057 Mon Sep 17 00:00:00 2001 From: Roman Mohr Date: Thu, 29 May 2025 23:18:09 -0700 Subject: [PATCH] Ensure that extra symlinks don't overlap with RPM included symlinks In order to create valid oci layers, we need to also consider symlinks which are extra added to an rpmtree to avoid duplicate reation, in case the RPM contains the link already and we just seek to override it. Fixes: #88 --- cmd/rpm2tar.go | 14 ++++++++------ pkg/rpm/tar.go | 4 ++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/rpm2tar.go b/cmd/rpm2tar.go index 5ddac29c..333159ac 100644 --- a/cmd/rpm2tar.go +++ b/cmd/rpm2tar.go @@ -4,12 +4,14 @@ import ( "archive/tar" "fmt" "os" + "path/filepath" "sort" "strings" + "github.com/spf13/cobra" + "github.com/rmohr/bazeldnf/pkg/order" "github.com/rmohr/bazeldnf/pkg/rpm" - "github.com/spf13/cobra" ) type rpm2tarOpts struct { @@ -55,12 +57,12 @@ func NewRpm2TarCmd() *cobra.Command { } for _, k := range rpm2taropts.sortedSymlinks { v := rpm2taropts.symlinks[k] - // If an absolute path is given let's add a `.` in front. This is - // not strictly necessary but adds a more correct tar path - // which aligns with the usual rpm entries which start with `./` - if strings.HasPrefix(k, "/") { - k = "." + k + // prefix link paths with `./` which aligns with the usual rpm entries which start with `./`. + if !strings.HasPrefix(k, "./") { + k = "./" + strings.TrimPrefix(filepath.Clean(k), "/") } + // Add normalized symlink to created paths to avoid recreation when merging RPMs + collector.AddPath(k) directoryTree.Add( []tar.Header{ { diff --git a/pkg/rpm/tar.go b/pkg/rpm/tar.go index 58ba3f22..ecd73bb5 100644 --- a/pkg/rpm/tar.go +++ b/pkg/rpm/tar.go @@ -25,6 +25,10 @@ func NewCollector() *Collector { } } +func (c *Collector) AddPath(path string) { + c.createdPaths[path] = struct{}{} +} + func (c *Collector) RPMToTar(rpmReader io.Reader, tarWriter *tar.Writer, noSymlinksAndDirs bool, capabilities map[string][]string, selinuxLabels map[string]string) error { rpm, err := rpmutils.ReadRpm(rpmReader) if err != nil {