Skip to content

Commit

Permalink
pv k8s sequence
Browse files Browse the repository at this point in the history
Signed-off-by: Raghavendra Talur <[email protected]>
  • Loading branch information
raghavendra-talur committed Jan 22, 2025
1 parent acc70c7 commit 18d738b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
35 changes: 35 additions & 0 deletions internal/controller/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const (
// after this condition is true.
VRGConditionTypeClusterDataReady = "ClusterDataReady"

// K8s objects are ready. This condition is used to indicate that all the
// K8s objects required for the app to be active in the cluster are ready.
VRGConditionTypeK8sObjectsReady = "K8sObjectsReady"

// PV cluster data is protected. This condition indicates whether an app,
// which is active in a cluster, has all its PV related cluster data
// protected from a disaster by uploading it to the required S3 store(s).
Expand Down Expand Up @@ -58,6 +62,7 @@ const (
VRGConditionReasonDataProtected = "DataProtected"
VRGConditionReasonProgressing = "Progressing"
VRGConditionReasonClusterDataRestored = "Restored"
VRGConditionReasonK8sObjectsRestored = "K8sObjectsRestored"
VRGConditionReasonError = "Error"
VRGConditionReasonErrorUnknown = "UnknownError"
VRGConditionReasonUploading = "Uploading"
Expand Down Expand Up @@ -116,6 +121,14 @@ func setVRGInitialCondition(conditions *[]metav1.Condition, observedGeneration i
LastTransitionTime: time,
Message: message,
})
setStatusConditionIfNotFound(conditions, metav1.Condition{
Type: VRGConditionTypeK8sObjectsReady,
Reason: VRGConditionReasonInitializing,
ObservedGeneration: observedGeneration,
Status: metav1.ConditionUnknown,
LastTransitionTime: time,
Message: message,
})
}

// sets conditions when VRG as Secondary is replicating the data with Primary.
Expand Down Expand Up @@ -371,6 +384,28 @@ func newVRGClusterDataUnprotectedCondition(observedGeneration int64, reason, mes
}
}

// sets conditions when K8s objects are restored
func setVRGK8sObjectsReadyCondition(conditions *[]metav1.Condition, observedGeneration int64, message string) {
setStatusCondition(conditions, metav1.Condition{
Type: VRGConditionTypeK8sObjectsReady,
Reason: VRGConditionReasonK8sObjectsRestored,
ObservedGeneration: observedGeneration,
Status: metav1.ConditionTrue,
Message: message,
})
}

// sets conditions when K8s objects failed to restore
func setVRGK8sObjectsErrorCondition(conditions *[]metav1.Condition, observedGeneration int64, message string) {
setStatusCondition(conditions, metav1.Condition{
Type: VRGConditionTypeK8sObjectsReady,
Reason: VRGConditionReasonError,
ObservedGeneration: observedGeneration,
Status: metav1.ConditionFalse,
Message: message,
})
}

