This commit is contained in:
ppom 2023-07-12 17:45:16 +02:00
parent 98f7f15ae0
commit 075b9252b7
6 changed files with 25 additions and 13 deletions

View File

@ -50,9 +50,9 @@ func (a *ActionStore) Quit() {
a.mutex.Lock()
defer a.mutex.Unlock()
for _, actions := range a.store {
for _, sigs := range actions {
for action, sigs := range actions {
for sig := range sigs {
close(sig)
sig <- action.OnExit
}
}
}

View File

@ -76,6 +76,7 @@ func sleep(d time.Duration) chan bool {
func (a *Action) exec(match string, advance time.Duration) {
defer wgActions.Done()
doExec := true
// Wait for either end of sleep time, or actionStore requesting stop
if a.afterDuration != 0 && a.afterDuration > advance {
@ -83,24 +84,26 @@ func (a *Action) exec(match string, advance time.Duration) {
select {
case <-sleep(a.afterDuration - advance):
// no-op
case _, _ = <-stopAction:
case doExec = <-stopAction:
// no-op
}
// Let's not wait for the lock
go actionStore.Unregister(a, match, stopAction)
}
computedCommand := make([]string, 0, len(a.Cmd))
for _, item := range a.Cmd {
computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.patternWithBraces, match))
}
if doExec {
computedCommand := make([]string, 0, len(a.Cmd))
for _, item := range a.Cmd {
computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.patternWithBraces, match))
}
log.Printf("INFO %s.%s.%s: run %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand)
log.Printf("INFO %s.%s.%s: run %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand)
cmd := exec.Command(computedCommand[0], computedCommand[1:]...)
cmd := exec.Command(computedCommand[0], computedCommand[1:]...)
if ret := cmd.Run(); ret != nil {
log.Printf("ERROR %s.%s.%s: run %s, code %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand, ret)
if ret := cmd.Run(); ret != nil {
log.Printf("ERROR %s.%s.%s: run %s, code %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand, ret)
}
}
}

View File

@ -56,6 +56,8 @@ type Action struct {
After string `yaml:"after"`
afterDuration time.Duration `yaml:"-"`
OnExit bool `yaml:"onexit"`
}
type LogEntry struct {
@ -144,6 +146,8 @@ func (c *Conf) setup() {
log.Fatalln("FATAL Bad configuration: Failed to parse after time in ", stream.name, ".", filter.name, ".", action.name, ":", err)
}
action.afterDuration = afterDuration
} else if action.OnExit {
log.Fatalln("FATAL Bad configuration: Cannot have `onexit:true` without an `after` directive in", stream.name, ".", filter.name, ".", action.name)
}
if filter.longuestActionDuration == nil || filter.longuestActionDuration.Milliseconds() < action.afterDuration.Milliseconds() {
filter.longuestActionDuration = &action.afterDuration

View File

@ -17,3 +17,4 @@ streams:
sleepdamn:
cmd: [ "echo", "sleep", "<ip>" ]
after: 8m
onexit: true

View File

@ -1,5 +1,4 @@
---
# TODO heavily comment this file
# definitions are just a place to put chunks of conf you want to reuse in another place
# they're not readed by reaction
definitions:
@ -42,3 +41,8 @@ streams:
# if after is defined, the action will not take place immediately, but after a specified duration.
# same format as retry-period
after: 48h
# let's say reaction is quitting. does it run all those pending commands which had an `after` duration set?
# if you want reaction to run those pending commands before exiting, you can set this:
# onexit: true
# (defaults to false)
# here it is not useful because we will flush the chain containing the bans anyway (see ./reaction.service)

2
go.mod
View File

@ -3,5 +3,5 @@ module framagit.org/ppom/reaction
go 1.19
require (
gopkg.in/yaml.v3 v3.0.1 // indirect
gopkg.in/yaml.v3 v3.0.1
)