Skip to content

Commit fe1af92

Browse files
committed
opts: MountOpt: improve validation of boolean values
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 5de99e6 commit fe1af92

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

opts/mount.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,8 @@ func (m *MountOpt) Set(value string) error {
9797

9898
if !hasValue {
9999
switch key {
100-
case "readonly", "ro":
101-
mount.ReadOnly = true
102-
continue
103-
case "volume-nocopy":
104-
volumeOptions().NoCopy = true
105-
continue
106-
case "bind-nonrecursive":
107-
return errors.New("bind-nonrecursive is deprecated, use bind-recursive=disabled instead")
100+
case "readonly", "ro", "volume-nocopy", "bind-nonrecursive":
101+
// boolean values
108102
default:
109103
return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
110104
}
@@ -123,9 +117,9 @@ func (m *MountOpt) Set(value string) error {
123117
case "target", "dst", "destination":
124118
mount.Target = val
125119
case "readonly", "ro":
126-
mount.ReadOnly, err = strconv.ParseBool(val)
120+
mount.ReadOnly, err = parseBoolValue(key, val, hasValue)
127121
if err != nil {
128-
return fmt.Errorf("invalid value for %s: %s", key, val)
122+
return err
129123
}
130124
case "consistency":
131125
mount.Consistency = mounttypes.Consistency(strings.ToLower(val))
@@ -151,9 +145,9 @@ func (m *MountOpt) Set(value string) error {
151145
case "volume-subpath":
152146
volumeOptions().Subpath = val
153147
case "volume-nocopy":
154-
volumeOptions().NoCopy, err = strconv.ParseBool(val)
148+
volumeOptions().NoCopy, err = parseBoolValue(key, val, hasValue)
155149
if err != nil {
156-
return fmt.Errorf("invalid value for volume-nocopy: %s", val)
150+
return err
157151
}
158152
case "volume-label":
159153
setValueOnMap(volumeOptions().Labels, val)

opts/mount_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func TestMountOptReadOnly(t *testing.T) {
188188
{value: "readonly", exp: true},
189189
{value: "readonly=", expErr: `invalid value for 'readonly': value is empty`},
190190
{value: "readonly= true", expErr: `invalid value for 'readonly' in 'readonly= true': value should not have whitespace`},
191-
{value: "readonly=no", expErr: `invalid value for readonly: no`},
191+
{value: "readonly=no", expErr: `invalid value for 'readonly': invalid boolean value ("no"): must be one of "true", "1", "false", or "0" (default "true")`},
192192
{value: "readonly=1", exp: true},
193193
{value: "readonly=true", exp: true},
194194
{value: "readonly=0", exp: false},
@@ -232,7 +232,7 @@ func TestMountOptVolumeNoCopy(t *testing.T) {
232232
{value: "volume-nocopy", exp: true},
233233
{value: "volume-nocopy=", expErr: `invalid value for 'volume-nocopy': value is empty`},
234234
{value: "volume-nocopy= true", expErr: `invalid value for 'volume-nocopy' in 'volume-nocopy= true': value should not have whitespace`},
235-
{value: "volume-nocopy=no", expErr: `invalid value for volume-nocopy: no`},
235+
{value: "volume-nocopy=no", expErr: `invalid value for 'volume-nocopy': invalid boolean value ("no"): must be one of "true", "1", "false", or "0" (default "true")`},
236236
{value: "volume-nocopy=1", exp: true},
237237
{value: "volume-nocopy=true", exp: true},
238238
{value: "volume-nocopy=0", exp: false},

opts/mount_utils.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package opts
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
// parseBoolValue returns the boolean value represented by the string. It returns
8+
// true if no value is set.
9+
//
10+
// It is similar to [strconv.ParseBool], but only accepts 1, true, 0, false.
11+
// Any other value returns an error.
12+
func parseBoolValue(key string, val string, hasValue bool) (bool, error) {
13+
if !hasValue {
14+
return true, nil
15+
}
16+
switch val {
17+
case "1", "true":
18+
return true, nil
19+
case "0", "false":
20+
return false, nil
21+
default:
22+
return false, fmt.Errorf(`invalid value for '%s': invalid boolean value (%q): must be one of "true", "1", "false", or "0" (default "true")`, key, val)
23+
}
24+
}

0 commit comments

Comments
 (0)