From 15cf300c7dda99c2f499920318cea1b8dda33fb1 Mon Sep 17 00:00:00 2001 From: Donnie Adams Date: Sun, 2 Feb 2025 08:41:23 -0500 Subject: [PATCH] fix: run daemon tools as tools when referenced by other tools Daemon tools are usually started when other tools reference them by URL. However, they are not run like other tools. Therefore, their credentials are not processed as expected. This change will detect when tools reference daemon tools and ensure they are run like other tools. Signed-off-by: Donnie Adams --- pkg/engine/http.go | 26 ++++++++++++++++++-------- pkg/runner/runner.go | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/pkg/engine/http.go b/pkg/engine/http.go index 109db559..46b17d07 100644 --- a/pkg/engine/http.go +++ b/pkg/engine/http.go @@ -41,15 +41,11 @@ func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Too } if strings.HasSuffix(parsed.Hostname(), DaemonURLSuffix) { - referencedToolName := strings.TrimSuffix(parsed.Hostname(), DaemonURLSuffix) - referencedToolRefs, ok := tool.ToolMapping[referencedToolName] - if !ok || len(referencedToolRefs) != 1 { - return nil, fmt.Errorf("invalid reference [%s] to tool [%s] from [%s], missing \"tools: %s\" parameter", toolURL, referencedToolName, tool.Source, referencedToolName) - } - referencedTool, ok := prg.ToolSet[referencedToolRefs[0].ToolID] - if !ok { - return nil, fmt.Errorf("failed to find tool [%s] for [%s]", referencedToolName, parsed.Hostname()) + referencedTool, err := DaemonTool(prg, tool, parsed.Hostname()) + if err != nil { + return nil, err } + toolURL, err = e.startDaemon(referencedTool) if err != nil { return nil, err @@ -143,3 +139,17 @@ func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Too Result: &s, }, nil } + +func DaemonTool(prg *types.Program, tool types.Tool, daemonHost string) (types.Tool, error) { + referencedToolName := strings.TrimSuffix(daemonHost, DaemonURLSuffix) + referencedToolRefs, ok := tool.ToolMapping[referencedToolName] + if !ok || len(referencedToolRefs) != 1 { + return types.Tool{}, fmt.Errorf("invalid reference [%s] to tool [%s] from [%s], missing \"tools: %s\" parameter", daemonHost, referencedToolName, tool.Source, referencedToolName) + } + referencedTool, ok := prg.ToolSet[referencedToolRefs[0].ToolID] + if !ok { + return types.Tool{}, fmt.Errorf("failed to find tool [%s] for [%s]", referencedToolName, daemonHost) + } + + return referencedTool, nil +} diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index e2699cf6..a89944c0 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -350,6 +350,17 @@ func (r *Runner) start(callCtx engine.Context, state *State, monitor Monitor, en } } + if toolName, _, ok := strings.Cut(strings.TrimSpace(callCtx.Tool.Instructions), engine.DaemonURLSuffix); callCtx.Tool.IsHTTP() && ok { + referencedTool, err := engine.DaemonTool(callCtx.Program, callCtx.Tool, strings.TrimPrefix(strings.TrimPrefix(toolName, "#!http://"), "#!https://")) + if err != nil { + return nil, err + } + res, err := r.subCall(callCtx.Ctx, callCtx, monitor, env, referencedTool.ID, "{}", "", engine.NoCategory) + if err != nil { + return res, err + } + } + ret, err := e.Start(callCtx, input) if err != nil { return nil, err @@ -550,6 +561,17 @@ func (r *Runner) resume(callCtx engine.Context, monitor Monitor, env []string, s }) } + if toolName, _, ok := strings.Cut(strings.TrimSpace(callCtx.Tool.Instructions), engine.DaemonURLSuffix); callCtx.Tool.IsHTTP() && ok { + referencedTool, err := engine.DaemonTool(callCtx.Program, callCtx.Tool, strings.TrimPrefix(strings.TrimPrefix(toolName, "#!http://"), "#!https://")) + if err != nil { + return nil, err + } + res, err := r.subCall(callCtx.Ctx, callCtx, monitor, env, referencedTool.ID, "{}", "", engine.NoCategory) + if err != nil { + return res, err + } + } + nextContinuation, err := e.Continue(callCtx, state.Continuation.State, engineResults...) if err != nil { return nil, err