Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf2d229e

Browse files
fix!: use devcontainer ID when rebuilding a devcontainer (#18604)
This PR replaces the use of the **container** ID with the**devcontainer** ID. This is a breaking change. This allows rebuilding adevcontainer when there is no valid container ID.
1 parenteca6381 commitf2d229e

File tree

11 files changed

+149
-161
lines changed

11 files changed

+149
-161
lines changed

‎agent/agentcontainers/api.go

Lines changed: 21 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ func (api *API) Routes() http.Handler {
496496
r.Get("/",api.handleList)
497497
// TODO(mafredri): Simplify this route as the previous /devcontainers
498498
// /-route was dropped. We can drop the /devcontainers prefix here too.
499-
r.Route("/devcontainers",func(r chi.Router) {
500-
r.Post("/container/{container}/recreate",api.handleDevcontainerRecreate)
499+
r.Route("/devcontainers/{devcontainer}",func(r chi.Router) {
500+
r.Post("/recreate",api.handleDevcontainerRecreate)
501501
})
502502

503503
returnr
@@ -861,68 +861,40 @@ func (api *API) getContainers() (codersdk.WorkspaceAgentListContainersResponse,
861861
// devcontainer by referencing the container.
862862
func (api*API)handleDevcontainerRecreate(w http.ResponseWriter,r*http.Request) {
863863
ctx:=r.Context()
864-
containerID:=chi.URLParam(r,"container")
864+
devcontainerID:=chi.URLParam(r,"devcontainer")
865865

866-
ifcontainerID=="" {
866+
ifdevcontainerID=="" {
867867
httpapi.Write(ctx,w,http.StatusBadRequest, codersdk.Response{
868-
Message:"Missing container ID or name",
869-
Detail:"Container ID or name is required to recreate a devcontainer.",
870-
})
871-
return
872-
}
873-
874-
containers,err:=api.getContainers()
875-
iferr!=nil {
876-
httpapi.Write(ctx,w,http.StatusInternalServerError, codersdk.Response{
877-
Message:"Could not list containers",
878-
Detail:err.Error(),
879-
})
880-
return
881-
}
882-
883-
containerIdx:=slices.IndexFunc(containers.Containers,func(c codersdk.WorkspaceAgentContainer)bool {returnc.Match(containerID) })
884-
ifcontainerIdx==-1 {
885-
httpapi.Write(ctx,w,http.StatusNotFound, codersdk.Response{
886-
Message:"Container not found",
887-
Detail:"Container ID or name not found in the list of containers.",
888-
})
889-
return
890-
}
891-
892-
container:=containers.Containers[containerIdx]
893-
workspaceFolder:=container.Labels[DevcontainerLocalFolderLabel]
894-
configPath:=container.Labels[DevcontainerConfigFileLabel]
895-
896-
// Workspace folder is required to recreate a container, we don't verify
897-
// the config path here because it's optional.
898-
ifworkspaceFolder=="" {
899-
httpapi.Write(ctx,w,http.StatusBadRequest, codersdk.Response{
900-
Message:"Missing workspace folder label",
901-
Detail:"The container is not a devcontainer, the container must have the workspace folder label to support recreation.",
868+
Message:"Missing devcontainer ID",
869+
Detail:"Devcontainer ID is required to recreate a devcontainer.",
902870
})
903871
return
904872
}
905873

906874
api.mu.Lock()
907875

908-
dc,ok:=api.knownDevcontainers[workspaceFolder]
909-
switch {
910-
case!ok:
876+
vardc codersdk.WorkspaceAgentDevcontainer
877+
for_,knownDC:=rangeapi.knownDevcontainers {
878+
ifknownDC.ID.String()==devcontainerID {
879+
dc=knownDC
880+
break
881+
}
882+
}
883+
ifdc.ID==uuid.Nil {
911884
api.mu.Unlock()
912885

913-
// This case should not happen if the container is a valid devcontainer.
914-
api.logger.Error(ctx,"devcontainer not found for workspace folder",slog.F("workspace_folder",workspaceFolder))
915-
httpapi.Write(ctx,w,http.StatusInternalServerError, codersdk.Response{
886+
httpapi.Write(ctx,w,http.StatusNotFound, codersdk.Response{
916887
Message:"Devcontainer not found.",
917-
Detail:fmt.Sprintf("Could not find devcontainerfor workspace folder: %q",workspaceFolder),
888+
Detail:fmt.Sprintf("Could not find devcontainerwith ID: %q",devcontainerID),
918889
})
919890
return
920-
casedc.Status==codersdk.WorkspaceAgentDevcontainerStatusStarting:
891+
}
892+
ifdc.Status==codersdk.WorkspaceAgentDevcontainerStatusStarting {
921893
api.mu.Unlock()
922894

923895
httpapi.Write(ctx,w,http.StatusConflict, codersdk.Response{
924896
Message:"Devcontainer recreation already in progress",
925-
Detail:fmt.Sprintf("Recreation forworkspace folder%q is already underway.",dc.WorkspaceFolder),
897+
Detail:fmt.Sprintf("Recreation fordevcontainer%q is already underway.",dc.Name),
926898
})
927899
return
928900
}
@@ -933,14 +905,14 @@ func (api *API) handleDevcontainerRecreate(w http.ResponseWriter, r *http.Reques
933905
dc.Container=nil
934906
api.knownDevcontainers[dc.WorkspaceFolder]=dc
935907
gofunc() {
936-
_=api.CreateDevcontainer(dc.WorkspaceFolder,configPath,WithRemoveExistingContainer())
908+
_=api.CreateDevcontainer(dc.WorkspaceFolder,dc.ConfigPath,WithRemoveExistingContainer())
937909
}()
938910

939911
api.mu.Unlock()
940912

941913
httpapi.Write(ctx,w,http.StatusAccepted, codersdk.Response{
942914
Message:"Devcontainer recreation initiated",
943-
Detail:fmt.Sprintf("Recreation process forworkspace folder%q has started.",dc.WorkspaceFolder),
915+
Detail:fmt.Sprintf("Recreation process fordevcontainer%q has started.",dc.Name),
944916
})
945917
}
946918

‎agent/agentcontainers/api_test.go

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -493,78 +493,77 @@ func TestAPI(t *testing.T) {
493493
t.Run("Recreate",func(t*testing.T) {
494494
t.Parallel()
495495

496-
validContainer:= codersdk.WorkspaceAgentContainer{
497-
ID:"container-id",
498-
FriendlyName:"container-name",
496+
devcontainerID1:=uuid.New()
497+
devcontainerID2:=uuid.New()
498+
workspaceFolder1:="/workspace/test1"
499+
workspaceFolder2:="/workspace/test2"
500+
configPath1:="/workspace/test1/.devcontainer/devcontainer.json"
501+
configPath2:="/workspace/test2/.devcontainer/devcontainer.json"
502+
503+
// Create a container that represents an existing devcontainer
504+
devContainer1:= codersdk.WorkspaceAgentContainer{
505+
ID:"container-1",
506+
FriendlyName:"test-container-1",
499507
Running:true,
500508
Labels:map[string]string{
501-
agentcontainers.DevcontainerLocalFolderLabel:"/workspaces",
502-
agentcontainers.DevcontainerConfigFileLabel:"/workspace/.devcontainer/devcontainer.json",
509+
agentcontainers.DevcontainerLocalFolderLabel:workspaceFolder1,
510+
agentcontainers.DevcontainerConfigFileLabel:configPath1,
503511
},
504512
}
505513

506-
missingFolderContainer:= codersdk.WorkspaceAgentContainer{
507-
ID:"missing-folder-container",
508-
FriendlyName:"missing-folder-container",
509-
Labels:map[string]string{},
514+
devContainer2:= codersdk.WorkspaceAgentContainer{
515+
ID:"container-2",
516+
FriendlyName:"test-container-2",
517+
Running:true,
518+
Labels:map[string]string{
519+
agentcontainers.DevcontainerLocalFolderLabel:workspaceFolder2,
520+
agentcontainers.DevcontainerConfigFileLabel:configPath2,
521+
},
510522
}
511523

512524
tests:= []struct {
513-
namestring
514-
containerIDstring
515-
lister*fakeContainerCLI
516-
devcontainerCLI*fakeDevcontainerCLI
517-
wantStatus []int
518-
wantBody []string
525+
namestring
526+
devcontainerIDstring
527+
setupDevcontainers []codersdk.WorkspaceAgentDevcontainer
528+
lister*fakeContainerCLI
529+
devcontainerCLI*fakeDevcontainerCLI
530+
wantStatus []int
531+
wantBody []string
519532
}{
520533
{
521-
name:"Missingcontainer ID",
522-
containerID:"",
534+
name:"Missingdevcontainer ID",
535+
devcontainerID:"",
523536
lister:&fakeContainerCLI{},
524537
devcontainerCLI:&fakeDevcontainerCLI{},
525538
wantStatus: []int{http.StatusBadRequest},
526-
wantBody: []string{"Missingcontainer ID or name"},
539+
wantBody: []string{"Missingdevcontainer ID"},
527540
},
528541
{
529-
name:"List error",
530-
containerID:"container-id",
542+
name:"Devcontainer not found",
543+
devcontainerID:uuid.NewString(),
531544
lister:&fakeContainerCLI{
532-
listErr:xerrors.New("list error"),
533-
},
534-
devcontainerCLI:&fakeDevcontainerCLI{},
535-
wantStatus: []int{http.StatusInternalServerError},
536-
wantBody: []string{"Could not list containers"},
537-
},
538-
{
539-
name:"Container not found",
540-
containerID:"nonexistent-container",
541-
lister:&fakeContainerCLI{
542-
containers: codersdk.WorkspaceAgentListContainersResponse{
543-
Containers: []codersdk.WorkspaceAgentContainer{validContainer},
544-
},
545+
arch:"<none>",// Unsupported architecture, don't inject subagent.
545546
},
546547
devcontainerCLI:&fakeDevcontainerCLI{},
547548
wantStatus: []int{http.StatusNotFound},
548-
wantBody: []string{"Container not found"},
549+
wantBody: []string{"Devcontainer not found"},
549550
},
550551
{
551-
name:"Missing workspace folder label",
552-
containerID:"missing-folder-container",
553-
lister:&fakeContainerCLI{
554-
containers: codersdk.WorkspaceAgentListContainersResponse{
555-
Containers: []codersdk.WorkspaceAgentContainer{missingFolderContainer},
552+
name:"Devcontainer CLI error",
553+
devcontainerID:devcontainerID1.String(),
554+
setupDevcontainers: []codersdk.WorkspaceAgentDevcontainer{
555+
{
556+
ID:devcontainerID1,
557+
Name:"test-devcontainer-1",
558+
WorkspaceFolder:workspaceFolder1,
559+
ConfigPath:configPath1,
560+
Status:codersdk.WorkspaceAgentDevcontainerStatusRunning,
561+
Container:&devContainer1,
556562
},
557563
},
558-
devcontainerCLI:&fakeDevcontainerCLI{},
559-
wantStatus: []int{http.StatusBadRequest},
560-
wantBody: []string{"Missing workspace folder label"},
561-
},
562-
{
563-
name:"Devcontainer CLI error",
564-
containerID:"container-id",
565564
lister:&fakeContainerCLI{
566565
containers: codersdk.WorkspaceAgentListContainersResponse{
567-
Containers: []codersdk.WorkspaceAgentContainer{validContainer},
566+
Containers: []codersdk.WorkspaceAgentContainer{devContainer1},
568567
},
569568
arch:"<none>",// Unsupported architecture, don't inject subagent.
570569
},
@@ -575,11 +574,21 @@ func TestAPI(t *testing.T) {
575574
wantBody: []string{"Devcontainer recreation initiated","Devcontainer recreation already in progress"},
576575
},
577576
{
578-
name:"OK",
579-
containerID:"container-id",
577+
name:"OK",
578+
devcontainerID:devcontainerID2.String(),
579+
setupDevcontainers: []codersdk.WorkspaceAgentDevcontainer{
580+
{
581+
ID:devcontainerID2,
582+
Name:"test-devcontainer-2",
583+
WorkspaceFolder:workspaceFolder2,
584+
ConfigPath:configPath2,
585+
Status:codersdk.WorkspaceAgentDevcontainerStatusRunning,
586+
Container:&devContainer2,
587+
},
588+
},
580589
lister:&fakeContainerCLI{
581590
containers: codersdk.WorkspaceAgentListContainersResponse{
582-
Containers: []codersdk.WorkspaceAgentContainer{validContainer},
591+
Containers: []codersdk.WorkspaceAgentContainer{devContainer2},
583592
},
584593
arch:"<none>",// Unsupported architecture, don't inject subagent.
585594
},
@@ -608,13 +617,16 @@ func TestAPI(t *testing.T) {
608617

609618
// Setup router with the handler under test.
610619
r:=chi.NewRouter()
620+
611621
api:=agentcontainers.NewAPI(
612622
logger,
613623
agentcontainers.WithClock(mClock),
614624
agentcontainers.WithContainerCLI(tt.lister),
615625
agentcontainers.WithDevcontainerCLI(tt.devcontainerCLI),
616626
agentcontainers.WithWatcher(watcher.NewNoop()),
627+
agentcontainers.WithDevcontainers(tt.setupDevcontainers,nil),
617628
)
629+
618630
api.Init()
619631
deferapi.Close()
620632
r.Mount("/",api.Routes())
@@ -626,7 +638,7 @@ func TestAPI(t *testing.T) {
626638

627639
fori:=rangett.wantStatus {
628640
// Simulate HTTP request to the recreate endpoint.
629-
req:=httptest.NewRequest(http.MethodPost,"/devcontainers/container/"+tt.containerID+"/recreate",nil).
641+
req:=httptest.NewRequest(http.MethodPost,"/devcontainers/"+tt.devcontainerID+"/recreate",nil).
630642
WithContext(ctx)
631643
rec:=httptest.NewRecorder()
632644
r.ServeHTTP(rec,req)

‎coderd/apidoc/docs.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/coderd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,7 @@ func New(options *Options) *API {
13141314
r.Get("/listening-ports",api.workspaceAgentListeningPorts)
13151315
r.Get("/connection",api.workspaceAgentConnection)
13161316
r.Get("/containers",api.workspaceAgentListContainers)
1317-
r.Post("/containers/devcontainers/container/{container}/recreate",api.workspaceAgentRecreateDevcontainer)
1317+
r.Post("/containers/devcontainers/{devcontainer}/recreate",api.workspaceAgentRecreateDevcontainer)
13181318
r.Get("/coordinate",api.workspaceAgentClientCoordinate)
13191319

13201320
// PTY is part of workspaceAppServer.

‎coderd/workspaceagents.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -905,19 +905,19 @@ func (api *API) workspaceAgentListContainers(rw http.ResponseWriter, r *http.Req
905905
// @Tags Agents
906906
// @Produce json
907907
// @Param workspaceagent path string true "Workspace agent ID" format(uuid)
908-
// @Paramcontainer path string true "Container ID or name"
908+
// @Paramdevcontainer path string true "Devcontainer ID"
909909
// @Success 202 {object} codersdk.Response
910-
// @Router /workspaceagents/{workspaceagent}/containers/devcontainers/container/{container}/recreate [post]
910+
// @Router /workspaceagents/{workspaceagent}/containers/devcontainers/{devcontainer}/recreate [post]
911911
func (api*API)workspaceAgentRecreateDevcontainer(rw http.ResponseWriter,r*http.Request) {
912912
ctx:=r.Context()
913913
workspaceAgent:=httpmw.WorkspaceAgentParam(r)
914914

915-
container:=chi.URLParam(r,"container")
916-
ifcontainer=="" {
915+
devcontainer:=chi.URLParam(r,"devcontainer")
916+
ifdevcontainer=="" {
917917
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
918-
Message:"Container ID or name is required.",
918+
Message:"Devcontainer ID is required.",
919919
Validations: []codersdk.ValidationError{
920-
{Field:"container",Detail:"Container ID or name is required."},
920+
{Field:"devcontainer",Detail:"Devcontainer ID is required."},
921921
},
922922
})
923923
return
@@ -961,7 +961,7 @@ func (api *API) workspaceAgentRecreateDevcontainer(rw http.ResponseWriter, r *ht
961961
}
962962
deferrelease()
963963

964-
m,err:=agentConn.RecreateDevcontainer(ctx,container)
964+
m,err:=agentConn.RecreateDevcontainer(ctx,devcontainer)
965965
iferr!=nil {
966966
iferrors.Is(err,context.Canceled) {
967967
httpapi.Write(ctx,rw,http.StatusRequestTimeout, codersdk.Response{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp