From fc85b7eeef69da2c27bce004ae1e7af550e92672 Mon Sep 17 00:00:00 2001 From: Christoph Landsdorf Date: Mon, 31 Jul 2023 13:27:03 +0000 Subject: [PATCH] feat: support setting cpu shares --- docs/resources/container.md | 1 + .../provider/resource_docker_container.go | 6 ++++++ .../resource_docker_container_funcs.go | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/docs/resources/container.md b/docs/resources/container.md index e293ffcd7..60fd4af87 100644 --- a/docs/resources/container.md +++ b/docs/resources/container.md @@ -50,6 +50,7 @@ resource "docker_image" "ubuntu" { - `domainname` (String) Domain name of the container. - `entrypoint` (List of String) The command to use as the Entrypoint for the container. The Entrypoint allows you to configure a container to run as an executable. For example, to run `/usr/bin/myprogram` when starting a container, set the entrypoint to be `"/usr/bin/myprogra"]`. - `env` (Set of String) Environment variables to set in the form of `KEY=VALUE`, e.g. `DEBUG=0` +- `cpus` (String) Specify how much of the available CPU resources a container can use. e.g a value of 1.5 means the container is guaranteed at most one and a half of the CPUs - `gpus` (String) GPU devices to add to the container. Currently, only the value `all` is supported. Passing any other value will result in unexpected behavior. - `group_add` (Set of String) Additional groups for the container user - `healthcheck` (Block List, Max: 1) A test to perform to check that the container is healthy (see [below for nested schema](#nestedblock--healthcheck)) diff --git a/internal/provider/resource_docker_container.go b/internal/provider/resource_docker_container.go index 4682a35f7..85bc92b06 100644 --- a/internal/provider/resource_docker_container.go +++ b/internal/provider/resource_docker_container.go @@ -951,6 +951,12 @@ func resourceDockerContainer() *schema.Resource { Optional: true, ForceNew: true, }, + "cpus": { + Type: schema.TypeString, + Description: "Specify how much of the available CPU resources a container can use. e.g a value of 1.5 means the container is guaranteed at most one and a half of the CPUs", + Optional: true, + ForceNew: true, + }, "cgroupns_mode": { Type: schema.TypeString, Description: "Cgroup namespace mode to use for the container. Possible values are: `private`, `host`.", diff --git a/internal/provider/resource_docker_container_funcs.go b/internal/provider/resource_docker_container_funcs.go index 694c5208d..3a183312e 100644 --- a/internal/provider/resource_docker_container_funcs.go +++ b/internal/provider/resource_docker_container_funcs.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "log" + "math/big" "os" "strings" "time" @@ -311,6 +312,23 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData, hostConfig.ShmSize = int64(v.(int)) * 1024 * 1024 } + if v, ok := d.GetOk("cpus"); ok { + if client.ClientVersion() >= "1.28" { + cpu, ok := new(big.Rat).SetString(v.(string)) + if !ok { + return diag.Errorf("Error setting cpus: Failed to parse %v as a rational number", v.(string)) + } + nano := cpu.Mul(cpu, big.NewRat(1e9, 1)) + if !nano.IsInt() { + return diag.Errorf("Error setting cpus: value is too precise") + } + + hostConfig.NanoCPUs = nano.Num().Int64() + } else { + log.Printf("[WARN] Setting CPUs count/quota requires docker version 1.28 or higher") + } + } + if v, ok := d.GetOk("cpu_shares"); ok { hostConfig.CPUShares = int64(v.(int)) } @@ -726,6 +744,9 @@ func resourceDockerContainerRead(ctx context.Context, d *schema.ResourceData, me d.Set("memory_swap", container.HostConfig.MemorySwap) } d.Set("shm_size", container.HostConfig.ShmSize/1024/1024) + if container.HostConfig.NanoCPUs > 0 { + d.Set("cpus", container.HostConfig.NanoCPUs) + } d.Set("cpu_shares", container.HostConfig.CPUShares) d.Set("cpu_set", container.HostConfig.CpusetCpus) d.Set("log_driver", container.HostConfig.LogConfig.Type)