in container_images/registry-image-forked/commands/unpack.go [73:184]
func extractLayer(dest string, layer v1.Layer, bar *mpb.Bar, chown bool) error {
r, err := layer.Compressed()
if err != nil {
return err
}
gr, err := gzip.NewReader(bar.ProxyReader(r))
if err != nil {
return err
}
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
path := filepath.Join(dest, filepath.Clean(hdr.Name))
base := filepath.Base(path)
dir := filepath.Dir(path)
log := logrus.WithFields(logrus.Fields{
"Name": hdr.Name,
})
log.Debug("unpacking")
if base == whiteoutOpaqueDir {
fi, err := os.Lstat(dir)
if err != nil && !os.IsNotExist(err) {
return err
}
log.Debugf("removing contents of %s", dir)
if err := os.RemoveAll(dir); err != nil {
return err
}
if err := os.Mkdir(dir, fi.Mode()&os.ModePerm); err != nil {
return err
}
continue
} else if strings.HasPrefix(base, whiteoutPrefix) {
// layer has marked a file as deleted
name := strings.TrimPrefix(base, whiteoutPrefix)
removedPath := filepath.Join(dir, name)
log.Debugf("removing %s", removedPath)
err := os.RemoveAll(removedPath)
if err != nil {
return nil
}
continue
}
if hdr.Typeflag == tar.TypeBlock || hdr.Typeflag == tar.TypeChar {
// devices can't be created in a user namespace
log.Debugf("skipping device %s", hdr.Name)
continue
}
if hdr.Typeflag == tar.TypeSymlink {
log.Debugf("symlinking to %s", hdr.Linkname)
}
if hdr.Typeflag == tar.TypeLink {
log.Debugf("hardlinking to %s", hdr.Linkname)
}
if fi, err := os.Lstat(path); err == nil {
if fi.IsDir() && hdr.Name == "." {
continue
}
if !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) {
log.Debugf("removing existing path")
if err := os.RemoveAll(path); err != nil {
return err
}
}
}
if err := tarfs.ExtractEntry(hdr, dest, tr, chown); err != nil {
log.Debugf("extracting")
return err
}
}
err = gr.Close()
if err != nil {
return err
}
err = r.Close()
if err != nil {
return err
}
bar.SetTotal(bar.Current(), true)
return nil
}