@@ -33,6 +33,7 @@ import (
3333
3434 "github.com/go-logr/logr"
3535 "github.com/google/go-cmp/cmp"
36+ "github.com/google/go-containerregistry/pkg/name"
3637 llamav1alpha1 "github.com/llamastack/llama-stack-k8s-operator/api/v1alpha1"
3738 "github.com/llamastack/llama-stack-k8s-operator/pkg/cluster"
3839 "github.com/llamastack/llama-stack-k8s-operator/pkg/deploy"
@@ -92,6 +93,8 @@ type LlamaStackDistributionReconciler struct {
9293 Scheme * runtime.Scheme
9394 // Feature flags
9495 EnableNetworkPolicy bool
96+ // Image mapping overrides
97+ ImageMappingOverrides map [string ]string
9598 // Cluster info
9699 ClusterInfo * cluster.ClusterInfo
97100 httpClient * http.Client
@@ -597,21 +600,40 @@ func (r *LlamaStackDistributionReconciler) configMapUpdatePredicate(e event.Upda
597600 return false
598601 }
599602
600- // Parse the feature flags if the operator config ConfigMap has changed
603+ // Check if this is the operator config ConfigMap
604+ if r .handleOperatorConfigUpdate (newConfigMap ) {
605+ return true
606+ }
607+
608+ // Handle referenced ConfigMap updates
609+ return r .handleReferencedConfigMapUpdate (oldConfigMap , newConfigMap )
610+ }
611+
612+ // handleOperatorConfigUpdate processes updates to the operator config ConfigMap.
613+ func (r * LlamaStackDistributionReconciler ) handleOperatorConfigUpdate (configMap * corev1.ConfigMap ) bool {
601614 operatorNamespace , err := deploy .GetOperatorNamespace ()
602615 if err != nil {
603616 return false
604617 }
605- if newConfigMap .Name == operatorConfigData && newConfigMap .Namespace == operatorNamespace {
606- EnableNetworkPolicy , err := parseFeatureFlags (newConfigMap .Data )
607- if err != nil {
608- log .FromContext (context .Background ()).Error (err , "Failed to parse feature flags" )
609- } else {
610- r .EnableNetworkPolicy = EnableNetworkPolicy
611- }
612- return true
618+
619+ if configMap .Name != operatorConfigData || configMap .Namespace != operatorNamespace {
620+ return false
613621 }
614622
623+ // Update feature flags
624+ EnableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
625+ if err != nil {
626+ log .FromContext (context .Background ()).Error (err , "Failed to parse feature flags" )
627+ } else {
628+ r .EnableNetworkPolicy = EnableNetworkPolicy
629+ }
630+
631+ r .ImageMappingOverrides = ParseImageMappingOverrides (configMap .Data )
632+ return true
633+ }
634+
635+ // handleReferencedConfigMapUpdate processes updates to referenced ConfigMaps.
636+ func (r * LlamaStackDistributionReconciler ) handleReferencedConfigMapUpdate (oldConfigMap , newConfigMap * corev1.ConfigMap ) bool {
615637 // Only proceed if this ConfigMap is referenced by any LlamaStackDistribution
616638 if ! r .isConfigMapReferenced (newConfigMap ) {
617639 return false
@@ -783,7 +805,7 @@ func (r *LlamaStackDistributionReconciler) findLlamaStackDistributionsForConfigM
783805
784806 operatorNamespace , err := deploy .GetOperatorNamespace ()
785807 if err != nil {
786- log . FromContext ( context . Background ()) .Error (err , "Failed to get operator namespace for config map event processing" )
808+ logger .Error (err , "Failed to get operator namespace for config map event processing" )
787809 return nil
788810 }
789811 // If the operator config was changed, we reconcile all LlamaStackDistributions
@@ -1672,53 +1694,103 @@ func NewLlamaStackDistributionReconciler(ctx context.Context, client client.Clie
16721694 return nil , fmt .Errorf ("failed to get operator namespace: %w" , err )
16731695 }
16741696
1675- // Get the ConfigMap
1676- // If the ConfigMap doesn't exist, create it with default feature flags
1677- // If the ConfigMap exists, parse the feature flags from the Configmap
1697+ // Initialize operator config ConfigMap
1698+ configMap , err := initializeOperatorConfigMap (ctx , client , operatorNamespace )
1699+ if err != nil {
1700+ return nil , err
1701+ }
1702+
1703+ // Parse feature flags from ConfigMap
1704+ enableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
1705+ if err != nil {
1706+ return nil , fmt .Errorf ("failed to parse feature flags: %w" , err )
1707+ }
1708+
1709+ // Parse image mapping overrides from ConfigMap
1710+ imageMappingOverrides := ParseImageMappingOverrides (configMap .Data )
1711+
1712+ return & LlamaStackDistributionReconciler {
1713+ Client : client ,
1714+ Scheme : scheme ,
1715+ EnableNetworkPolicy : enableNetworkPolicy ,
1716+ ImageMappingOverrides : imageMappingOverrides ,
1717+ ClusterInfo : clusterInfo ,
1718+ httpClient : & http.Client {Timeout : 5 * time .Second },
1719+ }, nil
1720+ }
1721+
1722+ // initializeOperatorConfigMap gets or creates the operator config ConfigMap.
1723+ func initializeOperatorConfigMap (ctx context.Context , c client.Client , operatorNamespace string ) (* corev1.ConfigMap , error ) {
16781724 configMap := & corev1.ConfigMap {}
16791725 configMapName := types.NamespacedName {
16801726 Name : operatorConfigData ,
16811727 Namespace : operatorNamespace ,
16821728 }
16831729
1684- if err = client .Get (ctx , configMapName , configMap ); err != nil {
1685- if ! k8serrors . IsNotFound ( err ) {
1686- return nil , fmt . Errorf ( "failed to get ConfigMap: %w" , err )
1687- }
1730+ err := c .Get (ctx , configMapName , configMap )
1731+ if err == nil {
1732+ return configMap , nil
1733+ }
16881734
1689- // ConfigMap doesn't exist, create it with defaults
1690- configMap , err = createDefaultConfigMap (configMapName )
1691- if err != nil {
1692- return nil , fmt .Errorf ("failed to generate default configMap: %w" , err )
1735+ if ! k8serrors .IsNotFound (err ) {
1736+ return nil , fmt .Errorf ("failed to get ConfigMap: %w" , err )
1737+ }
1738+
1739+ // ConfigMap doesn't exist, create it with defaults
1740+ configMap , err = createDefaultConfigMap (configMapName )
1741+ if err != nil {
1742+ return nil , fmt .Errorf ("failed to generate default configMap: %w" , err )
1743+ }
1744+
1745+ if err = c .Create (ctx , configMap ); err != nil {
1746+ return nil , fmt .Errorf ("failed to create ConfigMap: %w" , err )
1747+ }
1748+
1749+ return configMap , nil
1750+ }
1751+
1752+ func ParseImageMappingOverrides (configMapData map [string ]string ) map [string ]string {
1753+ imageMappingOverrides := make (map [string ]string )
1754+ logger := log .FromContext (context .Background ())
1755+
1756+ // Look for the image-overrides key in the ConfigMap data
1757+ if overridesYAML , exists := configMapData ["image-overrides" ]; exists {
1758+ // Parse the YAML content
1759+ var overrides map [string ]string
1760+ if err := yaml .Unmarshal ([]byte (overridesYAML ), & overrides ); err != nil {
1761+ // Log error but continue with empty overrides
1762+ logger .V (1 ).Info ("failed to parse image-overrides YAML" , "error" , err )
1763+ return imageMappingOverrides
16931764 }
16941765
1695- if err = client .Create (ctx , configMap ); err != nil {
1696- return nil , fmt .Errorf ("failed to create ConfigMap: %w" , err )
1766+ // Validate and copy the parsed overrides to our result map
1767+ for version , image := range overrides {
1768+ // Validate the image reference format
1769+ if _ , err := name .ParseReference (image ); err != nil {
1770+ logger .V (1 ).Info (
1771+ "skipping invalid image override" ,
1772+ "version" , version ,
1773+ "image" , image ,
1774+ "error" , err ,
1775+ )
1776+ continue
1777+ }
1778+ imageMappingOverrides [version ] = image
16971779 }
16981780 }
16991781
1700- // Parse feature flags from ConfigMap
1701- enableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
1702- if err != nil {
1703- return nil , fmt .Errorf ("failed to parse feature flags: %w" , err )
1704- }
1705- return & LlamaStackDistributionReconciler {
1706- Client : client ,
1707- Scheme : scheme ,
1708- EnableNetworkPolicy : enableNetworkPolicy ,
1709- ClusterInfo : clusterInfo ,
1710- httpClient : & http.Client {Timeout : 5 * time .Second },
1711- }, nil
1782+ return imageMappingOverrides
17121783}
17131784
17141785// NewTestReconciler creates a reconciler for testing, allowing injection of a custom http client and feature flags.
17151786func NewTestReconciler (client client.Client , scheme * runtime.Scheme , clusterInfo * cluster.ClusterInfo ,
17161787 httpClient * http.Client , enableNetworkPolicy bool ) * LlamaStackDistributionReconciler {
17171788 return & LlamaStackDistributionReconciler {
1718- Client : client ,
1719- Scheme : scheme ,
1720- ClusterInfo : clusterInfo ,
1721- httpClient : httpClient ,
1722- EnableNetworkPolicy : enableNetworkPolicy ,
1789+ Client : client ,
1790+ Scheme : scheme ,
1791+ ClusterInfo : clusterInfo ,
1792+ httpClient : httpClient ,
1793+ EnableNetworkPolicy : enableNetworkPolicy ,
1794+ ImageMappingOverrides : make (map [string ]string ),
17231795 }
17241796}
0 commit comments