diff --git a/examples/default.yaml b/examples/default.yaml index 36d04ac95f5..92ac2ec9932 100644 --- a/examples/default.yaml +++ b/examples/default.yaml @@ -193,7 +193,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}}, and {{.User}} +# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}} # 🟢 Builtin default: null # provision: # # `system` is executed with root privileges @@ -235,6 +235,7 @@ containerd: # playbook: playbook.yaml # Probe scripts to check readiness. +# The scripts can use the following template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}} # 🟢 Builtin default: null # probes: # # Only `readiness` probes are supported right now. @@ -377,8 +378,8 @@ networks: # - guestSocket: "/run/user/{{.UID}}/my.sock" # hostSocket: mysocket # # default: reverse: false -# # "guestSocket" can include these template variables: {{.Home}}, {{.UID}}, and {{.User}}. -# # "hostSocket" can include {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, and {{.User}}. +# # "guestSocket" can include these template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}. +# # "hostSocket" can include {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}. # # "reverse" can only be used for unix sockets right now, not for tcp sockets. # # Put sockets into "{{.Dir}}/sock" to avoid collision with Lima internal sockets! # # Sockets can also be forwarded to ports and vice versa, but not to/from a range of ports. @@ -397,8 +398,8 @@ networks: # - guest: "/etc/myconfig.cfg" # host: "{{.Dir}}/copied-from-guest/myconfig" # # deleteOnStop: false -# # "guest" can include these template variables: {{.Home}}, {{.UID}}, and {{.User}}. -# # "host" can include {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, and {{.User}}. +# # "guest" can include these template variables: {{.Home}}, {{.UID}}, {{.User}}, and {{.Param.Key}}. +# # "host" can include {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}. # # "deleteOnStop" will delete the file from the host when the instance is stopped. # Message. Information to be shown to the user, given as a Go template for the instance. @@ -418,6 +419,11 @@ networks: # env: # KEY: value +# Defines variables used for customizing the functionality. +# These variables can be referenced as {{.Param.Key}} in lima.yaml. +# param: +# Key: value + # Lima will override the proxy environment variables with values from the current process # environment (the environment in effect when you run `limactl start`). It will automatically # replace the strings "localhost" and "127.0.0.1" with the host gateway address from inside diff --git a/pkg/hostagent/hostagent.go b/pkg/hostagent/hostagent.go index 52a85551444..0f09c6cee51 100644 --- a/pkg/hostagent/hostagent.go +++ b/pkg/hostagent/hostagent.go @@ -155,13 +155,13 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt // Block ports 22 and sshLocalPort on all IPs for _, port := range []int{sshGuestPort, sshLocalPort} { rule := limayaml.PortForward{GuestIP: net.IPv4zero, GuestPort: port, Ignore: true} - limayaml.FillPortForwardDefaults(&rule, inst.Dir) + limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Param) rules = append(rules, rule) } rules = append(rules, y.PortForwards...) // Default forwards for all non-privileged ports from "127.0.0.1" and "::1" rule := limayaml.PortForward{} - limayaml.FillPortForwardDefaults(&rule, inst.Dir) + limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Param) rules = append(rules, rule) limaDriver := driverutil.CreateTargetDriverInstance(&driver.BaseDriver{ diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index 13815bb675f..f69a320f9ba 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -394,7 +394,7 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { if provision.Mode == ProvisionModeDependency && provision.SkipDefaultDependencyResolution == nil { provision.SkipDefaultDependencyResolution = ptr.Of(false) } - if out, err := executeGuestTemplate(provision.Script, instDir); err == nil { + if out, err := executeGuestTemplate(provision.Script, instDir, y.Param); err == nil { provision.Script = out.String() } else { logrus.WithError(err).Warnf("Couldn't process provisioning script %q as a template", provision.Script) @@ -460,17 +460,22 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { if probe.Description == "" { probe.Description = fmt.Sprintf("user probe %d/%d", i+1, len(y.Probes)) } + if out, err := executeGuestTemplate(probe.Script, instDir, y.Param); err == nil { + probe.Script = out.String() + } else { + logrus.WithError(err).Warnf("Couldn't process probing script %q as a template", probe.Script) + } } y.PortForwards = append(append(o.PortForwards, y.PortForwards...), d.PortForwards...) for i := range y.PortForwards { - FillPortForwardDefaults(&y.PortForwards[i], instDir) + FillPortForwardDefaults(&y.PortForwards[i], instDir, y.Param) // After defaults processing the singular HostPort and GuestPort values should not be used again. } y.CopyToHost = append(append(o.CopyToHost, y.CopyToHost...), d.CopyToHost...) for i := range y.CopyToHost { - FillCopyToHostDefaults(&y.CopyToHost[i], instDir) + FillCopyToHostDefaults(&y.CopyToHost[i], instDir, y.Param) } if y.HostResolver.Enabled == nil { @@ -669,6 +674,18 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { } y.Env = env + param := make(map[string]string) + for k, v := range d.Param { + param[k] = v + } + for k, v := range y.Param { + param[k] = v + } + for k, v := range o.Param { + param[k] = v + } + y.Param = param + if y.CACertificates.RemoveDefaults == nil { y.CACertificates.RemoveDefaults = d.CACertificates.RemoveDefaults } @@ -735,15 +752,16 @@ func fixUpForPlainMode(y *LimaYAML) { y.TimeZone = ptr.Of("") } -func executeGuestTemplate(format, instDir string) (bytes.Buffer, error) { +func executeGuestTemplate(format, instDir string, param map[string]string) (bytes.Buffer, error) { tmpl, err := template.New("").Parse(format) if err == nil { user, _ := osutil.LimaUser(false) - data := map[string]string{ - "Home": fmt.Sprintf("/home/%s.linux", user.Username), - "Name": filepath.Base(instDir), - "UID": user.Uid, - "User": user.Username, + data := map[string]interface{}{ + "Home": fmt.Sprintf("/home/%s.linux", user.Username), + "Name": filepath.Base(instDir), + "UID": user.Uid, + "User": user.Username, + "Param": param, } var out bytes.Buffer if err := tmpl.Execute(&out, data); err == nil { @@ -753,18 +771,19 @@ func executeGuestTemplate(format, instDir string) (bytes.Buffer, error) { return bytes.Buffer{}, err } -func executeHostTemplate(format, instDir string) (bytes.Buffer, error) { +func executeHostTemplate(format, instDir string, param map[string]string) (bytes.Buffer, error) { tmpl, err := template.New("").Parse(format) if err == nil { user, _ := osutil.LimaUser(false) home, _ := os.UserHomeDir() limaHome, _ := dirnames.LimaDir() - data := map[string]string{ - "Dir": instDir, - "Home": home, - "Name": filepath.Base(instDir), - "UID": user.Uid, - "User": user.Username, + data := map[string]interface{}{ + "Dir": instDir, + "Home": home, + "Name": filepath.Base(instDir), + "UID": user.Uid, + "User": user.Username, + "Param": param, "Instance": filepath.Base(instDir), // DEPRECATED, use `{{.Name}}` "LimaHome": limaHome, // DEPRECATED, use `{{.Dir}}` instead of `{{.LimaHome}}/{{.Instance}}` @@ -777,7 +796,7 @@ func executeHostTemplate(format, instDir string) (bytes.Buffer, error) { return bytes.Buffer{}, err } -func FillPortForwardDefaults(rule *PortForward, instDir string) { +func FillPortForwardDefaults(rule *PortForward, instDir string, param map[string]string) { if rule.Proto == "" { rule.Proto = TCP } @@ -809,14 +828,14 @@ func FillPortForwardDefaults(rule *PortForward, instDir string) { } } if rule.GuestSocket != "" { - if out, err := executeGuestTemplate(rule.GuestSocket, instDir); err == nil { + if out, err := executeGuestTemplate(rule.GuestSocket, instDir, param); err == nil { rule.GuestSocket = out.String() } else { logrus.WithError(err).Warnf("Couldn't process guestSocket %q as a template", rule.GuestSocket) } } if rule.HostSocket != "" { - if out, err := executeHostTemplate(rule.HostSocket, instDir); err == nil { + if out, err := executeHostTemplate(rule.HostSocket, instDir, param); err == nil { rule.HostSocket = out.String() } else { logrus.WithError(err).Warnf("Couldn't process hostSocket %q as a template", rule.HostSocket) @@ -827,16 +846,16 @@ func FillPortForwardDefaults(rule *PortForward, instDir string) { } } -func FillCopyToHostDefaults(rule *CopyToHost, instDir string) { +func FillCopyToHostDefaults(rule *CopyToHost, instDir string, param map[string]string) { if rule.GuestFile != "" { - if out, err := executeGuestTemplate(rule.GuestFile, instDir); err == nil { + if out, err := executeGuestTemplate(rule.GuestFile, instDir, param); err == nil { rule.GuestFile = out.String() } else { logrus.WithError(err).Warnf("Couldn't process guest %q as a template", rule.GuestFile) } } if rule.HostFile != "" { - if out, err := executeHostTemplate(rule.HostFile, instDir); err == nil { + if out, err := executeHostTemplate(rule.HostFile, instDir, param); err == nil { rule.HostFile = out.String() } else { logrus.WithError(err).Warnf("Couldn't process host %q as a template", rule.HostFile) diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index ecca9e362c0..c09fcdbd9c3 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -129,10 +129,10 @@ func TestFillDefault(t *testing.T) { }, MountType: ptr.Of(NINEP), Provision: []Provision{ - {Script: "#!/bin/true"}, + {Script: "#!/bin/true # {{.Param.ONE}}"}, }, Probes: []Probe{ - {Script: "#!/bin/false"}, + {Script: "#!/bin/false # {{.Param.ONE}}"}, }, Networks: []Network{ {Lima: "shared"}, @@ -145,19 +145,22 @@ func TestFillDefault(t *testing.T) { {GuestPort: 80}, {GuestPort: 8080, HostPort: 8888}, { - GuestSocket: "{{.Home}} | {{.UID}} | {{.User}}", - HostSocket: "{{.Home}} | {{.Dir}} | {{.Name}} | {{.UID}} | {{.User}}", + GuestSocket: "{{.Home}} | {{.UID}} | {{.User}} | {{.Param.ONE}}", + HostSocket: "{{.Home}} | {{.Dir}} | {{.Name}} | {{.UID}} | {{.User}} | {{.Param.ONE}}", }, }, CopyToHost: []CopyToHost{ { - GuestFile: "{{.Home}} | {{.UID}} | {{.User}}", - HostFile: "{{.Home}} | {{.Dir}} | {{.Name}} | {{.UID}} | {{.User}}", + GuestFile: "{{.Home}} | {{.UID}} | {{.User}} | {{.Param.ONE}}", + HostFile: "{{.Home}} | {{.Dir}} | {{.Name}} | {{.UID}} | {{.User}} | {{.Param.ONE}}", }, }, Env: map[string]string{ "ONE": "Eins", }, + Param: map[string]string{ + "ONE": "Eins", + }, CACertificates: CACertificates{ Files: []string{"ca.crt"}, Certs: []string{ @@ -212,10 +215,12 @@ func TestFillDefault(t *testing.T) { expect.Provision = y.Provision expect.Provision[0].Mode = ProvisionModeSystem + expect.Provision[0].Script = "#!/bin/true # Eins" expect.Probes = y.Probes expect.Probes[0].Mode = ProbeModeReadiness expect.Probes[0].Description = "user probe 1/1" + expect.Probes[0].Script = "#!/bin/true # Eins" expect.Networks = y.Networks expect.Networks[0].MACAddress = MACAddress(fmt.Sprintf("%s#%d", filePath, 0)) @@ -243,14 +248,16 @@ func TestFillDefault(t *testing.T) { expect.PortForwards[2].HostPort = 8888 expect.PortForwards[2].HostPortRange = [2]int{8888, 8888} - expect.PortForwards[3].GuestSocket = fmt.Sprintf("%s | %s | %s", guestHome, user.Uid, user.Username) - expect.PortForwards[3].HostSocket = fmt.Sprintf("%s | %s | %s | %s | %s", hostHome, instDir, instName, user.Uid, user.Username) + expect.PortForwards[3].GuestSocket = fmt.Sprintf("%s | %s | %s | %s", guestHome, user.Uid, user.Username, y.Param["ONE"]) + expect.PortForwards[3].HostSocket = fmt.Sprintf("%s | %s | %s | %s | %s | %s", hostHome, instDir, instName, user.Uid, user.Username, y.Param["ONE"]) - expect.CopyToHost[0].GuestFile = fmt.Sprintf("%s | %s | %s", guestHome, user.Uid, user.Username) - expect.CopyToHost[0].HostFile = fmt.Sprintf("%s | %s | %s | %s | %s", hostHome, instDir, instName, user.Uid, user.Username) + expect.CopyToHost[0].GuestFile = fmt.Sprintf("%s | %s | %s | %s", guestHome, user.Uid, user.Username, y.Param["ONE"]) + expect.CopyToHost[0].HostFile = fmt.Sprintf("%s | %s | %s | %s | %s | %s", hostHome, instDir, instName, user.Uid, user.Username, y.Param["ONE"]) expect.Env = y.Env + expect.Param = y.Param + expect.CACertificates = CACertificates{ RemoveDefaults: ptr.Of(false), Files: []string{"ca.crt"}, @@ -380,6 +387,10 @@ func TestFillDefault(t *testing.T) { "ONE": "one", "TWO": "two", }, + Param: map[string]string{ + "ONE": "one", + "TWO": "two", + }, CACertificates: CACertificates{ RemoveDefaults: ptr.Of(true), Certs: []string{ @@ -459,6 +470,8 @@ func TestFillDefault(t *testing.T) { // "TWO" does not exist in filledDefaults.Env, so is set from d.Env expect.Env["TWO"] = d.Env["TWO"] + expect.Param["TWO"] = d.Param["TWO"] + FillDefault(&y, &d, &LimaYAML{}, filePath) assert.DeepEqual(t, &y, &expect, opts...) @@ -584,6 +597,10 @@ func TestFillDefault(t *testing.T) { "TWO": "deux", "THREE": "trois", }, + Param: map[string]string{ + "TWO": "deux", + "THREE": "trois", + }, CACertificates: CACertificates{ RemoveDefaults: ptr.Of(true), }, @@ -632,6 +649,8 @@ func TestFillDefault(t *testing.T) { // ONE remains from filledDefaults.Env; the rest are set from o expect.Env["ONE"] = y.Env["ONE"] + expect.Param["ONE"] = y.Param["ONE"] + expect.CACertificates.RemoveDefaults = ptr.Of(true) expect.CACertificates.Files = []string{"ca.crt"} expect.CACertificates.Certs = []string{ diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go index a6761b6cf4d..4b3bc1cdd7c 100644 --- a/pkg/limayaml/limayaml.go +++ b/pkg/limayaml/limayaml.go @@ -34,6 +34,7 @@ type LimaYAML struct { Networks []Network `yaml:"networks,omitempty" json:"networks,omitempty"` // `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. diff --git a/pkg/limayaml/load.go b/pkg/limayaml/load.go index f9c7e3c4ac5..20670eb605d 100644 --- a/pkg/limayaml/load.go +++ b/pkg/limayaml/load.go @@ -86,6 +86,11 @@ func Load(b []byte, filePath string) (*LimaYAML, error) { return nil, err } + // It should be called before the `y` parameter is passed to FillDefault() that execute template. + if err := ValidateParamIsUsed(&y); err != nil { + return nil, err + } + FillDefault(&y, &d, &o, filePath) return &y, nil } diff --git a/pkg/limayaml/validate.go b/pkg/limayaml/validate.go index 6e398a59af5..9210e86ccad 100644 --- a/pkg/limayaml/validate.go +++ b/pkg/limayaml/validate.go @@ -7,6 +7,7 @@ import ( "os" "path" "path/filepath" + "regexp" "runtime" "strings" @@ -252,7 +253,7 @@ func Validate(y *LimaYAML, warn bool) error { } if rule.GuestSocket != "" { if !path.IsAbs(rule.GuestSocket) { - return fmt.Errorf("field `%s.guestSocket` must be an absolute path", field) + return fmt.Errorf("field `%s.guestSocket` must be an absolute path, but is %q", field, rule.GuestSocket) } if rule.HostSocket == "" && rule.HostPortRange[1]-rule.HostPortRange[0] > 0 { return fmt.Errorf("field `%s.guestSocket` can only be mapped to a single port or socket. not a range", field) @@ -287,7 +288,7 @@ func Validate(y *LimaYAML, warn bool) error { field := fmt.Sprintf("CopyToHost[%d]", i) if rule.GuestFile != "" { if !path.IsAbs(rule.GuestFile) { - return fmt.Errorf("field `%s.guest` must be an absolute path", field) + return fmt.Errorf("field `%s.guest` must be an absolute path, but is %q", field, rule.GuestFile) } } if rule.HostFile != "" { @@ -385,6 +386,46 @@ func validateNetwork(y *LimaYAML) error { return nil } +// ValidateParamIsUsed checks if the keys in the `param` field are used in any script, probe, copyToHost, or portForward. +// It should be called before the `y` parameter is passed to FillDefault() that execute template. +func ValidateParamIsUsed(y *LimaYAML) error { + for key := range y.Param { + re, err := regexp.Compile(`{{[^}]*\.Param\.` + key + `[^}]*}}`) + if err != nil { + return fmt.Errorf("field to compile regexp for key %q: %w", key, err) + } + keyIsUsed := false + for _, p := range y.Provision { + if re.MatchString(p.Script) { + keyIsUsed = true + break + } + } + for _, p := range y.Probes { + if re.MatchString(p.Script) { + keyIsUsed = true + break + } + } + for _, p := range y.CopyToHost { + if re.MatchString(p.GuestFile) || re.MatchString(p.HostFile) { + keyIsUsed = true + break + } + } + for _, p := range y.PortForwards { + if re.MatchString(p.GuestSocket) || re.MatchString(p.HostSocket) { + keyIsUsed = true + break + } + } + if !keyIsUsed { + return fmt.Errorf("field `param` key %q is not used in any provision, probe, copyToHost, or portForward", key) + } + } + return nil +} + func validatePort(field string, port int) error { switch { case port < 0: diff --git a/pkg/limayaml/validate_test.go b/pkg/limayaml/validate_test.go index 751952cc23f..9be1b3a63e9 100644 --- a/pkg/limayaml/validate_test.go +++ b/pkg/limayaml/validate_test.go @@ -30,3 +30,50 @@ func TestValidateDefault(t *testing.T) { err = Validate(y, true) assert.NilError(t, err) } + +func TestValidateParamIsUsed(t *testing.T) { + paramYaml := `param: + name: value` + _, err := Load([]byte(paramYaml), "paramIsNotUsed.yaml") + assert.Error(t, err, "field `param` key \"name\" is not used in any provision, probe, copyToHost, or portForward") + + fieldsUsingParam := []string{ + `provision: [{"script": "echo {{ .Param.name }}"}]`, + `probes: [{"script": "echo {{ .Param.name }}"}]`, + `copyToHost: [{"guest": "/tmp/{{ .Param.name }}", "host": "/tmp"}]`, + `copyToHost: [{"guest": "/tmp", "host": "/tmp/{{ .Param.name }}"}]`, + `portForwards: [{"guestSocket": "/tmp/{{ .Param.name }}", "hostSocket": "/tmp"}]`, + `portForwards: [{"guestSocket": "/tmp", "hostSocket": "/tmp/{{ .Param.name }}"}]`, + } + for _, fieldUsingParam := range fieldsUsingParam { + _, err = Load([]byte(fieldUsingParam+"\n"+paramYaml), "paramIsUsed.yaml") + // + assert.NilError(t, err) + } + + // use "{{if .Param.rootful \"true\"}}{{else}}{{end}}"" in provision, probe, copyToHost, and portForward + rootfulYaml := `param: + rootful: true` + fieldsUsingIfParamRootfulTrue := []string{ + `provision: [{"script": "echo {{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`, + `probes: [{"script": "echo {{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`, + `copyToHost: [{"guest": "/tmp/{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}", "host": "/tmp"}]`, + `copyToHost: [{"guest": "/tmp", "host": "/tmp/{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`, + `portForwards: [{"guestSocket": "{{if eq .Param.rootful \"true\"}}/var/run{{else}}/run/user/{{.UID}}{{end}}/docker.sock", "hostSocket": "{{.Dir}}/sock/docker.sock"}]`, + `portForwards: [{"guestSocket": "/var/run/docker.sock", "hostSocket": "{{.Dir}}/sock/docker-{{if eq .Param.rootful \"true\"}}rootfule{{else}}rootless{{end}}.sock"}]`, + } + for _, fieldUsingIfParamRootfulTrue := range fieldsUsingIfParamRootfulTrue { + _, err = Load([]byte(fieldUsingIfParamRootfulTrue+"\n"+rootfulYaml), "paramIsUsed.yaml") + // + assert.NilError(t, err) + } + + // use rootFul instead of rootful + rootFulYaml := `param: + rootFul: true` + for _, fieldUsingIfParamRootfulTrue := range fieldsUsingIfParamRootfulTrue { + _, err = Load([]byte(fieldUsingIfParamRootfulTrue+"\n"+rootFulYaml), "paramIsUsed.yaml") + // + assert.Error(t, err, "field `param` key \"rootFul\" is not used in any provision, probe, copyToHost, or portForward") + } +} diff --git a/pkg/store/instance.go b/pkg/store/instance.go index 6edfc435f05..1a88a8c63f3 100644 --- a/pkg/store/instance.go +++ b/pkg/store/instance.go @@ -59,6 +59,7 @@ type Instance struct { SSHAddress string `json:"sshAddress,omitempty"` Protected bool `json:"protected"` LimaVersion string `json:"limaVersion"` + Param map[string]string `json:"param,omitempty"` } func (inst *Instance) LoadYAML() (*limayaml.LimaYAML, error) { @@ -180,6 +181,7 @@ func Inspect(instName string) (*Instance, error) { } else if !errors.Is(err, os.ErrNotExist) { inst.Errors = append(inst.Errors, err) } + inst.Param = y.Param return inst, nil } diff --git a/pkg/vz/vz_driver_darwin.go b/pkg/vz/vz_driver_darwin.go index 8b0353a06eb..15bba3416c6 100644 --- a/pkg/vz/vz_driver_darwin.go +++ b/pkg/vz/vz_driver_darwin.go @@ -42,6 +42,7 @@ var knownYamlProperties = []string{ "MountInotify", "Networks", "OS", + "Param", "Plain", "PortForwards", "Probes", diff --git a/pkg/wsl2/wsl_driver_windows.go b/pkg/wsl2/wsl_driver_windows.go index 49b9c55a230..6f285e48c7c 100644 --- a/pkg/wsl2/wsl_driver_windows.go +++ b/pkg/wsl2/wsl_driver_windows.go @@ -29,6 +29,7 @@ var knownYamlProperties = []string{ "Message", "Mounts", "MountType", + "Param", "Plain", "PortForwards", "Probes",