Files
go-alived/internal/health/script.go
2025-12-08 22:23:45 +08:00

74 lines
1.4 KiB
Go

package health
import (
"context"
"fmt"
"os/exec"
"time"
)
type ScriptChecker struct {
name string
script string
args []string
timeout time.Duration
}
func NewScriptChecker(name string, config map[string]interface{}) (*ScriptChecker, error) {
script, ok := config["script"].(string)
if !ok {
return nil, fmt.Errorf("script checker: missing or invalid 'script' field")
}
var args []string
if argsInterface, ok := config["args"].([]interface{}); ok {
args = make([]string, len(argsInterface))
for i, arg := range argsInterface {
if argStr, ok := arg.(string); ok {
args[i] = argStr
}
}
}
timeout := 10 * time.Second
if t, ok := config["timeout"].(string); ok {
if d, err := time.ParseDuration(t); err == nil {
timeout = d
}
}
return &ScriptChecker{
name: name,
script: script,
args: args,
timeout: timeout,
}, nil
}
func (c *ScriptChecker) Name() string {
return c.name
}
func (c *ScriptChecker) Type() string {
return "script"
}
func (c *ScriptChecker) Check(ctx context.Context) CheckResult {
cmdCtx, cancel := context.WithTimeout(ctx, c.timeout)
defer cancel()
cmd := exec.CommandContext(cmdCtx, c.script, c.args...)
err := cmd.Run()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if exitErr.ExitCode() != 0 {
return CheckResultFailure
}
}
return CheckResultFailure
}
return CheckResultSuccess
}