1
2
3 package wclayer
4
5 import (
6 "context"
7 "os"
8 "path/filepath"
9 "strings"
10
11 "github.com/Microsoft/go-winio"
12 "github.com/Microsoft/hcsshim/internal/hcserror"
13 "github.com/Microsoft/hcsshim/internal/oc"
14 "github.com/Microsoft/hcsshim/internal/safefile"
15 "go.opencensus.io/trace"
16 )
17
18
19
20
21
22 func ImportLayer(ctx context.Context, path string, importFolderPath string, parentLayerPaths []string) (err error) {
23 title := "hcsshim::ImportLayer"
24 ctx, span := oc.StartSpan(ctx, title)
25 defer span.End()
26 defer func() { oc.SetSpanStatus(span, err) }()
27 span.AddAttributes(
28 trace.StringAttribute("path", path),
29 trace.StringAttribute("importFolderPath", importFolderPath),
30 trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
31
32
33 layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
34 if err != nil {
35 return err
36 }
37
38 err = importLayer(&stdDriverInfo, path, importFolderPath, layers)
39 if err != nil {
40 return hcserror.New(err, title, "")
41 }
42 return nil
43 }
44
45
46 type LayerWriter interface {
47
48 Add(name string, fileInfo *winio.FileBasicInfo) error
49
50 AddLink(name string, target string) error
51
52 Remove(name string) error
53
54
55 Write(b []byte) (int, error)
56
57 Close() error
58 }
59
60 type legacyLayerWriterWrapper struct {
61 ctx context.Context
62 s *trace.Span
63
64 *legacyLayerWriter
65 path string
66 parentLayerPaths []string
67 }
68
69 func (r *legacyLayerWriterWrapper) Close() (err error) {
70 defer r.s.End()
71 defer func() { oc.SetSpanStatus(r.s, err) }()
72 defer os.RemoveAll(r.root.Name())
73 defer r.legacyLayerWriter.CloseRoots()
74
75 err = r.legacyLayerWriter.Close()
76 if err != nil {
77 return err
78 }
79
80 if err = ImportLayer(r.ctx, r.destRoot.Name(), r.path, r.parentLayerPaths); err != nil {
81 return err
82 }
83 for _, name := range r.Tombstones {
84 if err = safefile.RemoveRelative(name, r.destRoot); err != nil && !os.IsNotExist(err) {
85 return err
86 }
87 }
88
89 for _, lnk := range r.PendingLinks {
90 if err = safefile.RemoveRelative(lnk.Path, r.destRoot); err != nil && !os.IsNotExist(err) {
91 return err
92 }
93 if err = safefile.LinkRelative(lnk.Target, lnk.TargetRoot, lnk.Path, r.destRoot); err != nil {
94 return err
95 }
96 }
97
98
99
100
101
102
103
104
105 err = reapplyDirectoryTimes(r.destRoot, r.changedDi)
106 if err != nil {
107 return err
108 }
109
110
111 if r.HasUtilityVM {
112 err := safefile.EnsureNotReparsePointRelative("UtilityVM", r.destRoot)
113 if err != nil {
114 return err
115 }
116 err = ProcessUtilityVMImage(r.ctx, filepath.Join(r.destRoot.Name(), "UtilityVM"))
117 if err != nil {
118 return err
119 }
120 }
121 return nil
122 }
123
124
125
126
127 func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) (_ LayerWriter, err error) {
128 ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerWriter")
129 defer func() {
130 if err != nil {
131 oc.SetSpanStatus(span, err)
132 span.End()
133 }
134 }()
135 span.AddAttributes(
136 trace.StringAttribute("path", path),
137 trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
138
139 if len(parentLayerPaths) == 0 {
140
141 f, err := safefile.OpenRoot(path)
142 if err != nil {
143 return nil, err
144 }
145 return &baseLayerWriter{
146 ctx: ctx,
147 s: span,
148 root: f,
149 }, nil
150 }
151
152 importPath, err := os.MkdirTemp("", "hcs")
153 if err != nil {
154 return nil, err
155 }
156 w, err := newLegacyLayerWriter(importPath, parentLayerPaths, path)
157 if err != nil {
158 return nil, err
159 }
160 return &legacyLayerWriterWrapper{
161 ctx: ctx,
162 s: span,
163 legacyLayerWriter: w,
164 path: importPath,
165 parentLayerPaths: parentLayerPaths,
166 }, nil
167 }
168
View as plain text