diff --git a/cli/commands.go b/cli/commands.go index 1a7916c742..074b80dd11 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -2,6 +2,8 @@ package cli import ( "os" + "os/signal" + "syscall" auditFile "github.com/hashicorp/vault/builtin/audit/file" auditSyslog "github.com/hashicorp/vault/builtin/audit/syslog" @@ -68,6 +70,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { "transit": transit.Factory, "mysql": mysql.Factory, }, + ShutdownCh: makeShutdownCh(), }, nil }, @@ -268,3 +271,20 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, } } + +// 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. +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 +} diff --git a/command/server.go b/command/server.go index 2796b22cda..ed842a26f8 100644 --- a/command/server.go +++ b/command/server.go @@ -32,6 +32,7 @@ type ServerCommand struct { CredentialBackends map[string]logical.Factory LogicalBackends map[string]logical.Factory + ShutdownCh <-chan struct{} Meta } @@ -237,7 +238,14 @@ func (c *ServerCommand) Run(args []string) int { // Release the log gate. logGate.Flush() - <-make(chan struct{}) + // Wait for shutdown + select { + case <-c.ShutdownCh: + c.Ui.Output("==> Vault shutdown triggered") + if err := core.Shutdown(); err != nil { + c.Ui.Error(fmt.Sprintf("Error with core shutdown: %s", err)) + } + } return 0 } @@ -407,8 +415,8 @@ General Options: specified multiple times. If it is a directory, all files with a ".hcl" or ".json" suffix will be loaded. - -dev Enables Dev mode. In this mode, Vault is completely - in-memory and unsealed. Do not run the Dev server in + -dev Enables Dev mode. In this mode, Vault is completely + in-memory and unsealed. Do not run the Dev server in production! -log-level=info Log verbosity. Defaults to "info", will be outputted