@@ -30,6 +30,8 @@ import (
3030
3131 "sigs.k8s.io/yaml"
3232
33+ yamlflow "gopkg.in/yaml.v3"
34+
3335 mellanoxv1alpha1 "github.com/Mellanox/network-operator/api/v1alpha1"
3436
3537 "github.com/google/go-containerregistry/pkg/authn"
@@ -80,6 +82,18 @@ type Release struct {
8082 MaintenanceOperator * ReleaseImageSpec
8183}
8284
85+ type DocaDriverMatrix struct {
86+ Precompiled []struct {
87+ OS string `yaml:"os"`
88+ Arch []string `yaml:"archs,flow"`
89+ Kernels []string `yaml:"kernels,flow"`
90+ } `yaml:"precompiled"`
91+ DynamicallyCompiled []struct {
92+ OS string `yaml:"os,flow"`
93+ Arch []string `yaml:"archs,flow"`
94+ } `yaml:"dynamically_compiled"`
95+ }
96+
8397func readDefaults (releaseDefaults string ) Release {
8498 f , err := os .ReadFile (filepath .Clean (releaseDefaults ))
8599 if err != nil {
@@ -136,9 +150,82 @@ func main() {
136150 outputDir := flag .String ("outputDir" , "." , "Destination directory to render templates to" )
137151 releaseDefaults := flag .String ("releaseDefaults" , "release.yaml" , "Destination of the release defaults definition" )
138152 retrieveSha := flag .Bool ("with-sha256" , false , "retrieve SHA256 for container images references" )
153+ docaDriverCheck := flag .Bool ("doca-driver-check" , false , "Verify DOCA Driver tags" )
154+ docaDriverMatrix := flag .String ("doca-driver-matrix" , "tmp/doca-driver-matrix.yaml" , "DOCA Driver tags matrix" )
139155 flag .Parse ()
140156 release := readDefaults (* releaseDefaults )
141157 readEnvironmentVariables (& release )
158+
159+ if ! * docaDriverCheck {
160+ renderTemplates (release , templateDir , outputDir , retrieveSha )
161+ } else {
162+ docaDriverTagsCheck (release , docaDriverMatrix )
163+ }
164+ }
165+
166+ func docaDriverTagsCheck (release Release , docaDriverMatrix * string ) {
167+ f , err := os .ReadFile (filepath .Clean (* docaDriverMatrix ))
168+ if err != nil {
169+ fmt .Printf ("Error: %v\n " , err )
170+ os .Exit (1 )
171+ }
172+ var config DocaDriverMatrix
173+ if err := yamlflow .Unmarshal (f , & config ); err != nil {
174+ fmt .Printf ("Error: %v\n " , err )
175+ os .Exit (1 )
176+ }
177+ auth , err := getAuth ()
178+ if err != nil {
179+ fmt .Printf ("Error: %v\n " , err )
180+ os .Exit (1 )
181+ }
182+ tags , err := resolveTags (release .Mofed .Repository , release .Mofed .Image , auth )
183+ if err != nil {
184+ fmt .Printf ("Error: %v\n " , err )
185+ os .Exit (1 )
186+ }
187+ if err := validateTags (config , tags , release .Mofed .Version ); err != nil {
188+ fmt .Printf ("Error: %v\n " , err )
189+ os .Exit (1 )
190+ }
191+ }
192+
193+ func validateTags (config DocaDriverMatrix , tags []string , version string ) error {
194+ // Build expected OS-arch combinations
195+ expectedCombinations := make (map [string ]struct {})
196+ for _ , entry := range config .DynamicallyCompiled {
197+ for _ , arch := range entry .Arch {
198+ key := fmt .Sprintf ("%s-%s" , entry .OS , arch )
199+ expectedCombinations [key ] = struct {}{}
200+ }
201+ }
202+
203+ // Filter tags based on version prefix
204+ filteredTags := []string {}
205+ for _ , tag := range tags {
206+ if strings .HasPrefix (tag , version ) {
207+ filteredTags = append (filteredTags , tag )
208+ }
209+ }
210+
211+ // Validate if each expected combination exists in the filtered tags
212+ for combo := range expectedCombinations {
213+ found := false
214+ for _ , tag := range filteredTags {
215+ if strings .Contains (tag , combo ) {
216+ found = true
217+ break
218+ }
219+ }
220+ if ! found {
221+ return fmt .Errorf ("missing os-arch combination: %s" , combo )
222+ }
223+ }
224+
225+ return nil
226+ }
227+
228+ func renderTemplates (release Release , templateDir , outputDir * string , retrieveSha * bool ) {
142229 if * retrieveSha {
143230 err := resolveImagesSha (& release )
144231 if err != nil {
@@ -198,15 +285,23 @@ func main() {
198285 }
199286}
200287
201- func resolveImagesSha ( release * Release ) error {
288+ func getAuth () ( * authn. Basic , error ) {
202289 nvcrToken := os .Getenv ("NGC_CLI_API_KEY" )
203290 if nvcrToken == "" {
204- return fmt .Errorf ("NGC_CLI_API_KEY is unset" )
291+ return nil , fmt .Errorf ("NGC_CLI_API_KEY is unset" )
205292 }
206293 auth := & authn.Basic {
207294 Username : "$oauthtoken" ,
208295 Password : nvcrToken ,
209296 }
297+ return auth , nil
298+ }
299+
300+ func resolveImagesSha (release * Release ) error {
301+ auth , err := getAuth ()
302+ if err != nil {
303+ return err
304+ }
210305 v := reflect .ValueOf (* release )
211306 for i := 0 ; i < v .NumField (); i ++ {
212307 field := v .Field (i )
@@ -263,27 +358,35 @@ func resolveImageSha(repo, image, tag string, auth *authn.Basic) (string, error)
263358 return digest .String (), nil
264359}
265360
266- func resolveDocaDriversShas (repoName , imageName , ver string , auth * authn.Basic ) ([]string , error ) {
267- shaArray := make ([]string , 0 )
361+ func resolveTags (repoName , imageName string , auth * authn.Basic ) ([]string , error ) {
362+ tags := make ([]string , 0 )
268363 image := fmt .Sprintf ("%s/%s" , repoName , imageName )
269364 repo , err := containerregistryname .NewRepository (image )
270365 if err != nil {
271- return shaArray , err
366+ return tags , err
272367 }
273- var tags []string
274368 if strings .Contains (repoName , "nvstaging" ) {
275369 tags , err = remote .List (repo , remote .WithAuth (auth ))
276370 if err != nil {
277- return shaArray , err
371+ return tags , err
278372 }
279373 } else {
280374 // Container registry might fail if providing unneeded auth
281375 tags , err = remote .List (repo )
282376 if err != nil {
283- return shaArray , err
377+ return tags , err
284378 }
285379 }
286380 sort .Strings (tags )
381+ return tags , nil
382+ }
383+
384+ func resolveDocaDriversShas (repoName , imageName , ver string , auth * authn.Basic ) ([]string , error ) {
385+ shaArray := make ([]string , 0 )
386+ tags , err := resolveTags (repoName , imageName , auth )
387+ if err != nil {
388+ return shaArray , err
389+ }
287390 shaSet := make (map [string ]interface {})
288391 for _ , tag := range tags {
289392 if strings .Contains (tag , ver ) && (strings .Contains (tag , "rhcos" ) || strings .Contains (tag , "rhel" )) {
0 commit comments