Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/cmd/limactl/genschema.go
1645 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package main
5
6
import (
7
"encoding/json"
8
"errors"
9
"fmt"
10
"os"
11
12
"github.com/invopop/jsonschema"
13
"github.com/sirupsen/logrus"
14
"github.com/spf13/cobra"
15
orderedmap "github.com/wk8/go-ordered-map/v2"
16
17
"github.com/lima-vm/lima/v2/pkg/jsonschemautil"
18
"github.com/lima-vm/lima/v2/pkg/limatype"
19
)
20
21
func newGenSchemaCommand() *cobra.Command {
22
genschemaCommand := &cobra.Command{
23
Use: "generate-jsonschema",
24
Short: "Generate json-schema document",
25
Args: WrapArgsError(cobra.ArbitraryArgs),
26
RunE: genschemaAction,
27
Hidden: true,
28
}
29
genschemaCommand.Flags().String("schemafile", "", "Output file")
30
return genschemaCommand
31
}
32
33
func toAny(args []string) []any {
34
result := []any{nil}
35
for _, arg := range args {
36
result = append(result, arg)
37
}
38
return result
39
}
40
41
func getProp(props *orderedmap.OrderedMap[string, *jsonschema.Schema], key string) *jsonschema.Schema {
42
value, ok := props.Get(key)
43
if !ok {
44
return nil
45
}
46
return value
47
}
48
49
func genschemaAction(cmd *cobra.Command, args []string) error {
50
file, err := cmd.Flags().GetString("schemafile")
51
if err != nil {
52
return err
53
}
54
55
schema := jsonschema.Reflect(&limatype.LimaYAML{})
56
// allow Disk to be either string (name) or object (struct)
57
schema.Definitions["Disk"].Type = "" // was: "object"
58
schema.Definitions["Disk"].OneOf = []*jsonschema.Schema{
59
{Type: "string"},
60
{Type: "object"},
61
}
62
// allow BaseTemplates to be either string (url) or array (array)
63
schema.Definitions["BaseTemplates"].Type = "" // was: "array"
64
schema.Definitions["BaseTemplates"].OneOf = []*jsonschema.Schema{
65
{Type: "string"},
66
{Type: "array"},
67
}
68
// allow LocatorWithDigest to be either string (url) or object (struct)
69
schema.Definitions["LocatorWithDigest"].Type = "" // was: "object"
70
schema.Definitions["LocatorWithDigest"].OneOf = []*jsonschema.Schema{
71
{Type: "string"},
72
{Type: "object"},
73
}
74
properties := schema.Definitions["LimaYAML"].Properties
75
getProp(properties, "os").Enum = toAny(limatype.OSTypes)
76
getProp(properties, "arch").Enum = toAny(limatype.ArchTypes)
77
getProp(properties, "mountType").Enum = toAny(limatype.MountTypes)
78
getProp(properties, "vmType").Enum = toAny(limatype.VMTypes)
79
j, err := json.MarshalIndent(schema, "", " ")
80
if err != nil {
81
return err
82
}
83
if len(args) == 0 {
84
_, err = fmt.Fprintln(cmd.OutOrStdout(), string(j))
85
return err
86
}
87
88
if file == "" {
89
return errors.New("need --schemafile to validate")
90
}
91
err = os.WriteFile(file, j, 0o644)
92
if err != nil {
93
return err
94
}
95
for _, f := range args {
96
err = jsonschemautil.Validate(file, f)
97
if err != nil {
98
return fmt.Errorf("%q: %w", f, err)
99
}
100
logrus.Infof("%q: OK", f)
101
}
102
103
return err
104
}
105
106