resources: Improve the state/cache system
Refactor the state cache into the engine. This makes resource writing less error prone, and paves the way for better notifications.
This commit is contained in:
@@ -129,19 +129,35 @@ func (g *Graph) Process(v *Vertex) error {
|
|||||||
if changed, err := obj.SendRecv(obj); err != nil {
|
if changed, err := obj.SendRecv(obj); err != nil {
|
||||||
return errwrap.Wrapf(err, "could not SendRecv in Process")
|
return errwrap.Wrapf(err, "could not SendRecv in Process")
|
||||||
} else if changed {
|
} else if changed {
|
||||||
obj.StateOK(false) // invalidate cache
|
obj.StateOK(false) // invalidate cache, mark as dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if global.DEBUG {
|
||||||
|
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), !obj.Meta().Noop)
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkOK bool
|
||||||
|
var err error
|
||||||
|
if obj.IsStateOK() { // check cached state, to skip CheckApply
|
||||||
|
checkOK, err = true, nil
|
||||||
|
} else {
|
||||||
// if this fails, don't UpdateTimestamp()
|
// if this fails, don't UpdateTimestamp()
|
||||||
checkok, err := obj.CheckApply(!obj.Meta().Noop)
|
checkOK, err = obj.CheckApply(!obj.Meta().Noop)
|
||||||
if checkok && err != nil { // should never return this way
|
}
|
||||||
log.Fatalf("%s[%s]: CheckApply(): %t, %+v", obj.Kind(), obj.GetName(), checkok, err)
|
|
||||||
|
if checkOK && err != nil { // should never return this way
|
||||||
|
log.Fatalf("%s[%s]: CheckApply(): %t, %+v", obj.Kind(), obj.GetName(), checkOK, err)
|
||||||
}
|
}
|
||||||
if global.DEBUG {
|
if global.DEBUG {
|
||||||
log.Printf("%s[%s]: CheckApply(): %t, %v", obj.Kind(), obj.GetName(), checkok, err)
|
log.Printf("%s[%s]: CheckApply(): %t, %v", obj.Kind(), obj.GetName(), checkOK, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !checkok { // if state *was* not ok, we had to have apply'ed
|
// if CheckApply ran without noop and without error, state should be good
|
||||||
|
if !obj.Meta().Noop && err == nil { // aka !obj.Meta().Noop || checkOK
|
||||||
|
obj.StateOK(true) // reset
|
||||||
|
}
|
||||||
|
|
||||||
|
if !checkOK { // if state *was* not ok, we had to have apply'ed
|
||||||
if err != nil { // error during check or apply
|
if err != nil { // error during check or apply
|
||||||
ok = false
|
ok = false
|
||||||
} else {
|
} else {
|
||||||
@@ -189,7 +205,7 @@ func (g *Graph) Worker(v *Vertex) error {
|
|||||||
// the Watch() function about which graph it is
|
// the Watch() function about which graph it is
|
||||||
// running on, which isolates things nicely...
|
// running on, which isolates things nicely...
|
||||||
obj := v.Res
|
obj := v.Res
|
||||||
chanProcess := make(chan event.Event)
|
processChan := make(chan event.Event)
|
||||||
go func() {
|
go func() {
|
||||||
running := false
|
running := false
|
||||||
var timer = time.NewTimer(time.Duration(math.MaxInt64)) // longest duration
|
var timer = time.NewTimer(time.Duration(math.MaxInt64)) // longest duration
|
||||||
@@ -205,14 +221,14 @@ func (g *Graph) Worker(v *Vertex) error {
|
|||||||
// event loop will keep running and change state,
|
// event loop will keep running and change state,
|
||||||
// causing the converged timeout to fire!
|
// causing the converged timeout to fire!
|
||||||
select {
|
select {
|
||||||
case event, ok := <-chanProcess: // must use like this
|
case event, ok := <-processChan: // must use like this
|
||||||
if running && ok {
|
if running && ok {
|
||||||
// we got an event that wasn't a close,
|
// we got an event that wasn't a close,
|
||||||
// while we were waiting for the timer!
|
// while we were waiting for the timer!
|
||||||
// if this happens, it might be a bug:(
|
// if this happens, it might be a bug:(
|
||||||
log.Fatalf("%s[%s]: Worker: Unexpected event: %+v", v.Kind(), v.GetName(), event)
|
log.Fatalf("%s[%s]: Worker: Unexpected event: %+v", v.Kind(), v.GetName(), event)
|
||||||
}
|
}
|
||||||
if !ok { // chanProcess closed, let's exit
|
if !ok { // processChan closed, let's exit
|
||||||
break Loop // no event, so no ack!
|
break Loop // no event, so no ack!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +261,7 @@ func (g *Graph) Worker(v *Vertex) error {
|
|||||||
running = false
|
running = false
|
||||||
log.Printf("%s[%s]: CheckApply delay expired!", v.Kind(), v.GetName())
|
log.Printf("%s[%s]: CheckApply delay expired!", v.Kind(), v.GetName())
|
||||||
// re-send this failed event, to trigger a CheckApply()
|
// re-send this failed event, to trigger a CheckApply()
|
||||||
go func() { chanProcess <- saved }()
|
go func() { processChan <- saved }()
|
||||||
// TODO: should we send a fake event instead?
|
// TODO: should we send a fake event instead?
|
||||||
//saved = nil
|
//saved = nil
|
||||||
}
|
}
|
||||||
@@ -308,14 +324,14 @@ func (g *Graph) Worker(v *Vertex) error {
|
|||||||
// NOTE: we can avoid the send if running Watch guarantees
|
// NOTE: we can avoid the send if running Watch guarantees
|
||||||
// one CheckApply event on startup!
|
// one CheckApply event on startup!
|
||||||
//if pendingSendEvent { // TODO: should this become a list in the future?
|
//if pendingSendEvent { // TODO: should this become a list in the future?
|
||||||
// if exit, err := obj.DoSend(chanProcess, ""); exit || err != nil {
|
// if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
// return err // we exit or bubble up a NACK...
|
// return err // we exit or bubble up a NACK...
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reset the watch retry count after some amount of success
|
// TODO: reset the watch retry count after some amount of success
|
||||||
e := v.Res.Watch(chanProcess)
|
e := v.Res.Watch(processChan)
|
||||||
if e == nil { // exit signal
|
if e == nil { // exit signal
|
||||||
err = nil // clean exit
|
err = nil // clean exit
|
||||||
break
|
break
|
||||||
@@ -339,7 +355,7 @@ func (g *Graph) Worker(v *Vertex) error {
|
|||||||
// by getting the Watch resource to send one event once it's up!
|
// by getting the Watch resource to send one event once it's up!
|
||||||
//v.SendEvent(eventPoke, false, false)
|
//v.SendEvent(eventPoke, false, false)
|
||||||
}
|
}
|
||||||
close(chanProcess)
|
close(processChan)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ func (obj *ExecRes) Watch(processChan chan event.Event) error {
|
|||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// it is okay to invalidate the clean state on poke too
|
// it is okay to invalidate the clean state on poke too
|
||||||
obj.isStateOK = false // something made state dirty
|
obj.StateOK(false) // something made state dirty
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -221,12 +221,11 @@ func (obj *ExecRes) Watch(processChan chan event.Event) error {
|
|||||||
// CheckApply checks the resource state and applies the resource if the bool
|
// CheckApply checks the resource state and applies the resource if the bool
|
||||||
// input is true. It returns error info and if the state check passed or not.
|
// input is true. It returns error info and if the state check passed or not.
|
||||||
// TODO: expand the IfCmd to be a list of commands
|
// TODO: expand the IfCmd to be a list of commands
|
||||||
func (obj *ExecRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *ExecRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
// if there is a watch command, but no if command, run based on state
|
// if there is a watch command, but no if command, run based on state
|
||||||
if obj.WatchCmd != "" && obj.IfCmd == "" {
|
if obj.WatchCmd != "" && obj.IfCmd == "" {
|
||||||
if obj.isStateOK {
|
if obj.IsStateOK() { // FIXME: this is done by engine now...
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +263,7 @@ func (obj *ExecRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
// if there is no watcher and no onlyif check, assume we should run
|
// if there is no watcher and no onlyif check, assume we should run
|
||||||
} else { // if obj.WatchCmd == "" && obj.IfCmd == "" {
|
} else { // if obj.WatchCmd == "" && obj.IfCmd == "" {
|
||||||
// just run if state is dirty
|
// just run if state is dirty
|
||||||
if obj.isStateOK {
|
if obj.IsStateOK() { // FIXME: this is done by engine now...
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,11 +330,11 @@ func (obj *ExecRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
}
|
}
|
||||||
// XXX: return based on exit value!!
|
// XXX: return based on exit value!!
|
||||||
|
|
||||||
// the state tracking is for exec resources that can't "detect" their
|
// The state tracking is for exec resources that can't "detect" their
|
||||||
// state, and assume it's invalid when the Watch() function triggers.
|
// state, and assume it's invalid when the Watch() function triggers.
|
||||||
// if we apply state successfully, we should reset it here so that we
|
// If we apply state successfully, we should reset it here so that we
|
||||||
// know that we have applied since the state was set not ok by event!
|
// know that we have applied since the state was set not ok by event!
|
||||||
obj.isStateOK = true // reset
|
// This now happens automatically after the engine runs CheckApply().
|
||||||
return false, nil // success
|
return false, nil // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,6 @@ func (obj *FileRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
var send = false // send event?
|
var send = false // send event?
|
||||||
var exit = false
|
var exit = false
|
||||||
var dirty = false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if global.DEBUG {
|
if global.DEBUG {
|
||||||
@@ -190,14 +189,14 @@ func (obj *FileRes) Watch(processChan chan event.Event) error {
|
|||||||
log.Printf("%s[%s]: Event(%s): %v", obj.Kind(), obj.GetName(), event.Body.Name, event.Body.Op)
|
log.Printf("%s[%s]: Event(%s): %v", obj.Kind(), obj.GetName(), event.Body.Name, event.Body.Op)
|
||||||
}
|
}
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
|
|
||||||
case event := <-obj.Events():
|
case event := <-obj.Events():
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
if exit, send = obj.ReadEvent(&event); exit {
|
if exit, send = obj.ReadEvent(&event); exit {
|
||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
//dirty = false // these events don't invalidate state
|
//obj.StateOK(false) // dirty // these events don't invalidate state
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
cuid.SetConverged(true) // converged!
|
cuid.SetConverged(true) // converged!
|
||||||
@@ -206,18 +205,13 @@ func (obj *FileRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
// do all our event sending all together to avoid duplicate msgs
|
// do all our event sending all together to avoid duplicate msgs
|
||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only invalid state on certain types of events
|
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -645,11 +639,6 @@ func (obj *FileRes) contentCheckApply(apply bool) (checkOK bool, _ error) {
|
|||||||
// CheckApply checks the resource state and applies the resource if the bool
|
// CheckApply checks the resource state and applies the resource if the bool
|
||||||
// input is true. It returns error info and if the state check passed or not.
|
// input is true. It returns error info and if the state check passed or not.
|
||||||
func (obj *FileRes) CheckApply(apply bool) (checkOK bool, _ error) {
|
func (obj *FileRes) CheckApply(apply bool) (checkOK bool, _ error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
if obj.isStateOK { // cache the state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
checkOK = true
|
checkOK = true
|
||||||
|
|
||||||
@@ -673,10 +662,6 @@ func (obj *FileRes) CheckApply(apply bool) (checkOK bool, _ error) {
|
|||||||
// checkOK = false
|
// checkOK = false
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// if we did work successfully, or are in a good state, then state is ok
|
|
||||||
if apply || checkOK {
|
|
||||||
obj.isStateOK = true
|
|
||||||
}
|
|
||||||
return checkOK, nil // w00t
|
return checkOK, nil // w00t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ func (obj *HostnameRes) Watch(processChan chan event.Event) error {
|
|||||||
bus.Signal(signals)
|
bus.Signal(signals)
|
||||||
|
|
||||||
var send = false // send event?
|
var send = false // send event?
|
||||||
var dirty = false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
obj.SetState(ResStateWatching) // reset
|
obj.SetState(ResStateWatching) // reset
|
||||||
@@ -151,7 +150,7 @@ func (obj *HostnameRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-signals:
|
case <-signals:
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
|
|
||||||
case event := <-obj.Events():
|
case event := <-obj.Events():
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
@@ -160,7 +159,7 @@ func (obj *HostnameRes) Watch(processChan chan event.Event) error {
|
|||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
cuid.SetConverged(true) // converged!
|
cuid.SetConverged(true) // converged!
|
||||||
@@ -175,11 +174,7 @@ func (obj *HostnameRes) Watch(processChan chan event.Event) error {
|
|||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
// only do this on certain types of events
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -223,12 +218,6 @@ func updateHostnameProperty(object dbus.BusObject, expectedValue, property, sett
|
|||||||
|
|
||||||
// CheckApply method for Hostname resource.
|
// CheckApply method for Hostname resource.
|
||||||
func (obj *HostnameRes) CheckApply(apply bool) (checkOK bool, err error) {
|
func (obj *HostnameRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%v[%v]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
if obj.isStateOK { // cached state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := util.SystemBusPrivateUsable()
|
conn, err := util.SystemBusPrivateUsable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errwrap.Wrap(err, "Failed to connect to the private system bus")
|
return false, errwrap.Wrap(err, "Failed to connect to the private system bus")
|
||||||
@@ -260,10 +249,6 @@ func (obj *HostnameRes) CheckApply(apply bool) (checkOK bool, err error) {
|
|||||||
checkOK = checkOK && propertyCheckOK
|
checkOK = checkOK && propertyCheckOK
|
||||||
}
|
}
|
||||||
|
|
||||||
if apply || checkOK {
|
|
||||||
obj.isStateOK = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkOK, nil
|
return checkOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,16 +125,15 @@ func (obj *MsgRes) Watch(processChan chan event.Event) error {
|
|||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: invalidate cached state on poke events
|
// TODO: invalidate cached state on poke events
|
||||||
obj.logStateOK = false
|
//obj.logStateOK = false
|
||||||
if obj.Journal {
|
//if obj.Journal {
|
||||||
obj.journalStateOK = false
|
// obj.journalStateOK = false
|
||||||
}
|
//}
|
||||||
if obj.Syslog {
|
//if obj.Syslog {
|
||||||
obj.syslogStateOK = false
|
// obj.syslogStateOK = false
|
||||||
}
|
//}
|
||||||
*/
|
//obj.updateStateOK()
|
||||||
send = true
|
send = true
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
@@ -205,7 +204,7 @@ func (obj *MsgRes) Compare(res Res) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAllStateOK derives a compound state from all internal cache flags that apply to this resource.
|
// isAllStateOK derives a compound state from all internal cache flags that apply to this resource.
|
||||||
func (obj *MsgRes) isAllStateOK() bool {
|
func (obj *MsgRes) isAllStateOK() bool {
|
||||||
if obj.Journal && !obj.journalStateOK {
|
if obj.Journal && !obj.journalStateOK {
|
||||||
return false
|
return false
|
||||||
@@ -216,6 +215,11 @@ func (obj *MsgRes) isAllStateOK() bool {
|
|||||||
return obj.logStateOK
|
return obj.logStateOK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateStateOK sets the global state so it can be read by the engine.
|
||||||
|
func (obj *MsgRes) updateStateOK() {
|
||||||
|
obj.StateOK(obj.isAllStateOK())
|
||||||
|
}
|
||||||
|
|
||||||
// JournalPriority converts a string description to a numeric priority.
|
// JournalPriority converts a string description to a numeric priority.
|
||||||
// XXX: Have Validate() make sure it actually is one of these.
|
// XXX: Have Validate() make sure it actually is one of these.
|
||||||
func (obj *MsgRes) journalPriority() journal.Priority {
|
func (obj *MsgRes) journalPriority() journal.Priority {
|
||||||
@@ -243,15 +247,16 @@ func (obj *MsgRes) journalPriority() journal.Priority {
|
|||||||
// CheckApply method for Msg resource.
|
// CheckApply method for Msg resource.
|
||||||
// Every check leads to an apply, meaning that the message is flushed to the journal.
|
// Every check leads to an apply, meaning that the message is flushed to the journal.
|
||||||
func (obj *MsgRes) CheckApply(apply bool) (bool, error) {
|
func (obj *MsgRes) CheckApply(apply bool) (bool, error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
if obj.isAllStateOK() {
|
// isStateOK() done by engine, so we updateStateOK() to pass in value
|
||||||
return true, nil
|
//if obj.isAllStateOK() {
|
||||||
}
|
// return true, nil
|
||||||
|
//}
|
||||||
|
|
||||||
if !obj.logStateOK {
|
if !obj.logStateOK {
|
||||||
log.Printf("%s[%s]: Body: %s", obj.Kind(), obj.GetName(), obj.Body)
|
log.Printf("%s[%s]: Body: %s", obj.Kind(), obj.GetName(), obj.Body)
|
||||||
obj.logStateOK = true
|
obj.logStateOK = true
|
||||||
|
obj.updateStateOK()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apply {
|
if !apply {
|
||||||
@@ -262,10 +267,12 @@ func (obj *MsgRes) CheckApply(apply bool) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
obj.journalStateOK = true
|
obj.journalStateOK = true
|
||||||
|
obj.updateStateOK()
|
||||||
}
|
}
|
||||||
if obj.Syslog && !obj.syslogStateOK {
|
if obj.Syslog && !obj.syslogStateOK {
|
||||||
// TODO: implement syslog client
|
// TODO: implement syslog client
|
||||||
obj.syslogStateOK = true
|
obj.syslogStateOK = true
|
||||||
|
obj.updateStateOK()
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package resources
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/event"
|
"github.com/purpleidea/mgmt/event"
|
||||||
@@ -102,8 +101,6 @@ func (obj *NoopRes) Watch(processChan chan event.Event) error {
|
|||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only do this on certain types of events
|
|
||||||
//obj.isStateOK = false // something made state dirty
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -112,8 +109,7 @@ func (obj *NoopRes) Watch(processChan chan event.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckApply method for Noop resource. Does nothing, returns happy!
|
// CheckApply method for Noop resource. Does nothing, returns happy!
|
||||||
func (obj *NoopRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *NoopRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
return true, nil // state is always okay
|
return true, nil // state is always okay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ func (obj *NspawnRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
var send = false
|
var send = false
|
||||||
var exit = false
|
var exit = false
|
||||||
var dirty = false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
obj.SetState(ResStateWatching)
|
obj.SetState(ResStateWatching)
|
||||||
@@ -155,7 +154,7 @@ func (obj *NspawnRes) Watch(processChan chan event.Event) error {
|
|||||||
return fmt.Errorf("Unknown event: %s", event.Name)
|
return fmt.Errorf("Unknown event: %s", event.Name)
|
||||||
}
|
}
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
case event := <-obj.Events():
|
case event := <-obj.Events():
|
||||||
@@ -171,18 +170,13 @@ func (obj *NspawnRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
// do all our event sending all together to avoid duplicate msgs
|
// do all our event sending all together to avoid duplicate msgs
|
||||||
if send || !obj.isStateOK {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only invalid state on certain types of events
|
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -193,15 +187,7 @@ func (obj *NspawnRes) Watch(processChan chan event.Event) error {
|
|||||||
// CheckApply is run to check the state and, if apply is true, to apply the
|
// CheckApply is run to check the state and, if apply is true, to apply the
|
||||||
// necessary changes to reach the desired state. this is run before Watch and
|
// necessary changes to reach the desired state. this is run before Watch and
|
||||||
// again if watch finds a change occurring to the state
|
// again if watch finds a change occurring to the state
|
||||||
func (obj *NspawnRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *NspawnRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
if global.DEBUG {
|
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj.isStateOK { // cache the state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// this resource depends on systemd ensure that it's running
|
// this resource depends on systemd ensure that it's running
|
||||||
if !systemdUtil.IsRunningSystemd() {
|
if !systemdUtil.IsRunningSystemd() {
|
||||||
return false, errors.New("Systemd is not running.")
|
return false, errors.New("Systemd is not running.")
|
||||||
@@ -241,11 +227,10 @@ func (obj *NspawnRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
if global.DEBUG {
|
if global.DEBUG {
|
||||||
log.Printf("%s[%s]: CheckApply() in valid state", obj.Kind(), obj.GetName())
|
log.Printf("%s[%s]: CheckApply() in valid state", obj.Kind(), obj.GetName())
|
||||||
}
|
}
|
||||||
obj.isStateOK = true // state is ok
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of state checking. if we're here, checkok is false
|
// end of state checking. if we're here, checkOK is false
|
||||||
if !apply {
|
if !apply {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@@ -271,7 +256,6 @@ func (obj *NspawnRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.isStateOK = true // state is now good
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -239,8 +238,6 @@ func (obj *PasswordRes) Watch(processChan chan event.Event) error {
|
|||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only do this on certain types of events
|
|
||||||
//obj.isStateOK = false // something made state dirty
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -249,9 +246,7 @@ func (obj *PasswordRes) Watch(processChan chan event.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckApply method for Password resource. Does nothing, returns happy!
|
// CheckApply method for Password resource. Does nothing, returns happy!
|
||||||
func (obj *PasswordRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *PasswordRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ func (obj *PkgRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
var send = false // send event?
|
var send = false // send event?
|
||||||
var exit = false
|
var exit = false
|
||||||
var dirty = false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if global.DEBUG {
|
if global.DEBUG {
|
||||||
@@ -165,14 +164,14 @@ func (obj *PkgRes) Watch(processChan chan event.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
|
|
||||||
case event := <-obj.Events():
|
case event := <-obj.Events():
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
if exit, send = obj.ReadEvent(&event); exit {
|
if exit, send = obj.ReadEvent(&event); exit {
|
||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
dirty = false // these events don't invalidate state
|
//obj.StateOK(false) // these events don't invalidate state
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
cuid.SetConverged(true) // converged!
|
cuid.SetConverged(true) // converged!
|
||||||
@@ -181,18 +180,13 @@ func (obj *PkgRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
// do all our event sending all together to avoid duplicate msgs
|
// do all our event sending all together to avoid duplicate msgs
|
||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only invalid state on certain types of events
|
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -264,16 +258,8 @@ func (obj *PkgRes) pkgMappingHelper(bus *packagekit.Conn) (map[string]*packageki
|
|||||||
|
|
||||||
// CheckApply checks the resource state and applies the resource if the bool
|
// CheckApply checks the resource state and applies the resource if the bool
|
||||||
// input is true. It returns error info and if the state check passed or not.
|
// input is true. It returns error info and if the state check passed or not.
|
||||||
func (obj *PkgRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *PkgRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%s: CheckApply(%t)", obj.fmtNames(obj.getNames()), apply)
|
log.Printf("%s: Check", obj.fmtNames(obj.getNames()))
|
||||||
|
|
||||||
if obj.State == "" { // TODO: Validate() should replace this check!
|
|
||||||
log.Fatalf("%s: Package state is undefined!", obj.fmtNames(obj.getNames()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj.isStateOK { // cache the state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bus := packagekit.NewBus()
|
bus := packagekit.NewBus()
|
||||||
if bus == nil {
|
if bus == nil {
|
||||||
@@ -309,12 +295,10 @@ func (obj *PkgRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
case "newest":
|
case "newest":
|
||||||
if validState {
|
if validState {
|
||||||
obj.isStateOK = true // reset
|
|
||||||
return true, nil // state is correct, exit!
|
return true, nil // state is correct, exit!
|
||||||
}
|
}
|
||||||
default: // version string
|
default: // version string
|
||||||
if obj.State == data.Version && data.Version != "" {
|
if obj.State == data.Version && data.Version != "" {
|
||||||
obj.isStateOK = true // reset
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,7 +342,6 @@ func (obj *PkgRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
return false, err // fail
|
return false, err // fail
|
||||||
}
|
}
|
||||||
log.Printf("%s: Set: %v success!", obj.fmtNames(util.StrListIntersection(applyPackages, obj.getNames())), obj.State)
|
log.Printf("%s: Set: %v success!", obj.fmtNames(util.StrListIntersection(applyPackages, obj.getNames())), obj.State)
|
||||||
obj.isStateOK = true // reset
|
|
||||||
return false, nil // success
|
return false, nil // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ func (obj *BaseRes) Init() error {
|
|||||||
if obj.kind == "" {
|
if obj.kind == "" {
|
||||||
return fmt.Errorf("Resource did not set kind!")
|
return fmt.Errorf("Resource did not set kind!")
|
||||||
}
|
}
|
||||||
obj.events = make(chan event.Event) // unbuffered chan size to avoid stale events
|
obj.events = make(chan event.Event) // unbuffered chan to avoid stale events
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
var svc = fmt.Sprintf("%s.service", obj.Name) // systemd name
|
var svc = fmt.Sprintf("%s.service", obj.Name) // systemd name
|
||||||
var send = false // send event?
|
var send = false // send event?
|
||||||
var exit = false
|
var exit = false
|
||||||
var dirty = false
|
|
||||||
var invalid = false // does the svc exist or not?
|
var invalid = false // does the svc exist or not?
|
||||||
var previous bool // previous invalid value
|
var previous bool // previous invalid value
|
||||||
set := conn.NewSubscriptionSet() // no error should be returned
|
set := conn.NewSubscriptionSet() // no error should be returned
|
||||||
@@ -150,7 +149,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
if previous != invalid { // if invalid changed, send signal
|
if previous != invalid { // if invalid changed, send signal
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
if invalid {
|
if invalid {
|
||||||
@@ -173,7 +172,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
if event.GetActivity() {
|
if event.GetActivity() {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
@@ -183,7 +182,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !activeSet {
|
if !activeSet {
|
||||||
@@ -216,7 +215,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
log.Printf("Svc[%s]->Stopped", svc)
|
log.Printf("Svc[%s]->Stopped", svc)
|
||||||
}
|
}
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
|
|
||||||
case err := <-subErrors:
|
case err := <-subErrors:
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
@@ -228,7 +227,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
return nil // exit
|
return nil // exit
|
||||||
}
|
}
|
||||||
if event.GetActivity() {
|
if event.GetActivity() {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-cuid.ConvergedTimer():
|
case <-cuid.ConvergedTimer():
|
||||||
@@ -238,17 +237,13 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -258,13 +253,7 @@ func (obj *SvcRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
// CheckApply checks the resource state and applies the resource if the bool
|
// CheckApply checks the resource state and applies the resource if the bool
|
||||||
// input is true. It returns error info and if the state check passed or not.
|
// input is true. It returns error info and if the state check passed or not.
|
||||||
func (obj *SvcRes) CheckApply(apply bool) (checkok bool, err error) {
|
func (obj *SvcRes) CheckApply(apply bool) (checkOK bool, err error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
if obj.isStateOK { // cache the state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !systemdUtil.IsRunningSystemd() {
|
if !systemdUtil.IsRunningSystemd() {
|
||||||
return false, fmt.Errorf("Systemd is not running.")
|
return false, fmt.Errorf("Systemd is not running.")
|
||||||
}
|
}
|
||||||
@@ -301,7 +290,6 @@ func (obj *SvcRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
var startupOK = true // XXX: DETECT AND SET
|
var startupOK = true // XXX: DETECT AND SET
|
||||||
|
|
||||||
if stateOK && startupOK {
|
if stateOK && startupOK {
|
||||||
obj.isStateOK = true
|
|
||||||
return true, nil // we are in the correct state
|
return true, nil // we are in the correct state
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +337,6 @@ func (obj *SvcRes) CheckApply(apply bool) (checkok bool, err error) {
|
|||||||
|
|
||||||
// XXX: also set enabled on boot
|
// XXX: also set enabled on boot
|
||||||
|
|
||||||
obj.isStateOK = true
|
|
||||||
return false, nil // success
|
return false, nil // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ func (obj *TimerRes) Watch(processChan chan event.Event) error {
|
|||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
//obj.isStateOK = false
|
|
||||||
if exit, err := obj.DoSend(processChan, "timer ticked"); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, "timer ticked"); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -162,6 +161,5 @@ func (obj *TimerRes) Compare(res Res) bool {
|
|||||||
|
|
||||||
// CheckApply method for Timer resource. Does nothing, returns happy!
|
// CheckApply method for Timer resource. Does nothing, returns happy!
|
||||||
func (obj *TimerRes) CheckApply(apply bool) (bool, error) {
|
func (obj *TimerRes) CheckApply(apply bool) (bool, error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
return true, nil // state is always okay
|
return true, nil // state is always okay
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ func (obj *VirtRes) Watch(processChan chan event.Event) error {
|
|||||||
|
|
||||||
var send = false
|
var send = false
|
||||||
var exit = false
|
var exit = false
|
||||||
var dirty = false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -215,37 +214,37 @@ func (obj *VirtRes) Watch(processChan chan event.Event) error {
|
|||||||
switch event {
|
switch event {
|
||||||
case libvirt.VIR_DOMAIN_EVENT_DEFINED:
|
case libvirt.VIR_DOMAIN_EVENT_DEFINED:
|
||||||
if obj.Transient {
|
if obj.Transient {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
case libvirt.VIR_DOMAIN_EVENT_UNDEFINED:
|
case libvirt.VIR_DOMAIN_EVENT_UNDEFINED:
|
||||||
if !obj.Transient {
|
if !obj.Transient {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
case libvirt.VIR_DOMAIN_EVENT_STARTED:
|
case libvirt.VIR_DOMAIN_EVENT_STARTED:
|
||||||
fallthrough
|
fallthrough
|
||||||
case libvirt.VIR_DOMAIN_EVENT_RESUMED:
|
case libvirt.VIR_DOMAIN_EVENT_RESUMED:
|
||||||
if obj.State != "running" {
|
if obj.State != "running" {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
case libvirt.VIR_DOMAIN_EVENT_SUSPENDED:
|
case libvirt.VIR_DOMAIN_EVENT_SUSPENDED:
|
||||||
if obj.State != "paused" {
|
if obj.State != "paused" {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
case libvirt.VIR_DOMAIN_EVENT_STOPPED:
|
case libvirt.VIR_DOMAIN_EVENT_STOPPED:
|
||||||
fallthrough
|
fallthrough
|
||||||
case libvirt.VIR_DOMAIN_EVENT_SHUTDOWN:
|
case libvirt.VIR_DOMAIN_EVENT_SHUTDOWN:
|
||||||
if obj.State != "shutoff" {
|
if obj.State != "shutoff" {
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
case libvirt.VIR_DOMAIN_EVENT_PMSUSPENDED:
|
case libvirt.VIR_DOMAIN_EVENT_PMSUSPENDED:
|
||||||
fallthrough
|
fallthrough
|
||||||
case libvirt.VIR_DOMAIN_EVENT_CRASHED:
|
case libvirt.VIR_DOMAIN_EVENT_CRASHED:
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,17 +265,12 @@ func (obj *VirtRes) Watch(processChan chan event.Event) error {
|
|||||||
case <-Startup(startup):
|
case <-Startup(startup):
|
||||||
cuid.SetConverged(false)
|
cuid.SetConverged(false)
|
||||||
send = true
|
send = true
|
||||||
dirty = true
|
obj.StateOK(false) // dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
if send {
|
if send {
|
||||||
startup = true // startup finished
|
startup = true // startup finished
|
||||||
send = false
|
send = false
|
||||||
// only invalid state on certain types of events
|
|
||||||
if dirty {
|
|
||||||
dirty = false
|
|
||||||
obj.isStateOK = false // something made state dirty
|
|
||||||
}
|
|
||||||
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
if exit, err := obj.DoSend(processChan, ""); exit || err != nil {
|
||||||
return err // we exit or bubble up a NACK...
|
return err // we exit or bubble up a NACK...
|
||||||
}
|
}
|
||||||
@@ -379,12 +373,6 @@ func (obj *VirtRes) domainCreate() (libvirt.VirDomain, bool, error) {
|
|||||||
// CheckApply checks the resource state and applies the resource if the bool
|
// CheckApply checks the resource state and applies the resource if the bool
|
||||||
// input is true. It returns error info and if the state check passed or not.
|
// input is true. It returns error info and if the state check passed or not.
|
||||||
func (obj *VirtRes) CheckApply(apply bool) (bool, error) {
|
func (obj *VirtRes) CheckApply(apply bool) (bool, error) {
|
||||||
log.Printf("%s[%s]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
|
||||||
|
|
||||||
if obj.isStateOK { // cache the state
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
obj.conn, err = obj.connect()
|
obj.conn, err = obj.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -399,7 +387,6 @@ func (obj *VirtRes) CheckApply(apply bool) (bool, error) {
|
|||||||
} else if virErr, ok := err.(libvirt.VirError); ok && virErr.Code == libvirt.VIR_ERR_NO_DOMAIN {
|
} else if virErr, ok := err.(libvirt.VirError); ok && virErr.Code == libvirt.VIR_ERR_NO_DOMAIN {
|
||||||
// domain not found
|
// domain not found
|
||||||
if obj.absent {
|
if obj.absent {
|
||||||
obj.isStateOK = true
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,9 +525,6 @@ func (obj *VirtRes) CheckApply(apply bool) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if apply || checkOK {
|
|
||||||
obj.isStateOK = true
|
|
||||||
}
|
|
||||||
return checkOK, nil // w00t
|
return checkOK, nil // w00t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user