From 1e255b6df92b8797acc91f95a53b88c044dfd683 Mon Sep 17 00:00:00 2001
From: Jordan Williams <jordan@jwillikers.com>
Date: Wed, 17 Mar 2021 13:39:33 -0500
Subject: Generate Kubernetes PersistentVolumeClaims from named volumes

Fixes #5788

This commit adds support for named volumes in podman-generate-kube.
Named volumes are output in the YAML as PersistentVolumeClaims.
To avoid naming conflicts, the volume name is suffixed with "-pvc".
This commit adds a corresponding suffix for host path mounts.
Host path volumes are suffixed with "-host".

Signed-off-by: Jordan Williams <jordan@jwillikers.com>
---
 libpod/kube.go | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

(limited to 'libpod')

diff --git a/libpod/kube.go b/libpod/kube.go
index 407c4ae00..b4dd4f10a 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -330,8 +330,6 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNS
 	}
 
 	if len(c.config.UserVolumes) > 0 {
-		// TODO When we until we can resolve what the volume name should be, this is disabled
-		// Volume names need to be coordinated "globally" in the kube files.
 		volumeMounts, volumes, err := libpodMountsToKubeVolumeMounts(c)
 		if err != nil {
 			return kubeContainer, kubeVolumes, nil, err
@@ -493,8 +491,7 @@ func libpodEnvVarsToKubeEnvVars(envs []string) ([]v1.EnvVar, error) {
 
 // libpodMountsToKubeVolumeMounts converts the containers mounts to a struct kube understands
 func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume, error) {
-	// TODO when named volumes are supported in play kube, also parse named volumes here
-	_, mounts := c.sortUserVolumes(c.config.Spec)
+	namedVolumes, mounts := c.sortUserVolumes(c.config.Spec)
 	vms := make([]v1.VolumeMount, 0, len(mounts))
 	vos := make([]v1.Volume, 0, len(mounts))
 	for _, m := range mounts {
@@ -505,9 +502,34 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume
 		vms = append(vms, vm)
 		vos = append(vos, vo)
 	}
+	for _, v := range namedVolumes {
+		vm, vo := generateKubePersistentVolumeClaim(v)
+		vms = append(vms, vm)
+		vos = append(vos, vo)
+	}
 	return vms, vos, nil
 }
 
+// generateKubePersistentVolumeClaim converts a ContainerNamedVolume to a Kubernetes PersistentVolumeClaim
+func generateKubePersistentVolumeClaim(v *ContainerNamedVolume) (v1.VolumeMount, v1.Volume) {
+	ro := util.StringInSlice("ro", v.Options)
+
+	// To avoid naming conflicts with any host path mounts, add a unique suffix to the volume's name.
+	name := v.Name + "-pvc"
+
+	vm := v1.VolumeMount{}
+	vm.Name = name
+	vm.MountPath = v.Dest
+	vm.ReadOnly = ro
+
+	pvc := v1.PersistentVolumeClaimVolumeSource{ClaimName: v.Name, ReadOnly: ro}
+	vs := v1.VolumeSource{}
+	vs.PersistentVolumeClaim = &pvc
+	vo := v1.Volume{Name: name, VolumeSource: vs}
+
+	return vm, vo
+}
+
 // generateKubeVolumeMount takes a user specified mount and returns
 // a kubernetes VolumeMount (to be added to the container) and a kubernetes Volume
 // (to be added to the pod)
@@ -519,6 +541,8 @@ func generateKubeVolumeMount(m specs.Mount) (v1.VolumeMount, v1.Volume, error) {
 	if err != nil {
 		return vm, vo, err
 	}
+	// To avoid naming conflicts with any persistent volume mounts, add a unique suffix to the volume's name.
+	name += "-host"
 	vm.Name = name
 	vm.MountPath = m.Destination
 	if util.StringInSlice("ro", m.Options) {
-- 
cgit v1.2.3-54-g00ecf