Skip to content

Commit e963c32

Browse files
authored
Merge pull request #3947 from AkihiroSuda/mount-only
editflags: add `--mount-only` flag
2 parents 8a4fcf0 + 2637311 commit e963c32

File tree

2 files changed

+95
-13
lines changed

2 files changed

+95
-13
lines changed

cmd/limactl/editflags/editflags.go

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ func RegisterEdit(cmd *cobra.Command, commentPrefix string) {
4444
})
4545

4646
flags.StringSlice("mount", nil, commentPrefix+"Directories to mount, suffix ':w' for writable (Do not specify directories that overlap with the existing mounts)") // colima-compatible
47+
flags.StringSlice("mount-only", nil, commentPrefix+"Similar to --mount, but overrides the existing mounts")
48+
4749
flags.Bool("mount-none", false, commentPrefix+"Remove all mounts")
4850

4951
flags.String("mount-type", "", commentPrefix+"Mount type (reverse-sshfs, 9p, virtiofs)") // Similar to colima's --mount-type=(sshfs|9p|virtiofs), but "reverse-sshfs" is Lima is called "sshfs" in colima
@@ -167,6 +169,20 @@ func BuildPortForwardExpression(portForwards []string) (string, error) {
167169
return expr, nil
168170
}
169171

172+
func buildMountListExpression(ss []string) (string, error) {
173+
expr := `[`
174+
for i, s := range ss {
175+
writable := strings.HasSuffix(s, ":w")
176+
loc := strings.TrimSuffix(s, ":w")
177+
expr += fmt.Sprintf(`{"location": %q, "writable": %v}`, loc, writable)
178+
if i < len(ss)-1 {
179+
expr += ","
180+
}
181+
}
182+
expr += `]`
183+
return expr, nil
184+
}
185+
170186
// YQExpressions returns YQ expressions.
171187
func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
172188
type def struct {
@@ -207,30 +223,52 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) {
207223
if err != nil {
208224
return "", err
209225
}
210-
expr := `.mounts += [`
211-
for i, s := range ss {
212-
writable := strings.HasSuffix(s, ":w")
213-
loc := strings.TrimSuffix(s, ":w")
214-
expr += fmt.Sprintf(`{"location": %q, "writable": %v}`, loc, writable)
215-
if i < len(ss)-1 {
216-
expr += ","
217-
}
226+
mountListExpr, err := buildMountListExpression(ss)
227+
if err != nil {
228+
return "", err
229+
}
230+
expr := `.mounts += ` + mountListExpr + ` | .mounts |= unique_by(.location)`
231+
mountOnly, err := flags.GetStringSlice("mount-only")
232+
if err != nil {
233+
return "", err
234+
}
235+
if len(mountOnly) > 0 {
236+
return "", errors.New("flag `--mount` conflicts with `--mount-only`")
218237
}
219-
expr += `] | .mounts |= unique_by(.location)`
220238
return expr, nil
221239
},
222240
false,
223241
false,
224242
},
225243
{
226-
"mount-none",
244+
"mount-only",
227245
func(_ *flag.Flag) (string, error) {
228-
ss, err := flags.GetStringSlice("mount")
246+
ss, err := flags.GetStringSlice("mount-only")
247+
if err != nil {
248+
return "", err
249+
}
250+
mountListExpr, err := buildMountListExpression(ss)
229251
if err != nil {
230252
return "", err
231253
}
232-
if len(ss) > 0 {
233-
return "", errors.New("flag `--mount-none` conflicts with `--mount`")
254+
expr := `.mounts = ` + mountListExpr
255+
return expr, nil
256+
},
257+
false,
258+
false,
259+
},
260+
{
261+
"mount-none",
262+
func(_ *flag.Flag) (string, error) {
263+
incompatibleFlagNames := []string{"mount", "mount-only"}
264+
for _, name := range incompatibleFlagNames {
265+
ss, err := flags.GetStringSlice(name)
266+
if err != nil {
267+
return "", err
268+
}
269+
if len(ss) > 0 {
270+
return "", errors.New("flag `--mount-none` conflicts with `" + name + "`")
271+
}
234272
}
235273
return ".mounts = null", nil
236274
},

cmd/limactl/editflags/editflags_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package editflags
66
import (
77
"testing"
88

9+
"github.com/spf13/cobra"
910
"gotest.tools/v3/assert"
1011
)
1112

@@ -157,3 +158,46 @@ func TestParsePortForward(t *testing.T) {
157158
})
158159
}
159160
}
161+
162+
func TestYQExpressions(t *testing.T) {
163+
tests := []struct {
164+
name string
165+
args []string
166+
newInstance bool
167+
expected []string
168+
expectError string
169+
}{
170+
{
171+
name: "mount",
172+
args: []string{"--mount", "/foo", "--mount", "/bar:w"},
173+
newInstance: false,
174+
expected: []string{`.mounts += [{"location": "/foo", "writable": false},{"location": "/bar", "writable": true}] | .mounts |= unique_by(.location)`},
175+
},
176+
{
177+
name: "mount-only",
178+
args: []string{"--mount-only", "/foo", "--mount-only", "/bar:w"},
179+
newInstance: false,
180+
expected: []string{`.mounts = [{"location": "/foo", "writable": false},{"location": "/bar", "writable": true}]`},
181+
},
182+
{
183+
name: "mixture of mount and mount-only",
184+
args: []string{"--mount", "/foo", "--mount-only", "/bar:w"},
185+
newInstance: false,
186+
expectError: "flag `--mount` conflicts with `--mount-only`",
187+
},
188+
}
189+
for _, tt := range tests {
190+
t.Run(tt.name, func(t *testing.T) {
191+
cmd := &cobra.Command{}
192+
RegisterEdit(cmd, "")
193+
assert.NilError(t, cmd.ParseFlags(tt.args))
194+
expr, err := YQExpressions(cmd.Flags(), tt.newInstance)
195+
if tt.expectError != "" {
196+
assert.ErrorContains(t, err, tt.expectError)
197+
} else {
198+
assert.NilError(t, err)
199+
assert.DeepEqual(t, tt.expected, expr)
200+
}
201+
})
202+
}
203+
}

0 commit comments

Comments
 (0)