From d70b85a69f833019af3d67c84bc9b6f540b3b22e Mon Sep 17 00:00:00 2001 From: "huanbi.hy" Date: Tue, 27 Aug 2024 11:29:13 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8DmanifestEqual=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=BC=BA=E9=99=B7=E3=80=82=E8=AF=A5=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=B9=8B=E5=89=8D=E5=9C=A8manifest=E5=86=85=E5=AE=B9=E5=AE=9E?= =?UTF-8?q?=E9=99=85=E4=B8=8A=E5=AE=8C=E5=85=A8=E4=B8=80=E8=87=B4=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E6=98=AFkey=E9=A1=BA=E5=BA=8F=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C=E4=BC=9A=E8=BF=94?= =?UTF-8?q?=E5=9B=9Efalse=EF=BC=8C=E6=B2=A1=E6=9C=89=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E6=AF=94=E8=BE=83=E3=80=82=E8=80=8C=E7=94=B1=E4=BA=8EdestManif?= =?UTF-8?q?est=E6=98=AF=E6=9C=AC=E5=9C=B0=E6=9E=84=E9=80=A0=E7=9A=84?= =?UTF-8?q?=EF=BC=8C=E5=9B=A0=E6=AD=A4key=E9=A1=BA=E5=BA=8F=E5=A4=A7?= =?UTF-8?q?=E6=A6=82=E7=8E=87=E4=B8=8E=E8=BF=9C=E7=A8=8B=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E3=80=82=E8=BF=99=E5=AF=BC=E8=87=B4=E9=87=8D=E5=A4=8D=E5=90=91?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E4=BB=93=E5=BA=93=E6=8F=90=E4=BA=A4push?= =?UTF-8?q?=EF=BC=9B=E8=80=8C=E5=9C=A8=E8=BF=9C=E7=A8=8B=E4=BB=93=E5=BA=93?= =?UTF-8?q?=E5=BC=80=E5=90=AFimmutable=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E4=BC=9A=E5=AF=BC=E8=87=B4=E4=BB=BB=E5=8A=A1=E9=A2=84?= =?UTF-8?q?=E6=9C=9F=E5=A4=96=E7=9A=84=E5=A4=B1=E8=B4=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/sync/destination.go | 72 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/pkg/sync/destination.go b/pkg/sync/destination.go index 820c393..62f0d9b 100644 --- a/pkg/sync/destination.go +++ b/pkg/sync/destination.go @@ -1,7 +1,6 @@ package sync import ( - "bytes" "context" "encoding/json" "fmt" @@ -214,11 +213,72 @@ func (i *ImageDestination) String() string { } func manifestEqual(m1, m2 []byte) bool { - var a bytes.Buffer - _ = json.Compact(&a, m1) + var a map[string]interface{} + var b map[string]interface{} - var b bytes.Buffer - _ = json.Compact(&b, m2) + json.Unmarshal(m1, &a) + json.Unmarshal(m2, &b) - return a.String() == b.String() + return compareMap(a, b) +} + +func compareMap(map1, map2 map[string]interface{}) bool { + if len(map1) != len(map2) { + return false + } + + for key, value1 := range map1 { + value2, ok := map2[key] + if !ok { + return false + } + + switch v1 := value1.(type) { + case map[string]interface{}: + v2, ok := value2.(map[string]interface{}) + if !ok || !compareMap(v1, v2) { + return false + } + case []interface{}: + v2, ok := value2.([]interface{}) + if !ok || !compareSlice(v1, v2) { + return false + } + default: + if value1 != value2 { + return false + } + } + } + + return true +} + +func compareSlice(slice1, slice2 []interface{}) bool { + if len(slice1) != len(slice2) { + return false + } + + for i, v1 := range slice1 { + v2 := slice2[i] + + switch elem1 := v1.(type) { + case map[string]interface{}: + elem2, ok := v2.(map[string]interface{}) + if !ok || !compareMap(elem1, elem2) { + return false + } + case []interface{}: + elem2, ok := v2.([]interface{}) + if !ok || !compareSlice(elem1, elem2) { + return false + } + default: + if v1 != v2 { + return false + } + } + } + + return true } From 83414dd1405c625a155a5d637b0e336642175b4a Mon Sep 17 00:00:00 2001 From: "huanbi.hy" Date: Tue, 27 Aug 2024 21:35:58 +0800 Subject: [PATCH 2/2] Add reflection error handling and replace custom implementation with deepEqual. --- pkg/sync/destination.go | 65 ++++------------------------------------- 1 file changed, 5 insertions(+), 60 deletions(-) diff --git a/pkg/sync/destination.go b/pkg/sync/destination.go index 62f0d9b..24b7e8e 100644 --- a/pkg/sync/destination.go +++ b/pkg/sync/destination.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "reflect" "strings" "github.com/AliyunContainerService/image-syncer/pkg/utils/auth" @@ -216,69 +217,13 @@ func manifestEqual(m1, m2 []byte) bool { var a map[string]interface{} var b map[string]interface{} - json.Unmarshal(m1, &a) - json.Unmarshal(m2, &b) - - return compareMap(a, b) -} - -func compareMap(map1, map2 map[string]interface{}) bool { - if len(map1) != len(map2) { + if err := json.Unmarshal(m1, &a); err != nil { + //Received an unexpected manifest retrieval result, return false to trigger a fallback to the push task. return false } - - for key, value1 := range map1 { - value2, ok := map2[key] - if !ok { - return false - } - - switch v1 := value1.(type) { - case map[string]interface{}: - v2, ok := value2.(map[string]interface{}) - if !ok || !compareMap(v1, v2) { - return false - } - case []interface{}: - v2, ok := value2.([]interface{}) - if !ok || !compareSlice(v1, v2) { - return false - } - default: - if value1 != value2 { - return false - } - } - } - - return true -} - -func compareSlice(slice1, slice2 []interface{}) bool { - if len(slice1) != len(slice2) { + if err := json.Unmarshal(m2, &b); err != nil { return false } - for i, v1 := range slice1 { - v2 := slice2[i] - - switch elem1 := v1.(type) { - case map[string]interface{}: - elem2, ok := v2.(map[string]interface{}) - if !ok || !compareMap(elem1, elem2) { - return false - } - case []interface{}: - elem2, ok := v2.([]interface{}) - if !ok || !compareSlice(elem1, elem2) { - return false - } - default: - if v1 != v2 { - return false - } - } - } - - return true + return reflect.DeepEqual(a, b) }