mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
It's possible for a workspace to become in an invalid state. This is something we'll detect for jobs, and allow monitoring of. These commands will allow admins to manually reconcile state.
126 lines
3.9 KiB
Go
126 lines
3.9 KiB
Go
package coderd
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/coder/coder/coderd/database"
|
|
"github.com/coder/coder/coderd/httpapi"
|
|
"github.com/coder/coder/coderd/httpmw"
|
|
"github.com/coder/coder/codersdk"
|
|
)
|
|
|
|
func (api *api) workspaceBuild(rw http.ResponseWriter, r *http.Request) {
|
|
workspaceBuild := httpmw.WorkspaceBuildParam(r)
|
|
job, err := api.Database.GetProvisionerJobByID(r.Context(), workspaceBuild.JobID)
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get provisioner job: %s", err),
|
|
})
|
|
return
|
|
}
|
|
|
|
httpapi.Write(rw, http.StatusOK, convertWorkspaceBuild(workspaceBuild, convertProvisionerJob(job)))
|
|
}
|
|
|
|
func (api *api) patchCancelWorkspaceBuild(rw http.ResponseWriter, r *http.Request) {
|
|
workspaceBuild := httpmw.WorkspaceBuildParam(r)
|
|
job, err := api.Database.GetProvisionerJobByID(r.Context(), workspaceBuild.JobID)
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get provisioner job: %s", err),
|
|
})
|
|
return
|
|
}
|
|
if job.CompletedAt.Valid {
|
|
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
|
Message: "Job has already completed!",
|
|
})
|
|
return
|
|
}
|
|
if job.CanceledAt.Valid {
|
|
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
|
Message: "Job has already been marked as canceled!",
|
|
})
|
|
return
|
|
}
|
|
err = api.Database.UpdateProvisionerJobWithCancelByID(r.Context(), database.UpdateProvisionerJobWithCancelByIDParams{
|
|
ID: job.ID,
|
|
CanceledAt: sql.NullTime{
|
|
Time: database.Now(),
|
|
Valid: true,
|
|
},
|
|
})
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("update provisioner job: %s", err),
|
|
})
|
|
return
|
|
}
|
|
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
|
Message: "Job has been marked as canceled...",
|
|
})
|
|
}
|
|
|
|
func (api *api) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) {
|
|
workspaceBuild := httpmw.WorkspaceBuildParam(r)
|
|
job, err := api.Database.GetProvisionerJobByID(r.Context(), workspaceBuild.JobID)
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get provisioner job: %s", err),
|
|
})
|
|
return
|
|
}
|
|
api.provisionerJobResources(rw, r, job)
|
|
}
|
|
|
|
func (api *api) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) {
|
|
workspaceBuild := httpmw.WorkspaceBuildParam(r)
|
|
job, err := api.Database.GetProvisionerJobByID(r.Context(), workspaceBuild.JobID)
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get provisioner job: %s", err),
|
|
})
|
|
return
|
|
}
|
|
api.provisionerJobLogs(rw, r, job)
|
|
}
|
|
|
|
func (*api) workspaceBuildState(rw http.ResponseWriter, r *http.Request) {
|
|
workspaceBuild := httpmw.WorkspaceBuildParam(r)
|
|
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
rw.WriteHeader(http.StatusOK)
|
|
_, _ = rw.Write(workspaceBuild.ProvisionerState)
|
|
}
|
|
|
|
func convertWorkspaceBuild(workspaceBuild database.WorkspaceBuild, job codersdk.ProvisionerJob) codersdk.WorkspaceBuild {
|
|
//nolint:unconvert
|
|
return codersdk.WorkspaceBuild{
|
|
ID: workspaceBuild.ID,
|
|
CreatedAt: workspaceBuild.CreatedAt,
|
|
UpdatedAt: workspaceBuild.UpdatedAt,
|
|
WorkspaceID: workspaceBuild.WorkspaceID,
|
|
TemplateVersionID: workspaceBuild.TemplateVersionID,
|
|
BeforeID: workspaceBuild.BeforeID.UUID,
|
|
AfterID: workspaceBuild.AfterID.UUID,
|
|
Name: workspaceBuild.Name,
|
|
Transition: workspaceBuild.Transition,
|
|
InitiatorID: workspaceBuild.InitiatorID,
|
|
Job: job,
|
|
}
|
|
}
|
|
|
|
func convertWorkspaceResource(resource database.WorkspaceResource, agents []codersdk.WorkspaceAgent) codersdk.WorkspaceResource {
|
|
return codersdk.WorkspaceResource{
|
|
ID: resource.ID,
|
|
CreatedAt: resource.CreatedAt,
|
|
JobID: resource.JobID,
|
|
Transition: resource.Transition,
|
|
Type: resource.Type,
|
|
Name: resource.Name,
|
|
Agents: agents,
|
|
}
|
|
}
|