github.com/percona/percona-xtradb-cluster-operator@v1.14.0/pkg/controller/pxcrestore/restore.go (about) 1 package pxcrestore 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/pkg/errors" 8 batchv1 "k8s.io/api/batch/v1" 9 corev1 "k8s.io/api/core/v1" 10 k8serrors "k8s.io/apimachinery/pkg/api/errors" 11 "k8s.io/apimachinery/pkg/types" 12 logf "sigs.k8s.io/controller-runtime/pkg/log" 13 14 api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" 15 "github.com/percona/percona-xtradb-cluster-operator/pkg/k8s" 16 ) 17 18 func (r *ReconcilePerconaXtraDBClusterRestore) restore(ctx context.Context, cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraDBCluster) error { 19 log := logf.FromContext(ctx) 20 21 if cluster.Spec.Backup == nil { 22 return errors.New("undefined backup section in a cluster spec") 23 } 24 25 restorer, err := r.getRestorer(cr, bcp, cluster) 26 if err != nil { 27 return errors.Wrap(err, "failed to get restorer") 28 } 29 job, err := restorer.Job() 30 if err != nil { 31 return errors.Wrap(err, "failed to get restore job") 32 } 33 if err = k8s.SetControllerReference(cr, job, r.scheme); err != nil { 34 return err 35 } 36 37 if err = restorer.Init(ctx); err != nil { 38 return errors.Wrap(err, "failed to init restore") 39 } 40 defer func() { 41 if derr := restorer.Finalize(ctx); derr != nil { 42 log.Error(derr, "failed to finalize restore") 43 } 44 }() 45 46 return r.createJob(ctx, job) 47 } 48 49 func (r *ReconcilePerconaXtraDBClusterRestore) pitr(ctx context.Context, cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraDBCluster) error { 50 log := logf.FromContext(ctx) 51 52 restorer, err := r.getRestorer(cr, bcp, cluster) 53 if err != nil { 54 return errors.Wrap(err, "failed to get restorer") 55 } 56 job, err := restorer.PITRJob() 57 if err != nil { 58 return errors.Wrap(err, "failed to create pitr restore job") 59 } 60 if err := k8s.SetControllerReference(cr, job, r.scheme); err != nil { 61 return err 62 } 63 if err = restorer.Init(ctx); err != nil { 64 return errors.Wrap(err, "failed to init restore") 65 } 66 defer func() { 67 if derr := restorer.Finalize(ctx); derr != nil { 68 log.Error(derr, "failed to finalize restore") 69 } 70 }() 71 72 return r.createJob(ctx, job) 73 } 74 75 func (r *ReconcilePerconaXtraDBClusterRestore) validate(ctx context.Context, cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraDBCluster) error { 76 restorer, err := r.getRestorer(cr, bcp, cluster) 77 if err != nil { 78 return errors.Wrap(err, "failed to get restorer") 79 } 80 job, err := restorer.Job() 81 if err != nil { 82 return errors.Wrap(err, "failed to create restore job") 83 } 84 if err := restorer.ValidateJob(ctx, job); err != nil { 85 return errors.Wrap(err, "failed to validate job") 86 } 87 88 if cr.Spec.PITR != nil { 89 job, err := restorer.PITRJob() 90 if err != nil { 91 return errors.Wrap(err, "failed to create pitr restore job") 92 } 93 if err := restorer.ValidateJob(ctx, job); err != nil { 94 return errors.Wrap(err, "failed to validate job") 95 } 96 } 97 if err := restorer.Validate(ctx); err != nil { 98 return errors.Wrap(err, "failed to validate backup existence") 99 } 100 return nil 101 } 102 103 func (r *ReconcilePerconaXtraDBClusterRestore) createJob(ctx context.Context, job *batchv1.Job) error { 104 err := r.client.Create(ctx, job) 105 if err != nil { 106 return errors.Wrap(err, "create job") 107 } 108 109 for { 110 time.Sleep(time.Second * 1) 111 112 checkJob := batchv1.Job{} 113 err := r.client.Get(ctx, types.NamespacedName{Name: job.Name, Namespace: job.Namespace}, &checkJob) 114 if err != nil { 115 if k8serrors.IsNotFound(err) { 116 return nil 117 } 118 return errors.Wrap(err, "get job status") 119 } 120 for _, cond := range checkJob.Status.Conditions { 121 if cond.Status != corev1.ConditionTrue { 122 continue 123 } 124 switch cond.Type { 125 case batchv1.JobComplete: 126 return nil 127 case batchv1.JobFailed: 128 return errors.New(cond.Message) 129 } 130 } 131 } 132 }