...
1 package service
2
3 import (
4 "fmt"
5 "strings"
6
7 "github.com/pkg/errors"
8
9 "github.com/docker/docker/api/types/swarm"
10 swarmapi "github.com/moby/swarmkit/v2/api"
11 "github.com/moby/swarmkit/v2/api/genericresource"
12 )
13
14
15
16
17
18
19
20
21
22 func ValidateSingleGenericResource(val string) (string, error) {
23 if strings.Count(val, "=") < 1 {
24 return "", fmt.Errorf("invalid generic-resource format `%s` expected `name=value`", val)
25 }
26
27 return val, nil
28 }
29
30
31
32
33 func ParseGenericResources(value []string) ([]swarm.GenericResource, error) {
34 if len(value) == 0 {
35 return nil, nil
36 }
37
38 resources, err := genericresource.Parse(value)
39 if err != nil {
40 return nil, errors.Wrapf(err, "invalid generic resource specification")
41 }
42
43 swarmResources := genericResourcesFromGRPC(resources)
44 for _, res := range swarmResources {
45 if res.NamedResourceSpec != nil {
46 return nil, fmt.Errorf("invalid generic-resource request `%s=%s`, Named Generic Resources is not supported for service create or update", res.NamedResourceSpec.Kind, res.NamedResourceSpec.Value)
47 }
48 }
49
50 return swarmResources, nil
51 }
52
53
54 func genericResourcesFromGRPC(genericRes []*swarmapi.GenericResource) []swarm.GenericResource {
55 generic := make([]swarm.GenericResource, 0, len(genericRes))
56 for _, res := range genericRes {
57 var current swarm.GenericResource
58
59 switch r := res.Resource.(type) {
60 case *swarmapi.GenericResource_DiscreteResourceSpec:
61 current.DiscreteResourceSpec = &swarm.DiscreteGenericResource{
62 Kind: r.DiscreteResourceSpec.Kind,
63 Value: r.DiscreteResourceSpec.Value,
64 }
65 case *swarmapi.GenericResource_NamedResourceSpec:
66 current.NamedResourceSpec = &swarm.NamedGenericResource{
67 Kind: r.NamedResourceSpec.Kind,
68 Value: r.NamedResourceSpec.Value,
69 }
70 }
71
72 generic = append(generic, current)
73 }
74
75 return generic
76 }
77
78 func buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swarm.GenericResource, error) {
79 m := make(map[string]swarm.GenericResource)
80
81 for _, res := range genericRes {
82 if res.DiscreteResourceSpec == nil {
83 return nil, fmt.Errorf("invalid generic-resource `%+v` for service task", res)
84 }
85
86 _, ok := m[res.DiscreteResourceSpec.Kind]
87 if ok {
88 return nil, fmt.Errorf("duplicate generic-resource `%+v` for service task", res.DiscreteResourceSpec.Kind)
89 }
90
91 m[res.DiscreteResourceSpec.Kind] = res
92 }
93
94 return m, nil
95 }
96
97 func buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource {
98 l := make([]swarm.GenericResource, 0, len(genericRes))
99
100 for _, res := range genericRes {
101 l = append(l, res)
102 }
103
104 return l
105 }
106
View as plain text