Skip to content

chore: watch workspace endpoint #4060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9c5c047
fix: match term color
f0ssel Aug 25, 2022
b3a171b
fmt:
f0ssel Aug 25, 2022
4e4a365
Add resources to workspace watch endpoint
f0ssel Aug 25, 2022
fae7dd2
better wrapped errors
f0ssel Aug 25, 2022
8e5cda7
support sse
f0ssel Aug 25, 2022
e82e201
correct schema
f0ssel Aug 25, 2022
8635e4a
share SetupSSE func
f0ssel Aug 25, 2022
784b361
fix events
f0ssel Sep 14, 2022
f32cddd
better err
f0ssel Sep 14, 2022
800e0a8
Fix casting
f0ssel Sep 14, 2022
efcbbab
fix test
f0ssel Sep 14, 2022
cf59581
remove dead code
f0ssel Sep 14, 2022
35f5894
panic on bad cast
f0ssel Sep 14, 2022
316f0ba
fix flusher
f0ssel Sep 14, 2022
953bb62
rename serversideeventtype
f0ssel Sep 14, 2022
e1f238c
formatting
f0ssel Sep 14, 2022
0ebb9aa
make gen
f0ssel Sep 14, 2022
ec97a71
fix var
f0ssel Sep 14, 2022
d717208
server-sent
f0ssel Sep 15, 2022
a1646b7
ts types
f0ssel Sep 15, 2022
5ca27e5
new convert workspace build
f0ssel Sep 16, 2022
19ff07e
consolidate
f0ssel Sep 16, 2022
13a6e3f
add workspace build converter
f0ssel Sep 16, 2022
03cc931
consolidate data collection
f0ssel Sep 16, 2022
7efae96
more consolidation
f0ssel Sep 16, 2022
4178f5a
split conversion and data fetching
f0ssel Sep 16, 2022
e7614dd
fix missing owner
f0ssel Sep 16, 2022
1f7440b
fix errors
f0ssel Sep 16, 2022
c38f55b
fix js tests
f0ssel Sep 16, 2022
eebd889
revert webpack changes
f0ssel Sep 16, 2022
86da07d
pr comments
f0ssel Sep 16, 2022
ef37372
make gen
f0ssel Sep 16, 2022
026dd2f
save some queries
f0ssel Sep 16, 2022
4e95a99
always return slive
f0ssel Sep 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
consolidate
  • Loading branch information
f0ssel committed Sep 16, 2022
commit 19ff07e77e8f88cd75f0a598857c92622a23fbba
45 changes: 0 additions & 45 deletions coderd/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,50 +806,6 @@ func (api *API) workspaceBuildState(rw http.ResponseWriter, r *http.Request) {
_, _ = rw.Write(workspaceBuild.ProvisionerState)
}

func convertWorkspaceBuild(
workspaceOwner *database.User,
buildInitiator *database.User,
workspace database.Workspace,
workspaceBuild database.WorkspaceBuild,
job database.ProvisionerJob,
) codersdk.WorkspaceBuild {
//nolint:unconvert
if workspace.ID != workspaceBuild.WorkspaceID {
panic("workspace and build do not match")
}

// Both owner and initiator should always be present. But from a static
// code analysis POV, these could be nil.
ownerName := "unknown"
if workspaceOwner != nil {
ownerName = workspaceOwner.Username
}

initiatorName := "unknown"
if workspaceOwner != nil {
initiatorName = buildInitiator.Username
}

return codersdk.WorkspaceBuild{
ID: workspaceBuild.ID,
CreatedAt: workspaceBuild.CreatedAt,
UpdatedAt: workspaceBuild.UpdatedAt,
WorkspaceOwnerID: workspace.OwnerID,
WorkspaceOwnerName: ownerName,
WorkspaceID: workspaceBuild.WorkspaceID,
WorkspaceName: workspace.Name,
TemplateVersionID: workspaceBuild.TemplateVersionID,
BuildNumber: workspaceBuild.BuildNumber,
Transition: codersdk.WorkspaceTransition(workspaceBuild.Transition),
InitiatorID: workspaceBuild.InitiatorID,
InitiatorUsername: initiatorName,
Job: convertProvisionerJob(job),
Deadline: codersdk.NewNullTime(workspaceBuild.Deadline, !workspaceBuild.Deadline.IsZero()),
Reason: codersdk.BuildReason(workspaceBuild.Reason),
Resources: []codersdk.WorkspaceResource{},
}
}

