@@ -59,7 +59,7 @@ type VirtioVsock struct {
5959
6060// VirtioBlk configures a disk device.
6161type VirtioBlk struct {
62- StorageConfig
62+ DiskStorageConfig
6363 DeviceIdentifier string `json:"deviceIdentifier,omitempty"`
6464}
6565
@@ -82,7 +82,7 @@ type RosettaShare struct {
8282
8383// NVMExpressController configures a NVMe controller in the guest
8484type NVMExpressController struct {
85- StorageConfig
85+ DiskStorageConfig
8686}
8787
8888// VirtioRng configures a random number generator (RNG) device.
@@ -117,7 +117,8 @@ const (
117117)
118118
119119type NetworkBlockDevice struct {
120- VirtioBlk
120+ NetworkBlockStorageConfig
121+ DeviceIdentifier string
121122 Timeout time.Duration
122123 SynchronizationMode NBDSynchronizationMode
123124}
@@ -479,8 +480,10 @@ func (dev *VirtioRng) FromOptions(options []option) error {
479480
480481func nvmExpressControllerNewEmpty () * NVMExpressController {
481482 return & NVMExpressController {
482- StorageConfig : StorageConfig {
483- DevName : "nvme" ,
483+ DiskStorageConfig : DiskStorageConfig {
484+ StorageConfig : StorageConfig {
485+ DevName : "nvme" ,
486+ },
484487 },
485488 }
486489}
@@ -496,8 +499,10 @@ func NVMExpressControllerNew(imagePath string) (*NVMExpressController, error) {
496499
497500func virtioBlkNewEmpty () * VirtioBlk {
498501 return & VirtioBlk {
499- StorageConfig : StorageConfig {
500- DevName : "virtio-blk" ,
502+ DiskStorageConfig : DiskStorageConfig {
503+ StorageConfig : StorageConfig {
504+ DevName : "virtio-blk" ,
505+ },
501506 },
502507 DeviceIdentifier : "" ,
503508 }
@@ -527,11 +532,11 @@ func (dev *VirtioBlk) FromOptions(options []option) error {
527532 }
528533 }
529534
530- return dev .StorageConfig .FromOptions (unhandledOpts )
535+ return dev .DiskStorageConfig .FromOptions (unhandledOpts )
531536}
532537
533538func (dev * VirtioBlk ) ToCmdLine () ([]string , error ) {
534- cmdLine , err := dev .StorageConfig .ToCmdLine ()
539+ cmdLine , err := dev .DiskStorageConfig .ToCmdLine ()
535540 if err != nil {
536541 return []string {}, err
537542 }
@@ -681,12 +686,12 @@ func (dev *RosettaShare) FromOptions(options []option) error {
681686
682687func networkBlockDeviceNewEmpty () * NetworkBlockDevice {
683688 return & NetworkBlockDevice {
684- VirtioBlk : VirtioBlk {
689+ NetworkBlockStorageConfig : NetworkBlockStorageConfig {
685690 StorageConfig : StorageConfig {
686691 DevName : "nbd" ,
687692 },
688- DeviceIdentifier : "" ,
689693 },
694+ DeviceIdentifier : "" ,
690695 Timeout : time .Duration (15000 * time .Millisecond ), // set a default timeout to 15s
691696 SynchronizationMode : SynchronizationFullMode , // default mode to full
692697 }
@@ -707,14 +712,17 @@ func NetworkBlockDeviceNew(uri string, timeout uint32, synchronization NBDSynchr
707712}
708713
709714func (nbd * NetworkBlockDevice ) ToCmdLine () ([]string , error ) {
710- cmdLine , err := nbd .VirtioBlk .ToCmdLine ()
715+ cmdLine , err := nbd .NetworkBlockStorageConfig .ToCmdLine ()
711716 if err != nil {
712717 return []string {}, err
713718 }
714719 if len (cmdLine ) != 2 {
715720 return []string {}, fmt .Errorf ("unexpected storage config commandline" )
716721 }
717722
723+ if nbd .DeviceIdentifier != "" {
724+ cmdLine [1 ] = fmt .Sprintf ("%s,deviceId=%s" , cmdLine [1 ], nbd .DeviceIdentifier )
725+ }
718726 if nbd .Timeout .Milliseconds () > 0 {
719727 cmdLine [1 ] = fmt .Sprintf ("%s,timeout=%d" , cmdLine [1 ], nbd .Timeout .Milliseconds ())
720728 }
@@ -729,6 +737,8 @@ func (nbd *NetworkBlockDevice) FromOptions(options []option) error {
729737 unhandledOpts := []option {}
730738 for _ , option := range options {
731739 switch option .key {
740+ case "deviceId" :
741+ nbd .DeviceIdentifier = option .value
732742 case "timeout" :
733743 timeoutMS , err := strconv .ParseInt (option .value , 10 , 32 )
734744 if err != nil {
@@ -749,17 +759,19 @@ func (nbd *NetworkBlockDevice) FromOptions(options []option) error {
749759 }
750760 }
751761
752- return nbd .VirtioBlk .FromOptions (unhandledOpts )
762+ return nbd .NetworkBlockStorageConfig .FromOptions (unhandledOpts )
753763}
754764
755765type USBMassStorage struct {
756- StorageConfig
766+ DiskStorageConfig
757767}
758768
759769func usbMassStorageNewEmpty () * USBMassStorage {
760770 return & USBMassStorage {
761- StorageConfig {
762- DevName : "usb-mass-storage" ,
771+ DiskStorageConfig : DiskStorageConfig {
772+ StorageConfig : StorageConfig {
773+ DevName : "usb-mass-storage" ,
774+ },
763775 },
764776 }
765777}
@@ -779,38 +791,66 @@ func (dev *USBMassStorage) SetReadOnly(readOnly bool) {
779791
780792// StorageConfig configures a disk device.
781793type StorageConfig struct {
782- DevName string `json:"devName"`
794+ DevName string `json:"devName"`
795+ ReadOnly bool `json:"readOnly,omitempty"`
796+ }
797+
798+ type DiskStorageConfig struct {
799+ StorageConfig
783800 ImagePath string `json:"imagePath,omitempty"`
784- URI string `json:"uri,omitempty"`
785- ReadOnly bool `json:"readOnly,omitempty"`
786801}
787802
788- func (config * StorageConfig ) ToCmdLine () ([]string , error ) {
789- if config .ImagePath != "" && config .URI != "" {
790- return nil , fmt .Errorf ("%s devices cannot have both path to a disk image and a uri to a remote block device" , config .DevName )
803+ type NetworkBlockStorageConfig struct {
804+ StorageConfig
805+ URI string `json:"uri,omitempty"`
806+ }
807+
808+ func (config * DiskStorageConfig ) ToCmdLine () ([]string , error ) {
809+ if config .ImagePath == "" {
810+ return nil , fmt .Errorf ("%s devices need the path to a disk image" , config .DevName )
791811 }
792- if config .ImagePath == "" && config .URI == "" {
793- return nil , fmt .Errorf ("%s devices need a path to a disk image or a uri to a remote block device" , config .DevName )
812+
813+ value := fmt .Sprintf ("%s,path=%s" , config .DevName , config .ImagePath )
814+
815+ if config .ReadOnly {
816+ value += ",readonly"
794817 }
795- var value string
796- if config .ImagePath != "" {
797- value = fmt .Sprintf ("%s,path=%s" , config .DevName , config .ImagePath )
818+ return []string {"--device" , value }, nil
819+ }
820+
821+ func (config * DiskStorageConfig ) FromOptions (options []option ) error {
822+ for _ , option := range options {
823+ switch option .key {
824+ case "path" :
825+ config .ImagePath = option .value
826+ case "readonly" :
827+ if option .value != "" {
828+ return fmt .Errorf ("unexpected value for virtio-blk 'readonly' option: %s" , option .value )
829+ }
830+ config .ReadOnly = true
831+ default :
832+ return fmt .Errorf ("unknown option for %s devices: %s" , config .DevName , option .key )
833+ }
798834 }
799- if config .URI != "" {
800- value = fmt .Sprintf ("%s,uri=%s" , config .DevName , config .URI )
835+ return nil
836+ }
837+
838+ func (config * NetworkBlockStorageConfig ) ToCmdLine () ([]string , error ) {
839+ if config .URI == "" {
840+ return nil , fmt .Errorf ("%s devices need the uri to a remote block device" , config .DevName )
801841 }
802842
843+ value := fmt .Sprintf ("%s,uri=%s" , config .DevName , config .URI )
844+
803845 if config .ReadOnly {
804846 value += ",readonly"
805847 }
806848 return []string {"--device" , value }, nil
807849}
808850
809- func (config * StorageConfig ) FromOptions (options []option ) error {
851+ func (config * NetworkBlockStorageConfig ) FromOptions (options []option ) error {
810852 for _ , option := range options {
811853 switch option .key {
812- case "path" :
813- config .ImagePath = option .value
814854 case "uri" :
815855 config .URI = option .value
816856 case "readonly" :
0 commit comments