@@ -23,7 +23,9 @@ import (
23
23
"fmt"
24
24
"io/ioutil"
25
25
"os"
26
+ "os/exec"
26
27
"path/filepath"
28
+ "regexp"
27
29
"strconv"
28
30
"strings"
29
31
"syscall"
@@ -94,6 +96,10 @@ func (d *Driver) Create() error {
94
96
return err
95
97
}
96
98
99
+ if _ , err := d .resizeDiskImageIfNeeded (d .DiskCapacity ); err != nil {
100
+ return err
101
+ }
102
+
97
103
return nil
98
104
}
99
105
@@ -405,19 +411,90 @@ func (d *Driver) findHyperkitProcess() (ps.Process, error) {
405
411
return p , nil
406
412
}
407
413
414
+ func (d * Driver ) runQcowTool (args ... string ) (string , error ) {
415
+ log .Debugf ("Running %s %s" , d .QcowToolPath , strings .Join (args , " " ))
416
+ out , err := exec .Command (d .QcowToolPath , args ... ).Output () // #nosec G204
417
+ if err != nil {
418
+ log .Debugf ("qcow-tool error: %v" , err )
419
+
420
+ var exitErr * exec.ExitError
421
+ if errors .As (err , & exitErr ) {
422
+ log .Debugf ("stderr: %s" , exitErr .Stderr )
423
+ }
424
+ return "" , err
425
+ }
426
+
427
+ return string (out ), nil
428
+ }
429
+
430
+ func (d * Driver ) resizeDiskImage (newCapacity uint64 ) error {
431
+ log .Debugf ("resizeDiskImage(%d)" , newCapacity )
432
+
433
+ _ , err := d .runQcowTool ("resize" , fmt .Sprintf ("--size=%d" , newCapacity ), d .getDiskPath ())
434
+ if err != nil {
435
+ return err
436
+ }
437
+
438
+ d .DiskCapacity = newCapacity
439
+ return nil
440
+ }
441
+
442
+ func (d * Driver ) checkIfResizeNeeded (newCapacity uint64 ) (bool , error ) {
443
+ if newCapacity == 0 {
444
+ return false , nil
445
+ }
446
+
447
+ out , err := d .runQcowTool ("info" , d .getDiskPath ())
448
+ if err != nil {
449
+ return false , err
450
+ }
451
+
452
+ sizeRegexp := regexp .MustCompile (`\(size ([[:digit:]]+)\)` )
453
+ submatches := sizeRegexp .FindStringSubmatch (out )
454
+ if len (submatches ) != 2 {
455
+ return false , fmt .Errorf ("Could not parse current image size" )
456
+ }
457
+ currentCapacity , err := strconv .ParseUint (submatches [1 ], 10 , 64 )
458
+ if err != nil {
459
+ return false , fmt .Errorf ("Could not parse current image size: %w" , err )
460
+ }
461
+ if currentCapacity == newCapacity {
462
+ log .Debugf ("disk image capacity is already %d bytes" , currentCapacity )
463
+ return false , nil
464
+ }
465
+ if currentCapacity > newCapacity {
466
+ return false , fmt .Errorf ("current disk image capacity is bigger than the requested size (%d > %d)" , currentCapacity , newCapacity )
467
+ }
468
+
469
+ return true , nil
470
+ }
471
+
472
+ func (d * Driver ) resizeDiskImageIfNeeded (newCapacity uint64 ) (bool , error ) {
473
+ resizeNeeded , err := d .checkIfResizeNeeded (newCapacity )
474
+ if err != nil || ! resizeNeeded {
475
+ return false , err
476
+ }
477
+ err = d .resizeDiskImage (newCapacity )
478
+ if err != nil {
479
+ return false , err
480
+ }
481
+
482
+ return true , nil
483
+ }
484
+
408
485
func (d * Driver ) UpdateConfigRaw (rawConfig []byte ) error {
409
486
var newDriver Driver
410
487
err := json .Unmarshal (rawConfig , & newDriver )
411
488
if err != nil {
412
489
return err
413
490
}
414
491
415
- if newDriver .Memory == d .Memory && newDriver . CPU == d . CPU {
416
- /* For now only changing memory and CPU is supported/tested.
417
- * If none of these changed, we might be trying to change another
418
- * value, which is may or may not work, return ErrNotImplemented for now
419
- */
420
- return drivers . ErrNotImplemented
492
+ if newDriver .DiskCapacity != d .DiskCapacity {
493
+ _ , err = d . resizeDiskImageIfNeeded ( newDriver . DiskCapacity )
494
+ if err != nil {
495
+ log . Debugf ( "failed to resize disk image: %v" , err )
496
+ return err
497
+ }
421
498
}
422
499
* d = newDriver
423
500
0 commit comments