@@ -3,6 +3,7 @@ package limayaml
33import (
44 "bytes"
55 "crypto/sha256"
6+ "errors"
67 "fmt"
78 "net"
89 "os"
@@ -11,6 +12,7 @@ import (
1112 "strconv"
1213 "text/template"
1314
15+ "github.com/coreos/go-semver/semver"
1416 "github.com/docker/go-units"
1517 "github.com/lima-vm/lima/pkg/networks"
1618 "github.com/pbnjay/memory"
@@ -127,13 +129,7 @@ func defaultGuestInstallPrefix() string {
127129// - DNS are picked from the highest priority where DNS is not empty.
128130// - CACertificates Files and Certs are uniquely appended in d, y, o order
129131func FillDefault (y , d , o * LimaYAML , filePath string ) {
130- if y .VMType == nil {
131- y .VMType = d .VMType
132- }
133- if o .VMType != nil {
134- y .VMType = o .VMType
135- }
136- y .VMType = pointer .String (ResolveVMType (y .VMType ))
132+ y .VMType = pointer .String (ResolveVMType (y , d , o , filePath ))
137133 if y .OS == nil {
138134 y .OS = d .OS
139135 }
@@ -860,11 +856,95 @@ func NewVMType(driver string) VMType {
860856 }
861857}
862858
863- func ResolveVMType (s * string ) VMType {
864- if s == nil || * s == "" || * s == "default" {
859+ func isExistingInstanceDir (dir string ) bool {
860+ // existence of "lima.yaml" does not signify existence of the instance,
861+ // because the file is created during the initialization of the instance.
862+ for _ , f := range []string {filenames .HostAgentStdoutLog , filenames .HostAgentStderrLog ,
863+ filenames .VzIdentifier , filenames .BaseDisk , filenames .DiffDisk , filenames .CIDataISO } {
864+ file := filepath .Join (dir , f )
865+ if _ , err := os .Lstat (file ); ! errors .Is (err , os .ErrNotExist ) {
866+ return true
867+ }
868+ }
869+ return false
870+ }
871+
872+ func ResolveVMType (y , d , o * LimaYAML , filePath string ) VMType {
873+ // Check if the VMType is explicitly specified
874+ for i , f := range []* LimaYAML {o , y , d } {
875+ if f .VMType != nil && * f .VMType != "" && * f .VMType != "default" {
876+ logrus .Debugf ("ResolveVMType: resolved VMType %q (explicitly specified in []*LimaYAML{o,y,d}[%d])" , * f .VMType , i )
877+ return NewVMType (* f .VMType )
878+ }
879+ }
880+
881+ // If this is an existing instance, guess the VMType from the contents of the instance directory.
882+ // Note that the instance directory may be created by a previous version of Lima.
883+ if dir , basename := filepath .Split (filePath ); dir != "" && basename == filenames .LimaYAML && isExistingInstanceDir (dir ) {
884+ vzIdentifier := filepath .Join (dir , filenames .VzIdentifier )
885+ if _ , err := os .Lstat (vzIdentifier ); ! errors .Is (err , os .ErrNotExist ) {
886+ logrus .Debugf ("ResolveVMType: resolved VMType %q (existing instance, with %q)" , VZ , vzIdentifier )
887+ return VZ
888+ }
889+ logrus .Debugf ("ResolveVMType: resolved VMType %q (existing instance, without %q)" , QEMU , vzIdentifier )
890+ return QEMU
891+ }
892+
893+ // Resolve the best type, depending on GOOS
894+ switch runtime .GOOS {
895+ case "darwin" :
896+ macOSProductVersion , err := osutil .ProductVersion ()
897+ if err != nil {
898+ logrus .WithError (err ).Warn ("Failed to get macOS product version" )
899+ logrus .Debugf ("ResolveVMType: resolved VMType %q (default for unknown version of macOS)" , QEMU )
900+ return QEMU
901+ }
902+ // Virtualization.framework in macOS prior to 13.5 could not boot Linux kernel v6.2 on Intel
903+ // https://github.com/lima-vm/lima/issues/1577
904+ if macOSProductVersion .LessThan (* semver .New ("13.5.0" )) {
905+ logrus .Debugf ("ResolveVMType: resolved VMType %q (default for macOS prior to 13.5)" , QEMU )
906+ return QEMU
907+ }
908+ // Use QEMU if the config depends on QEMU
909+ for i , f := range []* LimaYAML {o , y , d } {
910+ if f .Arch != nil && ! IsNativeArch (* f .Arch ) {
911+ logrus .Debugf ("ResolveVMType: resolved VMType %q (non-native arch=%q is specified in []*LimaYAML{o,y,d}[%d])" , QEMU , * f .Arch , i )
912+ return QEMU
913+ }
914+ if f .Firmware .LegacyBIOS != nil && * f .Firmware .LegacyBIOS {
915+ logrus .Debugf ("ResolveVMType: resolved VMType %q (firmware.legacyBIOS is specified in []*LimaYAML{o,y,d}[%d])" , QEMU , i )
916+ return QEMU
917+ }
918+ if f .MountType != nil && * f .MountType == NINEP {
919+ logrus .Debugf ("ResolveVMType: resolved VMType %q (mountType=%q is specified in []*LimaYAML{o,y,d}[%d])" , QEMU , NINEP , i )
920+ return QEMU
921+ }
922+ if f .Audio .Device != nil {
923+ switch * f .Audio .Device {
924+ case "" , "none" , "default" , "vz" :
925+ // NOP
926+ default :
927+ logrus .Debugf ("ResolveVMType: resolved VMType %q (audio.device=%q is specified in []*LimaYAML{o,y,d}[%d])" , QEMU , * f .Audio .Device , i )
928+ return QEMU
929+ }
930+ }
931+ if f .Video .Display != nil {
932+ switch * f .Video .Display {
933+ case "" , "none" , "default" , "vz" :
934+ // NOP
935+ default :
936+ logrus .Debugf ("ResolveVMType: resolved VMType %q (video.display=%q is specified in []*LimaYAML{o,y,d}[%d])" , QEMU , * f .Video .Display , i )
937+ return QEMU
938+ }
939+ }
940+ }
941+ // Use VZ if the config is compatible with VZ
942+ logrus .Debugf ("ResolveVMType: resolved VMType %q (default for macOS 13.5 and later)" , VZ )
943+ return VZ
944+ default :
945+ logrus .Debugf ("ResolveVMType: resolved VMType %q (default for GOOS=%q)" , QEMU , runtime .GOOS )
865946 return QEMU
866947 }
867- return NewVMType (* s )
868948}
869949
870950func ResolveOS (s * string ) OS {
0 commit comments