Documentation
¶
Overview ¶
Package registry provides thread-safe registration and retrieval of bundler implementations.
The registry enables a plugin-like architecture where bundler implementations can self-register during package initialization, and the framework can discover and instantiate them dynamically at runtime.
Core Types ¶
Registry: Thread-safe storage for bundler factory functions
type Registry struct {
mu sync.RWMutex
factories map[types.BundleType]Factory
}
Factory: Function that creates a bundler instance
type Factory func(cfg *config.Config) Bundler
Bundler: Interface that all bundler implementations must satisfy
type Bundler interface {
Make(ctx context.Context, input recipe.RecipeInput, dir string) (*result.Result, error)
}
Registration Pattern ¶
Component names are defined in recipes/registry.yaml. Bundlers self-register in their package init() functions:
package gpuoperator
import (
"github.com/NVIDIA/aicr/pkg/bundler/registry"
"github.com/NVIDIA/aicr/pkg/bundler/types"
)
func init() {
registry.MustRegister(types.BundleType("gpu-operator"), func(cfg *config.Config) registry.Bundler {
return NewBundler(cfg)
})
}
The MustRegister function panics on duplicate registration, ensuring early detection of configuration errors.
Usage - Global Registry ¶
Create a registry from global registrations:
reg := registry.NewFromGlobal(cfg)
Get all registered types:
types := registry.GlobalTypes()
fmt.Printf("Available bundlers: %v\n", types)
Get a bundler instance:
bundler, ok := reg.Get(types.BundleType("gpu-operator"))
if ok {
result, err := bundler.Make(ctx, recipe, outputDir)
}
Get all bundlers:
bundlers := reg.GetAll()
Usage - Custom Registry ¶
Create a custom registry for testing:
reg := registry.NewRegistry()
reg.Register(types.BundleType("gpu-operator"), mockBundler)
Thread Safety ¶
The registry uses sync.RWMutex for safe concurrent access:
- Reads (Get, GetAll, List, Count) acquire read locks
- Writes (Register, Unregister) acquire write locks
This allows multiple bundlers to be retrieved concurrently during parallel bundle generation.
Error Handling ¶
Global Register returns an error if a type is already registered:
err := registry.Register(types.BundleType("gpu-operator"), factory)
if err != nil {
// Handle duplicate registration
}
MustRegister panics on duplicate registration:
registry.MustRegister(types.BundleType("gpu-operator"), factory)
// Panics if already registered
Discovery ¶
The framework uses the registry for dynamic discovery:
// Get all available bundler types
available := registry.GlobalTypes()
// Create instances for all types
reg := registry.NewFromGlobal(cfg)
bundlers := reg.GetAll()
// Execute bundlers in parallel
for _, b := range bundlers {
go b.Make(ctx, recipe, outputDir)
}
Testing ¶
Create isolated registries for testing:
func TestMyBundler(t *testing.T) {
reg := registry.NewRegistry()
reg.Register(types.BundleType("gpu-operator"), mockBundler)
bundler, ok := reg.Get(types.BundleType("gpu-operator"))
if !ok {
t.Fatal("bundler not found")
}
// Test bundler...
}
Index ¶
- func GlobalTypes() []types.BundleType
- func MustRegister(bundleType types.BundleType, factory Factory)
- func Register(bundleType types.BundleType, factory Factory) error
- type Bundler
- type Factory
- type Registry
- func (r *Registry) Count() int
- func (r *Registry) Get(bundleType types.BundleType) (Bundler, bool)
- func (r *Registry) GetAll() map[types.BundleType]Bundler
- func (r *Registry) IsEmpty() bool
- func (r *Registry) List() []types.BundleType
- func (r *Registry) Register(bundleType types.BundleType, b Bundler)
- func (r *Registry) Unregister(bundleType types.BundleType) error
- type ValidatableBundler
- type ValuesExtractor
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GlobalTypes ¶
func GlobalTypes() []types.BundleType
GlobalTypes returns all globally registered bundler types.
func MustRegister ¶
func MustRegister(bundleType types.BundleType, factory Factory)
MustRegister is a convenience function that panics on registration error. Use this in init() functions where registration must succeed.
Types ¶
type Bundler ¶
type Bundler interface {
Make(ctx context.Context, input recipe.RecipeInput, dir string) (*result.Result, error)
}
Bundler defines the interface for creating application bundles. Implementations generate deployment artifacts from recipes. The RecipeInput interface allows bundlers to work with both both legacy recipes (measurements-based) and modern recipes (component references).
type Factory ¶
Factory is a function that creates a new Bundler instance. Used for dynamic bundler registration via init() functions.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages registered bundlers with thread-safe operations.
func NewFromGlobal ¶
NewFromGlobal creates a new Registry populated with all globally registered bundlers. Each bundler is instantiated using the provided config.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry creates a new empty Registry instance. Bundlers should be registered explicitly using Register().
func (*Registry) Get ¶
func (r *Registry) Get(bundleType types.BundleType) (Bundler, bool)
Get retrieves a bundler by type from this registry.
func (*Registry) GetAll ¶
func (r *Registry) GetAll() map[types.BundleType]Bundler
GetAll returns all registered bundlers.
func (*Registry) IsEmpty ¶
IsEmpty returns true if no bundlers are registered. This is useful for checking if a registry has been populated.
func (*Registry) List ¶
func (r *Registry) List() []types.BundleType
List returns all registered bundler types.
func (*Registry) Register ¶
func (r *Registry) Register(bundleType types.BundleType, b Bundler)
Register registers a bundler in this registry.
func (*Registry) Unregister ¶
func (r *Registry) Unregister(bundleType types.BundleType) error
Unregister removes a bundler from this registry.
type ValidatableBundler ¶
type ValidatableBundler interface {
Bundler
Validate(ctx context.Context, input recipe.RecipeInput) error
}
ValidatableBundler is an optional interface that bundlers can implement to validate recipes before processing. This provides type-safe validation without reflection.
type ValuesExtractor ¶
type ValuesExtractor interface {
// ExtractValues returns the processed values map for this component.
// This includes base values, overlay merging, and user overrides applied.
// Returns the component name and values map.
ExtractValues(ctx context.Context, input recipe.RecipeInput) (componentName string, values map[string]any, err error)
}
ValuesExtractor defines the interface for extracting component values. This is used by the Helm bundle generator to collect values from each bundler without requiring file I/O. Bundlers should implement this interface.