Select Git revision
Forked from
ai3 / thirdparty / rsyslog-exporter
Source project has a limited visibility.
triggers.go 2.29 KiB
package watcher
import (
"encoding/json"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"git.autistici.org/ai3/tools/replds2/common"
pb "git.autistici.org/ai3/tools/replds2/proto"
)
// The nullTriggerManager does nothing.
type nullTriggerManager struct{}
func (nullTriggerManager) Has(string) bool { return false }
func (nullTriggerManager) Notify(*common.NotifyBatch) {}
// The scriptTriggerManager runs user-configured trigger scripts.
type scriptTriggerManager map[string]*scriptTrigger
func (m scriptTriggerManager) Has(path string) bool {
_, ok := m[path]
return ok
}
func (m scriptTriggerManager) Notify(b *common.NotifyBatch) {
b.Apply(func(path string, nodes []*pb.Node) {
trigger := m[path]
if err := trigger.Run(nodes); err != nil {
log.Printf("trigger error: %v", err)
}
})
}
type scriptTrigger struct {
name string
Path string `json:"path"`
Command string `json:"command"`
}
func (t *scriptTrigger) Run(nodes []*pb.Node) error {
// Build an environment for the script.
changedEnvStr := "REPLDS_CHANGES="
for _, node := range nodes {
if !node.Deleted {
changedEnvStr += node.Path
}
}
env := os.Environ()
env = append(env, "REPLDS=1")
env = append(env, changedEnvStr)
// Run the command using the shell.
cmd := exec.Command("/bin/sh", "-c", t.Command)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
cmd.Env = env
log.Printf("executing trigger '%s'", t.name)
return cmd.Run()
}
func LoadTriggersFromDir(dir string) (TriggerManager, error) {
d, err := os.Open(dir)
if err != nil {
return nil, err
}
defer d.Close()
m := make(map[string]*scriptTrigger)
files, err := d.Readdir(0)
if err != nil {
return nil, err
}
for _, f := range files {
if !f.Mode().IsRegular() {
continue
}
if strings.Contains(f.Name(), ".") {
continue
}
data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
if err != nil {
log.Printf("couldn't read %s: %v", f.Name(), err)
continue
}
var trig scriptTrigger
trig.name = f.Name()
if err := json.Unmarshal(data, &trig); err != nil {
log.Printf("invalid JSON in %s: %v", f.Name(), err)
continue
}
if trig.Path == "" || trig.Command == "" {
log.Printf("invalid trigger specification in %s", f.Name())
continue
}
m[trig.Path] = &trig
}
return scriptTriggerManager(m), nil
}