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:
@@ -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
|
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.
|
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
|
##Examples
|
||||||
For example configurations, please consult the [examples/](https://github.com/purpleidea/mgmt/tree/master/examples) directory in the git
|
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:
|
source repository. It is available from:
|
||||||
|
|||||||
17
config.go
17
config.go
@@ -85,7 +85,7 @@ func ParseConfigFromFile(filename string) *GraphConfig {
|
|||||||
|
|
||||||
// NewGraphFromConfig returns a new graph from existing input, such as from the
|
// NewGraphFromConfig returns a new graph from existing input, such as from the
|
||||||
// existing graph, and a GraphConfig struct.
|
// 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
|
var graph *Graph // new graph to return
|
||||||
if g == nil { // FIXME: how can we check for an empty graph?
|
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 {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Error: Config: Can't convert: %v of type: %T to Res.", x, x)
|
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 {
|
if _, exists := lookup[kind]; !exists {
|
||||||
lookup[kind] = make(map[string]*Vertex)
|
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
|
lookup[kind][obj.GetName()] = v // used for constructing edges
|
||||||
keep = append(keep, v) // append
|
keep = append(keep, v) // append
|
||||||
|
|
||||||
} else {
|
} else if !noop { // do not export any resources if noop
|
||||||
// XXX: do this in a different function...
|
// XXX: do this in a different function...
|
||||||
// add to etcd storage...
|
// add to etcd storage...
|
||||||
obj.SetName(obj.GetName()[2:]) //slice off @@
|
obj.SetName(obj.GetName()[2:]) //slice off @@
|
||||||
@@ -177,6 +179,11 @@ func (g *Graph) NewGraphFromConfig(config *GraphConfig, etcdO *EtcdWObject, host
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collect resources but add the noop metaparam
|
||||||
|
if noop {
|
||||||
|
obj.Meta().Noop = noop
|
||||||
|
}
|
||||||
|
|
||||||
if t.Pattern != "" { // XXX: simplistic for now
|
if t.Pattern != "" { // XXX: simplistic for now
|
||||||
obj.CollectPattern(t.Pattern) // obj.Dirname = t.Pattern
|
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() {
|
func (g *Graph) AutoEdges() {
|
||||||
log.Println("Compile: Adding AutoEdges...")
|
log.Println("Compile: Adding AutoEdges...")
|
||||||
for _, v := range g.GetVertices() { // for each vertexes 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
|
continue
|
||||||
}
|
}
|
||||||
autoEdgeObj := v.AutoEdges()
|
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!")
|
return fmt.Errorf("The two resources aren't the same kind!")
|
||||||
}
|
}
|
||||||
// someone doesn't want to group!
|
// 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!")
|
return fmt.Errorf("One of the autogroup flags is false!")
|
||||||
}
|
}
|
||||||
if v1.Res.IsGrouped() { // already grouped!
|
if v1.Res.IsGrouped() { // already grouped!
|
||||||
|
|||||||
4
exec.go
4
exec.go
@@ -391,6 +391,10 @@ func (obj *ExecRes) Compare(res Res) bool {
|
|||||||
switch res.(type) {
|
switch res.(type) {
|
||||||
case *ExecRes:
|
case *ExecRes:
|
||||||
res := res.(*ExecRes)
|
res := res.(*ExecRes)
|
||||||
|
if !obj.BaseRes.Compare(res) { // call base Compare
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Name != res.Name {
|
if obj.Name != res.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
4
file.go
4
file.go
@@ -478,6 +478,10 @@ func (obj *FileRes) Compare(res Res) bool {
|
|||||||
switch res.(type) {
|
switch res.(type) {
|
||||||
case *FileRes:
|
case *FileRes:
|
||||||
res := res.(*FileRes)
|
res := res.(*FileRes)
|
||||||
|
if !obj.BaseRes.Compare(res) { // call base Compare
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Name != res.Name {
|
if obj.Name != res.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
7
main.go
7
main.go
@@ -103,6 +103,7 @@ func run(c *cli.Context) error {
|
|||||||
if hostname == "" {
|
if hostname == "" {
|
||||||
hostname, _ = os.Hostname() // etcd watch key // XXX: this is not the correct key name this is the set key name... WOOPS
|
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
|
exitchan := make(chan Event) // exit event
|
||||||
go func() {
|
go func() {
|
||||||
@@ -157,7 +158,7 @@ func run(c *cli.Context) error {
|
|||||||
|
|
||||||
// build graph from yaml file on events (eg: from etcd)
|
// build graph from yaml file on events (eg: from etcd)
|
||||||
// we need the vertices to be paused to work on them
|
// 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
|
fullGraph = newFullgraph
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Config: Error making new graph from config: %v", err)
|
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",
|
Usage: "exit after a maximum of approximately this many seconds",
|
||||||
EnvVar: "MGMT_MAX_RUNTIME",
|
EnvVar: "MGMT_MAX_RUNTIME",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "noop",
|
||||||
|
Usage: "globally force all resources into no-op mode",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
4
noop.go
4
noop.go
@@ -133,6 +133,10 @@ func (obj *NoopRes) Compare(res Res) bool {
|
|||||||
// we can only compare NoopRes to others of the same resource
|
// we can only compare NoopRes to others of the same resource
|
||||||
case *NoopRes:
|
case *NoopRes:
|
||||||
res := res.(*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 {
|
if obj.Name != res.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -729,7 +729,7 @@ func (g *Graph) Process(v *Vertex) {
|
|||||||
|
|
||||||
obj.SetState(resStateCheckApply)
|
obj.SetState(resStateCheckApply)
|
||||||
// if this fails, don't UpdateTimestamp()
|
// 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
|
if checkok && err != nil { // should never return this way
|
||||||
log.Fatalf("%v[%v]: CheckApply(): %t, %+v", obj.Kind(), obj.GetName(), checkok, err)
|
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
|
// when noop is true we always want to update timestamp
|
||||||
if obj.GetMeta().Noop && err == nil {
|
if obj.Meta().Noop && err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -638,7 +638,7 @@ func NewNoopResTest(name string) *NoopResTest {
|
|||||||
NoopRes: NoopRes{
|
NoopRes: NoopRes{
|
||||||
BaseRes: BaseRes{
|
BaseRes: BaseRes{
|
||||||
Name: name,
|
Name: name,
|
||||||
Meta: MetaParams{
|
MetaParams: MetaParams{
|
||||||
AutoGroup: true, // always autogroup
|
AutoGroup: true, // always autogroup
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
4
pkg.go
4
pkg.go
@@ -507,6 +507,10 @@ func (obj *PkgRes) Compare(res Res) bool {
|
|||||||
switch res.(type) {
|
switch res.(type) {
|
||||||
case *PkgRes:
|
case *PkgRes:
|
||||||
res := res.(*PkgRes)
|
res := res.(*PkgRes)
|
||||||
|
if !obj.BaseRes.Compare(res) { // call base Compare
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Name != res.Name {
|
if obj.Name != res.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
39
resources.go
39
resources.go
@@ -69,7 +69,7 @@ type Base interface {
|
|||||||
GetName() string // can't be named "Name()" because of struct field
|
GetName() string // can't be named "Name()" because of struct field
|
||||||
SetName(string)
|
SetName(string)
|
||||||
Kind() string
|
Kind() string
|
||||||
GetMeta() MetaParams
|
Meta() *MetaParams
|
||||||
AssociateData(Converger)
|
AssociateData(Converger)
|
||||||
IsWatching() bool
|
IsWatching() bool
|
||||||
SetWatching(bool)
|
SetWatching(bool)
|
||||||
@@ -99,16 +99,16 @@ type Res interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BaseRes struct {
|
type BaseRes struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Meta MetaParams `yaml:"meta"` // struct of all the metaparams
|
MetaParams MetaParams `yaml:"meta"` // struct of all the metaparams
|
||||||
kind string
|
kind string
|
||||||
events chan Event
|
events chan Event
|
||||||
converger Converger // converged tracking
|
converger Converger // converged tracking
|
||||||
state resState
|
state resState
|
||||||
watching bool // is Watch() loop running ?
|
watching bool // is Watch() loop running ?
|
||||||
isStateOK bool // whether the state is okay based on events or not
|
isStateOK bool // whether the state is okay based on events or not
|
||||||
isGrouped bool // am i contained within a group?
|
isGrouped bool // am i contained within a group?
|
||||||
grouped []Res // list of any grouped resources
|
grouped []Res // list of any grouped resources
|
||||||
}
|
}
|
||||||
|
|
||||||
// wraps the IFF method when used with a list of UUID's
|
// wraps the IFF method when used with a list of UUID's
|
||||||
@@ -167,8 +167,8 @@ func (obj *BaseRes) Kind() string {
|
|||||||
return obj.kind
|
return obj.kind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *BaseRes) GetMeta() MetaParams {
|
func (obj *BaseRes) Meta() *MetaParams {
|
||||||
return obj.Meta
|
return &obj.MetaParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssociateData associates some data with the object in question
|
// AssociateData associates some data with the object in question
|
||||||
@@ -292,6 +292,19 @@ func (obj *BaseRes) SetGroup(g []Res) {
|
|||||||
obj.grouped = g
|
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) {
|
func (obj *BaseRes) CollectPattern(pattern string) {
|
||||||
// XXX: default method is empty
|
// XXX: default method is empty
|
||||||
}
|
}
|
||||||
|
|||||||
4
svc.go
4
svc.go
@@ -424,6 +424,10 @@ func (obj *SvcRes) Compare(res Res) bool {
|
|||||||
switch res.(type) {
|
switch res.(type) {
|
||||||
case *SvcRes:
|
case *SvcRes:
|
||||||
res := res.(*SvcRes)
|
res := res.(*SvcRes)
|
||||||
|
if !obj.BaseRes.Compare(res) { // call base Compare
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Name != res.Name {
|
if obj.Name != res.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user