@@ -38,7 +38,8 @@ const (
38
38
// Set is a set of volumes.
39
39
type Set struct {
40
40
volumes map [string ]* Volume
41
- providers map [string ][]Mount
41
+ mounts map [string ][]Mount
42
+ providers map [string ]Provider
42
43
tempDir string
43
44
runtime string
44
45
volumeDir string
@@ -65,7 +66,8 @@ func NewSet(runtime string) *Set {
65
66
func NewSetWithTempDir (runtime , tempDir string ) * Set {
66
67
return & Set {
67
68
runtime : runtime ,
68
- providers : make (map [string ][]Mount ),
69
+ mounts : make (map [string ][]Mount ),
70
+ providers : make (map [string ]Provider ),
69
71
volumes : make (map [string ]* Volume ),
70
72
tempDir : tempDir ,
71
73
}
@@ -81,7 +83,12 @@ func (vs *Set) AddFrom(ctx context.Context, vp Provider) error {
81
83
if _ , exists := vs .providers [vp .Name ()]; exists {
82
84
return fmt .Errorf ("failed to add %q: %w" , vp .Name (), errdefs .ErrAlreadyExists )
83
85
}
84
- dir , err := os .MkdirTemp (vs .tempDir , "AddFrom" )
86
+ vs .providers [vp .Name ()] = vp
87
+ return nil
88
+ }
89
+
90
+ func (vs * Set ) copyToHostFromProvider (ctx context.Context , vp Provider ) error {
91
+ dir , err := os .MkdirTemp (vs .tempDir , "copyToHostFromProvider" )
85
92
if err != nil {
86
93
return err
87
94
}
@@ -100,7 +107,7 @@ func (vs *Set) AddFrom(ctx context.Context, vp Provider) error {
100
107
101
108
mounts = append (mounts , Mount {key : v .name , Destination : v .containerPath , ReadOnly : false })
102
109
}
103
- vs .providers [vp .Name ()] = mounts
110
+ vs .mounts [vp .Name ()] = mounts
104
111
return nil
105
112
}
106
113
@@ -147,7 +154,7 @@ func mountDiskImage(source, target string) error {
147
154
148
155
// PrepareDirectory creates a directory that have volumes.
149
156
func (vs * Set ) PrepareDirectory (ctx context.Context ) (retErr error ) {
150
- dir , err := os .MkdirTemp (vs .tempDir , "Prepare " )
157
+ dir , err := os .MkdirTemp (vs .tempDir , "PrepareDirectory " )
151
158
if err != nil {
152
159
retErr = err
153
160
return
@@ -161,19 +168,10 @@ func (vs *Set) PrepareDirectory(ctx context.Context) (retErr error) {
161
168
}
162
169
}()
163
170
164
- for _ , v := range vs .volumes {
165
- path , err := fs .RootPath (dir , v .name )
166
- if err != nil {
167
- return err
168
- }
169
- if v .hostPath == "" {
170
- continue
171
- }
172
- err = fs .CopyDir (path , v .hostPath )
173
- if err != nil {
174
- retErr = fmt .Errorf ("failed to copy volume %q: %w" , v .name , err )
175
- return
176
- }
171
+ err = vs .copyToHost (ctx , dir )
172
+ if err != nil {
173
+ retErr = err
174
+ return
177
175
}
178
176
179
177
vs .volumeDir = dir
@@ -221,30 +219,75 @@ func (vs *Set) PrepareDriveMount(ctx context.Context, size int64) (dm *proto.Fir
221
219
}
222
220
}()
223
221
222
+ err = vs .copyToHost (ctx , dir )
223
+ if err != nil {
224
+ retErr = err
225
+ return
226
+ }
227
+
228
+ dm = & proto.FirecrackerDriveMount {
229
+ HostPath : path ,
230
+ VMPath : vmVolumePath ,
231
+ FilesystemType : fsType ,
232
+ IsWritable : true ,
233
+ }
234
+ vs .volumeDir = vmVolumePath
235
+ return
236
+ }
237
+
238
+ // PrepareInGuest prepares volumes inside the VM.
239
+ func (vs * Set ) PrepareInGuest (ctx context.Context , container string ) error {
240
+ for _ , provider := range vs .providers {
241
+ gp , guest := provider .(* GuestVolumeImageProvider )
242
+ if ! guest {
243
+ continue
244
+ }
245
+
246
+ err := gp .pull (ctx )
247
+ if err != nil {
248
+ return err
249
+ }
250
+
251
+ err = gp .copy (ctx , container )
252
+ if err != nil {
253
+ return err
254
+ }
255
+
256
+ err = vs .copyToHostFromProvider (ctx , provider )
257
+ if err != nil {
258
+ return err
259
+ }
260
+ }
261
+ return nil
262
+ }
263
+
264
+ func (vs * Set ) copyToHost (ctx context.Context , dir string ) error {
265
+ for _ , provider := range vs .providers {
266
+ _ , guest := provider .(* GuestVolumeImageProvider )
267
+ if guest {
268
+ continue
269
+ }
270
+
271
+ err := vs .copyToHostFromProvider (ctx , provider )
272
+ if err != nil {
273
+ return err
274
+ }
275
+ }
276
+
224
277
for _ , v := range vs .volumes {
225
278
path , err := fs .RootPath (dir , v .name )
226
279
if err != nil {
227
- retErr = err
228
- return
280
+ return err
229
281
}
230
282
if v .hostPath == "" {
231
283
continue
232
284
}
233
285
err = fs .CopyDir (path , v .hostPath )
234
286
if err != nil {
235
- retErr = fmt .Errorf ("failed to copy volume %q: %w" , v .name , err )
236
- return
287
+ return fmt .Errorf ("failed to copy volume %q: %w" , v .name , err )
237
288
}
238
289
}
239
-
240
- dm = & proto.FirecrackerDriveMount {
241
- HostPath : path ,
242
- VMPath : vmVolumePath ,
243
- FilesystemType : fsType ,
244
- IsWritable : true ,
245
- }
246
- vs .volumeDir = vmVolumePath
247
- return
290
+ return nil
248
291
}
249
292
250
293
// Mount is used to expose volumes to containers.
@@ -303,5 +346,10 @@ func (vs *Set) WithMounts(mountpoints []Mount) (oci.SpecOpts, error) {
303
346
304
347
// WithMountsFromProvider exposes volumes from the provider.
305
348
func (vs * Set ) WithMountsFromProvider (name string ) (oci.SpecOpts , error ) {
306
- return vs .WithMounts (vs .providers [name ])
349
+ _ , exists := vs .providers [name ]
350
+ if ! exists {
351
+ return nil , fmt .Errorf ("failed to find volume %q: %w" , name , errdefs .ErrNotFound )
352
+ }
353
+
354
+ return vs .WithMounts (vs .mounts [name ])
307
355
}
0 commit comments