diff --git a/charts/go.mod b/charts/go.mod index 8acd1f3aa..472217596 100644 --- a/charts/go.mod +++ b/charts/go.mod @@ -99,8 +99,8 @@ require ( golang.org/x/text v0.14.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.25.3 - k8s.io/apimachinery v0.25.3 + k8s.io/api v0.30.2 + k8s.io/apimachinery v0.30.2 k8s.io/client-go v0.24.2 // indirect k8s.io/helm v2.17.0+incompatible // indirect ) diff --git a/go.mod b/go.mod index 2bdb4e2d1..33f953795 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/k8up-io/k8up/v2 -go 1.21 +go 1.22.0 + +toolchain go1.22.4 require ( github.com/firepear/qsplit/v2 v2.5.0 @@ -14,10 +16,10 @@ require ( github.com/stretchr/testify v1.9.0 github.com/urfave/cli/v2 v2.23.7 go.uber.org/zap v1.26.0 - golang.org/x/net v0.22.0 - k8s.io/api v0.29.2 - k8s.io/apimachinery v0.29.2 - k8s.io/client-go v0.29.2 + golang.org/x/net v0.23.0 + k8s.io/api v0.30.2 + k8s.io/apimachinery v0.30.2 + k8s.io/client-go v0.30.2 k8s.io/utils v0.0.0-20240310230437-4693a0247e57 sigs.k8s.io/controller-runtime v0.17.2 sigs.k8s.io/controller-tools v0.14.0 diff --git a/go.sum b/go.sum index 2d36ee0f4..fafefa178 100644 --- a/go.sum +++ b/go.sum @@ -109,10 +109,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= -github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= +github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -184,8 +184,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -253,14 +253,14 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= -k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= +k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= +k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= -k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= -k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= -k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= +k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= +k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= +k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= diff --git a/operator/backupcontroller/controller_integration_test.go b/operator/backupcontroller/controller_integration_test.go index 7bf7ce6f0..755f88b39 100644 --- a/operator/backupcontroller/controller_integration_test.go +++ b/operator/backupcontroller/controller_integration_test.go @@ -312,7 +312,9 @@ func (ts *BackupTestSuite) Test_GivenBackupAndMountedRWOPVCOnOneNode_ExpectBacku pvc1.Status.Phase = corev1.ClaimBound pvc2.Status.Phase = corev1.ClaimBound - ts.UpdateStatus(pvc1, pvc2) + pod1.Status.Phase = corev1.PodRunning + pod2.Status.Phase = corev1.PodRunning + ts.UpdateStatus(pvc1, pvc2, pod1, pod2) result := ts.whenReconciling(ts.BackupResource) ts.Assert().GreaterOrEqual(result.RequeueAfter, 30*time.Second) @@ -359,7 +361,9 @@ func (ts *BackupTestSuite) Test_GivenBackupAndMountedRWOPVCOnTwoNodes_ExpectBack pvc1.Status.Phase = corev1.ClaimBound pvc2.Status.Phase = corev1.ClaimBound - ts.UpdateStatus(pvc1, pvc2) + pod1.Status.Phase = corev1.PodRunning + pod2.Status.Phase = corev1.PodRunning + ts.UpdateStatus(pvc1, pvc2, pod1, pod2) result := ts.whenReconciling(ts.BackupResource) ts.Assert().GreaterOrEqual(result.RequeueAfter, 30*time.Second) @@ -395,7 +399,9 @@ func (ts *BackupTestSuite) Test_GivenBackupAndMountedRWOPVCOnOneNodeWithFinished ts.EnsureResources(ts.BackupResource, pvc1, pod1, pod2) pvc1.Status.Phase = corev1.ClaimBound - ts.UpdateStatus(pvc1) + pod1.Status.Phase = corev1.PodRunning + pod2.Status.Phase = corev1.PodRunning + ts.UpdateStatus(pvc1, pod1, pod2) result := ts.whenReconciling(ts.BackupResource) ts.Assert().GreaterOrEqual(result.RequeueAfter, 30*time.Second) @@ -451,6 +457,35 @@ func (ts *BackupTestSuite) Test_GivenBackupAndUnmountedRWOPVCOnTwoNodes_ExpectBa ts.assertJobSpecs(&job2, nodeNamePv2, []corev1.Volume{volumePvc2}, nil, []string{}) } +func (ts *BackupTestSuite) Test_GivenBackupAndRWOPVCWithFinishedPod_ExpectFinishedPodToBeIgnored() { + pvc1 := ts.newPvc("test-pvc1", corev1.ReadWriteOnce) + nodeNamePod1 := "worker" + nodeNamePod2 := "control-plane" + volumePvc1 := corev1.Volume{ + Name: "test-pvc1", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvc1.Name, + }, + }, + } + tolerations := make([]corev1.Toleration, 0) + pod1 := ts.newPod("test-pod1", nodeNamePod1, tolerations, []corev1.Volume{volumePvc1}) + pod2 := ts.newPod("test-pod2", nodeNamePod2, tolerations, []corev1.Volume{volumePvc1}) + + ts.EnsureResources(ts.BackupResource, pvc1, pod1, pod2) + + pvc1.Status.Phase = corev1.ClaimBound + pod1.Status.Phase = corev1.PodRunning + pod2.Status.Phase = corev1.PodSucceeded + ts.UpdateStatus(pvc1, pod1, pod2) + + ts.whenReconciling(ts.BackupResource) + job := ts.expectABackupJob() + + ts.assertJobSpecs(job, nodeNamePod1, []corev1.Volume{volumePvc1}, tolerations, []string{pod1.Name}) +} + func (ts *BackupTestSuite) assertCondition(conditions []metav1.Condition, condType k8upv1.ConditionType, reason k8upv1.ConditionReason, status metav1.ConditionStatus) { cond := meta.FindStatusCondition(conditions, condType.String()) ts.Require().NotNil(cond, "condition of type %s missing", condType) diff --git a/operator/backupcontroller/executor.go b/operator/backupcontroller/executor.go index 46cf8aa9c..3744e58f3 100644 --- a/operator/backupcontroller/executor.go +++ b/operator/backupcontroller/executor.go @@ -69,6 +69,10 @@ func (b *BackupExecutor) listAndFilterPVCs(ctx context.Context, annotation strin return nil, fmt.Errorf("list pods: %w", err) } for _, pod := range pods.Items { + if pod.Status.Phase != corev1.PodRunning { + log.V(1).Info("Ignoring Pod which is not running", "pod", pod.GetName()) + continue + } for _, volume := range pod.Spec.Volumes { if volume.PersistentVolumeClaim != nil { pvcPodMap[volume.PersistentVolumeClaim.ClaimName] = pod