Skip to content

Add command to generate jsonschema for limayaml #2306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
skip = .git,*.pb.desc,*/node_modules/*,*/public/js/*,*/public/scss/*

# Comma separated list of words to be ignored. Words must be lowercased.
ignore-words-list = ans,distroname,testof,hda,ststr
ignore-words-list = ans,distroname,testof,hda,ststr,archtypes

# Check file names as well.
check-filenames = true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
_output/
_artifacts/
lima.REJECTED.yaml
schema-limayaml.json
.config
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -421,6 +421,14 @@ ifeq ($(native_compiling),true)
--output _output --prefix $(PREFIX)
endif

################################################################################
schema-limayaml.json: _output/bin/limactl$(exe)
$< generate-jsonschema >$@

.PHONY: check-jsonschema
check-jsonschema: schema-limayaml.json
check-jsonschema --schemafile $< examples/default.yaml

################################################################################
.PHONY: diagrams
diagrams: docs/lima-sequence-diagram.png
59 changes: 59 additions & 0 deletions cmd/limactl/genschema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"encoding/json"
"fmt"

"github.com/invopop/jsonschema"
"github.com/lima-vm/lima/pkg/limayaml"
"github.com/spf13/cobra"
orderedmap "github.com/wk8/go-ordered-map/v2"
)

func newGenSchemaCommand() *cobra.Command {
genschemaCommand := &cobra.Command{
Use: "generate-jsonschema",
Short: "Generate json-schema document",
Args: WrapArgsError(cobra.NoArgs),
RunE: genschemaAction,
Hidden: true,
}
return genschemaCommand
}

func toAny(args []string) []any {
result := []any{nil}
for _, arg := range args {
result = append(result, arg)
}
return result
}

func getProp(props *orderedmap.OrderedMap[string, *jsonschema.Schema], key string) *jsonschema.Schema {
value, ok := props.Get(key)
if !ok {
return nil
}
return value
}

func genschemaAction(cmd *cobra.Command, _ []string) error {
schema := jsonschema.Reflect(&limayaml.LimaYAML{})
// allow Disk to be either string (name) or object (struct)
schema.Definitions["Disk"].Type = "" // was: "object"
schema.Definitions["Disk"].OneOf = []*jsonschema.Schema{
{Type: "string"},
{Type: "object"},
}
properties := schema.Definitions["LimaYAML"].Properties
getProp(properties, "os").Enum = toAny(limayaml.OSTypes)
getProp(properties, "arch").Enum = toAny(limayaml.ArchTypes)
getProp(properties, "mountType").Enum = toAny(limayaml.MountTypes)
getProp(properties, "vmType").Enum = toAny(limayaml.VMTypes)
j, err := json.MarshalIndent(schema, "", " ")
if err != nil {
return err
}
_, err = fmt.Fprintln(cmd.OutOrStdout(), string(j))
return err
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a test? What happens when this is out of the sync with the YAML struct definition?

1 change: 1 addition & 0 deletions cmd/limactl/main.go
Original file line number Diff line number Diff line change
@@ -150,6 +150,7 @@ func newApp() *cobra.Command {
newDiskCommand(),
newUsernetCommand(),
newGenDocCommand(),
newGenSchemaCommand(),
newSnapshotCommand(),
newProtectCommand(),
newUnprotectCommand(),
25 changes: 13 additions & 12 deletions examples/default.yaml
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ os: null
arch: null

# OpenStack-compatible disk image.
# 🟢 Builtin default: null (must be specified)
# 🟢 Builtin default: none (must be specified)
# 🔵 This file: Ubuntu images
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
@@ -74,7 +74,7 @@ disk: null
# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
# "location" can use these template variables: {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}.
# "mountPoint" can use these template variables: {{.Home}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
# 🟢 Builtin default: null (Mount nothing)
# 🟢 Builtin default: [] (Mount nothing)
# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
mounts:
- location: "~"
@@ -123,8 +123,9 @@ mounts:

# List of mount types not supported by the kernel of this distro.
# Also used to resolve the default mount type when not explicitly specified.
# 🟢 Builtin default: null
mountTypesUnsupported: null
# 🟢 Builtin default: []
mountTypesUnsupported:
# - "9p"

# Mount type for above mounts, such as "reverse-sshfs" (from sshocker), "9p" (QEMU’s virtio-9p-pci, aka virtfs),
# or "virtiofs" (experimental on Linux; needs `vmType: vz` on macOS).
@@ -139,7 +140,7 @@ mountInotify: null
# instance, labeled by name. (e.g. if the disk is named "data", it will be labeled
# "lima-data" inside the instance). The disk will be mounted inside the instance at
# `/mnt/lima-${VOLUME}`.
# 🟢 Builtin default: null
# 🟢 Builtin default: []
additionalDisks:
# disks should either be a list of disk name strings, for example:
# - "data"
@@ -222,7 +223,7 @@ containerd:
# Provisioning scripts need to be idempotent because they might be called
# multiple times, e.g. when the host VM is being restarted.
# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
# 🟢 Builtin default: null
# 🟢 Builtin default: []
# provision:
# # `system` is executed with root privileges
# - mode: system
@@ -265,7 +266,7 @@ containerd:
# Probe scripts to check readiness.
# The scripts run in user mode. They must start with a '#!' line.
# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
# 🟢 Builtin default: null
# 🟢 Builtin default: []
# probes:
# # Only `readiness` probes are supported right now.
# - mode: readiness
@@ -352,7 +353,7 @@ video:

# The instance can get routable IP addresses from the vmnet framework using
# https://github.com/lima-vm/socket_vmnet.
# 🟢 Builtin default: null
# 🟢 Builtin default: []
networks:
# Lima can manage daemons for networks defined in $LIMA_HOME/_config/networks.yaml
# automatically. The socket_vmnet binary must be installed into
@@ -435,7 +436,7 @@ networks:
# The same template variables as for listing instances can be used, for example {{.Dir}}.
# You can view the complete list of variables using `limactl list --list-fields` command.
# It also includes {{.HostOS}} and {{.HostArch}} vars, for the runtime GOOS and GOARCH.
# 🟢 Builtin default: null
# 🟢 Builtin default: ""
# message: |
# This will be shown to the user.

@@ -444,7 +445,7 @@ networks:
# to /etc/environment.
# If you set any of "ftp_proxy", "http_proxy", "https_proxy", or "no_proxy", then
# Lima will automatically set an uppercase variant to the same value as well.
# 🟢 Builtin default: null
# 🟢 Builtin default: {}
# env:
# KEY: value

@@ -480,7 +481,7 @@ hostResolver:
# Static names can be defined here as an alternative to adding them to the hosts /etc/hosts.
# Values can be either other hostnames, or IP addresses. The host.lima.internal name is
# predefined to specify the gateway address to the host.
# 🟢 Builtin default: null
# 🟢 Builtin default: {}
hosts:
# guest.name: 127.1.1.1
# host.name: host.lima.internal
@@ -492,7 +493,7 @@ hostResolver:
# that has an IPv4 address, to the list. In case this still doesn't work (e.g. VPN
# setups), the servers can be specified here explicitly. If nameservers are specified
# here, then the configuration from network preferences will be ignored.
# 🟢 Builtin default: null
# 🟢 Builtin default: []
# dns:
# - 1.1.1.1
# - 1.0.0.1
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ require (
github.com/goccy/go-yaml v1.12.0
github.com/google/go-cmp v0.6.0
github.com/google/yamlfmt v0.13.0
github.com/invopop/jsonschema v0.12.0
github.com/lima-vm/go-qcow2reader v0.2.0
github.com/lima-vm/sshocker v0.3.4
github.com/mattn/go-isatty v0.0.20
@@ -39,6 +40,7 @@ require (
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/wk8/go-ordered-map/v2 v2.1.8
golang.org/x/net v0.30.0
golang.org/x/sync v0.8.0
golang.org/x/sys v0.26.0
@@ -57,8 +59,10 @@ require (
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/a8m/envsubst v1.4.2 // indirect
github.com/alecthomas/participle/v2 v2.1.1 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
github.com/braydonk/yaml v0.7.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/containerd/errdefs v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -21,12 +21,16 @@ github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW5
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e h1:IdMhFPEfTZQU971tIHx3UhY4l+yCeynprnINrDTSrOc=
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e/go.mod h1:aXGMJsd3XrnUFTuyf/pTGg5jG6CY8JMZ5juywvShjgQ=
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k=
github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk=
github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI=
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
@@ -140,6 +144,8 @@ github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c h1:gYfYE403/nlrGNY
github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c/go.mod h1:Di7LXRyUcnvAcLicFhtM9/MlZl/TNgRSDHORM2c6CMI=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9 h1:LZJWucZz7ztCqY6Jsu7N9g124iJ2kt/O62j3+UchZFg=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -272,6 +278,8 @@ github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
@@ -202,7 +202,7 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
if err != nil {
return nil, err
}
mountPoint, err := localpathutil.Expand(f.MountPoint)
mountPoint, err := localpathutil.Expand(*f.MountPoint)
if err != nil {
return nil, err
}
2 changes: 1 addition & 1 deletion pkg/hostagent/mount.go
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ func (a *HostAgent) setupMount(m limayaml.Mount) (*mount, error) {
return nil, err
}

mountPoint, err := localpathutil.Expand(m.MountPoint)
mountPoint, err := localpathutil.Expand(*m.MountPoint)
if err != nil {
return nil, err
}
16 changes: 9 additions & 7 deletions pkg/limayaml/defaults.go
Original file line number Diff line number Diff line change
@@ -619,10 +619,12 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
} else {
logrus.WithError(err).Warnf("Couldn't process mount location %q as a template", mount.Location)
}
if out, err := executeGuestTemplate(mount.MountPoint, instDir, y.Param); err == nil {
mount.MountPoint = out.String()
} else {
logrus.WithError(err).Warnf("Couldn't process mount point %q as a template", mount.MountPoint)
if mount.MountPoint != nil {
if out, err := executeGuestTemplate(*mount.MountPoint, instDir, y.Param); err == nil {
mount.MountPoint = ptr.Of(out.String())
} else {
logrus.WithError(err).Warnf("Couldn't process mount point %q as a template", *mount.MountPoint)
}
}
if i, ok := location[mount.Location]; ok {
if mount.SSHFS.Cache != nil {
@@ -652,7 +654,7 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
if mount.Writable != nil {
mounts[i].Writable = mount.Writable
}
if mount.MountPoint != "" {
if mount.MountPoint != nil {
mounts[i].MountPoint = mount.MountPoint
}
} else {
@@ -695,8 +697,8 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
mounts[i].NineP.Cache = ptr.Of(Default9pCacheForRO)
}
}
if mount.MountPoint == "" {
mounts[i].MountPoint = mount.Location
if mount.MountPoint == nil {
mounts[i].MountPoint = ptr.Of(mount.Location)
}
}

8 changes: 4 additions & 4 deletions pkg/limayaml/defaults_test.go
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ func TestFillDefault(t *testing.T) {
},
Mounts: []Mount{
{Location: "/tmp"},
{Location: "{{.Dir}}/{{.Param.ONE}}", MountPoint: "/mnt/{{.Param.ONE}}"},
{Location: "{{.Dir}}/{{.Param.ONE}}", MountPoint: ptr.Of("/mnt/{{.Param.ONE}}")},
},
MountType: ptr.Of(NINEP),
Provision: []Provision{
@@ -205,7 +205,7 @@ func TestFillDefault(t *testing.T) {
}

expect.Mounts = slices.Clone(y.Mounts)
expect.Mounts[0].MountPoint = expect.Mounts[0].Location
expect.Mounts[0].MountPoint = ptr.Of(expect.Mounts[0].Location)
expect.Mounts[0].Writable = ptr.Of(false)
expect.Mounts[0].SSHFS.Cache = ptr.Of(true)
expect.Mounts[0].SSHFS.FollowSymlinks = ptr.Of(false)
@@ -217,7 +217,7 @@ func TestFillDefault(t *testing.T) {
expect.Mounts[0].Virtiofs.QueueSize = nil
// Only missing Mounts field is Writable, and the default value is also the null value: false
expect.Mounts[1].Location = fmt.Sprintf("%s/%s", instDir, y.Param["ONE"])
expect.Mounts[1].MountPoint = fmt.Sprintf("/mnt/%s", y.Param["ONE"])
expect.Mounts[1].MountPoint = ptr.Of(fmt.Sprintf("/mnt/%s", y.Param["ONE"]))
expect.Mounts[1].Writable = ptr.Of(false)
expect.Mounts[1].SSHFS.Cache = ptr.Of(true)
expect.Mounts[1].SSHFS.FollowSymlinks = ptr.Of(false)
@@ -431,7 +431,7 @@ func TestFillDefault(t *testing.T) {
expect.Containerd.Archives = slices.Clone(d.Containerd.Archives)
expect.Containerd.Archives[0].Arch = *d.Arch
expect.Mounts = slices.Clone(d.Mounts)
expect.Mounts[0].MountPoint = expect.Mounts[0].Location
expect.Mounts[0].MountPoint = ptr.Of(expect.Mounts[0].Location)
expect.Mounts[0].SSHFS.Cache = ptr.Of(true)
expect.Mounts[0].SSHFS.FollowSymlinks = ptr.Of(false)
expect.Mounts[0].SSHFS.SFTPDriver = ptr.Of("")
117 changes: 62 additions & 55 deletions pkg/limayaml/limayaml.go
Original file line number Diff line number Diff line change
@@ -7,46 +7,46 @@ import (
)

type LimaYAML struct {
MinimumLimaVersion *string `yaml:"minimumLimaVersion,omitempty" json:"minimumLimaVersion,omitempty"`
VMType *VMType `yaml:"vmType,omitempty" json:"vmType,omitempty"`
MinimumLimaVersion *string `yaml:"minimumLimaVersion,omitempty" json:"minimumLimaVersion,omitempty" jsonschema:"nullable"`
VMType *VMType `yaml:"vmType,omitempty" json:"vmType,omitempty" jsonschema:"nullable"`
VMOpts VMOpts `yaml:"vmOpts,omitempty" json:"vmOpts,omitempty"`
OS *OS `yaml:"os,omitempty" json:"os,omitempty"`
Arch *Arch `yaml:"arch,omitempty" json:"arch,omitempty"`
OS *OS `yaml:"os,omitempty" json:"os,omitempty" jsonschema:"nullable"`
Arch *Arch `yaml:"arch,omitempty" json:"arch,omitempty" jsonschema:"nullable"`
Images []Image `yaml:"images" json:"images"` // REQUIRED
CPUType CPUType `yaml:"cpuType,omitempty" json:"cpuType,omitempty"`
CPUs *int `yaml:"cpus,omitempty" json:"cpus,omitempty"`
Memory *string `yaml:"memory,omitempty" json:"memory,omitempty"` // go-units.RAMInBytes
Disk *string `yaml:"disk,omitempty" json:"disk,omitempty"` // go-units.RAMInBytes
AdditionalDisks []Disk `yaml:"additionalDisks,omitempty" json:"additionalDisks,omitempty"`
CPUType CPUType `yaml:"cpuType,omitempty" json:"cpuType,omitempty" jsonschema:"nullable"`
CPUs *int `yaml:"cpus,omitempty" json:"cpus,omitempty" jsonschema:"nullable"`
Memory *string `yaml:"memory,omitempty" json:"memory,omitempty" jsonschema:"nullable"` // go-units.RAMInBytes
Disk *string `yaml:"disk,omitempty" json:"disk,omitempty" jsonschema:"nullable"` // go-units.RAMInBytes
AdditionalDisks []Disk `yaml:"additionalDisks,omitempty" json:"additionalDisks,omitempty" jsonschema:"nullable"`
Mounts []Mount `yaml:"mounts,omitempty" json:"mounts,omitempty"`
MountTypesUnsupported []string `yaml:"mountTypesUnsupported,omitempty" json:"mountTypesUnsupported,omitempty"`
MountType *MountType `yaml:"mountType,omitempty" json:"mountType,omitempty"`
MountInotify *bool `yaml:"mountInotify,omitempty" json:"mountInotify,omitempty"`
MountTypesUnsupported []string `yaml:"mountTypesUnsupported,omitempty" json:"mountTypesUnsupported,omitempty" jsonschema:"nullable"`
MountType *MountType `yaml:"mountType,omitempty" json:"mountType,omitempty" jsonschema:"nullable"`
MountInotify *bool `yaml:"mountInotify,omitempty" json:"mountInotify,omitempty" jsonschema:"nullable"`
SSH SSH `yaml:"ssh,omitempty" json:"ssh,omitempty"` // REQUIRED (FIXME)
Firmware Firmware `yaml:"firmware,omitempty" json:"firmware,omitempty"`
Audio Audio `yaml:"audio,omitempty" json:"audio,omitempty"`
Video Video `yaml:"video,omitempty" json:"video,omitempty"`
Provision []Provision `yaml:"provision,omitempty" json:"provision,omitempty"`
UpgradePackages *bool `yaml:"upgradePackages,omitempty" json:"upgradePackages,omitempty"`
UpgradePackages *bool `yaml:"upgradePackages,omitempty" json:"upgradePackages,omitempty" jsonschema:"nullable"`
Containerd Containerd `yaml:"containerd,omitempty" json:"containerd,omitempty"`
GuestInstallPrefix *string `yaml:"guestInstallPrefix,omitempty" json:"guestInstallPrefix,omitempty"`
GuestInstallPrefix *string `yaml:"guestInstallPrefix,omitempty" json:"guestInstallPrefix,omitempty" jsonschema:"nullable"`
Probes []Probe `yaml:"probes,omitempty" json:"probes,omitempty"`
PortForwards []PortForward `yaml:"portForwards,omitempty" json:"portForwards,omitempty"`
CopyToHost []CopyToHost `yaml:"copyToHost,omitempty" json:"copyToHost,omitempty"`
Message string `yaml:"message,omitempty" json:"message,omitempty"`
Networks []Network `yaml:"networks,omitempty" json:"networks,omitempty"`
Networks []Network `yaml:"networks,omitempty" json:"networks,omitempty" jsonschema:"nullable"`
// `network` was deprecated in Lima v0.7.0, removed in Lima v0.14.0. Use `networks` instead.
Env map[string]string `yaml:"env,omitempty" json:"env,omitempty"`
Param map[string]string `yaml:"param,omitempty" json:"param,omitempty"`
DNS []net.IP `yaml:"dns,omitempty" json:"dns,omitempty"`
HostResolver HostResolver `yaml:"hostResolver,omitempty" json:"hostResolver,omitempty"`
// `useHostResolver` was deprecated in Lima v0.8.1, removed in Lima v0.14.0. Use `hostResolver.enabled` instead.
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"`
PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty" jsonschema:"nullable"`
CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"`
Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"`
Plain *bool `yaml:"plain,omitempty" json:"plain,omitempty"`
TimeZone *string `yaml:"timezone,omitempty" json:"timezone,omitempty"`
NestedVirtualization *bool `yaml:"nestedVirtualization,omitempty" json:"nestedVirtualization,omitempty"`
Plain *bool `yaml:"plain,omitempty" json:"plain,omitempty" jsonschema:"nullable"`
TimeZone *string `yaml:"timezone,omitempty" json:"timezone,omitempty" jsonschema:"nullable"`
NestedVirtualization *bool `yaml:"nestedVirtualization,omitempty" json:"nestedVirtualization,omitempty" jsonschema:"nullable"`
}

type (
@@ -76,17 +76,24 @@ const (
WSL2 VMType = "wsl2"
)

var (
OSTypes = []OS{LINUX}
ArchTypes = []Arch{X8664, AARCH64, ARMV7L, RISCV64}
MountTypes = []MountType{REVSSHFS, NINEP, VIRTIOFS, WSLMount}
VMTypes = []VMType{QEMU, VZ, WSL2}
)

type VMOpts struct {
QEMU QEMUOpts `yaml:"qemu,omitempty" json:"qemu,omitempty"`
}

type QEMUOpts struct {
MinimumVersion *string `yaml:"minimumVersion,omitempty" json:"minimumVersion,omitempty"`
MinimumVersion *string `yaml:"minimumVersion,omitempty" json:"minimumVersion,omitempty" jsonschema:"nullable"`
}

type Rosetta struct {
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
BinFmt *bool `yaml:"binfmt,omitempty" json:"binfmt,omitempty"`
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty" jsonschema:"nullable"`
BinFmt *bool `yaml:"binfmt,omitempty" json:"binfmt,omitempty" jsonschema:"nullable"`
}

type File struct {
@@ -120,8 +127,8 @@ type Disk struct {

type Mount struct {
Location string `yaml:"location" json:"location"` // REQUIRED
MountPoint string `yaml:"mountPoint,omitempty" json:"mountPoint,omitempty"`
Writable *bool `yaml:"writable,omitempty" json:"writable,omitempty"`
MountPoint *string `yaml:"mountPoint,omitempty" json:"mountPoint,omitempty" jsonschema:"nullable"`
Writable *bool `yaml:"writable,omitempty" json:"writable,omitempty" jsonschema:"nullable"`
SSHFS SSHFS `yaml:"sshfs,omitempty" json:"sshfs,omitempty"`
NineP NineP `yaml:"9p,omitempty" json:"9p,omitempty"`
Virtiofs Virtiofs `yaml:"virtiofs,omitempty" json:"virtiofs,omitempty"`
@@ -135,36 +142,36 @@ const (
)

type SSHFS struct {
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
SFTPDriver *SFTPDriver `yaml:"sftpDriver,omitempty" json:"sftpDriver,omitempty"`
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty" jsonschema:"nullable"`
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty" jsonschema:"nullable"`
SFTPDriver *SFTPDriver `yaml:"sftpDriver,omitempty" json:"sftpDriver,omitempty" jsonschema:"nullable"`
}

type NineP struct {
SecurityModel *string `yaml:"securityModel,omitempty" json:"securityModel,omitempty"`
ProtocolVersion *string `yaml:"protocolVersion,omitempty" json:"protocolVersion,omitempty"`
Msize *string `yaml:"msize,omitempty" json:"msize,omitempty"`
Cache *string `yaml:"cache,omitempty" json:"cache,omitempty"`
SecurityModel *string `yaml:"securityModel,omitempty" json:"securityModel,omitempty" jsonschema:"nullable"`
ProtocolVersion *string `yaml:"protocolVersion,omitempty" json:"protocolVersion,omitempty" jsonschema:"nullable"`
Msize *string `yaml:"msize,omitempty" json:"msize,omitempty" jsonschema:"nullable"`
Cache *string `yaml:"cache,omitempty" json:"cache,omitempty" jsonschema:"nullable"`
}

type Virtiofs struct {
QueueSize *int `yaml:"queueSize,omitempty" json:"queueSize,omitempty"`
}

type SSH struct {
LocalPort *int `yaml:"localPort,omitempty" json:"localPort,omitempty"`
LocalPort *int `yaml:"localPort,omitempty" json:"localPort,omitempty" jsonschema:"nullable"`

// LoadDotSSHPubKeys loads ~/.ssh/*.pub in addition to $LIMA_HOME/_config/user.pub .
LoadDotSSHPubKeys *bool `yaml:"loadDotSSHPubKeys,omitempty" json:"loadDotSSHPubKeys,omitempty"` // default: false
ForwardAgent *bool `yaml:"forwardAgent,omitempty" json:"forwardAgent,omitempty"` // default: false
ForwardX11 *bool `yaml:"forwardX11,omitempty" json:"forwardX11,omitempty"` // default: false
ForwardX11Trusted *bool `yaml:"forwardX11Trusted,omitempty" json:"forwardX11Trusted,omitempty"` // default: false
LoadDotSSHPubKeys *bool `yaml:"loadDotSSHPubKeys,omitempty" json:"loadDotSSHPubKeys,omitempty" jsonschema:"nullable"` // default: false
ForwardAgent *bool `yaml:"forwardAgent,omitempty" json:"forwardAgent,omitempty" jsonschema:"nullable"` // default: false
ForwardX11 *bool `yaml:"forwardX11,omitempty" json:"forwardX11,omitempty" jsonschema:"nullable"` // default: false
ForwardX11Trusted *bool `yaml:"forwardX11Trusted,omitempty" json:"forwardX11Trusted,omitempty" jsonschema:"nullable"` // default: false
}

type Firmware struct {
// LegacyBIOS disables UEFI if set.
// LegacyBIOS is ignored for aarch64.
LegacyBIOS *bool `yaml:"legacyBIOS,omitempty" json:"legacyBIOS,omitempty"`
LegacyBIOS *bool `yaml:"legacyBIOS,omitempty" json:"legacyBIOS,omitempty" jsonschema:"nullable"`

// Images specify UEFI images (edk2-aarch64-code.fd.gz).
// Defaults to built-in UEFI.
@@ -173,17 +180,17 @@ type Firmware struct {

type Audio struct {
// Device is a QEMU audiodev string
Device *string `yaml:"device,omitempty" json:"device,omitempty"`
Device *string `yaml:"device,omitempty" json:"device,omitempty" jsonschema:"nullable"`
}

type VNCOptions struct {
Display *string `yaml:"display,omitempty" json:"display,omitempty"`
Display *string `yaml:"display,omitempty" json:"display,omitempty" jsonschema:"nullable"`
}

type Video struct {
// Display is a QEMU display string
Display *string `yaml:"display,omitempty" json:"display,omitempty"`
VNC VNCOptions `yaml:"vnc" json:"vnc"`
Display *string `yaml:"display,omitempty" json:"display,omitempty" jsonschema:"nullable"`
VNC VNCOptions `yaml:"vnc,omitempty" json:"vnc,omitempty"`
}

type ProvisionMode = string
@@ -197,16 +204,16 @@ const (
)

type Provision struct {
Mode ProvisionMode `yaml:"mode" json:"mode"` // default: "system"
Mode ProvisionMode `yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"default=system"`
SkipDefaultDependencyResolution *bool `yaml:"skipDefaultDependencyResolution,omitempty" json:"skipDefaultDependencyResolution,omitempty"`
Script string `yaml:"script" json:"script"`
Playbook string `yaml:"playbook,omitempty" json:"playbook,omitempty"`
}

type Containerd struct {
System *bool `yaml:"system,omitempty" json:"system,omitempty"` // default: false
User *bool `yaml:"user,omitempty" json:"user,omitempty"` // default: true
Archives []File `yaml:"archives,omitempty" json:"archives,omitempty"` // default: see defaultContainerdArchives
System *bool `yaml:"system,omitempty" json:"system,omitempty" jsonschema:"nullable"` // default: false
User *bool `yaml:"user,omitempty" json:"user,omitempty" jsonschema:"nullable"` // default: true
Archives []File `yaml:"archives,omitempty" json:"archives,omitempty"` // default: see defaultContainerdArchives
}

type ProbeMode = string
@@ -216,10 +223,10 @@ const (
)

type Probe struct {
Mode ProbeMode // default: "readiness"
Description string
Script string
Hint string
Mode ProbeMode `yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"default=readiness"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Script string `yaml:"script,omitempty" json:"script,omitempty"`
Hint string `yaml:"hint,omitempty" json:"hint,omitempty"`
}

type Proto = string
@@ -264,13 +271,13 @@ type Network struct {
}

type HostResolver struct {
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
IPv6 *bool `yaml:"ipv6,omitempty" json:"ipv6,omitempty"`
Hosts map[string]string `yaml:"hosts,omitempty" json:"hosts,omitempty"`
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty" jsonschema:"nullable"`
IPv6 *bool `yaml:"ipv6,omitempty" json:"ipv6,omitempty" jsonschema:"nullable"`
Hosts map[string]string `yaml:"hosts,omitempty" json:"hosts,omitempty" jsonschema:"nullable"`
}

type CACertificates struct {
RemoveDefaults *bool `yaml:"removeDefaults,omitempty" json:"removeDefaults,omitempty"` // default: false
Files []string `yaml:"files,omitempty" json:"files,omitempty"`
Certs []string `yaml:"certs,omitempty" json:"certs,omitempty"`
RemoveDefaults *bool `yaml:"removeDefaults,omitempty" json:"removeDefaults,omitempty" jsonschema:"nullable"` // default: false
Files []string `yaml:"files,omitempty" json:"files,omitempty" jsonschema:"nullable"`
Certs []string `yaml:"certs,omitempty" json:"certs,omitempty" jsonschema:"nullable"`
}
2 changes: 1 addition & 1 deletion pkg/limayaml/validate.go
Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ func ValidateParamIsUsed(y *LimaYAML) error {
keyIsUsed = true
break
}
if re.MatchString(p.MountPoint) {
if p.MountPoint != nil && re.MatchString(*p.MountPoint) {
keyIsUsed = true
break
}