package wclayer import ( "io/ioutil" "os" "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/sirupsen/logrus" ) // ExportLayer will create a folder at exportFolderPath and fill that folder with // the transport format version of the layer identified by layerId. This transport // format includes any metadata required for later importing the layer (using // ImportLayer), and requires the full list of parent layer paths in order to // perform the export. func ExportLayer(path string, exportFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ExportLayer" fields := logrus.Fields{ "path": path, "exportFolderPath": exportFolderPath, } logrus.WithFields(fields).Debug(title) defer func() { if err != nil { fields[logrus.ErrorKey] = err logrus.WithFields(fields).Error(err) } else { logrus.WithFields(fields).Debug(title + " - succeeded") } }() // Generate layer descriptors layers, err := layerPathsToDescriptors(parentLayerPaths) if err != nil { return err } err = exportLayer(&stdDriverInfo, path, exportFolderPath, layers) if err != nil { return hcserror.New(err, title+" - failed", "") } return nil } type LayerReader interface { Next() (string, int64, *winio.FileBasicInfo, error) Read(b []byte) (int, error) Close() error } // NewLayerReader returns a new layer reader for reading the contents of an on-disk layer. // The caller must have taken the SeBackupPrivilege privilege // to call this and any methods on the resulting LayerReader. func NewLayerReader(path string, parentLayerPaths []string) (LayerReader, error) { exportPath, err := ioutil.TempDir("", "hcs") if err != nil { return nil, err } err = ExportLayer(path, exportPath, parentLayerPaths) if err != nil { os.RemoveAll(exportPath) return nil, err } return &legacyLayerReaderWrapper{newLegacyLayerReader(exportPath)}, nil } type legacyLayerReaderWrapper struct { *legacyLayerReader } func (r *legacyLayerReaderWrapper) Close() error { err := r.legacyLayerReader.Close() os.RemoveAll(r.root) return err }