github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controller/configuration/tool_image_builder.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package configuration
    21  
    22  import (
    23  	corev1 "k8s.io/api/core/v1"
    24  
    25  	appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1"
    26  	cfgcm "github.com/1aal/kubeblocks/pkg/configuration/config_manager"
    27  	"github.com/1aal/kubeblocks/pkg/constant"
    28  	"github.com/1aal/kubeblocks/pkg/controller/component"
    29  	"github.com/1aal/kubeblocks/pkg/controller/factory"
    30  	intctrlutil "github.com/1aal/kubeblocks/pkg/controllerutil"
    31  	viper "github.com/1aal/kubeblocks/pkg/viperx"
    32  )
    33  
    34  const (
    35  	toolsVolumeName                  = "kb-tools"
    36  	initSecRenderedToolContainerName = "init-secondary-rendered-tool"
    37  
    38  	tplRenderToolPath = "/bin/config_render"
    39  )
    40  
    41  func buildConfigToolsContainer(cfgManagerParams *cfgcm.CfgManagerBuildParams, podSpec *corev1.PodSpec, comp *component.SynthesizedComponent) error {
    42  	if len(cfgManagerParams.ConfigSpecsBuildParams) == 0 {
    43  		return nil
    44  	}
    45  
    46  	// construct config manager tools volume
    47  	toolContainers := make([]appsv1alpha1.ToolConfig, 0)
    48  	toolsMap := make(map[string]cfgcm.ConfigSpecMeta)
    49  	for _, buildParam := range cfgManagerParams.ConfigSpecsBuildParams {
    50  		if buildParam.ToolsImageSpec == nil {
    51  			continue
    52  		}
    53  		for _, toolConfig := range buildParam.ToolsImageSpec.ToolConfigs {
    54  			if _, ok := toolsMap[toolConfig.Name]; !ok {
    55  				replaceToolsImageHolder(&toolConfig, podSpec, buildParam.ConfigSpec.VolumeName)
    56  				toolContainers = append(toolContainers, toolConfig)
    57  				toolsMap[toolConfig.Name] = buildParam
    58  			}
    59  		}
    60  		buildToolsVolumeMount(cfgManagerParams, podSpec, buildParam.ConfigSpec.VolumeName, buildParam.ToolsImageSpec.MountPoint)
    61  	}
    62  
    63  	// Ensure that the order in which iniContainers are generated does not change
    64  	toolContainers = checkAndInstallToolsImageVolume(toolContainers, cfgManagerParams.ConfigSpecsBuildParams)
    65  	if len(toolContainers) == 0 {
    66  		return nil
    67  	}
    68  
    69  	containers, err := factory.BuildCfgManagerToolsContainer(cfgManagerParams, comp, toolContainers, toolsMap)
    70  	if err == nil {
    71  		cfgManagerParams.ToolsContainers = containers
    72  	}
    73  	return err
    74  }
    75  
    76  func checkAndInstallToolsImageVolume(toolContainers []appsv1alpha1.ToolConfig, buildParams []cfgcm.ConfigSpecMeta) []appsv1alpha1.ToolConfig {
    77  	for _, buildParam := range buildParams {
    78  		if buildParam.ToolsImageSpec != nil && buildParam.ConfigSpec.LegacyRenderedConfigSpec != nil {
    79  			// auto install config_render tool
    80  			toolContainers = checkAndCreateRenderedInitContainer(toolContainers, buildParam.ToolsImageSpec.MountPoint)
    81  		}
    82  	}
    83  	return toolContainers
    84  }
    85  
    86  func checkAndCreateRenderedInitContainer(toolContainers []appsv1alpha1.ToolConfig, mountPoint string) []appsv1alpha1.ToolConfig {
    87  	kbToolsImage := viper.GetString(constant.KBToolsImage)
    88  	for _, container := range toolContainers {
    89  		if container.Name == initSecRenderedToolContainerName {
    90  			return nil
    91  		}
    92  	}
    93  	toolContainers = append(toolContainers, appsv1alpha1.ToolConfig{
    94  		Name:    initSecRenderedToolContainerName,
    95  		Image:   kbToolsImage,
    96  		Command: []string{"cp", tplRenderToolPath, mountPoint},
    97  	})
    98  	return toolContainers
    99  }
   100  
   101  func replaceToolsImageHolder(toolConfig *appsv1alpha1.ToolConfig, podSpec *corev1.PodSpec, volumeName string) {
   102  	switch {
   103  	case toolConfig.Image == constant.KBToolsImagePlaceHolder:
   104  		toolConfig.Image = viper.GetString(constant.KBToolsImage)
   105  	case toolConfig.Image == "":
   106  		usingContainers := intctrlutil.GetPodContainerWithVolumeMount(podSpec, volumeName)
   107  		if len(usingContainers) != 0 {
   108  			toolConfig.Image = usingContainers[0].Image
   109  		}
   110  	}
   111  }
   112  
   113  func buildToolsVolumeMount(cfgManagerParams *cfgcm.CfgManagerBuildParams, podSpec *corev1.PodSpec, volumeName string, mountPoint string) {
   114  	if cfgcm.FindVolumeMount(cfgManagerParams.Volumes, toolsVolumeName) != nil {
   115  		return
   116  	}
   117  	cfgManagerParams.ScriptVolume = append(cfgManagerParams.ScriptVolume, corev1.Volume{
   118  		Name: toolsVolumeName,
   119  		VolumeSource: corev1.VolumeSource{
   120  			EmptyDir: &corev1.EmptyDirVolumeSource{},
   121  		},
   122  	})
   123  
   124  	n := len(cfgManagerParams.Volumes)
   125  	cfgManagerParams.Volumes = append(cfgManagerParams.Volumes, corev1.VolumeMount{
   126  		Name:      toolsVolumeName,
   127  		MountPath: mountPoint,
   128  	})
   129  
   130  	usingContainers := intctrlutil.GetPodContainerWithVolumeMount(podSpec, volumeName)
   131  	for _, container := range usingContainers {
   132  		container.VolumeMounts = append(container.VolumeMounts, cfgManagerParams.Volumes[n])
   133  	}
   134  }