Skip to content

Commit

Permalink
Add timeout support
Browse files Browse the repository at this point in the history
Waiting on tektoncd/pipeline#355 to be
merged to add top-level timeout.
  • Loading branch information
abayer committed Jan 31, 2019
1 parent a9b0fb7 commit fa0c817
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 8 deletions.
56 changes: 49 additions & 7 deletions pkg/buildpipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"regexp"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -69,10 +70,26 @@ type Timeout struct {
Unit TimeoutUnit `yaml:"unit,omitempty"`
}

// TODO: Not yet implemented in build-pipeline
func (t Timeout) ToDuration() (*metav1.Duration, error) {
durationStr := ""
// TODO: Populate a default timeout unit, most likely seconds.
if t.Unit != "" {
durationStr = fmt.Sprintf("%d%c", t.Time, t.Unit[0])
} else {
durationStr = fmt.Sprintf("%ds", t.Time)
}

if d, err := time.ParseDuration(durationStr); err != nil {
return nil, err
} else {
return &metav1.Duration{Duration: d}, nil
}
}

type RootOptions struct {
Timeout Timeout `yaml:"timeout,omitempty"`
Retry int8 `yaml:"retry,omitempty"`
// TODO: Not yet implemented in build-pipeline
Retry int8 `yaml:"retry,omitempty"`
}

type Stash struct {
Expand All @@ -86,12 +103,13 @@ type Unstash struct {
Dir string `yaml:"dir,omitempty"`
}

// TODO: Not yet implemented in build-pipeline
type StageOptions struct {
RootOptions `yaml:",inline"`

Stash Stash `yaml:"stash,omitempty"`
Unstash Unstash `yaml:"unstash,omitempty"`
// TODO: Not yet implemented in build-pipeline
Stash Stash `yaml:"stash,omitempty"`
Unstash Unstash `yaml:"unstash,omitempty"`

Workspace *string `yaml:"workspace,omitempty"`
}

Expand Down Expand Up @@ -585,11 +603,18 @@ func stageToTask(s Stage, pipelineIdentifier string, buildIdentifier string, nam
return nil, errors.New("post on stages not yet supported")
}

duration := &metav1.Duration{}

if !equality.Semantic.DeepEqual(s.Options, StageOptions{}) {
o := s.Options
if !equality.Semantic.DeepEqual(o.Timeout, Timeout{}) {
return nil, errors.New("Timeout on stage not yet supported")
if d, err := o.Timeout.ToDuration(); err != nil {
return nil, err
} else {
duration = d
}
}

if o.Retry != 0 {
return nil, errors.New("Retry on stage not yet supported")
}
Expand Down Expand Up @@ -636,6 +661,10 @@ func stageToTask(s Stage, pipelineIdentifier string, buildIdentifier string, nam
ws.TargetPath = wsPath
}

if !equality.Semantic.DeepEqual(duration, &metav1.Duration{}) {
t.Spec.Timeout = duration
}

t.Spec.Inputs = &pipelinev1alpha1.Inputs{
Resources: []pipelinev1alpha1.TaskResource{*ws,
{
Expand Down Expand Up @@ -734,8 +763,21 @@ func (j *Jenkinsfile) GenerateCRDs(pipelineIdentifier string, buildIdentifier st
if len(j.Post) != 0 {
return nil, nil, errors.New("post at top level not yet supported")
}

// duration := &metav1.Duration{}

if !equality.Semantic.DeepEqual(j.Options, RootOptions{}) {
return nil, nil, errors.New("options at top level not yet supported")
o := j.Options
if !equality.Semantic.DeepEqual(o.Timeout, Timeout{}) {
if _, err := o.Timeout.ToDuration(); err != nil {
return nil, nil, err
} else {
// duration = d
}
}
if o.Retry != 0 {
return nil, nil, errors.New("Retry at top level not yet supported")
}
}

if suffix == "" {
Expand Down
55 changes: 54 additions & 1 deletion pkg/buildpipeline/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/knative/pkg/apis"
"io/ioutil"
"testing"
"time"
)

// TODO: Write a builder for generating the expected objects. Because
Expand Down Expand Up @@ -757,7 +758,7 @@ func TestParseJenkinsfileYaml(t *testing.T) {
}},
}},
},
expectedErrorMsg: "options at top level not yet supported",
expectedErrorMsg: "Retry at top level not yet supported",
},
{
name: "stage_and_step_agent",
Expand Down Expand Up @@ -857,6 +858,58 @@ func TestParseJenkinsfileYaml(t *testing.T) {
)),
},
},
{
name: "stage timeout",
yaml: `apiVersion: v0.1
agent:
image: some-image
stages:
- name: A Working Stage
options:
timeout:
time: 50
unit: minutes
steps:
- command: echo
args:
- hello
- world
`,
expected: &Jenkinsfile{
APIVersion: "v0.1",
Agent: Agent{
Image: "some-image",
},
Stages: []Stage{{
Name: "A Working Stage",
Options: StageOptions{
RootOptions: RootOptions{
Timeout: Timeout{
Time: 50,
Unit: "minutes",
},
},
},
Steps: []Step{{
Command: "echo",
Arguments: []string{"hello", "world"},
}},
}},
},
pipeline: tb.Pipeline("somepipeline-build-somebuild-abcd", "somenamespace", tb.PipelineSpec(
tb.PipelineTask("a-working-stage", "somepipeline-build-somebuild-stage-a-working-stage-abcd",
tb.PipelineTaskInputResource("workspace", "common-workspace")),
tb.PipelineDeclaredResource("common-workspace", pipelinev1alpha1.PipelineResourceTypeGit))),
tasks: []*pipelinev1alpha1.Task{
tb.Task("somepipeline-build-somebuild-stage-a-working-stage-abcd", "somenamespace", tb.TaskSpec(
tb.TaskTimeout(50*time.Minute),
tb.TaskInputs(tb.InputsResource("workspace", pipelinev1alpha1.PipelineResourceTypeGit,
tb.ResourceTargetPath("workspace"))),
tb.TaskOutputs(tb.OutputsResource("workspace", pipelinev1alpha1.PipelineResourceTypeGit)),
tb.Step("stage-a-working-stage-step-0-abcd", "some-image", tb.Command("echo"), tb.Args("hello", "world")),
)),
},
},
}

for _, tt := range tests {
Expand Down

0 comments on commit fa0c817

Please sign in to comment.