@@ -6,8 +6,10 @@ import (
66 "log/slog"
77 "net/http"
88 "os"
9+ "strings"
910
1011 "github.com/spf13/cobra"
12+ "golang.org/x/xerrors"
1113
1214 "github.com/coder/agentapi/lib/httpapi"
1315 "github.com/coder/agentapi/lib/logctx"
@@ -68,6 +70,48 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
6870 return agentType , nil
6971}
7072
73+ func runServer (ctx context.Context , logger * slog.Logger , argsToPass []string ) error {
74+ agent := argsToPass [0 ]
75+ agentType , err := parseAgentType (agent , agentTypeVar )
76+ if err != nil {
77+ return xerrors .Errorf ("failed to parse agent type: %w" , err )
78+ }
79+ var process * termexec.Process
80+ if printOpenAPI {
81+ process = nil
82+ } else {
83+ process , err = httpapi .SetupProcess (ctx , agent , argsToPass [1 :]... )
84+ if err != nil {
85+ return xerrors .Errorf ("failed to setup process: %w" , err )
86+ }
87+ }
88+ srv := httpapi .NewServer (ctx , agentType , process , port )
89+ if printOpenAPI {
90+ fmt .Println (srv .GetOpenAPI ())
91+ return nil
92+ }
93+ logger .Info ("Starting server on port" , "port" , port )
94+ processExitCh := make (chan error , 1 )
95+ go func () {
96+ defer close (processExitCh )
97+ if err := process .Wait (); err != nil {
98+ processExitCh <- xerrors .Errorf ("agent exited with error:\n ========\n %s\n ========\n : %w" , strings .TrimSpace (process .ReadScreen ()), err )
99+ }
100+ if err := srv .Stop (ctx ); err != nil {
101+ logger .Error ("Failed to stop server" , "error" , err )
102+ }
103+ }()
104+ if err := srv .Start (); err != nil && err != context .Canceled && err != http .ErrServerClosed {
105+ return xerrors .Errorf ("failed to start server: %w" , err )
106+ }
107+ select {
108+ case err := <- processExitCh :
109+ return xerrors .Errorf ("process exited with error: %w" , err )
110+ default :
111+ }
112+ return nil
113+ }
114+
71115var ServerCmd = & cobra.Command {
72116 Use : "server [agent]" ,
73117 Short : "Run the server" ,
@@ -76,39 +120,8 @@ var ServerCmd = &cobra.Command{
76120 Run : func (cmd * cobra.Command , args []string ) {
77121 logger := slog .New (slog .NewTextHandler (os .Stdout , nil ))
78122 ctx := logctx .WithLogger (context .Background (), logger )
79- argsToPass := cmd .Flags ().Args ()
80- agent := argsToPass [0 ]
81- agentType , err := parseAgentType (agent , agentTypeVar )
82- if err != nil {
83- logger .Error ("Failed to parse agent type" , "error" , err )
84- os .Exit (1 )
85- }
86- var process * termexec.Process
87- if printOpenAPI {
88- process = nil
89- } else {
90- process , err = httpapi .SetupProcess (ctx , agent , argsToPass [1 :]... )
91- if err != nil {
92- logger .Error ("Failed to setup process" , "error" , err )
93- os .Exit (1 )
94- }
95- }
96- srv := httpapi .NewServer (ctx , agentType , process , port )
97- if printOpenAPI {
98- fmt .Println (srv .GetOpenAPI ())
99- os .Exit (0 )
100- }
101- logger .Info ("Starting server on port" , "port" , port )
102- go func () {
103- if err := process .Wait (); err != nil {
104- logger .Error ("Process exited with error" , "error" , err )
105- }
106- if err := srv .Stop (ctx ); err != nil {
107- logger .Error ("Failed to stop server" , "error" , err )
108- }
109- }()
110- if err := srv .Start (); err != nil && err != context .Canceled && err != http .ErrServerClosed {
111- logger .Error ("Failed to start server" , "error" , err )
123+ if err := runServer (ctx , logger , cmd .Flags ().Args ()); err != nil {
124+ fmt .Fprintf (os .Stderr , "%+v\n " , err )
112125 os .Exit (1 )
113126 }
114127 },
0 commit comments