launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/worker/localstorage/worker.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package localstorage
     5  
     6  import (
     7  	"net"
     8  
     9  	"github.com/loggo/loggo"
    10  	"launchpad.net/errgo/errors"
    11  	"launchpad.net/tomb"
    12  
    13  	"launchpad.net/juju-core/agent"
    14  	"launchpad.net/juju-core/environs/filestorage"
    15  	"launchpad.net/juju-core/environs/httpstorage"
    16  	"launchpad.net/juju-core/worker"
    17  )
    18  
    19  var logger = loggo.GetLogger("juju.worker.localstorage")
    20  
    21  var mask = errors.Mask
    22  
    23  type storageWorker struct {
    24  	config agent.Config
    25  	tomb   tomb.Tomb
    26  }
    27  
    28  func NewWorker(config agent.Config) worker.Worker {
    29  	w := &storageWorker{config: config}
    30  	go func() {
    31  		defer w.tomb.Done()
    32  		w.tomb.Kill(w.waitForDeath())
    33  	}()
    34  	return w
    35  }
    36  
    37  // Kill implements worker.Worker.Kill.
    38  func (s *storageWorker) Kill() {
    39  	s.tomb.Kill(nil)
    40  }
    41  
    42  // Wait implements worker.Worker.Wait.
    43  func (s *storageWorker) Wait() error {
    44  	return s.tomb.Wait()
    45  }
    46  
    47  func (s *storageWorker) serveStorage(storageAddr, storageDir string, config *config) (net.Listener, error) {
    48  	authenticated := len(config.caCertPEM) > 0 && len(config.caKeyPEM) > 0
    49  	scheme := "http://"
    50  	if authenticated {
    51  		scheme = "https://"
    52  	}
    53  	logger.Infof("serving storage from %s to %s%s", storageDir, scheme, storageAddr)
    54  	storage, err := filestorage.NewFileStorageWriter(storageDir, filestorage.UseDefaultTmpDir)
    55  	if err != nil {
    56  		return nil, mask(err)
    57  	}
    58  	if authenticated {
    59  		return httpstorage.ServeTLS(
    60  			storageAddr,
    61  			storage,
    62  			config.caCertPEM,
    63  			config.caKeyPEM,
    64  			config.hostnames,
    65  			config.authkey,
    66  		)
    67  	}
    68  	return httpstorage.Serve(storageAddr, storage)
    69  }
    70  
    71  func (s *storageWorker) waitForDeath() error {
    72  	config, err := loadConfig(s.config)
    73  	if err != nil {
    74  		logger.Errorf("error loading config: %v", err)
    75  		return err
    76  	}
    77  
    78  	storageListener, err := s.serveStorage(config.storageAddr, config.storageDir, config)
    79  	if err != nil {
    80  		logger.Errorf("error with local storage: %v", err)
    81  		return err
    82  	}
    83  	defer storageListener.Close()
    84  
    85  	logger.Infof("storage routines started, awaiting death")
    86  
    87  	<-s.tomb.Dying()
    88  
    89  	logger.Infof("dying, closing storage listeners")
    90  	return tomb.ErrDying
    91  }