Skip to content

refactor: Return template version name in the workspace build API #5178

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 6 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions coderd/database/databasefake/databasefake.go
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,26 @@ func (q *fakeQuerier) GetTemplateVersionByID(_ context.Context, templateVersionI
return database.TemplateVersion{}, sql.ErrNoRows
}

func (q *fakeQuerier) GetTemplateVersionsByIDs(_ context.Context, ids []uuid.UUID) ([]database.TemplateVersion, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()

versions := make([]database.TemplateVersion, 0)
for _, version := range q.templateVersions {
for _, id := range ids {
if id == version.ID {
versions = append(versions, version)
break
}
}
}
if len(versions) == 0 {
return nil, sql.ErrNoRows
}

return versions, nil
}

func (q *fakeQuerier) GetTemplateVersionByJobID(_ context.Context, jobID uuid.UUID) (database.TemplateVersion, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
Expand Down
1 change: 1 addition & 0 deletions coderd/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions coderd/database/queries/templateversions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ FROM
WHERE
id = $1;

-- name: GetTemplateVersionsByIDs :many
SELECT
*
FROM
template_versions
WHERE
id = ANY(@ids :: uuid [ ]);

-- name: InsertTemplateVersion :one
INSERT INTO
template_versions (
Expand Down
101 changes: 65 additions & 36 deletions coderd/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) {
data.metadata,
data.agents,
data.apps,
data.templateVersions[0],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will panic if the length is not at least 1. That may be fine if we have the expectation that this is always true, but wanted to point it out.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we always expect to have at least 1. Thanks for pointing it out.

)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Expand Down Expand Up @@ -157,6 +158,7 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
data.metadata,
data.agents,
data.apps,
data.templateVersions,
)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Expand Down Expand Up @@ -239,6 +241,7 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ
data.metadata,
data.agents,
data.apps,
data.templateVersions[0],
)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Expand Down Expand Up @@ -517,6 +520,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
[]database.WorkspaceResourceMetadatum{},
[]database.WorkspaceAgent{},
[]database.WorkspaceApp{},
database.TemplateVersion{},
)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Expand Down Expand Up @@ -702,12 +706,13 @@ func (api *API) workspaceBuildState(rw http.ResponseWriter, r *http.Request) {
}

type workspaceBuildsData struct {
users []database.User
jobs []database.ProvisionerJob
resources []database.WorkspaceResource
metadata []database.WorkspaceResourceMetadatum
agents []database.WorkspaceAgent
apps []database.WorkspaceApp
users []database.User
jobs []database.ProvisionerJob
templateVersions []database.TemplateVersion
resources []database.WorkspaceResource
metadata []database.WorkspaceResourceMetadatum
agents []database.WorkspaceAgent
apps []database.WorkspaceApp
}

func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.Workspace, workspaceBuilds []database.WorkspaceBuild) (workspaceBuildsData, error) {
Expand All @@ -732,15 +737,25 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.W
return workspaceBuildsData{}, xerrors.Errorf("get provisioner jobs: %w", err)
}

templateVersionIDs := make([]uuid.UUID, 0, len(workspaceBuilds))
for _, build := range workspaceBuilds {
templateVersionIDs = append(templateVersionIDs, build.TemplateVersionID)
}
templateVersions, err := api.Database.GetTemplateVersionsByIDs(ctx, templateVersionIDs)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return workspaceBuildsData{}, xerrors.Errorf("get template versions: %w", err)
}

resources, err := api.Database.GetWorkspaceResourcesByJobIDs(ctx, jobIDs)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return workspaceBuildsData{}, xerrors.Errorf("get workspace resources by job: %w", err)
}

if len(resources) == 0 {
return workspaceBuildsData{
users: users,
jobs: jobs,
users: users,
jobs: jobs,
templateVersions: templateVersions,
}, nil
}

Expand All @@ -761,10 +776,11 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.W

if len(resources) == 0 {
return workspaceBuildsData{
users: users,
jobs: jobs,
resources: resources,
metadata: metadata,
users: users,
jobs: jobs,
templateVersions: templateVersions,
resources: resources,
metadata: metadata,
}, nil
}

