diff --git a/pkg/limayaml/validate.go b/pkg/limayaml/validate.go index 2bc8ad4b6484..4a5fb4ca9e0b 100644 --- a/pkg/limayaml/validate.go +++ b/pkg/limayaml/validate.go @@ -372,6 +372,37 @@ func Validate(y *LimaYAML, warn bool) error { } } + if y.Rosetta.Enabled != nil && *y.Rosetta.Enabled && *y.VMType != VZ { + return fmt.Errorf("field `rosetta.enabled` can only be enabled for VMType %q; got %q", VZ, *y.VMType) + } + + if y.NestedVirtualization != nil && *y.NestedVirtualization && *y.VMType != VZ { + return fmt.Errorf("field `nestedVirtualization` can only be enabled for VMType %q; got %q", VZ, *y.VMType) + } + + if err := validateMountType(y); err != nil { + return err + } + + return nil +} + +func validateMountType(y *LimaYAML) error { + validMountTypes := map[string]bool{ + REVSSHFS: true, + NINEP: true, + VIRTIOFS: true, + WSLMount: true, + } + + if !validMountTypes[*y.MountType] { + return fmt.Errorf("field `mountType` must be: %q, %q, %q, %q; got %q", REVSSHFS, NINEP, VIRTIOFS, WSLMount, *y.MountType) + } + + if *y.MountType == VIRTIOFS && runtime.GOOS == "darwin" && *y.VMType != VZ { + return fmt.Errorf("field `mountType` %q on macOS requires vmType %q; got %q", *y.MountType, VZ, *y.VMType) + } + return nil } @@ -432,6 +463,9 @@ func validateNetwork(y *LimaYAML) error { return fmt.Errorf("field `%s.macAddress` must be a 48 bit (6 bytes) MAC address; actual length of %q is %d bytes", field, nw.MACAddress, len(hw)) } } + if nw.VZNAT != nil && *nw.VZNAT && *y.VMType != VZ { + return fmt.Errorf("field `%s.vzNAT` needs vmType set to %q; got %q", field, VZ, *y.VMType) + } // FillDefault() will make sure that nw.Interface is not the empty string if len(nw.Interface) >= 16 { return fmt.Errorf("field `%s.interface` must be less than 16 bytes, but is %d bytes: %q", field, len(nw.Interface), nw.Interface) diff --git a/pkg/limayaml/validate_test.go b/pkg/limayaml/validate_test.go index 4895531ed066..6a1cbc88ebaa 100644 --- a/pkg/limayaml/validate_test.go +++ b/pkg/limayaml/validate_test.go @@ -186,3 +186,134 @@ func TestValidateParamIsUsed(t *testing.T) { assert.Error(t, err, "field `param` key \"rootFul\" is not used in any provision, probe, copyToHost, or portForward") } } + +func TestValidateRosetta(t *testing.T) { + images := `images: [{"location": "/"}]` + + nilData := `` + y, err := Load([]byte(nilData+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) + + invalidRosetta := ` +rosetta: + enabled: true +vmType: "qemu" +` + y, err = Load([]byte(invalidRosetta+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + if runtime.GOOS == "darwin" && IsNativeArch(AARCH64) { + assert.Error(t, err, "field `rosetta.enabled` can only be enabled for VMType \"vz\"; got \"qemu\"") + } else { + assert.NilError(t, err) + } + + validRosetta := ` +rosetta: + enabled: true +vmType: "vz" +` + y, err = Load([]byte(validRosetta+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) + + rosettaDisabled := ` +rosetta: + enabled: false +vmType: "qemu" +` + y, err = Load([]byte(rosettaDisabled+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) +} + +func TestValidateNestedVirtualization(t *testing.T) { + images := `images: [{"location": "/"}]` + + validYAML := ` +nestedVirtualization: true +vmType: vz +` + images + + y, err := Load([]byte(validYAML), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) + + invalidYAML := ` +nestedVirtualization: true +vmType: qemu +` + images + + y, err = Load([]byte(invalidYAML), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.Error(t, err, "field `nestedVirtualization` can only be enabled for VMType \"vz\"; got \"qemu\"") +} + +func TestValidateMountTypeOS(t *testing.T) { + images := `images: [{"location": "/"}]` + + nilMountConf := `` + y, err := Load([]byte(nilMountConf+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) + + inValidMountTypeLinux := ` +mountType: "random" +` + y, err = Load([]byte(inValidMountTypeLinux+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, true) + assert.Error(t, err, "field `mountType` must be \"reverse-sshfs\" or \"9p\" or \"virtiofs\", or \"wsl2\", got \"random\"") + + validMountTypeLinux := ` +mountType: "virtiofs" +` + y, err = Load([]byte(validMountTypeLinux+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, true) + if runtime.GOOS == "darwin" && IsNativeArch(AARCH64) { + assert.Error(t, err, "field `mountType` \"virtiofs\" on macOS requires vmType \"vz\"; got \"qemu\"") + } else { + assert.NilError(t, err) + } + + validMountTypeMac := ` +mountType: "virtiofs" +vmType: "vz" +` + y, err = Load([]byte(validMountTypeMac+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + assert.NilError(t, err) + + invalidMountTypeMac := ` +mountType: "virtiofs" +vmType: "qemu" +` + y, err = Load([]byte(invalidMountTypeMac+"\n"+images), "lima.yaml") + assert.NilError(t, err) + + err = Validate(y, false) + if runtime.GOOS == "darwin" { + assert.Error(t, err, "field `mountType` \"virtiofs\" on macOS requires vmType \"vz\"; got \"qemu\"") + } else { + assert.NilError(t, err) + } +}