From 66944baad657aded4aba07fac28ea590e120afac Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Wed, 18 Nov 2020 20:51:59 +0100 Subject: [PATCH] Add support for persistent volume claims in kube files In k8s a persistent volume claim (PVC) allow pods to define a volume by referencing the name of a PVC. The PVC basically contains criterias that k8s then use to select which storage source it will use for the volume. Podman only provide one abtracted storage, the named volumes, and create them if they don't exists yet. So this patch simply use a volume with the name of the PVC. Signed-off-by: Alban Bedel --- pkg/specgen/generate/kube/kube.go | 9 +++++++ pkg/specgen/generate/kube/volume.go | 15 +++++++++-- test/e2e/play_kube_test.go | 41 +++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index aee30b6525..5f72d28bbe 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -181,6 +181,15 @@ func ToSpecGen(ctx context.Context, containerYAML v1.Container, iid string, newI mount.Options = []string{"ro"} } s.Mounts = append(s.Mounts, mount) + case KubeVolumeTypeNamed: + namedVolume := specgen.NamedVolume{ + Dest: volume.MountPath, + Name: volumeSource.Source, + } + if volume.ReadOnly { + namedVolume.Options = []string{"ro"} + } + s.Volumes = append(s.Volumes, &namedVolume) default: return nil, errors.Errorf("Unsupported volume source type") } diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index b24583e8e4..2ef0f4c23b 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -21,12 +21,13 @@ type KubeVolumeType int const ( KubeVolumeTypeBindMount KubeVolumeType = iota + KubeVolumeTypeNamed KubeVolumeType = iota ) type KubeVolume struct { // Type of volume to create Type KubeVolumeType - // Path for bind mount + // Path for bind mount or volume name for named volume Source string } @@ -87,12 +88,22 @@ func VolumeFromHostPath(hostPath *v1.HostPathVolumeSource) (*KubeVolume, error) }, nil } +// Create a KubeVolume from a PersistentVolumeClaimVolumeSource +func VolumeFromPersistentVolumeClaim(claim *v1.PersistentVolumeClaimVolumeSource) (*KubeVolume, error) { + return &KubeVolume{ + Type: KubeVolumeTypeNamed, + Source: claim.ClaimName, + }, nil +} + // Create a KubeVolume from one of the supported VolumeSource func VolumeFromSource(volumeSource v1.VolumeSource) (*KubeVolume, error) { if volumeSource.HostPath != nil { return VolumeFromHostPath(volumeSource.HostPath) + } else if volumeSource.PersistentVolumeClaim != nil { + return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim) } else { - return nil, errors.Errorf("HostPath is currently the only supported VolumeSource") + return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the conly supported VolumeSource") } } diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index eb82b3862f..5ecfdd6b50 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -169,6 +169,10 @@ spec: path: {{ .HostPath.Path }} type: {{ .HostPath.Type }} {{- end }} + {{- if (eq .VolumeType "PersistentVolumeClaim") }} + persistentVolumeClaim: + claimName: {{ .PersistentVolumeClaim.ClaimName }} + {{- end }} {{ end }} {{ end }} status: {} @@ -699,10 +703,15 @@ type HostPath struct { Type string } +type PersistentVolumeClaim struct { + ClaimName string +} + type Volume struct { VolumeType string Name string HostPath + PersistentVolumeClaim } // getHostPathVolume takes a type and a location for a HostPath @@ -718,6 +727,18 @@ func getHostPathVolume(vType, vPath string) *Volume { } } +// getHostPathVolume takes a name for a Persistentvolumeclaim +// volume giving it a default name of volName +func getPersistentVolumeClaimVolume(vName string) *Volume { + return &Volume{ + VolumeType: "PersistentVolumeClaim", + Name: defaultVolName, + PersistentVolumeClaim: PersistentVolumeClaim{ + ClaimName: vName, + }, + } +} + type Env struct { Name string Value string @@ -1389,6 +1410,26 @@ spec: Expect(inspect.OutputToString()).To(ContainSubstring(correct)) }) + It("podman play kube test with PersistentVolumeClaim volume", func() { + volumeName := "namedVolume" + + ctr := getCtr(withVolumeMount("/test", false), withImage(BB)) + pod := getPod(withVolume(getPersistentVolumeClaimVolume(volumeName)), withCtr(ctr)) + err = generateKubeYaml("pod", pod, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ (index .Mounts 0).Type }}:{{ (index .Mounts 0).Name }}"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + + correct := fmt.Sprintf("volume:%s", volumeName) + Expect(inspect.OutputToString()).To(Equal(correct)) + }) + It("podman play kube applies labels to pods", func() { var numReplicas int32 = 5 expectedLabelKey := "key1"