From 4d137f46f87b1f4e1e0ee5c47a5d42735c4c8a56 Mon Sep 17 00:00:00 2001 From: Sharad Ganapathy Date: Sat, 16 Jul 2016 19:37:34 -0700 Subject: [PATCH] Adding timer resource and usage examples --- config.go | 11 ++-- examples/timer1.yaml | 25 ++++++++ examples/timer2.yaml | 43 +++++++++++++ timer.go | 148 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 examples/timer1.yaml create mode 100644 examples/timer2.yaml create mode 100644 timer.go diff --git a/config.go b/config.go index 99ac67bce2..0a361301ad 100644 --- a/config.go +++ b/config.go @@ -46,11 +46,12 @@ type edgeConfig struct { type GraphConfig struct { Graph string `yaml:"graph"` Resources struct { - Noop []*NoopRes `yaml:"noop"` - Pkg []*PkgRes `yaml:"pkg"` - File []*FileRes `yaml:"file"` - Svc []*SvcRes `yaml:"svc"` - Exec []*ExecRes `yaml:"exec"` + Noop []*NoopRes `yaml:"noop"` + Pkg []*PkgRes `yaml:"pkg"` + File []*FileRes `yaml:"file"` + Svc []*SvcRes `yaml:"svc"` + Exec []*ExecRes `yaml:"exec"` + Timer []*TimerRes `yaml:"timer"` } `yaml:"resources"` Collector []collectorResConfig `yaml:"collect"` Edges []edgeConfig `yaml:"edges"` diff --git a/examples/timer1.yaml b/examples/timer1.yaml new file mode 100644 index 0000000000..0bd3f15eee --- /dev/null +++ b/examples/timer1.yaml @@ -0,0 +1,25 @@ +--- +graph: mygraph +comment: timer example +resources: + timer: + - name: timer1 + interval: 30 + exec: + - name: exec1 + cmd: echo hello world + timeout: 0 + watchcmd: '' + watchshell: '' + ifcmd: '' + ifshell: '' + pollint: 0 + state: present +edges: +- name: e1 + from: + kind: timer + name: timer1 + to: + kind: exec + name: exec1 diff --git a/examples/timer2.yaml b/examples/timer2.yaml new file mode 100644 index 0000000000..7e8d0e0fe1 --- /dev/null +++ b/examples/timer2.yaml @@ -0,0 +1,43 @@ +--- +graph: mygraph +comment: example of multiple timers +resources: + timer: + - name: timer1 + interval: 30 + - name: timer2 + interval: 60 + exec: + - name: exec1 + cmd: echo hello world 30 + timeout: 0 + watchcmd: '' + watchshell: '' + ifcmd: '' + ifshell: '' + pollint: 0 + state: present + - name: exec2 + cmd: echo hello world 60 + timeout: 0 + watchcmd: '' + watchshell: '' + ifcmd: '' + ifshell: '' + pollint: 0 + state: present +edges: +- name: e1 + from: + kind: timer + name: timer1 + to: + kind: exec + name: exec1 +- name: e2 + from: + kind: timer + name: timer2 + to: + kind: exec + name: exec2 diff --git a/timer.go b/timer.go new file mode 100644 index 0000000000..5b47423c05 --- /dev/null +++ b/timer.go @@ -0,0 +1,148 @@ +// Mgmt +// Copyright (C) 2013-2016+ 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 main + +import ( + "encoding/gob" + "log" + "time" +) + +func init() { + gob.Register(&TimerRes{}) +} + +// TimerRes is a timer resource +type TimerRes struct { + BaseRes `yaml:",inline"` + Interval int `yaml:"interval"` // Interval : Interval between runs +} + +type TimerUUID struct { + BaseUUID + name string +} + +// NewTimerRes creates a new TimerRes +func NewTimerRes(name string, interval int) *TimerRes { + obj := &TimerRes{ + BaseRes: BaseRes{ + Name: name, + }, + Interval: interval, + } + obj.Init() + return obj +} + +func (obj *TimerRes) Init() { + obj.BaseRes.kind = "Timer" + obj.BaseRes.Init() // call base init, b/c we're overrriding +} + +// Validate the params that are passed to TimerRes +// Currently we are getting only an interval in seconds +// which gets validated by go compiler +func (obj *TimerRes) Validate() bool { + return true +} + +func (obj *TimerRes) Watch(processChan chan Event) { + if obj.IsWatching() { + return + } + + // Create a time.Ticker for the given interval + ticker := time.NewTicker(time.Duration(obj.Interval) * time.Second) + defer ticker.Stop() + + obj.SetWatching(true) + defer obj.SetWatching(false) + cuuid := obj.converger.Register() + defer cuuid.Unregister() + + var send = false + + for { + obj.SetState(resStateWatching) + select { + case <-ticker.C: // received the timer event + send = true + log.Printf("%v[%v]: received tick", obj.Kind(), obj.GetName()) + case event := <-obj.events: + cuuid.SetConverged(false) + if exit, _ := obj.ReadEvent(&event); exit { + return + } + case _ = <-cuuid.ConvergedTimer(): + cuuid.SetConverged(true) + continue + } + if send { + send = false + obj.isStateOK = false + resp := NewResp() + processChan <- Event{eventNil, resp, "timer ticked", true} + resp.ACKWait() + } + } +} + +func (obj *TimerRes) GetUUIDs() []ResUUID { + x := &TimerUUID{ + BaseUUID: BaseUUID{ + name: obj.GetName(), + kind: obj.Kind(), + }, + name: obj.Name, + } + return []ResUUID{x} +} + +func (obj *TimerRes) AutoEdges() AutoEdge { + return nil +} + +func (obj *TimerRes) Compare(res Res) bool { + switch res.(type) { + case *TimerRes: + res := res.(*TimerRes) + if !obj.BaseRes.Compare(res) { + return false + } + if obj.Name != res.Name { + return false + } + if obj.Interval != res.Interval { + return false + } + default: + return false + } + return true +} + +// CheckApply method for Timer resource. Does nothing, returns happy! +func (obj *TimerRes) CheckApply(apply bool) (bool, error) { + log.Printf("%v[%v]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply) + return true, nil // state is always okay +} + +func (obj *TimerRes) CollectPatten(pattern string) { + return +}