Skip to content

Commit 2cae046

Browse files
author
Shivam Mukhade
authored
Merge pull request #559 from chmouel/issue-430-match-timeout-from-pipelinerun
Respect timeout from pr by default
2 parents 3b67589 + 5e3db73 commit 2cae046

File tree

10 files changed

+48
-21
lines changed

10 files changed

+48
-21
lines changed

config/302-pac-configmap.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ data:
4242
# Add extra IPS (ie: 127.0.0.1) or networks (127.0.0.0/16) separated by commas.
4343
bitbucket-cloud-additional-source-ip: ""
4444

45-
# The default time to wait for a pipelineRun
46-
default-pipelinerun-timeout: "2h"
45+
# Global setting for pipelinerun timeout regardless of how the user
46+
# pipelinerun timeout.
47+
# default-pipelinerun-timeout: "2h"
4748

4849
kind: ConfigMap
4950
metadata:

docs/content/docs/install/settings.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,15 @@ There is a few things you can configure through the configmap
4040

4141
The base URL for the [tekton hub](https://github.com/tektoncd/hub/)
4242
API. default to the [public hub](https://hub.tekton.dev/): <https://api.hub.tekton.dev/v1>
43+
44+
* `default-pipelinerun-timeout`
45+
46+
Let specify a global timeout across all pipeline. If you define the value
47+
every PipelineRun running under Pipelines-as-Code
48+
49+
If it hasn't been set the timeout setting ordering will be :
50+
51+
* Picked up from the timeout setting [as
52+
defined](https://tekton.dev/docs/pipelines/pipelineruns/#configuring-a-failure-timeout)
53+
in the `PipelineRun` spec.timeout.
54+
* If it hasn't defined it will use the default tekton controller timeout setting (default: 1 hour).

pkg/adapter/adapter.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ func (l listener) handleEvent() http.HandlerFunc {
129129
localRequest := request.Clone(request.Context())
130130

131131
go func() {
132-
s.processEvent(ctx, localRequest, payload)
132+
err := s.processEvent(ctx, localRequest, payload)
133+
if err != nil {
134+
l.run.Clients.Log.Errorf("an error occurred: %v", err)
135+
}
133136
}()
134137

135138
l.writeResponse(response, http.StatusAccepted, "accepted")

pkg/adapter/sinker.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ type sinker struct {
2020
event *info.Event
2121
}
2222

23-
func (s *sinker) processEvent(ctx context.Context, request *http.Request, payload []byte) {
23+
func (s *sinker) processEvent(ctx context.Context, request *http.Request, payload []byte) error {
2424
var err error
2525
s.event, err = s.vcx.ParsePayload(ctx, s.run, request, string(payload))
2626
if err != nil {
2727
s.run.Clients.Log.Errorf("failed to parse event: %v", err)
28-
return
28+
return err
2929
}
3030
s.event.Request = &info.Request{
3131
Header: request.Header,
@@ -44,4 +44,5 @@ func (s *sinker) processEvent(ctx context.Context, request *http.Request, payloa
4444
s.run.Clients.Log.Errorf("Cannot create status: %s %s", err, createStatusErr)
4545
}
4646
}
47+
return err
4748
}

pkg/kubeinteraction/wait.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
const (
1717
interval = 1 * time.Second
18-
timeout = 120 * time.Minute
1918
)
2019

2120
type ConditionAccessorFn func(ca knativeapi.ConditionAccessor) (bool, error)
@@ -83,11 +82,11 @@ func PipelineRunSucceed(name string) ConditionAccessorFn {
8382
return Succeed(name)
8483
}
8584

86-
func PollImmediateWithContext(ctx context.Context, fn func() (bool, error)) error {
87-
return wait.PollImmediate(interval, timeout, func() (bool, error) {
85+
func PollImmediateWithContext(ctx context.Context, pollTimeout time.Duration, fn func() (bool, error)) error {
86+
return wait.PollImmediate(interval, pollTimeout, func() (bool, error) {
8887
select {
8988
case <-ctx.Done():
90-
return true, ctx.Err()
89+
return true, fmt.Errorf("polling timed out, pipelinerun has exceeded its timeout: %v", pollTimeout)
9190
default:
9291
}
9392
return fn()
@@ -101,7 +100,8 @@ func PollImmediateWithContext(ctx context.Context, fn func() (bool, error)) erro
101100
func waitForPipelineRunState(ctx context.Context, tektonbeta1 tektonv1beta1client.TektonV1beta1Interface, pr *v1beta1.PipelineRun, polltimeout time.Duration, inState ConditionAccessorFn) error {
102101
ctx, cancel := context.WithTimeout(ctx, polltimeout)
103102
defer cancel()
104-
return PollImmediateWithContext(ctx, func() (bool, error) {
103+
104+
return PollImmediateWithContext(ctx, polltimeout, func() (bool, error) {
105105
r, err := tektonbeta1.PipelineRuns(pr.Namespace).Get(ctx, pr.Name, metav1.GetOptions{})
106106
if err != nil {
107107
return true, err

pkg/params/info/pac.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type PacOpts struct {
1717
TektonDashboardURL string
1818
HubURL string
1919
RemoteTasks bool
20-
DefaultPipelineRunTimeout time.Duration
20+
DefaultPipelineRunTimeout *time.Duration
2121

2222
// bitbucket cloud specific fields
2323
BitbucketCloudCheckSourceIP bool

pkg/params/run.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func (r *Run) GetConfigFromConfigMap(ctx context.Context) error {
3333
if ns == "" {
3434
return fmt.Errorf("failed to find pipelines-as-code installation namespace")
3535
}
36+
// TODO: move this to kubeinteractions class so we can add unittests.
3637
cfg, err := r.Clients.Kube.CoreV1().ConfigMaps(ns).Get(ctx, info.PACConfigmapName, v1.GetOptions{})
3738
if err != nil {
3839
return err
@@ -72,14 +73,10 @@ func (r *Run) GetConfigFromConfigMap(ctx context.Context) error {
7273
if timeout, ok := cfg.Data["default-pipelinerun-timeout"]; ok {
7374
parsedTimeout, err := time.ParseDuration(timeout)
7475
if err != nil {
75-
r.Clients.Log.Infof("failed to parse default-pipelinerun-timeout: %s, using %v as default timeout",
76-
cfg.Data["default-pipelinerun-timeout"], info.DefaultPipelineRunTimeout)
77-
r.Info.Pac.DefaultPipelineRunTimeout = info.DefaultPipelineRunTimeout
76+
r.Clients.Log.Errorf("failed to parse default-pipelinerun-timeout: %s", cfg.Data["default-pipelinerun-timeout"])
7877
} else {
79-
r.Info.Pac.DefaultPipelineRunTimeout = parsedTimeout
78+
r.Info.Pac.DefaultPipelineRunTimeout = &parsedTimeout
8079
}
81-
} else {
82-
r.Info.Pac.DefaultPipelineRunTimeout = info.DefaultPipelineRunTimeout
8380
}
8481

8582
if check, ok := cfg.Data["bitbucket-cloud-check-source-ip"]; ok {

pkg/pipelineascode/pipelineascode.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"path/filepath"
77
"strconv"
8+
"time"
89

910
apipac "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode"
1011
"github.com/openshift-pipelines/pipelines-as-code/pkg/formatting"
@@ -173,9 +174,18 @@ func Run(ctx context.Context, cs *params.Run, providerintf provider.Interface, k
173174
return fmt.Errorf("cannot create a in_progress status on the provider platform: %w", err)
174175
}
175176

177+
var duration time.Duration
178+
if cs.Info.Pac.DefaultPipelineRunTimeout != nil {
179+
duration = *cs.Info.Pac.DefaultPipelineRunTimeout
180+
} else {
181+
// Tekton Pipeline controller should always set this value.
182+
duration = pr.Spec.Timeout.Duration + 1*time.Minute
183+
}
176184
cs.Clients.Log.Infof("Waiting for PipelineRun %s/%s to Succeed in a maximum time of %s minutes",
177-
pr.Namespace, pr.Name, formatting.HumanDuration(cs.Info.Pac.DefaultPipelineRunTimeout))
178-
if err := k8int.WaitForPipelineRunSucceed(ctx, cs.Clients.Tekton.TektonV1beta1(), pr, cs.Info.Pac.DefaultPipelineRunTimeout); err != nil {
185+
pr.Namespace, pr.Name, formatting.HumanDuration(duration))
186+
if err := k8int.WaitForPipelineRunSucceed(ctx, cs.Clients.Tekton.TektonV1beta1(), pr, duration); err != nil {
187+
// if we have a timeout from the pipeline run, we would not know it. We would need to get the PR status to know.
188+
// maybe something to improve in the future.
179189
return fmt.Errorf("pipelinerun %s in namespace %s has a failed status: %w",
180190
pipelineRun.GetGenerateName(), repo.GetNamespace(), err)
181191
}

pkg/pipelineascode/pipelinesascode_github_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/http"
1111
"strings"
1212
"testing"
13+
"time"
1314

1415
"github.com/google/go-github/v43/github"
1516
"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
@@ -332,6 +333,7 @@ func TestRun(t *testing.T) {
332333
stdata, _ := testclient.SeedTestData(t, ctx, tdata)
333334
tdc := testDynamic.Options{}
334335
dc, _ := tdc.Client()
336+
duration, _ := time.ParseDuration("0h0m5s")
335337
cs := &params.Run{
336338
Clients: clients.Clients{
337339
PipelineAsCode: stdata.PipelineAsCode,
@@ -343,7 +345,8 @@ func TestRun(t *testing.T) {
343345
},
344346
Info: info.Info{
345347
Pac: &info.PacOpts{
346-
SecretAutoCreation: true,
348+
SecretAutoCreation: true,
349+
DefaultPipelineRunTimeout: &duration,
347350
},
348351
},
349352
}

test/pkg/wait/wait.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type Opts struct {
2323
func UntilRepositoryUpdated(ctx context.Context, clients clients.Clients, opts Opts) error {
2424
ctx, cancel := context.WithTimeout(ctx, opts.PollTimeout)
2525
defer cancel()
26-
return kubeinteraction.PollImmediateWithContext(ctx, func() (bool, error) {
26+
return kubeinteraction.PollImmediateWithContext(ctx, opts.PollTimeout, func() (bool, error) {
2727
clients.PipelineAsCode.PipelinesascodeV1alpha1().Repositories(opts.Namespace)
2828
r, err := clients.PipelineAsCode.PipelinesascodeV1alpha1().Repositories(opts.Namespace).Get(ctx, opts.RepoName,
2929
metav1.GetOptions{})

0 commit comments

Comments
 (0)