Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG DFBUGS-1422: vrg: get start time of recover/backup from first velero req #443

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 92 additions & 34 deletions internal/controller/vrg_kubeobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,20 +270,18 @@ func (v *VRGInstance) kubeObjectsCaptureStartOrResume(
}
}

request0, ok := requests[kubeObjectsCaptureName(namePrefix, groups[0].Name, v.s3StoreAccessors[0].S3ProfileName)]
firstRequest := getFirstRequest(groups, requests, namePrefix, v.s3StoreAccessors[0].S3ProfileName)

if ok {
v.kubeObjectsCaptureComplete(
result,
captureStartConditionally,
captureNumber,
veleroNamespaceName,
interval,
labels,
request0.StartTime(),
request0.Object().GetAnnotations(),
)
}
v.kubeObjectsCaptureComplete(
result,
captureStartConditionally,
captureNumber,
veleroNamespaceName,
interval,
labels,
firstRequest.StartTime(),
firstRequest.Object().GetAnnotations(),
)
}

func (v *VRGInstance) executeHook(hook kubeobjects.HookSpec, log1 logr.Logger) error {
Expand Down Expand Up @@ -674,7 +672,8 @@ func (v *VRGInstance) kubeObjectsRecoveryStartOrResume(
}
}

startTime := requests[0].StartTime()
startTime := getRequestsStartTime(requests)

duration := time.Since(startTime.Time)
log.Info("Kube objects recovered", "groups", len(groups), "start", startTime, "duration", duration)

Expand Down Expand Up @@ -800,18 +799,13 @@ func kubeObjectsRequestsWatch(
}

func getCaptureGroups(recipe Recipe.Recipe) ([]kubeobjects.CaptureSpec, error) {
var workflow *Recipe.Workflow

for _, w := range recipe.Spec.Workflows {
if w.Name == Recipe.BackupWorkflowName {
workflow = w

break
}
workflow, err := getBackupWorkflow(recipe)
if err != nil {
return nil, err
}

if workflow == nil {
return nil, ErrWorkflowNotFound
if err := validateWorkflow(workflow); err != nil {
return nil, err
}

resources := make([]kubeobjects.CaptureSpec, len(workflow.Sequence))
Expand All @@ -837,18 +831,13 @@ func getCaptureGroups(recipe Recipe.Recipe) ([]kubeobjects.CaptureSpec, error) {
}

func getRecoverGroups(recipe Recipe.Recipe) ([]kubeobjects.RecoverSpec, error) {
var workflow *Recipe.Workflow

for _, w := range recipe.Spec.Workflows {
if w.Name == Recipe.RestoreWorkflowName {
workflow = w

break
}
workflow, err := getRestoreWorkflow(recipe)
if err != nil {
return nil, err
}

if workflow == nil {
return nil, ErrWorkflowNotFound
if err := validateWorkflow(workflow); err != nil {
return nil, err
}

resources := make([]kubeobjects.RecoverSpec, len(workflow.Sequence))
Expand Down Expand Up @@ -1120,3 +1109,72 @@ func convertRecipeGroupToCaptureSpec(group Recipe.Group) (*kubeobjects.CaptureSp

return &captureSpec, nil
}

func getFirstRequest(groups []kubeobjects.CaptureSpec, requests map[string]kubeobjects.Request,
namePrefix string, s3ProfileName string,
) kubeobjects.Request {
for _, group := range groups {
cg := group

if cg.IsHook {
continue
}

// else it is a resource group
return requests[kubeObjectsCaptureName(namePrefix, cg.Name, s3ProfileName)]
}

return nil
}

func getBackupWorkflow(recipe Recipe.Recipe) (*Recipe.Workflow, error) {
for _, w := range recipe.Spec.Workflows {
if w.Name == Recipe.BackupWorkflowName {
return w, nil
}
}

return nil, ErrWorkflowNotFound
}

func getRestoreWorkflow(recipe Recipe.Recipe) (*Recipe.Workflow, error) {
for _, w := range recipe.Spec.Workflows {
if w.Name == Recipe.RestoreWorkflowName {
return w, nil
}
}

return nil, ErrWorkflowNotFound
}

func validateWorkflow(workflow *Recipe.Workflow) error {
if len(workflow.Sequence) == 0 {
return nil
}

var workflowHasResourceTypeGroup bool

for _, resource := range workflow.Sequence {
for resourceType := range resource {
if resourceType == "group" {
workflowHasResourceTypeGroup = true
}
}
}

if !workflowHasResourceTypeGroup {
return fmt.Errorf("a workflow must contain at least one group")
}

return nil
}

func getRequestsStartTime(requests []kubeobjects.Request) metav1.Time {
for _, request := range requests {
if request != nil {
return request.StartTime()
}
}

return metav1.Time{}
}
7 changes: 7 additions & 0 deletions internal/controller/vrg_recipe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ var _ = Describe("VolumeReplicationGroupRecipe", func() {
}

recipeVolumesDefine(volumes(nssParameterRef))
recipeGroupsDefine(resources(nssParameterRef))
vrgRecipeParametersDefine(parameters)
recipeHooksDefine(hook(ns0ParameterRef))
})
Expand Down Expand Up @@ -496,6 +497,7 @@ var _ = Describe("VolumeReplicationGroupRecipe", func() {
BeforeEach(func() {
nsSlices(1, 2)
vrg.Namespace = nsNamesSlice[0]
recipeGroupsDefine(resources(vrg.Namespace))
})
It("includes only the VRG's namespace in its PVC selection", func() {
Expect(err).ToNot(HaveOccurred())
Expand All @@ -510,6 +512,7 @@ var _ = Describe("VolumeReplicationGroupRecipe", func() {
nsSlices(1, 2)
vrg.Namespace = nsNamesSlice[0]
recipeVolumesDefine(volumes(vrg.Namespace))
recipeGroupsDefine(resources(vrg.Namespace))
})
It("includes only it in its PVC selection", func() {
Expect(err).ToNot(HaveOccurred())
Expand Down Expand Up @@ -549,6 +552,8 @@ var _ = Describe("VolumeReplicationGroupRecipe", func() {
nsSlices(1, 2)
Expect(apiReader.Get(ctx, client.ObjectKeyFromObject(r), r)).To(Succeed())
recipeVolumesDefine(volumes(vrg.Namespace))
recipeGroupsDefine(resources(vrg.Namespace))
recipeCaptureWorkflowDefine(allGroupsAllHooksWorkflow())
Expect(k8sClient.Update(ctx, r)).To(Succeed())
})
It("includes only it in its PVC selection", func() {
Expand Down Expand Up @@ -587,6 +592,8 @@ var _ = Describe("VolumeReplicationGroupRecipe", func() {
Context("recovery hooks in the same namespace", func() {
BeforeEach(func() {
recipeHooksDefine(hook(vrg.Namespace))
recipeGroupsDefine(resources(vrg.Namespace))
recipeCaptureWorkflowDefine(allGroupsAllHooksWorkflow())
})
It("sets DataReady condition's message to something besides a recipe error", func() {
Eventually(vrgDataReadyConditionGet).ShouldNot(BeNil())
Expand Down