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