diff --git a/cmd/limactl/edit.go b/cmd/limactl/edit.go index 33ee9581333..da66b82df97 100644 --- a/cmd/limactl/edit.go +++ b/cmd/limactl/edit.go @@ -125,6 +125,11 @@ func editAction(cmd *cobra.Command, args []string) error { // TODO: may need to support editing the rejected YAML return fmt.Errorf("the YAML is invalid, saved the buffer as %q: %w", rejectedYAML, err) } + + if err := limayaml.ValidateYAMLAgainstLatest(yBytes, yContent); err != nil { + return saveRejectedYAML(yBytes, err) + } + if err := os.WriteFile(filePath, yBytes, 0o644); err != nil { return err } @@ -171,3 +176,12 @@ func askWhetherToStart() (bool, error) { func editBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { return bashCompleteInstanceNames(cmd) } + +func saveRejectedYAML(y []byte, origErr error) error { + rejectedYAML := "lima.REJECTED.yaml" + if writeErr := os.WriteFile(rejectedYAML, y, 0o644); writeErr != nil { + return fmt.Errorf("the YAML is invalid, attempted to save the buffer as %q but failed: %w: %w", rejectedYAML, writeErr, origErr) + } + // TODO: may need to support editing the rejected YAML + return fmt.Errorf("the YAML is invalid, saved the buffer as %q: %w", rejectedYAML, origErr) +} diff --git a/pkg/limayaml/validate.go b/pkg/limayaml/validate.go index 750383e2c51..06047cd101e 100644 --- a/pkg/limayaml/validate.go +++ b/pkg/limayaml/validate.go @@ -595,3 +595,27 @@ func warnExperimental(y *LimaYAML) { logrus.Warn("`mountInotify` is experimental") } } + +// ValidateYAMLAgainstLatest validates the values between the latest YAML and the updated(New) YAML. +func ValidateYAMLAgainstLatest(yNew, yLatest []byte) error { + var l, n LimaYAML + var err error + if err = Unmarshal(yLatest, &l, "Unmarshal latest YAML bytes"); err != nil { + return err + } + if err = Unmarshal(yNew, &n, "Unmarshal new YAML byte"); err != nil { + return err + } + + // Skip validation if both fields are unset. + if n.Disk == nil && l.Disk == nil { + return nil + } + nDisk, _ := units.RAMInBytes(*n.Disk) + lDisk, _ := units.RAMInBytes(*l.Disk) + if nDisk < lDisk { + return fmt.Errorf("field `disk`: shrinking the disk (%v --> %v) is not supported", *l.Disk, *n.Disk) + } + + return nil +}