New label to get volumes from another service

- fix container name
- the volume-from label works only with "same-pod" label of course. It
  allows the use of the same volume from another service to be shared in
  a same pod. E.g. php-fpm + nginx
This commit is contained in:
2022-05-07 10:07:10 +02:00
parent b1b96d8318
commit 2e1950174c
2 changed files with 87 additions and 9 deletions

View File

@@ -359,9 +359,7 @@ func prepareVolumes(deployment, name string, s *types.ServiceConfig, container *
// the volume is a path and it's explicitally asked to be a configmap in labels
cm := buildCMFromPath(name, volname)
volname = strings.Replace(volname, "./", "", 1)
volname = strings.ReplaceAll(volname, "/", "-")
volname = strings.ReplaceAll(volname, ".", "-")
volname = PathToName(volname)
cm.K8sBase.Metadata.Name = helm.ReleaseNameTpl + "-" + name + "-" + volname
// build a configmap from the volume path
@@ -402,7 +400,7 @@ func prepareVolumes(deployment, name string, s *types.ServiceConfig, container *
"name": volname,
"mountPath": volepath,
})
container.VolumeMounts = mountPoints
container.VolumeMounts = append(container.VolumeMounts, mountPoints...)
isEmptyDir = true
break
}
@@ -433,7 +431,7 @@ func prepareVolumes(deployment, name string, s *types.ServiceConfig, container *
}
}
}
container.VolumeMounts = mountPoints
container.VolumeMounts = append(container.VolumeMounts, mountPoints...)
return volumes
}
@@ -570,10 +568,8 @@ func prepareEnvFromFiles(name string, s *types.ServiceConfig, container *helm.Co
// manage environment files (env_file in compose)
for _, envfile := range s.EnvFile {
f := strings.ReplaceAll(envfile, "_", "-")
f := PathToName(envfile)
f = strings.ReplaceAll(f, ".env", "")
f = strings.ReplaceAll(f, ".", "")
f = strings.ReplaceAll(f, "/", "")
isSecret := false
for _, s := range secretsFiles {
s = strings.TrimSpace(s)
@@ -787,7 +783,7 @@ func newContainerForDeployment(deployName, containerName string, deployment *hel
})
}
setEnvToValues(containerName, s, container)
prepareContainer(container, s, deployName)
prepareContainer(container, s, containerName)
prepareEnvFromFiles(deployName, s, container, fileGeneratorChan)
// add the container in deployment
@@ -803,6 +799,9 @@ func newContainerForDeployment(deployName, containerName string, deployment *hel
if deployment.Spec.Template.Spec.Volumes == nil {
deployment.Spec.Template.Spec.Volumes = make([]map[string]interface{}, 0)
}
// manage LABEL_VOLUMEFROM
addVolumeFrom(deployment, container, s)
// and then we can add other volumes
deployment.Spec.Template.Spec.Volumes = append(
deployment.Spec.Template.Spec.Volumes,
prepareVolumes(deployName, containerName, s, container, fileGeneratorChan)...,
@@ -819,3 +818,79 @@ func newContainerForDeployment(deployName, containerName string, deployment *hel
return container
}
// addVolumeFrom takes the LABEL_VOLUMEFROM to get volumes from another container. This can only work with
// container that has got LABEL_SAMEPOD as we need to get the volumes from another container in the same deployment.
func addVolumeFrom(deployment *helm.Deployment, container *helm.Container, s *types.ServiceConfig) {
labelfrom, ok := s.Labels[helm.LABEL_VOLUMEFROM]
if !ok {
return
}
// decode Yaml from the label
var volumesFrom map[string]map[string]string
err := yaml.Unmarshal([]byte(labelfrom), &volumesFrom)
if err != nil {
logger.ActivateColors = true
logger.Red(err.Error())
logger.ActivateColors = false
return
}
// for each declared volume "from", we will find it from the deployment volumes and add it to the container.
// Then, to avoid duplicates, we will remove it from the ServiceConfig object.
for name, volumes := range volumesFrom {
for volumeName := range volumes {
initianame := volumeName
volumeName = PathToName(volumeName)
// get the volume from the deployment container "name"
var ctn *helm.Container
for _, c := range deployment.Spec.Template.Spec.Containers {
if c.Name == name {
ctn = c
break
}
}
if ctn == nil {
logger.ActivateColors = true
logger.Red("VolumeFrom: container %s not found", name)
logger.ActivateColors = false
continue
}
// get the volume from the container
for _, v := range ctn.VolumeMounts {
switch v := v.(type) {
case map[string]interface{}:
if v["name"] == volumeName {
if container.VolumeMounts == nil {
container.VolumeMounts = make([]interface{}, 0)
}
// make a copy of the volume mount and then add it to the VolumeMounts
var mountpoint = make(map[string]interface{})
for k, v := range v {
mountpoint[k] = v
}
container.VolumeMounts = append(container.VolumeMounts, mountpoint)
// remove the volume from the ServiceConfig
volumes := s.Volumes
for i, vol := range volumes {
if vol.Source == initianame {
volumes = append(volumes[:i], volumes[i+1:]...)
break
}
}
s.Volumes = volumes
}
}
}
}
}
}
func PathToName(path string) string {
path = strings.TrimPrefix(path, "./")
path = strings.ReplaceAll(path, ".", "-")
path = strings.ReplaceAll(path, "/", "-")
return path
}

View File

@@ -14,6 +14,7 @@ const (
LABEL_VOL_CM = K + "/configmap-volumes"
LABEL_HEALTHCHECK = K + "/healthcheck"
LABEL_SAMEPOD = K + "/same-pod"
LABEL_VOLUMEFROM = K + "/volume-from"
LABEL_EMPTYDIRS = K + "/empty-dirs"
LABEL_IGNORE = K + "/ignore"
LABEL_SECRETVARS = K + "/secret-vars"
@@ -34,6 +35,7 @@ func GetLabelsDocumentation() string {
{{.LABEL_INGRESS | printf "%-33s"}}: set the port to expose in an ingress (coma separated)
{{.LABEL_VOL_CM | printf "%-33s"}}: specifies that the volumes points on a configmap (coma separated)
{{.LABEL_SAMEPOD | printf "%-33s"}}: specifies that the pod should be deployed in the same pod than the given service name
{{.LABEL_VOLUMEFROM | printf "%-33s"}}: specifies that the volumes to be mounted from the given service (yaml style)
{{.LABEL_EMPTYDIRS | printf "%-33s"}}: specifies that the given volume names should be "emptyDir" instead of persistentVolumeClaim (coma separated)
{{.LABEL_HEALTHCHECK | printf "%-33s"}}: specifies that the container should be monitored by a healthcheck, **it overrides the docker-compose healthcheck**.
{{ printf "%-34s" ""}} You can use these form of label values:
@@ -49,6 +51,7 @@ func GetLabelsDocumentation() string {
"LABEL_VOL_CM": LABEL_VOL_CM,
"LABEL_HEALTHCHECK": LABEL_HEALTHCHECK,
"LABEL_SAMEPOD": LABEL_SAMEPOD,
"LABEL_VOLUMEFROM": LABEL_VOLUMEFROM,
"LABEL_EMPTYDIRS": LABEL_EMPTYDIRS,
"LABEL_IGNORE": LABEL_IGNORE,
"LABEL_MAP_ENV": LABEL_MAP_ENV,