mirror of https://github.com/docker/docs.git
archive.ApplyLayer(): parse a tar archive as a standard aufs-compatible diff, and apply it on a directory
This commit is contained in:
parent
a5031d47d9
commit
318dd33fb7
|
@ -0,0 +1,59 @@
|
||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ApplyLayer parses a diff in the standard layer format from `layer`, and
|
||||||
|
// applies it to the directory `dest`.
|
||||||
|
func ApplyLayer(dest string, layer Archive) error {
|
||||||
|
// Poor man's diff applyer in 2 steps:
|
||||||
|
|
||||||
|
// Step 1: untar everything in place
|
||||||
|
if err := Untar(layer, dest); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: walk for whiteouts and apply them, removing them in the process
|
||||||
|
err := filepath.Walk(dest, func(fullPath string, f os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebase path
|
||||||
|
path, err := filepath.Rel(dest, fullPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
path = filepath.Join("/", path)
|
||||||
|
|
||||||
|
// Skip AUFS metadata
|
||||||
|
if matched, err := filepath.Match("/.wh..wh.*", path); err != nil {
|
||||||
|
return err
|
||||||
|
} else if matched {
|
||||||
|
log.Printf("Removing aufs metadata %s", fullPath)
|
||||||
|
_ = os.Remove(fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := filepath.Base(path)
|
||||||
|
if strings.HasPrefix(filename, ".wh.") {
|
||||||
|
rmTargetName := filename[len(".wh."):]
|
||||||
|
rmTargetPath := filepath.Join(filepath.Dir(fullPath), rmTargetName)
|
||||||
|
// Remove the file targeted by the whiteout
|
||||||
|
log.Printf("Removing whiteout target %s", rmTargetPath)
|
||||||
|
_ = os.Remove(rmTargetPath)
|
||||||
|
// Remove the whiteout itself
|
||||||
|
log.Printf("Removing whiteout %s", fullPath)
|
||||||
|
_ = os.Remove(fullPath)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue