Skip to content

Commit f7fd9c3

Browse files
authored
Merge pull request moby#51381 from thaJeztah/simplify_pkg_security
client/pkg/security: simplify
2 parents 0b56248 + 31f7f62 commit f7fd9c3

File tree

2 files changed

+50
-106
lines changed

2 files changed

+50
-106
lines changed
Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package security
22

33
import (
4-
"errors"
5-
"fmt"
64
"strings"
75
)
86

@@ -19,30 +17,24 @@ type KeyValue struct {
1917

2018
// DecodeOptions decodes a security options string slice to a
2119
// type-safe [Option].
22-
func DecodeOptions(opts []string) ([]Option, error) {
23-
so := []Option{}
20+
func DecodeOptions(opts []string) []Option {
21+
so := make([]Option, 0, len(opts))
2422
for _, opt := range opts {
25-
// support output from a < 1.13 docker daemon
26-
if !strings.Contains(opt, "=") {
27-
so = append(so, Option{Name: opt})
28-
continue
29-
}
3023
secopt := Option{}
3124
for _, s := range strings.Split(opt, ",") {
32-
k, v, ok := strings.Cut(s, "=")
33-
if !ok {
34-
return nil, fmt.Errorf("invalid security option %q", s)
35-
}
36-
if k == "" || v == "" {
37-
return nil, errors.New("invalid empty security option")
25+
k, v, _ := strings.Cut(s, "=")
26+
if k == "" {
27+
continue
3828
}
3929
if k == "name" {
4030
secopt.Name = v
4131
continue
4232
}
4333
secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})
4434
}
45-
so = append(so, secopt)
35+
if secopt.Name != "" {
36+
so = append(so, secopt)
37+
}
4638
}
47-
return so, nil
39+
return so
4840
}

client/pkg/security/security_opts_test.go

Lines changed: 41 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import (
1010

1111
func TestDecode(t *testing.T) {
1212
tests := []struct {
13-
name string
14-
opts []string
15-
want []Option
16-
wantErr string
13+
name string
14+
opts []string
15+
want []Option
1716
}{
1817
{
1918
name: "empty options",
@@ -25,13 +24,6 @@ func TestDecode(t *testing.T) {
2524
opts: nil,
2625
want: []Option{},
2726
},
28-
{
29-
name: "legacy format without equals",
30-
opts: []string{"apparmor:unconfined"},
31-
want: []Option{
32-
{Name: "apparmor:unconfined"},
33-
},
34-
},
3527
{
3628
name: "single option with name only",
3729
opts: []string{"name=apparmor"},
@@ -74,74 +66,64 @@ func TestDecode(t *testing.T) {
7466
},
7567
},
7668
{
77-
name: "mixed legacy and new format",
78-
opts: []string{
79-
"label:disable",
80-
"name=apparmor,profile=custom",
81-
},
82-
want: []Option{
83-
{Name: "label:disable"},
84-
{
85-
Name: "apparmor",
86-
Options: []KeyValue{
87-
{Key: "profile", Value: "custom"},
88-
},
89-
},
90-
},
91-
},
92-
{
93-
name: "option without name key",
94-
opts: []string{"profile=custom,type=container_t"},
69+
name: "option with equals in value",
70+
opts: []string{"name=selinux,level=s0:c1=c2"},
9571
want: []Option{
9672
{
73+
Name: "selinux",
9774
Options: []KeyValue{
98-
{Key: "profile", Value: "custom"},
99-
{Key: "type", Value: "container_t"},
75+
{Key: "level", Value: "s0:c1=c2"},
10076
},
10177
},
10278
},
10379
},
10480
{
105-
name: "option with equals in value",
106-
opts: []string{"name=selinux,level=s0:c1=c2"},
81+
name: "invalid option without equals in comma-separated list",
82+
opts: []string{"name=apparmor,invalid"},
10783
want: []Option{
10884
{
109-
Name: "selinux",
85+
Name: "apparmor",
11086
Options: []KeyValue{
111-
{Key: "level", Value: "s0:c1=c2"},
87+
{Key: "invalid"},
11288
},
11389
},
11490
},
11591
},
11692
{
117-
name: "invalid option without equals in comma-separated list",
118-
opts: []string{"name=apparmor,invalid"},
119-
wantErr: `invalid security option "invalid"`,
120-
},
121-
{
122-
name: "empty key",
123-
opts: []string{"=value"},
124-
wantErr: "invalid empty security option",
93+
name: "empty key",
94+
opts: []string{"=value"},
95+
want: []Option{},
12596
},
12697
{
127-
name: "empty value",
128-
opts: []string{"key="},
129-
wantErr: "invalid empty security option",
98+
name: "empty value",
99+
opts: []string{"key="},
100+
want: []Option{},
130101
},
131102
{
132-
name: "empty key and value",
133-
opts: []string{"="},
134-
wantErr: "invalid empty security option",
103+
name: "empty key and value",
104+
opts: []string{"="},
105+
want: []Option{},
135106
},
136107
{
137-
name: "empty key in middle",
138-
opts: []string{"name=apparmor,=value"},
139-
wantErr: "invalid empty security option",
108+
name: "empty key in middle",
109+
opts: []string{"name=apparmor,=value"},
110+
want: []Option{
111+
{
112+
Name: "apparmor",
113+
},
114+
},
140115
},
141116
{
142-
name: "empty value in middle",
143-
opts: []string{"name=apparmor,key="},
144-
wantErr: "invalid empty security option",
117+
name: "empty value in middle",
118+
opts: []string{"name=apparmor,key="},
119+
want: []Option{
120+
{
121+
Name: "apparmor",
122+
Options: []KeyValue{
123+
{Key: "key", Value: ""},
124+
},
125+
},
126+
},
145127
},
146128
{
147129
name: "complex real-world example",
@@ -178,15 +160,8 @@ func TestDecode(t *testing.T) {
178160

179161
for _, tc := range tests {
180162
t.Run(tc.name, func(t *testing.T) {
181-
got, err := DecodeOptions(tc.opts)
182-
183-
if tc.wantErr == "" {
184-
assert.NilError(t, err)
185-
assert.Check(t, cmp.DeepEqual(got, tc.want))
186-
} else {
187-
assert.Check(t, err != nil, "expected error but got none")
188-
assert.ErrorContains(t, err, tc.wantErr)
189-
}
163+
got := DecodeOptions(tc.opts)
164+
assert.Check(t, cmp.DeepEqual(got, tc.want))
190165
})
191166
}
192167
}
@@ -196,31 +171,11 @@ func BenchmarkDecode(b *testing.B) {
196171
"name=selinux,user=system_u,role=system_r,type=container_t,level=s0:c1.c2",
197172
"name=apparmor,profile=/usr/bin/docker",
198173
"name=seccomp,profile=builtin",
199-
"legacy:format",
200-
}
201-
202-
b.ResetTimer()
203-
for i := 0; i < b.N; i++ {
204-
_, err := DecodeOptions(opts)
205-
if err != nil {
206-
b.Fatal(err)
207-
}
208-
}
209-
}
210-
211-
func BenchmarkDecodeLegacy(b *testing.B) {
212-
opts := []string{
213-
"apparmor:unconfined",
214-
"label:disable",
215-
"seccomp:unconfined",
216174
}
217175

218176
b.ResetTimer()
219177
for i := 0; i < b.N; i++ {
220-
_, err := DecodeOptions(opts)
221-
if err != nil {
222-
b.Fatal(err)
223-
}
178+
_ = DecodeOptions(opts)
224179
}
225180
}
226181

@@ -232,9 +187,6 @@ func BenchmarkDecodeComplex(b *testing.B) {
232187

233188
b.ResetTimer()
234189
for i := 0; i < b.N; i++ {
235-
_, err := DecodeOptions(opts)
236-
if err != nil {
237-
b.Fatal(err)
238-
}
190+
_ = DecodeOptions(opts)
239191
}
240192
}

0 commit comments

Comments
 (0)