Skip to content

Commit c6fcd7e

Browse files
authored
fix: report failed CompletedJob (#8318)
1 parent 45eca67 commit c6fcd7e

8 files changed

+693
-1
lines changed

provisioner/terraform/resources.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
385385
resourceIcon := map[string]string{}
386386
resourceCost := map[string]int32{}
387387

388+
metadataTargetLabels := map[string]bool{}
388389
for _, resources := range tfResourcesByLabel {
389390
for _, resource := range resources {
390391
if resource.Type != "coder_metadata" {
@@ -396,7 +397,6 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
396397
if err != nil {
397398
return nil, xerrors.Errorf("decode metadata attributes: %w", err)
398399
}
399-
400400
resourceLabel := convertAddressToLabel(resource.Address)
401401

402402
var attachedNode *gographviz.Node
@@ -433,6 +433,11 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
433433
}
434434
targetLabel := attachedResource.Label
435435

436+
if metadataTargetLabels[targetLabel] {
437+
return nil, xerrors.Errorf("duplicate metadata resource: %s", targetLabel)
438+
}
439+
metadataTargetLabels[targetLabel] = true
440+
436441
resourceHidden[targetLabel] = attrs.Hide
437442
resourceIcon[targetLabel] = attrs.Icon
438443
resourceCost[targetLabel] = attrs.DailyCost

provisioner/terraform/resources_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,25 @@ func TestAppSlugValidation(t *testing.T) {
636636
require.ErrorContains(t, err, "duplicate app slug")
637637
}
638638

639+
func TestMetadataResourceDuplicate(t *testing.T) {
640+
t.Parallel()
641+
642+
// Load the multiple-apps state file and edit it.
643+
dir := filepath.Join("testdata", "resource-metadata-duplicate")
644+
tfPlanRaw, err := os.ReadFile(filepath.Join(dir, "resource-metadata-duplicate.tfplan.json"))
645+
require.NoError(t, err)
646+
var tfPlan tfjson.Plan
647+
err = json.Unmarshal(tfPlanRaw, &tfPlan)
648+
require.NoError(t, err)
649+
tfPlanGraph, err := os.ReadFile(filepath.Join(dir, "resource-metadata-duplicate.tfplan.dot"))
650+
require.NoError(t, err)
651+
652+
state, err := terraform.ConvertState([]*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph))
653+
require.Nil(t, state)
654+
require.Error(t, err)
655+
require.ErrorContains(t, err, "duplicate metadata resource: null_resource.about")
656+
}
657+
639658
func TestParameterValidation(t *testing.T) {
640659
t.Parallel()
641660

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "0.9.0"
6+
}
7+
}
8+
}
9+
10+
resource "coder_agent" "main" {
11+
os = "linux"
12+
arch = "amd64"
13+
metadata {
14+
key = "process_count"
15+
display_name = "Process Count"
16+
script = "ps -ef | wc -l"
17+
interval = 5
18+
timeout = 1
19+
}
20+
}
21+
22+
resource "null_resource" "about" {
23+
depends_on = [
24+
coder_agent.main,
25+
]
26+
}
27+
28+
resource "coder_metadata" "about_info" {
29+
resource_id = null_resource.about.id
30+
hide = true
31+
icon = "/icon/server.svg"
32+
daily_cost = 29
33+
item {
34+
key = "hello"
35+
value = "world"
36+
}
37+
item {
38+
key = "null"
39+
}
40+
}
41+
42+
resource "coder_metadata" "other_info" {
43+
resource_id = null_resource.about.id
44+
hide = true
45+
icon = "/icon/server.svg"
46+
daily_cost = 20
47+
item {
48+
key = "hello"
49+
value = "world"
50+
}
51+
}

provisioner/terraform/testdata/resource-metadata-duplicate/resource-metadata-duplicate.tfplan.dot

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

0 commit comments

Comments
 (0)