Skip to content

Commit 249df98

Browse files
Merge pull request #28969 from guillermodotn/main
kube: fix quantityToInt64 dropping scale for fractional BinarySI
2 parents 082408c + 5401c2d commit 249df98

3 files changed

Lines changed: 74 additions & 22 deletions

File tree

pkg/specgen/generate/kube/kube.go

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
294294
// but apply to the containers with the prefixed name
295295
s.SeccompProfilePath = opts.SeccompPaths.FindForContainer(opts.Container.Name)
296296

297-
err = setupContainerResources(s, opts.Container)
298-
if err != nil {
299-
return nil, fmt.Errorf("failed to configure container resources: %w", err)
300-
}
297+
setupContainerResources(s, opts.Container)
301298

302299
err = setupContainerDevices(s, opts.Container)
303300
if err != nil {
@@ -881,7 +878,7 @@ func makeHealthCheck(inCmd string, interval int32, retries int32, timeout int32,
881878
return &hc, nil
882879
}
883880

884-
func setupContainerResources(s *specgen.SpecGenerator, containerYAML v1.Container) error {
881+
func setupContainerResources(s *specgen.SpecGenerator, containerYAML v1.Container) {
885882
s.ResourceLimits = &spec.LinuxResources{}
886883
milliCPU := containerYAML.Resources.Limits.Cpu().MilliValue()
887884
if milliCPU > 0 {
@@ -892,15 +889,9 @@ func setupContainerResources(s *specgen.SpecGenerator, containerYAML v1.Containe
892889
}
893890
}
894891

895-
limit, err := quantityToInt64(containerYAML.Resources.Limits.Memory())
896-
if err != nil {
897-
return fmt.Errorf("failed to set memory limit: %w", err)
898-
}
892+
limit := quantityToInt64(containerYAML.Resources.Limits.Memory())
899893

900-
memoryRes, err := quantityToInt64(containerYAML.Resources.Requests.Memory())
901-
if err != nil {
902-
return fmt.Errorf("failed to set memory reservation: %w", err)
903-
}
894+
memoryRes := quantityToInt64(containerYAML.Resources.Requests.Memory())
904895

905896
if limit > 0 || memoryRes > 0 {
906897
s.ResourceLimits.Memory = &spec.LinuxMemory{}
@@ -913,8 +904,6 @@ func setupContainerResources(s *specgen.SpecGenerator, containerYAML v1.Containe
913904
if memoryRes > 0 {
914905
s.ResourceLimits.Memory.Reservation = &memoryRes
915906
}
916-
917-
return nil
918907
}
919908

920909
const PodmanDeviceResourcePrefix = "io.podman/device"
@@ -1036,16 +1025,14 @@ func setupSecurityContext(s *specgen.SpecGenerator, securityContext *v1.Security
10361025
}
10371026
}
10381027

1039-
func quantityToInt64(quantity *resource.Quantity) (int64, error) {
1028+
func quantityToInt64(quantity *resource.Quantity) int64 {
10401029
if i, ok := quantity.AsInt64(); ok {
1041-
return i, nil
1042-
}
1043-
1044-
if i, ok := quantity.AsDec().Unscaled(); ok {
1045-
return i, nil
1030+
return i
10461031
}
10471032

1048-
return 0, fmt.Errorf("quantity cannot be represented as int64: %v", quantity)
1033+
// Value() properly accounts for the decimal scale, unlike
1034+
// AsDec().Unscaled() which silently drops it.
1035+
return quantity.Value()
10491036
}
10501037

10511038
// read a k8s secret in JSON/YAML format from the secret manager

pkg/specgen/generate/kube/kube_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/stretchr/testify/assert"
99
v1 "go.podman.io/podman/v6/pkg/k8s.io/api/core/v1"
10+
"go.podman.io/podman/v6/pkg/k8s.io/apimachinery/pkg/api/resource"
1011
"go.podman.io/podman/v6/pkg/k8s.io/apimachinery/pkg/util/intstr"
1112
)
1213

@@ -137,3 +138,45 @@ func TestGetPortNumber(t *testing.T) {
137138
assert.NoError(t, e)
138139
assert.Equal(t, i, 6000)
139140
}
141+
142+
func TestQuantityToInt64(t *testing.T) {
143+
tests := []struct {
144+
name string
145+
input string
146+
expected int64
147+
}{
148+
{
149+
name: "integer BinarySI",
150+
input: "1536Mi",
151+
expected: 1536 * 1024 * 1024,
152+
},
153+
{
154+
name: "fractional BinarySI",
155+
input: "1.5Gi",
156+
expected: 1536 * 1024 * 1024,
157+
},
158+
{
159+
name: "larger fractional BinarySI",
160+
input: "2.5Gi",
161+
expected: 2560 * 1024 * 1024,
162+
},
163+
{
164+
name: "fractional DecimalSI",
165+
input: "1.5G",
166+
expected: 1500000000,
167+
},
168+
{
169+
name: "zero",
170+
input: "0",
171+
expected: 0,
172+
},
173+
}
174+
175+
for _, tt := range tests {
176+
t.Run(tt.name, func(t *testing.T) {
177+
q := resource.MustParse(tt.input)
178+
got := quantityToInt64(&q)
179+
assert.Equal(t, tt.expected, got)
180+
})
181+
}
182+
}

test/e2e/play_kube_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4274,6 +4274,28 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`)
42744274
Expect(inspect.OutputToString()).To(ContainSubstring("Memory: " + expectedMemoryLimit))
42754275
})
42764276

4277+
It("allows setting fractional BinarySI memory limits", func() {
4278+
SkipIfContainerized("Resource limits require a running systemd")
4279+
podmanTest.CgroupManager = "systemd"
4280+
4281+
pod := getPod(withCtr(getCtr(
4282+
withMemoryLimit("1.5Gi"),
4283+
withMemoryRequest("1.5Gi"),
4284+
)))
4285+
err := generateKubeYaml("pod", pod, kubeYaml)
4286+
Expect(err).ToNot(HaveOccurred())
4287+
4288+
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
4289+
kube.WaitWithDefaultTimeout()
4290+
Expect(kube).Should(Exit(0))
4291+
4292+
inspect := podmanTest.PodmanExitCleanly("inspect", getCtrNameInPod(pod), "--format", `
4293+
Memory: {{ .HostConfig.Memory }}
4294+
MemoryReservation: {{ .HostConfig.MemoryReservation }}`)
4295+
Expect(inspect.OutputToString()).To(ContainSubstring("Memory: 1610612736"))
4296+
Expect(inspect.OutputToString()).To(ContainSubstring("MemoryReservation: 1610612736"))
4297+
})
4298+
42774299
It("allows setting resource limits with --cpus 1", func() {
42784300
SkipIfContainerized("Resource limits require a running systemd")
42794301
SkipIfRootless("CPU limits require root")

0 commit comments

Comments
 (0)