Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit798a4a4

Browse files
committed
feat(coderd): use task data model for send/logs
1 parentd4202a5 commit798a4a4

File tree

2 files changed

+69
-90
lines changed

2 files changed

+69
-90
lines changed

‎coderd/aitasks.go‎

Lines changed: 35 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"strings"
1212
"time"
1313

14-
"github.com/go-chi/chi/v5"
1514
"github.com/google/uuid"
1615

1716
"cdr.dev/slog"
@@ -768,15 +767,7 @@ func (api *API) taskDelete(rw http.ResponseWriter, r *http.Request) {
768767
// workspace and validate the sidebar app health.
769768
func (api*API)taskSend(rw http.ResponseWriter,r*http.Request) {
770769
ctx:=r.Context()
771-
772-
idStr:=chi.URLParam(r,"id")
773-
taskID,err:=uuid.Parse(idStr)
774-
iferr!=nil {
775-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
776-
Message:fmt.Sprintf("Invalid UUID %q for task ID.",idStr),
777-
})
778-
return
779-
}
770+
task:=httpmw.TaskParam(r)
780771

781772
varreq codersdk.TaskSendRequest
782773
if!httpapi.Read(ctx,rw,r,&req) {
@@ -789,7 +780,7 @@ func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
789780
return
790781
}
791782

