Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

composefs: add parent directory if missing #1929

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
23 changes: 19 additions & 4 deletions pkg/chunked/dump/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,23 @@ func sanitizeName(name string) string {
return path
}

func dumpNode(out io.Writer, links map[string]int, verityDigests map[string]string, entry *internal.FileMetadata) error {
func dumpNode(out io.Writer, added map[string]struct{}, links map[string]int, verityDigests map[string]string, entry *internal.FileMetadata) error {
path := sanitizeName(entry.Name)

parent := filepath.Dir(path)
if _, found := added[parent]; !found && entry.Name != "/" {
parentEntry := &internal.FileMetadata{
Name: parent,
Type: internal.TypeDir,
Mode: 0o755,
}
if err := dumpNode(out, added, links, verityDigests, parentEntry); err != nil {
return err
}

}
added[path] = struct{}{}

if _, err := fmt.Fprint(out, escaped(path, ESCAPE_STANDARD)); err != nil {
return err
}
Expand Down Expand Up @@ -201,6 +215,7 @@ func GenerateDump(tocI interface{}, verityDigests map[string]string) (io.Reader,
}()

links := make(map[string]int)
added := make(map[string]struct{})
for _, e := range toc.Entries {
if e.Linkname == "" {
continue
Expand All @@ -211,14 +226,14 @@ func GenerateDump(tocI interface{}, verityDigests map[string]string) (io.Reader,
links[e.Linkname] = links[e.Linkname] + 1
}

if len(toc.Entries) == 0 || (sanitizeName(toc.Entries[0].Name) != "/") {
if len(toc.Entries) == 0 {
root := &internal.FileMetadata{
Name: "/",
Type: internal.TypeDir,
Mode: 0o755,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn’t this special case for / now redundant with the new logic?

Copy link
Member Author

Choose a reason for hiding this comment

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

I could drop the condition || (sanitizeName(toc.Entries[0].Name) != "/") but we still need it for len(toc.Entries) == 0 as we never call dumpNode()

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, I didn’t realize that was also a practical possibility.

I do think removing the second condition would be valuable in itself — and it would make the “empty entries” special case a bit more noticeable.

}

if err := dumpNode(w, links, verityDigests, root); err != nil {
if err := dumpNode(w, added, links, verityDigests, root); err != nil {
pipeW.CloseWithError(err)
closed = true
return
Expand All @@ -229,7 +244,7 @@ func GenerateDump(tocI interface{}, verityDigests map[string]string) (io.Reader,
if e.Type == internal.TypeChunk {
continue
}
if err := dumpNode(w, links, verityDigests, &e); err != nil {
if err := dumpNode(w, added, links, verityDigests, &e); err != nil {
pipeW.CloseWithError(err)
closed = true
return
Expand Down
28 changes: 23 additions & 5 deletions pkg/chunked/dump/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,37 +87,52 @@ func TestDumpNode(t *testing.T) {
Linkname: "existingfile",
}

var bufRegularFile, bufDirectory, bufSymlink, bufHardlink bytes.Buffer
missingParentEntry := &internal.FileMetadata{
Name: "foo/bar/baz/entry",
Type: internal.TypeReg,
ModTime: &modTime,
}

var bufRegularFile, bufDirectory, bufSymlink, bufHardlink, bufMissingParent bytes.Buffer

err := dumpNode(&bufRegularFile, map[string]int{}, map[string]string{}, regularFileEntry)
added := map[string]struct{}{"/": {}}

err := dumpNode(&bufRegularFile, added, map[string]int{}, map[string]string{}, regularFileEntry)
if err != nil {
t.Errorf("unexpected error for regular file: %v", err)
}

err = dumpNode(&bufDirectory, map[string]int{}, map[string]string{}, directoryEntry)
err = dumpNode(&bufDirectory, added, map[string]int{}, map[string]string{}, directoryEntry)
if err != nil {
t.Errorf("unexpected error for directory: %v", err)
}

err = dumpNode(&bufSymlink, map[string]int{}, map[string]string{}, symlinkEntry)
err = dumpNode(&bufSymlink, added, map[string]int{}, map[string]string{}, symlinkEntry)
if err != nil {
t.Errorf("unexpected error for symlink: %v", err)
}

err = dumpNode(&bufHardlink, map[string]int{}, map[string]string{}, hardlinkEntry)
err = dumpNode(&bufHardlink, added, map[string]int{}, map[string]string{}, hardlinkEntry)
if err != nil {
t.Errorf("unexpected error for hardlink: %v", err)
}

err = dumpNode(&bufMissingParent, added, map[string]int{}, map[string]string{}, missingParentEntry)
if err != nil {
t.Errorf("unexpected error: %v", err)
}

expectedRegularFile := "/example.txt 100 100000 1 1000 1000 0 1672531200.0 ab/cdef1234567890 - - user.key1=value1\n"
expectedDirectory := "/mydir 0 40000 1 1000 1000 0 1672531200.0 - - - user.key2=value2\n"
expectedSymlink := "/mysymlink 0 120000 1 0 0 0 1672531200.0 targetfile - -\n"
expectedHardlink := "/myhardlink 0 @100000 1 0 0 0 1672531200.0 /existingfile - -\n"
expectedActualMissingParent := "/foo 0 40755 1 0 0 0 0.0 - - -\n/foo/bar 0 40755 1 0 0 0 0.0 - - -\n/foo/bar/baz 0 40755 1 0 0 0 0.0 - - -\n/foo/bar/baz/entry 0 100000 1 0 0 0 1672531200.0 - - -\n"

actualRegularFile := bufRegularFile.String()
actualDirectory := bufDirectory.String()
actualSymlink := bufSymlink.String()
actualHardlink := bufHardlink.String()
actualMissingParent := bufMissingParent.String()

if actualRegularFile != expectedRegularFile {
t.Errorf("for regular file, got %q, want %q", actualRegularFile, expectedRegularFile)
Expand All @@ -134,4 +149,7 @@ func TestDumpNode(t *testing.T) {
if actualHardlink != expectedHardlink {
t.Errorf("for hardlink, got %q, want %q", actualHardlink, expectedHardlink)
}
if actualMissingParent != expectedActualMissingParent {
t.Errorf("for missing parent, got %q, want %q", actualMissingParent, expectedActualMissingParent)
}
}