Procházet zdrojové kódy

Add resource reservations to container inspect

Signed-off-by: Guillaume Tardif <[email protected]>
Guillaume Tardif před 5 roky
rodič
revize
6516632ecf

+ 24 - 13
aci/convert/convert.go

@@ -470,17 +470,26 @@ func fqdn(group containerinstance.ContainerGroup, region string) string {
 // ContainerGroupToContainer composes a Container from an ACI container definition
 func ContainerGroupToContainer(containerID string, cg containerinstance.ContainerGroup, cc containerinstance.Container, region string) containers.Container {
 	memLimits := 0.
-	if cc.Resources != nil &&
-		cc.Resources.Limits != nil &&
-		cc.Resources.Limits.MemoryInGB != nil {
-		memLimits = *cc.Resources.Limits.MemoryInGB * 1024 * 1024 * 1024
-	}
-
+	memRequest := 0.
 	cpuLimit := 0.
-	if cc.Resources != nil &&
-		cc.Resources.Limits != nil &&
-		cc.Resources.Limits.CPU != nil {
-		cpuLimit = *cc.Resources.Limits.CPU
+	cpuReservation := 0.
+	if cc.Resources != nil {
+		if cc.Resources.Limits != nil {
+			if cc.Resources.Limits.MemoryInGB != nil {
+				memLimits = *cc.Resources.Limits.MemoryInGB * 1024 * 1024 * 1024
+			}
+			if cc.Resources.Limits.CPU != nil {
+				cpuLimit = *cc.Resources.Limits.CPU
+			}
+		}
+		if cc.Resources.Requests != nil {
+			if cc.Resources.Requests.MemoryInGB != nil {
+				memRequest = *cc.Resources.Requests.MemoryInGB * 1024 * 1024 * 1024
+			}
+			if cc.Resources.Requests.CPU != nil {
+				cpuReservation = *cc.Resources.Requests.CPU
+			}
+		}
 	}
 
 	command := ""
@@ -504,9 +513,11 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
 		Env:  envVars,
 	}
 	hostConfig := &containers.HostConfig{
-		CPULimit:      cpuLimit,
-		MemoryLimit:   uint64(memLimits),
-		RestartPolicy: toContainerRestartPolicy(cg.RestartPolicy),
+		CPULimit:          cpuLimit,
+		CPUReservation:    cpuReservation,
+		MemoryLimit:       uint64(memLimits),
+		MemoryReservation: uint64(memRequest),
+		RestartPolicy:     toContainerRestartPolicy(cg.RestartPolicy),
 	}
 	c := containers.Container{
 		ID:          containerID,

+ 9 - 3
aci/convert/convert_test.go

@@ -83,6 +83,10 @@ func TestContainerGroupToContainer(t *testing.T) {
 			Resources: &containerinstance.ResourceRequirements{
 				Limits: &containerinstance.ResourceLimits{
 					CPU:        to.Float64Ptr(3),
+					MemoryInGB: to.Float64Ptr(0.2),
+				},
+				Requests: &containerinstance.ResourceRequests{
+					CPU:        to.Float64Ptr(2),
 					MemoryInGB: to.Float64Ptr(0.1),
 				},
 			},
@@ -105,9 +109,11 @@ func TestContainerGroupToContainer(t *testing.T) {
 			FQDN: "myapp.eastus.azurecontainer.io",
 		},
 		HostConfig: &containers.HostConfig{
-			CPULimit:      3,
-			MemoryLimit:   107374182,
-			RestartPolicy: "any",
+			CPULimit:          3,
+			CPUReservation:    2,
+			MemoryLimit:       214748364,
+			MemoryReservation: 107374182,
+			RestartPolicy:     "any",
 		},
 	}
 

+ 5 - 3
api/containers/api.go

@@ -61,9 +61,11 @@ type RuntimeConfig struct {
 
 // HostConfig config of the container host
 type HostConfig struct {
-	RestartPolicy string
-	CPULimit      float64
-	MemoryLimit   uint64
+	RestartPolicy     string
+	CPUReservation    float64
+	CPULimit          float64
+	MemoryReservation uint64
+	MemoryLimit       uint64
 }
 
 // Port represents a published port of a container

+ 2 - 0
cli/cmd/testdata/inspect-out-id.golden

@@ -9,7 +9,9 @@
     "PidsLimit": 0,
     "HostConfig": {
         "RestartPolicy": "none",
+        "CPUReservation": 0,
         "CPULimit": 0,
+        "MemoryReservation": 0,
         "MemoryLimit": 0
     },
     "Platform": "Linux"

+ 37 - 1
tests/aci-e2e/e2e-aci_test.go

@@ -250,6 +250,7 @@ func TestRunVolume(t *testing.T) {
 		assert.NilError(t, err)
 		assert.Equal(t, containerInspect.Platform, "Linux")
 		assert.Equal(t, containerInspect.HostConfig.CPULimit, 1.0)
+		assert.Equal(t, containerInspect.HostConfig.CPUReservation, 1.0)
 		assert.Equal(t, containerInspect.HostConfig.RestartPolicy, containers.RestartPolicyNone)
 
 		assert.Assert(t, is.Len(containerInspect.Ports, 1))
@@ -388,7 +389,7 @@ func TestContainerRunAttached(t *testing.T) {
 			}
 			return poll.Continue("waiting for container to be running, current inspect result: \n%s", res.Combined())
 		}
-		poll.WaitOn(t, checkRunning, poll.WithDelay(5*time.Second), poll.WithTimeout(60*time.Second))
+		poll.WaitOn(t, checkRunning, poll.WithDelay(5*time.Second), poll.WithTimeout(90*time.Second))
 
 		inspectRes := c.RunDockerCmd("inspect", container)
 
@@ -397,6 +398,8 @@ func TestContainerRunAttached(t *testing.T) {
 		assert.Equal(t, containerInspect.Platform, "Linux")
 		assert.Equal(t, containerInspect.HostConfig.CPULimit, 0.1)
 		assert.Equal(t, containerInspect.HostConfig.MemoryLimit, uint64(107374182))
+		assert.Equal(t, containerInspect.HostConfig.CPUReservation, 0.1)
+		assert.Equal(t, containerInspect.HostConfig.MemoryReservation, uint64(107374182))
 		assert.Equal(t, containerInspect.HostConfig.RestartPolicy, containers.RestartPolicyOnFailure)
 
 		assert.Assert(t, is.Len(containerInspect.Ports, 1))
@@ -480,6 +483,39 @@ func overwriteFileStorageAccount(t *testing.T, absComposefileName string, storag
 	assert.NilError(t, err)
 }
 
+func TestUpResources(t *testing.T) {
+	const (
+		composeProjectName = "testresources"
+		serverContainer    = composeProjectName + "_web"
+		wordsContainer     = composeProjectName + "_words"
+	)
+
+	c := NewParallelE2eCLI(t, binDir)
+	setupTestResourceGroup(t, c)
+
+	t.Run("compose up", func(t *testing.T) {
+		c.RunDockerCmd("compose", "up", "-f", "../composefiles/aci-demo/aci_demo_port_resources.yaml", "--project-name", composeProjectName)
+
+		res := c.RunDockerCmd("inspect", serverContainer)
+
+		webInspect, err := ParseContainerInspect(res.Stdout())
+		assert.NilError(t, err)
+		assert.Equal(t, webInspect.HostConfig.CPULimit, 0.7)
+		assert.Equal(t, webInspect.HostConfig.MemoryLimit, uint64(1073741824))
+		assert.Equal(t, webInspect.HostConfig.CPUReservation, 0.5)
+		assert.Equal(t, webInspect.HostConfig.MemoryReservation, uint64(536870912))
+
+		res = c.RunDockerCmd("inspect", wordsContainer)
+
+		wordsInspect, err := ParseContainerInspect(res.Stdout())
+		assert.NilError(t, err)
+		assert.Equal(t, wordsInspect.HostConfig.CPULimit, 0.5)
+		assert.Equal(t, wordsInspect.HostConfig.MemoryLimit, uint64(751619276))
+		assert.Equal(t, wordsInspect.HostConfig.CPUReservation, 0.5)
+		assert.Equal(t, wordsInspect.HostConfig.MemoryReservation, uint64(751619276))
+	})
+}
+
 func TestUpUpdate(t *testing.T) {
 	const (
 		composeProjectName = "acidemo"

+ 0 - 14
tests/composefiles/aci-demo/aci_demo_port.yaml

@@ -1,14 +0,0 @@
-services:
-  db:
-    build: db
-    image: gtardif/sentences-db
-
-  words:
-    build: words
-    image: gtardif/sentences-api
-
-  web:
-    build: web
-    image: gtardif/sentences-web
-    ports:
-      - "80:80"

+ 24 - 0
tests/composefiles/aci-demo/aci_demo_port_resources.yaml

@@ -0,0 +1,24 @@
+services:
+  db:
+    image: gtardif/sentences-db
+
+  words:
+    image: gtardif/sentences-api
+    deploy:
+      resources:
+        reservations:
+          cpus: '0.5'
+          memory: 0.7G
+
+  web:
+    image: gtardif/sentences-web
+    ports:
+      - "80:80"
+    deploy:
+      resources:
+        limits:
+          cpus: '0.7'
+          memory: 1G
+        reservations:
+          cpus: '0.5'
+          memory: 0.5G

+ 2 - 0
tests/e2e/testdata/inspect-id.golden

@@ -9,7 +9,9 @@
     "PidsLimit": 0,
     "HostConfig": {
         "RestartPolicy": "none",
+        "CPUReservation": 0,
         "CPULimit": 0,
+        "MemoryReservation": 0,
         "MemoryLimit": 0
     },
     "Platform": "Linux"