github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/swarmkit/api/equality/equality.go (about) 1 package equality 2 3 import ( 4 "crypto/subtle" 5 "reflect" 6 7 "github.com/docker/swarmkit/api" 8 ) 9 10 // TasksEqualStable returns true if the tasks are functionally equal, ignoring status, 11 // version and other superfluous fields. 12 // 13 // This used to decide whether or not to propagate a task update to a controller. 14 func TasksEqualStable(a, b *api.Task) bool { 15 // shallow copy 16 copyA, copyB := *a, *b 17 18 copyA.Status, copyB.Status = api.TaskStatus{}, api.TaskStatus{} 19 copyA.Meta, copyB.Meta = api.Meta{}, api.Meta{} 20 21 return reflect.DeepEqual(©A, ©B) 22 } 23 24 // TaskStatusesEqualStable compares the task status excluding timestamp fields. 25 func TaskStatusesEqualStable(a, b *api.TaskStatus) bool { 26 copyA, copyB := *a, *b 27 28 copyA.Timestamp, copyB.Timestamp = nil, nil 29 return reflect.DeepEqual(©A, ©B) 30 } 31 32 // RootCAEqualStable compares RootCAs, excluding join tokens, which are randomly generated 33 func RootCAEqualStable(a, b *api.RootCA) bool { 34 if a == nil && b == nil { 35 return true 36 } 37 if a == nil || b == nil { 38 return false 39 } 40 41 var aRotationKey, bRotationKey []byte 42 if a.RootRotation != nil { 43 aRotationKey = a.RootRotation.CAKey 44 } 45 if b.RootRotation != nil { 46 bRotationKey = b.RootRotation.CAKey 47 } 48 if subtle.ConstantTimeCompare(a.CAKey, b.CAKey) != 1 || subtle.ConstantTimeCompare(aRotationKey, bRotationKey) != 1 { 49 return false 50 } 51 52 copyA, copyB := *a, *b 53 copyA.JoinTokens, copyB.JoinTokens = api.JoinTokens{}, api.JoinTokens{} 54 return reflect.DeepEqual(copyA, copyB) 55 } 56 57 // ExternalCAsEqualStable compares lists of external CAs and determines whether they are equal. 58 func ExternalCAsEqualStable(a, b []*api.ExternalCA) bool { 59 // because DeepEqual will treat an empty list and a nil list differently, we want to manually check this first 60 if len(a) == 0 && len(b) == 0 { 61 return true 62 } 63 // The assumption is that each individual api.ExternalCA within both lists are created from deserializing from a 64 // protobuf, so no special affordances are made to treat a nil map and empty map in the Options field of an 65 // api.ExternalCA as equivalent. 66 return reflect.DeepEqual(a, b) 67 }