github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/jujud/agent/agent.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  /*
     5  agent contains jujud's machine agent.
     6  */
     7  package agent
     8  
     9  import (
    10  	"sync"
    11  
    12  	"github.com/juju/cmd"
    13  	"github.com/juju/errors"
    14  	"github.com/juju/gnuflag"
    15  	"gopkg.in/juju/names.v2"
    16  
    17  	"github.com/juju/juju/agent"
    18  	"github.com/juju/juju/cmd/jujud/util"
    19  )
    20  
    21  // AgentConf is a terribly confused interface.
    22  //
    23  // Parts of it are a mixin for cmd.Command implementations; others are a mixin
    24  // for agent.Agent implementations; others bridge the two. We should be aiming
    25  // to separate the cmd responsibilities from the agent responsibilities.
    26  type AgentConf interface {
    27  
    28  	// AddFlags injects common agent flags into f.
    29  	AddFlags(f *gnuflag.FlagSet)
    30  
    31  	// CheckArgs reports whether the given args are valid for this agent.
    32  	CheckArgs(args []string) error
    33  
    34  	// DataDir returns the directory where this agent should store its data.
    35  	DataDir() string
    36  
    37  	// ReadConfig reads the agent's config from its config file.
    38  	ReadConfig(tag string) error
    39  
    40  	// CurrentConfig returns the agent config for this agent.
    41  	CurrentConfig() agent.Config
    42  
    43  	// ChangeConfig modifies this configuration using the given mutator.
    44  	ChangeConfig(change agent.ConfigMutator) error
    45  }
    46  
    47  // NewAgentConf returns a new value that satisfies AgentConf
    48  func NewAgentConf(dataDir string) AgentConf {
    49  	return &agentConf{dataDir: dataDir}
    50  }
    51  
    52  // agentConf handles command-line flags shared by all agents.
    53  type agentConf struct {
    54  	dataDir string
    55  	mu      sync.Mutex
    56  	_config agent.ConfigSetterWriter
    57  }
    58  
    59  // AddFlags injects common agent flags into f.
    60  func (c *agentConf) AddFlags(f *gnuflag.FlagSet) {
    61  	// TODO(dimitern) 2014-02-19 bug 1282025
    62  	// We need to pass a config location here instead and
    63  	// use it to locate the conf and the infer the data-dir
    64  	// from there instead of passing it like that.
    65  	f.StringVar(&c.dataDir, "data-dir", util.DataDir, "directory for juju data")
    66  }
    67  
    68  // CheckArgs reports whether the given args are valid for this agent.
    69  func (c *agentConf) CheckArgs(args []string) error {
    70  	if c.dataDir == "" {
    71  		return util.RequiredError("data-dir")
    72  	}
    73  	return cmd.CheckEmpty(args)
    74  }
    75  
    76  // DataDir returns the directory where this agent should store its data.
    77  func (c *agentConf) DataDir() string {
    78  	return c.dataDir
    79  }
    80  
    81  // ReadConfig reads the agent's config from its config file.
    82  func (c *agentConf) ReadConfig(tag string) error {
    83  	t, err := names.ParseTag(tag)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	c.mu.Lock()
    88  	defer c.mu.Unlock()
    89  	conf, err := agent.ReadConfig(agent.ConfigPath(c.dataDir, t))
    90  	if err != nil {
    91  		return err
    92  	}
    93  	c._config = conf
    94  	return nil
    95  }
    96  
    97  // ChangeConfig modifies this configuration using the given mutator.
    98  func (ch *agentConf) ChangeConfig(change agent.ConfigMutator) error {
    99  	ch.mu.Lock()
   100  	defer ch.mu.Unlock()
   101  	if err := change(ch._config); err != nil {
   102  		return errors.Trace(err)
   103  	}
   104  	if err := ch._config.Write(); err != nil {
   105  		return errors.Annotate(err, "cannot write agent configuration")
   106  	}
   107  	return nil
   108  }
   109  
   110  // CurrentConfig returns the agent config for this agent.
   111  func (ch *agentConf) CurrentConfig() agent.Config {
   112  	ch.mu.Lock()
   113  	defer ch.mu.Unlock()
   114  	return ch._config.Clone()
   115  }