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

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/loggo/loggo"
    10  	"launchpad.net/gnuflag"
    11  	"launchpad.net/tomb"
    12  
    13  	"launchpad.net/juju-core/cmd"
    14  	"launchpad.net/juju-core/names"
    15  	"launchpad.net/juju-core/state"
    16  	"launchpad.net/juju-core/worker"
    17  	workerlogger "launchpad.net/juju-core/worker/logger"
    18  	"launchpad.net/juju-core/worker/uniter"
    19  	"launchpad.net/juju-core/worker/upgrader"
    20  )
    21  
    22  var agentLogger = loggo.GetLogger("juju.jujud")
    23  
    24  // UnitAgent is a cmd.Command responsible for running a unit agent.
    25  type UnitAgent struct {
    26  	cmd.CommandBase
    27  	tomb     tomb.Tomb
    28  	Conf     AgentConf
    29  	UnitName string
    30  	runner   worker.Runner
    31  }
    32  
    33  // Info returns usage information for the command.
    34  func (a *UnitAgent) Info() *cmd.Info {
    35  	return &cmd.Info{
    36  		Name:    "unit",
    37  		Purpose: "run a juju unit agent",
    38  	}
    39  }
    40  
    41  func (a *UnitAgent) SetFlags(f *gnuflag.FlagSet) {
    42  	a.Conf.addFlags(f)
    43  	f.StringVar(&a.UnitName, "unit-name", "", "name of the unit to run")
    44  }
    45  
    46  // Init initializes the command for running.
    47  func (a *UnitAgent) Init(args []string) error {
    48  	if a.UnitName == "" {
    49  		return requiredError("unit-name")
    50  	}
    51  	if !names.IsUnit(a.UnitName) {
    52  		return fmt.Errorf(`--unit-name option expects "<service>/<n>" argument`)
    53  	}
    54  	if err := a.Conf.checkArgs(args); err != nil {
    55  		return err
    56  	}
    57  	a.runner = worker.NewRunner(isFatal, moreImportant)
    58  	return nil
    59  }
    60  
    61  // Stop stops the unit agent.
    62  func (a *UnitAgent) Stop() error {
    63  	a.runner.Kill()
    64  	return a.tomb.Wait()
    65  }
    66  
    67  // Run runs a unit agent.
    68  func (a *UnitAgent) Run(ctx *cmd.Context) error {
    69  	defer a.tomb.Done()
    70  	if err := a.Conf.read(a.Tag()); err != nil {
    71  		return err
    72  	}
    73  	agentLogger.Infof("unit agent %v start", a.Tag())
    74  	a.runner.StartWorker("api", a.APIWorkers)
    75  	err := agentDone(a.runner.Wait())
    76  	a.tomb.Kill(err)
    77  	return err
    78  }
    79  
    80  func (a *UnitAgent) APIWorkers() (worker.Worker, error) {
    81  	agentConfig := a.Conf.config
    82  	st, entity, err := openAPIState(agentConfig, a)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	dataDir := a.Conf.dataDir
    87  	runner := worker.NewRunner(connectionIsFatal(st), moreImportant)
    88  	runner.StartWorker("upgrader", func() (worker.Worker, error) {
    89  		return upgrader.NewUpgrader(st.Upgrader(), agentConfig), nil
    90  	})
    91  	runner.StartWorker("logger", func() (worker.Worker, error) {
    92  		return workerlogger.NewLogger(st.Logger(), agentConfig), nil
    93  	})
    94  	runner.StartWorker("uniter", func() (worker.Worker, error) {
    95  		return uniter.NewUniter(st.Uniter(), entity.Tag(), dataDir), nil
    96  	})
    97  	return newCloseWorker(runner, st), nil
    98  }
    99  
   100  func (a *UnitAgent) Entity(st *state.State) (AgentState, error) {
   101  	return st.Unit(a.UnitName)
   102  }
   103  
   104  func (a *UnitAgent) Tag() string {
   105  	return names.UnitTag(a.UnitName)
   106  }