From 50975ae94ab3b48c65b1e24391c9e2cb38d32f38 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Tue, 23 Apr 2024 08:05:00 +0200 Subject: [PATCH] Fix static volume binding It is possible there are many things like this to fix. I made too much complexity on searching services in deployment while the map key is enough to get the righ deployment for a compose service. Need to check the "same-pod" possibilities later. --- generator/deployment.go | 38 +++++++++-------- generator/generator.go | 90 ++++++++++++++++++++++++----------------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/generator/deployment.go b/generator/deployment.go index bfe5bfe..2ee7f37 100644 --- a/generator/deployment.go +++ b/generator/deployment.go @@ -89,7 +89,7 @@ func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment { }, }, }, - configMaps: map[string]*ConfigMapMount{}, + configMaps: make(map[string]*ConfigMapMount), } // add containers @@ -204,6 +204,10 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) { } container, index := utils.GetContainerByName(service.Name, d.Spec.Template.Spec.Containers) + defer func(d *Deployment, container *corev1.Container, index int) { + d.Spec.Template.Spec.Containers[index] = *container + }(d, container, index) + for _, volume := range service.Volumes { // not declared as a bind volume, skip if _, ok := tobind[volume.Source]; !isSamePod && volume.Type == "bind" && !ok { @@ -279,35 +283,35 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) { } } else { dirname := filepath.Dir(volume.Source) - pathnme := utils.PathToName(dirname) + pathname := utils.PathToName(dirname) var cm *ConfigMap - if v, ok := d.configMaps[pathnme]; !ok { + if v, ok := d.configMaps[pathname]; !ok { cm = NewConfigMap(*d.service, appName) cm.usage = FileMapUsageFiles cm.path = dirname - cm.Name = utils.TplName(service.Name, appName) + "-" + pathnme - d.configMaps[pathnme] = &ConfigMapMount{ + cm.Name = utils.TplName(service.Name, appName) + "-" + pathname + // assign a new mountPathConfig to the configMap + d.configMaps[pathname] = &ConfigMapMount{ configMap: cm, - mountPath: []mountPathConfig{}, + mountPath: []mountPathConfig{{ + mountPath: volume.Target, + subPath: filepath.Base(volume.Source), + }}, } } else { cm = v.configMap - } - - cm.AppendFile(volume.Source) - d.configMaps[pathnme] = &ConfigMapMount{ - configMap: cm, - mountPath: append(d.configMaps[pathnme].mountPath, mountPathConfig{ + mp := d.configMaps[pathname].mountPath + mp = append(mp, mountPathConfig{ mountPath: volume.Target, subPath: filepath.Base(volume.Source), - }), + }) + d.configMaps[pathname].mountPath = mp + } + cm.AppendFile(volume.Source) } } - } - - d.Spec.Template.Spec.Containers[index] = *container } func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) { @@ -496,7 +500,7 @@ func (d *Deployment) Yaml() ([]byte, error) { continue } - if strings.Contains(volume, "- mountPath: ") { + if strings.Contains(volume, "mountPath: ") { spaces = strings.Repeat(" ", utils.CountStartingSpaces(volume)) content[line] = spaces + `{{- if .Values.` + serviceName + `.persistence.` + volumeName + `.enabled }}` + "\n" + volume changing = true diff --git a/generator/generator.go b/generator/generator.go index 850753f..f08e237 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -114,11 +114,16 @@ func Generate(project *types.Project) (*HelmChart, error) { // now we have all deployments, we can create PVC if needed (it's separated from // the above loop because we need all deployments to not duplicate PVC for "same-pod" services) + // bind static volumes + for _, service := range project.Services { + addStaticVolumes(deployments, service) + } for _, service := range project.Services { if err := buildVolumes(service, chart, deployments); err != nil { return nil, err } } + // drop all "same-pod" deployments because the containers and volumes are already // in the target deployment for _, service := range podToMerge { @@ -156,7 +161,10 @@ func Generate(project *types.Project) (*HelmChart, error) { // generate yaml files for _, d := range deployments { - y, _ := d.Yaml() + y, err := d.Yaml() + if err != nil { + return nil, err + } chart.Templates[d.Filename()] = &ChartTemplate{ Content: y, Servicename: d.service.Name, @@ -386,47 +394,55 @@ func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map } } - // add the bound configMaps files to the deployment containers - for _, d := range deployments { - container, index := utils.GetContainerByName(service.Name, d.Spec.Template.Spec.Containers) - if container == nil { // may append for the same-pod services - break - } - for volumeName, config := range d.configMaps { - var y []byte - var err error - if y, err = config.configMap.Yaml(); err != nil { - log.Fatal(err) - } - // add the configmap to the chart - d.chart.Templates[config.configMap.Filename()] = &ChartTemplate{ - Content: y, - Servicename: d.service.Name, - } - // add the moint path to the container - for _, m := range config.mountPath { - container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ - Name: utils.PathToName(volumeName), - MountPath: m.mountPath, - SubPath: m.subPath, - }) - } + return nil +} - d.Spec.Template.Spec.Volumes = append(d.Spec.Template.Spec.Volumes, corev1.Volume{ - Name: utils.PathToName(volumeName), - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: config.configMap.Name, - }, - }, - }, +func addStaticVolumes(deployments map[string]*Deployment, service types.ServiceConfig) { + // add the bound configMaps files to the deployment containers + var d *Deployment + var ok bool + if d, ok = deployments[service.Name]; !ok { + log.Printf("service %s not found in deployments", service.Name) + return + } + + container, index := utils.GetContainerByName(service.Name, d.Spec.Template.Spec.Containers) + if container == nil { // may append for the same-pod services + return + } + for volumeName, config := range d.configMaps { + var y []byte + var err error + if y, err = config.configMap.Yaml(); err != nil { + log.Fatal(err) + } + // add the configmap to the chart + d.chart.Templates[config.configMap.Filename()] = &ChartTemplate{ + Content: y, + Servicename: d.service.Name, + } + // add the moint path to the container + for _, m := range config.mountPath { + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: utils.PathToName(volumeName), + MountPath: m.mountPath, + SubPath: m.subPath, }) } - d.Spec.Template.Spec.Containers[index] = *container + d.Spec.Template.Spec.Volumes = append(d.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: utils.PathToName(volumeName), + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: config.configMap.Name, + }, + }, + }, + }) } - return nil + + d.Spec.Template.Spec.Containers[index] = *container } // generateConfigMapsAndSecrets creates the configmaps and secrets from the environment variables.