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

Commit07d4171

Browse files
authored
fix(provisioner): handle multiple agents, apps, scripts and envs (#13741)
1 parentf6639b7 commit07d4171

File tree

17 files changed

+2786
-4
lines changed

17 files changed

+2786
-4
lines changed

‎provisioner/terraform/resources.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,11 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
427427
for_,agents:=rangeresourceAgents {
428428
for_,agent:=rangeagents {
429429
// Find agents with the matching ID and associate them!
430-
ifagent.Id!=attrs.AgentID {
430+
431+
if!dependsOnAgent(graph,agent,attrs.AgentID,resource) {
431432
continue
432433
}
434+
433435
agent.Apps=append(agent.Apps,&proto.App{
434436
Slug:attrs.Slug,
435437
DisplayName:attrs.DisplayName,
@@ -461,7 +463,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
461463
for_,agents:=rangeresourceAgents {
462464
for_,agent:=rangeagents {
463465
// Find agents with the matching ID and associate them!
464-
ifagent.Id!=attrs.AgentID {
466+
if!dependsOnAgent(graph,agent,attrs.AgentID,resource) {
465467
continue
466468
}
467469
agent.ExtraEnvs=append(agent.ExtraEnvs,&proto.Env{
@@ -487,7 +489,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
487489
for_,agents:=rangeresourceAgents {
488490
for_,agent:=rangeagents {
489491
// Find agents with the matching ID and associate them!
490-
ifagent.Id!=attrs.AgentID {
492+
if!dependsOnAgent(graph,agent,attrs.AgentID,resource) {
491493
continue
492494
}
493495
agent.Scripts=append(agent.Scripts,&proto.Script{
@@ -748,6 +750,30 @@ func convertAddressToLabel(address string) string {
748750
returncut
749751
}
750752

753+
funcdependsOnAgent(graph*gographviz.Graph,agent*proto.Agent,resourceAgentIDstring,resource*tfjson.StateResource)bool {
754+
// Plan: we need to find if there is edge between the agent and the resource.
755+
ifagent.Id==""&&resourceAgentID=="" {
756+
resourceNodeSuffix:=fmt.Sprintf(`] %s.%s (expand)"`,resource.Type,resource.Name)
757+
agentNodeSuffix:=fmt.Sprintf(`] coder_agent.%s (expand)"`,agent.Name)
758+
759+
// Traverse the graph to check if the coder_<resource_type> depends on coder_agent.
760+
for_,dst:=rangegraph.Edges.SrcToDsts {
761+
for_,edges:=rangedst {
762+
for_,edge:=rangeedges {
763+
ifstrings.HasSuffix(edge.Src,resourceNodeSuffix)&&
764+
strings.HasSuffix(edge.Dst,agentNodeSuffix) {
765+
returntrue
766+
}
767+
}
768+
}
769+
}
770+
returnfalse
771+
}
772+
773+
// Provision: agent ID and child resource ID are present
774+
returnagent.Id==resourceAgentID
775+
}
776+
751777
typegraphResourcestruct {
752778
Labelstring
753779
Depthuint

‎provisioner/terraform/resources_test.go

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,150 @@ func TestConvertResources(t *testing.T) {
219219
}},
220220
}},
221221
},
222+
"multiple-agents-multiple-apps": {
223+
resources: []*proto.Resource{{
224+
Name:"dev1",
225+
Type:"null_resource",
226+
Agents: []*proto.Agent{{
227+
Name:"dev1",
228+
OperatingSystem:"linux",
229+
Architecture:"amd64",
230+
Apps: []*proto.App{
231+
{
232+
Slug:"app1",
233+
DisplayName:"app1",
234+
// Subdomain defaults to false if unspecified.
235+
Subdomain:false,
236+
},
237+
{
238+
Slug:"app2",
239+
DisplayName:"app2",
240+
Subdomain:true,
241+
Healthcheck:&proto.Healthcheck{
242+
Url:"http://localhost:13337/healthz",
243+
Interval:5,
244+
Threshold:6,
245+
},
246+
},
247+
},
248+
Auth:&proto.Agent_Token{},
249+
ConnectionTimeoutSeconds:120,
250+
DisplayApps:&displayApps,
251+
}},
252+
}, {
253+
Name:"dev2",
254+
Type:"null_resource",
255+
Agents: []*proto.Agent{{
256+
Name:"dev2",
257+
OperatingSystem:"linux",
258+
Architecture:"amd64",
259+
Apps: []*proto.App{
260+
{
261+
Slug:"app3",
262+
DisplayName:"app3",
263+
Subdomain:false,
264+
},
265+
},
266+
Auth:&proto.Agent_Token{},
267+
ConnectionTimeoutSeconds:120,
268+
DisplayApps:&displayApps,
269+
}},
270+
}},
271+
},
272+
"multiple-agents-multiple-envs": {
273+
resources: []*proto.Resource{{
274+
Name:"dev1",
275+
Type:"null_resource",
276+
Agents: []*proto.Agent{{
277+
Name:"dev1",
278+
OperatingSystem:"linux",
279+
Architecture:"amd64",
280+
ExtraEnvs: []*proto.Env{
281+
{
282+
Name:"ENV_1",
283+
Value:"Env 1",
284+
},
285+
{
286+
Name:"ENV_2",
287+
Value:"Env 2",
288+
},
289+
},
290+
Auth:&proto.Agent_Token{},
291+
ConnectionTimeoutSeconds:120,
292+
DisplayApps:&displayApps,
293+
}},
294+
}, {
295+
Name:"dev2",
296+
Type:"null_resource",
297+
Agents: []*proto.Agent{{
298+
Name:"dev2",
299+
OperatingSystem:"linux",
300+
Architecture:"amd64",
301+
ExtraEnvs: []*proto.Env{
302+
{
303+
Name:"ENV_3",
304+
Value:"Env 3",
305+
},
306+
},
307+
Auth:&proto.Agent_Token{},
308+
ConnectionTimeoutSeconds:120,
309+
DisplayApps:&displayApps,
310+
}},
311+
}, {
312+
Name:"env1",
313+
Type:"coder_env",
314+
}, {
315+
Name:"env2",
316+
Type:"coder_env",
317+
}, {
318+
Name:"env3",
319+
Type:"coder_env",
320+
}},
321+
},
322+
"multiple-agents-multiple-scripts": {
323+
resources: []*proto.Resource{{
324+
Name:"dev1",
325+
Type:"null_resource",
326+
Agents: []*proto.Agent{{
327+
Name:"dev1",
328+
OperatingSystem:"linux",
329+
Architecture:"amd64",
330+
Scripts: []*proto.Script{
331+
{
332+
DisplayName:"Foobar Script 1",
333+
Script:"echo foobar 1",
334+
RunOnStart:true,
335+
},
336+
{
337+
DisplayName:"Foobar Script 2",
338+
Script:"echo foobar 2",
339+
RunOnStart:true,
340+
},
341+
},
342+
Auth:&proto.Agent_Token{},
343+
ConnectionTimeoutSeconds:120,
344+
DisplayApps:&displayApps,
345+
}},
346+
}, {
347+
Name:"dev2",
348+
Type:"null_resource",
349+
Agents: []*proto.Agent{{
350+
Name:"dev2",
351+
OperatingSystem:"linux",
352+
Architecture:"amd64",
353+
Scripts: []*proto.Script{
354+
{
355+
DisplayName:"Foobar Script 3",
356+
Script:"echo foobar 3",
357+
RunOnStart:true,
358+
},
359+
},
360+
Auth:&proto.Agent_Token{},
361+
ConnectionTimeoutSeconds:120,
362+
DisplayApps:&displayApps,
363+
}},
364+
}},
365+
},
222366
// Tests fetching metadata about workspace resources.
223367
"resource-metadata": {
224368
resources: []*proto.Resource{{
@@ -565,6 +709,18 @@ func TestConvertResources(t *testing.T) {
565709
sortResources(state.Resources)
566710
sortExternalAuthProviders(state.ExternalAuthProviders)
567711

712+
for_,resource:=rangestate.Resources {
713+
for_,agent:=rangeresource.Agents {
714+
agent.Id=""
715+
ifagent.GetToken()!="" {
716+
agent.Auth=&proto.Agent_Token{}
717+
}
718+
ifagent.GetInstanceId()!="" {
719+
agent.Auth=&proto.Agent_InstanceId{}
720+
}
721+
}
722+
}
723+
568724
expectedNoMetadata:=make([]*proto.Resource,0)
569725
for_,resource:=rangeexpected.resources {
570726
resourceCopy,_:=protobuf.Clone(resource).(*proto.Resource)
@@ -642,7 +798,6 @@ func TestConvertResources(t *testing.T) {
642798
varresourcesMap []map[string]interface{}
643799
err=json.Unmarshal(data,&resourcesMap)
644800
require.NoError(t,err)
645-
646801
require.Equal(t,expectedMap,resourcesMap)
647802
require.ElementsMatch(t,expected.externalAuthProviders,state.ExternalAuthProviders)
648803
})
@@ -911,6 +1066,12 @@ func sortResources(resources []*proto.Resource) {
9111066
sort.Slice(agent.Apps,func(i,jint)bool {
9121067
returnagent.Apps[i].Slug<agent.Apps[j].Slug
9131068
})
1069+
sort.Slice(agent.ExtraEnvs,func(i,jint)bool {
1070+
returnagent.ExtraEnvs[i].Name<agent.ExtraEnvs[j].Name
1071+
})
1072+
sort.Slice(agent.Scripts,func(i,jint)bool {
1073+
returnagent.Scripts[i].DisplayName<agent.Scripts[j].DisplayName
1074+
})
9141075
}
9151076
sort.Slice(resource.Agents,func(i,jint)bool {
9161077
returnresource.Agents[i].Name<resource.Agents[j].Name
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
terraform {
2+
required_providers {
3+
coder={
4+
source="coder/coder"
5+
version="0.22.0"
6+
}
7+
}
8+
}
9+
10+
resource"coder_agent""dev1" {
11+
os="linux"
12+
arch="amd64"
13+
}
14+
15+
resource"coder_agent""dev2" {
16+
os="linux"
17+
arch="amd64"
18+
}
19+
20+
# app1 is for testing subdomain default.
21+
resource"coder_app""app1" {
22+
agent_id=coder_agent.dev1.id
23+
slug="app1"
24+
# subdomain should default to false.
25+
# subdomain = false
26+
}
27+
28+
# app2 tests that subdomaincan be true, and that healthchecks work.
29+
resource"coder_app""app2" {
30+
agent_id=coder_agent.dev1.id
31+
slug="app2"
32+
subdomain=true
33+
healthcheck {
34+
url="http://localhost:13337/healthz"
35+
interval=5
36+
threshold=6
37+
}
38+
}
39+
40+
# app3 tests that subdomain can explicitly be false.
41+
resource"coder_app""app3" {
42+
agent_id=coder_agent.dev2.id
43+
slug="app3"
44+
subdomain=false
45+
}
46+
47+
resource"null_resource""dev1" {
48+
depends_on=[
49+
coder_agent.dev1
50+
]
51+
}
52+
53+
resource"null_resource""dev2" {
54+
depends_on=[
55+
coder_agent.dev2
56+
]
57+
}

‎provisioner/terraform/testdata/multiple-agents-multiple-apps/multiple-agents-multiple-apps.tfplan.dot

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp