@@ -12,6 +12,8 @@ import (
1212 "path"
1313 "regexp"
1414 "slices"
15+ "sort"
16+ "strconv"
1517 "strings"
1618 "text/template"
1719 "time"
@@ -405,3 +407,94 @@ func (m *Maintenance) Test(
405407
406408 return nil
407409}
410+
411+ // Generate extension's ClusterImageCatalogs starting from a base set of catalogs
412+ func (m * Maintenance ) GenerateCatalogs (
413+ ctx context.Context ,
414+ // The source directory containing the extension folders. Defaults to the current directory
415+ // +ignore=["dagger", ".github"]
416+ // +defaultPath="/"
417+ source * dagger.Directory ,
418+ // The directory containing the starting catalogs. Defaults to "/image-catalogs"
419+ // +defaultPath="/image-catalogs"
420+ catalogsDir * dagger.Directory ,
421+ ) (* dagger.Directory , error ) {
422+ outDir := dag .Directory ()
423+
424+ catalogs , err := getMinimalCatalogs (ctx , catalogsDir )
425+ if err != nil {
426+ return nil , fmt .Errorf ("while retrieving base catalogs: %w" , err )
427+ }
428+
429+ targetExtensions , err := getExtensions (ctx , source )
430+ if err != nil {
431+ return nil , fmt .Errorf ("while retrieving extensions: %w" , err )
432+ }
433+ if len (targetExtensions ) == 0 {
434+ return nil , fmt .Errorf ("no extensions found in source directory" )
435+ }
436+
437+ catalogWritten := false
438+ for _ , catalog := range catalogs {
439+ catalogOS , ok := catalog .Metadata .Labels [LabelImageOS ]
440+ if ! ok {
441+ return nil , fmt .Errorf ("while retrieving OS for %q catalog" , catalog .Metadata .Name )
442+ }
443+
444+ for dir , extension := range targetExtensions {
445+ matrix , err := parseBuildMatrix (ctx , source , dir )
446+ if err != nil {
447+ return nil , fmt .Errorf ("while parsing build Matrix for extension %s: %w" , extension , err )
448+ }
449+ if ! slices .Contains (matrix .Distributions , catalogOS ) {
450+ continue
451+ }
452+
453+ for i := range catalog .Spec .Images {
454+ img := & catalog .Spec .Images [i ]
455+ if ! slices .Contains (matrix .MajorVersions , strconv .Itoa (img .Major )) {
456+ continue
457+ }
458+
459+ metadata , err := parseExtensionMetadata (ctx , source .Directory (dir ))
460+ if err != nil {
461+ return nil , fmt .Errorf ("while parsing extension %s metadata: %w" , extension , err )
462+ }
463+
464+ targetExtensionImage , err := getExtensionImage (metadata , catalogOS , img .Major )
465+ if err != nil {
466+ return nil , fmt .Errorf ("while retrieving extension %s image: %w" , extension , err )
467+ }
468+
469+ extensionsConfig := ExtensionConfiguration {
470+ Name : metadata .Name ,
471+ ImageVolumeSource : ImageVolumeSource {
472+ Reference : targetExtensionImage ,
473+ },
474+ ExtensionControlPath : metadata .ExtensionControlPath ,
475+ DynamicLibraryPath : metadata .DynamicLibraryPath ,
476+ LdLibraryPath : metadata .LdLibraryPath ,
477+ }
478+
479+ img .Extensions = append (img .Extensions , extensionsConfig )
480+
481+ // Sort extensions by name
482+ sort .Slice (img .Extensions , func (i , j int ) bool {
483+ return img .Extensions [i ].Name < img .Extensions [j ].Name
484+ })
485+ }
486+ }
487+
488+ outDir , err = writeCatalogToDir (catalog , outDir )
489+ if err != nil {
490+ return nil , fmt .Errorf ("while writing catalog %s: %w" , catalog .Metadata .Name , err )
491+ }
492+ catalogWritten = true
493+ }
494+
495+ if ! catalogWritten {
496+ return nil , fmt .Errorf ("no catalogs matched the selection criteria" )
497+ }
498+
499+ return outDir , nil
500+ }
0 commit comments