Skip to content

Commit

Permalink
Translate Memory Limit to Swap in API
Browse files Browse the repository at this point in the history
in specgen, CLI path uses the given memory limit to define the swap value (if not already specified)
add a route to this piece of code from within the api handlers

resolves containers#13145

Signed-off-by: cdoern <[email protected]>
  • Loading branch information
cdoern authored and cdoern committed Apr 18, 2022
1 parent d6f47e6 commit be0da4a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
17 changes: 17 additions & 0 deletions pkg/api/handlers/libpod/containers_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import (
"context"
"encoding/json"
"net/http"
"strconv"

"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgen/generate"
"github.com/containers/podman/v4/pkg/specgenutil"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -39,6 +41,20 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
t := true
sg.Passwd = &t
}

// need to check for memory limit to adjust swap
if sg.ResourceLimits != nil && sg.ResourceLimits.Memory != nil {
s := ""
var l int64 = 0
if sg.ResourceLimits.Memory.Swap != nil {
s = strconv.Itoa(int(*sg.ResourceLimits.Memory.Swap))
}
if sg.ResourceLimits.Memory.Limit != nil {
l = *sg.ResourceLimits.Memory.Limit
}
specgenutil.LimitToSwap(sg.ResourceLimits.Memory, s, l)
}

warn, err := generate.CompleteSpec(r.Context(), runtime, &sg)
if err != nil {
utils.InternalServerError(w, err)
Expand All @@ -54,6 +70,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}

response := entities.ContainerCreateResponse{ID: ctr.ID(), Warnings: warn}
utils.WriteJSON(w, http.StatusCreated, response)
}
20 changes: 12 additions & 8 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
return io, nil
}

func LimitToSwap(memory *specs.LinuxMemory, swap string, ml int64) {
if ml > 0 {
memory.Limit = &ml
if swap == "" {
limit := 2 * ml
memory.Swap = &(limit)
}
}
}

func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) {
var err error
memory := &specs.LinuxMemory{}
Expand All @@ -135,14 +145,8 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOption
if err != nil {
return nil, errors.Wrapf(err, "invalid value for memory")
}
if ml > 0 {
memory.Limit = &ml
if c.MemorySwap == "" {
limit := 2 * ml
memory.Swap = &(limit)
}
hasLimits = true
}
LimitToSwap(memory, c.MemorySwap, ml)
hasLimits = true
}
if m := c.MemoryReservation; len(m) > 0 {
mr, err := units.RAMInBytes(m)
Expand Down
29 changes: 29 additions & 0 deletions test/apiv2/python/rest_api/test_v2_0_0_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,35 @@ def _impl(fifo, stop):
self.fail("Server failed to respond in 10s")
top.join()

def test_memory(self):
r = requests.post(
self.podman_url + "/v1.4.0/libpod/containers/create",
json={
"Name": "memory",
"Cmd": ["top"],
"Image": "alpine:latest",
"Resource_Limits": {
"Memory":{
"Limit": 1000,
},
"CPU":{
"Shares": 200,
},
},
},
)
self.assertEqual(r.status_code, 201, r.text)
payload = r.json()
container_id = payload["Id"]
self.assertIsNotNone(container_id)

r = requests.get(self.podman_url + f"/v1.40/containers/{container_id}/json")
self.assertEqual(r.status_code, 200, r.text)
self.assertId(r.content)
out = r.json()
self.assertEqual(2000, out["HostConfig"]["MemorySwap"])
self.assertEqual(1000, out["HostConfig"]["Memory"])


if __name__ == "__main__":
unittest.main()

0 comments on commit be0da4a

Please sign in to comment.