diff --git a/cli/exec/exec.go b/cli/exec/exec.go index 641ae5485..0182e1f16 100644 --- a/cli/exec/exec.go +++ b/cli/exec/exec.go @@ -23,8 +23,8 @@ import ( "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/compiler" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/linter" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/matrix" - "github.com/woodpecker-ci/woodpecker/pipeline/interrupt" "github.com/woodpecker-ci/woodpecker/pipeline/multipart" + "github.com/woodpecker-ci/woodpecker/shared/utils" ) // Command exports the exec command. @@ -192,7 +192,9 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout")) defer cancel() - ctx = interrupt.WithContext(ctx) + ctx = utils.WithContextSigtermCallback(ctx, func() { + println("ctrl+c received, terminating process") + }) return pipeline.New(compiled, pipeline.WithContext(ctx), diff --git a/cmd/agent/agent.go b/cmd/agent/agent.go index a4d07cede..a52ceb268 100644 --- a/cmd/agent/agent.go +++ b/cmd/agent/agent.go @@ -35,6 +35,7 @@ import ( "github.com/woodpecker-ci/woodpecker/agent" "github.com/woodpecker-ci/woodpecker/pipeline/backend" "github.com/woodpecker-ci/woodpecker/pipeline/rpc" + "github.com/woodpecker-ci/woodpecker/shared/utils" ) func loop(c *cli.Context) error { @@ -119,7 +120,7 @@ func loop(c *cli.Context) error { context.Background(), metadata.Pairs("hostname", hostname), ) - ctx = WithContextFunc(ctx, func() { + ctx = utils.WithContextSigtermCallback(ctx, func() { println("ctrl+c received, terminating process") sigterm.Set() }) diff --git a/cmd/agent/signal.go b/cmd/agent/signal.go deleted file mode 100644 index cec55529b..000000000 --- a/cmd/agent/signal.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017 Drone.IO Inc. -// -// This file is licensed under the terms of the MIT license. -// For a copy, see https://opensource.org/licenses/MIT. - -package main - -import ( - "context" - "os" - "os/signal" - "syscall" -) - -// WithContextFunc returns a copy of parent context that is canceled when -// an os interrupt signal is received. The callback function f is invoked -// before cancellation. -func WithContextFunc(ctx context.Context, f func()) context.Context { - ctx, cancel := context.WithCancel(ctx) - go func() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - defer signal.Stop(c) - - select { - case <-ctx.Done(): - case <-c: - f() - cancel() - } - }() - - return ctx -} diff --git a/pipeline/interrupt/interrupt.go b/pipeline/interrupt/interrupt.go deleted file mode 100644 index 477db8dc7..000000000 --- a/pipeline/interrupt/interrupt.go +++ /dev/null @@ -1,36 +0,0 @@ -package interrupt - -import ( - "context" - "os" - "os/signal" -) - -// WithContext returns a copy of parent context whose Done channel is closed -// when an os interrupt signal is received. -func WithContext(ctx context.Context) context.Context { - return WithContextFunc(ctx, func() { - println("ctrl+c received, terminating process") - }) -} - -// WithContextFunc returns a copy of parent context that is canceled when -// an os interrupt signal is received. The callback function f is invoked -// before cancellation. -func WithContextFunc(ctx context.Context, f func()) context.Context { - ctx, cancel := context.WithCancel(ctx) - go func() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - defer signal.Stop(c) - - select { - case <-ctx.Done(): - case <-c: - f() - cancel() - } - }() - - return ctx -} diff --git a/shared/utils/context.go b/shared/utils/context.go new file mode 100644 index 000000000..66cc6687d --- /dev/null +++ b/shared/utils/context.go @@ -0,0 +1,44 @@ +// Copyright 2022 Woodpecker 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 utils + +import ( + "context" + "os" + "os/signal" + "syscall" +) + +// Returns a copy of parent context that is canceled when +// an os interrupt signal is received. +func WithContextSigtermCallback(ctx context.Context, f func()) context.Context { + ctx, cancel := context.WithCancel(ctx) + go func() { + recivedSignal := make(chan os.Signal, 1) + signal.Notify(recivedSignal, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(recivedSignal) + + select { + case <-ctx.Done(): + case <-recivedSignal: + cancel() + if f != nil { + f() + } + } + }() + + return ctx +}