1
0
Fork 0
mirror of https://github.com/kastenhq/kubestr.git synced 2024-12-14 11:57:56 +00:00

Updating CreatePodArgs to consume PVC args in []string{} format instead of string (#285)

* Updating the PVCName, MountPath, DevicePath signature in CreatePodArgs

* Refactoring PVCName, MountPath, DevicePath variables into a single PVCMap with path definitions

* Removing unused PVCName variable from CreatePodArgs

* Updating DevicePath and MountPath error messages
This commit is contained in:
Shlok Chaudhari 2024-08-07 15:06:53 -05:00 committed by GitHub
parent 6a5cc24f36
commit e2e1a6e51a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 194 additions and 103 deletions

View file

@ -133,13 +133,16 @@ func (b *blockMountChecker) Mount(ctx context.Context) (*BlockMountCheckerResult
tB = time.Now()
_, err = b.appCreator.CreatePod(ctx, &types.CreatePodArgs{
Name: b.podName,
PVCName: b.pvcName,
Namespace: b.args.Namespace,
RunAsUser: b.args.RunAsUser,
ContainerImage: b.args.ContainerImage,
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "tail -f /dev/null"},
DevicePath: "/mnt/block",
PVCMap: map[string]types.VolumePath{
b.pvcName: {
DevicePath: "/mnt/block",
},
},
})
if err != nil {
fmt.Printf(" -> Failed to create Pod (%v)\n", err)

View file

@ -299,13 +299,16 @@ func TestBlockMountCheckerMount(t *testing.T) {
createPodArgs := func(b *blockMountChecker) *types.CreatePodArgs {
return &types.CreatePodArgs{
Name: b.podName,
PVCName: b.pvcName,
Namespace: b.args.Namespace,
RunAsUser: b.args.RunAsUser,
ContainerImage: b.args.ContainerImage,
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "tail -f /dev/null"},
DevicePath: "/mnt/block",
PVCMap: map[string]types.VolumePath{
b.pvcName: {
DevicePath: "/mnt/block",
},
},
}
}
createPod := func(b *blockMountChecker) *v1.Pod {

View file

@ -208,27 +208,28 @@ func (c *applicationCreate) CreatePod(ctx context.Context, args *types.CreatePod
Command: args.Command,
Args: args.ContainerArgs,
}},
Volumes: []v1.Volume{{
Name: volumeNameInPod,
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
ClaimName: args.PVCName,
},
}},
},
},
}
if args.MountPath != "" {
pod.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{{
Name: volumeNameInPod,
MountPath: args.MountPath,
}}
} else { // args.DevicePath
pod.Spec.Containers[0].VolumeDevices = []v1.VolumeDevice{{
Name: volumeNameInPod,
DevicePath: args.DevicePath,
}}
for pvcName, path := range args.PVCMap {
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
Name: fmt.Sprintf("%s-%s", volumeNameInPod, pvcName),
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
ClaimName: pvcName,
},
},
})
if len(path.MountPath) != 0 {
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{
Name: fmt.Sprintf("%s-%s", volumeNameInPod, pvcName),
MountPath: path.MountPath,
})
} else {
pod.Spec.Containers[0].VolumeDevices = append(pod.Spec.Containers[0].VolumeDevices, v1.VolumeDevice{
Name: fmt.Sprintf("%s-%s", volumeNameInPod, pvcName),
DevicePath: path.DevicePath,
})
}
}
if args.RunAsUser > 0 {

View file

@ -517,12 +517,15 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
RunAsUser: 1000,
ContainerImage: "containerimage",
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
errChecker: IsNil,
podChecker: NotNil,
@ -532,10 +535,13 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
failCreates: true,
errChecker: NotNil,
@ -546,10 +552,13 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
errChecker: NotNil,
podChecker: IsNil,
@ -560,10 +569,13 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
args: &types.CreatePodArgs{
GenerateName: "name",
Name: "name",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
errChecker: NotNil,
podChecker: IsNil,
@ -573,9 +585,9 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "",
Namespace: "ns",
Command: []string{"somecommand"},
PVCMap: map[string]types.VolumePath{"pvcname": {}},
},
errChecker: NotNil,
podChecker: IsNil,
@ -585,11 +597,14 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
DevicePath: "/mnt/dev",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
DevicePath: "/mnt/dev",
},
},
},
errChecker: NotNil,
podChecker: IsNil,
@ -599,10 +614,9 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{"": {MountPath: "/mnt/fs"}},
},
errChecker: NotNil,
podChecker: IsNil,
@ -612,10 +626,13 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "pvcname",
Namespace: "",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
errChecker: NotNil,
podChecker: IsNil,
@ -625,10 +642,13 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
GenerateName: "name",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
MountPath: "/mnt/fs",
PVCMap: map[string]types.VolumePath{
"pvcname": {
MountPath: "/mnt/fs",
},
},
},
errChecker: IsNil,
podChecker: NotNil,
@ -637,11 +657,14 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
description: "ns namespace pod is created (Name/DevicePath)",
cli: fake.NewSimpleClientset(),
args: &types.CreatePodArgs{
Name: "name",
PVCName: "pvcname",
Namespace: "ns",
Command: []string{"somecommand"},
DevicePath: "/mnt/dev",
Name: "name",
Namespace: "ns",
Command: []string{"somecommand"},
PVCMap: map[string]types.VolumePath{
"pvcname": {
DevicePath: "/mnt/dev",
},
},
},
errChecker: IsNil,
podChecker: NotNil,
@ -678,27 +701,31 @@ func (s *CSITestSuite) TestCreatePod(c *C) {
c.Assert(len(pod.Spec.Containers), Equals, 1)
c.Assert(pod.Spec.Containers[0].Command, DeepEquals, tc.args.Command)
c.Assert(pod.Spec.Containers[0].Args, DeepEquals, tc.args.ContainerArgs)
if tc.args.MountPath != "" {
c.Assert(pod.Spec.Containers[0].VolumeMounts, DeepEquals, []v1.VolumeMount{{
Name: "persistent-storage",
MountPath: tc.args.MountPath,
}})
c.Assert(pod.Spec.Containers[0].VolumeDevices, IsNil)
} else {
c.Assert(pod.Spec.Containers[0].VolumeDevices, DeepEquals, []v1.VolumeDevice{{
Name: "persistent-storage",
DevicePath: tc.args.DevicePath,
}})
c.Assert(pod.Spec.Containers[0].VolumeMounts, IsNil)
}
c.Assert(pod.Spec.Volumes, DeepEquals, []v1.Volume{{
Name: "persistent-storage",
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
ClaimName: tc.args.PVCName,
index := 0
for pvcName, path := range tc.args.PVCMap {
if len(path.MountPath) != 0 {
c.Assert(pod.Spec.Containers[0].VolumeMounts[index], DeepEquals, v1.VolumeMount{
Name: fmt.Sprintf("persistent-storage-%s", pvcName),
MountPath: path.MountPath,
})
c.Assert(pod.Spec.Containers[0].VolumeDevices, IsNil)
} else {
c.Assert(pod.Spec.Containers[0].VolumeDevices[index], DeepEquals, v1.VolumeDevice{
Name: fmt.Sprintf("persistent-storage-%s", pvcName),
DevicePath: path.DevicePath,
})
c.Assert(pod.Spec.Containers[0].VolumeMounts, IsNil)
}
c.Assert(pod.Spec.Volumes[index], DeepEquals, v1.Volume{
Name: fmt.Sprintf("persistent-storage-%s", pvcName),
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
ClaimName: pvcName,
},
},
}},
})
})
index++
}
if tc.args.ContainerImage == "" {
c.Assert(pod.Spec.Containers[0].Image, Equals, common.DefaultPodImage)
} else {

View file

@ -209,23 +209,29 @@ func (p *pvcBrowserSteps) CreateInspectorApplication(ctx context.Context, args *
}
podArgs := &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: "filebrowser/filebrowser:v2",
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
MountPath: "/pvc-data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/pvc-data",
},
},
}
if args.ShowTree {
podArgs = &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: "alpine:3.19",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "while true; do sleep 3600; done"},
MountPath: "/pvc-data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/pvc-data",
},
},
}
}
pod, err := p.createAppOps.CreatePod(ctx, podArgs)