792-
iferr=api.authAndDoWithTaskSidebarAppClient(r,taskID,func(ctx context.Context,client*http.Client,appURL*url.URL)error {
783+
iferr:=api.authAndDoWithTaskAppClient(r,task,func(ctx context.Context,client*http.Client,appURL*url.URL)error {
793784
agentAPIClient,err:=aiagentapi.NewClient(appURL.String(),aiagentapi.WithHTTPClient(client))
794785
iferr!=nil {
795786
returnhttperror.NewResponseError(http.StatusBadGateway, codersdk.Response{
@@ -848,18 +839,10 @@ func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
848839
// We enforce ApplicationConnect RBAC on the workspace and validate the sidebar app health.
849840
func (api*API)taskLogs(rw http.ResponseWriter,r*http.Request) {
850841
ctx:=r.Context()
851-
852-
idStr:=chi.URLParam(r,"id")
853-
taskID,err:=uuid.Parse(idStr)
854-
iferr!=nil {
855-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
856-
Message:fmt.Sprintf("Invalid UUID %q for task ID.",idStr),
857-
})
858-
return
859-
}
842+
task:=httpmw.TaskParam(r)
860843

861844
varout codersdk.TaskLogsResponse
862-
iferr:=api.authAndDoWithTaskSidebarAppClient(r,taskID,func(ctx context.Context,client*http.Client,appURL*url.URL)error {
845+
iferr:=api.authAndDoWithTaskAppClient(r,task,func(ctx context.Context,client*http.Client,appURL*url.URL)error {
863846
agentAPIClient,err:=aiagentapi.NewClient(appURL.String(),aiagentapi.WithHTTPClient(client))
864847
iferr!=nil {
865848
returnhttperror.NewResponseError(http.StatusBadGateway, codersdk.Response{
@@ -907,7 +890,7 @@ func (api *API) taskLogs(rw http.ResponseWriter, r *http.Request) {
907890
httpapi.Write(ctx,rw,http.StatusOK,out)
908891
}
909892

910-
//authAndDoWithTaskSidebarAppClient centralizes the shared logic to:
893+
//authAndDoWithTaskAppClient centralizes the shared logic to:
911894
//
912895
// - Fetch the task workspace
913896
// - Authorize ApplicationConnect on the workspace
@@ -916,15 +899,31 @@ func (api *API) taskLogs(rw http.ResponseWriter, r *http.Request) {
916899
//
917900
// The provided callback receives the context, an HTTP client that dials via the
918901
// agent, and the base app URL (as a value URL) to perform any request.
919-
func (api*API)authAndDoWithTaskSidebarAppClient(
902+
func (api*API)authAndDoWithTaskAppClient(
920903
r*http.Request,
921-
taskID uuid.UUID,
904+
task database.Task,
922905
dofunc(ctx context.Context,client*http.Client,appURL*url.URL)error,
923906
)error {
924907
ctx:=r.Context()
925908

926-
workspaceID:=taskID
927-
workspace,err:=api.Database.GetWorkspaceByID(ctx,workspaceID)
909+
iftask.Status!=database.TaskStatusActive {
910+
returnhttperror.NewResponseError(http.StatusBadRequest, codersdk.Response{
911+
Message:"Task status must be active.",
912+
Detail:fmt.Sprintf("Task status is %q, it must be %q to interact with the task.",task.Status,codersdk.TaskStatusActive),
913+
})
914+
}
915+
if!task.WorkspaceID.Valid {
916+
returnhttperror.NewResponseError(http.StatusBadRequest, codersdk.Response{
917+
Message:"Task does not have a workspace.",
918+
})
919+
}
920+
if!task.WorkspaceAppID.Valid {
921+
returnhttperror.NewResponseError(http.StatusBadRequest, codersdk.Response{
922+
Message:"Task does not have a workspace app.",
923+
})
924+
}
925+
926+
workspace,err:=api.Database.GetWorkspaceByID(ctx,task.WorkspaceID.UUID)
928927
iferr!=nil {
929928
ifhttpapi.Is404Error(err) {
930929
returnhttperror.ErrResourceNotFound
@@ -940,65 +939,30 @@ func (api *API) authAndDoWithTaskSidebarAppClient(
940939
returnhttperror.ErrResourceNotFound
941940
}
942941

943-
data,err:=api.workspaceData(ctx,[]database.Workspace{workspace})
942+
apps,err:=api.Database.GetWorkspaceAppsByAgentID(ctx,task.WorkspaceAgentID.UUID)
944943
iferr!=nil {
945944
returnhttperror.NewResponseError(http.StatusInternalServerError, codersdk.Response{
946945
Message:"Internal error fetching workspace resources.",
947946
Detail:err.Error(),
948947
})
949948
}
950-
iflen(data.builds)==0||len(data.templates)==0 {
951-
returnhttperror.ErrResourceNotFound
952-
}
953-
build:=data.builds[0]
954-
ifbuild.HasAITask==nil||!*build.HasAITask||build.AITaskSidebarAppID==nil||*build.AITaskSidebarAppID==uuid.Nil {
955-
returnhttperror.NewResponseError(http.StatusBadRequest, codersdk.Response{
956-
Message:"Task is not configured with a sidebar app.",
957-
})
958-
}
959949

960-
// Find the sidebar app details to get the URL and validate app health.
961-
sidebarAppID:=*build.AITaskSidebarAppID
962-
agentID,sidebarApp,ok:=func() (uuid.UUID, codersdk.WorkspaceApp,bool) {
963-
for_,res:=rangebuild.Resources {
964-
for_,agent:=rangeres.Agents {
965-
for_,app:=rangeagent.Apps {
966-
ifapp.ID==sidebarAppID {
967-
returnagent.ID,app,true
968-
}
969-
}
970-
}
950+
varapp*database.WorkspaceApp
951+
for_,a:=rangeapps {
952+
ifa.ID==task.WorkspaceAppID.UUID {
953+
app=&a
954+
break
971955
}
972-
returnuuid.Nil, codersdk.WorkspaceApp{},false
973-
}()
974-
if!ok {
975-
returnhttperror.NewResponseError(http.StatusBadRequest, codersdk.Response{
976-
Message:"Task sidebar app not found in latest build.",
977-
})
978-
}
979-
980-
// Return an informative error if the app isn't healthy rather than trying
981-
// and failing.
982-
switchsidebarApp.Health {
983-
casecodersdk.WorkspaceAppHealthDisabled:
984-
// No health check, pass through.
985-
casecodersdk.WorkspaceAppHealthInitializing:
986-
returnhttperror.NewResponseError(http.StatusServiceUnavailable, codersdk.Response{
987-
Message:"Task sidebar app is initializing. Try again shortly.",
988-
})
989-
casecodersdk.WorkspaceAppHealthUnhealthy:
990-
returnhttperror.NewResponseError(http.StatusServiceUnavailable, codersdk.Response{
991-
Message:"Task sidebar app is unhealthy.",
992-
})
993956
}
994957

995958
// Build the direct app URL and dial the agent.
996-
ifsidebarApp.URL=="" {
959+
appURL:=app.Url.String
960+
ifappURL=="" {
997961
returnhttperror.NewResponseError(http.StatusInternalServerError, codersdk.Response{
998962
Message:"Task sidebar app URL is not configured.",
999963
})
1000964
}
1001-
parsedURL,err:=url.Parse(sidebarApp.URL)
965+
parsedURL,err:=url.Parse(appURL)
1002966
iferr!=nil {
1003967
returnhttperror.NewResponseError(http.StatusInternalServerError, codersdk.Response{
1004968
Message:"Internal error parsing task app URL.",
@@ -1013,7 +977,7 @@ func (api *API) authAndDoWithTaskSidebarAppClient(
1013977

1014978
dialCtx,dialCancel:=context.WithTimeout(ctx,time.Second*30)
1015979
deferdialCancel()
1016-
agentConn,release,err:=api.agentProvider.AgentConn(dialCtx,agentID)
980+
agentConn,release,err:=api.agentProvider.AgentConn(dialCtx,task.WorkspaceAgentID.UUID)
1017981
iferr!=nil {
1018982
returnhttperror.NewResponseError(http.StatusBadGateway, codersdk.Response{
1019983
Message:"Failed to reach task app endpoint.",

‎coderd/aitasks_test.go‎

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ func TestTasks(t *testing.T) {
215215
Apps: []*proto.App{
216216
{
217217
Id:taskAppID.String(),
218-
Slug:"task-sidebar",
219-
DisplayName:"TaskSidebar",
218+
Slug:"task-app",
219+
DisplayName:"TaskApp",
220220
Url:opt.appURL,
221221
},
222222
},
@@ -226,9 +226,7 @@ func TestTasks(t *testing.T) {
226226
},
227227
AiTasks: []*proto.AITask{
228228
{
229-
SidebarApp:&proto.AITaskSidebarApp{
230-
Id:taskAppID.String(),
231-
},
229+
AppId:taskAppID.String(),
232230
},
233231
},
234232
},
@@ -472,7 +470,7 @@ func TestTasks(t *testing.T) {
472470
t.Run("IntegrationOK",func(t*testing.T) {
473471
t.Parallel()
474472

475-
client,_,api:=coderdtest.NewWithAPI(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
473+
client,db:=coderdtest.NewWithDatabase(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
476474
owner:=coderdtest.CreateFirstUser(t,client)
477475
userClient,_:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
478476

@@ -520,6 +518,14 @@ func TestTasks(t *testing.T) {
520518
})
521519
coderdtest.AwaitWorkspaceBuildJobCompleted(t,client,ws.LatestBuild.ID)
522520

521+
task:=dbgen.Task(t,db, database.TaskTable{
522+
OrganizationID:owner.OrganizationID,
523+
OwnerID:ws.OwnerID,
524+
TemplateVersionID:template.ActiveVersionID,
525+
WorkspaceID: uuid.NullUUID{UUID:ws.ID,Valid:true},
526+
Prompt:"send a message",
527+
})
528+
523529
// Start a fake agent so the workspace agent is connected before sending the message.
524530
agentClient:=agentsdk.New(client.URL,agentsdk.WithFixedToken(authToken))
525531
_=agenttest.New(t,client.URL,authToken,func(o*agent.Options) {
@@ -529,52 +535,61 @@ func TestTasks(t *testing.T) {
529535

530536
ctx:=testutil.Context(t,testutil.WaitMedium)
531537

532-
//Lookup thesidebar app ID.
538+
//Link theworkspace to the task.
533539
w,err:=client.Workspace(ctx,ws.ID)
534540
require.NoError(t,err)
535-
varsidebarAppID uuid.UUID
536541
for_,res:=rangew.LatestBuild.Resources {
537542
for_,ag:=rangeres.Agents {
538543
for_,app:=rangeag.Apps {
539-
ifapp.Slug=="task-sidebar" {
540-
sidebarAppID=app.ID
544+
ifapp.Slug=="task-app" {
545+
_,err=db.UpsertTaskWorkspaceApp(ctx, database.UpsertTaskWorkspaceAppParams{
546+
TaskID:task.ID,
547+
WorkspaceBuildNumber:w.LatestBuild.BuildNumber,
548+
WorkspaceAgentID: uuid.NullUUID{UUID:ag.ID,Valid:true},
549+
WorkspaceAppID: uuid.NullUUID{UUID:app.ID,Valid:true},
550+
})
551+
require.NoError(t,err)
541552
}
542553
}
543554
}
544555
}
545-
require.NotEqual(t,uuid.Nil,sidebarAppID)
556+
557+
// Update the task post-link.
558+
task,err=db.GetTaskByID(ctx,task.ID)
559+
require.NoError(t,err)
560+
require.True(t,task.WorkspaceAppID.Valid)
546561

547562
// Make the sidebar app unhealthy initially.
548-
err=api.Database.UpdateWorkspaceAppHealthByID(dbauthz.AsSystemRestricted(ctx), database.UpdateWorkspaceAppHealthByIDParams{
549-
ID:sidebarAppID,
563+
err=db.UpdateWorkspaceAppHealthByID(dbauthz.AsSystemRestricted(ctx), database.UpdateWorkspaceAppHealthByIDParams{
564+
ID:task.WorkspaceAppID.UUID,
550565
Health:database.WorkspaceAppHealthUnhealthy,
551566
})
552567
require.NoError(t,err)
553568

554569
exp:=codersdk.NewExperimentalClient(userClient)
555-
err=exp.TaskSend(ctx,"me",ws.ID, codersdk.TaskSendRequest{
570+
err=exp.TaskSend(ctx,"me",task.ID, codersdk.TaskSendRequest{
556571
Input:"Hello, Agent!",
557572
})
558573
require.Error(t,err,"wanted error due to unhealthy sidebar app")
559574

560575
// Make the sidebar app healthy.
561-
err=api.Database.UpdateWorkspaceAppHealthByID(dbauthz.AsSystemRestricted(ctx), database.UpdateWorkspaceAppHealthByIDParams{
562-
ID:sidebarAppID,
576+
err=db.UpdateWorkspaceAppHealthByID(dbauthz.AsSystemRestricted(ctx), database.UpdateWorkspaceAppHealthByIDParams{
577+
ID:task.WorkspaceAppID.UUID,
563578
Health:database.WorkspaceAppHealthHealthy,
564579
})
565580
require.NoError(t,err)
566581

567582
statusResponse=createStatusResponse("bad")
568583

569-
err=exp.TaskSend(ctx,"me",ws.ID, codersdk.TaskSendRequest{
584+
err=exp.TaskSend(ctx,"me",task.ID, codersdk.TaskSendRequest{
570585
Input:"Hello, Agent!",
571586
})
572587
require.Error(t,err,"wanted error due to bad status")
573588

574589
statusResponse=createStatusResponse("stable")
575590

576-
// Send task input to the tasks sidebar app and expect 204.e
577-
err=exp.TaskSend(ctx,"me",ws.ID, codersdk.TaskSendRequest{
591+
// Send task input to the tasks sidebar app and expect 204.
592+
err=exp.TaskSend(ctx,"me",task.ID, codersdk.TaskSendRequest{
578593
Input:"Hello, Agent!",
579594
})
580595
require.NoError(t,err,"wanted no error due to healthy sidebar app and stable status")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp