@@ -38,7 +38,8 @@ const (
3838// Set is a set of volumes.
3939type Set struct {
4040 volumes map [string ]* Volume
41- providers map [string ][]Mount
41+ mounts map [string ][]Mount
42+ providers map [string ]Provider
4243 tempDir string
4344 runtime string
4445 volumeDir string
@@ -65,7 +66,8 @@ func NewSet(runtime string) *Set {
6566func NewSetWithTempDir (runtime , tempDir string ) * Set {
6667 return & Set {
6768 runtime : runtime ,
68- providers : make (map [string ][]Mount ),
69+ mounts : make (map [string ][]Mount ),
70+ providers : make (map [string ]Provider ),
6971 volumes : make (map [string ]* Volume ),
7072 tempDir : tempDir ,
7173 }
@@ -81,7 +83,12 @@ func (vs *Set) AddFrom(ctx context.Context, vp Provider) error {
8183 if _ , exists := vs .providers [vp .Name ()]; exists {
8284 return fmt .Errorf ("failed to add %q: %w" , vp .Name (), errdefs .ErrAlreadyExists )
8385 }
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" )
8592 if err != nil {
8693 return err
8794 }
@@ -100,7 +107,7 @@ func (vs *Set) AddFrom(ctx context.Context, vp Provider) error {
100107
101108 mounts = append (mounts , Mount {key : v .name , Destination : v .containerPath , ReadOnly : false })
102109 }
103- vs .providers [vp .Name ()] = mounts
110+ vs .mounts [vp .Name ()] = mounts
104111 return nil
105112}
106113
@@ -147,7 +154,7 @@ func mountDiskImage(source, target string) error {
147154
148155// PrepareDirectory creates a directory that have volumes.
149156func (vs * Set ) PrepareDirectory (ctx context.Context ) (retErr error ) {
150- dir , err := os .MkdirTemp (vs .tempDir , "Prepare " )
157+ dir , err := os .MkdirTemp (vs .tempDir , "PrepareDirectory " )
151158 if err != nil {
152159 retErr = err
153160 return
@@ -161,19 +168,10 @@ func (vs *Set) PrepareDirectory(ctx context.Context) (retErr error) {
161168 }
162169 }()
163170
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
177175 }
178176
179177 vs .volumeDir = dir
@@ -221,30 +219,75 @@ func (vs *Set) PrepareDriveMount(ctx context.Context, size int64) (dm *proto.Fir
221219 }
222220 }()
223221
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+
224277 for _ , v := range vs .volumes {
225278 path , err := fs .RootPath (dir , v .name )
226279 if err != nil {
227- retErr = err
228- return
280+ return err
229281 }
230282 if v .hostPath == "" {
231283 continue
232284 }
233285 err = fs .CopyDir (path , v .hostPath )
234286 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 )
237288 }
238289 }
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
248291}
249292
250293// Mount is used to expose volumes to containers.
@@ -303,5 +346,10 @@ func (vs *Set) WithMounts(mountpoints []Mount) (oci.SpecOpts, error) {
303346
304347// WithMountsFromProvider exposes volumes from the provider.
305348func (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 ])
307355}
0 commit comments