View file

@ -539,12 +539,15 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForPVC(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
MountPath: "/pvc-data",
RunAsUser: 100,
ContainerImage: "filebrowser/filebrowser:v2",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/pvc-data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -594,12 +597,15 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForPVC(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
MountPath: "/pvc-data",
RunAsUser: 100,
ContainerImage: "filebrowser/filebrowser:v2",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/pvc-data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",

View file

@ -177,23 +177,29 @@ func (s *snapshotBrowserSteps) CreateInspectorApplication(ctx context.Context, a
}
podArgs := &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: "filebrowser/filebrowser:v2",
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
MountPath: "/snapshot-data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/snapshot-data",
},
},
}
if args.ShowTree {
podArgs = &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: "alpine:3.19",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "while true; do sleep 3600; done"},
MountPath: "/snapshot-data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/snapshot-data",
},
},
}
}
pod, err := s.createAppOps.CreatePod(ctx, podArgs)

View file

@ -343,12 +343,15 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForSnapshot(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc",
Namespace: "ns",
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
MountPath: "/snapshot-data",
RunAsUser: 100,
ContainerImage: "filebrowser/filebrowser:v2",
PVCMap: map[string]types.VolumePath{
"pvc": {
MountPath: "/snapshot-data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod",
@ -398,12 +401,15 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForSnapshot(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc",
Namespace: "ns",
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
MountPath: "/snapshot-data",
RunAsUser: 100,
ContainerImage: "filebrowser/filebrowser:v2",
PVCMap: map[string]types.VolumePath{
"pvc": {
MountPath: "/snapshot-data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod",

View file

@ -48,7 +48,7 @@ func (r *SnapshotRestoreRunner) RunSnapshotRestore(ctx context.Context, args *ty
kubeCli: r.KubeCli,
},
createAppOps: &applicationCreate{
kubeCli: r.KubeCli,
kubeCli: r.KubeCli,
k8sObjectReadyTimeout: args.K8sObjectReadyTimeout,
},
dataValidatorOps: &validateData{
@ -179,13 +179,16 @@ func (s *snapshotRestoreSteps) CreateApplication(ctx context.Context, args *type
}
podArgs := &types.CreatePodArgs{
GenerateName: originalPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: args.ContainerImage,
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", fmt.Sprintf("echo '%s' >> /data/out.txt; sync; tail -f /dev/null", genString)},
MountPath: "/data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/data",
},
},
}
pod, err := s.createAppOps.CreatePod(ctx, podArgs)
if err != nil {
@ -262,13 +265,16 @@ func (s *snapshotRestoreSteps) RestoreApplication(ctx context.Context, args *typ
}
podArgs := &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: pvc.Name,
Namespace: args.Namespace,
RunAsUser: args.RunAsUser,
ContainerImage: args.ContainerImage,
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "tail -f /dev/null"},
MountPath: "/data",
PVCMap: map[string]types.VolumePath{
pvc.Name: {
MountPath: "/data",
},
},
}
pod, err := s.createAppOps.CreatePod(ctx, podArgs)
if err != nil {

View file

@ -230,13 +230,16 @@ func (s *CSITestSuite) TestCreateApplication(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: originalPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "echo 'some string' >> /data/out.txt; sync; tail -f /dev/null"},
RunAsUser: 100,
ContainerImage: "image",
MountPath: "/data",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -271,13 +274,16 @@ func (s *CSITestSuite) TestCreateApplication(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: originalPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "echo 'some string' >> /data/out.txt; sync; tail -f /dev/null"},
RunAsUser: 100,
ContainerImage: "image",
MountPath: "/data",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -351,13 +357,16 @@ func (s *CSITestSuite) TestCreateApplication(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: originalPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "echo 'some string' >> /data/out.txt; sync; tail -f /dev/null"},
RunAsUser: 100,
ContainerImage: "image",
MountPath: "/data",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -618,13 +627,16 @@ func (s *CSITestSuite) TestRestoreApplication(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "tail -f /dev/null"},
MountPath: "/data",
RunAsUser: 100,
ContainerImage: "image",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -672,13 +684,16 @@ func (s *CSITestSuite) TestRestoreApplication(c *C) {
}, nil),
f.createAppOps.EXPECT().CreatePod(gomock.Any(), &types.CreatePodArgs{
GenerateName: clonedPodGenerateName,
PVCName: "pvc1",
Namespace: "ns",
Command: []string{"/bin/sh"},
ContainerArgs: []string{"-c", "tail -f /dev/null"},
MountPath: "/data",
RunAsUser: 100,
ContainerImage: "image",
PVCMap: map[string]types.VolumePath{
"pvc1": {
MountPath: "/data",
},
},
}).Return(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",

View file

@ -56,27 +56,39 @@ func (c *CreatePVCArgs) Validate() error {
return nil
}
type VolumePath struct {
MountPath string // Only one of MountPath or
DevicePath string // DevicePath should be specified.
}
type CreatePodArgs struct {
Name string // Only one of Name or
GenerateName string // GenerateName should be specified.
PVCName string
PVCMap map[string]VolumePath
Namespace string
RunAsUser int64
ContainerImage string
Command []string
ContainerArgs []string
MountPath string // Only one of MountPath or
DevicePath string // DevicePath should be specified.
}
func (c *CreatePodArgs) Validate() error {
if (c.GenerateName == "" && c.Name == "") ||
(c.GenerateName != "" && c.Name != "") ||
(c.MountPath == "" && c.DevicePath == "") ||
(c.MountPath != "" && c.DevicePath != "") ||
c.PVCName == "" || c.Namespace == "" {
(c.Namespace == "") || (c.PVCMap == nil) {
return fmt.Errorf("Invalid CreatePodArgs (%#v)", c)
}
for pvcName, path := range c.PVCMap {
if pvcName == "" {
return fmt.Errorf("PVC Name not set")
}
if path.DevicePath == "" && path.MountPath == "" {
return fmt.Errorf("Neither DevicePath nor MountPath are set. One is required.")
}
if path.DevicePath != "" && path.MountPath != "" {
return fmt.Errorf("Both MountPath and DevicePath are set. Only one must be set.")
}
}
return nil
}