Skip to content

Commit 949f507

Browse files
authored
Merge pull request #481 from j-griffith/modify_container_restart_policy
Set pod restart policy to "OnFailure" and cleanup succesful pods
2 parents 9ad0788 + 7b77455 commit 949f507

11 files changed

+98
-35
lines changed

pkg/controller/clone-controller.go

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package controller
22

33
import (
44
"fmt"
5+
56
"github.com/golang/glog"
67
"github.com/pkg/errors"
78
"k8s.io/api/core/v1"
@@ -156,6 +157,7 @@ func (cc *CloneController) processPvcItem(pvc *v1.PersistentVolumeClaim) error {
156157
//add the following annotation only if the pod pahse is succeeded, meaning job is completed
157158
if phase == string(v1.PodSucceeded) {
158159
anno[AnnCloneOf] = "true"
160+
defer cc.deleteClonePods(sourcePod.Namespace, sourcePod.Name, targetPod.Name)
159161
}
160162
var lab map[string]string
161163
if !checkIfLabelExists(pvc, common.CDILabelKey, common.CDILabelValue) {
@@ -168,6 +170,23 @@ func (cc *CloneController) processPvcItem(pvc *v1.PersistentVolumeClaim) error {
168170
return nil
169171
}
170172

173+
func (cc *CloneController) deleteClonePods(namespace, srcName, tgtName string) {
174+
srcReq := podDeleteRequest{
175+
namespace: namespace,
176+
podName: srcName,
177+
podLister: cc.Controller.podLister,
178+
k8sClient: cc.Controller.clientset,
179+
}
180+
tgtReq := podDeleteRequest{
181+
namespace: namespace,
182+
podName: tgtName,
183+
podLister: cc.Controller.podLister,
184+
k8sClient: cc.Controller.clientset,
185+
}
186+
deletePod(srcReq)
187+
deletePod(tgtReq)
188+
}
189+
171190
func (c *Controller) initializeExpectations(pvcKey string) error {
172191
return c.podExpectations.SetExpectations(pvcKey, 0, 0)
173192
}

pkg/controller/import-controller.go

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"k8s.io/client-go/tools/cache"
1111

1212
"fmt"
13+
1314
"kubevirt.io/containerized-data-importer/pkg/common"
1415
)
1516

@@ -118,6 +119,16 @@ func (ic *ImportController) processPvcItem(pvc *v1.PersistentVolumeClaim) error
118119
if pod != nil {
119120
anno[AnnImportPod] = string(pod.Name)
120121
anno[AnnPodPhase] = string(pod.Status.Phase)
122+
if pod.Status.Phase == "Succeeded" {
123+
dReq := podDeleteRequest{
124+
namespace: pod.Namespace,
125+
podName: pod.Name,
126+
podLister: ic.Controller.podLister,
127+
k8sClient: ic.Controller.clientset,
128+
}
129+
// just use defer here so we make sure our pvc updates get written prior to actual deletion
130+
defer deletePod(dReq)
131+
}
121132
}
122133

123134
var lab map[string]string

pkg/controller/upload-controller.go

+26-15
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,18 @@ func (c *UploadController) syncHandler(key string) error {
370370
}
371371

372372
// delete pod
373-
err = c.deletePod(pvc.Namespace, resourceName)
373+
// we're using a req struct for now until we can normalize the controllers a bit more and share things like lister, client etc
374+
// this way it's easy to stuff everything into an easy request struct, and can extend aditional behaviors if we want going forward
375+
// NOTE this is a special case where the user updated annotations on the pvc to abort the upload requests, we'll add another call
376+
// for this for the success case
377+
dReq := podDeleteRequest{
378+
namespace: pvc.Namespace,
379+
podName: resourceName,
380+
podLister: c.podLister,
381+
k8sClient: c.client,
382+
}
383+
384+
err = deletePod(dReq)
374385
if err != nil {
375386
return errors.Wrapf(err, "Error deleting upload pod for pvc: %s", key)
376387
}
@@ -410,6 +421,20 @@ func (c *UploadController) syncHandler(key string) error {
410421
if err = c.deleteService(pvc.Namespace, resourceName); err != nil {
411422
return errors.Wrapf(err, "Error deleting upload service for pvc %s", key)
412423
}
424+
425+
dReq := podDeleteRequest{
426+
namespace: pvc.Namespace,
427+
podName: resourceName,
428+
podLister: c.podLister,
429+
k8sClient: c.client,
430+
}
431+
432+
// delete the pod
433+
err = deletePod(dReq)
434+
if err != nil {
435+
return errors.Wrapf(err, "Error deleting upload pod for pvc: %s", key)
436+
}
437+
413438
} else {
414439
// make sure the service exists
415440
if _, err = c.getOrCreateUploadService(pvc, resourceName); err != nil {
@@ -448,20 +473,6 @@ func (c *UploadController) getOrCreateUploadService(pvc *v1.PersistentVolumeClai
448473
return service, err
449474
}
450475

451-
func (c *UploadController) deletePod(namespace, name string) error {
452-
pod, err := c.podLister.Pods(namespace).Get(name)
453-
if k8serrors.IsNotFound(err) {
454-
return nil
455-
}
456-
if err == nil && pod.DeletionTimestamp == nil {
457-
err = c.client.CoreV1().Pods(namespace).Delete(name, &metav1.DeleteOptions{})
458-
if k8serrors.IsNotFound(err) {
459-
return nil
460-
}
461-
}
462-
return err
463-
}
464-
465476
func (c *UploadController) deleteService(namespace, name string) error {
466477
service, err := c.serviceLister.Services(namespace).Get(name)
467478
if k8serrors.IsNotFound(err) {

pkg/controller/upload-controller_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ func TestUploadComplete(t *testing.T) {
355355

356356
f.expectUpdatePvcAction(updatedPVC)
357357
f.expectDeleteServiceAction(service)
358-
358+
f.expectDeletePodAction(pod)
359359
f.run(getPvcKey(pvc, t))
360360
}
361361

pkg/controller/util.go

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77
"time"
88

9+
corelisters "k8s.io/client-go/listers/core/v1"
910
"k8s.io/client-go/util/cert/triple"
1011

1112
"github.com/golang/glog"
@@ -27,6 +28,13 @@ const DataVolName = "cdi-data-vol"
2728
const ImagePathName = "image-path"
2829
const socketPathName = "socket-path"
2930

31+
type podDeleteRequest struct {
32+
namespace string
33+
podName string
34+
podLister corelisters.PodLister
35+
k8sClient kubernetes.Interface
36+
}
37+
3038
func checkPVC(pvc *v1.PersistentVolumeClaim, annotation string) bool {
3139
if pvc.DeletionTimestamp != nil {
3240
return false
@@ -216,7 +224,7 @@ func MakeImporterPodSpec(image, verbose, pullPolicy, ep, secret string, pvc *v1.
216224
Args: []string{"-v=" + verbose},
217225
},
218226
},
219-
RestartPolicy: v1.RestartPolicyNever,
227+
RestartPolicy: v1.RestartPolicyOnFailure,
220228
Volumes: []v1.Volume{
221229
{
222230
Name: DataVolName,
@@ -721,3 +729,20 @@ func MakeUploadServiceSpec(name string, pvc *v1.PersistentVolumeClaim) *v1.Servi
721729
}
722730
return service
723731
}
732+
733+
func deletePod(req podDeleteRequest) error {
734+
pod, err := req.podLister.Pods(req.namespace).Get(req.podName)
735+
if k8serrors.IsNotFound(err) {
736+
return nil
737+
}
738+
if err == nil && pod.DeletionTimestamp == nil {
739+
err = req.k8sClient.CoreV1().Pods(req.namespace).Delete(req.podName, &metav1.DeleteOptions{})
740+
if k8serrors.IsNotFound(err) {
741+
return nil
742+
}
743+
}
744+
if err != nil {
745+
glog.V(1).Infof("error encountered deleting pod (%s): %s", req.podName, err.Error())
746+
}
747+
return err
748+
}

pkg/controller/util_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ func createPod(pvc *v1.PersistentVolumeClaim, dvname string) *v1.Pod {
796796
Args: []string{"-v=5"},
797797
},
798798
},
799-
RestartPolicy: v1.RestartPolicyNever,
799+
RestartPolicy: v1.RestartPolicyOnFailure,
800800
Volumes: []v1.Volume{
801801
{
802802
Name: dvname,

tests/cloner_test.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525
fillCommand = "echo \"" + fillData + "\" >> " + testFile
2626
assertionPollInterval = 2 * time.Second
2727
cloneCompleteTimeout = 60 * time.Second
28+
shortTimeout = 2 * time.Second
2829
)
2930

3031
var _ = Describe(testSuiteName, func() {
@@ -69,6 +70,7 @@ func doCloneTest(f *framework.Framework, targetNs *v1.Namespace) {
6970
map[string]string{controller.AnnCloneRequest: f.Namespace.Name + "/" + sourcePVCName},
7071
nil))
7172
Expect(err).ToNot(HaveOccurred())
73+
fmt.Fprintf(GinkgoWriter, "INFO: wait for PVC claim phase: %s\n", targetPvc.Name)
7274
utils.WaitForPersistentVolumeClaimPhase(f.K8sClient, targetNs.Name, v1.ClaimBound, targetPvc.Name)
7375

7476
By("Find cloner pods")
@@ -94,11 +96,6 @@ func doCloneTest(f *framework.Framework, targetNs *v1.Namespace) {
9496
return srcNode == tgtNode
9597
}, cloneCompleteTimeout, assertionPollInterval).Should(BeTrue())
9698

97-
err = f.WaitTimeoutForPodStatus(sourcePod.Name, v1.PodSucceeded, cloneCompleteTimeout)
98-
Expect(err).ToNot(HaveOccurred())
99-
err = utils.WaitTimeoutForPodStatus(f.K8sClient, targetPod.Name, targetNs.Name, v1.PodSucceeded, cloneCompleteTimeout)
100-
Expect(err).ToNot(HaveOccurred())
101-
10299
By("Verify the clone annotation is on the target PVC")
103100
_, cloneAnnotationFound, err := utils.WaitForPVCAnnotation(f.K8sClient, targetNs.Name, targetPvc, controller.AnnCloneOf)
104101
Expect(err).ToNot(HaveOccurred())
@@ -119,4 +116,14 @@ func doCloneTest(f *framework.Framework, targetNs *v1.Namespace) {
119116
err = utils.DeletePVC(f.K8sClient, targetNs.Name, targetPvc)
120117
Expect(err).ToNot(HaveOccurred())
121118
}
119+
120+
By("Verify source pod deleted")
121+
deleted, err := utils.WaitPodDeleted(f.K8sClient, sourcePod.Name, targetPod.Namespace, time.Second*40)
122+
Expect(err).ToNot(HaveOccurred())
123+
Expect(deleted).To(BeTrue())
124+
125+
By("Verify target pod deleted")
126+
deleted, err = utils.WaitPodDeleted(f.K8sClient, targetPod.Name, targetNs.Name, time.Second*40)
127+
Expect(err).ToNot(HaveOccurred())
128+
Expect(deleted).To(BeTrue())
122129
}

tests/framework/pvc.go

-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ func VerifyPVCIsEmpty(f *Framework, pvc *k8sv1.PersistentVolumeClaim) bool {
4141
err = f.WaitTimeoutForPodReady(executorPod.Name, utils.PodWaitForTime)
4242
gomega.Expect(err).ToNot(gomega.HaveOccurred())
4343
output := f.ExecShellInPod(executorPod.Name, f.Namespace.Name, "ls -1 /pvc | wc -l")
44-
f.DeletePod(executorPod)
4544
return strings.Compare("0", output) == 0
4645
}
4746

@@ -67,7 +66,6 @@ func (f *Framework) VerifyTargetPVCContent(namespace *k8sv1.Namespace, pvc *k8sv
6766
err = utils.WaitTimeoutForPodReady(f.K8sClient, executorPod.Name, namespace.Name, utils.PodWaitForTime)
6867
gomega.Expect(err).ToNot(gomega.HaveOccurred())
6968
output := f.ExecShellInPod(executorPod.Name, namespace.Name, "cat "+fileName)
70-
f.DeletePod(executorPod)
7169
return strings.Compare(expectedData, output) == 0
7270
}
7371

@@ -78,6 +76,5 @@ func (f *Framework) VerifyTargetPVCContentMD5(namespace *k8sv1.Namespace, pvc *k
7876
err = utils.WaitTimeoutForPodReady(f.K8sClient, executorPod.Name, namespace.Name, utils.PodWaitForTime)
7977
gomega.Expect(err).ToNot(gomega.HaveOccurred())
8078
output := f.ExecShellInPod(executorPod.Name, namespace.Name, "md5sum "+fileName)
81-
f.DeletePod(executorPod)
8279
return strings.Compare(expectedHash, output[:32]) == 0
8380
}

tests/transport_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ var _ = Describe("Transport Tests", func() {
7171
if err != nil {
7272
PrintPodLog(f, importer.Name, ns)
7373
}
74-
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unable to get importer pod %q", ns+"/"+common.ImporterPodName))
7574

7675
By("Verifying PVC is not empty")
7776
Expect(framework.VerifyPVCIsEmpty(f, pvc)).To(BeFalse(), fmt.Sprintf("Found 0 imported files on PVC %q", pvc.Namespace+"/"+pvc.Name))

tests/upload_test.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import (
66
. "github.com/onsi/ginkgo"
77
. "github.com/onsi/gomega"
88

9-
k8sv1 "k8s.io/api/core/v1"
10-
119
"kubevirt.io/containerized-data-importer/tests/framework"
1210
"kubevirt.io/containerized-data-importer/tests/utils"
1311
)
@@ -46,15 +44,11 @@ var _ = Describe("Upload tests", func() {
4644
err = utils.UploadImageFromNode(f.K8sClient, f.GoCLIPath, token)
4745
Expect(err).ToNot(HaveOccurred())
4846

49-
By("Wait pod succeeded")
50-
err = f.WaitTimeoutForPodStatus(utils.UploadPodName(pvc), k8sv1.PodSucceeded, time.Second*20)
51-
Expect(err).ToNot(HaveOccurred())
52-
5347
By("Verify content")
5448
same := f.VerifyTargetPVCContentMD5(f.Namespace, pvc, testFile, utils.UploadFileMD5)
5549
Expect(same).To(BeTrue())
5650

57-
By("Delete upoad PVC")
51+
By("Delete upload PVC")
5852
err = f.DeletePVC(pvc)
5953
Expect(err).ToNot(HaveOccurred())
6054

tests/utils.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func PrintPodLog(f *framework.Framework, podName, namespace string) {
5656
if err == nil {
5757
fmt.Fprintf(ginkgo.GinkgoWriter, "INFO: Controller log\n%s\n", log)
5858
} else {
59-
fmt.Fprintf(ginkgo.GinkgoWriter, "INFO: Unable to get controller log")
59+
fmt.Fprintf(ginkgo.GinkgoWriter, "INFO: Unable to get controller log\n")
6060
}
6161
}
6262

0 commit comments

Comments
 (0)