github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/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  	"runtime"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/loggo"
    12  	"github.com/juju/names"
    13  	"launchpad.net/gnuflag"
    14  	"launchpad.net/tomb"
    15  
    16  	"github.com/juju/juju/version"
    17  	"github.com/juju/juju/worker"
    18  	"github.com/juju/juju/worker/apiaddressupdater"
    19  	workerlogger "github.com/juju/juju/worker/logger"
    20  	"github.com/juju/juju/worker/rsyslog"
    21  	"github.com/juju/juju/worker/uniter"
    22  	"github.com/juju/juju/worker/upgrader"
    23  )
    24  
    25  var agentLogger = loggo.GetLogger("juju.jujud")
    26  
    27  // UnitAgent is a cmd.Command responsible for running a unit agent.
    28  type UnitAgent struct {
    29  	cmd.CommandBase
    30  	tomb tomb.Tomb
    31  	AgentConf
    32  	UnitName string
    33  	runner   worker.Runner
    34  }
    35  
    36  // Info returns usage information for the command.
    37  func (a *UnitAgent) Info() *cmd.Info {
    38  	return &cmd.Info{
    39  		Name:    "unit",
    40  		Purpose: "run a juju unit agent",
    41  	}
    42  }
    43  
    44  func (a *UnitAgent) SetFlags(f *gnuflag.FlagSet) {
    45  	a.AgentConf.AddFlags(f)
    46  	f.StringVar(&a.UnitName, "unit-name", "", "name of the unit to run")
    47  }
    48  
    49  // Init initializes the command for running.
    50  func (a *UnitAgent) Init(args []string) error {
    51  	if a.UnitName == "" {
    52  		return requiredError("unit-name")
    53  	}
    54  	if !names.IsUnit(a.UnitName) {
    55  		return fmt.Errorf(`--unit-name option expects "<service>/<n>" argument`)
    56  	}
    57  	if err := a.AgentConf.CheckArgs(args); err != nil {
    58  		return err
    59  	}
    60  	a.runner = worker.NewRunner(isFatal, moreImportant)
    61  	return nil
    62  }
    63  
    64  // Stop stops the unit agent.
    65  func (a *UnitAgent) Stop() error {
    66  	a.runner.Kill()
    67  	return a.tomb.Wait()
    68  }
    69  
    70  // Run runs a unit agent.
    71  func (a *UnitAgent) Run(ctx *cmd.Context) error {
    72  	defer a.tomb.Done()
    73  	if err := a.ReadConfig(a.Tag()); err != nil {
    74  		return err
    75  	}
    76  	agentLogger.Infof("unit agent %v start (%s [%s])", a.Tag(), version.Current, runtime.Compiler)
    77  	a.runner.StartWorker("api", a.APIWorkers)
    78  	err := agentDone(a.runner.Wait())
    79  	a.tomb.Kill(err)
    80  	return err
    81  }
    82  
    83  func (a *UnitAgent) APIWorkers() (worker.Worker, error) {
    84  	agentConfig := a.CurrentConfig()
    85  	dataDir := agentConfig.DataDir()
    86  	hookLock, err := hookExecutionLock(dataDir)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  	st, entity, err := openAPIState(agentConfig, a)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	runner := worker.NewRunner(connectionIsFatal(st), moreImportant)
    95  	runner.StartWorker("upgrader", func() (worker.Worker, error) {
    96  		return upgrader.NewUpgrader(st.Upgrader(), agentConfig), nil
    97  	})
    98  	runner.StartWorker("logger", func() (worker.Worker, error) {
    99  		return workerlogger.NewLogger(st.Logger(), agentConfig), nil
   100  	})
   101  	runner.StartWorker("uniter", func() (worker.Worker, error) {
   102  		return uniter.NewUniter(st.Uniter(), entity.Tag(), dataDir, hookLock), nil
   103  	})
   104  	runner.StartWorker("apiaddressupdater", func() (worker.Worker, error) {
   105  		return apiaddressupdater.NewAPIAddressUpdater(st.Uniter(), a), nil
   106  	})
   107  	runner.StartWorker("rsyslog", func() (worker.Worker, error) {
   108  		return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslog.RsyslogModeForwarding)
   109  	})
   110  	return newCloseWorker(runner, st), nil
   111  }
   112  
   113  func (a *UnitAgent) Tag() string {
   114  	return names.NewUnitTag(a.UnitName).String()
   115  }