66 "regexp"
77 "strconv"
88
9+ "github.com/google/go-containerregistry/pkg/crane"
910 "github.com/google/go-containerregistry/pkg/name"
1011 containerregistryv1 "github.com/google/go-containerregistry/pkg/v1"
1112 "github.com/google/go-containerregistry/pkg/v1/remote"
@@ -59,10 +60,61 @@ func getDefaultExtensionImage(metadata *extensionMetadata) (string, error) {
5960 return getExtensionImage (metadata , DefaultDistribution , DefaultPgMajor )
6061}
6162
62- // getExtensionImage returns the extension image for a given distribution and pgMajor,
63- // resolved from the metadata.
63+ // getExtensionImage returns the extension image for a given distribution and pgMajor.
6464func getExtensionImage (metadata * extensionMetadata , distribution string , pgMajor int ) (string , error ) {
65- packageVersion := metadata .Versions [distribution ][strconv .Itoa (pgMajor )]
65+ version , err := extractExtensionVersion (metadata .Versions , distribution , pgMajor )
66+ if err != nil {
67+ return "" , fmt .Errorf ("while extracting extension version for %s: %w" , metadata .Name , err )
68+ }
69+
70+ image := fmt .Sprintf ("ghcr.io/cloudnative-pg/%s:%s-%d-%s" ,
71+ metadata .ImageName , version , pgMajor , distribution )
72+
73+ return image , nil
74+ }
75+
76+ // getExtensionImageWithTimestamp returns the extension image with the latest timestamp
77+ // for a given distribution and pgMajor.
78+ func getExtensionImageWithTimestamp (metadata * extensionMetadata , distribution string , pgMajor int ) (string , error ) {
79+ imageName := fmt .Sprintf ("ghcr.io/cloudnative-pg/%s" , metadata .ImageName )
80+ tags , err := crane .ListTags (imageName )
81+ if err != nil {
82+ return "" , fmt .Errorf ("while listing tags for image %s: %w" , imageName , err )
83+ }
84+
85+ version , err := extractExtensionVersion (metadata .Versions , distribution , pgMajor )
86+ if err != nil {
87+ return "" , fmt .Errorf ("while extracting extension version for %s: %w" , metadata .Name , err )
88+ }
89+
90+ re := regexp .MustCompile (
91+ fmt .Sprintf (`^%s-(\d{12})-%d-%s$` ,
92+ regexp .QuoteMeta (version ),
93+ pgMajor ,
94+ distribution ,
95+ ),
96+ )
97+
98+ var latestTag string
99+ for _ , tag := range tags {
100+ if re .MatchString (tag ) && tag > latestTag {
101+ latestTag = tag
102+ }
103+ }
104+ if latestTag == "" {
105+ return "" , fmt .Errorf (
106+ "no image found for image %s (version=%s pgMajor=%d os=%s" ,
107+ imageName , version , pgMajor , distribution ,
108+ )
109+ }
110+
111+ return fmt .Sprintf ("%s:%s" , imageName , latestTag ), nil
112+ }
113+
114+ // extractExtensionVersion returns the extension version for a given distribution and pgMajor,
115+ // extracted from the extension's metadata.
116+ func extractExtensionVersion (versions versionMap , distribution string , pgMajor int ) (string , error ) {
117+ packageVersion := versions [distribution ][strconv .Itoa (pgMajor )]
66118 if packageVersion == "" {
67119 return "" , fmt .Errorf ("no package version found for distribution %q and version %d" ,
68120 distribution , pgMajor )
@@ -73,9 +125,6 @@ func getExtensionImage(metadata *extensionMetadata, distribution string, pgMajor
73125 if len (matches ) < 2 {
74126 return "" , fmt .Errorf ("cannot extract extension version from %q" , packageVersion )
75127 }
76- version := matches [1 ]
77- image := fmt .Sprintf ("ghcr.io/cloudnative-pg/%s:%s-%d-%s" ,
78- metadata .ImageName , version , pgMajor , distribution )
79128
80- return image , nil
129+ return matches [ 1 ] , nil
81130}
0 commit comments