Info modal + proto
Deploy / deploy (push) Successful in 9s

This commit is contained in:
2026-08-31 16:37:43 +05:00
parent 202ab22530
commit 315ced56bb
7 changed files with 335 additions and 56 deletions
+31
View File
@@ -481,6 +481,37 @@ func (s *server) dockerTargets(ctx context.Context, name, op string) ([]string,
return targets, nil
}
// ServiceInfo returns raw status output for the modal: `systemctl status` / `docker ps -a` for the card.
func (s *server) ServiceInfo(ctx context.Context, req *connect.Request[homelabv1.ServiceInfoRequest]) (*connect.Response[homelabv1.ServiceInfoResponse], error) {
name, kind := req.Msg.GetName(), req.Msg.GetKind()
if !svcNameRe.MatchString(name) {
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("bad service name %q", name))
}
ctx, cancel := context.WithTimeout(ctx, svcTimeout)
defer cancel()
var out string
var err error
if kind == homelabv1.ServiceKind_DOCKER {
// compose project first, bare container (no label) as fallback
out, err = dockerOut(ctx, "ps", "-a", "--filter", "label=com.docker.compose.project="+name)
if strings.TrimSpace(out) == "" {
out, err = dockerOut(ctx, "ps", "-a", "--filter", "name="+name)
}
} else {
// status exits non-zero for inactive units (code 3) — that is valid output, not an error
c := exec.CommandContext(ctx, "systemctl", "--user", "status", name+".service", "--no-pager", "-n", "0")
b, cerr := c.CombinedOutput()
out, err = string(b), cerr
}
if err != nil && strings.TrimSpace(out) == "" {
log.Printf("service info %s/%s: ERROR %v", kind, name, err)
return nil, connect.NewError(connect.CodeInternal, err)
}
log.Printf("service info %s/%s ok", kind, name)
return connect.NewResponse(&homelabv1.ServiceInfoResponse{Output: strings.TrimRight(out, "\n")}), nil
}
func (s *server) RunScript(_ context.Context, req *connect.Request[homelabv1.RunScriptRequest]) (*connect.Response[homelabv1.RunScriptResponse], error) {
it, ok := s.exec[req.Msg.GetName()]
if !ok {