8
8
"path/filepath"
9
9
"strconv"
10
10
"strings"
11
- "sync"
12
11
"time"
13
12
)
14
13
@@ -212,18 +211,16 @@ func (m *Machine) Delete() error {
212
211
return Manage ().run ("unregistervm" , m .Name , "--delete" )
213
212
}
214
213
215
- var mutex sync.Mutex
216
-
217
- // GetMachine finds a machine by its name or UUID.
218
- func GetMachine (id string ) (* Machine , error ) {
214
+ // Machine returns the current machine state based on the current state.
215
+ func (m * manager ) Machine (ctx context.Context , id string ) (* Machine , error ) {
219
216
/* There is a strage behavior where running multiple instances of
220
217
'VBoxManage showvminfo' on same VM simultaneously can return an error of
221
218
'object is not ready (E_ACCESSDENIED)', so we sequential the operation with a mutex.
222
219
Note if you are running multiple process of go-virtualbox or 'showvminfo'
223
220
in the command line side by side, this not gonna work. */
224
- mutex .Lock ()
225
- stdout , stderr , err := Manage (). runOutErr ( "showvminfo" , id , "--machinereadable" )
226
- mutex .Unlock ()
221
+ m . lock .Lock ()
222
+ stdout , stderr , err := m . run ( ctx , "showvminfo" , id , "--machinereadable" )
223
+ m . lock .Unlock ()
227
224
if err != nil {
228
225
if reMachineNotFound .FindString (stderr ) != "" {
229
226
return nil , ErrMachineNotExist
@@ -251,28 +248,28 @@ func GetMachine(id string) (*Machine, error) {
251
248
}
252
249
253
250
/* Extract basic info */
254
- m := New ()
255
- m .Name = propMap ["name" ]
256
- m .Firmware = propMap ["firmware" ]
257
- m .UUID = propMap ["UUID" ]
258
- m .State = MachineState (propMap ["VMState" ])
251
+ vm := New ()
252
+ vm .Name = propMap ["name" ]
253
+ vm .Firmware = propMap ["firmware" ]
254
+ vm .UUID = propMap ["UUID" ]
255
+ vm .State = MachineState (propMap ["VMState" ])
259
256
n , err := strconv .ParseUint (propMap ["memory" ], 10 , 32 )
260
257
if err != nil {
261
258
return nil , err
262
259
}
263
- m .Memory = uint (n )
260
+ vm .Memory = uint (n )
264
261
n , err = strconv .ParseUint (propMap ["cpus" ], 10 , 32 )
265
262
if err != nil {
266
263
return nil , err
267
264
}
268
- m .CPUs = uint (n )
265
+ vm .CPUs = uint (n )
269
266
n , err = strconv .ParseUint (propMap ["vram" ], 10 , 32 )
270
267
if err != nil {
271
268
return nil , err
272
269
}
273
- m .VRAM = uint (n )
274
- m .CfgFile = propMap ["CfgFile" ]
275
- m .BaseFolder = filepath .Dir (m .CfgFile )
270
+ vm .VRAM = uint (n )
271
+ vm .CfgFile = propMap ["CfgFile" ]
272
+ vm .BaseFolder = filepath .Dir (vm .CfgFile )
276
273
277
274
/* Extract NIC info */
278
275
for i := 1 ; i <= 4 ; i ++ {
@@ -295,29 +292,46 @@ func GetMachine(id string) (*Machine, error) {
295
292
} else if nic .Network == NICNetBridged {
296
293
nic .HostInterface = propMap [fmt .Sprintf ("bridgeadapter%d" , i )]
297
294
}
298
- m .NICs = append (m .NICs , nic )
295
+ vm .NICs = append (vm .NICs , nic )
299
296
}
300
297
301
298
if err := s .Err (); err != nil {
302
299
return nil , err
303
300
}
304
- return m , nil
301
+ return vm , nil
302
+ }
303
+
304
+ // GetMachine finds a machine by its name or UUID.
305
+ //
306
+ // Deprecated: Use Manager.Machine()
307
+ func GetMachine (id string ) (* Machine , error ) {
308
+ return defaultManager .Machine (context .Background (), id )
305
309
}
306
310
307
311
// ListMachines lists all registered machines.
312
+ //
313
+ // Deprecated: Use Manager.ListMachines()
308
314
func ListMachines () ([]* Machine , error ) {
309
- out , err := Manage ().runOut ("list" , "vms" )
315
+ return defaultManager .ListMachines (context .Background ())
316
+ }
317
+
318
+ // ListMachines lists all registered machines.
319
+ func (m * manager ) ListMachines (ctx context.Context ) ([]* Machine , error ) {
320
+ m .lock .Lock ()
321
+ out , _ , err := m .run (ctx , "list" , "vms" )
322
+ m .lock .Unlock ()
310
323
if err != nil {
311
324
return nil , err
312
325
}
326
+
313
327
ms := []* Machine {}
314
328
s := bufio .NewScanner (strings .NewReader (out ))
315
329
for s .Scan () {
316
330
res := reVMNameUUID .FindStringSubmatch (s .Text ())
317
331
if res == nil {
318
332
continue
319
333
}
320
- m , err := GetMachine ( res [1 ])
334
+ m , err := m . Machine ( ctx , res [1 ])
321
335
if err != nil {
322
336
// Sometimes a VM is listed but not available, so we need to handle this.
323
337
if err == ErrMachineNotExist {
@@ -368,44 +382,44 @@ func CreateMachine(name, basefolder string) (*Machine, error) {
368
382
return m , nil
369
383
}
370
384
371
- // Modify changes the settings of the machine .
372
- func (m * Machine ) Modify ( ) error {
373
- args := []string {"modifyvm" , m .Name ,
374
- "--firmware" , m .Firmware ,
385
+ // UpdateMachine updates the machine details based on the struct fields .
386
+ func (m * manager ) UpdateMachine ( ctx context. Context , vm * Machine ) error {
387
+ args := []string {"modifyvm" , vm .Name ,
388
+ "--firmware" , vm .Firmware ,
375
389
"--bioslogofadein" , "off" ,
376
390
"--bioslogofadeout" , "off" ,
377
391
"--bioslogodisplaytime" , "0" ,
378
392
"--biosbootmenu" , "disabled" ,
379
393
380
- "--ostype" , m .OSType ,
381
- "--cpus" , fmt .Sprintf ("%d" , m .CPUs ),
382
- "--memory" , fmt .Sprintf ("%d" , m .Memory ),
383
- "--vram" , fmt .Sprintf ("%d" , m .VRAM ),
384
-
385
- "--acpi" , m .Flag .Get (ACPI ),
386
- "--ioapic" , m .Flag .Get (IOAPIC ),
387
- "--rtcuseutc" , m .Flag .Get (RTCUSEUTC ),
388
- "--cpuhotplug" , m .Flag .Get (CPUHOTPLUG ),
389
- "--pae" , m .Flag .Get (PAE ),
390
- "--longmode" , m .Flag .Get (LONGMODE ),
391
- "--hpet" , m .Flag .Get (HPET ),
392
- "--hwvirtex" , m .Flag .Get (HWVIRTEX ),
393
- "--triplefaultreset" , m .Flag .Get (TRIPLEFAULTRESET ),
394
- "--nestedpaging" , m .Flag .Get (NESTEDPAGING ),
395
- "--largepages" , m .Flag .Get (LARGEPAGES ),
396
- "--vtxvpid" , m .Flag .Get (VTXVPID ),
397
- "--vtxux" , m .Flag .Get (VTXUX ),
398
- "--accelerate3d" , m .Flag .Get (ACCELERATE3D ),
399
- }
400
-
401
- for i , dev := range m .BootOrder {
394
+ "--ostype" , vm .OSType ,
395
+ "--cpus" , fmt .Sprintf ("%d" , vm .CPUs ),
396
+ "--memory" , fmt .Sprintf ("%d" , vm .Memory ),
397
+ "--vram" , fmt .Sprintf ("%d" , vm .VRAM ),
398
+
399
+ "--acpi" , vm .Flag .Get (ACPI ),
400
+ "--ioapic" , vm .Flag .Get (IOAPIC ),
401
+ "--rtcuseutc" , vm .Flag .Get (RTCUSEUTC ),
402
+ "--cpuhotplug" , vm .Flag .Get (CPUHOTPLUG ),
403
+ "--pae" , vm .Flag .Get (PAE ),
404
+ "--longmode" , vm .Flag .Get (LONGMODE ),
405
+ "--hpet" , vm .Flag .Get (HPET ),
406
+ "--hwvirtex" , vm .Flag .Get (HWVIRTEX ),
407
+ "--triplefaultreset" , vm .Flag .Get (TRIPLEFAULTRESET ),
408
+ "--nestedpaging" , vm .Flag .Get (NESTEDPAGING ),
409
+ "--largepages" , vm .Flag .Get (LARGEPAGES ),
410
+ "--vtxvpid" , vm .Flag .Get (VTXVPID ),
411
+ "--vtxux" , vm .Flag .Get (VTXUX ),
412
+ "--accelerate3d" , vm .Flag .Get (ACCELERATE3D ),
413
+ }
414
+
415
+ for i , dev := range vm .BootOrder {
402
416
if i > 3 {
403
417
break // Only four slots `--boot{1,2,3,4}`. Ignore the rest.
404
418
}
405
419
args = append (args , fmt .Sprintf ("--boot%d" , i + 1 ), dev )
406
420
}
407
421
408
- for i , nic := range m .NICs {
422
+ for i , nic := range vm .NICs {
409
423
n := i + 1
410
424
args = append (args ,
411
425
fmt .Sprintf ("--nic%d" , n ), string (nic .Network ),
@@ -418,10 +432,14 @@ func (m *Machine) Modify() error {
418
432
}
419
433
}
420
434
421
- if err := Manage () .run (args ... ); err != nil {
435
+ if _ , _ , err := m .run (ctx , args ... ); err != nil {
422
436
return err
423
437
}
424
- return m .Refresh ()
438
+ return vm .Refresh ()
439
+ }
440
+
441
+ func (m * Machine ) Modify () error {
442
+ return defaultManager .UpdateMachine (context .Background (), m )
425
443
}
426
444
427
445
// AddNATPF adds a NAT port forarding rule to the n-th NIC with the given name.
@@ -475,22 +493,27 @@ func (m *Machine) DelStorageCtl(name string) error {
475
493
476
494
// AttachStorage attaches a storage medium to the named storage controller.
477
495
func (m * Machine ) AttachStorage (ctlName string , medium StorageMedium ) error {
478
- return Manage ().run ("storageattach" , m .Name , "--storagectl" , ctlName ,
496
+ _ , _ , err := defaultManager .run (context .Background (),
497
+ "storageattach" , m .Name , "--storagectl" , ctlName ,
479
498
"--port" , fmt .Sprintf ("%d" , medium .Port ),
480
499
"--device" , fmt .Sprintf ("%d" , medium .Device ),
481
500
"--type" , string (medium .DriveType ),
482
501
"--medium" , medium .Medium ,
483
502
)
503
+ return err
484
504
}
485
505
486
506
// SetExtraData attaches custom string to the VM.
487
507
func (m * Machine ) SetExtraData (key , val string ) error {
488
- return Manage ().run ("setextradata" , m .Name , key , val )
508
+ _ , _ , err := defaultManager .run (context .Background (),
509
+ "setextradata" , m .Name , key , val )
510
+ return err
489
511
}
490
512
491
513
// GetExtraData retrieves custom string from the VM.
492
514
func (m * Machine ) GetExtraData (key string ) (* string , error ) {
493
- value , err := Manage ().runOut ("getextradata" , m .Name , key )
515
+ value , _ , err := defaultManager .run (context .Background (),
516
+ "getextradata" , m .Name , key )
494
517
if err != nil {
495
518
return nil , err
496
519
}
@@ -506,13 +529,19 @@ func (m *Machine) GetExtraData(key string) (*string, error) {
506
529
507
530
// DeleteExtraData removes custom string from the VM.
508
531
func (m * Machine ) DeleteExtraData (key string ) error {
509
- return Manage ().run ("setextradata" , m .Name , key )
532
+ _ , _ , err := defaultManager .run (context .Background (),
533
+ "setextradata" , m .Name , key )
534
+ return err
510
535
}
511
536
512
537
// CloneMachine clones the given machine name into a new one.
513
538
func CloneMachine (baseImageName string , newImageName string , register bool ) error {
514
539
if register {
515
- return Manage ().run ("clonevm" , baseImageName , "--name" , newImageName , "--register" )
540
+ _ , _ , err := defaultManager .run (context .Background (),
541
+ "clonevm" , baseImageName , "--name" , newImageName , "--register" )
542
+ return err
516
543
}
517
- return Manage ().run ("clonevm" , baseImageName , "--name" , newImageName )
544
+ _ , _ , err := defaultManager .run (context .Background (),
545
+ "clonevm" , baseImageName , "--name" , newImageName )
546
+ return err
518
547
}
0 commit comments