func()

in oracle/controllers/instancecontroller/instance_controller_restore.go [430:517]


func (r *InstanceReconciler) restorePhysical(ctx context.Context, inst v1alpha1.Instance, backup *v1alpha1.Backup, req ctrl.Request, log logr.Logger) (*lropb.Operation, error) {
	// Confirm that an external LB is ready.
	if err := restorePhysicalPreflightCheck(ctx, r, req.Namespace, inst.Name, log); err != nil {
		return nil, err
	}
	if backup.Spec.Backupset != nil && !*backup.Spec.Backupset {
		return nil, fmt.Errorf("preflight check: located a physical backup, but in this release the auto-restore is only supported from a Backupset backup: %v", backup.Spec.Backupset)
	}

	if backup.Spec.Subtype != "" && backup.Spec.Subtype != "Instance" {
		return nil, fmt.Errorf("preflight check: located a physical backup, but in this release the auto-restore is only supported from a Backupset taken at the Instance level: %q", backup.Spec.Subtype)
	}
	log.Info("preflight check for a restore from a physical backup - all DONE", "backup", backup)
	dop := restoreDOP(inst.Spec.Restore.Dop, backup.Spec.Dop)
	timeLimitMinutes := controllers.PhysBackupTimeLimitDefault * 3
	if inst.Spec.Restore.TimeLimitMinutes != 0 {
		timeLimitMinutes = time.Duration(inst.Spec.Restore.TimeLimitMinutes) * time.Minute
	}
	ctxRestore, cancel := context.WithTimeout(context.Background(), timeLimitMinutes)
	defer cancel()

	var sTime, eTime *timestamppb.Timestamp
	var incarnation, backupIncarnation string
	var sSCN, eSCN int64
	var p v1alpha1.PITR
	var err error
	backupIncarnation = backup.Labels[controllers.IncarnationLabel]
	incarnation = backupIncarnation
	if inst.Spec.Restore.PITRRestore != nil {
		// preflight check in findPITRBackupForRestore that only either SCN or timestamp must be set in PITRRestore.
		if inst.Spec.Restore.PITRRestore.SCN != "" {
			sSCN, err = strconv.ParseInt(backup.Annotations[controllers.SCNAnnotation], 10, 64)
			if err != nil {
				return nil, fmt.Errorf("PITR restore preflight check: failed to parse backup SCN %v from backup %v", err, backup)
			}
			eSCN, err = strconv.ParseInt(inst.Spec.Restore.PITRRestore.SCN, 10, 64)
			if err != nil {
				return nil, fmt.Errorf("PITR restore preflight check: failed to parse restore SCN %v from spec %v", err, inst.Spec.Restore)
			}
		}

		if inst.Spec.Restore.PITRRestore.Timestamp != nil {
			backupTimestamp, err := time.Parse(time.RFC3339, backup.Annotations[controllers.TimestampAnnotation])
			if err != nil {
				log.Error(err, "failed to find backup timestamp")
				return nil, err
			}
			sTime = timestamppb.New(backupTimestamp)
			eTime = timestamppb.New(inst.Spec.Restore.PITRRestore.Timestamp.Time)
		}

		p, err = r.findRestorePITR(ctx, &inst)
		if err != nil {
			return nil, err
		}
		incarnation = inst.Spec.Restore.PITRRestore.Incarnation
		if incarnation == "" {
			if inst.Spec.Restore.PITRRestore.PITRRef != nil {
				// PITRRef was specified.
				incarnation = p.Status.CurrentDatabaseIncarnation
			} else {
				incarnation = inst.Status.CurrentDatabaseIncarnation
			}
		}
	}

	restoreReq := &controllers.PhysicalRestoreRequest{
		InstanceName:      inst.Name,
		CdbName:           inst.Spec.CDBName,
		Dop:               dop,
		LocalPath:         backup.Spec.LocalPath,
		GcsPath:           backup.Spec.GcsPath,
		LroInput:          &controllers.LROInput{OperationId: lroRestoreOperationID(physicalRestore, inst)},
		LogGcsPath:        p.Spec.StorageURI,
		Incarnation:       incarnation,
		BackupIncarnation: backupIncarnation,
		StartTime:         sTime,
		EndTime:           eTime,
		StartScn:          sSCN,
		EndScn:            eSCN,
	}
	resp, err := controllers.PhysicalRestore(ctxRestore, r, r.DatabaseClientFactory, inst.Namespace, inst.Name, *restoreReq)
	if err != nil {
		return nil, fmt.Errorf("failed on PhysicalRestore gRPC call: %v", err)
	}
	log.Info("config_agent_helpers.PhysicalRestore", "LRO", lroRestoreOperationID(physicalRestore, inst), "response", resp)
	return resp, nil
}