func (api *API) convertWorkspaceBuilds(
workspaceBuilds []database.WorkspaceBuild,
workspaces []database.Workspace,
Expand All @@ -860,7 +816,6 @@ func (api *API) convertWorkspaceBuilds(
resourceAgents []database.WorkspaceAgent,
agentApps []database.WorkspaceApp,
) ([]codersdk.WorkspaceBuild, error) {

workspaceByID := map[uuid.UUID]database.Workspace{}
for _, workspace := range workspaces {
workspaceByID[workspace.ID] = workspace
Expand Down
107 changes: 51 additions & 56 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,30 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
WorkspaceBuilds: []telemetry.WorkspaceBuild{telemetry.ConvertWorkspaceBuild(workspaceBuild)},
})

httpapi.Write(rw, http.StatusCreated, convertWorkspace(workspace, workspaceBuild, templateVersionJob, template,
findUser(apiKey.UserID, users), findUser(workspaceBuild.InitiatorID, users)))
wsb, err := api.convertWorkspaceBuilds(
[]database.WorkspaceBuild{workspaceBuild},
[]database.Workspace{workspace},
users,
[]database.ProvisionerJob{provisionerJob},
[]database.WorkspaceResource{},
[]database.WorkspaceResourceMetadatum{},
[]database.WorkspaceAgent{},
[]database.WorkspaceApp{},
)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error converting workspace build.",
Detail: err.Error(),
})
return
}

httpapi.Write(rw, http.StatusCreated, convertWorkspace(
workspace,
wsb[0],
template,
findUser(apiKey.UserID, users),
))
}

func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -810,6 +832,9 @@ func (api *API) convertWorkspaces(ctx context.Context, workspaces []database.Wor
users, err := api.Database.GetUsersByIDs(ctx, database.GetUsersByIDsParams{
IDs: userIDs,
})
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, xerrors.Errorf("get users: %w", err)
}

