@@ -10,6 +10,7 @@ import (
1010 "github.com/cybozu-go/mantle/pkg/controller/proto"
1111 "google.golang.org/grpc"
1212 corev1 "k8s.io/api/core/v1"
13+ aerrors "k8s.io/apimachinery/pkg/api/errors"
1314 "k8s.io/apimachinery/pkg/labels"
1415 "k8s.io/apimachinery/pkg/types"
1516 ctrl "sigs.k8s.io/controller-runtime"
@@ -109,10 +110,10 @@ func (s *SecondaryServer) CreateOrUpdatePVC(
109110 return & proto.CreateOrUpdatePVCResponse {Uid : string (pvc .GetUID ())}, nil
110111}
111112
112- func (s * SecondaryServer ) CreateOrUpdateMantleBackup (
113+ func (s * SecondaryServer ) CreateMantleBackup (
113114 ctx context.Context ,
114- req * proto.CreateOrUpdateMantleBackupRequest ,
115- ) (* proto.CreateOrUpdateMantleBackupResponse , error ) {
115+ req * proto.CreateMantleBackupRequest ,
116+ ) (* proto.CreateMantleBackupResponse , error ) {
116117 var backupReceived mantlev1.MantleBackup
117118 if err := json .Unmarshal (req .MantleBackup , & backupReceived ); err != nil {
118119 return nil , err
@@ -139,62 +140,45 @@ func (s *SecondaryServer) CreateOrUpdateMantleBackup(
139140 annotRemoteUID , backupReceived .GetName (), backupReceived .GetNamespace ())
140141 }
141142
142- var backup mantlev1.MantleBackup
143- backup .SetName (backupReceived .GetName ())
144- backup .SetNamespace (backupReceived .GetNamespace ())
145- if _ , err := ctrl .CreateOrUpdate (ctx , s .client , & backup , func () error {
146- if ! backup .CreationTimestamp .IsZero () {
147- errMsg := ""
148- if backup .Labels == nil {
149- errMsg = "labels field is nil in backup"
150- } else {
151- pvcUID , ok := backup .Labels [labelLocalBackupTargetPVCUID ]
152- if ! ok {
153- errMsg = "label not found"
154- } else if pvcUID != pvcUIDReceived {
155- errMsg = "label not matched"
156- }
157- }
158- if errMsg != "" {
159- return fmt .Errorf ("%s: %s: %s: %s" ,
160- errMsg , labelLocalBackupTargetPVCUID , backupReceived .GetName (), backupReceived .GetNamespace ())
161- }
162-
163- if backup .Annotations == nil {
164- errMsg = "annotation field is nil in backup"
165- } else {
166- remoteUID , ok := backup .Annotations [annotRemoteUID ]
167- if ! ok {
168- errMsg = "annotation not found in backup"
169- } else if remoteUID != remoteUIDReceived {
170- errMsg = "annotation not matched"
171- }
172- }
173- if errMsg != "" {
174- return fmt .Errorf ("%s: %s: %s: %s" ,
175- errMsg , annotRemoteUID , backupReceived .GetName (), backupReceived .GetNamespace ())
176- }
143+ var backupExists mantlev1.MantleBackup
144+ if err := s .client .Get (ctx , types.NamespacedName {
145+ Namespace : backupReceived .GetNamespace (),
146+ Name : backupReceived .GetName (),
147+ }, & backupExists ); err != nil {
148+ if ! aerrors .IsNotFound (err ) {
149+ return nil , fmt .Errorf ("failed to get MantleBackup: %w" , err )
150+ }
151+ // Not found, create a new one.
152+ if err := s .client .Create (ctx , & backupReceived ); err != nil {
153+ return nil , fmt .Errorf ("failed to create MantleBackup: %w" , err )
177154 }
155+ return & proto.CreateMantleBackupResponse {}, nil
156+ }
178157
179- backup .Finalizers = backupReceived .Finalizers
180- backup .Annotations = backupReceived .Annotations
181- backup .Labels = backupReceived .Labels
182- backup .Spec = backupReceived .Spec
183- return nil
184- }); err != nil {
185- return nil , fmt .Errorf ("CreateOrUpdate failed: %w" , err )
158+ // Found, check it.
159+ if backupExists .Labels == nil || backupExists .Annotations == nil {
160+ return nil , fmt .Errorf ("both labels and annotations must not be nil in the existing MantleBackup: %s/%s" ,
161+ backupReceived .GetNamespace (), backupReceived .GetName ())
162+ }
163+
164+ if pvcUID , ok := backupExists .Labels [labelLocalBackupTargetPVCUID ]; ! ok {
165+ return nil , fmt .Errorf ("label %s not found in the existing MantleBackup: %s/%s" ,
166+ labelLocalBackupTargetPVCUID , backupReceived .GetNamespace (), backupReceived .GetName ())
167+ } else if pvcUID != pvcUIDReceived {
168+ return nil , fmt .Errorf ("label %s not matched in the existing MantleBackup: %s/%s" ,
169+ labelLocalBackupTargetPVCUID , backupReceived .GetNamespace (), backupReceived .GetName ())
186170 }
187171
188- // Use Patch here because updateStatus is likely to fail due to "the object has been modified" error.
189- newBackup := backup .DeepCopy ()
190- newBackup .Status .CreatedAt = backupReceived .Status .CreatedAt
191- newBackup .Status .SnapSize = backupReceived .Status .SnapSize
192- newBackup .Status .TransferPartSize = backupReceived .Status .TransferPartSize
193- if err := s .client .Status ().Patch (ctx , newBackup , client .MergeFrom (& backup )); err != nil {
194- return nil , fmt .Errorf ("status patch failed: %w" , err )
172+ if remoteUID , ok := backupExists .Annotations [annotRemoteUID ]; ! ok {
173+ return nil , fmt .Errorf ("annotation %s not found in the existing MantleBackup: %s/%s" ,
174+ annotRemoteUID , backupReceived .GetNamespace (), backupReceived .GetName ())
175+ } else if remoteUID != remoteUIDReceived {
176+ return nil , fmt .Errorf ("annotation %s not matched in the existing MantleBackup: %s/%s" ,
177+ annotRemoteUID , backupReceived .GetNamespace (), backupReceived .GetName ())
195178 }
196179
197- return & proto.CreateOrUpdateMantleBackupResponse {}, nil
180+ // Already exists with matching pvc-uid and remote-uid, do nothing.
181+ return & proto.CreateMantleBackupResponse {}, nil
198182}
199183
200184func (s * SecondaryServer ) ListMantleBackup (
0 commit comments