Skip to content

Commit 349ccd1

Browse files
committed
limayaml: add a .saveOnStop field to control whether to use suspend
default `false` Signed-off-by: Norio Nomura <[email protected]>
1 parent 4fc95cd commit 349ccd1

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

pkg/limayaml/defaults.go

+27
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,32 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
855855
y.NestedVirtualization = ptr.Of(false)
856856
}
857857

858+
if y.SaveOnStop == nil {
859+
y.SaveOnStop = d.SaveOnStop
860+
}
861+
if o.SaveOnStop != nil {
862+
y.SaveOnStop = o.SaveOnStop
863+
}
864+
if y.SaveOnStop == nil {
865+
y.SaveOnStop = ptr.Of(false)
866+
}
867+
if *y.SaveOnStop {
868+
y.SaveOnStop = ptr.Of(false)
869+
if *y.VMType != VZ {
870+
logrus.Warn("saveOnStop is only supported for VM type vz")
871+
} else if runtime.GOARCH != "arm64" {
872+
logrus.Warn("saveOnStop is only supported for arm64 VM type vz")
873+
} else if runtime.GOOS != "darwin" {
874+
logrus.Warn("saveOnStop is only supported on macOS")
875+
} else if macOSProductVersion, err := osutil.ProductVersion(); err != nil {
876+
logrus.WithError(err).Warn("Failed to get macOS product version")
877+
} else if macOSProductVersion.LessThan(*semver.New("14.0.0")) {
878+
logrus.Warn("saveOnStop is not supported on macOS prior to 14.0")
879+
} else {
880+
y.SaveOnStop = ptr.Of(true)
881+
}
882+
}
883+
858884
if y.Plain == nil {
859885
y.Plain = d.Plain
860886
}
@@ -878,6 +904,7 @@ func fixUpForPlainMode(y *LimaYAML) {
878904
y.Containerd.User = ptr.Of(false)
879905
y.Rosetta.BinFmt = ptr.Of(false)
880906
y.Rosetta.Enabled = ptr.Of(false)
907+
y.SaveOnStop = ptr.Of(false)
881908
y.TimeZone = ptr.Of("")
882909
}
883910

pkg/limayaml/defaults_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func TestFillDefault(t *testing.T) {
112112
RemoveDefaults: ptr.Of(false),
113113
},
114114
NestedVirtualization: ptr.Of(false),
115+
SaveOnStop: ptr.Of(false),
115116
Plain: ptr.Of(false),
116117
User: User{
117118
Name: ptr.Of(user.Username),
@@ -437,6 +438,7 @@ func TestFillDefault(t *testing.T) {
437438
BinFmt: ptr.Of(true),
438439
},
439440
NestedVirtualization: ptr.Of(true),
441+
SaveOnStop: ptr.Of(true),
440442
User: User{
441443
Name: ptr.Of("xxx"),
442444
Comment: ptr.Of("Foo Bar"),
@@ -474,11 +476,13 @@ func TestFillDefault(t *testing.T) {
474476
Enabled: ptr.Of(true),
475477
BinFmt: ptr.Of(true),
476478
}
479+
expect.SaveOnStop = ptr.Of(true)
477480
} else {
478481
expect.Rosetta = Rosetta{
479482
Enabled: ptr.Of(false),
480483
BinFmt: ptr.Of(true),
481484
}
485+
expect.SaveOnStop = ptr.Of(false)
482486
}
483487
expect.Plain = ptr.Of(false)
484488

@@ -660,6 +664,7 @@ func TestFillDefault(t *testing.T) {
660664
BinFmt: ptr.Of(false),
661665
},
662666
NestedVirtualization: ptr.Of(false),
667+
SaveOnStop: ptr.Of(false),
663668
User: User{
664669
Name: ptr.Of("foo"),
665670
Comment: ptr.Of("foo bar baz"),
@@ -723,6 +728,7 @@ func TestFillDefault(t *testing.T) {
723728
expect.Plain = ptr.Of(false)
724729

725730
expect.NestedVirtualization = ptr.Of(false)
731+
expect.SaveOnStop = ptr.Of(false)
726732

727733
FillDefault(&y, &d, &o, filePath, false)
728734
assert.DeepEqual(t, &y, &expect, opts...)

pkg/limayaml/limayaml.go

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type LimaYAML struct {
4848
TimeZone *string `yaml:"timezone,omitempty" json:"timezone,omitempty" jsonschema:"nullable"`
4949
NestedVirtualization *bool `yaml:"nestedVirtualization,omitempty" json:"nestedVirtualization,omitempty" jsonschema:"nullable"`
5050
User User `yaml:"user,omitempty" json:"user,omitempty"`
51+
SaveOnStop *bool `yaml:"saveOnStop,omitempty" json:"saveOnStop,omitempty" jsonschema:"nullable"`
5152
}
5253

5354
type (

pkg/vz/vz_driver_darwin.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ var knownYamlProperties = []string{
5353
"PropagateProxyEnv",
5454
"Provision",
5555
"Rosetta",
56+
"SaveOnStop",
5657
"SSH",
5758
"TimeZone",
5859
"UpgradePackages",
@@ -67,11 +68,22 @@ type LimaVzDriver struct {
6768
*driver.BaseDriver
6869

6970
machine *virtualMachineWrapper
71+
72+
// Runtime configuration
73+
config LimaVzDriverRuntimeConfig
74+
}
75+
76+
type LimaVzDriverRuntimeConfig struct {
77+
// SaveOnStop is a flag to save the VM state on stop
78+
SaveOnStop bool `json:"saveOnStop"`
7079
}
7180

7281
func New(driver *driver.BaseDriver) *LimaVzDriver {
7382
return &LimaVzDriver{
7483
BaseDriver: driver,
84+
config: LimaVzDriverRuntimeConfig{
85+
SaveOnStop: *driver.Instance.Config.SaveOnStop,
86+
},
7587
}
7688
}
7789

@@ -193,11 +205,13 @@ func (l *LimaVzDriver) RunGUI() error {
193205
}
194206

195207
func (l *LimaVzDriver) Stop(_ context.Context) error {
196-
machineStatePath := filepath.Join(l.Instance.Dir, filenames.VzMachineState)
197-
if err := saveVM(l.machine.VirtualMachine, machineStatePath); err != nil {
198-
logrus.WithError(err).Warn("Failed to save VZ. Falling back to shutdown")
199-
} else {
200-
return nil
208+
if l.config.SaveOnStop {
209+
machineStatePath := filepath.Join(l.Instance.Dir, filenames.VzMachineState)
210+
if err := saveVM(l.machine.VirtualMachine, machineStatePath); err != nil {
211+
logrus.WithError(err).Warn("Failed to save VZ. Falling back to shutdown")
212+
} else {
213+
return nil
214+
}
201215
}
202216

203217
logrus.Info("Shutting down VZ")

templates/default.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@ hostResolver:
525525
# 🟢 Builtin default: /usr/local
526526
guestInstallPrefix: null
527527

528+
# When "saveOnStop" is enabled, Lima saves the VM instead of shutting it down.
529+
# The VM can be restored with `limactl start` if the saved state is available.
530+
# 🟢 Builtin default: false
531+
saveOnStop: null
532+
528533
# When the "plain" mode is enabled:
529534
# - the YAML properties for mounts, port forwarding, containerd, etc. will be ignored
530535
# - guest agent will not be running

0 commit comments

Comments
 (0)