Skip to content

Commit 669a0ee

Browse files
authored
feat: Add Cpu options and missing tests to cidfile option (runfinch#230)
Signed-off-by: Arjun Raja Yogidas <[email protected]>
1 parent 58eef04 commit 669a0ee

File tree

4 files changed

+96
-10
lines changed

4 files changed

+96
-10
lines changed

api/handlers/container/create.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ func (h *handler) create(w http.ResponseWriter, r *http.Request) {
202202
MemoryReservation: memoryReservation, // Memory soft limit (in bytes)
203203
MemorySwap: memorySwap, // Total memory usage (memory + swap); set `-1` to enable unlimited swap
204204
Ulimit: ulimits, // List of ulimits to be set in the container
205-
CPUPeriod: uint64(req.HostConfig.CPUPeriod),
205+
CPUPeriod: uint64(req.HostConfig.CPUPeriod), // CPU CFS (Completely Fair Scheduler) period
206+
CPUSetCPUs: req.HostConfig.CPUSetCPUs, // CpusetCpus 0-2, 0,1
207+
CPUSetMems: req.HostConfig.CPUSetMems, // CpusetMems 0-2, 0,1
206208
// #endregion
207209

208210
// #region for user flags

api/handlers/container/create_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,28 @@ var _ = Describe("Container Create API ", func() {
415415
Expect(rr.Body).Should(MatchJSON(jsonResponse))
416416
})
417417

418+
It("should set CpuSet create options for resources", func() {
419+
body := []byte(`{
420+
"Image": "test-image",
421+
"HostConfig": {
422+
"CpusetCpus": "0,1",
423+
"CpusetMems": "0,3"
424+
}
425+
}`)
426+
req, _ := http.NewRequest(http.MethodPost, "/containers/create", bytes.NewReader(body))
427+
428+
// expected create options
429+
createOpt.CPUSetCPUs = "0,1"
430+
createOpt.CPUSetMems = "0,3"
431+
service.EXPECT().Create(gomock.Any(), "test-image", nil, equalTo(createOpt), equalTo(netOpt)).Return(
432+
cid, nil)
433+
434+
// handler should return success message with 201 status code.
435+
h.create(rr, req)
436+
Expect(rr).Should(HaveHTTPStatus(http.StatusCreated))
437+
Expect(rr.Body).Should(MatchJSON(jsonResponse))
438+
})
439+
418440
It("should set MemoryReservation, MemorySwap and MemorySwappiness create options for resources", func() {
419441
body := []byte(`{
420442
"Image": "test-image",
@@ -523,6 +545,27 @@ var _ = Describe("Container Create API ", func() {
523545
Expect(rr.Body).Should(MatchJSON(jsonResponse))
524546
})
525547

548+
It("should set ContainerIdFile option", func() {
549+
body := []byte(`{
550+
"Image": "test-image",
551+
"HostConfig": {
552+
"ContainerIDFile": "/lib/example.txt"
553+
}
554+
}`)
555+
req, _ := http.NewRequest(http.MethodPost, "/containers/create", bytes.NewReader(body))
556+
557+
// expected create options
558+
createOpt.CidFile = "/lib/example.txt"
559+
560+
service.EXPECT().Create(gomock.Any(), "test-image", nil, equalTo(createOpt), equalTo(netOpt)).Return(
561+
cid, nil)
562+
563+
// handler should return success message with 201 status code.
564+
h.create(rr, req)
565+
Expect(rr).Should(HaveHTTPStatus(http.StatusCreated))
566+
Expect(rr.Body).Should(MatchJSON(jsonResponse))
567+
})
568+
526569
It("should return 404 if the image was not found", func() {
527570
body := []byte(`{"Image": "test-image"}`)
528571
req, _ := http.NewRequest(http.MethodPost, "/containers/create", bytes.NewReader(body))

api/types/container_types.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ type ContainerHostConfig struct {
101101
// TODO: Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
102102

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

115115
Ulimits []*Ulimit // List of ulimits to be set in the container

e2e/tests/container_create.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,47 @@ func ContainerCreate(opt *option.Option) {
749749
Expect(netDetails.MacAddress).Should(Equal(macAddress))
750750
}
751751
})
752+
753+
It("should create a container with both CPUSetCPUs and CPUSetMems options", func() {
754+
// define options
755+
options.Cmd = []string{"sleep", "Infinity"}
756+
options.HostConfig.CPUSetCPUs = "0,1" // Use CPUs 0 and 1
757+
options.HostConfig.CPUSetMems = "0" // Use only memory node 0
758+
759+
// create container
760+
statusCode, ctr := createContainer(uClient, url, testContainerName, options)
761+
Expect(statusCode).Should(Equal(http.StatusCreated))
762+
Expect(ctr.ID).ShouldNot(BeEmpty())
763+
764+
// start container
765+
command.Run(opt, "start", testContainerName)
766+
767+
// Get native container configuration
768+
nativeResp := command.Stdout(opt, "inspect", "--mode=native", testContainerName)
769+
var nativeInspect []map[string]interface{}
770+
err := json.Unmarshal(nativeResp, &nativeInspect)
771+
Expect(err).Should(BeNil())
772+
Expect(nativeInspect).Should(HaveLen(1))
773+
774+
// Navigate to the CPU settings
775+
spec, ok := nativeInspect[0]["Spec"].(map[string]interface{})
776+
Expect(ok).Should(BeTrue())
777+
linux, ok := spec["linux"].(map[string]interface{})
778+
Expect(ok).Should(BeTrue())
779+
resources, ok := linux["resources"].(map[string]interface{})
780+
Expect(ok).Should(BeTrue())
781+
cpu, ok := resources["cpu"].(map[string]interface{})
782+
Expect(ok).Should(BeTrue())
783+
784+
// Verify both settings are correct
785+
cpuSet, ok := cpu["cpus"].(string)
786+
Expect(ok).Should(BeTrue())
787+
Expect(cpuSet).Should(Equal("0,1"))
788+
789+
memSet, ok := cpu["mems"].(string)
790+
Expect(ok).Should(BeTrue())
791+
Expect(memSet).Should(Equal("0"))
792+
})
752793
})
753794
}
754795

0 commit comments

Comments
 (0)