Skip to content
Snippets Groups Projects
Select Git revision
  • da3c5ac30c40e5dfdfd7f722f611543cd784d0ba
  • master default protected
  • lintian-fixes
3 results

format

Blame
  • 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
    }