1
2
3 package computestorage
4
5 import (
6 "context"
7 "os"
8 "path/filepath"
9 "syscall"
10
11 "github.com/Microsoft/go-winio/vhd"
12 "github.com/Microsoft/hcsshim/internal/memory"
13 "github.com/pkg/errors"
14 "golang.org/x/sys/windows"
15
16 "github.com/Microsoft/hcsshim/internal/security"
17 )
18
19 const defaultVHDXBlockSizeInMB = 1
20
21
22
23
24
25
26
27
28
29
30
31
32 func SetupContainerBaseLayer(ctx context.Context, layerPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
33 var (
34 hivesPath = filepath.Join(layerPath, "Hives")
35 layoutPath = filepath.Join(layerPath, "Layout")
36 )
37
38
39
40
41 if _, err := os.Stat(hivesPath); err == nil {
42 if err := os.RemoveAll(hivesPath); err != nil {
43 return errors.Wrap(err, "failed to remove prexisting hives directory")
44 }
45 }
46 if _, err := os.Stat(layoutPath); err == nil {
47 if err := os.RemoveAll(layoutPath); err != nil {
48 return errors.Wrap(err, "failed to remove prexisting layout file")
49 }
50 }
51
52 if _, err := os.Stat(baseVhdPath); err == nil {
53 if err := os.RemoveAll(baseVhdPath); err != nil {
54 return errors.Wrap(err, "failed to remove base vhdx path")
55 }
56 }
57 if _, err := os.Stat(diffVhdPath); err == nil {
58 if err := os.RemoveAll(diffVhdPath); err != nil {
59 return errors.Wrap(err, "failed to remove differencing vhdx")
60 }
61 }
62
63 createParams := &vhd.CreateVirtualDiskParameters{
64 Version: 2,
65 Version2: vhd.CreateVersion2{
66 MaximumSize: sizeInGB * memory.GiB,
67 BlockSizeInBytes: defaultVHDXBlockSizeInMB * memory.MiB,
68 },
69 }
70 handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams)
71 if err != nil {
72 return errors.Wrap(err, "failed to create vhdx")
73 }
74
75 defer func() {
76 if err != nil {
77 _ = syscall.CloseHandle(handle)
78 os.RemoveAll(baseVhdPath)
79 os.RemoveAll(diffVhdPath)
80 }
81 }()
82
83 if err = FormatWritableLayerVhd(ctx, windows.Handle(handle)); err != nil {
84 return err
85 }
86
87 if err = syscall.CloseHandle(handle); err != nil {
88 return errors.Wrap(err, "failed to close vhdx handle")
89 }
90
91 options := OsLayerOptions{
92 Type: OsLayerTypeContainer,
93 }
94
95
96
97 if err = SetupBaseOSLayer(ctx, layerPath, 0, options); err != nil {
98 return err
99 }
100
101
102 if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
103 return errors.Wrap(err, "failed to create differencing disk")
104 }
105
106 if err = security.GrantVmGroupAccess(baseVhdPath); err != nil {
107 return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath)
108 }
109 if err = security.GrantVmGroupAccess(diffVhdPath); err != nil {
110 return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath)
111 }
112 return nil
113 }
114
115
116
117
118
119
120
121
122
123
124
125 func SetupUtilityVMBaseLayer(ctx context.Context, uvmPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
126
127 if _, err := os.Stat(baseVhdPath); err == nil {
128 if err := os.RemoveAll(baseVhdPath); err != nil {
129 return errors.Wrap(err, "failed to remove base vhdx")
130 }
131 }
132 if _, err := os.Stat(diffVhdPath); err == nil {
133 if err := os.RemoveAll(diffVhdPath); err != nil {
134 return errors.Wrap(err, "failed to remove differencing vhdx")
135 }
136 }
137
138
139 createParams := &vhd.CreateVirtualDiskParameters{
140 Version: 2,
141 Version2: vhd.CreateVersion2{
142 MaximumSize: sizeInGB * memory.GiB,
143 BlockSizeInBytes: defaultVHDXBlockSizeInMB * memory.MiB,
144 },
145 }
146 handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams)
147 if err != nil {
148 return errors.Wrap(err, "failed to create vhdx")
149 }
150
151 defer func() {
152 if err != nil {
153 _ = syscall.CloseHandle(handle)
154 os.RemoveAll(baseVhdPath)
155 os.RemoveAll(diffVhdPath)
156 }
157 }()
158
159
160
161 attachParams := &vhd.AttachVirtualDiskParameters{
162 Version: 2,
163 }
164 if err := vhd.AttachVirtualDisk(handle, vhd.AttachVirtualDiskFlagNone, attachParams); err != nil {
165 return errors.Wrapf(err, "failed to attach virtual disk")
166 }
167
168 options := OsLayerOptions{
169 Type: OsLayerTypeVM,
170 }
171 if err := SetupBaseOSLayer(ctx, uvmPath, windows.Handle(handle), options); err != nil {
172 return err
173 }
174
175
176
177 if err = vhd.DetachVirtualDisk(handle); err != nil {
178 return errors.Wrap(err, "failed to detach vhdx")
179 }
180 if err = syscall.CloseHandle(handle); err != nil {
181 return errors.Wrap(err, "failed to close vhdx handle")
182 }
183
184
185
186 if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
187 return errors.Wrap(err, "failed to create differencing disk")
188 }
189
190 if err := security.GrantVmGroupAccess(baseVhdPath); err != nil {
191 return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath)
192 }
193 if err := security.GrantVmGroupAccess(diffVhdPath); err != nil {
194 return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath)
195 }
196 return nil
197 }
198
View as plain text