064c43ee69
Some previous changes broke interrupting the debug on SigInterupt. This change restores the original behaviour by passing a context to requests. Since a new API client function was required to pass the context, I had it also return an io.ReadCloser, so that output can be streamed to files instead of fully buffering in process memory.
64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
mcli "github.com/mitchellh/cli"
|
|
|
|
"github.com/hashicorp/consul/command/cli"
|
|
)
|
|
|
|
// Factory is a function that returns a new instance of a CLI-sub command.
|
|
type Factory func(cli.Ui) (cli.Command, error)
|
|
|
|
// Register adds a new CLI sub-command to the registry.
|
|
func Register(name string, fn Factory) {
|
|
if registry == nil {
|
|
registry = make(map[string]Factory)
|
|
}
|
|
|
|
if registry[name] != nil {
|
|
panic(fmt.Errorf("Command %q is already registered", name))
|
|
}
|
|
registry[name] = fn
|
|
}
|
|
|
|
// CommandsFromRegistry returns a realized mapping of available CLI commands in a format that
|
|
// the CLI class can consume. This should be called after all registration is
|
|
// complete.
|
|
func CommandsFromRegistry(ui cli.Ui) map[string]mcli.CommandFactory {
|
|
m := make(map[string]mcli.CommandFactory)
|
|
for name, fn := range registry {
|
|
thisFn := fn
|
|
m[name] = func() (mcli.Command, error) {
|
|
return thisFn(ui)
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
// registry has an entry for each available CLI sub-command, indexed by sub
|
|
// command name. This should be populated at package init() time via Register().
|
|
var registry map[string]Factory
|
|
|
|
// MakeShutdownCh returns a channel that can be used for shutdown notifications
|
|
// for commands. This channel will send a message for every interrupt or SIGTERM
|
|
// received.
|
|
// Deprecated: use signal.NotifyContext
|
|
func MakeShutdownCh() <-chan struct{} {
|
|
resultCh := make(chan struct{})
|
|
signalCh := make(chan os.Signal, 4)
|
|
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
|
|
go func() {
|
|
for {
|
|
<-signalCh
|
|
resultCh <- struct{}{}
|
|
}
|
|
}()
|
|
|
|
return resultCh
|
|
}
|