Browse code

Move internal/opts to daemon/internal/opts

Signed-off-by: Derek McGowan <derek@mcg.dev>

Derek McGowan authored on 2025/07/25 04:14:14
Showing 11 changed files
... ...
@@ -4,9 +4,9 @@ import (
4 4
 	"runtime"
5 5
 
6 6
 	"github.com/docker/docker/daemon/config"
7
+	dopts "github.com/docker/docker/daemon/internal/opts"
7 8
 	"github.com/docker/docker/daemon/pkg/opts"
8 9
 	"github.com/docker/docker/daemon/pkg/registry"
9
-	dopts "github.com/docker/docker/internal/opts"
10 10
 	"github.com/spf13/pflag"
11 11
 )
12 12
 
... ...
@@ -13,9 +13,9 @@ import (
13 13
 
14 14
 	"dario.cat/mergo"
15 15
 	"github.com/containerd/log"
16
+	dopts "github.com/docker/docker/daemon/internal/opts"
16 17
 	"github.com/docker/docker/daemon/pkg/opts"
17 18
 	"github.com/docker/docker/daemon/pkg/registry"
18
-	dopts "github.com/docker/docker/internal/opts"
19 19
 	"github.com/moby/moby/api"
20 20
 	"github.com/moby/moby/api/types/versions"
21 21
 	"github.com/pkg/errors"
... ...
@@ -4,8 +4,8 @@ import (
4 4
 	"net/netip"
5 5
 	"testing"
6 6
 
7
+	dopts "github.com/docker/docker/daemon/internal/opts"
7 8
 	"github.com/docker/docker/daemon/pkg/opts"
8
-	dopts "github.com/docker/docker/internal/opts"
9 9
 	"github.com/google/go-cmp/cmp/cmpopts"
10 10
 	"github.com/moby/moby/api/types/container"
11 11
 	"github.com/spf13/pflag"
12 12
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+package opts
1
+
2
+import (
3
+	"errors"
4
+	"net/netip"
5
+)
6
+
7
+// ValidateHostGatewayIPs makes sure the addresses are valid, and there's at-most one IPv4 and one IPv6 address.
8
+func ValidateHostGatewayIPs(hostGatewayIPs []netip.Addr) error {
9
+	var have4, have6 bool
10
+	for _, ip := range hostGatewayIPs {
11
+		if ip.Is4() {
12
+			if have4 {
13
+				return errors.New("only one IPv4 host gateway IP address can be specified")
14
+			}
15
+			have4 = true
16
+		} else {
17
+			if have6 {
18
+				return errors.New("only one IPv6 host gateway IP address can be specified")
19
+			}
20
+			have6 = true
21
+		}
22
+	}
23
+	return nil
24
+}
0 25
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+package opts
1
+
2
+import (
3
+	"fmt"
4
+	"net/netip"
5
+)
6
+
7
+// NamedIPListOpts appends to an underlying []netip.Addr.
8
+type NamedIPListOpts struct {
9
+	name string
10
+	ips  *[]netip.Addr
11
+}
12
+
13
+// NewNamedIPListOptsRef constructs a NamedIPListOpts and returns its address.
14
+func NewNamedIPListOptsRef(name string, values *[]netip.Addr) *NamedIPListOpts {
15
+	return &NamedIPListOpts{
16
+		name: name,
17
+		ips:  values,
18
+	}
19
+}
20
+
21
+// String returns a string representation of the addresses in the underlying []netip.Addr.
22
+func (o *NamedIPListOpts) String() string {
23
+	if len(*o.ips) == 0 {
24
+		return ""
25
+	}
26
+	return fmt.Sprintf("%v", *o.ips)
27
+}
28
+
29
+// Set converts value to a netip.Addr and appends it to the underlying []netip.Addr.
30
+func (o *NamedIPListOpts) Set(value string) error {
31
+	ip, err := netip.ParseAddr(value)
32
+	if err != nil {
33
+		return err
34
+	}
35
+	*o.ips = append(*o.ips, ip)
36
+	return nil
37
+}
38
+
39
+// Type returns a string name for this Option type
40
+func (o *NamedIPListOpts) Type() string {
41
+	return "list"
42
+}
43
+
44
+// Name returns the name of the NamedIPListOpts in the configuration.
45
+func (o *NamedIPListOpts) Name() string {
46
+	return o.name
47
+}
0 48
new file mode 100644
... ...
@@ -0,0 +1,83 @@
0
+package opts
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+	"strconv"
6
+	"strings"
7
+
8
+	"github.com/docker/docker/daemon/pkg/opts"
9
+)
10
+
11
+// SetOpts holds a map of values and a validation function.
12
+type SetOpts struct {
13
+	values map[string]bool
14
+}
15
+
16
+// Set validates if needed the input value and add it to the
17
+// internal map, by splitting on '='.
18
+func (opts *SetOpts) Set(value string) error {
19
+	k, v, found := strings.Cut(value, "=")
20
+	if k == "" {
21
+		return errors.New("invalid option name: " + value)
22
+	}
23
+	var isSet bool
24
+	if !found {
25
+		isSet = true
26
+	} else {
27
+		var err error
28
+		isSet, err = strconv.ParseBool(v)
29
+		if err != nil {
30
+			return err
31
+		}
32
+	}
33
+	opts.values[k] = isSet
34
+	return nil
35
+}
36
+
37
+// GetAll returns the values of SetOpts as a map.
38
+func (opts *SetOpts) GetAll() map[string]bool {
39
+	return opts.values
40
+}
41
+
42
+func (opts *SetOpts) String() string {
43
+	return fmt.Sprintf("%v", opts.values)
44
+}
45
+
46
+// Type returns a string name for this Option type
47
+func (opts *SetOpts) Type() string {
48
+	return "map"
49
+}
50
+
51
+// NewSetOpts creates a new SetOpts with the specified set of values as a map of string to bool.
52
+func NewSetOpts(values map[string]bool) *SetOpts {
53
+	if values == nil {
54
+		values = make(map[string]bool)
55
+	}
56
+	return &SetOpts{
57
+		values: values,
58
+	}
59
+}
60
+
61
+// NamedSetOpts is a SetOpts struct with a configuration name.
62
+// This struct is useful to keep reference to the assigned
63
+// field name in the internal configuration struct.
64
+type NamedSetOpts struct {
65
+	SetOpts
66
+	name string
67
+}
68
+
69
+var _ opts.NamedOption = &NamedSetOpts{}
70
+
71
+// NewNamedSetOpts creates a reference to a new NamedSetOpts struct.
72
+func NewNamedSetOpts(name string, values map[string]bool) *NamedSetOpts {
73
+	return &NamedSetOpts{
74
+		SetOpts: *NewSetOpts(values),
75
+		name:    name,
76
+	}
77
+}
78
+
79
+// Name returns the name of the NamedSetOpts in the configuration.
80
+func (o *NamedSetOpts) Name() string {
81
+	return o.name
82
+}
0 83
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+package opts
1
+
2
+import (
3
+	"testing"
4
+
5
+	"gotest.tools/v3/assert"
6
+	is "gotest.tools/v3/assert/cmp"
7
+)
8
+
9
+func TestSetOpts(t *testing.T) {
10
+	tmpMap := make(map[string]bool)
11
+	o := NewSetOpts(tmpMap)
12
+	assert.NilError(t, o.Set("feature-a=1"))
13
+	assert.NilError(t, o.Set("feature-b=true"))
14
+	assert.NilError(t, o.Set("feature-c=0"))
15
+	assert.NilError(t, o.Set("feature-d=false"))
16
+	assert.NilError(t, o.Set("feature-e"))
17
+
18
+	expected := "map[feature-a:true feature-b:true feature-c:false feature-d:false feature-e:true]"
19
+	assert.Check(t, is.Equal(expected, o.String()))
20
+
21
+	expectedValue := map[string]bool{"feature-a": true, "feature-b": true, "feature-c": false, "feature-d": false, "feature-e": true}
22
+	assert.Check(t, is.DeepEqual(expectedValue, o.GetAll()))
23
+
24
+	err := o.Set("feature=not-a-bool")
25
+	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "not-a-bool": invalid syntax`))
26
+	err = o.Set("feature=")
27
+	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "": invalid syntax`))
28
+	err = o.Set("=true")
29
+	assert.Check(t, is.Error(err, `invalid option name: =true`))
30
+}
31
+
32
+func TestNamedSetOpts(t *testing.T) {
33
+	tmpMap := make(map[string]bool)
34
+	o := NewNamedSetOpts("features", tmpMap)
35
+	assert.Check(t, is.Equal("features", o.Name()))
36
+
37
+	assert.NilError(t, o.Set("feature-a=1"))
38
+	assert.NilError(t, o.Set("feature-b=true"))
39
+	assert.NilError(t, o.Set("feature-c=0"))
40
+	assert.NilError(t, o.Set("feature-d=false"))
41
+	assert.NilError(t, o.Set("feature-e"))
42
+
43
+	expected := "map[feature-a:true feature-b:true feature-c:false feature-d:false feature-e:true]"
44
+	assert.Check(t, is.Equal(expected, o.String()))
45
+
46
+	expectedValue := map[string]bool{"feature-a": true, "feature-b": true, "feature-c": false, "feature-d": false, "feature-e": true}
47
+	assert.Check(t, is.DeepEqual(expectedValue, o.GetAll()))
48
+
49
+	err := o.Set("feature=not-a-bool")
50
+	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "not-a-bool": invalid syntax`))
51
+	err = o.Set("feature=")
52
+	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "": invalid syntax`))
53
+	err = o.Set("=true")
54
+	assert.Check(t, is.Error(err, `invalid option name: =true`))
55
+}
0 56
deleted file mode 100644
... ...
@@ -1,25 +0,0 @@
1
-package opts
2
-
3
-import (
4
-	"errors"
5
-	"net/netip"
6
-)
7
-
8
-// ValidateHostGatewayIPs makes sure the addresses are valid, and there's at-most one IPv4 and one IPv6 address.
9
-func ValidateHostGatewayIPs(hostGatewayIPs []netip.Addr) error {
10
-	var have4, have6 bool
11
-	for _, ip := range hostGatewayIPs {
12
-		if ip.Is4() {
13
-			if have4 {
14
-				return errors.New("only one IPv4 host gateway IP address can be specified")
15
-			}
16
-			have4 = true
17
-		} else {
18
-			if have6 {
19
-				return errors.New("only one IPv6 host gateway IP address can be specified")
20
-			}
21
-			have6 = true
22
-		}
23
-	}
24
-	return nil
25
-}
26 1
deleted file mode 100644
... ...
@@ -1,48 +0,0 @@
1
-package opts
2
-
3
-import (
4
-	"fmt"
5
-	"net/netip"
6
-)
7
-
8
-// NamedIPListOpts appends to an underlying []netip.Addr.
9
-type NamedIPListOpts struct {
10
-	name string
11
-	ips  *[]netip.Addr
12
-}
13
-
14
-// NewNamedIPListOptsRef constructs a NamedIPListOpts and returns its address.
15
-func NewNamedIPListOptsRef(name string, values *[]netip.Addr) *NamedIPListOpts {
16
-	return &NamedIPListOpts{
17
-		name: name,
18
-		ips:  values,
19
-	}
20
-}
21
-
22
-// String returns a string representation of the addresses in the underlying []netip.Addr.
23
-func (o *NamedIPListOpts) String() string {
24
-	if len(*o.ips) == 0 {
25
-		return ""
26
-	}
27
-	return fmt.Sprintf("%v", *o.ips)
28
-}
29
-
30
-// Set converts value to a netip.Addr and appends it to the underlying []netip.Addr.
31
-func (o *NamedIPListOpts) Set(value string) error {
32
-	ip, err := netip.ParseAddr(value)
33
-	if err != nil {
34
-		return err
35
-	}
36
-	*o.ips = append(*o.ips, ip)
37
-	return nil
38
-}
39
-
40
-// Type returns a string name for this Option type
41
-func (o *NamedIPListOpts) Type() string {
42
-	return "list"
43
-}
44
-
45
-// Name returns the name of the NamedIPListOpts in the configuration.
46
-func (o *NamedIPListOpts) Name() string {
47
-	return o.name
48
-}
49 1
deleted file mode 100644
... ...
@@ -1,83 +0,0 @@
1
-package opts
2
-
3
-import (
4
-	"errors"
5
-	"fmt"
6
-	"strconv"
7
-	"strings"
8
-
9
-	"github.com/docker/docker/daemon/pkg/opts"
10
-)
11
-
12
-// SetOpts holds a map of values and a validation function.
13
-type SetOpts struct {
14
-	values map[string]bool
15
-}
16
-
17
-// Set validates if needed the input value and add it to the
18
-// internal map, by splitting on '='.
19
-func (opts *SetOpts) Set(value string) error {
20
-	k, v, found := strings.Cut(value, "=")
21
-	if k == "" {
22
-		return errors.New("invalid option name: " + value)
23
-	}
24
-	var isSet bool
25
-	if !found {
26
-		isSet = true
27
-	} else {
28
-		var err error
29
-		isSet, err = strconv.ParseBool(v)
30
-		if err != nil {
31
-			return err
32
-		}
33
-	}
34
-	opts.values[k] = isSet
35
-	return nil
36
-}
37
-
38
-// GetAll returns the values of SetOpts as a map.
39
-func (opts *SetOpts) GetAll() map[string]bool {
40
-	return opts.values
41
-}
42
-
43
-func (opts *SetOpts) String() string {
44
-	return fmt.Sprintf("%v", opts.values)
45
-}
46
-
47
-// Type returns a string name for this Option type
48
-func (opts *SetOpts) Type() string {
49
-	return "map"
50
-}
51
-
52
-// NewSetOpts creates a new SetOpts with the specified set of values as a map of string to bool.
53
-func NewSetOpts(values map[string]bool) *SetOpts {
54
-	if values == nil {
55
-		values = make(map[string]bool)
56
-	}
57
-	return &SetOpts{
58
-		values: values,
59
-	}
60
-}
61
-
62
-// NamedSetOpts is a SetOpts struct with a configuration name.
63
-// This struct is useful to keep reference to the assigned
64
-// field name in the internal configuration struct.
65
-type NamedSetOpts struct {
66
-	SetOpts
67
-	name string
68
-}
69
-
70
-var _ opts.NamedOption = &NamedSetOpts{}
71
-
72
-// NewNamedSetOpts creates a reference to a new NamedSetOpts struct.
73
-func NewNamedSetOpts(name string, values map[string]bool) *NamedSetOpts {
74
-	return &NamedSetOpts{
75
-		SetOpts: *NewSetOpts(values),
76
-		name:    name,
77
-	}
78
-}
79
-
80
-// Name returns the name of the NamedSetOpts in the configuration.
81
-func (o *NamedSetOpts) Name() string {
82
-	return o.name
83
-}
84 1
deleted file mode 100644
... ...
@@ -1,56 +0,0 @@
1
-package opts
2
-
3
-import (
4
-	"testing"
5
-
6
-	"gotest.tools/v3/assert"
7
-	is "gotest.tools/v3/assert/cmp"
8
-)
9
-
10
-func TestSetOpts(t *testing.T) {
11
-	tmpMap := make(map[string]bool)
12
-	o := NewSetOpts(tmpMap)
13
-	assert.NilError(t, o.Set("feature-a=1"))
14
-	assert.NilError(t, o.Set("feature-b=true"))
15
-	assert.NilError(t, o.Set("feature-c=0"))
16
-	assert.NilError(t, o.Set("feature-d=false"))
17
-	assert.NilError(t, o.Set("feature-e"))
18
-
19
-	expected := "map[feature-a:true feature-b:true feature-c:false feature-d:false feature-e:true]"
20
-	assert.Check(t, is.Equal(expected, o.String()))
21
-
22
-	expectedValue := map[string]bool{"feature-a": true, "feature-b": true, "feature-c": false, "feature-d": false, "feature-e": true}
23
-	assert.Check(t, is.DeepEqual(expectedValue, o.GetAll()))
24
-
25
-	err := o.Set("feature=not-a-bool")
26
-	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "not-a-bool": invalid syntax`))
27
-	err = o.Set("feature=")
28
-	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "": invalid syntax`))
29
-	err = o.Set("=true")
30
-	assert.Check(t, is.Error(err, `invalid option name: =true`))
31
-}
32
-
33
-func TestNamedSetOpts(t *testing.T) {
34
-	tmpMap := make(map[string]bool)
35
-	o := NewNamedSetOpts("features", tmpMap)
36
-	assert.Check(t, is.Equal("features", o.Name()))
37
-
38
-	assert.NilError(t, o.Set("feature-a=1"))
39
-	assert.NilError(t, o.Set("feature-b=true"))
40
-	assert.NilError(t, o.Set("feature-c=0"))
41
-	assert.NilError(t, o.Set("feature-d=false"))
42
-	assert.NilError(t, o.Set("feature-e"))
43
-
44
-	expected := "map[feature-a:true feature-b:true feature-c:false feature-d:false feature-e:true]"
45
-	assert.Check(t, is.Equal(expected, o.String()))
46
-
47
-	expectedValue := map[string]bool{"feature-a": true, "feature-b": true, "feature-c": false, "feature-d": false, "feature-e": true}
48
-	assert.Check(t, is.DeepEqual(expectedValue, o.GetAll()))
49
-
50
-	err := o.Set("feature=not-a-bool")
51
-	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "not-a-bool": invalid syntax`))
52
-	err = o.Set("feature=")
53
-	assert.Check(t, is.Error(err, `strconv.ParseBool: parsing "": invalid syntax`))
54
-	err = o.Set("=true")
55
-	assert.Check(t, is.Error(err, `invalid option name: =true`))
56
-}