func setStatusConditionIfNotFound(existingConditions *[]metav1.Condition, newCondition metav1.Condition) {
if existingConditions == nil {
existingConditions = &[]metav1.Condition{}
Expand Down
39 changes: 37 additions & 2 deletions internal/controller/volumereplicationgroup_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,10 +640,11 @@ func (v *VRGInstance) clusterDataRestore(result *ctrl.Result) (int, error) {
return numRestoredForVS + numRestoredForVR, fmt.Errorf("failed to restore PV/PVC for VolRep (%w)", err)
}

// Only after both succeed, we mark ClusterDataReady as true
msg := "Restored PVs and PVCs"
var msg string
if numRestoredForVS+numRestoredForVR == 0 {
msg = "Nothing to restore"
} else {
msg = fmt.Sprintf("Restored %d volsync PVs/PVCs and %d volrep PVs/PVCs", numRestoredForVS, numRestoredForVR)
}

setVRGClusterDataReadyCondition(&v.instance.Status.Conditions, v.instance.Generation, msg)
Expand Down Expand Up @@ -1183,6 +1184,18 @@ func (v *VRGInstance) processAsPrimary() ctrl.Result {

v.reconcileAsPrimary()

// restore kube objects
if v.shouldRestoreK8sObjects() {
err := v.kubeObjectsRecover(&v.result)

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Build image

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Unit tests

not enough arguments in call to v.kubeObjectsRecover

Check failure on line 1189 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Unit tests

not enough arguments in call to v.kubeObjectsRecover
if err != nil {
v.log.Info("Kube objects restore failed")
v.errorConditionLogAndSet(err, "Failed to restore k8s objects", setVRGK8sObjectsErrorCondition)

return v.updateVRGStatus(v.result)
}
v.log.Info("Kube objects restored", "count", objectsRestored)

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Build image

undefined: objectsRestored

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

undefined: objectsRestored) (typecheck)

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

undefined: objectsRestored (typecheck)

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint (.)

undefined: objectsRestored) (typecheck)

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Unit tests

undefined: objectsRestored

Check failure on line 1196 in internal/controller/volumereplicationgroup_controller.go

View workflow job for this annotation

GitHub Actions / Unit tests

undefined: objectsRestored
}

// If requeue is false, then VRG was successfully processed as primary.
// Hence the event to be generated is Success of type normal.
// Expectation is that, if something failed and requeue is true, then
Expand Down Expand Up @@ -1224,6 +1237,28 @@ func (v *VRGInstance) shouldRestoreClusterData() bool {
return true
}

func (v *VRGInstance) shouldRestoreK8sObjects() bool {
k8sObjectsRestored := findCondition(v.instance.Status.Conditions, VRGConditionTypeK8sObjectsReady)
if k8sObjectsRestored != nil {
v.log.Info("K8sObjectsReady condition",
"status", k8sObjectsRestored.Status,
"reason", k8sObjectsRestored.Reason,
"message", k8sObjectsRestored.Message,
"observedGeneration", k8sObjectsRestored.ObservedGeneration,
"generation", v.instance.Generation,
)

if k8sObjectsRestored.Status == metav1.ConditionTrue &&
k8sObjectsRestored.ObservedGeneration == v.instance.Generation {
v.log.Info("VRG's K8sObjectsReady condition found. All k8s objects must have already been restored")

return false
}
}

return true
}

func (v *VRGInstance) reconcileAsPrimary() {
var finalSyncPrepared struct {
volSync bool
Expand Down
10 changes: 9 additions & 1 deletion internal/controller/vrg_kubeobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,15 @@ func (v *VRGInstance) kubeObjectsRecover(result *ctrl.Result, s3ProfileName stri
v.instance.Status.KubeObjectProtection.CaptureToRecoverFrom = captureToRecoverFromIdentifier
log := v.log.WithValues("number", captureToRecoverFromIdentifier.Number, "profile", s3ProfileName)

return v.kubeObjectsRecoveryStartOrResume(result, s3ProfileName, captureToRecoverFromIdentifier, log)
err = v.kubeObjectsRecoveryStartOrResume(result, s3ProfileName, captureToRecoverFromIdentifier, log)
if err != nil {
return fmt.Errorf("kube objects recovery error: %v", err)
}

setVRGK8sObjectsReadyCondition(&v.instance.Status.Conditions,
v.instance.Generation, "Kube objects restored")

return nil
}

func (v *VRGInstance) findS3StoreAccessor(s3ProfileName string) (s3StoreAccessor, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/vrg_volrep.go
Original file line number Diff line number Diff line change
Expand Up @@ -2044,7 +2044,7 @@ func (v *VRGInstance) restorePVsAndPVCsFromS3(result *ctrl.Result) (int, error)

v.log.Info(fmt.Sprintf("Restored %d PVs and %d PVCs using profile %s", pvCount, pvcCount, s3ProfileName))

return pvCount + pvcCount, v.kubeObjectsRecover(result, s3ProfileName)
return pvCount + pvcCount, nil
}

if NoS3 {
Expand Down

0 comments on commit 18d738b

Please sign in to comment.