Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions ext4/internal/compactext4/compact.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,15 @@ func (w *Writer) makeInode(f *File, node *inode) (*inode, error) {
node.Devmajor = f.Devmajor
node.Devminor = f.Devminor
node.Data = nil
if f.Xattrs == nil {
f.Xattrs = make(map[string][]byte)
}

// copy over existing xattrs first, we need to merge existing xattrs and the passed xattrs.
existingXattrs := make(map[string][]byte)
if len(node.XattrInline) > 0 {
getXattrs(node.XattrInline[4:], existingXattrs, 0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From 4 onwards to skip the header? (format.XAttrHeaderMagic)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep.

}
node.XattrInline = nil

var xstate xattrState
Expand Down Expand Up @@ -452,6 +461,13 @@ func (w *Writer) makeInode(f *File, node *inode) (*inode, error) {
return nil, fmt.Errorf("invalid mode %o", mode)
}

// merge xattrs but prefer currently passed over existing
for name, data := range existingXattrs {
if _, ok := f.Xattrs[name]; !ok {
f.Xattrs[name] = data
}
}

// Accumulate the extended attributes.
if len(f.Xattrs) != 0 {
// Sort the xattrs to avoid non-determinism in map iteration.
Expand Down Expand Up @@ -514,15 +530,16 @@ func (w *Writer) lookup(name string, mustExist bool) (*inode, *inode, string, er
return dir, child, childname, nil
}

// CreateWithParents adds a file to the file system creating the parent directories in the path if
// they don't exist (like `mkdir -p`). These non existing parent directories are created
// MakeParents ensures that all the parent directories in the path specified by `name` exists. If
// they don't exist it creates them (like `mkdir -p`). These non existing parent directories are created
// with the same permissions as that of it's parent directory. It is expected that the a
// call to make these parent directories will be made at a later point with the correct
// permissions, at that time the permissions of these directories will be updated.
func (w *Writer) CreateWithParents(name string, f *File) error {
func (w *Writer) MakeParents(name string) error {
if err := w.finishInode(); err != nil {
return err
}

// go through the directories in the path one by one and create the
// parent directories if they don't exist.
cleanname := path.Clean("/" + name)[1:]
Expand Down Expand Up @@ -553,7 +570,7 @@ func (w *Writer) CreateWithParents(name string, f *File) error {
}
root = root.Children[dirname]
}
return w.Create(name, f)
return nil
Comment thread
katiewasnothere marked this conversation as resolved.
}

// Create adds a file to the file system.
Expand Down
15 changes: 10 additions & 5 deletions ext4/tar2ext4/tar2ext4.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"bufio"
"bytes"
"encoding/binary"
"github.com/pkg/errors"
"io"
"io/ioutil"
"os"
"path"
"strings"
"unsafe"

"github.com/pkg/errors"

"github.com/Microsoft/hcsshim/ext4/dmverity"
"github.com/Microsoft/hcsshim/ext4/internal/compactext4"
"github.com/Microsoft/hcsshim/ext4/internal/format"
Expand Down Expand Up @@ -86,19 +87,23 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
return err
}

if err = fs.MakeParents(hdr.Name); err != nil {
return errors.Wrapf(err, "failed to ensure parent directories for %s", hdr.Name)
}

if p.convertWhiteout {
dir, name := path.Split(hdr.Name)
if strings.HasPrefix(name, whiteoutPrefix) {
if name == opaqueWhiteout {
// Update the directory with the appropriate xattr.
f, err := fs.Stat(dir)
if err != nil {
return err
return errors.Wrapf(err, "failed to stat parent directory of whiteout %s", hdr.Name)
}
f.Xattrs["trusted.overlay.opaque"] = []byte("y")
err = fs.Create(dir, f)
if err != nil {
return err
return errors.Wrapf(err, "failed to create opaque dir %s", hdr.Name)
}
} else {
// Create an overlay-style whiteout.
Expand All @@ -109,7 +114,7 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
}
err = fs.Create(path.Join(dir, name[len(whiteoutPrefix):]), f)
if err != nil {
return err
return errors.Wrapf(err, "failed to create whiteout file for %s", hdr.Name)
}
}

Expand Down Expand Up @@ -161,7 +166,7 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
}
f.Mode &= ^compactext4.TypeMask
f.Mode |= typ
err = fs.CreateWithParents(hdr.Name, f)
err = fs.Create(hdr.Name, f)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion ext4/tar2ext4/tar2ext4_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ func Test_UnorderedTarExpansion(t *testing.T) {
var files = []struct {
path, body string
}{
{"foo/bar.txt", "inside bar.txt"},
{"foo/.wh.bar.txt", "inside bar.txt"},
{"data/", ""},
{"root.txt", "inside root.txt"},
{"foo/", ""},
{"A/.wh..wh..opq", ""},
{"A/B/b.txt", "inside b.txt"},
{"A/a.txt", "inside a.txt"},
{"A/", ""},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions test/vendor/github.com/Microsoft/hcsshim/ext4/tar2ext4/tar2ext4.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.