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