1
2
3 package wclayer
4
5 import (
6 "context"
7 "os"
8 "strings"
9
10 "github.com/Microsoft/go-winio"
11 "github.com/Microsoft/hcsshim/internal/hcserror"
12 "github.com/Microsoft/hcsshim/internal/oc"
13 "go.opencensus.io/trace"
14 )
15
16
17
18
19
20
21 func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) {
22 title := "hcsshim::ExportLayer"
23 ctx, span := oc.StartSpan(ctx, title)
24 defer span.End()
25 defer func() { oc.SetSpanStatus(span, err) }()
26 span.AddAttributes(
27 trace.StringAttribute("path", path),
28 trace.StringAttribute("exportFolderPath", exportFolderPath),
29 trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
30
31
32 layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
33 if err != nil {
34 return err
35 }
36
37 err = exportLayer(&stdDriverInfo, path, exportFolderPath, layers)
38 if err != nil {
39 return hcserror.New(err, title, "")
40 }
41 return nil
42 }
43
44
45 type LayerReader interface {
46
47 Next() (string, int64, *winio.FileBasicInfo, error)
48
49 LinkInfo() (uint32, *winio.FileIDInfo, error)
50
51
52 Read(b []byte) (int, error)
53
54 Close() error
55 }
56
57
58
59
60 func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) {
61 ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerReader")
62 defer func() {
63 if err != nil {
64 oc.SetSpanStatus(span, err)
65 span.End()
66 }
67 }()
68 span.AddAttributes(
69 trace.StringAttribute("path", path),
70 trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
71
72 if len(parentLayerPaths) == 0 {
73
74 return newBaseLayerReader(path, span), nil
75 }
76
77 exportPath, err := os.MkdirTemp("", "hcs")
78 if err != nil {
79 return nil, err
80 }
81 err = ExportLayer(ctx, path, exportPath, parentLayerPaths)
82 if err != nil {
83 os.RemoveAll(exportPath)
84 return nil, err
85 }
86 return &legacyLayerReaderWrapper{
87 ctx: ctx,
88 s: span,
89 legacyLayerReader: newLegacyLayerReader(exportPath),
90 }, nil
91 }
92
93 type legacyLayerReaderWrapper struct {
94 ctx context.Context
95 s *trace.Span
96
97 *legacyLayerReader
98 }
99
100 func (r *legacyLayerReaderWrapper) Close() (err error) {
101 defer r.s.End()
102 defer func() { oc.SetSpanStatus(r.s, err) }()
103
104 err = r.legacyLayerReader.Close()
105 os.RemoveAll(r.root)
106 return err
107 }
108
View as plain text