@@ -11,7 +11,10 @@ import (
11
11
)
12
12
13
13
// The VirtioDevice interface is an interface which is implemented by all virtio devices.
14
- type VirtioDevice VMComponent
14
+ type VirtioDevice interface {
15
+ VMComponent
16
+ Validate () error
17
+ }
15
18
16
19
const (
17
20
// Possible values for VirtioInput.InputType
@@ -140,6 +143,10 @@ func (v *VirtioBalloon) ToCmdLine() ([]string, error) {
140
143
return []string {"--device" , "virtio-balloon" }, nil
141
144
}
142
145
146
+ func (v * VirtioBalloon ) Validate () error {
147
+ return nil
148
+ }
149
+
143
150
type option struct {
144
151
key string
145
152
value string
@@ -230,7 +237,7 @@ func VirtioSerialNewStdio() (VirtioDevice, error) {
230
237
}, nil
231
238
}
232
239
233
- func (dev * VirtioSerial ) validate () error {
240
+ func (dev * VirtioSerial ) Validate () error {
234
241
if dev .LogFile != "" && dev .UsesStdio {
235
242
return fmt .Errorf ("'logFilePath' and 'stdio' cannot be set at the same time" )
236
243
}
@@ -242,7 +249,7 @@ func (dev *VirtioSerial) validate() error {
242
249
}
243
250
244
251
func (dev * VirtioSerial ) ToCmdLine () ([]string , error ) {
245
- if err := dev .validate (); err != nil {
252
+ if err := dev .Validate (); err != nil {
246
253
return nil , err
247
254
}
248
255
if dev .UsesStdio {
@@ -267,7 +274,7 @@ func (dev *VirtioSerial) FromOptions(options []option) error {
267
274
}
268
275
}
269
276
270
- return dev .validate ()
277
+ return dev .Validate ()
271
278
}
272
279
273
280
// VirtioInputNew creates a new input device for the virtual machine.
@@ -277,14 +284,14 @@ func VirtioInputNew(inputType string) (VirtioDevice, error) {
277
284
dev := & VirtioInput {
278
285
InputType : inputType ,
279
286
}
280
- if err := dev .validate (); err != nil {
287
+ if err := dev .Validate (); err != nil {
281
288
return nil , err
282
289
}
283
290
284
291
return dev , nil
285
292
}
286
293
287
- func (dev * VirtioInput ) validate () error {
294
+ func (dev * VirtioInput ) Validate () error {
288
295
if dev .InputType != VirtioInputPointingDevice && dev .InputType != VirtioInputKeyboardDevice {
289
296
return fmt .Errorf ("unknown option for virtio-input devices: %s" , dev .InputType )
290
297
}
@@ -293,7 +300,7 @@ func (dev *VirtioInput) validate() error {
293
300
}
294
301
295
302
func (dev * VirtioInput ) ToCmdLine () ([]string , error ) {
296
- if err := dev .validate (); err != nil {
303
+ if err := dev .Validate (); err != nil {
297
304
return nil , err
298
305
}
299
306
@@ -312,7 +319,7 @@ func (dev *VirtioInput) FromOptions(options []option) error {
312
319
return fmt .Errorf ("unknown option for virtio-input devices: %s" , option .key )
313
320
}
314
321
}
315
- return dev .validate ()
322
+ return dev .Validate ()
316
323
}
317
324
318
325
// VirtioGPUNew creates a new gpu device for the virtual machine.
@@ -328,7 +335,7 @@ func VirtioGPUNew() (VirtioDevice, error) {
328
335
}, nil
329
336
}
330
337
331
- func (dev * VirtioGPU ) validate () error {
338
+ func (dev * VirtioGPU ) Validate () error {
332
339
if dev .Height < 1 || dev .Width < 1 {
333
340
return fmt .Errorf ("invalid dimensions for virtio-gpu device resolution: %dx%d" , dev .Width , dev .Height )
334
341
}
@@ -337,7 +344,7 @@ func (dev *VirtioGPU) validate() error {
337
344
}
338
345
339
346
func (dev * VirtioGPU ) ToCmdLine () ([]string , error ) {
340
- if err := dev .validate (); err != nil {
347
+ if err := dev .Validate (); err != nil {
341
348
return nil , err
342
349
}
343
350
@@ -371,7 +378,7 @@ func (dev *VirtioGPU) FromOptions(options []option) error {
371
378
dev .Height = defaultVirtioGPUResolutionHeight
372
379
}
373
380
374
- return dev .validate ()
381
+ return dev .Validate ()
375
382
}
376
383
377
384
// VirtioNetNew creates a new network device for the virtual machine. It will
@@ -407,7 +414,7 @@ func (dev *VirtioNet) SetUnixSocketPath(path string) {
407
414
dev .Nat = false
408
415
}
409
416
410
- func (dev * VirtioNet ) validate () error {
417
+ func (dev * VirtioNet ) Validate () error {
411
418
if dev .Nat && dev .Socket != nil {
412
419
return fmt .Errorf ("'nat' and 'fd' cannot be set at the same time" )
413
420
}
@@ -425,7 +432,7 @@ func (dev *VirtioNet) validate() error {
425
432
}
426
433
427
434
func (dev * VirtioNet ) ToCmdLine () ([]string , error ) {
428
- if err := dev .validate (); err != nil {
435
+ if err := dev .Validate (); err != nil {
429
436
return nil , err
430
437
}
431
438
@@ -474,7 +481,7 @@ func (dev *VirtioNet) FromOptions(options []option) error {
474
481
}
475
482
}
476
483
477
- return dev .validate ()
484
+ return dev .Validate ()
478
485
}
479
486
480
487
// VirtioRngNew creates a new random number generator device to feed entropy
@@ -494,6 +501,10 @@ func (dev *VirtioRng) FromOptions(options []option) error {
494
501
return nil
495
502
}
496
503
504
+ func (dev * VirtioRng ) Validate () error {
505
+ return nil
506
+ }
507
+
497
508
func nvmExpressControllerNewEmpty () * NVMExpressController {
498
509
return & NVMExpressController {
499
510
DiskStorageConfig : DiskStorageConfig {
@@ -551,6 +562,24 @@ func (dev *VirtioBlk) FromOptions(options []option) error {
551
562
return dev .DiskStorageConfig .FromOptions (unhandledOpts )
552
563
}
553
564
565
+ func (dev * VirtioBlk ) Validate () error {
566
+ imgPath := dev .ImagePath
567
+ file , err := os .Open (imgPath )
568
+ if err != nil {
569
+ return fmt .Errorf ("failed to open file %s: %v" , imgPath , err )
570
+ }
571
+ defer file .Close ()
572
+ header := make ([]byte , 4 )
573
+ _ , err = file .Read (header )
574
+ if err != nil {
575
+ return fmt .Errorf ("failed to read the header of file %s: %v" , imgPath , err )
576
+ }
577
+ if string (header ) == "QFI\xfb " {
578
+ return fmt .Errorf ("vfkit does not support qcow2 image format" )
579
+ }
580
+ return nil
581
+ }
582
+
554
583
func (dev * VirtioBlk ) ToCmdLine () ([]string , error ) {
555
584
cmdLine , err := dev .DiskStorageConfig .ToCmdLine ()
556
585
if err != nil {
@@ -618,6 +647,10 @@ func (dev *VirtioVsock) FromOptions(options []option) error {
618
647
return nil
619
648
}
620
649
650
+ func (dev * VirtioVsock ) Validate () error {
651
+ return nil
652
+ }
653
+
621
654
// VirtioFsNew creates a new virtio-fs device for file sharing. It will share
622
655
// the directory at sharedDir with the virtual machine. This directory can be
623
656
// mounted in the VM using `mount -t virtiofs mountTag /some/dir`
@@ -655,6 +688,10 @@ func (dev *VirtioFs) FromOptions(options []option) error {
655
688
return nil
656
689
}
657
690
691
+ func (dev * VirtioFs ) Validate () error {
692
+ return nil
693
+ }
694
+
658
695
// RosettaShareNew RosettaShare creates a new rosetta share for running x86_64 binaries on M1 machines.
659
696
// It will share a directory containing the linux rosetta binaries with the
660
697
// virtual machine. This directory can be mounted in the VM using `mount -t
@@ -700,6 +737,10 @@ func (dev *RosettaShare) FromOptions(options []option) error {
700
737
return nil
701
738
}
702
739
740
+ func (dev * RosettaShare ) Validate () error {
741
+ return nil
742
+ }
743
+
703
744
func networkBlockDeviceNewEmpty () * NetworkBlockDevice {
704
745
return & NetworkBlockDevice {
705
746
NetworkBlockStorageConfig : NetworkBlockStorageConfig {
@@ -778,6 +819,10 @@ func (nbd *NetworkBlockDevice) FromOptions(options []option) error {
778
819
return nbd .NetworkBlockStorageConfig .FromOptions (unhandledOpts )
779
820
}
780
821
822
+ func (nbd * NetworkBlockDevice ) Validate () error {
823
+ return nil
824
+ }
825
+
781
826
type USBMassStorage struct {
782
827
DiskStorageConfig
783
828
}
@@ -851,6 +896,10 @@ func (config *DiskStorageConfig) FromOptions(options []option) error {
851
896
return nil
852
897
}
853
898
899
+ func (config * DiskStorageConfig ) Validate () error {
900
+ return nil
901
+ }
902
+
854
903
func (config * NetworkBlockStorageConfig ) ToCmdLine () ([]string , error ) {
855
904
if config .URI == "" {
856
905
return nil , fmt .Errorf ("%s devices need the uri to a remote block device" , config .DevName )
0 commit comments