Skip to content

Commit b850226

Browse files
committed
Change TimeoutHandler to respect namespace scoping
* Pass `--namespace` value to taskrun and pipelinerun NewController to facilitate namespace-scoped behaviors * Change TimeoutHandler `CheckTimeouts` to timeout taskrun/pipelinerun's in the scoped namespace or all namespaces (default if unset) Related: #2603
1 parent 62f41d8 commit b850226

File tree

7 files changed

+113
-22
lines changed

7 files changed

+113
-22
lines changed

cmd/controller/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func main() {
7070
ImageDigestExporterImage: *imageDigestExporterImage,
7171
}
7272
sharedmain.MainWithContext(injection.WithNamespaceScope(signals.NewContext(), *namespace), ControllerLogKey,
73-
taskrun.NewController(images),
74-
pipelinerun.NewController(images),
73+
taskrun.NewController(*namespace, images),
74+
pipelinerun.NewController(*namespace, images),
7575
)
7676
}

pkg/reconciler/pipelinerun/controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const (
4545
)
4646

4747
// NewController instantiates a new controller.Impl from knative.dev/pkg/controller
48-
func NewController(images pipeline.Images) func(context.Context, configmap.Watcher) *controller.Impl {
48+
func NewController(namespace string, images pipeline.Images) func(context.Context, configmap.Watcher) *controller.Impl {
4949
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
5050
logger := logging.FromContext(ctx)
5151
kubeclientset := kubeclient.Get(ctx)
@@ -87,7 +87,7 @@ func NewController(images pipeline.Images) func(context.Context, configmap.Watch
8787
impl := controller.NewImpl(c, c.Logger, pipeline.PipelineRunControllerName)
8888

8989
timeoutHandler.SetPipelineRunCallbackFunc(impl.Enqueue)
90-
timeoutHandler.CheckTimeouts(kubeclientset, pipelineclientset)
90+
timeoutHandler.CheckTimeouts(namespace, kubeclientset, pipelineclientset)
9191

9292
c.Logger.Info("Setting up event handlers")
9393
pipelineRunInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

pkg/reconciler/pipelinerun/pipelinerun_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import (
4747
)
4848

4949
var (
50+
namespace = ""
5051
ignoreLastTransitionTime = cmpopts.IgnoreTypes(apis.Condition{}.LastTransitionTime.Inner.Time)
5152
images = pipeline.Images{
5253
EntrypointImage: "override-with-entrypoint:latest",
@@ -75,7 +76,7 @@ func getPipelineRunController(t *testing.T, d test.Data) (test.Assets, func()) {
7576
configMapWatcher := configmap.NewInformedWatcher(c.Kube, system.GetNamespace())
7677
ctx, cancel := context.WithCancel(ctx)
7778
return test.Assets{
78-
Controller: NewController(images)(ctx, configMapWatcher),
79+
Controller: NewController(namespace, images)(ctx, configMapWatcher),
7980
Clients: c,
8081
}, cancel
8182
}

pkg/reconciler/taskrun/controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const (
4545
)
4646

4747
// NewController instantiates a new controller.Impl from knative.dev/pkg/controller
48-
func NewController(images pipeline.Images) func(context.Context, configmap.Watcher) *controller.Impl {
48+
func NewController(namespace string, images pipeline.Images) func(context.Context, configmap.Watcher) *controller.Impl {
4949
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
5050
logger := logging.FromContext(ctx)
5151
kubeclientset := kubeclient.Get(ctx)
@@ -90,7 +90,7 @@ func NewController(images pipeline.Images) func(context.Context, configmap.Watch
9090
impl := controller.NewImpl(c, c.Logger, pipeline.TaskRunControllerName)
9191

9292
timeoutHandler.SetTaskRunCallbackFunc(impl.Enqueue)
93-
timeoutHandler.CheckTimeouts(kubeclientset, pipelineclientset)
93+
timeoutHandler.CheckTimeouts(namespace, kubeclientset, pipelineclientset)
9494

9595
c.Logger.Info("Setting up event handlers")
9696
taskRunInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

pkg/reconciler/taskrun/taskrun_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ const (
6565
)
6666

6767
var (
68-
images = pipeline.Images{
68+
namespace = "" // all namespaces
69+
images = pipeline.Images{
6970
EntrypointImage: "override-with-entrypoint:latest",
7071
NopImage: "tianon/true",
7172
GitImage: "override-with-git:latest",
@@ -268,7 +269,7 @@ func getTaskRunController(t *testing.T, d test.Data) (test.Assets, func()) {
268269
c, _ := test.SeedTestData(t, ctx, d)
269270
configMapWatcher := configmap.NewInformedWatcher(c.Kube, system.GetNamespace())
270271
return test.Assets{
271-
Controller: NewController(images)(ctx, configMapWatcher),
272+
Controller: NewController(namespace, images)(ctx, configMapWatcher),
272273
Clients: c,
273274
}, cancel
274275
}

pkg/reconciler/timeout_handler.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,27 @@ func (t *TimeoutSet) checkPipelineRunTimeouts(namespace string, pipelineclientse
184184
}
185185
}
186186

187-
// CheckTimeouts function iterates through all namespaces and calls corresponding
188-
// taskrun/pipelinerun timeout functions
189-
func (t *TimeoutSet) CheckTimeouts(kubeclientset kubernetes.Interface, pipelineclientset clientset.Interface) {
190-
namespaces, err := kubeclientset.CoreV1().Namespaces().List(metav1.ListOptions{})
191-
if err != nil {
192-
t.logger.Errorf("Can't get namespaces list: %s", err)
193-
return
187+
// CheckTimeouts function iterates through a given namespace or all namespaces
188+
// (if empty string) and calls corresponding taskrun/pipelinerun timeout functions
189+
func (t *TimeoutSet) CheckTimeouts(namespace string, kubeclientset kubernetes.Interface, pipelineclientset clientset.Interface) {
190+
// scoped namespace
191+
namespaceNames := []string{namespace}
192+
// all namespaces
193+
if namespace == "" {
194+
namespaces, err := kubeclientset.CoreV1().Namespaces().List(metav1.ListOptions{})
195+
if err != nil {
196+
t.logger.Errorf("Can't get namespaces list: %s", err)
197+
return
198+
}
199+
namespaceNames = make([]string, len(namespaces.Items))
200+
for i, namespace := range namespaces.Items {
201+
namespaceNames[i] = namespace.GetName()
202+
}
194203
}
195-
for _, namespace := range namespaces.Items {
196-
t.checkTaskRunTimeouts(namespace.GetName(), pipelineclientset)
197-
t.checkPipelineRunTimeouts(namespace.GetName(), pipelineclientset)
204+
205+
for _, namespace := range namespaceNames {
206+
t.checkTaskRunTimeouts(namespace, pipelineclientset)
207+
t.checkPipelineRunTimeouts(namespace, pipelineclientset)
198208
}
199209
}
200210

pkg/reconciler/timeout_handler_test.go

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
)
3737

3838
var (
39+
allNs = ""
3940
testNs = "foo"
4041
simpleStep = tb.Step(testNs, tb.StepCommand("/mycmd"))
4142
simpleTask = tb.Task("test-task", tb.TaskSpec(simpleStep))
@@ -109,7 +110,7 @@ func TestTaskRunCheckTimeouts(t *testing.T) {
109110
}
110111

111112
th.SetTaskRunCallbackFunc(f)
112-
th.CheckTimeouts(c.Kube, c.Pipeline)
113+
th.CheckTimeouts(allNs, c.Kube, c.Pipeline)
113114

114115
for _, tc := range []struct {
115116
name string
@@ -157,6 +158,84 @@ func TestTaskRunCheckTimeouts(t *testing.T) {
157158

158159
}
159160

161+
func TestTaskRunSingleNamespaceCheckTimeouts(t *testing.T) {
162+
taskRunTimedout := tb.TaskRun("test-taskrun-run-timedout-foo", tb.TaskRunNamespace(testNs), tb.TaskRunSpec(
163+
tb.TaskRunTaskRef(simpleTask.Name, tb.TaskRefAPIVersion("a1")),
164+
tb.TaskRunTimeout(1*time.Second),
165+
), tb.TaskRunStatus(tb.StatusCondition(apis.Condition{
166+
Type: apis.ConditionSucceeded,
167+
Status: corev1.ConditionUnknown}),
168+
tb.TaskRunStartTime(time.Now().Add(-10*time.Second)),
169+
))
170+
171+
taskRunTimedoutOtherNS := tb.TaskRun("test-taskrun-run-timedout-bar", tb.TaskRunNamespace("otherNS"), tb.TaskRunSpec(
172+
tb.TaskRunTaskRef(simpleTask.Name, tb.TaskRefAPIVersion("a1")),
173+
tb.TaskRunTimeout(1*time.Second),
174+
), tb.TaskRunStatus(tb.StatusCondition(apis.Condition{
175+
Type: apis.ConditionSucceeded,
176+
Status: corev1.ConditionUnknown}),
177+
tb.TaskRunStartTime(time.Now().Add(-10*time.Second)),
178+
))
179+
180+
d := test.Data{
181+
TaskRuns: []*v1alpha1.TaskRun{taskRunTimedout, taskRunTimedoutOtherNS},
182+
Tasks: []*v1alpha1.Task{simpleTask},
183+
Namespaces: []*corev1.Namespace{{
184+
ObjectMeta: metav1.ObjectMeta{
185+
Name: testNs,
186+
},
187+
}},
188+
}
189+
ctx, _ := ttesting.SetupFakeContext(t)
190+
c, _ := test.SeedTestData(t, ctx, d)
191+
stopCh := make(chan struct{})
192+
defer close(stopCh)
193+
observer, _ := observer.New(zap.InfoLevel)
194+
195+
th := NewTimeoutHandler(stopCh, zap.New(observer).Sugar())
196+
gotCallback := sync.Map{}
197+
f := func(tr interface{}) {
198+
trNew := tr.(*v1alpha1.TaskRun)
199+
gotCallback.Store(trNew.Name, struct{}{})
200+
}
201+
202+
th.SetTaskRunCallbackFunc(f)
203+
th.CheckTimeouts(testNs, c.Kube, c.Pipeline)
204+
205+
for _, tc := range []struct {
206+
name string
207+
taskRun *v1alpha1.TaskRun
208+
expectCallback bool
209+
}{{
210+
name: "timedout",
211+
taskRun: taskRunTimedout,
212+
expectCallback: true,
213+
}, {
214+
name: "timedout",
215+
taskRun: taskRunTimedoutOtherNS,
216+
expectCallback: false,
217+
}} {
218+
t.Run(tc.name, func(t *testing.T) {
219+
if err := wait.PollImmediate(100*time.Millisecond, 3*time.Second, func() (bool, error) {
220+
if tc.expectCallback {
221+
if _, ok := gotCallback.Load(tc.taskRun.Name); ok {
222+
return true, nil
223+
}
224+
return false, nil
225+
}
226+
// not expecting callback
227+
if _, ok := gotCallback.Load(tc.taskRun.Name); ok {
228+
return false, fmt.Errorf("did not expect call back for %s why", tc.taskRun.Name)
229+
}
230+
return true, nil
231+
}); err != nil {
232+
t.Fatalf("Expected %s callback to be %t but got error: %s", tc.name, tc.expectCallback, err)
233+
}
234+
})
235+
}
236+
237+
}
238+
160239
func TestPipelinRunCheckTimeouts(t *testing.T) {
161240
simplePipeline := tb.Pipeline("test-pipeline", tb.PipelineNamespace(testNs), tb.PipelineSpec(
162241
tb.PipelineTask("hello-world-1", "hello-world"),
@@ -235,7 +314,7 @@ func TestPipelinRunCheckTimeouts(t *testing.T) {
235314
}
236315

237316
th.SetPipelineRunCallbackFunc(f)
238-
th.CheckTimeouts(c.Kube, c.Pipeline)
317+
th.CheckTimeouts(allNs, c.Kube, c.Pipeline)
239318
for _, tc := range []struct {
240319
name string
241320
pr *v1alpha1.PipelineRun
@@ -314,7 +393,7 @@ func TestWithNoFunc(t *testing.T) {
314393
t.Fatal("Expected CheckTimeouts function not to panic")
315394
}
316395
}()
317-
testHandler.CheckTimeouts(c.Kube, c.Pipeline)
396+
testHandler.CheckTimeouts(allNs, c.Kube, c.Pipeline)
318397

319398
}
320399

0 commit comments

Comments
 (0)