@@ -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"
@@ -94,6 +95,8 @@ type LlamaStackDistributionReconciler struct {
9495 Scheme * runtime.Scheme
9596 // Feature flags
9697 EnableNetworkPolicy bool
98+ // Image mapping overrides
99+ ImageMappingOverrides map [string ]string
97100 // Cluster info
98101 ClusterInfo * cluster.ClusterInfo
99102 httpClient * http.Client
@@ -682,21 +685,40 @@ func (r *LlamaStackDistributionReconciler) configMapUpdatePredicate(e event.Upda
682685 return false
683686 }
684687
685- // Parse the feature flags if the operator config ConfigMap has changed
688+ // Check if this is the operator config ConfigMap
689+ if r .handleOperatorConfigUpdate (newConfigMap ) {
690+ return true
691+ }
692+
693+ // Handle referenced ConfigMap updates
694+ return r .handleReferencedConfigMapUpdate (oldConfigMap , newConfigMap )
695+ }
696+
697+ // handleOperatorConfigUpdate processes updates to the operator config ConfigMap.
698+ func (r * LlamaStackDistributionReconciler ) handleOperatorConfigUpdate (configMap * corev1.ConfigMap ) bool {
686699 operatorNamespace , err := deploy .GetOperatorNamespace ()
687700 if err != nil {
688701 return false
689702 }
690- if newConfigMap .Name == operatorConfigData && newConfigMap .Namespace == operatorNamespace {
691- EnableNetworkPolicy , err := parseFeatureFlags (newConfigMap .Data )
692- if err != nil {
693- log .FromContext (context .Background ()).Error (err , "Failed to parse feature flags" )
694- } else {
695- r .EnableNetworkPolicy = EnableNetworkPolicy
696- }
697- return true
703+
704+ if configMap .Name != operatorConfigData || configMap .Namespace != operatorNamespace {
705+ return false
698706 }
699707
708+ // Update feature flags
709+ EnableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
710+ if err != nil {
711+ log .FromContext (context .Background ()).Error (err , "Failed to parse feature flags" )
712+ } else {
713+ r .EnableNetworkPolicy = EnableNetworkPolicy
714+ }
715+
716+ r .ImageMappingOverrides = ParseImageMappingOverrides (context .Background (), configMap .Data )
717+ return true
718+ }
719+
720+ // handleReferencedConfigMapUpdate processes updates to referenced ConfigMaps.
721+ func (r * LlamaStackDistributionReconciler ) handleReferencedConfigMapUpdate (oldConfigMap , newConfigMap * corev1.ConfigMap ) bool {
700722 // Only proceed if this ConfigMap is referenced by any LlamaStackDistribution
701723 if ! r .isConfigMapReferenced (newConfigMap ) {
702724 return false
@@ -868,7 +890,7 @@ func (r *LlamaStackDistributionReconciler) findLlamaStackDistributionsForConfigM
868890
869891 operatorNamespace , err := deploy .GetOperatorNamespace ()
870892 if err != nil {
871- log . FromContext ( context . Background ()) .Error (err , "Failed to get operator namespace for config map event processing" )
893+ logger .Error (err , "Failed to get operator namespace for config map event processing" )
872894 return nil
873895 }
874896 // If the operator config was changed, we reconcile all LlamaStackDistributions
@@ -1753,53 +1775,103 @@ func NewLlamaStackDistributionReconciler(ctx context.Context, client client.Clie
17531775 return nil , fmt .Errorf ("failed to get operator namespace: %w" , err )
17541776 }
17551777
1756- // Get the ConfigMap
1757- // If the ConfigMap doesn't exist, create it with default feature flags
1758- // If the ConfigMap exists, parse the feature flags from the Configmap
1778+ // Initialize operator config ConfigMap
1779+ configMap , err := initializeOperatorConfigMap (ctx , client , operatorNamespace )
1780+ if err != nil {
1781+ return nil , err
1782+ }
1783+
1784+ // Parse feature flags from ConfigMap
1785+ enableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
1786+ if err != nil {
1787+ return nil , fmt .Errorf ("failed to parse feature flags: %w" , err )
1788+ }
1789+
1790+ // Parse image mapping overrides from ConfigMap
1791+ imageMappingOverrides := ParseImageMappingOverrides (ctx , configMap .Data )
1792+
1793+ return & LlamaStackDistributionReconciler {
1794+ Client : client ,
1795+ Scheme : scheme ,
1796+ EnableNetworkPolicy : enableNetworkPolicy ,
1797+ ImageMappingOverrides : imageMappingOverrides ,
1798+ ClusterInfo : clusterInfo ,
1799+ httpClient : & http.Client {Timeout : 5 * time .Second },
1800+ }, nil
1801+ }
1802+
1803+ // initializeOperatorConfigMap gets or creates the operator config ConfigMap.
1804+ func initializeOperatorConfigMap (ctx context.Context , c client.Client , operatorNamespace string ) (* corev1.ConfigMap , error ) {
17591805 configMap := & corev1.ConfigMap {}
17601806 configMapName := types.NamespacedName {
17611807 Name : operatorConfigData ,
17621808 Namespace : operatorNamespace ,
17631809 }
17641810
1765- if err = client .Get (ctx , configMapName , configMap ); err != nil {
1766- if ! k8serrors . IsNotFound ( err ) {
1767- return nil , fmt . Errorf ( "failed to get ConfigMap: %w" , err )
1768- }
1811+ err := c .Get (ctx , configMapName , configMap )
1812+ if err == nil {
1813+ return configMap , nil
1814+ }
17691815
1770- // ConfigMap doesn't exist, create it with defaults
1771- configMap , err = createDefaultConfigMap (configMapName )
1772- if err != nil {
1773- return nil , fmt .Errorf ("failed to generate default configMap: %w" , err )
1816+ if ! k8serrors .IsNotFound (err ) {
1817+ return nil , fmt .Errorf ("failed to get ConfigMap: %w" , err )
1818+ }
1819+
1820+ // ConfigMap doesn't exist, create it with defaults
1821+ configMap , err = createDefaultConfigMap (configMapName )
1822+ if err != nil {
1823+ return nil , fmt .Errorf ("failed to generate default configMap: %w" , err )
1824+ }
1825+
1826+ if err = c .Create (ctx , configMap ); err != nil {
1827+ return nil , fmt .Errorf ("failed to create ConfigMap: %w" , err )
1828+ }
1829+
1830+ return configMap , nil
1831+ }
1832+
1833+ func ParseImageMappingOverrides (ctx context.Context , configMapData map [string ]string ) map [string ]string {
1834+ imageMappingOverrides := make (map [string ]string )
1835+ logger := log .FromContext (ctx )
1836+
1837+ // Look for the image-overrides key in the ConfigMap data
1838+ if overridesYAML , exists := configMapData ["image-overrides" ]; exists {
1839+ // Parse the YAML content
1840+ var overrides map [string ]string
1841+ if err := yaml .Unmarshal ([]byte (overridesYAML ), & overrides ); err != nil {
1842+ // Log error but continue with empty overrides
1843+ logger .V (1 ).Info ("failed to parse image-overrides YAML" , "error" , err )
1844+ return imageMappingOverrides
17741845 }
17751846
1776- if err = client .Create (ctx , configMap ); err != nil {
1777- return nil , fmt .Errorf ("failed to create ConfigMap: %w" , err )
1847+ // Validate and copy the parsed overrides to our result map
1848+ for version , image := range overrides {
1849+ // Validate the image reference format
1850+ if _ , err := name .ParseReference (image ); err != nil {
1851+ logger .V (1 ).Info (
1852+ "skipping invalid image override" ,
1853+ "version" , version ,
1854+ "image" , image ,
1855+ "error" , err ,
1856+ )
1857+ continue
1858+ }
1859+ imageMappingOverrides [version ] = image
17781860 }
17791861 }
17801862
1781- // Parse feature flags from ConfigMap
1782- enableNetworkPolicy , err := parseFeatureFlags (configMap .Data )
1783- if err != nil {
1784- return nil , fmt .Errorf ("failed to parse feature flags: %w" , err )
1785- }
1786- return & LlamaStackDistributionReconciler {
1787- Client : client ,
1788- Scheme : scheme ,
1789- EnableNetworkPolicy : enableNetworkPolicy ,
1790- ClusterInfo : clusterInfo ,
1791- httpClient : & http.Client {Timeout : 5 * time .Second },
1792- }, nil
1863+ return imageMappingOverrides
17931864}
17941865
17951866// NewTestReconciler creates a reconciler for testing, allowing injection of a custom http client and feature flags.
17961867func NewTestReconciler (client client.Client , scheme * runtime.Scheme , clusterInfo * cluster.ClusterInfo ,
17971868 httpClient * http.Client , enableNetworkPolicy bool ) * LlamaStackDistributionReconciler {
17981869 return & LlamaStackDistributionReconciler {
1799- Client : client ,
1800- Scheme : scheme ,
1801- ClusterInfo : clusterInfo ,
1802- httpClient : httpClient ,
1803- EnableNetworkPolicy : enableNetworkPolicy ,
1870+ Client : client ,
1871+ Scheme : scheme ,
1872+ ClusterInfo : clusterInfo ,
1873+ httpClient : httpClient ,
1874+ EnableNetworkPolicy : enableNetworkPolicy ,
1875+ ImageMappingOverrides : make (map [string ]string ),
18041876 }
18051877}
0 commit comments