diff --git a/lib/main.go b/lib/main.go index b8cbc35a..6a2b11cd 100644 --- a/lib/main.go +++ b/lib/main.go @@ -442,7 +442,7 @@ func (obj *Main) Run() error { } continue } - newGraph.Flags = pgraph.Flags{Debug: obj.Flags.Debug} + newGraph.SetValue("debug", obj.Flags.Debug) // pass in the information we need newGraph.AssociateData(&resources.Data{ Hostname: hostname, diff --git a/pgraph/actions.go b/pgraph/actions.go index 17f8e87e..9dfaeee6 100644 --- a/pgraph/actions.go +++ b/pgraph/actions.go @@ -28,6 +28,7 @@ import ( "github.com/purpleidea/mgmt/event" "github.com/purpleidea/mgmt/prometheus" "github.com/purpleidea/mgmt/resources" + "github.com/purpleidea/mgmt/util" multierr "github.com/hashicorp/go-multierror" errwrap "github.com/pkg/errors" @@ -54,7 +55,7 @@ func (g *Graph) OKTimestamp(v *Vertex) bool { // if they're equal (eg: on init of 0) then we also can't run // b/c we should let our pre-req's go first... x, y := v.GetTimestamp(), n.GetTimestamp() - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: OKTimestamp: (%v) >= %s[%s](%v): !%v", v.GetKind(), v.GetName(), x, n.GetKind(), n.GetName(), y, x >= y) } if x >= y { @@ -81,7 +82,7 @@ func (g *Graph) Poke(v *Vertex) error { // needs to be poked if already running, or not running though! // TODO: does this need an || activity flag? if n.Res.GetState() != resources.ResStateProcess { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Poke: %s[%s]", v.GetKind(), v.GetName(), n.GetKind(), n.GetName()) } wg.Add(1) @@ -93,7 +94,7 @@ func (g *Graph) Poke(v *Vertex) error { }(n) } else { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Poke: %s[%s]: Skipped!", v.GetKind(), v.GetName(), n.GetKind(), n.GetName()) } } @@ -116,7 +117,7 @@ func (g *Graph) BackPoke(v *Vertex) { // TODO: implement a stateLT (less than) to tell if something // happens earlier in the state cycle and that doesn't wrap nil if x >= y && (s != resources.ResStateProcess && s != resources.ResStateCheckApply) { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: BackPoke: %s[%s]", v.GetKind(), v.GetName(), n.GetKind(), n.GetName()) } wg.Add(1) @@ -126,7 +127,7 @@ func (g *Graph) BackPoke(v *Vertex) { }(n) } else { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: BackPoke: %s[%s]: Skipped!", v.GetKind(), v.GetName(), n.GetKind(), n.GetName()) } } @@ -171,7 +172,7 @@ func (g *Graph) SetDownstreamRefresh(v *Vertex, b bool) { // Process is the primary function to execute for a particular vertex in the graph. func (g *Graph) Process(v *Vertex) error { obj := v.Res - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Process()", obj.GetKind(), obj.GetName()) } // FIXME: should these SetState methods be here or after the sema code? @@ -186,7 +187,7 @@ func (g *Graph) Process(v *Vertex) error { return nil } // timestamp must be okay... - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: OKTimestamp(%v)", obj.GetKind(), obj.GetName(), v.GetTimestamp()) } @@ -198,7 +199,7 @@ func (g *Graph) Process(v *Vertex) error { // The exception is that semaphores with a zero count will always block! // TODO: Add a close mechanism to close/unblock zero count semaphores... semas := obj.Meta().Sema - if g.Flags.Debug && len(semas) > 0 { + if b, ok := g.Value("debug"); ok && util.Bool(b) && len(semas) > 0 { log.Printf("%s[%s]: Sema: P(%s)", obj.GetKind(), obj.GetName(), strings.Join(semas, ", ")) } if err := g.SemaLock(semas); err != nil { // lock @@ -206,7 +207,7 @@ func (g *Graph) Process(v *Vertex) error { return fmt.Errorf("shutdown of semaphores") } defer g.SemaUnlock(semas) // unlock - if g.Flags.Debug && len(semas) > 0 { + if b, ok := g.Value("debug"); ok && util.Bool(b) && len(semas) > 0 { defer log.Printf("%s[%s]: Sema: V(%s)", obj.GetKind(), obj.GetName(), strings.Join(semas, ", ")) } @@ -230,7 +231,7 @@ func (g *Graph) Process(v *Vertex) error { var checkOK bool var err error - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: CheckApply(%t)", obj.GetKind(), obj.GetName(), !noop) } @@ -267,7 +268,7 @@ func (g *Graph) Process(v *Vertex) error { if !checkOK { // something changed, restart timer cuid, _, _ := v.Res.ConvergerUIDs() // get the converger uid used to report status cuid.ResetTimer() // activity! - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Converger: ResetTimer", obj.GetKind(), obj.GetName()) } } @@ -277,7 +278,7 @@ func (g *Graph) Process(v *Vertex) error { if checkOK && err != nil { // should never return this way log.Fatalf("%s[%s]: CheckApply(): %t, %+v", obj.GetKind(), obj.GetName(), checkOK, err) } - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: CheckApply(): %t, %v", obj.GetKind(), obj.GetName(), checkOK, err) } @@ -371,7 +372,7 @@ Loop: // if process started, but no action yet, skip! if v.Res.GetState() == resources.ResStateProcess { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Skipped event!", v.GetKind(), v.GetName()) } ev.ACK() // ready for next message @@ -382,7 +383,7 @@ Loop: // if running, we skip running a new execution! // if waiting, we skip running a new execution! if running || waiting { - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Playback added!", v.GetKind(), v.GetName()) } playback = true @@ -477,7 +478,7 @@ Loop: if v.Res.Meta().Poll == 0 { // skip for polling wcuid.SetConverged(false) } - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: CheckApply finished!", v.GetKind(), v.GetName()) } done = make(chan struct{}) // reset @@ -520,7 +521,7 @@ func (g *Graph) Worker(v *Vertex) error { // the Watch() function about which graph it is // running on, which isolates things nicely... obj := v.Res - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("%s[%s]: Worker: Running", v.GetKind(), v.GetName()) defer log.Printf("%s[%s]: Worker: Stopped", v.GetKind(), v.GetName()) } diff --git a/pgraph/autoedge.go b/pgraph/autoedge.go index 24b6d165..18dddf42 100644 --- a/pgraph/autoedge.go +++ b/pgraph/autoedge.go @@ -23,6 +23,7 @@ import ( "log" "github.com/purpleidea/mgmt/resources" + "github.com/purpleidea/mgmt/util" ) // add edges to the vertex in a graph based on if it matches a uid list @@ -38,7 +39,7 @@ func (g *Graph) addEdgesByMatchingUIDS(v *Vertex, uids []resources.ResUID) []boo if v == vv { // skip self continue } - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Printf("Compile: AutoEdge: Match: %s[%s] with UID: %s[%s]", vv.GetKind(), vv.GetName(), uid.GetKind(), uid.GetName()) } // we must match to an effective UID for the resource, @@ -84,7 +85,7 @@ func (g *Graph) AutoEdges() { log.Printf("%s[%s]: Config: The auto edge list is empty!", v.GetKind(), v.GetName()) break // inner loop } - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { log.Println("Compile: AutoEdge: UIDS:") for i, u := range uids { log.Printf("Compile: AutoEdge: UID%d: %v", i, u) diff --git a/pgraph/autogroup.go b/pgraph/autogroup.go index 4a1b173a..c4b9fc7f 100644 --- a/pgraph/autogroup.go +++ b/pgraph/autogroup.go @@ -21,6 +21,8 @@ import ( "fmt" "log" + "github.com/purpleidea/mgmt/util" + errwrap "github.com/pkg/errors" ) @@ -310,7 +312,7 @@ func (g *Graph) autoGroup(ag AutoGrouper) chan string { wStr := fmt.Sprintf("%s", w) if err := ag.vertexCmp(v, w); err != nil { // cmp ? - if g.Flags.Debug { + if b, ok := g.Value("debug"); ok && util.Bool(b) { strch <- fmt.Sprintf("Compile: Grouping: !GroupCmp for: %s into %s", wStr, vStr) } diff --git a/pgraph/pgraph.go b/pgraph/pgraph.go index 78582b7b..3a7d948b 100644 --- a/pgraph/pgraph.go +++ b/pgraph/pgraph.go @@ -42,11 +42,6 @@ const ( graphStatePaused ) -// Flags contains specific constants used by the graph. -type Flags struct { - Debug bool -} - // Graph is the graph structure in this library. // The graph abstract data type (ADT) is defined as follows: // * the directed graph arrows point from left to right ( -> ) @@ -60,7 +55,6 @@ type Graph struct { kv map[string]interface{} // some values associated with the graph // legacy - Flags Flags state graphState fastPause bool // used to disable pokes for a fast pause mutex *sync.Mutex // used when modifying graph State variable @@ -158,7 +152,6 @@ func (g *Graph) Copy() *Graph { kv: g.kv, // legacy - Flags: g.Flags, state: g.state, mutex: g.mutex, wg: g.wg, diff --git a/util/interfaces.go b/util/interfaces.go new file mode 100644 index 00000000..9f96c7c2 --- /dev/null +++ b/util/interfaces.go @@ -0,0 +1,27 @@ +// Mgmt +// Copyright (C) 2013-2017+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package util + +// Bool returns the interface value if it is a bool, and otherwise it panics. +func Bool(x interface{}) bool { + b, ok := x.(bool) + if !ok { + panic("not a bool") + } + return b +}