Expand All @@ -779,12 +795,13 @@ func (api *API) workspaceBuildsData(ctx context.Context, workspaces []database.W
}

return workspaceBuildsData{
users: users,
jobs: jobs,
resources: resources,
metadata: metadata,
agents: agents,
apps: apps,
users: users,
jobs: jobs,
templateVersions: templateVersions,
resources: resources,
metadata: metadata,
agents: agents,
apps: apps,
}, nil
}

Expand All @@ -797,6 +814,7 @@ func (api *API) convertWorkspaceBuilds(
resourceMetadata []database.WorkspaceResourceMetadatum,
resourceAgents []database.WorkspaceAgent,
agentApps []database.WorkspaceApp,
templateVersions []database.TemplateVersion,
) ([]codersdk.WorkspaceBuild, error) {
workspaceByID := map[uuid.UUID]database.Workspace{}
for _, workspace := range workspaces {
Expand All @@ -806,6 +824,10 @@ func (api *API) convertWorkspaceBuilds(
for _, job := range jobs {
jobByID[job.ID] = job
}
templateVersionByID := map[uuid.UUID]database.TemplateVersion{}
for _, templateVersion := range templateVersions {
templateVersionByID[templateVersion.ID] = templateVersion
}

var apiBuilds []codersdk.WorkspaceBuild
for _, build := range workspaceBuilds {
Expand All @@ -817,6 +839,10 @@ func (api *API) convertWorkspaceBuilds(
if !exists {
return nil, xerrors.New("workspace not found")
}
templateVersion, exists := templateVersionByID[build.TemplateVersionID]
if !exists {
return nil, xerrors.New("template version not found")
}

apiBuild, err := api.convertWorkspaceBuild(
build,
Expand All @@ -827,6 +853,7 @@ func (api *API) convertWorkspaceBuilds(
resourceMetadata,
resourceAgents,
agentApps,
templateVersion,
)
if err != nil {
return nil, xerrors.Errorf("converting workspace build: %w", err)
Expand All @@ -847,6 +874,7 @@ func (api *API) convertWorkspaceBuild(
resourceMetadata []database.WorkspaceResourceMetadatum,
resourceAgents []database.WorkspaceAgent,
agentApps []database.WorkspaceApp,
templateVersion database.TemplateVersion,
) (codersdk.WorkspaceBuild, error) {
userByID := map[uuid.UUID]database.User{}
for _, user := range users {
Expand Down Expand Up @@ -897,24 +925,25 @@ func (api *API) convertWorkspaceBuild(
apiJob := convertProvisionerJob(job)
transition := codersdk.WorkspaceTransition(build.Transition)
return codersdk.WorkspaceBuild{
ID: build.ID,
CreatedAt: build.CreatedAt,
UpdatedAt: build.UpdatedAt,
WorkspaceOwnerID: workspace.OwnerID,
WorkspaceOwnerName: owner.Username,
WorkspaceID: build.WorkspaceID,
WorkspaceName: workspace.Name,
TemplateVersionID: build.TemplateVersionID,
BuildNumber: build.BuildNumber,
Transition: transition,
InitiatorID: build.InitiatorID,
InitiatorUsername: initiator.Username,
Job: apiJob,
Deadline: codersdk.NewNullTime(build.Deadline, !build.Deadline.IsZero()),
Reason: codersdk.BuildReason(build.Reason),
Resources: apiResources,
Status: convertWorkspaceStatus(apiJob.Status, transition),
DailyCost: build.DailyCost,
ID: build.ID,
CreatedAt: build.CreatedAt,
UpdatedAt: build.UpdatedAt,
WorkspaceOwnerID: workspace.OwnerID,
WorkspaceOwnerName: owner.Username,
WorkspaceID: build.WorkspaceID,
WorkspaceName: workspace.Name,
TemplateVersionID: build.TemplateVersionID,
TemplateVersionName: templateVersion.Name,
BuildNumber: build.BuildNumber,
Transition: transition,
InitiatorID: build.InitiatorID,
InitiatorUsername: initiator.Username,
Job: apiJob,
Deadline: codersdk.NewNullTime(build.Deadline, !build.Deadline.IsZero()),
Reason: codersdk.BuildReason(build.Reason),
Resources: apiResources,
Status: convertWorkspaceStatus(apiJob.Status, transition),
DailyCost: build.DailyCost,
}, nil
}

Expand Down
2 changes: 2 additions & 0 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
[]database.WorkspaceResourceMetadatum{},
[]database.WorkspaceAgent{},
[]database.WorkspaceApp{},
database.TemplateVersion{},
)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Expand Down Expand Up @@ -930,6 +931,7 @@ func (api *API) workspaceData(ctx context.Context, workspaces []database.Workspa
data.metadata,
data.agents,
data.apps,
data.templateVersions,
)
if err != nil {
return workspaceData{}, xerrors.Errorf("convert workspace builds: %w", err)
Expand Down
37 changes: 19 additions & 18 deletions codersdk/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,25 @@ const (
// WorkspaceBuild is an at-point representation of a workspace state.
// BuildNumbers start at 1 and increase by 1 for each subsequent build
type WorkspaceBuild struct {
ID uuid.UUID `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
WorkspaceID uuid.UUID `json:"workspace_id"`
WorkspaceName string `json:"workspace_name"`
WorkspaceOwnerID uuid.UUID `json:"workspace_owner_id"`
WorkspaceOwnerName string `json:"workspace_owner_name"`
TemplateVersionID uuid.UUID `json:"template_version_id"`
BuildNumber int32 `json:"build_number"`
Transition WorkspaceTransition `json:"transition"`
InitiatorID uuid.UUID `json:"initiator_id"`
InitiatorUsername string `json:"initiator_name"`
Job ProvisionerJob `json:"job"`
Reason BuildReason `db:"reason" json:"reason"`
Resources []WorkspaceResource `json:"resources"`
Deadline NullTime `json:"deadline,omitempty"`
Status WorkspaceStatus `json:"status"`
DailyCost int32 `json:"daily_cost"`
ID uuid.UUID `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
WorkspaceID uuid.UUID `json:"workspace_id"`
WorkspaceName string `json:"workspace_name"`
WorkspaceOwnerID uuid.UUID `json:"workspace_owner_id"`
WorkspaceOwnerName string `json:"workspace_owner_name"`
TemplateVersionID uuid.UUID `json:"template_version_id"`
TemplateVersionName string `json:"template_version_name"`
BuildNumber int32 `json:"build_number"`
Transition WorkspaceTransition `json:"transition"`
InitiatorID uuid.UUID `json:"initiator_id"`
InitiatorUsername string `json:"initiator_name"`
Job ProvisionerJob `json:"job"`
Reason BuildReason `db:"reason" json:"reason"`
Resources []WorkspaceResource `json:"resources"`
Deadline NullTime `json:"deadline,omitempty"`
Status WorkspaceStatus `json:"status"`
DailyCost int32 `json:"daily_cost"`
}

type WorkspaceResource struct {
Expand Down
1 change: 1 addition & 0 deletions site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ export interface WorkspaceBuild {
readonly workspace_owner_id: string
readonly workspace_owner_name: string
readonly template_version_id: string
readonly template_version_name: string
readonly build_number: number
readonly transition: WorkspaceTransition
readonly initiator_id: string
Expand Down
2 changes: 2 additions & 0 deletions site/src/testHelpers/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = {
initiator_name: MockUser.username,
job: MockProvisionerJob,
template_version_id: MockTemplateVersion.id,
template_version_name: MockTemplateVersion.name,
transition: "start",
updated_at: "2022-05-17T17:39:01.382927298Z",
workspace_name: "test-workspace",
Expand All @@ -424,6 +425,7 @@ export const MockFailedWorkspaceBuild = (
initiator_name: MockUser.username,
job: MockFailedProvisionerJob,
template_version_id: MockTemplateVersion.id,
template_version_name: MockTemplateVersion.name,
transition: transition,
updated_at: "2022-05-17T17:39:01.382927298Z",
workspace_name: "test-workspace",
Expand Down