mirror of
https://github.com/lima-vm/lima.git
synced 2026-10-28 11:44:35 +08:00
97 lines
2.7 KiB
Go
97 lines
2.7 KiB
Go
package limayaml
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/AkihiroSuda/lima/pkg/localpathutil"
|
|
"github.com/docker/go-units"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func Validate(y LimaYAML) error {
|
|
FillDefault(&y)
|
|
return ValidateRaw(y)
|
|
}
|
|
|
|
func ValidateRaw(y LimaYAML) error {
|
|
switch y.Arch {
|
|
case X8664, AARCH64:
|
|
default:
|
|
return errors.Errorf("field `arch` must be %q or %q , got %q", X8664, AARCH64, y.Arch)
|
|
}
|
|
|
|
if len(y.Images) == 0 {
|
|
return errors.New("field `images` must be set")
|
|
}
|
|
for i, f := range y.Images {
|
|
if !strings.Contains(f.Location, "://") {
|
|
if _, err := localpathutil.Expand(f.Location); err != nil {
|
|
return errors.Wrapf(err, "field `images[%d].location` refers to an invalid local file path: %q",
|
|
i, f.Location)
|
|
}
|
|
// f.Location does NOT need to be accessible, so we do NOT check os.Stat(f.Location)
|
|
}
|
|
switch f.Arch {
|
|
case X8664, AARCH64:
|
|
default:
|
|
return errors.Errorf("field `images.arch` must be %q or %q, got %q", X8664, AARCH64, f.Arch)
|
|
}
|
|
}
|
|
|
|
if y.CPUs == 0 {
|
|
return errors.New("field `cpus` must be set")
|
|
}
|
|
|
|
if _, err := units.RAMInBytes(y.Memory); err != nil {
|
|
return errors.Wrapf(err, "field `memory` has an invalid value")
|
|
}
|
|
|
|
if _, err := units.RAMInBytes(y.Disk); err != nil {
|
|
return errors.Wrapf(err, "field `memory` has an invalid value")
|
|
}
|
|
|
|
for i, f := range y.Mounts {
|
|
if !filepath.IsAbs(f.Location) && !strings.HasPrefix(f.Location, "~") {
|
|
return errors.Errorf("field `mounts[%d].location` must be an absolute path, got %q",
|
|
i, f.Location)
|
|
}
|
|
loc, err := localpathutil.Expand(f.Location)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "field `mounts[%d].location` refers to an unexpandable path: %q",
|
|
i, f.Location)
|
|
}
|
|
switch loc {
|
|
case "/", "/bin", "/dev", "/etc", "/home", "/opt", "/sbin", "/tmp", "/usr", "/var":
|
|
return errors.Errorf("field `mounts[%d].location` must not be a system path such as /etc or /usr", i)
|
|
}
|
|
|
|
st, err := os.Stat(loc)
|
|
if err != nil {
|
|
if !errors.Is(err, os.ErrNotExist) {
|
|
return errors.Wrapf(err, "field `mounts[%d].location` refers to an inaccessible path: %q",
|
|
i, f.Location)
|
|
}
|
|
} else if !st.IsDir() {
|
|
return errors.Wrapf(err, "field `mounts[%d].location` refers to a non-directory path: %q",
|
|
i, f.Location)
|
|
}
|
|
}
|
|
|
|
switch {
|
|
case y.SSH.LocalPort < 0:
|
|
return errors.New("field `ssh.localPort` must be > 0")
|
|
case y.SSH.LocalPort == 0:
|
|
return errors.New("field `ssh.localPort` must be set, e.g, 60022 (FIXME: support automatic port assignment)")
|
|
case y.SSH.LocalPort == 22:
|
|
return errors.New("field `ssh.localPort` must not be 22")
|
|
case y.SSH.LocalPort > 65535:
|
|
return errors.New("field `ssh.localPort` must be < 65535")
|
|
}
|
|
|
|
// y.Firmware.LegacyBIOS is ignored for aarch64, but not a fatal error.
|
|
|
|
return nil
|
|
}
|