...
1 package cmp
2
3 import (
4 v1 "github.com/google/go-containerregistry/pkg/v1"
5
6 "edge-infra.dev/pkg/f8n/warehouse/oci"
7 "edge-infra.dev/pkg/f8n/warehouse/oci/layer"
8 "edge-infra.dev/pkg/f8n/warehouse/oci/walk"
9 )
10
11
12 func Diff(a oci.Artifact, bb ...oci.Artifact) ([]v1.Hash, error) {
13
14
15 diff, err := toMap(a)
16 if err != nil {
17 return nil, err
18 }
19
20
21 ad, err := a.Digest()
22 if err != nil {
23 return nil, err
24 }
25 hitA := false
26 visited := map[v1.Hash]bool{}
27
28 for _, b := range bb {
29
30 h, err := b.Digest()
31 if err != nil {
32 return nil, err
33 }
34 if h == ad {
35 return nil, nil
36 }
37 if visited[h] {
38 continue
39 }
40
41 if err := walk.Walk(b, &walk.Fns{
42 Index: func(ii v1.ImageIndex, _ v1.ImageIndex) error {
43 h, err := ii.Digest()
44 if err != nil {
45 return err
46 }
47
48 if h == ad {
49 hitA = true
50 return walk.SkipAll
51 }
52 visited[h] = true
53 if diff[h] {
54 delete(diff, h)
55 }
56 return nil
57 },
58 Image: func(img v1.Image, _ v1.ImageIndex) error {
59 h, err := img.Digest()
60 if err != nil {
61 return err
62 }
63 ch, err := img.ConfigName()
64 if err != nil {
65 return err
66 }
67
68 if h == ad {
69 hitA = true
70 return walk.SkipAll
71 }
72 visited[h] = true
73 visited[ch] = true
74
75 if diff[h] {
76 delete(diff, h)
77 }
78 if diff[ch] {
79 delete(diff, ch)
80 }
81 return nil
82 },
83 Layer: func(l layer.Layer, _ v1.Image) error {
84 h, err := l.Digest()
85 if err != nil {
86 return err
87 }
88
89 visited[h] = true
90 if diff[h] {
91 delete(diff, h)
92 }
93 return nil
94 },
95 }); err != nil {
96 return nil, err
97 }
98
99
100
101 if len(diff) == 0 || hitA {
102 return nil, nil
103 }
104 }
105
106
107 return mapToSlice(diff), nil
108 }
109
View as plain text