fix: Correctly get and set nanoCPUs for docker_container (#771)

This commit is contained in:
Martin 2025-08-13 16:33:16 +02:00 committed by GitHub
parent 78c64d5888
commit b53a6ba6e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 119 additions and 3 deletions

View file

@ -19,8 +19,23 @@ env:
GO_VERSION: "1.22"
jobs:
compile-fast:
runs-on: ubuntu-22.04
if: github.event.pull_request.draft == true
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Run GoReleaser (Fast)
uses: goreleaser/goreleaser-action@v5
with:
version: latest
args: release --config .goreleaser-fast.yml --rm-dist --skip-publish --snapshot --skip-sign
compile:
runs-on: ubuntu-22.04
if: github.event.pull_request.draft != true
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5

27
.goreleaser-fast.yml Normal file
View file

@ -0,0 +1,27 @@
# Fast build configuration for development/PR builds
# Only builds for the most common platforms to provide quick feedback
builds:
- env:
- CGO_ENABLED=0
mod_timestamp: "{{ .CommitTimestamp }}"
flags:
- -trimpath
ldflags:
- "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}"
goos:
- linux
- darwin
goarch:
- amd64
- arm64
binary: "{{ .ProjectName }}_v{{ .Version }}"
archives:
- format: zip
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
checksum:
name_template: "{{ .ProjectName }}_{{ .Version }}_SHA256SUMS"
algorithm: sha256
release:
disable: true
changelog:
skip: true

View file

@ -2,6 +2,7 @@ package provider
import (
"fmt"
"math/big"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@ -134,3 +135,23 @@ func containsIgnorableErrorMessage(errorMsg string, ignorableErrorMessages ...st
return false
}
// Convert nanoseconds to seconds as a decimal string
// e.g., 1,000,000,000 nanoseconds = 1.0 seconds
func nanoInt64ToDecimalString(nanoInt64 int64) string {
if nanoInt64 == 0 {
return "0"
}
rat := new(big.Rat).SetFrac64(nanoInt64, 1e9)
str := rat.FloatString(9)
// If we have a "round" value like 100000000, we want to return "1.0" instead of further processing
if strings.Count(str, "0") == 9 {
return rat.FloatString(1)
}
// Remove trailing zeros to ensure a clean representation without unnecessary decimal places
str = strings.TrimRight(str, "0")
return str
}

View file

@ -0,0 +1,23 @@
package provider
import "testing"
func TestNanoInt64ToDecimalString(t *testing.T) {
tests := []struct {
nanoInt64 int64
expected string
}{
{0, "0"},
{1000000000, "1.0"},
{1500000000, "1.5"},
{2000000000, "2.0"},
{2250000000, "2.25"},
}
for _, test := range tests {
result := nanoInt64ToDecimalString(test.nanoInt64)
if result != test.expected {
t.Errorf("Expected %s for %d, got %s", test.expected, test.nanoInt64, result)
}
}
}

View file

@ -324,8 +324,12 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData,
}
if v, ok := d.GetOk("cpus"); ok {
hostConfig.CPUPeriod = 100000
hostConfig.CPUQuota = int64(v.(float32) * 100000)
nanocpus, err := opts.ParseCPUs(v.(string))
if err != nil {
return diag.Errorf("Error setting cpus: %s", err)
}
hostConfig.NanoCPUs = nanocpus
if _, ook := d.GetOk("cpu_period"); ook {
log.Printf("[WARN] Value for cpus is set, ignore cpu_period setting")
@ -786,7 +790,7 @@ func resourceDockerContainerRead(ctx context.Context, d *schema.ResourceData, me
}
d.Set("shm_size", container.HostConfig.ShmSize/1024/1024)
if container.HostConfig.NanoCPUs > 0 {
d.Set("cpus", container.HostConfig.NanoCPUs)
d.Set("cpus", nanoInt64ToDecimalString(container.HostConfig.NanoCPUs))
}
d.Set("cpu_shares", container.HostConfig.CPUShares)
d.Set("cpu_set", container.HostConfig.CpusetCpus)

View file

@ -1450,6 +1450,23 @@ func TestAccDockerContainer_nameattrnochange(t *testing.T) {
},
})
}
func TestAccDockerContainer_cpus(t *testing.T) {
var c container.InspectResponse
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: loadTestConfiguration(t, RESOURCE, "docker_container", "testAccDockerContainerCpus"),
Check: resource.ComposeTestCheckFunc(
testAccContainerRunning("docker_container.foo", &c),
),
},
},
})
}
func TestAccDockerContainer_nostart(t *testing.T) {
var c container.InspectResponse
resource.Test(t, resource.TestCase{

View file

@ -0,0 +1,9 @@
resource "docker_image" "foo" {
name = "nginx:latest"
}
resource "docker_container" "foo" {
image = docker_image.foo.image_id
name = "nginx"
cpus = "1.5"
}