diff --git a/packer.go b/packer.go index 273cca2c5..6ecc42ee1 100644 --- a/packer.go +++ b/packer.go @@ -96,6 +96,8 @@ func main() { os.Exit(1) } + setupSignalHandlers(env) + exitCode, err := env.Cli(os.Args[1:]) if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) diff --git a/signal.go b/signal.go new file mode 100644 index 000000000..22590628b --- /dev/null +++ b/signal.go @@ -0,0 +1,29 @@ +package main + +import ( + "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/packer/plugin" + "log" + "os" + "os/signal" +) + +// Prepares the signal handlers so that we handle interrupts properly. +// The signal handler exists in a goroutine. +func setupSignalHandlers(env packer.Environment) { + ch := make(chan os.Signal, 1) + signal.Notify(ch, os.Interrupt) + + go func() { + <-ch + log.Println("First interrupt. Ignoring, will let plugins handle...") + <-ch + log.Println("Second interrupt. Exiting now.") + + env.Ui().Error("Interrupt signal received twice. Forcefully exiting now.") + + // Force kill all the plugins + plugin.CleanupClients() + os.Exit(1) + }() +}