hashicorp / nomad

Nomad is an easy-to-use, flexible, and performant workload orchestrator that can deploy a mix of microservice, batch, containerized, and non-containerized applications. Nomad is easy to operate and scale and has native Consul and Vault integrations.
https://www.nomadproject.io/
Other
14.94k stars 1.96k forks source link

Cannot use variables/interpolation with configurations expecting integers #5531

Open james-masson opened 5 years ago

james-masson commented 5 years ago

Nomad version

Nomad v0.8.7 (21a2d93eecf018ad2209a5eab6aae6c359267933+CHANGES)

Operating system and Environment details

Gentoo Linux + Docker 18.09.2

Issue

Cannot use variables/interpolation with configurations expecting integers.

I'm configuring a docker job to populate the shm_size config which expects an integer.

If submit the interpolation with surrounding quotes "${NOMAD_META_SHM_SIZE}",

I get

* field "shm_size" with input "${NOMAD_META_SHM_SIZE}" doesn't seem to be of type integer
* group "cluster" -> task "runme" -> config: 1 error(s) occurred:

If I submit the interpolation without surrounding quotes ${NOMAD_META_SHM_SIZE}

I get a syntax error

eg.

Error getting job struct: Error parsing job file from job.nomad: error parsing: At 24:20: illegal char

In terraform, this interpolated change of type seems to be handled internally, but here it seems a hard requirement of the shm_size configuration.

Job file (if appropriate)

job "stuff" {
  type = "service"
  datacenters = ["dc1"]
  meta {
    SHM_SIZE = 2000000000
  }
  group "cluster" {
    task "runme" {
      driver = "docker"
      config {
        shm_size = "${NOMAD_META_SHM_SIZE}"
        image = "image"
      }
    }
  }
}
cgbaker commented 5 years ago

Thanks for reporting this, @james-masson . I'll look into this right away.

james-masson commented 5 years ago

Thanks! - while I remember, it also makes no sense that it requires an integer, because docker also accepts strings with units - ie.

     --shm-size=""
          Size of /dev/shm. The format is <number><unit>.
          number must be greater than 0.  Unit is optional and can be b (bytes), k (kilobytes), m(megabytes), or g (gigabytes).
          If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses 64m.
cgbaker commented 5 years ago

So, the first issue is that anything in the meta stanza for the job will be converted into strings: https://www.nomadproject.io/docs/job-specification/meta.html#meta-parameters So even if the task config interpolation supported non-strings, this field would still be a string.

I'll bring this up with the team and we can think about how this works into existing plans around HCL/HCL2 in the job spec.

james-masson commented 5 years ago

A nice fix for this particular occurrence would be to accept strings for docker -> shm_size

With docker-cli and docker-compose, not sure if the string/unit conversion is done on the client or the docker-daemon - but the standard seems to be to accept a string,

cgbaker commented 5 years ago

Agreed.

grahamsk commented 5 years ago

Hi all - Any update on this one? I'm looking at interpolating cpu/memory values in nomad templates.

wiedenmeier commented 5 years ago

+1 on this. It would be really nice to be able to specify memory as a meta parameter to a job.

I definitely see the issue with all parameters being strings, maybe a workaround would be attempting to parse string values as integers for fields that require ints?

cgbaker commented 5 years ago

no update, folks. this is in our internal tracker as well. thanks for pinging on this issue, will update here when this is resolved.

tommyalatalo commented 4 years ago

I also stumbled upon this just now, trying to set log rotation integers as meta values and using them doesn't work because of the strings issue here.

Hoping this gets updated soon so that integers get better support.

chancez commented 4 years ago

Ouch, i was hoping to do something like this in one of our tasks to give the a job all the resources on a particular node:

      resources {
        cpu = "${attr.cpu.totalcompute}"
        memory = "${attr.memory.totalbytes / 1024 / 1024}"
      }
cgbaker commented 3 years ago

@chancez, I'm not sure how to go about that. the attr block is known after scheduling, while the resources block must be known before scheduling (because it's part of the scheduling consideration).

For the rest, HCL2 support means there's probably a number of different ways to achieve this (I'm personally still learning my way around HCL2). Here's one way:

variable "shm_size" {
  type = number
  default = "12345678"
}
job "example" {
  type = "service"
  datacenters = ["dc1"]
  meta {
    SHM_SIZE = "${var.shm_size}"
  }
  group "cluster" {
    task "runme" {
      driver = "docker"
      config {
        shm_size = var.shm_size
        image = "nginx"
      }
    }
  }
}

This makes it into the API and through to docker:

$ nomad job inspect example | jq '.Job.Meta,.Job.TaskGroups[0].Tasks[0].Config'
{
  "SHM_SIZE": "12345678"
}
{
  "image": "nginx",
  "shm_size": 12345678
}

$ docker inspect 079b | jq '.[0].HostConfig.ShmSize'
12345678

edit: updated this with a nicer version after some experimentation

chomey commented 1 year ago

Bumping this, any update on integer interpolation? Would love to use dynamic job resource sizing (cpu/memory)

sadjy commented 1 year ago

Is there any update of this topic? I'm also interested in dynamic job resource sizing.

prabirshrestha commented 11 months ago

Hitting the same issue when trying to set port via nomadVars.

static = {{ with nomadVar "nomad/jobs/tarefik" }}{{ .port }}{{ end }}
automatumkilian commented 4 months ago

This would be THE essential feature for us! We start dockers with quite different memory usage from 10 GB to 100 GB and restricting them all to 100 GB would be as inefficient as we are already today. Since this ticket is already 5 years old, is there any progress to pass over some litte INT in the meantime? This would really help us.