ipc: the capability methods share one dispatch shape (V-575)
Thirteen arms of dispatch spelled out the same handler: nil check, unmarshal, call, marshal, and a hand-written unknown-method error at the bottom of each. callDirect, callDirectNoParams and callDirectVoid hold the three shapes those arms come in, so the switch now says which Server field backs which method and nothing else. The nil check is the load-bearing part and it is unchanged: a nil field is the capability being unconfigured on this box, and the wire still answers ErrUnknownMethod. WrapKeyFn and UnlockFn keep their own arms because they take apart the request rather than passing it through. No wire change.
This commit is contained in:
+82
-149
@@ -583,180 +583,113 @@ func (s *Server) dispatch(ctx context.Context, req Request) (json.RawMessage, er
|
||||
return marshalResult(PingResp{Alive: true, Locked: locked}), nil
|
||||
|
||||
case MethodAssertStepUp:
|
||||
if s.StepUp != nil {
|
||||
return marshalResult(nil), s.StepUp(ctx)
|
||||
if s.StepUp == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return marshalResult(nil), s.StepUp(ctx)
|
||||
|
||||
case MethodStoreEncryptionKey:
|
||||
if s.WrapKeyFn != nil {
|
||||
var p storeEncryptionKeyReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.WrapKeyFn(ctx, p.Secret, p.Explicit)
|
||||
if s.WrapKeyFn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
var p storeEncryptionKeyReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.WrapKeyFn(ctx, p.Secret, p.Explicit)
|
||||
|
||||
case MethodUnlock:
|
||||
if s.UnlockFn != nil {
|
||||
var p unlockReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.UnlockFn(ctx, p.Secret)
|
||||
if s.UnlockFn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
var p unlockReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.UnlockFn(ctx, p.Secret)
|
||||
|
||||
case MethodIngestMail:
|
||||
if s.IngestMailFn != nil {
|
||||
var p IngestMailReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.IngestMailFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.IngestMailFn)
|
||||
case MethodSwapModel:
|
||||
if s.SwapModelFn != nil {
|
||||
var p SwapModelReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.SwapModelFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.SwapModelFn)
|
||||
case MethodDescribeImage:
|
||||
if s.DescribeImageFn != nil {
|
||||
var p DescribeImageReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.DescribeImageFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.DescribeImageFn)
|
||||
case MethodCaptureStart:
|
||||
if s.CaptureStartFn != nil {
|
||||
var p CaptureStartReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureStartFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureStartFn)
|
||||
case MethodCaptureAppend:
|
||||
if s.CaptureAppendFn != nil {
|
||||
var p CaptureAppendReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureAppendFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureAppendFn)
|
||||
case MethodCaptureStop:
|
||||
if s.CaptureStopFn != nil {
|
||||
var p CaptureStopReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureStopFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
case MethodCaptureStatus:
|
||||
if s.CaptureStatusFn != nil {
|
||||
resp, err := s.CaptureStatusFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureStopFn)
|
||||
case MethodEnrollSpeaker:
|
||||
if s.EnrollSpeakerFn != nil {
|
||||
var p EnrollSpeakerReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.EnrollSpeakerFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.EnrollSpeakerFn)
|
||||
case MethodCaptureStatus:
|
||||
return callDirectNoParams(ctx, req, s.CaptureStatusFn)
|
||||
case MethodListSpeakers:
|
||||
if s.ListSpeakersFn != nil {
|
||||
resp, err := s.ListSpeakersFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
case MethodForgetSpeaker:
|
||||
if s.ForgetSpeakerFn != nil {
|
||||
var p ForgetSpeakerReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ForgetSpeakerFn(ctx, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirectNoParams(ctx, req, s.ListSpeakersFn)
|
||||
case MethodModelStatus:
|
||||
if s.ModelStatusFn != nil {
|
||||
resp, err := s.ModelStatusFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return callDirectNoParams(ctx, req, s.ModelStatusFn)
|
||||
case MethodForgetSpeaker:
|
||||
return callDirectVoid(ctx, req, s.ForgetSpeakerFn)
|
||||
}
|
||||
|
||||
h, ok := methodTable[req.Method]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return h(ctx, api, req.Params)
|
||||
}
|
||||
|
||||
// callDirect runs a daemon-supplied handler that bypasses CoreAPI: unmarshal
|
||||
// the params, call it, marshal the reply. A nil handler is the capability being
|
||||
// unconfigured on this box, and the wire says so as an unknown method.
|
||||
func callDirect[P any, R any](ctx context.Context, req Request, fn func(context.Context, P) (R, error)) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
var p P
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := fn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(r), nil
|
||||
}
|
||||
|
||||
// callDirectNoParams is callDirect for a handler that reads no params. Like
|
||||
// withoutParams it never touches req.Params.
|
||||
func callDirectNoParams[R any](ctx context.Context, req Request, fn func(context.Context) (R, error)) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
r, err := fn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(r), nil
|
||||
}
|
||||
|
||||
// callDirectVoid is callDirect for a handler with nothing to report back. The
|
||||
// wire reply is always null.
|
||||
func callDirectVoid[P any](ctx context.Context, req Request, fn func(context.Context, P) error) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
var p P
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := fn(ctx, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), nil
|
||||
}
|
||||
|
||||
func unknownMethod(m Method) error {
|
||||
return fmt.Errorf("%w: %s", ErrUnknownMethod, m)
|
||||
}
|
||||
|
||||
func unmarshalParams(raw json.RawMessage, v any) error {
|
||||
if len(raw) == 0 {
|
||||
raw = []byte("null")
|
||||
|
||||
Reference in New Issue
Block a user