summaryrefslogtreecommitdiff
path: root/test/e2e
diff options
context:
space:
mode:
authorJordan Christiansen <xordspar0@gmail.com>2020-09-28 13:57:58 -0500
committerJordan Christiansen <xordspar0@gmail.com>2020-10-12 08:38:37 -0500
commita413d4d77f1701a62b9bb2e7beb00145544e2306 (patch)
treefd29521eed106a03104eeeaecc6ce5fad040b617 /test/e2e
parentcec240375d6dceb09c705d6d55e67aeff037327f (diff)
downloadpodman-a413d4d77f1701a62b9bb2e7beb00145544e2306.tar.gz
podman-a413d4d77f1701a62b9bb2e7beb00145544e2306.tar.bz2
podman-a413d4d77f1701a62b9bb2e7beb00145544e2306.zip
Add support for resource limits to play kube
Signed-off-by: Jordan Christiansen <xordspar0@gmail.com>
Diffstat (limited to 'test/e2e')
-rw-r--r--test/e2e/common_test.go9
-rw-r--r--test/e2e/play_kube_test.go131
2 files changed, 136 insertions, 4 deletions
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index ec910109b..e36c86690 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -612,6 +612,15 @@ func SkipIfRootlessCgroupsV1(reason string) {
}
}
+func SkipIfUnprevilegedCPULimits() {
+ info := GetHostDistributionInfo()
+ if isRootless() &&
+ info.Distribution == "fedora" &&
+ (info.Version == "31" || info.Version == "32") {
+ ginkgo.Skip("Rootless Fedora doesn't have permission to set CPU limits before version 33")
+ }
+}
+
func SkipIfRootless(reason string) {
checkReason(reason)
if os.Geteuid() != 0 {
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index b6a390950..3906fa49d 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "strconv"
"strings"
"text/template"
@@ -111,7 +112,19 @@ spec:
image: {{ .Image }}
name: {{ .Name }}
imagePullPolicy: {{ .PullPolicy }}
- resources: {}
+ {{- if or .CpuRequest .CpuLimit .MemoryRequest .MemoryLimit }}
+ resources:
+ {{- if or .CpuRequest .MemoryRequest }}
+ requests:
+ {{if .CpuRequest }}cpu: {{ .CpuRequest }}{{ end }}
+ {{if .MemoryRequest }}memory: {{ .MemoryRequest }}{{ end }}
+ {{- end }}
+ {{- if or .CpuLimit .MemoryLimit }}
+ limits:
+ {{if .CpuLimit }}cpu: {{ .CpuLimit }}{{ end }}
+ {{if .MemoryLimit }}memory: {{ .MemoryLimit }}{{ end }}
+ {{- end }}
+ {{- end }}
{{ if .SecurityContext }}
securityContext:
allowPrivilegeEscalation: true
@@ -223,7 +236,19 @@ spec:
image: {{ .Image }}
name: {{ .Name }}
imagePullPolicy: {{ .PullPolicy }}
- resources: {}
+ {{- if or .CpuRequest .CpuLimit .MemoryRequest .MemoryLimit }}
+ resources:
+ {{- if or .CpuRequest .MemoryRequest }}
+ requests:
+ {{if .CpuRequest }}cpu: {{ .CpuRequest }}{{ end }}
+ {{if .MemoryRequest }}memory: {{ .MemoryRequest }}{{ end }}
+ {{- end }}
+ {{- if or .CpuLimit .MemoryLimit }}
+ limits:
+ {{if .CpuLimit }}cpu: {{ .CpuLimit }}{{ end }}
+ {{if .MemoryLimit }}memory: {{ .MemoryLimit }}{{ end }}
+ {{- end }}
+ {{- end }}
{{ if .SecurityContext }}
securityContext:
allowPrivilegeEscalation: true
@@ -261,6 +286,8 @@ var (
defaultDeploymentName = "testDeployment"
defaultConfigMapName = "testConfigMap"
seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
+ // CPU Period in ms
+ defaultCPUPeriod = 100
)
func writeYaml(content string, fileName string) error {
@@ -503,6 +530,10 @@ type Ctr struct {
Image string
Cmd []string
Arg []string
+ CpuRequest string
+ CpuLimit string
+ MemoryRequest string
+ MemoryLimit string
SecurityContext bool
Caps bool
CapAdd []string
@@ -521,7 +552,25 @@ type Ctr struct {
// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
// and the configured options
func getCtr(options ...ctrOption) *Ctr {
- c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, defaultCtrArg, true, false, nil, nil, "", "", "", false, "", "", false, []Env{}, []EnvFrom{}}
+ c := Ctr{
+ Name: defaultCtrName,
+ Image: defaultCtrImage,
+ Cmd: defaultCtrCmd,
+ Arg: defaultCtrArg,
+ SecurityContext: true,
+ Caps: false,
+ CapAdd: nil,
+ CapDrop: nil,
+ PullPolicy: "",
+ HostIP: "",
+ Port: "",
+ VolumeMount: false,
+ VolumeMountPath: "",
+ VolumeName: "",
+ VolumeReadOnly: false,
+ Env: []Env{},
+ EnvFrom: []EnvFrom{},
+ }
for _, option := range options {
option(&c)
}
@@ -548,6 +597,30 @@ func withImage(img string) ctrOption {
}
}
+func withCpuRequest(request string) ctrOption {
+ return func(c *Ctr) {
+ c.CpuRequest = request
+ }
+}
+
+func withCpuLimit(limit string) ctrOption {
+ return func(c *Ctr) {
+ c.CpuLimit = limit
+ }
+}
+
+func withMemoryRequest(request string) ctrOption {
+ return func(c *Ctr) {
+ c.MemoryRequest = request
+ }
+}
+
+func withMemoryLimit(limit string) ctrOption {
+ return func(c *Ctr) {
+ c.MemoryLimit = limit
+ }
+}
+
func withSecurityContext(sc bool) ctrOption {
return func(c *Ctr) {
c.SecurityContext = sc
@@ -648,7 +721,12 @@ type EnvFrom struct {
From string
}
-var _ = Describe("Podman generate kube", func() {
+func milliCPUToQuota(milliCPU string) int {
+ milli, _ := strconv.Atoi(strings.Trim(milliCPU, "m"))
+ return milli * defaultCPUPeriod
+}
+
+var _ = Describe("Podman play kube", func() {
var (
tempdir string
err error
@@ -1324,4 +1402,49 @@ spec:
Expect(inspect.OutputToString()).To(ContainSubstring(correctLabels))
}
})
+
+ It("podman play kube allows setting resource limits", func() {
+ SkipIfContainerized("Resource limits require a running systemd")
+ SkipIfRootlessCgroupsV1("Limits require root or cgroups v2")
+ SkipIfUnprevilegedCPULimits()
+ podmanTest.CgroupManager = "systemd"
+
+ var (
+ numReplicas int32 = 3
+ expectedCpuRequest string = "100m"
+ expectedCpuLimit string = "200m"
+ expectedMemoryRequest string = "10000000"
+ expectedMemoryLimit string = "20000000"
+ )
+
+ expectedCpuQuota := milliCPUToQuota(expectedCpuLimit)
+
+ deployment := getDeployment(
+ withReplicas(numReplicas),
+ withPod(getPod(withCtr(getCtr(
+ withCpuRequest(expectedCpuRequest),
+ withCpuLimit(expectedCpuLimit),
+ withMemoryRequest(expectedMemoryRequest),
+ withMemoryLimit(expectedMemoryLimit),
+ )))))
+ err := generateKubeYaml("deployment", deployment, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ for _, pod := range getPodNamesInDeployment(deployment) {
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&pod), "--format", `
+CpuPeriod: {{ .HostConfig.CpuPeriod }}
+CpuQuota: {{ .HostConfig.CpuQuota }}
+Memory: {{ .HostConfig.Memory }}
+MemoryReservation: {{ .HostConfig.MemoryReservation }}`})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s: %d", "CpuQuota", expectedCpuQuota)))
+ Expect(inspect.OutputToString()).To(ContainSubstring("MemoryReservation: " + expectedMemoryRequest))
+ Expect(inspect.OutputToString()).To(ContainSubstring("Memory: " + expectedMemoryLimit))
+ }
+ })
})