...
1 package opts
2
3 import (
4 "encoding/csv"
5 "fmt"
6 "os"
7 "strconv"
8 "strings"
9
10 swarmtypes "github.com/docker/docker/api/types/swarm"
11 )
12
13
14 type ConfigOpt struct {
15 values []*swarmtypes.ConfigReference
16 }
17
18
19 func (o *ConfigOpt) Set(value string) error {
20 csvReader := csv.NewReader(strings.NewReader(value))
21 fields, err := csvReader.Read()
22 if err != nil {
23 return err
24 }
25
26 options := &swarmtypes.ConfigReference{
27 File: &swarmtypes.ConfigReferenceFileTarget{
28 UID: "0",
29 GID: "0",
30 Mode: 0o444,
31 },
32 }
33
34
35 if len(fields) == 1 && !strings.Contains(fields[0], "=") {
36 options.File.Name = fields[0]
37 options.ConfigName = fields[0]
38 o.values = append(o.values, options)
39 return nil
40 }
41
42 for _, field := range fields {
43 key, val, ok := strings.Cut(field, "=")
44 if !ok || key == "" {
45 return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
46 }
47
48
49 switch strings.ToLower(key) {
50 case "source", "src":
51 options.ConfigName = val
52 case "target":
53 options.File.Name = val
54 case "uid":
55 options.File.UID = val
56 case "gid":
57 options.File.GID = val
58 case "mode":
59 m, err := strconv.ParseUint(val, 0, 32)
60 if err != nil {
61 return fmt.Errorf("invalid mode specified: %v", err)
62 }
63
64 options.File.Mode = os.FileMode(m)
65 default:
66 return fmt.Errorf("invalid field in config request: %s", key)
67 }
68 }
69
70 if options.ConfigName == "" {
71 return fmt.Errorf("source is required")
72 }
73 if options.File.Name == "" {
74 options.File.Name = options.ConfigName
75 }
76
77 o.values = append(o.values, options)
78 return nil
79 }
80
81
82 func (o *ConfigOpt) Type() string {
83 return "config"
84 }
85
86
87 func (o *ConfigOpt) String() string {
88 configs := []string{}
89 for _, config := range o.values {
90 repr := fmt.Sprintf("%s -> %s", config.ConfigName, config.File.Name)
91 configs = append(configs, repr)
92 }
93 return strings.Join(configs, ", ")
94 }
95
96
97 func (o *ConfigOpt) Value() []*swarmtypes.ConfigReference {
98 return o.values
99 }
100
View as plain text