Add global --noop support

This is part two of the earlier patch in
6bbce039aa

We also rename GetMeta to just Meta to clean up the API.
This commit is contained in:
James Shubin
2016-05-14 12:03:32 -04:00
parent 12ea860eba
commit 9f56e4a582
11 changed files with 72 additions and 22 deletions

View File

@@ -179,6 +179,11 @@ Exit if the machine has converged for approximately this many seconds.
Exit when the agent has run for approximately this many seconds. This is not
generally recommended, but may be useful for users who know what they're doing.
####`--noop`
Globally force all resources into no-op mode. This also disables the export to
etcd functionality, but does not disable resource collection, however all
resources that are collected will have their individual noop settings set.
##Examples
For example configurations, please consult the [examples/](https://github.com/purpleidea/mgmt/tree/master/examples) directory in the git
source repository. It is available from:

View File

@@ -85,7 +85,7 @@ func ParseConfigFromFile(filename string) *GraphConfig {
// NewGraphFromConfig returns a new graph from existing input, such as from the
// existing graph, and a GraphConfig struct.
func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, hostname string) (*Graph, error) {
func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, hostname string, noop bool) (*Graph, error) {
var graph *Graph // new graph to return
if g == nil { // FIXME: how can we check for an empty graph?
@@ -122,7 +122,9 @@ func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, host
if !ok {
return nil, fmt.Errorf("Error: Config: Can't convert: %v of type: %T to Res.", x, x)
}
if noop {
obj.Meta().Noop = noop
}
if _, exists := lookup[kind]; !exists {
lookup[kind] = make(map[string]*Vertex)
}
@@ -141,7 +143,7 @@ func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, host
lookup[kind][obj.GetName()] = v // used for constructing edges
keep = append(keep, v) // append
} else {
} else if !noop { // do not export any resources if noop
// XXX: do this in a different function...
// add to etcd storage...
obj.SetName(obj.GetName()[2:]) //slice off @@
@@ -177,6 +179,11 @@ func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, host
continue
}
// collect resources but add the noop metaparam
if noop {
obj.Meta().Noop = noop
}
if t.Pattern != "" { // XXX: simplistic for now
obj.CollectPattern(t.Pattern) // obj.Dirname = t.Pattern
}
@@ -271,7 +278,7 @@ func (g *Graph) addEdgesByMatchingUUIDS(v *Vertex, uuids []ResUUID) []bool {
func (g *Graph) AutoEdges() {
log.Println("Compile: Adding AutoEdges...")
for _, v := range g.GetVertices() { // for each vertexes autoedges
if !v.GetMeta().AutoEdge { // is the metaparam true?
if !v.Meta().AutoEdge { // is the metaparam true?
continue
}
autoEdgeObj := v.AutoEdges()
@@ -398,7 +405,7 @@ func (ag *baseGrouper) vertexCmp(v1, v2 *Vertex) error {
return fmt.Errorf("The two resources aren't the same kind!")
}
// someone doesn't want to group!
if !v1.GetMeta().AutoGroup || !v2.GetMeta().AutoGroup {
if !v1.Meta().AutoGroup || !v2.Meta().AutoGroup {
return fmt.Errorf("One of the autogroup flags is false!")
}
if v1.Res.IsGrouped() { // already grouped!

View File

@@ -391,6 +391,10 @@ func (obj *ExecRes) Compare(res Res) bool {
switch res.(type) {
case *ExecRes:
res := res.(*ExecRes)
if !obj.BaseRes.Compare(res) { // call base Compare
return false
}
if obj.Name != res.Name {
return false
}

View File

@@ -478,6 +478,10 @@ func (obj *FileRes) Compare(res Res) bool {
switch res.(type) {
case *FileRes:
res := res.(*FileRes)
if !obj.BaseRes.Compare(res) { // call base Compare
return false
}
if obj.Name != res.Name {
return false
}

View File

@@ -103,6 +103,7 @@ func run(c *cli.Context) error {
if hostname == "" {
hostname, _ = os.Hostname() // etcd watch key // XXX: this is not the correct key name this is the set key name... WOOPS
}
noop := c.Bool("noop")
exitchan := make(chan Event) // exit event
go func() {
@@ -157,7 +158,7 @@ func run(c *cli.Context) error {
// build graph from yaml file on events (eg: from etcd)
// we need the vertices to be paused to work on them
if newFullgraph, err := fullGraph.NewGraphFromConfig(config, etcdO, hostname); err == nil { // keep references to all original elements
if newFullgraph, err := fullGraph.NewGraphFromConfig(config, etcdO, hostname, noop); err == nil { // keep references to all original elements
fullGraph = newFullgraph
} else {
log.Printf("Config: Error making new graph from config: %v", err)
@@ -295,6 +296,10 @@ func main() {
Usage: "exit after a maximum of approximately this many seconds",
EnvVar: "MGMT_MAX_RUNTIME",
},
cli.BoolFlag{
Name: "noop",
Usage: "globally force all resources into no-op mode",
},
},
},
}

View File

@@ -133,6 +133,10 @@ func (obj *NoopRes) Compare(res Res) bool {
// we can only compare NoopRes to others of the same resource
case *NoopRes:
res := res.(*NoopRes)
// calling base Compare is unneeded for the noop res
//if !obj.BaseRes.Compare(res) { // call base Compare
// return false
//}
if obj.Name != res.Name {
return false
}

View File

@@ -729,7 +729,7 @@ func (g *Graph) Process(v *Vertex) {
obj.SetState(resStateCheckApply)
// if this fails, don't UpdateTimestamp()
checkok, err := obj.CheckApply(!obj.GetMeta().Noop)
checkok, err := obj.CheckApply(!obj.Meta().Noop)
if checkok && err != nil { // should never return this way
log.Fatalf("%v[%v]: CheckApply(): %t, %+v", obj.Kind(), obj.GetName(), checkok, err)
}
@@ -746,7 +746,7 @@ func (g *Graph) Process(v *Vertex) {
}
// when noop is true we always want to update timestamp
if obj.GetMeta().Noop && err == nil {
if obj.Meta().Noop && err == nil {
ok = true
}

View File

@@ -638,7 +638,7 @@ func NewNoopResTest(name string) *NoopResTest {
NoopRes: NoopRes{
BaseRes: BaseRes{
Name: name,
Meta: MetaParams{
MetaParams: MetaParams{
AutoGroup: true, // always autogroup
},
},

4
pkg.go
View File

@@ -507,6 +507,10 @@ func (obj *PkgRes) Compare(res Res) bool {
switch res.(type) {
case *PkgRes:
res := res.(*PkgRes)
if !obj.BaseRes.Compare(res) { // call base Compare
return false
}
if obj.Name != res.Name {
return false
}

View File

@@ -69,7 +69,7 @@ type Base interface {
GetName() string // can't be named "Name()" because of struct field
SetName(string)
Kind() string
GetMeta() MetaParams
Meta() *MetaParams
AssociateData(Converger)
IsWatching() bool
SetWatching(bool)
@@ -100,7 +100,7 @@ type Res interface {
type BaseRes struct {
Name string `yaml:"name"`
Meta MetaParams `yaml:"meta"` // struct of all the metaparams
MetaParams MetaParams `yaml:"meta"` // struct of all the metaparams
kind string
events chan Event
converger Converger // converged tracking
@@ -167,8 +167,8 @@ func (obj *BaseRes) Kind() string {
return obj.kind
}
func (obj *BaseRes) GetMeta() MetaParams {
return obj.Meta
func (obj *BaseRes) Meta() *MetaParams {
return &obj.MetaParams
}
// AssociateData associates some data with the object in question
@@ -292,6 +292,19 @@ func (obj *BaseRes) SetGroup(g []Res) {
obj.grouped = g
}
// Compare is the base compare method, which also handles the metaparams cmp
func (obj *BaseRes) Compare(res Res) bool {
if obj.Meta().Noop != res.Meta().Noop {
// obj is the existing res, res is the *new* resource
// if we go from no-noop -> noop, we can re-use the obj
// if we go from noop -> no-noop, we need to regenerate
if obj.Meta().Noop { // asymmetrical
return false // going from noop to no-noop!
}
}
return true
}
func (obj *BaseRes) CollectPattern(pattern string) {
// XXX: default method is empty
}

4
svc.go
View File

@@ -424,6 +424,10 @@ func (obj *SvcRes) Compare(res Res) bool {
switch res.(type) {
case *SvcRes:
res := res.(*SvcRes)
if !obj.BaseRes.Compare(res) { // call base Compare
return false
}
if obj.Name != res.Name {
return false
}