Skip to content

Commit

Permalink
chunked ApplyDiff(): track implicitly-created directories in layers
Browse files Browse the repository at this point in the history
When applying a chunked diff, ApplyDiff() iterates through the entries
in the diff's table of contents, creating directories and other
zero-length items like empty files, symbolic links, and directories,
building a queue of hard links, and asking goroutines to locate files in
other layers and configured OSTree repositories which contain content
that matches what should eventually end up in non-zero-length files in
the layer.

If a file's entire contents couldn't be found locally, but it was split
into chunks in the chunked diff, ApplyDiff() then searches for the
chunks in local layers.

Lastly, the contents of files with non-zero lengths, which ApplyDiff()
had attempted to find locally, but which weren't found locally, are then
requested from the registry.

Track which directories in the layer are created implicitly by
ApplyDiff(), so that the overlay driver can reset their ownership,
permissions, extended attributes, and datestamps to match the
immediately lower layer, if there is one.

Signed-off-by: Nalin Dahyabhai <[email protected]>
  • Loading branch information
nalind committed Jul 6, 2023
1 parent 2a0c3c2 commit fbdfc6b
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 126 deletions.
1 change: 1 addition & 0 deletions drivers/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ type DriverWithDifferOutput struct {
Metadata string
BigData map[string][]byte
TarSplit []byte
ImplicitDirs []string
TOCDigest digest.Digest
}

Expand Down
43 changes: 43 additions & 0 deletions drivers/overlay/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -2084,6 +2084,49 @@ func (d *Driver) ApplyDiffFromStagingDirectory(id, parent, stagingDirectory stri
return err
}

lowerDiffDirs, err := d.getLowerDiffPaths(id)
if err != nil {
return err
}
if len(lowerDiffDirs) > 0 {
backfiller := unionbackfill.NewBackfiller(options.Mappings, lowerDiffDirs)
for _, implicitDir := range diffOutput.ImplicitDirs {
hdr, err := backfiller.Backfill(implicitDir)
if err != nil {
return err
}
if hdr == nil {
continue
}
path := filepath.Join(stagingDirectory, implicitDir)
idPair := idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid}
if options.Mappings != nil {
if mapped, err := options.Mappings.ToHost(idPair); err == nil {
idPair = mapped
}
}
if err := os.Chown(path, idPair.UID, idPair.GID); err != nil {
return err
}
for xattr, xval := range hdr.Xattrs {
if err := system.Lsetxattr(path, xattr, []byte(xval), 0); err != nil {
return err
}
}
if err := os.Chmod(path, os.FileMode(hdr.Mode)&os.ModePerm); err != nil {
return err
}
atime := hdr.AccessTime
mtime := hdr.ModTime
if atime.IsZero() {
atime = mtime
}
if err := os.Chtimes(path, atime, mtime); err != nil {
return err
}
}
}

diffOutput.UncompressedDigest = diffOutput.TOCDigest

return os.Rename(stagingDirectory, diffPath)
Expand Down
2 changes: 1 addition & 1 deletion pkg/chunked/internal/compression.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type FileMetadata struct {
ChunkDigest string `json:"chunkDigest,omitempty"`
ChunkType string `json:"chunkType,omitempty"`

// internal: computed by mergeTOCEntries.
// internal: computed by mergeTocEntries.
Chunks []*FileMetadata `json:"-"`
}

Expand Down
Loading

0 comments on commit fbdfc6b

Please sign in to comment.