Files
certman/app/executor/hook.go
Steven Tracey e0f68788c0
Some checks failed
Build (artifact) / build (push) Failing after 1m3s
Major Refactoring, Client can now be used as a library
2026-03-16 21:48:32 +01:00

74 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package executor
import (
"context"
"errors"
"os"
"os/exec"
"syscall"
"time"
"git.nevets.tech/Keys/certman/common"
pb "git.nevets.tech/Keys/certman/proto/v1"
)
type hookServer struct {
pb.UnimplementedHookServiceServer
}
func (s *hookServer) ExecuteHook(ctx context.Context, req *pb.ExecuteHookRequest) (*pb.ExecuteHookResponse, error) {
h := req.GetHook()
if h == nil {
return &pb.ExecuteHookResponse{Error: "missing hook"}, nil
}
// Minimal validation
if len(h.GetCommand()) == 0 {
return &pb.ExecuteHookResponse{Error: "command is empty"}, nil
}
// Timeout
timeout := time.Duration(h.GetTimeoutSeconds()) * time.Second
if timeout <= 0 {
timeout = 30 * time.Second
}
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
// Build command
cmdArgs := h.GetCommand()
cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...)
if cwd := h.GetCwd(); cwd != "" {
cmd.Dir = cwd
}
// Env: inherit current + overlay provided
env := os.Environ()
for k, v := range h.GetEnv() {
env = append(env, k+"="+v)
}
cmd.Env = env
// Run as user/group if specified (Linux/Unix)
if h.GetUser() != "" || h.GetGroup() != "" {
cred, err := common.MakeCredential(h.GetUser(), h.GetGroup())
if err != nil {
return &pb.ExecuteHookResponse{Error: brief(err)}, nil
}
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: cred,
}
}
// Were intentionally NOT returning stdout/stderr; only a brief error on failure.
if err := cmd.Run(); err != nil {
// If context deadline hit, make the error message short and explicit.
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
return &pb.ExecuteHookResponse{Error: "hook timed out"}, nil
}
return &pb.ExecuteHookResponse{Error: brief(err)}, nil
}
return &pb.ExecuteHookResponse{Error: ""}, nil
}