@@ -66,7 +66,7 @@ func RegisterEdit(cmd *cobra.Command, commentPrefix string) {
6666
6767 flags .Bool ("rosetta" , false , commentPrefix + "Enable Rosetta (for vz instances)" )
6868
69- flags .String ("set" , "" , commentPrefix + "Modify the template inplace, using yq syntax" )
69+ flags .StringArray ("set" , [] string {} , commentPrefix + "Modify the template inplace, using yq syntax. Can be passed multiple times. " )
7070
7171 flags .Uint16 ("ssh-port" , 0 , commentPrefix + "SSH port (0 for random)" ) // colima-compatible
7272 _ = cmd .RegisterFlagCompletionFunc ("ssh-port" , func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
@@ -115,9 +115,9 @@ func RegisterCreate(cmd *cobra.Command, commentPrefix string) {
115115 })
116116}
117117
118- func defaultExprFunc (expr string ) func (v * flag.Flag ) (string , error ) {
119- return func (v * flag.Flag ) (string , error ) {
120- return fmt .Sprintf (expr , v .Value ), nil
118+ func defaultExprFunc (expr string ) func (v * flag.Flag ) ([] string , error ) {
119+ return func (v * flag.Flag ) ([] string , error ) {
120+ return [] string { fmt .Sprintf (expr , v .Value )} , nil
121121 }
122122}
123123
@@ -193,7 +193,7 @@ func buildMountListExpression(ss []string) (string, error) {
193193func YQExpressions (flags * flag.FlagSet , newInstance bool ) ([]string , error ) {
194194 type def struct {
195195 flagName string
196- exprFunc func (* flag.Flag ) (string , error )
196+ exprFunc func (* flag.Flag ) ([] string , error )
197197 onlyValidForNewInstances bool
198198 experimental bool
199199 }
@@ -202,10 +202,10 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
202202 {"cpus" , d (".cpus = %s" ), false , false },
203203 {
204204 "dns" ,
205- func (_ * flag.Flag ) (string , error ) {
205+ func (_ * flag.Flag ) ([] string , error ) {
206206 ipSlice , err := flags .GetIPSlice ("dns" )
207207 if err != nil {
208- return "" , err
208+ return nil , err
209209 }
210210 expr := `.dns += [`
211211 for i , ip := range ipSlice {
@@ -216,69 +216,69 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
216216 }
217217 expr += `] | .dns |= unique | .hostResolver.enabled=false`
218218 logrus .Warnf ("Disabling HostResolver, as custom DNS addresses (%v) are specified" , ipSlice )
219- return expr , nil
219+ return [] string { expr } , nil
220220 },
221221 false ,
222222 false ,
223223 },
224224 {"memory" , d (".memory = \" %sGiB\" " ), false , false },
225225 {
226226 "mount" ,
227- func (_ * flag.Flag ) (string , error ) {
227+ func (_ * flag.Flag ) ([] string , error ) {
228228 ss , err := flags .GetStringSlice ("mount" )
229229 slices .Reverse (ss )
230230 if err != nil {
231- return "" , err
231+ return nil , err
232232 }
233233 mountListExpr , err := buildMountListExpression (ss )
234234 if err != nil {
235- return "" , err
235+ return nil , err
236236 }
237237 // mount options take precedence over template settings
238238 expr := fmt .Sprintf (".mounts = %s + .mounts" , mountListExpr )
239239 mountOnly , err := flags .GetStringSlice ("mount-only" )
240240 if err != nil {
241- return "" , err
241+ return nil , err
242242 }
243243 if len (mountOnly ) > 0 {
244- return "" , errors .New ("flag `--mount` conflicts with `--mount-only`" )
244+ return nil , errors .New ("flag `--mount` conflicts with `--mount-only`" )
245245 }
246- return expr , nil
246+ return [] string { expr } , nil
247247 },
248248 false ,
249249 false ,
250250 },
251251 {
252252 "mount-only" ,
253- func (_ * flag.Flag ) (string , error ) {
253+ func (_ * flag.Flag ) ([] string , error ) {
254254 ss , err := flags .GetStringSlice ("mount-only" )
255255 if err != nil {
256- return "" , err
256+ return nil , err
257257 }
258258 mountListExpr , err := buildMountListExpression (ss )
259259 if err != nil {
260- return "" , err
260+ return nil , err
261261 }
262262 expr := `.mounts = ` + mountListExpr
263- return expr , nil
263+ return [] string { expr } , nil
264264 },
265265 false ,
266266 false ,
267267 },
268268 {
269269 "mount-none" ,
270- func (_ * flag.Flag ) (string , error ) {
270+ func (_ * flag.Flag ) ([] string , error ) {
271271 incompatibleFlagNames := []string {"mount" , "mount-only" }
272272 for _ , name := range incompatibleFlagNames {
273273 ss , err := flags .GetStringSlice (name )
274274 if err != nil {
275- return "" , err
275+ return nil , err
276276 }
277277 if len (ss ) > 0 {
278- return "" , errors .New ("flag `--mount-none` conflicts with `" + name + "`" )
278+ return nil , errors .New ("flag `--mount-none` conflicts with `" + name + "`" )
279279 }
280280 }
281- return ".mounts = null" , nil
281+ return [] string { ".mounts = null" } , nil
282282 },
283283 false ,
284284 false ,
@@ -289,10 +289,10 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
289289 {"mount-writable" , d (".mounts[].writable = %s" ), false , false },
290290 {
291291 "network" ,
292- func (_ * flag.Flag ) (string , error ) {
292+ func (_ * flag.Flag ) ([] string , error ) {
293293 ss , err := flags .GetStringSlice ("network" )
294294 if err != nil {
295- return "" , err
295+ return nil , err
296296 }
297297 expr := `.networks += [`
298298 for i , s := range ss {
@@ -304,43 +304,45 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
304304 network := strings .TrimPrefix (s , "lima:" )
305305 expr += fmt .Sprintf (`{"lima": %q}` , network )
306306 default :
307- return "" , fmt .Errorf ("network name must be \" vzNAT\" or \" lima:*\" , got %q" , s )
307+ return nil , fmt .Errorf ("network name must be \" vzNAT\" or \" lima:*\" , got %q" , s )
308308 }
309309 if i < len (ss )- 1 {
310310 expr += ","
311311 }
312312 }
313313 expr += `] | .networks |= unique_by(.lima)`
314- return expr , nil
314+ return [] string { expr } , nil
315315 },
316316 false ,
317317 false ,
318318 },
319319
320320 {
321321 "rosetta" ,
322- func (_ * flag.Flag ) (string , error ) {
322+ func (_ * flag.Flag ) ([] string , error ) {
323323 b , err := flags .GetBool ("rosetta" )
324324 if err != nil {
325- return "" , err
325+ return nil , err
326326 }
327- return fmt .Sprintf (".vmOpts.vz.rosetta.enabled = %v | .vmOpts.vz.rosetta.binfmt = %v" , b , b ), nil
327+ return [] string { fmt .Sprintf (".vmOpts.vz.rosetta.enabled = %v | .vmOpts.vz.rosetta.binfmt = %v" , b , b )} , nil
328328 },
329329 false ,
330330 false ,
331331 },
332- {"set" , d ("%s" ), false , false },
332+ {"set" , func (v * flag.Flag ) ([]string , error ) {
333+ return v .Value .(flag.SliceValue ).GetSlice (), nil
334+ }, false , false },
333335 {
334336 "video" ,
335- func (_ * flag.Flag ) (string , error ) {
337+ func (_ * flag.Flag ) ([] string , error ) {
336338 b , err := flags .GetBool ("video" )
337339 if err != nil {
338- return "" , err
340+ return nil , err
339341 }
340342 if b {
341- return ".video.display = \" default\" " , nil
343+ return [] string { ".video.display = \" default\" " } , nil
342344 }
343- return ".video.display = \" none\" " , nil
345+ return [] string { ".video.display = \" none\" " } , nil
344346 },
345347 false ,
346348 false ,
@@ -349,22 +351,22 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
349351 {"arch" , d (".arch = %q" ), true , false },
350352 {
351353 "containerd" ,
352- func (_ * flag.Flag ) (string , error ) {
354+ func (_ * flag.Flag ) ([] string , error ) {
353355 s , err := flags .GetString ("containerd" )
354356 if err != nil {
355- return "" , err
357+ return nil , err
356358 }
357359 switch s {
358360 case "user" :
359- return `.containerd.user = true | .containerd.system = false` , nil
361+ return [] string { `.containerd.user = true | .containerd.system = false` } , nil
360362 case "system" :
361- return `.containerd.user = false | .containerd.system = true` , nil
363+ return [] string { `.containerd.user = false | .containerd.system = true` } , nil
362364 case "user+system" , "system+user" :
363- return `.containerd.user = true | .containerd.system = true` , nil
365+ return [] string { `.containerd.user = true | .containerd.system = true` } , nil
364366 case "none" :
365- return `.containerd.user = false | .containerd.system = false` , nil
367+ return [] string { `.containerd.user = false | .containerd.system = false` } , nil
366368 default :
367- return "" , fmt .Errorf (`expected one of ["user", "system", "user+system", "none"], got %q` , s )
369+ return nil , fmt .Errorf (`expected one of ["user", "system", "user+system", "none"], got %q` , s )
368370 }
369371 },
370372 true ,
@@ -374,12 +376,16 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
374376 {"plain" , d (".plain = %s" ), true , false },
375377 {
376378 "port-forward" ,
377- func (_ * flag.Flag ) (string , error ) {
379+ func (_ * flag.Flag ) ([] string , error ) {
378380 ss , err := flags .GetStringArray ("port-forward" )
379381 if err != nil {
380- return "" , err
382+ return nil , err
381383 }
382- return BuildPortForwardExpression (ss )
384+ value , err := BuildPortForwardExpression (ss )
385+ if err != nil {
386+ return nil , err
387+ }
388+ return []string {value }, nil
383389 },
384390 false ,
385391 false ,
@@ -397,11 +403,11 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
397403 def .flagName , def .flagName , v .Value .String ())
398404 continue
399405 }
400- expr , err := def .exprFunc (v )
406+ newExprs , err := def .exprFunc (v )
401407 if err != nil {
402408 return exprs , fmt .Errorf ("error while processing flag %q: %w" , def .flagName , err )
403409 }
404- exprs = append (exprs , expr )
410+ exprs = append (exprs , newExprs ... )
405411 }
406412 }
407413 return exprs , nil
0 commit comments