-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic blocks do not render all fields in content block. #9871
Comments
Another example in https://discuss.hashicorp.com/t/hcl2-temporary-iterator-variable-interpolation/20053/2 jobspecvariables {
netscaler_endpoints = ["1.2.3.4", "4.5.6.7", "8.9.10.11"]
}
job "netscaler-prometheus" {
datacenters = ["dc1"]
constraint {
attribute = "${attr.nomad.version}"
operator = "semver"
value = ">= 1.0.0"
}
dynamic "group" {
for_each = var.netscaler_endpoints
#iterator = ip
labels = ["prom-exporter-${group.value}"]
content {
network {
port "http" {}
dns {
servers = ["10.10.10.10"]
}
}
task "prom-exporter" {
driver = "docker"
config {
image = "quay.io/citrix/citrix-adc-metrics-exporter:1.4.6"
args = [
format("--target-nsip=%s", group.value),
"--port=${NOMAD_PORT_http}"
]
ports = ["http"]
}
service {
name = "prom-exporter"
port = "http"
check {
type = "http"
port = "http"
path = "/"
interval = "5s"
timeout = "3s"
}
}
resources {
cpu = 500
memory = 256
}
} # task ends here
} # content block ends here
} # dynamic block ends here
} # job ends here The results from that are interesting because the
|
I've put together a failing unit test that demonstrates the bug pretty clearly and hints that the problem is in how we handle blocks that are read as
From https://github.com/hashicorp/nomad/compare/b-9871-dynamic-blocks: failing unit testdiff --git a/jobspec2/parse_test.go b/jobspec2/parse_test.go
index e54d50cfa..5215eed02 100644
--- a/jobspec2/parse_test.go
+++ b/jobspec2/parse_test.go
@@ -7,6 +7,7 @@ import (
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/jobspec"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -277,21 +278,41 @@ job "example" {
}
func TestParseDynamic(t *testing.T) {
- hcl := `
-job "example" {
-
-dynamic "group" {
- for_each = ["groupA", "groupB", "groupC"]
- labels = [group.value]
+ hcl := `locals {
+ instances = [
+ { name = "groupA", idx = 1 },
+ { name = "groupB", idx = 2 },
+ { name = "groupC", idx = 3 },
+ ]
+}
- content {
- task "simple" {
- driver = "raw_exec"
+job "example" {
+ dynamic "group" {
+ for_each = local.instances
+ labels = [group.value.name]
+
+ content {
+ count = group.value.idx
+
+ task "simple" {
+ driver = "raw_exec"
+ config {
+ command = group.value.name
+ }
+ meta {
+ VERSION = group.value.idx
+ }
+ env {
+ ID = format("id:%s", group.value.idx)
+ }
+ resources {
+ cpu = group.value.idx
+ }
+ }
}
}
}
-}
`
out, err := ParseWithConfig(&ParseConfig{
Path: "input.hcl",
@@ -305,6 +326,12 @@ dynamic "group" {
require.Equal(t, "groupA", *out.TaskGroups[0].Name)
require.Equal(t, "groupB", *out.TaskGroups[1].Name)
require.Equal(t, "groupC", *out.TaskGroups[2].Name)
+ require.Equal(t, 1, *out.TaskGroups[0].Tasks[0].Resources.CPU)
+
+ // TODO: map[string]interface{} blocks all fail
+ assert.Equal(t, "groupA", out.TaskGroups[0].Tasks[0].Config["command"])
+ assert.Equal(t, "1", out.TaskGroups[0].Tasks[0].Meta["VERSION"])
+ assert.Equal(t, "id:1", out.TaskGroups[0].Tasks[0].Env["ID"])
}
func TestParse_InvalidScalingSyntax(t *testing.T) { |
A patch that seems to fix the problem in the HCL library (hat-tip to @notnoop who discovered this): diff --git a/vendor/github.com/hashicorp/hcl/v2/ext/dynblock/expand_body.go b/vendor/github.com/hashicorp/hcl/v2/ext/dynblock/expand_body.go
index 65a9eab2d..94dd35c45 100644
--- a/vendor/github.com/hashicorp/hcl/v2/ext/dynblock/expand_body.go
+++ b/vendor/github.com/hashicorp/hcl/v2/ext/dynblock/expand_body.go
@@ -251,10 +251,9 @@ func (b *expandBody) expandChild(child hcl.Body, i *iteration) hcl.Body {
}
func (b *expandBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
- // blocks aren't allowed in JustAttributes mode and this body can
- // only produce blocks, so we'll just pass straight through to our
- // underlying body here.
- return b.original.JustAttributes()
+ attrs, diags := b.original.JustAttributes()
+ attrs = b.prepareAttributes(attrs)
+ return attrs, diags
}
func (b *expandBody) MissingItemRange() hcl.Range { Turns out "this body can only produce blocks" is not true, at least for Nomad. We use a vendored branch of the |
Appreciate the update and the fix! |
Would it also be possible to use a variable in the task name? |
I'm going to lock this issue because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active issues. |
Nomad version
Verified in both versions below
Operating system and Environment details
Ubuntu 20.04.1 LTS
Issue
Dynamic blocks do not render all fields causing local HCL variables to be transmitted to the server.
Reproduction steps
Use a dynamic block for groups and attempt to use the value in a docker image.
Job file
Generated JSON sent to the server:
Nomad Server logs
The text was updated successfully, but these errors were encountered: