github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/signal.go (about)

     1  package main
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"os/signal"
     7  	"syscall"
     8  
     9  	"github.com/mitchellh/packer/packer"
    10  	"github.com/mitchellh/packer/packer/plugin"
    11  )
    12  
    13  // Prepares the signal handlers so that we handle interrupts properly.
    14  // The signal handler exists in a goroutine.
    15  func setupSignalHandlers(ui packer.Ui) {
    16  	ch := make(chan os.Signal, 1)
    17  	signal.Notify(ch, os.Interrupt)
    18  	signal.Notify(ch, syscall.SIGTERM)
    19  
    20  	go func() {
    21  		// First interrupt. We mostly ignore this because it allows the
    22  		// plugins time to cleanup.
    23  		<-ch
    24  		log.Println("First interrupt. Ignoring to allow plugins to clean up.")
    25  
    26  		ui.Error("Interrupt signal received. Cleaning up...")
    27  
    28  		// Second interrupt. Go down hard.
    29  		<-ch
    30  		log.Println("Second interrupt. Exiting now.")
    31  
    32  		ui.Error("Interrupt signal received twice. Forcefully exiting now.")
    33  
    34  		// Force kill all the plugins, but mark that we're killing them
    35  		// first so that we don't get panics everywhere.
    36  		plugin.CleanupClients()
    37  		os.Exit(1)
    38  	}()
    39  }