Skip to content

Commit

Permalink
Tanslate 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 <cbdoer23@g.holycross.edu>
  • Loading branch information
cdoern committed Apr 12, 2022
1 parent 4a53689 commit 4a08c9c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
13 changes: 13 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 All @@ -28,6 +30,16 @@ 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 := ""
if sg.ResourceLimits.Memory.Swap != nil {
s = strconv.Itoa(int(*sg.ResourceLimits.Memory.Swap))
}
specgenutil.LimitToSwap(sg.ResourceLimits.Memory, s, *sg.ResourceLimits.Memory.Limit)
}

warn, err := generate.CompleteSpec(r.Context(), runtime, &sg)
if err != nil {
utils.InternalServerError(w, err)
Expand All @@ -43,6 +55,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
28 changes: 28 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,34 @@ 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.40/containers/create?name=memory",
json={
"Image": "alpine:latest",
"Resource_Limits": {
"Memory":
{
"Limit": 536870912
},
"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(1073741824, out["HostConfig"]["MemorySwap"])
self.assertEqual(536870912, out["HostConfig"]["Memory"])


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

0 comments on commit 4a08c9c

Please sign in to comment.