mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat: add app status tracking to the backend (#17163)
This does ~95% of the backend work required to integrate the AI work. Most left to integrate from the tasks branch is just frontend, which will be a lot smaller I believe. The real difference between this branch and that one is the abstraction -- this now attaches statuses to apps, and returns the latest status reported as part of a workspace. This change enables us to have a similar UX to in the tasks branch, but for agents other than Claude Code as well. Any app can report status now.
This commit is contained in:
@ -84,6 +84,7 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) {
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.appStatuses,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions[0],
|
||||
@ -202,6 +203,7 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.appStatuses,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions,
|
||||
@ -292,6 +294,7 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ
|
||||
data.metadata,
|
||||
data.agents,
|
||||
data.apps,
|
||||
data.appStatuses,
|
||||
data.scripts,
|
||||
data.logSources,
|
||||
data.templateVersions[0],
|
||||
@ -432,6 +435,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
[]database.WorkspaceResourceMetadatum{},
|
||||
[]database.WorkspaceAgent{},
|
||||
[]database.WorkspaceApp{},
|
||||
[]database.WorkspaceAppStatus{},
|
||||
[]database.WorkspaceAgentScript{},
|
||||
[]database.WorkspaceAgentLogSource{},
|
||||
database.TemplateVersion{},
|
||||
@ -764,6 +768,7 @@ type workspaceBuildsData struct {
|
||||
metadata []database.WorkspaceResourceMetadatum
|
||||
agents []database.WorkspaceAgent
|
||||
apps []database.WorkspaceApp
|
||||
appStatuses []database.WorkspaceAppStatus
|
||||
scripts []database.WorkspaceAgentScript
|
||||
logSources []database.WorkspaceAgentLogSource
|
||||
provisionerDaemons []database.GetEligibleProvisionerDaemonsByProvisionerJobIDsRow
|
||||
@ -874,6 +879,17 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaceBuilds []datab
|
||||
return workspaceBuildsData{}, err
|
||||
}
|
||||
|
||||
appIDs := make([]uuid.UUID, 0)
|
||||
for _, app := range apps {
|
||||
appIDs = append(appIDs, app.ID)
|
||||
}
|
||||
|
||||
// nolint:gocritic // Getting workspace app statuses by app IDs is a system function.
|
||||
statuses, err := api.Database.GetWorkspaceAppStatusesByAppIDs(dbauthz.AsSystemRestricted(ctx), appIDs)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return workspaceBuildsData{}, xerrors.Errorf("get workspace app statuses: %w", err)
|
||||
}
|
||||
|
||||
return workspaceBuildsData{
|
||||
jobs: jobs,
|
||||
templateVersions: templateVersions,
|
||||
@ -881,6 +897,7 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaceBuilds []datab
|
||||
metadata: metadata,
|
||||
agents: agents,
|
||||
apps: apps,
|
||||
appStatuses: statuses,
|
||||
scripts: scripts,
|
||||
logSources: logSources,
|
||||
provisionerDaemons: pendingJobProvisioners,
|
||||
@ -895,6 +912,7 @@ func (api *API) convertWorkspaceBuilds(
|
||||
resourceMetadata []database.WorkspaceResourceMetadatum,
|
||||
resourceAgents []database.WorkspaceAgent,
|
||||
agentApps []database.WorkspaceApp,
|
||||
agentAppStatuses []database.WorkspaceAppStatus,
|
||||
agentScripts []database.WorkspaceAgentScript,
|
||||
agentLogSources []database.WorkspaceAgentLogSource,
|
||||
templateVersions []database.TemplateVersion,
|
||||
@ -937,6 +955,7 @@ func (api *API) convertWorkspaceBuilds(
|
||||
resourceMetadata,
|
||||
resourceAgents,
|
||||
agentApps,
|
||||
agentAppStatuses,
|
||||
agentScripts,
|
||||
agentLogSources,
|
||||
templateVersion,
|
||||
@ -960,6 +979,7 @@ func (api *API) convertWorkspaceBuild(
|
||||
resourceMetadata []database.WorkspaceResourceMetadatum,
|
||||
resourceAgents []database.WorkspaceAgent,
|
||||
agentApps []database.WorkspaceApp,
|
||||
agentAppStatuses []database.WorkspaceAppStatus,
|
||||
agentScripts []database.WorkspaceAgentScript,
|
||||
agentLogSources []database.WorkspaceAgentLogSource,
|
||||
templateVersion database.TemplateVersion,
|
||||
@ -997,6 +1017,10 @@ func (api *API) convertWorkspaceBuild(
|
||||
provisionerDaemonsForThisWorkspaceBuild = append(provisionerDaemonsForThisWorkspaceBuild, provisionerDaemon.ProvisionerDaemon)
|
||||
}
|
||||
matchedProvisioners := db2sdk.MatchedProvisioners(provisionerDaemonsForThisWorkspaceBuild, job.ProvisionerJob.CreatedAt, provisionerdserver.StaleInterval)
|
||||
statusesByAgentID := map[uuid.UUID][]database.WorkspaceAppStatus{}
|
||||
for _, status := range agentAppStatuses {
|
||||
statusesByAgentID[status.AgentID] = append(statusesByAgentID[status.AgentID], status)
|
||||
}
|
||||
|
||||
resources := resourcesByJobID[job.ProvisionerJob.ID]
|
||||
apiResources := make([]codersdk.WorkspaceResource, 0)
|
||||
@ -1018,9 +1042,10 @@ func (api *API) convertWorkspaceBuild(
|
||||
|
||||
apps := appsByAgentID[agent.ID]
|
||||
scripts := scriptsByAgentID[agent.ID]
|
||||
statuses := statusesByAgentID[agent.ID]
|
||||
logSources := logSourcesByAgentID[agent.ID]
|
||||
apiAgent, err := db2sdk.WorkspaceAgent(
|
||||
api.DERPMap(), *api.TailnetCoordinator.Load(), agent, db2sdk.Apps(apps, agent, workspace.OwnerUsername, workspace), convertScripts(scripts), convertLogSources(logSources), api.AgentInactiveDisconnectTimeout,
|
||||
api.DERPMap(), *api.TailnetCoordinator.Load(), agent, db2sdk.Apps(apps, statuses, agent, workspace.OwnerUsername, workspace), convertScripts(scripts), convertLogSources(logSources), api.AgentInactiveDisconnectTimeout,
|
||||
api.DeploymentValues.AgentFallbackTroubleshootingURL.String(),
|
||||
)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user