@@ -316,17 +316,8 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
316316 })
317317 if err == nil {
318318 // If the workspace already exists, don't allow creation.
319- template , err := api .Database .GetTemplateByID (r .Context (), workspace .TemplateID )
320- if err != nil {
321- httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
322- Message : fmt .Sprintf ("Find template for conflicting workspace name %q." , createWorkspace .Name ),
323- Detail : err .Error (),
324- })
325- return
326- }
327- // The template is fetched for clarity to the user on where the conflicting name may be.
328319 httpapi .Write (rw , http .StatusConflict , codersdk.Response {
329- Message : fmt .Sprintf ("Workspace %q already exists in the %q template ." , createWorkspace . Name , template .Name ),
320+ Message : fmt .Sprintf ("Workspace %q already exists." , createWorkspace .Name ),
330321 Validations : []codersdk.ValidationError {{
331322 Field : "name" ,
332323 Detail : "This value is already in use and should be unique." ,
@@ -479,6 +470,68 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
479470 findUser (apiKey .UserID , users ), findUser (workspaceBuild .InitiatorID , users )))
480471}
481472
473+ func (api * API ) patchWorkspace (rw http.ResponseWriter , r * http.Request ) {
474+ workspace := httpmw .WorkspaceParam (r )
475+ if ! api .Authorize (r , rbac .ActionUpdate , workspace ) {
476+ httpapi .ResourceNotFound (rw )
477+ return
478+ }
479+
480+ var req codersdk.UpdateWorkspaceRequest
481+ if ! httpapi .Read (rw , r , & req ) {
482+ return
483+ }
484+
485+ if req .Name == "" || req .Name == workspace .Name {
486+ // Nothing changed, optionally this could be an error.
487+ rw .WriteHeader (http .StatusNoContent )
488+ return
489+ }
490+ // The reason we double check here is in case more fields can be
491+ // patched in the future, it's enough if one changes.
492+ name := workspace .Name
493+ if req .Name != "" || req .Name != workspace .Name {
494+ name = req .Name
495+ }
496+
497+ _ , err := api .Database .UpdateWorkspace (r .Context (), database.UpdateWorkspaceParams {
498+ ID : workspace .ID ,
499+ Name : name ,
500+ })
501+ if err != nil {
502+ // The query protects against updating deleted workspaces and
503+ // the existence of the workspace is checked in the request,
504+ // if we get ErrNoRows it means the workspace was deleted.
505+ //
506+ // We could do this check earlier but we'd need to start a
507+ // transaction.
508+ if errors .Is (err , sql .ErrNoRows ) {
509+ httpapi .Write (rw , http .StatusMethodNotAllowed , codersdk.Response {
510+ Message : fmt .Sprintf ("Workspace %q is deleted and cannot be updated." , workspace .Name ),
511+ })
512+ return
513+ }
514+ // Check if the name was already in use.
515+ if database .IsUniqueViolation (err , database .UniqueWorkspacesOwnerIDLowerIdx ) {
516+ httpapi .Write (rw , http .StatusConflict , codersdk.Response {
517+ Message : fmt .Sprintf ("Workspace %q already exists." , req .Name ),
518+ Validations : []codersdk.ValidationError {{
519+ Field : "name" ,
520+ Detail : "This value is already in use and should be unique." ,
521+ }},
522+ })
523+ return
524+ }
525+ httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
526+ Message : "Internal error updating workspace." ,
527+ Detail : err .Error (),
528+ })
529+ return
530+ }
531+
532+ rw .WriteHeader (http .StatusNoContent )
533+ }
534+
482535func (api * API ) putWorkspaceAutostart (rw http.ResponseWriter , r * http.Request ) {
483536 workspace := httpmw .WorkspaceParam (r )
484537 if ! api .Authorize (r , rbac .ActionUpdate , workspace ) {
@@ -556,7 +609,6 @@ func (api *API) putWorkspaceTTL(rw http.ResponseWriter, r *http.Request) {
556609
557610 return nil
558611 })
559-
560612 if err != nil {
561613 resp := codersdk.Response {
562614 Message : "Error updating workspace time until shutdown." ,
@@ -656,7 +708,6 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) {
656708
657709 return nil
658710 })
659-
660711 if err != nil {
661712 api .Logger .Info (r .Context (), "extending workspace" , slog .Error (err ))
662713 }
@@ -861,6 +912,7 @@ func convertWorkspaces(ctx context.Context, db database.Store, workspaces []data
861912 }
862913 return apiWorkspaces , nil
863914}
915+
864916func convertWorkspace (
865917 workspace database.Workspace ,
866918 workspaceBuild database.WorkspaceBuild ,
0 commit comments