github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/terminationworker/worker.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package terminationworker
     5  
     6  import (
     7  	"os"
     8  	"os/signal"
     9  	"syscall"
    10  
    11  	"launchpad.net/tomb"
    12  
    13  	"github.com/juju/juju/worker"
    14  )
    15  
    16  // TerminationSignal is the signal that
    17  // indicates the agent should terminate
    18  // and uninstall itself.
    19  //
    20  // We do not use SIGTERM as SIGTERM is the
    21  // default signal used to initiate a graceful
    22  // shutdown.
    23  const TerminationSignal = syscall.SIGABRT
    24  
    25  // NewWorker returns a worker that wais for a
    26  
    27  type terminationWorker struct {
    28  	tomb tomb.Tomb
    29  }
    30  
    31  // TerminationSignal signal and exits with
    32  // ErrTerminateAgent.
    33  func NewWorker() worker.Worker {
    34  	u := &terminationWorker{}
    35  	go func() {
    36  		defer u.tomb.Done()
    37  		u.tomb.Kill(u.loop())
    38  	}()
    39  	return u
    40  }
    41  
    42  func (u *terminationWorker) Kill() {
    43  	u.tomb.Kill(nil)
    44  }
    45  
    46  func (u *terminationWorker) Wait() error {
    47  	return u.tomb.Wait()
    48  }
    49  
    50  func (u *terminationWorker) loop() (err error) {
    51  	c := make(chan os.Signal, 1)
    52  	signal.Notify(c, TerminationSignal)
    53  	defer signal.Stop(c)
    54  	select {
    55  	case <-c:
    56  		return worker.ErrTerminateAgent
    57  	case <-u.tomb.Dying():
    58  		return nil
    59  	}
    60  }