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

Add the support of configuring the default timeout of TaskRun #996

Merged
merged 1 commit into from
Jul 3, 2019
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
8 changes: 7 additions & 1 deletion cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/knative/pkg/logging"

apisconfig "github.com/tektoncd/pipeline/pkg/apis/config"
tklogging "github.com/tektoncd/pipeline/pkg/logging"
corev1 "k8s.io/api/core/v1"
kubeinformers "k8s.io/client-go/informers"
Expand Down Expand Up @@ -116,7 +117,11 @@ func main() {

pipelineInformer := pipelineInformerFactory.Tekton().V1alpha1().Pipelines()
pipelineRunInformer := pipelineInformerFactory.Tekton().V1alpha1().PipelineRuns()
timeoutHandler := reconciler.NewTimeoutHandler(stopCh, logger)

store := apisconfig.NewStore(logger.Named("config-store"))
store.WatchConfigs(configMapWatcher)

timeoutHandler := reconciler.NewTimeoutHandler(stopCh, logger, store)

trc := taskrun.NewController(opt,
taskRunInformer,
Expand All @@ -126,6 +131,7 @@ func main() {
podInformer,
nil, //entrypoint cache will be initialized by controller if not provided
timeoutHandler,
store,
)
prc := pipelinerun.NewController(opt,
pipelineRunInformer,
Expand Down
39 changes: 39 additions & 0 deletions config/config-defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2019 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: ConfigMap
metadata:
name: config-defaults
namespace: tekton-pipelines
data:
_example: |
################################
# #
# EXAMPLE CONFIGURATION #
# #
################################

# This block is not actually functional configuration,
# but serves to illustrate the available configuration
# options and document them in a way that is accessible
# to users that `kubectl edit` this config map.
#
# These sample configuration options may be copied out of
# this example block and unindented to be in the data block
# to actually change the configuration.

# default-timeout-minutes contains the default number of
# minutes to use for TaskRun, if none is specified.
default-timeout-minutes: "60" # 60 minutes
2 changes: 1 addition & 1 deletion docs/taskruns.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ following fields:
[input resources](#providing-resources)
- [`outputs`] - Specifies [output resources](#providing-resources)
- `timeout` - Specifies timeout after which the `TaskRun` will fail. Defaults
to ten minutes.
to 60 minutes.
- [`nodeSelector`] - a selector which must be true for the pod to fit on a
node. The selector which must match a node's labels for the pod to be
scheduled on that node. More info:
Expand Down
6 changes: 6 additions & 0 deletions hack/update-codegen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,11 @@ ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
pipeline:v1alpha1 \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt

# Depends on generate-groups.sh to install bin/deepcopy-gen
${GOPATH}/bin/deepcopy-gen \
-O zz_generated.deepcopy \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
-i github.com/tektoncd/pipeline/pkg/apis/config

# Make sure our dependencies are up-to-date
${REPO_ROOT_DIR}/hack/update-deps.sh
63 changes: 63 additions & 0 deletions pkg/apis/config/default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Copyright 2019 The Tekton Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
houshengbo marked this conversation as resolved.
Show resolved Hide resolved
"fmt"
"strconv"

corev1 "k8s.io/api/core/v1"
)

const (
// ConfigName is the name of the configmap
DefaultsConfigName = "config-defaults"
DefaultTimeoutMinutes = 60
defaultTimeoutMinutesKey = "default-timeout-minutes"
)

// ConfigDefault holds the default configurations
// +k8s:deepcopy-gen=true
type ConfigDefault struct {
DefaultTimeoutMinutes int
}

// Equals returns true if two Configs are identical
func (cfg *ConfigDefault) Equals(other *ConfigDefault) bool {
return other.DefaultTimeoutMinutes == cfg.DefaultTimeoutMinutes
}

// NewConfigDefaultFromMap returns a Config given a map corresponding to a ConfigMap
func NewConfigDefaultFromMap(cfgMap map[string]string) (*ConfigDefault, error) {
tc := ConfigDefault{
DefaultTimeoutMinutes: DefaultTimeoutMinutes,
}
if defaultTimeoutMin, ok := cfgMap[defaultTimeoutMinutesKey]; ok {
timeout, err := strconv.ParseInt(defaultTimeoutMin, 10, 0)
if err != nil {
return nil, fmt.Errorf("failed parsing tracing config %q", defaultTimeoutMinutesKey)
}
tc.DefaultTimeoutMinutes = int(timeout)
}

return &tc, nil
}

// NewConfigDefaultFromConfigMap returns a Config for the given configmap
func NewConfigDefaultFromConfigMap(config *corev1.ConfigMap) (*ConfigDefault, error) {
return NewConfigDefaultFromMap(config.Data)
}
49 changes: 49 additions & 0 deletions pkg/apis/config/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright 2019 The Tekton Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"github.com/google/go-cmp/cmp"
test "github.com/tektoncd/pipeline/pkg/reconciler/testing"
"testing"
)

func TestNewConfigDefaultFromConfigMap(t *testing.T) {
expectedConfig := &ConfigDefault{
DefaultTimeoutMinutes: 50,
}
verifyConfigFileWithExpectedConfig(t, DefaultsConfigName, expectedConfig)
}

func TestNewConfigDefaultFromEmptyConfigMap(t *testing.T) {
DefaultsConfigEmptyName := "config-defaults-empty"
expectedConfig := &ConfigDefault{
DefaultTimeoutMinutes: 60,
}
verifyConfigFileWithExpectedConfig(t, DefaultsConfigEmptyName, expectedConfig)
}

func verifyConfigFileWithExpectedConfig(t *testing.T, fileName string, expectedConfig *ConfigDefault) {
cm := test.ConfigMapFromTestFile(t, fileName)
if configDefault, err := NewConfigDefaultFromConfigMap(cm); err == nil {
if d := cmp.Diff(configDefault, expectedConfig); d != "" {
t.Errorf("Diff:\n%s", d)
}
} else {
t.Errorf("NewConfigDefaultFromConfigMap(actual) = %v", err)
}
}
17 changes: 17 additions & 0 deletions pkg/apis/config/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Copyright 2019 The Tekton Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config
91 changes: 91 additions & 0 deletions pkg/apis/config/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright 2019 The Tekton Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"context"
"github.com/knative/pkg/configmap"
)

type cfgKey struct{}

// Config holds the collection of configurations that we attach to contexts.
// +k8s:deepcopy-gen=false
type Config struct {
ConfigDefault *ConfigDefault
}

// FromContext extracts a Config from the provided context.
func FromContext(ctx context.Context) *Config {
x, ok := ctx.Value(cfgKey{}).(*Config)
if ok {
return x
}
return nil
}

// FromContextOrDefaults is like FromContext, but when no Config is attached it
// returns a Config populated with the defaults for each of the Config fields.
func FromContextOrDefaults(ctx context.Context) *Config {
if cfg := FromContext(ctx); cfg != nil {
return cfg
}
defaults, _ := NewConfigDefaultFromMap(map[string]string{})
return &Config{
ConfigDefault: defaults,
}
}

// ToContext attaches the provided Config to the provided context, returning the
// new context with the Config attached.
func ToContext(ctx context.Context, c *Config) context.Context {
return context.WithValue(ctx, cfgKey{}, c)
}

// Store is a typed wrapper around configmap.Untyped store to handle our configmaps.
// +k8s:deepcopy-gen=false
type Store struct {
*configmap.UntypedStore
}

// NewStore creates a new store of Configs and optionally calls functions when ConfigMaps are updated.
func NewStore(logger configmap.Logger, onAfterStore ...func(name string, value interface{})) *Store {
store := &Store{
UntypedStore: configmap.NewUntypedStore(
"defaults",
logger,
configmap.Constructors{
DefaultsConfigName: NewConfigDefaultFromConfigMap,
},
onAfterStore...,
),
}

return store
}

// ToContext attaches the current Config state to the provided context.
func (s *Store) ToContext(ctx context.Context) context.Context {
return ToContext(ctx, s.Load())
}

// Load creates a Config from the current config state of the Store.
func (s *Store) Load() *Config {
return &Config{
ConfigDefault: s.UntypedLoad(DefaultsConfigName).(*ConfigDefault).DeepCopy(),
}
}
38 changes: 38 additions & 0 deletions pkg/apis/config/store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright 2019 The Tekton Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"context"
"github.com/google/go-cmp/cmp"
logtesting "github.com/knative/pkg/logging/testing"
test "github.com/tektoncd/pipeline/pkg/reconciler/testing"
"testing"
)

func TestStoreLoadWithContext(t *testing.T) {
store := NewStore(logtesting.TestLogger(t))
defaultConfig := test.ConfigMapFromTestFile(t, "config-defaults")
store.OnConfigChanged(defaultConfig)

config := FromContext(store.ToContext(context.Background()))

expected, _ := NewConfigDefaultFromConfigMap(defaultConfig)
if diff := cmp.Diff(config.ConfigDefault, expected); diff != "" {
t.Errorf("Unexpected default config (-want, +got): %v", diff)
}
}
39 changes: 39 additions & 0 deletions pkg/apis/config/testdata/config-defaults-empty.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2019 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: ConfigMap
metadata:
name: config-defaults
namespace: tekton-pipelines
data:
_example: |
################################
# #
# EXAMPLE CONFIGURATION #
# #
################################

# This block is not actually functional configuration,
# but serves to illustrate the available configuration
# options and document them in a way that is accessible
# to users that `kubectl edit` this config map.
#
# These sample configuration options may be copied out of
# this example block and unindented to be in the data block
# to actually change the configuration.

# default-timeout-minutes contains the default number of
# minutes to use for TaskRun, if none is specified.
default-timeout-minutes: "60" # 60 minutes
Loading