Skip to content

Commit

Permalink
Merge pull request #5875 from nalind/paxrecords
Browse files Browse the repository at this point in the history
copier: use .PAXRecords instead of .Xattrs
  • Loading branch information
openshift-merge-bot[bot] authored Dec 13, 2024
2 parents 79bb8ab + cfd98d7 commit ac62622
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
29 changes: 27 additions & 2 deletions copier/copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const (
cISUID = 0o4000 // Set uid, from archive/tar
cISGID = 0o2000 // Set gid, from archive/tar
cISVTX = 0o1000 // Save text (sticky bit), from archive/tar
// xattrs in the PAXRecords map are namespaced with this prefix
xattrPAXRecordNamespace = "SCHILY.xattr."
)

func init() {
Expand Down Expand Up @@ -1427,6 +1429,23 @@ func handleRename(rename map[string]string, name string) string {
return name
}

// mapWithPrefixedKeysWithoutKeyPrefix returns a map containing every element
// of m that had p as a prefix in its (string) key, with that prefix stripped
// from its key. items are shallow-copied using assignment. if m is nil, the
// returned map will be nil, otherwise it will at least have been allocated
func mapWithPrefixedKeysWithoutKeyPrefix[K any](m map[string]K, p string) map[string]K {
if m == nil {
return m
}
cloned := make(map[string]K, len(m))
for k, v := range m {
if strings.HasPrefix(k, p) {
cloned[strings.TrimPrefix(k, p)] = v
}
}
return cloned
}

func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath string, options GetOptions, tw *tar.Writer, hardlinkChecker *hardlinkChecker, idMappings *idtools.IDMappings) error {
// build the header using the name provided
hdr, err := tar.FileInfoHeader(srcfi, symlinkTarget)
Expand Down Expand Up @@ -1455,8 +1474,13 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str
if err != nil {
return fmt.Errorf("getting extended attributes for %q: %w", contentPath, err)
}
if len(xattrs) > 0 && hdr.PAXRecords == nil {
hdr.PAXRecords = make(map[string]string, len(xattrs))
}
}
for k, v := range xattrs {
hdr.PAXRecords[xattrPAXRecordNamespace+k] = v
}
hdr.Xattrs = xattrs // nolint:staticcheck
if hdr.Typeflag == tar.TypeReg {
// if it's an archive and we're extracting archives, read the
// file and spool out its contents in-line. (if we just
Expand Down Expand Up @@ -1959,7 +1983,8 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
}
// set xattrs, including some that might have been reset by chown()
if !req.PutOptions.StripXattrs {
if err = Lsetxattrs(path, hdr.Xattrs); err != nil { // nolint:staticcheck
xattrs := mapWithPrefixedKeysWithoutKeyPrefix(hdr.PAXRecords, xattrPAXRecordNamespace)
if err = Lsetxattrs(path, xattrs); err != nil { // nolint:staticcheck
if !req.PutOptions.IgnoreXattrErrors {
return fmt.Errorf("copier: put: error setting extended attributes on %q: %w", path, err)
}
Expand Down
6 changes: 5 additions & 1 deletion tests/conformance/conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const (
cISUID = 0o4000 // Set uid, from archive/tar
cISGID = 0o2000 // Set gid, from archive/tar
cISVTX = 0o1000 // Save text (sticky bit), from archive/tar
// xattrs in the PAXRecords map are namespaced with this prefix
xattrPAXRecordNamespace = "SCHILY.xattr."
)

var (
Expand Down Expand Up @@ -2150,7 +2152,9 @@ var internalTestCases = []testCase{
Size: 8,
Mode: 0o640,
ModTime: testDate,
Xattrs: map[string]string{"user.a": "test"},
PAXRecords: map[string]string{
xattrPAXRecordNamespace + "user.a": "test",
},
}
if err = tw.WriteHeader(&hdr); err != nil {
return fmt.Errorf("writing tar archive header: %w", err)
Expand Down

0 comments on commit ac62622

Please sign in to comment.