Files
certman/app/executor/hook.go
Steven Tracey 6aacbfbb71
All checks were successful
Build (artifact) / build (push) Has been skipped
[CI-SKIP] Store Pre-Claude Code
2026-04-22 22:26:21 -04:00

74 lines
1.8 KiB
Go
Raw Permalink 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 main
import (
"context"
"errors"
"os"
"os/exec"
"syscall"
"time"
"git.nevets.tech/Steven/certman/common"
pb "git.nevets.tech/Steven/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
}