@@ -4,19 +4,19 @@ import (
44 "fmt"
55 "os"
66 "path"
7+ "reflect"
8+ "sort"
79 "strings"
8- "time"
910
1011 "github.com/urfave/cli"
1112
1213 "github.com/docker-library/bashbrew/architecture"
1314 "github.com/docker-library/bashbrew/manifest"
1415)
1516
16- func entriesToManifestToolYaml (singleArch bool , r Repo , entries ... * manifest.Manifest2822Entry ) (string , time. Time , int , error ) {
17+ func entriesToManifestToolYaml (singleArch bool , r Repo , entries ... * manifest.Manifest2822Entry ) (string , [] string , error ) {
1718 yaml := ""
18- mru := time.Time {}
19- expectedNumber := 0
19+ remoteDigests := []string {}
2020 entryIdentifiers := []string {}
2121 for _ , entry := range entries {
2222 entryIdentifiers = append (entryIdentifiers , r .EntryIdentifier (entry ))
@@ -41,29 +41,26 @@ func entriesToManifestToolYaml(singleArch bool, r Repo, entries ...*manifest.Man
4141 }
4242
4343 archImage := fmt .Sprintf ("%s/%s:%s" , archNamespace , r .RepoName , entry .Tags [0 ])
44- archImageMeta := fetchDockerHubTagMeta (archImage )
45- if archU := archImageMeta .lastUpdatedTime (); archU .After (mru ) {
46- mru = archU
47- }
4844
49- // count up how many images we expect to push successfully in this manifest list
50- expectedNumber += len (archImageMeta .Images )
51- // for non-manifest-list tags, this will be 1 and for failed lookups it'll be 0
45+ // keep track of how many images we expect to push successfully in this manifest list (and what their manifest digests are)
46+ // for non-manifest-list tags, this will be exactly 1 and for failed lookups it'll be 0
5247 // (and if one of _these_ tags is a manifest list, we've goofed somewhere)
53- if len (archImageMeta .Images ) != 1 {
54- fmt .Fprintf (os .Stderr , "warning: expected 1 image for %q; got %d\n " , archImage , len (archImageMeta .Images ))
48+ archImageDigests := fetchRegistryManiestListDigests (archImage )
49+ if len (archImageDigests ) != 1 {
50+ fmt .Fprintf (os .Stderr , "warning: expected 1 image for %q; got %d\n " , archImage , len (archImageDigests ))
5551 }
52+ remoteDigests = append (remoteDigests , archImageDigests ... )
5653
57- yaml += fmt .Sprintf (" - image: %s\n platform:\n " , archImage )
54+ yaml += fmt .Sprintf (" - image: %s\n " , archImage )
55+ yaml += fmt .Sprintf (" platform:\n " )
5856 yaml += fmt .Sprintf (" os: %s\n " , ociArch .OS )
5957 yaml += fmt .Sprintf (" architecture: %s\n " , ociArch .Architecture )
6058 if ociArch .Variant != "" {
6159 yaml += fmt .Sprintf (" variant: %s\n " , ociArch .Variant )
6260 }
6361 }
6462 }
65-
66- return "manifests:\n " + yaml , mru , expectedNumber , nil
63+ return "manifests:\n " + yaml , remoteDigests , nil
6764}
6865
6966func tagsToManifestToolYaml (repo string , tags ... string ) string {
@@ -130,37 +127,25 @@ func cmdPutShared(c *cli.Context) error {
130127
131128 failed := []string {}
132129 for _ , group := range sharedTagGroups {
133- yaml , mostRecentPush , expectedNumber , err := entriesToManifestToolYaml (singleArch , * r , group .Entries ... )
130+ yaml , expectedRemoteDigests , err := entriesToManifestToolYaml (singleArch , * r , group .Entries ... )
134131 if err != nil {
135132 return err
136133 }
137134
138- if expectedNumber < 1 {
139- // if "expectedNumber" comes back as 0, we've probably got an API issue, so let's count up what we probably _should_ push
135+ sort .Strings (expectedRemoteDigests )
136+ if len (expectedRemoteDigests ) < 1 {
137+ // if "expectedRemoteDigests" comes back empty, we've probably got an API issue (or a build error/push timing problem)
140138 fmt .Fprintf (os .Stderr , "warning: no images expected to push for %q\n " , fmt .Sprintf ("%s:%s" , targetRepo , group .SharedTags [0 ]))
141- for _ , entry := range group .Entries {
142- expectedNumber += len (entry .Architectures )
143- }
144139 }
145140
146141 tagsToPush := []string {}
147142 for _ , tag := range group .SharedTags {
148143 image := fmt .Sprintf ("%s:%s" , targetRepo , tag )
149144 if ! force {
150- hubMeta := fetchDockerHubTagMeta (image )
151- tagUpdated := hubMeta .lastUpdatedTime ()
152- doPush := false
153- if mostRecentPush .After (tagUpdated ) {
154- // if one of the images that make up the manifest list has been updated since the manifest list was last pushed, we probably need to push
155- doPush = true
156- }
157- if ! singleArch && len (hubMeta .Images ) != expectedNumber {
158- // if we're supposed to push more (or less) images than the current manifest list contains, we probably need to push
159- // this _should_ already be accounting for tags that haven't been pushed yet (see notes above in "entriesToManifestToolYaml" where this is calculated)
160- doPush = true
161- }
162- if ! doPush {
163- fmt .Fprintf (os .Stderr , "skipping %s (created %s, last updated %s)\n " , image , mostRecentPush .Local ().Format (time .RFC3339 ), tagUpdated .Local ().Format (time .RFC3339 ))
145+ remoteDigests := fetchRegistryManiestListDigests (image )
146+ sort .Strings (remoteDigests )
147+ if reflect .DeepEqual (remoteDigests , expectedRemoteDigests ) {
148+ fmt .Fprintf (os .Stderr , "skipping %s (%d remote digests up-to-date)\n " , image , len (remoteDigests ))
164149 continue
165150 }
166151 }
0 commit comments