-
Notifications
You must be signed in to change notification settings - Fork 116
fix: report cancelled status when PipelineRun is deleted #2349
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,12 +2,15 @@ package reconciler | |
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/keys" | ||
| "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1" | ||
| "github.com/openshift-pipelines/pipelines-as-code/pkg/kubeinteraction" | ||
| "github.com/openshift-pipelines/pipelines-as-code/pkg/provider" | ||
| tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" | ||
| "go.uber.org/zap" | ||
| "k8s.io/apimachinery/pkg/api/errors" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "knative.dev/pkg/logging" | ||
|
|
@@ -59,6 +62,37 @@ func (r *Reconciler) FinalizeKind(ctx context.Context, pr *tektonv1.PipelineRun) | |
| } | ||
| return nil | ||
| } | ||
|
|
||
| // report the PipelineRun as cancelled as it was queued or started but it is deleted | ||
| // but its status is still in progress or queued on git provider | ||
| if err := r.reportPipelineRunAsCancelled(ctx, logger, repo, pr); err != nil { | ||
| logger.Errorf("failed to report started pipeline run as cancelled: %w", err) | ||
| return err | ||
| } | ||
|
Comment on lines
+66
to
+71
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be defered as soon as we confirm the Repository? SInce there are some fast-returns inside this if-statement there's several happy paths and failure paths which could cause this to get skipped |
||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (r *Reconciler) reportPipelineRunAsCancelled(ctx context.Context, logger *zap.SugaredLogger, repo *v1alpha1.Repository, pr *tektonv1.PipelineRun) error { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In other functions we use |
||
| detectedProvider, event, err := r.initGitProviderClient(ctx, logger, repo, pr) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| consoleURL := r.run.Clients.ConsoleUI().DetailURL(pr) | ||
| status := provider.StatusOpts{ | ||
| Conclusion: "cancelled", | ||
| Text: fmt.Sprintf("PipelineRun %s was deleted", pr.GetName()), | ||
| DetailsURL: consoleURL, | ||
| PipelineRunName: pr.GetName(), | ||
| PipelineRun: pr, | ||
| OriginalPipelineRunName: pr.GetAnnotations()[keys.OriginalPRName], | ||
| } | ||
|
|
||
| if err := createStatusWithRetry(ctx, logger, detectedProvider, event, status); err != nil { | ||
| return fmt.Errorf("failed to report cancelled status to provider: %w", err) | ||
| } | ||
|
|
||
| logger.Infof("updated cancelled status on provider platform for pipelineRun %s", pr.GetName()) | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -293,40 +293,10 @@ func (r *Reconciler) updatePipelineRunToInProgress(ctx context.Context, logger * | |||||||
| if err != nil { | ||||||||
| return fmt.Errorf("cannot update state: %w", err) | ||||||||
| } | ||||||||
| pacInfo := r.run.Info.GetPacOpts() | ||||||||
| detectedProvider, event, err := r.detectProvider(ctx, logger, pr) | ||||||||
| if err != nil { | ||||||||
| logger.Error(err) | ||||||||
| return nil | ||||||||
| } | ||||||||
| detectedProvider.SetPacInfo(&pacInfo) | ||||||||
|
|
||||||||
| if event.InstallationID > 0 { | ||||||||
| event.Provider.WebhookSecret, _ = pac.GetCurrentNSWebhookSecret(ctx, r.kinteract, r.run) | ||||||||
| } else { | ||||||||
| // secretNS is needed when git provider is other than Github. | ||||||||
| secretNS := repo.GetNamespace() | ||||||||
| if repo.Spec.GitProvider != nil && repo.Spec.GitProvider.Secret == nil && r.globalRepo != nil && r.globalRepo.Spec.GitProvider != nil && r.globalRepo.Spec.GitProvider.Secret != nil { | ||||||||
| secretNS = r.globalRepo.GetNamespace() | ||||||||
| } | ||||||||
|
|
||||||||
| secretFromRepo := pac.SecretFromRepository{ | ||||||||
| K8int: r.kinteract, | ||||||||
| Config: detectedProvider.GetConfig(), | ||||||||
| Event: event, | ||||||||
| Repo: repo, | ||||||||
| WebhookType: pacInfo.WebhookType, | ||||||||
| Logger: logger, | ||||||||
| Namespace: secretNS, | ||||||||
| } | ||||||||
| if err := secretFromRepo.Get(ctx); err != nil { | ||||||||
| return fmt.Errorf("cannot get secret from repository: %w", err) | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| err = detectedProvider.SetClient(ctx, r.run, event, repo, r.eventEmitter) | ||||||||
| detectedProvider, event, err := r.initGitProviderClient(ctx, logger, repo, pr) | ||||||||
| if err != nil { | ||||||||
| return fmt.Errorf("cannot set client: %w", err) | ||||||||
| return fmt.Errorf("cannot initialize git provider client: %w", err) | ||||||||
| } | ||||||||
|
|
||||||||
| consoleURL := r.run.Clients.ConsoleUI().DetailURL(pr) | ||||||||
|
|
@@ -364,6 +334,45 @@ func (r *Reconciler) updatePipelineRunToInProgress(ctx context.Context, logger * | |||||||
| return nil | ||||||||
| } | ||||||||
|
|
||||||||
| func (r *Reconciler) initGitProviderClient(ctx context.Context, logger *zap.SugaredLogger, repo *v1alpha1.Repository, pr *tektonv1.PipelineRun) (provider.Interface, *info.Event, error) { | ||||||||
| pacInfo := r.run.Info.GetPacOpts() | ||||||||
| detectedProvider, event, err := r.detectProvider(ctx, logger, pr) | ||||||||
| if err != nil { | ||||||||
| return nil, nil, fmt.Errorf("cannot detect provider: %w", err) | ||||||||
| } | ||||||||
| detectedProvider.SetPacInfo(&pacInfo) | ||||||||
|
|
||||||||
| if event.InstallationID > 0 { | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking suggestion
Suggested change
|
||||||||
| event.Provider.WebhookSecret, _ = pac.GetCurrentNSWebhookSecret(ctx, r.kinteract, r.run) | ||||||||
| } else { | ||||||||
| // secretNS is needed when git provider is other than Github. | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| secretNS := repo.GetNamespace() | ||||||||
| if repo.Spec.GitProvider != nil && repo.Spec.GitProvider.Secret == nil && r.globalRepo != nil && r.globalRepo.Spec.GitProvider != nil && r.globalRepo.Spec.GitProvider.Secret != nil { | ||||||||
| secretNS = r.globalRepo.GetNamespace() | ||||||||
| } | ||||||||
|
|
||||||||
| secretFromRepo := pac.SecretFromRepository{ | ||||||||
| K8int: r.kinteract, | ||||||||
| Config: detectedProvider.GetConfig(), | ||||||||
| Event: event, | ||||||||
| Repo: repo, | ||||||||
| WebhookType: pacInfo.WebhookType, | ||||||||
| Logger: logger, | ||||||||
| Namespace: secretNS, | ||||||||
| } | ||||||||
| if err := secretFromRepo.Get(ctx); err != nil { | ||||||||
| return nil, nil, fmt.Errorf("cannot get secret from repository: %w", err) | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| err = detectedProvider.SetClient(ctx, r.run, event, repo, r.eventEmitter) | ||||||||
| if err != nil { | ||||||||
| return nil, nil, fmt.Errorf("cannot set client: %w", err) | ||||||||
| } | ||||||||
|
|
||||||||
| return detectedProvider, event, nil | ||||||||
| } | ||||||||
|
|
||||||||
| func (r *Reconciler) updatePipelineRunState(ctx context.Context, logger *zap.SugaredLogger, pr *tektonv1.PipelineRun, state string) (*tektonv1.PipelineRun, error) { | ||||||||
| currentState := pr.GetAnnotations()[keys.State] | ||||||||
| logger.Infof("updating pipelineRun %v/%v state from %s to %s", pr.GetNamespace(), pr.GetName(), currentState, state) | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if
return erris the right move here, since it will block the finalizer from being cleared. On one hand, that will help ensure the status is updated. On the other hand though, if for example a repository CR's API key expires or is rate limited, its PLRs effectively can't be deleted. WDYT?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I was also skeptic about it that whether we should error out on api failure or not π€ but now I'm more inclined towards to not returning error. I will update this