1 package oci
2
3 import (
4 "context"
5 "errors"
6 "strconv"
7 "strings"
8
9 "github.com/Microsoft/hcsshim/internal/log"
10 "github.com/Microsoft/hcsshim/internal/logfields"
11 "github.com/Microsoft/hcsshim/pkg/annotations"
12 "github.com/opencontainers/runtime-spec/specs-go"
13 "github.com/sirupsen/logrus"
14 )
15
16 var ErrAnnotationExpansionConflict = errors.New("annotation expansion conflict")
17
18
19 func ProcessAnnotations(ctx context.Context, s *specs.Spec) (err error) {
20
21
22
23
24
25
26
27
28
29
30 for key, exps := range annotations.AnnotationExpansions {
31
32 if val, ok := s.Annotations[key]; ok {
33
34
35 for _, k := range exps {
36 if v, ok := s.Annotations[k]; ok && val != v {
37 err = ErrAnnotationExpansionConflict
38 log.G(ctx).WithFields(logrus.Fields{
39 logfields.OCIAnnotation: key,
40 logfields.Value: val,
41 logfields.OCIAnnotation + "-conflict": k,
42 logfields.Value + "-conflict": v,
43 }).WithError(err).Warning("annotation expansion would overwrite conflicting value")
44 continue
45 }
46 s.Annotations[k] = val
47 }
48 }
49 }
50
51 return err
52 }
53
54
55
56
57
58
59 func ParseAnnotationsDisableGMSA(ctx context.Context, s *specs.Spec) bool {
60 return ParseAnnotationsBool(ctx, s.Annotations, annotations.WCOWDisableGMSA, false)
61 }
62
63
64
65
66
67 func ParseAnnotationsBool(ctx context.Context, a map[string]string, key string, def bool) bool {
68 if v, ok := a[key]; ok {
69 switch strings.ToLower(v) {
70 case "true":
71 return true
72 case "false":
73 return false
74 default:
75 logAnnotationParseError(ctx, key, v, logfields.Bool, nil)
76 }
77 }
78 return def
79 }
80
81
82
83 func parseAnnotationsUint32(ctx context.Context, a map[string]string, key string, def uint32) uint32 {
84 if v, ok := a[key]; ok {
85 countu, err := strconv.ParseUint(v, 10, 32)
86 if err == nil {
87 v := uint32(countu)
88 return v
89 }
90 logAnnotationParseError(ctx, key, v, logfields.Uint32, err)
91 }
92 return def
93 }
94
95
96
97 func parseAnnotationsUint64(ctx context.Context, a map[string]string, key string, def uint64) uint64 {
98 if v, ok := a[key]; ok {
99 countu, err := strconv.ParseUint(v, 10, 64)
100 if err == nil {
101 return countu
102 }
103 logAnnotationParseError(ctx, key, v, logfields.Uint64, err)
104 }
105 return def
106 }
107
108
109 func parseAnnotationsString(a map[string]string, key string, def string) string {
110 if v, ok := a[key]; ok {
111 return v
112 }
113 return def
114 }
115
116
117
118 func ParseAnnotationCommaSeparated(annotation string, annotations map[string]string) []string {
119 cs, ok := annotations[annotation]
120 if !ok || cs == "" {
121 return nil
122 }
123 results := strings.Split(cs, ",")
124 return results
125 }
126
127 func logAnnotationParseError(ctx context.Context, k, v, et string, err error) {
128 entry := log.G(ctx).WithFields(logrus.Fields{
129 logfields.OCIAnnotation: k,
130 logfields.Value: v,
131 logfields.ExpectedType: et,
132 })
133 if err != nil {
134 entry = entry.WithError(err)
135 }
136 entry.Warning("annotation could not be parsed")
137 }
138
View as plain text