jobIDs := make([]uuid.UUID, 0, len(workspaceBuilds))
for _, build := range workspaceBuilds {
Expand Down Expand Up @@ -850,8 +875,22 @@ func (api *API) convertWorkspaces(ctx context.Context, workspaces []database.Wor
return nil, xerrors.Errorf("fetching workspace apps: %w", err)
}

buildByWorkspaceID := map[uuid.UUID]database.WorkspaceBuild{}
for _, workspaceBuild := range workspaceBuilds {
apiBuilds, err := api.convertWorkspaceBuilds(
workspaceBuilds,
workspaces,
users,
jobs,
workspaceResources,
resourceMetadata,
resourceAgents,
agentApps,
)
if err != nil {
return nil, xerrors.Errorf("converting workspace build: %w", err)
}

buildByWorkspaceID := map[uuid.UUID]codersdk.WorkspaceBuild{}
for _, workspaceBuild := range apiBuilds {
buildByWorkspaceID[workspaceBuild.WorkspaceID] = workspaceBuild
}
templateByID := map[uuid.UUID]database.Template{}
Expand All @@ -862,26 +901,6 @@ func (api *API) convertWorkspaces(ctx context.Context, workspaces []database.Wor
for _, user := range users {
userByID[user.ID] = user
}
jobByID := map[uuid.UUID]database.ProvisionerJob{}
for _, job := range jobs {
jobByID[job.ID] = job
}
resourcesByJobID := map[uuid.UUID][]database.WorkspaceResource{}
for _, resource := range workspaceResources {
resourcesByJobID[resource.JobID] = append(resourcesByJobID[resource.JobID], resource)
}
metadataByResourceID := map[uuid.UUID][]database.WorkspaceResourceMetadatum{}
for _, metadata := range resourceMetadata {
metadataByResourceID[metadata.WorkspaceResourceID] = append(metadataByResourceID[metadata.WorkspaceResourceID], metadata)
}
agentsByResourceID := map[uuid.UUID][]database.WorkspaceAgent{}
for _, agent := range resourceAgents {
agentsByResourceID[agent.ResourceID] = append(agentsByResourceID[agent.ResourceID], agent)
}
appsByAgentID := map[uuid.UUID][]database.WorkspaceApp{}
for _, app := range agentApps {
appsByAgentID[app.AgentID] = append(appsByAgentID[app.AgentID], app)
}

apiWorkspaces := make([]codersdk.Workspace, 0, len(workspaces))
for _, workspace := range workspaces {
Expand All @@ -893,39 +912,17 @@ func (api *API) convertWorkspaces(ctx context.Context, workspaces []database.Wor
if !exists {
return nil, xerrors.Errorf("template not found for workspace %q", workspace.Name)
}
job, exists := jobByID[build.JobID]
if !exists {
return nil, xerrors.Errorf("build job not found for workspace: %w", err)
}
owner, exists := userByID[workspace.OwnerID]
if !exists {
return nil, xerrors.Errorf("owner not found for workspace: %q", workspace.Name)
}
initiator, exists := userByID[build.InitiatorID]
if !exists {
return nil, xerrors.Errorf("build initiator not found for workspace: %q", workspace.Name)
}

resources := resourcesByJobID[job.ID]
var apiResources []codersdk.WorkspaceResource
for _, resource := range resources {
apiAgents := make([]codersdk.WorkspaceAgent, 0)
agents := agentsByResourceID[resource.ID]
for _, agent := range agents {
apps := appsByAgentID[agent.ID]
apiAgent, err := convertWorkspaceAgent(api.DERPMap, api.TailnetCoordinator, agent, convertApps(apps), api.AgentInactiveDisconnectTimeout)
if err != nil {
return nil, xerrors.Errorf("converting workspace agent: %w", err)
}
apiAgents = append(apiAgents, apiAgent)
}
metadata := metadataByResourceID[resource.ID]
apiResources = append(apiResources, convertWorkspaceResource(resource, apiAgents, metadata))
}

apiWorkspace := convertWorkspace(workspace, build, job, template, &owner, &initiator)
apiWorkspace.LatestBuild.Resources = apiResources
apiWorkspaces = append(apiWorkspaces, apiWorkspace)
apiWorkspaces = append(apiWorkspaces, convertWorkspace(
workspace,
build,
template,
&owner,
))
}
sort.Slice(apiWorkspaces, func(i, j int) bool {
iw := apiWorkspaces[i]
Expand All @@ -941,11 +938,9 @@ func (api *API) convertWorkspaces(ctx context.Context, workspaces []database.Wor

func convertWorkspace(
workspace database.Workspace,
workspaceBuild database.WorkspaceBuild,
job database.ProvisionerJob,
workspaceBuild codersdk.WorkspaceBuild,
template database.Template,
owner *database.User,
initiator *database.User,
) codersdk.Workspace {
var autostartSchedule *string
if workspace.AutostartSchedule.Valid {
Expand All @@ -960,7 +955,7 @@ func convertWorkspace(
OwnerID: workspace.OwnerID,
OwnerName: owner.Username,
TemplateID: workspace.TemplateID,
LatestBuild: convertWorkspaceBuild(owner, initiator, workspace, workspaceBuild, job),
LatestBuild: workspaceBuild,
TemplateName: template.Name,
TemplateIcon: template.Icon,
Outdated: workspaceBuild.TemplateVersionID.String() != template.ActiveVersionID.String(),
Expand Down