Skip to content

Commit

Permalink
copier: add NoOverwriteNonDirDir option
Browse files Browse the repository at this point in the history
Similar to the `NoOverwriteDirNonDir` one, add an option that disables
non-directories from being overwritten by directories.

Required-for: containers/podman/issues/14420
Signed-off-by: Valentin Rothberg <[email protected]>
  • Loading branch information
vrothberg committed Jun 7, 2022
1 parent 44fccd7 commit e22e0e6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
5 changes: 4 additions & 1 deletion copier/copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ type PutOptions struct {
IgnoreXattrErrors bool // ignore any errors encountered when attempting to set extended attributes
IgnoreDevices bool // ignore items which are character or block devices
NoOverwriteDirNonDir bool // instead of quietly overwriting directories with non-directories, return an error
NoOverwriteNonDirDir bool // instead of quietly overwriting non-directories with directories, return an error
Rename map[string]string // rename items with the specified names, or under the specified names
}

Expand Down Expand Up @@ -1796,7 +1797,9 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
if err = os.Mkdir(path, 0700); err != nil && os.IsExist(err) {
var st os.FileInfo
if st, err = os.Lstat(path); err == nil && !st.IsDir() {
// it's not a directory, so remove it and mkdir
if req.PutOptions.NoOverwriteNonDirDir {
return errors.Wrapf(err, "copier: put: error creating directory at %q", path)
}
if err = os.Remove(path); err == nil {
err = os.Mkdir(path, 0700)
}
Expand Down
29 changes: 28 additions & 1 deletion copier/copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,10 @@ func testPut(t *testing.T) {
}
}

// Overwrite directory
for _, overwrite := range []bool{false, true} {
for _, typeFlag := range []byte{tar.TypeReg, tar.TypeLink, tar.TypeSymlink, tar.TypeChar, tar.TypeBlock, tar.TypeFifo} {
t.Run(fmt.Sprintf("overwrite=%v,type=%c", overwrite, typeFlag), func(t *testing.T) {
t.Run(fmt.Sprintf("overwrite (dir)=%v,type=%c", overwrite, typeFlag), func(t *testing.T) {
archive := makeArchiveSlice([]tar.Header{
{Name: "target", Typeflag: tar.TypeSymlink, Mode: 0755, Linkname: "target", ModTime: testDate},
{Name: "target", Typeflag: tar.TypeDir, Mode: 0755, ModTime: testDate},
Expand All @@ -563,6 +564,32 @@ func testPut(t *testing.T) {
}
}

// Overwrite non-directory
for _, overwrite := range []bool{false, true} {
for _, typeFlag := range []byte{tar.TypeReg, tar.TypeLink, tar.TypeSymlink, tar.TypeChar, tar.TypeBlock, tar.TypeFifo} {
t.Run(fmt.Sprintf("overwrite (non-dir)=%v,type=%c", overwrite, typeFlag), func(t *testing.T) {
archive := makeArchiveSlice([]tar.Header{
{Name: "target", Typeflag: tar.TypeSymlink, Mode: 0755, Linkname: "target", ModTime: testDate},
{Name: "target", Typeflag: tar.TypeReg, Mode: 0755, ModTime: testDate},
{Name: "target", Typeflag: tar.TypeSymlink, Mode: 0755, Linkname: "target", ModTime: testDate},
{Name: "target", Typeflag: tar.TypeReg, Size: 123, Mode: 0755, ModTime: testDate},
{Name: "test", Typeflag: typeFlag, Size: 0, Mode: 0755, Linkname: "target", ModTime: testDate},
{Name: "test", Typeflag: tar.TypeDir, Size: 0, Mode: 0755, ModTime: testDate},
})
tmp, err := ioutil.TempDir("", "copier-test-")
require.NoErrorf(t, err, "error creating temporary directory")
defer os.RemoveAll(tmp)
err = Put(tmp, tmp, PutOptions{UIDMap: uidMap, GIDMap: gidMap, NoOverwriteNonDirDir: !overwrite}, bytes.NewReader(archive))
if overwrite {
if unwrapError(err) != syscall.EPERM {
assert.Nilf(t, err, "expected to overwrite file with type %c: %v", typeFlag, err)
}
} else {
assert.Errorf(t, err, "expected an error trying to overwrite file of type %c", typeFlag)
}
})
}
}
for _, ignoreDevices := range []bool{false, true} {
for _, typeFlag := range []byte{tar.TypeChar, tar.TypeBlock} {
t.Run(fmt.Sprintf("ignoreDevices=%v,type=%c", ignoreDevices, typeFlag), func(t *testing.T) {
Expand Down

0 comments on commit e22e0e6

Please sign in to comment.