talos/pkg/cli/context.go
Andrey Smirnov 0babc39653 feat: split osctl commands into Talos API and cluster management
This keeps backwards compatibility with `osctl` CLI binary with the
exception of `osctl config generate` which was renamed to `osctl
gen config` to avoid confusion with other `osctl config`
commands which operate on client config, not Talos server config.

Command implementation and helpers were split into subpackages for
cleaner code and more visible boundaries. The resulting binary still
combines commands from both sections into a single binary.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
2020-03-20 22:45:04 +03:00

46 lines
1.0 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package cli
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
)
// WithContext wraps function call to provide a context cancellable with ^C.
func WithContext(ctx context.Context, f func(context.Context) error) error {
wrappedCtx, wrappedCtxCancel := context.WithCancel(ctx)
defer wrappedCtxCancel()
// listen for ^C and SIGTERM and abort context
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
exited := make(chan struct{})
defer close(exited)
go func() {
select {
case <-sigCh:
wrappedCtxCancel()
case <-wrappedCtx.Done():
return
case <-exited:
}
select {
case <-sigCh:
signal.Stop(sigCh)
fmt.Fprintln(os.Stderr, "Signal received, aborting, press Ctrl+C once again to abort immediately...")
case <-exited:
}
}()
return f(wrappedCtx)
}