func writeTarFromLayer(r hcsshim.LayerReader, w io.Writer) error { t := tar.NewWriter(w) for { name, size, fileInfo, err := r.Next() if err == io.EOF { break } if err != nil { return err } if fileInfo == nil { // Write a whiteout file. hdr := &tar.Header{ Name: filepath.ToSlash(filepath.Join(filepath.Dir(name), archive.WhiteoutPrefix+filepath.Base(name))), } err := t.WriteHeader(hdr) if err != nil { return err } } else { err = backuptar.WriteTarFileFromBackupStream(t, r, name, size, fileInfo) if err != nil { return err } } } return t.Close() }
// exportLayer generates an archive from a layer based on the given ID. func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) { if hcsshim.IsTP4() { // Export in TP4 format to maintain compatibility with existing images and // because ExportLayer is somewhat broken on TP4 and can't work with the new // scheme. tempFolder, err := ioutil.TempDir("", "hcs") if err != nil { return nil, err } defer func() { if err != nil { os.RemoveAll(tempFolder) } }() if err = hcsshim.ExportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil { return nil, err } archive, err := archive.Tar(tempFolder, archive.Uncompressed) if err != nil { return nil, err } return ioutils.NewReadCloserWrapper(archive, func() error { err := archive.Close() os.RemoveAll(tempFolder) return err }), nil } var r hcsshim.LayerReader r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths) if err != nil { return nil, err } archive, w := io.Pipe() go func() { err := writeTarFromLayer(r, w) cerr := r.Close() if err == nil { err = cerr } w.CloseWithError(err) }() return archive, nil }
// exportLayer generates an archive from a layer based on the given ID. func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) { var r hcsshim.LayerReader r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths) if err != nil { return nil, err } archive, w := io.Pipe() go func() { err := writeTarFromLayer(r, w) cerr := r.Close() if err == nil { err = cerr } w.CloseWithError(err) }() return archive, nil }