60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
package commands
|
|
|
|
import (
|
|
gocontext "context"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/containerd/containerd"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type killer interface {
|
|
Kill(gocontext.Context, syscall.Signal, ...containerd.KillOpts) error
|
|
}
|
|
|
|
// ForwardAllSignals forwards signals
|
|
func ForwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal {
|
|
sigc := make(chan os.Signal, 128)
|
|
signal.Notify(sigc)
|
|
go func() {
|
|
for s := range sigc {
|
|
logrus.Debug("forwarding signal ", s)
|
|
if err := task.Kill(ctx, s.(syscall.Signal)); err != nil {
|
|
logrus.WithError(err).Errorf("forward signal %s", s)
|
|
}
|
|
}
|
|
}()
|
|
return sigc
|
|
}
|
|
|
|
// StopCatch stops and closes a channel
|
|
func StopCatch(sigc chan os.Signal) {
|
|
signal.Stop(sigc)
|
|
close(sigc)
|
|
}
|
|
|
|
// ParseSignal parses a given string into a syscall.Signal
|
|
// it checks that the signal exists in the platform-appropriate signalMap
|
|
func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
|
s, err := strconv.Atoi(rawSignal)
|
|
if err == nil {
|
|
sig := syscall.Signal(s)
|
|
for _, msig := range signalMap {
|
|
if sig == msig {
|
|
return sig, nil
|
|
}
|
|
}
|
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
}
|
|
signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
|
|
if !ok {
|
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
}
|
|
return signal, nil
|
|
}
|