github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/swarmkit/api/storeobject.go (about) 1 package api 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/docker/go-events" 9 ) 10 11 var ( 12 errUnknownStoreAction = errors.New("unrecognized action type") 13 errConflictingFilters = errors.New("conflicting filters specified") 14 errNoKindSpecified = errors.New("no kind of object specified") 15 errUnrecognizedAction = errors.New("unrecognized action") 16 ) 17 18 // StoreObject is an abstract object that can be handled by the store. 19 type StoreObject interface { 20 GetID() string // Get ID 21 GetMeta() Meta // Retrieve metadata 22 SetMeta(Meta) // Set metadata 23 CopyStoreObject() StoreObject // Return a copy of this object 24 EventCreate() Event // Return a creation event 25 EventUpdate(oldObject StoreObject) Event // Return an update event 26 EventDelete() Event // Return a deletion event 27 } 28 29 // Event is the type used for events passed over watcher channels, and also 30 // the type used to specify filtering in calls to Watch. 31 type Event interface { 32 // TODO(stevvooe): Consider whether it makes sense to squish both the 33 // matcher type and the primary type into the same type. It might be better 34 // to build a matcher from an event prototype. 35 36 // Matches checks if this item in a watch queue Matches the event 37 // description. 38 Matches(events.Event) bool 39 } 40 41 // EventCreate is an interface implemented by every creation event type 42 type EventCreate interface { 43 IsEventCreate() bool 44 } 45 46 // EventUpdate is an interface impelemented by every update event type 47 type EventUpdate interface { 48 IsEventUpdate() bool 49 } 50 51 // EventDelete is an interface implemented by every delete event type 52 type EventDelete interface { 53 IsEventDelete() 54 } 55 56 func customIndexer(kind string, annotations *Annotations) (bool, [][]byte, error) { 57 var converted [][]byte 58 59 for _, entry := range annotations.Indices { 60 index := make([]byte, 0, len(kind)+1+len(entry.Key)+1+len(entry.Val)+1) 61 if kind != "" { 62 index = append(index, []byte(kind)...) 63 index = append(index, '|') 64 } 65 index = append(index, []byte(entry.Key)...) 66 index = append(index, '|') 67 index = append(index, []byte(entry.Val)...) 68 index = append(index, '\x00') 69 converted = append(converted, index) 70 } 71 72 // Add the null character as a terminator 73 return len(converted) != 0, converted, nil 74 } 75 76 func fromArgs(args ...interface{}) ([]byte, error) { 77 if len(args) != 1 { 78 return nil, fmt.Errorf("must provide only a single argument") 79 } 80 arg, ok := args[0].(string) 81 if !ok { 82 return nil, fmt.Errorf("argument must be a string: %#v", args[0]) 83 } 84 // Add the null character as a terminator 85 arg += "\x00" 86 return []byte(arg), nil 87 } 88 89 func prefixFromArgs(args ...interface{}) ([]byte, error) { 90 val, err := fromArgs(args...) 91 if err != nil { 92 return nil, err 93 } 94 95 // Strip the null terminator, the rest is a prefix 96 n := len(val) 97 if n > 0 { 98 return val[:n-1], nil 99 } 100 return val, nil 101 } 102 103 func checkCustom(a1, a2 Annotations) bool { 104 if len(a1.Indices) == 1 { 105 for _, ind := range a2.Indices { 106 if ind.Key == a1.Indices[0].Key && ind.Val == a1.Indices[0].Val { 107 return true 108 } 109 } 110 } 111 return false 112 } 113 114 func checkCustomPrefix(a1, a2 Annotations) bool { 115 if len(a1.Indices) == 1 { 116 for _, ind := range a2.Indices { 117 if ind.Key == a1.Indices[0].Key && strings.HasPrefix(ind.Val, a1.Indices[0].Val) { 118 return true 119 } 120 } 121 } 122 return false 123 }