diff --git a/CHANGELOG.md b/CHANGELOG.md index 16e5a54d42d..db99c39eb30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ IMPROVEMENTS: * discovery: Support Consul gRPC health checks. [[GH-4251](https://github.com/hashicorp/nomad/issues/4251)] * driver/docker: Add progress monitoring and inactivity detection to docker image pulls [[GH-4192](https://github.com/hashicorp/nomad/issues/4192)] + * env: Default interpolation of optional meta fields of parameterized jobs to + an empty string rather than the field key. [[GH-3720](https://github.com/hashicorp/nomad/issues/3720)] ## 0.8.3 (April 27, 2018) diff --git a/client/driver/env/env.go b/client/driver/env/env.go index 923ebaa656d..19f93496741 100644 --- a/client/driver/env/env.go +++ b/client/driver/env/env.go @@ -397,7 +397,23 @@ func (b *Builder) setAlloc(alloc *structs.Allocation) *Builder { // Set meta combined := alloc.Job.CombinedTaskMeta(alloc.TaskGroup, b.taskName) - b.taskMeta = make(map[string]string, len(combined)*2) + // taskMetaSize is double to total meta keys to account for given and upper + // cased values + taskMetaSize := len(combined) * 2 + + // if job is parameterized initialize optional meta to empty strings + if alloc.Job.IsParameterized() { + b.taskMeta = make(map[string]string, + taskMetaSize+(len(alloc.Job.ParameterizedJob.MetaOptional)*2)) + + for _, k := range alloc.Job.ParameterizedJob.MetaOptional { + b.taskMeta[fmt.Sprintf("%s%s", MetaPrefix, strings.ToUpper(k))] = "" + b.taskMeta[fmt.Sprintf("%s%s", MetaPrefix, k)] = "" + } + } else { + b.taskMeta = make(map[string]string, taskMetaSize) + } + for k, v := range combined { b.taskMeta[fmt.Sprintf("%s%s", MetaPrefix, strings.ToUpper(k))] = v b.taskMeta[fmt.Sprintf("%s%s", MetaPrefix, k)] = v diff --git a/client/driver/env/env_test.go b/client/driver/env/env_test.go index 6ea4e72e60d..35a70329283 100644 --- a/client/driver/env/env_test.go +++ b/client/driver/env/env_test.go @@ -11,6 +11,7 @@ import ( cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" + "github.com/stretchr/testify/require" ) const ( @@ -372,3 +373,18 @@ func TestEnvironment_UpdateTask(t *testing.T) { t.Errorf("Expected NOMAD_META_taskmeta to be unset but found: %q", v) } } + +// TestEnvironment_InterpolateEmptyOptionalMeta asserts that in a parameterized +// job, if an optional meta field is not set, it will get interpolated as an +// empty string. +func TestEnvironment_InterpolateEmptyOptionalMeta(t *testing.T) { + a := mock.Alloc() + a.Job.ParameterizedJob = &structs.ParameterizedJobConfig{ + MetaOptional: []string{"metaopt1", "metaopt2"}, + } + task := a.Job.TaskGroups[0].Tasks[0] + task.Meta = map[string]string{"metaopt1": "metaopt1val"} + env := NewBuilder(mock.Node(), a, task, "global").Build() + require.Equal(t, "metaopt1val", env.ReplaceEnv("${NOMAD_META_metaopt1}")) + require.Empty(t, env.ReplaceEnv("${NOMAD_META_metaopt2}")) +}