Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/handlers/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ func (h *handler) create(w http.ResponseWriter, r *http.Request) {
CPUShares: uint64(req.HostConfig.CPUShares), // CPU shares (relative weight)
CPUQuota: CpuQuota, // CPUQuota limits the CPU CFS (Completely Fair Scheduler) quota
CPUPeriod: uint64(req.HostConfig.CPUPeriod),
CPURealtimePeriod: uint64(req.HostConfig.CPURealtimePeriod),
CPURealtimeRuntime: uint64(req.HostConfig.CPURealtimeRuntime),
Memory: memory, // memory limit (in bytes)
MemorySwap: memorySwap, // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemoryReservation: memoryReservation, // Memory soft limit (in bytes)
Expand Down
25 changes: 24 additions & 1 deletion api/handlers/container/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
"github.com/containerd/nerdctl/v2/pkg/config"
"github.com/containerd/nerdctl/v2/pkg/defaults"
"github.com/docker/go-connections/nat"
"go.uber.org/mock/gomock"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"go.uber.org/mock/gomock"

"github.com/runfinch/finch-daemon/mocks/mocks_container"
"github.com/runfinch/finch-daemon/mocks/mocks_logger"
Expand Down Expand Up @@ -437,6 +437,29 @@ var _ = Describe("Container Create API ", func() {
Expect(rr.Body).Should(MatchJSON(jsonResponse))
})

It("should set both CPURealtimePeriod and CPURealtimeRuntime create options for resources", func() {
body := []byte(`{
"Image": "test-image",
"HostConfig": {
"CpuRealtimePeriod": 1000000,
"CpuRealtimeRuntime": 950000
}
}`)
req, _ := http.NewRequest(http.MethodPost, "/containers/create", bytes.NewReader(body))

// expected create options
createOpt.CPURealtimePeriod = 1000000
createOpt.CPURealtimeRuntime = 950000

service.EXPECT().Create(gomock.Any(), "test-image", nil, equalTo(createOpt), equalTo(netOpt)).Return(
cid, nil)

// handler should return success message with 201 status code.
h.create(rr, req)
Expect(rr).Should(HaveHTTPStatus(http.StatusCreated))
Expect(rr.Body).Should(MatchJSON(jsonResponse))
})

It("should set MemoryReservation, MemorySwap and MemorySwappiness create options for resources", func() {
body := []byte(`{
"Image": "test-image",
Expand Down
20 changes: 11 additions & 9 deletions api/types/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,17 @@ type ContainerHostConfig struct {
// TODO: Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)

// Contains container's resources (cgroups, ulimits)
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
CPUSetCPUs string `json:"CpusetCpus"` // CPUSetCPUs specifies the CPUs in which to allow execution (0-3, 0,1)
CPUSetMems string `json:"CpusetMems"` // CPUSetMems specifies the memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
Memory int64 // Memory limit (in bytes)
MemoryReservation int64 // MemoryReservation specifies the memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness int64 // MemorySwappiness64 specifies the tune container memory swappiness (0 to 100) (default -1)
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
CPUSetCPUs string `json:"CpusetCpus"` // CPUSetCPUs specifies the CPUs in which to allow execution (0-3, 0,1)
CPUSetMems string `json:"CpusetMems"` // CPUSetMems specifies the memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
CPURealtimePeriod int64 `json:"CpuRealtimePeriod"` // CPU real-time period
CPURealtimeRuntime int64 `json:"CpuRealtimeRuntime"` // CPU real-time runtime
Memory int64 // Memory limit (in bytes)
MemoryReservation int64 // MemoryReservation specifies the memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness int64 // MemorySwappiness64 specifies the tune container memory swappiness (0 to 100) (default -1)
// TODO: Resources

Ulimits []*Ulimit // List of ulimits to be set in the container
Expand Down
40 changes: 40 additions & 0 deletions e2e/tests/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,46 @@ func ContainerCreate(opt *option.Option, pOpt util.NewOpt) {
Expect(int64(period)).Should(Equal(int64(100000)))
})

It("should create a container with both CPURealtimePeriod and CPURealtimeRuntime options", func() {
// define options
options.Cmd = []string{"sleep", "Infinity"}
options.HostConfig.CPURealtimePeriod = 1000000
options.HostConfig.CPURealtimeRuntime = 950000

// create container
statusCode, ctr := createContainer(uClient, url, testContainerName, options)
Expect(statusCode).Should(Equal(http.StatusCreated))
Expect(ctr.ID).ShouldNot(BeEmpty())

// start container
command.Run(opt, "start", testContainerName)

nativeResp := command.Stdout(opt, "inspect", "--mode=native", testContainerName)
var nativeInspect []map[string]interface{}
err := json.Unmarshal(nativeResp, &nativeInspect)
Expect(err).Should(BeNil())
Expect(nativeInspect).Should(HaveLen(1))

// Navigate to the CPU settings
spec, ok := nativeInspect[0]["Spec"].(map[string]interface{})
Expect(ok).Should(BeTrue())
linux, ok := spec["linux"].(map[string]interface{})
Expect(ok).Should(BeTrue())
resources, ok := linux["resources"].(map[string]interface{})
Expect(ok).Should(BeTrue())
cpu, ok := resources["cpu"].(map[string]interface{})
Expect(ok).Should(BeTrue())

// Verify both CPURealtimePeriod and CPURealtimeRuntime values
realtimePeriod, ok := cpu["realtimePeriod"].(float64)
Expect(ok).Should(BeTrue())
Expect(int64(realtimePeriod)).Should(Equal(int64(1000000)))

realtimeRuntime, ok := cpu["realtimeRuntime"].(float64)
Expect(ok).Should(BeTrue())
Expect(int64(realtimeRuntime)).Should(Equal(int64(950000)))
})

It("should create a container with specified Memory qouta and PidLimits options", func() {
// define options
options.Cmd = []string{"sleep", "Infinity"}
Expand Down
2 changes: 1 addition & 1 deletion mocks/mocks_container/container.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading