package limainfo
import (
"context"
"errors"
"io/fs"
"path/filepath"
"runtime"
"github.com/sirupsen/logrus"
"github.com/lima-vm/lima/v2/pkg/envutil"
"github.com/lima-vm/lima/v2/pkg/limatype"
"github.com/lima-vm/lima/v2/pkg/limatype/dirnames"
"github.com/lima-vm/lima/v2/pkg/limatype/filenames"
"github.com/lima-vm/lima/v2/pkg/limayaml"
"github.com/lima-vm/lima/v2/pkg/plugins"
"github.com/lima-vm/lima/v2/pkg/registry"
"github.com/lima-vm/lima/v2/pkg/templatestore"
"github.com/lima-vm/lima/v2/pkg/usrlocal"
"github.com/lima-vm/lima/v2/pkg/version"
)
type LimaInfo struct {
Version string `json:"version"`
Templates []templatestore.Template `json:"templates"`
DefaultTemplate *limatype.LimaYAML `json:"defaultTemplate"`
LimaHome string `json:"limaHome"`
VMTypes []string `json:"vmTypes"`
VMTypesEx map[string]DriverExt `json:"vmTypesEx"`
GuestAgents map[limatype.Arch]GuestAgent `json:"guestAgents"`
ShellEnvBlock []string `json:"shellEnvBlock"`
HostOS string `json:"hostOS"`
HostArch string `json:"hostArch"`
IdentityFile string `json:"identityFile"`
Plugins []plugins.Plugin `json:"plugins"`
LibexecPaths []string `json:"libexecPaths"`
SharePaths []string `json:"sharePaths"`
}
type DriverExt struct {
Location string `json:"location,omitempty"`
}
type GuestAgent struct {
Location string `json:"location"`
}
func New(ctx context.Context) (*LimaInfo, error) {
b, err := templatestore.Read(templatestore.Default)
if err != nil {
return nil, err
}
y, err := limayaml.Load(ctx, b, "")
if err != nil {
return nil, err
}
reg := registry.List()
if len(reg) == 0 {
return nil, errors.New("no VM types found; ensure that the drivers are properly registered")
}
vmTypesEx := make(map[string]DriverExt)
var vmTypes []string
for name, path := range reg {
vmTypesEx[name] = DriverExt{
Location: path,
}
vmTypes = append(vmTypes, name)
}
info := &LimaInfo{
Version: version.Version,
DefaultTemplate: y,
VMTypes: vmTypes,
VMTypesEx: vmTypesEx,
GuestAgents: make(map[limatype.Arch]GuestAgent),
ShellEnvBlock: envutil.GetDefaultBlockList(),
HostOS: runtime.GOOS,
HostArch: limatype.NewArch(runtime.GOARCH),
}
info.Templates, err = templatestore.Templates()
if err != nil {
return nil, err
}
info.LimaHome, err = dirnames.LimaDir()
if err != nil {
return nil, err
}
configDir, err := dirnames.LimaConfigDir()
if err != nil {
return nil, err
}
info.LibexecPaths, err = usrlocal.LibexecLima()
if err != nil {
return nil, err
}
info.SharePaths, err = usrlocal.ShareLima()
if err != nil {
return nil, err
}
info.IdentityFile = filepath.Join(configDir, filenames.UserPrivateKey)
for _, arch := range limatype.ArchTypes {
bin, err := usrlocal.GuestAgentBinary(limatype.LINUX, arch)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
logrus.WithError(err).Debugf("Failed to resolve the guest agent binary for %q", arch)
} else {
logrus.WithError(err).Warnf("Failed to resolve the guest agent binary for %q", arch)
}
continue
}
info.GuestAgents[arch] = GuestAgent{
Location: bin,
}
}
info.Plugins, err = plugins.Discover()
if err != nil {
logrus.WithError(err).Warn("Failed to discover plugins")
}
return info, nil
}