exportlayer.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package wclayer
  2. import (
  3. "context"
  4. "io/ioutil"
  5. "os"
  6. "strings"
  7. "github.com/Microsoft/go-winio"
  8. "github.com/Microsoft/hcsshim/internal/hcserror"
  9. "github.com/Microsoft/hcsshim/internal/oc"
  10. "go.opencensus.io/trace"
  11. )
  12. // ExportLayer will create a folder at exportFolderPath and fill that folder with
  13. // the transport format version of the layer identified by layerId. This transport
  14. // format includes any metadata required for later importing the layer (using
  15. // ImportLayer), and requires the full list of parent layer paths in order to
  16. // perform the export.
  17. func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) {
  18. title := "hcsshim::ExportLayer"
  19. ctx, span := trace.StartSpan(ctx, title)
  20. defer span.End()
  21. defer func() { oc.SetSpanStatus(span, err) }()
  22. span.AddAttributes(
  23. trace.StringAttribute("path", path),
  24. trace.StringAttribute("exportFolderPath", exportFolderPath),
  25. trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
  26. // Generate layer descriptors
  27. layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
  28. if err != nil {
  29. return err
  30. }
  31. err = exportLayer(&stdDriverInfo, path, exportFolderPath, layers)
  32. if err != nil {
  33. return hcserror.New(err, title+" - failed", "")
  34. }
  35. return nil
  36. }
  37. type LayerReader interface {
  38. Next() (string, int64, *winio.FileBasicInfo, error)
  39. Read(b []byte) (int, error)
  40. Close() error
  41. }
  42. // NewLayerReader returns a new layer reader for reading the contents of an on-disk layer.
  43. // The caller must have taken the SeBackupPrivilege privilege
  44. // to call this and any methods on the resulting LayerReader.
  45. func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) {
  46. ctx, span := trace.StartSpan(ctx, "hcsshim::NewLayerReader")
  47. defer func() {
  48. if err != nil {
  49. oc.SetSpanStatus(span, err)
  50. span.End()
  51. }
  52. }()
  53. span.AddAttributes(
  54. trace.StringAttribute("path", path),
  55. trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
  56. exportPath, err := ioutil.TempDir("", "hcs")
  57. if err != nil {
  58. return nil, err
  59. }
  60. err = ExportLayer(ctx, path, exportPath, parentLayerPaths)
  61. if err != nil {
  62. os.RemoveAll(exportPath)
  63. return nil, err
  64. }
  65. return &legacyLayerReaderWrapper{
  66. ctx: ctx,
  67. s: span,
  68. legacyLayerReader: newLegacyLayerReader(exportPath),
  69. }, nil
  70. }
  71. type legacyLayerReaderWrapper struct {
  72. ctx context.Context
  73. s *trace.Span
  74. *legacyLayerReader
  75. }
  76. func (r *legacyLayerReaderWrapper) Close() (err error) {
  77. defer r.s.End()
  78. defer func() { oc.SetSpanStatus(r.s, err) }()
  79. err = r.legacyLayerReader.Close()
  80. os.RemoveAll(r.root)
  81. return err
  82. }