diff --git a/root/usr/bin/cgroup-limits b/root/usr/bin/cgroup-limits index 9f1dc1f..2a8bee3 100755 --- a/root/usr/bin/cgroup-limits +++ b/root/usr/bin/cgroup-limits @@ -19,10 +19,12 @@ Variables currently supported: Maximum amount of user memory in bytes. If this value is set to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that there is no limit set. The value is taken from - /sys/fs/cgroup/memory/memory.limit_in_bytes + /sys/fs/cgroup/memory/memory.limit_in_bytes for cgroups v1 + and from /sys/fs/cgroup/memory.max for cgroups v2 NUMBER_OF_CORES Number of detected CPU cores that can be used. This value is - calculated from /sys/fs/cgroup/cpuset/cpuset.cpus + calculated from /sys/fs/cgroup/cpuset/cpuset.cpus for cgroups v1 + and from /sys/fs/cgroup/cpuset.cpus.effective for cgroups v2 NO_MEMORY_LIMIT Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller can act as if no memory limit was set. Undefined otherwise. @@ -46,7 +48,11 @@ def get_memory_limit(): """ limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes') + # If first file does not exist, try cgroups v2 file + limit = limit or _read_file('/sys/fs/cgroup/memory.max') if limit is None or not limit.isdigit(): + if limit == 'max': + return 9223372036854775807 print("Warning: Can't detect memory limit from cgroups", file=sys.stderr) return None @@ -61,7 +67,11 @@ def get_number_of_cores(): core_count = 0 line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus') + # If first file does not exist, try cgroups v2 file + line = line or _read_file('/sys/fs/cgroup/cpuset.cpus.effective') if line is None: + # None of the files above exists when running podman as non-root, + # so in that case, this warning is printed every-time print("Warning: Can't detect number of CPU cores from cgroups", file=sys.stderr) return None diff --git a/test/run b/test/run index 9a25c12..da66ed9 100755 --- a/test/run +++ b/test/run @@ -1,6 +1,6 @@ #!/bin/bash # -# The 'run' performs a simple test that verifies that STI image. +# The 'run' performs a simple test that verifies that S2I image. # The main focus is that the image prints out the base-usage properly. # # IMAGE_NAME specifies a name of the candidate image used for testing. @@ -9,18 +9,82 @@ IMAGE_NAME=${IMAGE_NAME-centos/s2i-core-centos7-candidate} test_docker_run_usage() { - echo "Testing 'docker run' usage..." - docker run --rm ${IMAGE_NAME} &>/dev/null + echo "Testing 'docker run' usage..." + docker run --rm ${IMAGE_NAME} &>/dev/null +} + +test_cgroup_limits() { + echo "Testing 'cgroup limits' usage..." + if [ $EUID -eq 0 ]; then + echo " The test is running as root, all tests for cgroup limits will be run" + + # check memory limited (only works when running as root) + echo " Testing 'limited memory' usage..." + if ! ( eval $(docker run --rm --memory=512M ${IMAGE_NAME} /usr/bin/cgroup-limits) + echo "MEMORY_LIMIT_IN_BYTES=$MEMORY_LIMIT_IN_BYTES" + [ "$MEMORY_LIMIT_IN_BYTES" -eq 536870912 ] ); then + echo "MEMORY_LIMIT_IN_BYTES not set to 536870912." + return 1 + fi + + # check cores number (only works when running as root) + echo " Testing 'NUMBER_OF_CORES' value..." + if ! ( eval $(docker run --rm ${IMAGE_NAME} /usr/bin/cgroup-limits) + echo "NUMBER_OF_CORES=$NUMBER_OF_CORES" + [ "$NUMBER_OF_CORES" -gt 0 ] ); then + echo "NUMBER_OF_CORES not set." + return 1 + fi + + # check cores number (only works when running as root) + echo " Testing 'NUMBER_OF_CORES' value with --cpuset-cpus=0..." + if ! ( eval $(docker run --rm --cpuset-cpus=0 ${IMAGE_NAME} /usr/bin/cgroup-limits) + echo "NUMBER_OF_CORES=$NUMBER_OF_CORES" + [ "$NUMBER_OF_CORES" -eq 1 ] ); then + echo "NUMBER_OF_CORES not set to 1 when set --cpuset-cpus=0." + return 1 + fi + + else + echo " The test is running as non-root, some tests for cgroup limits are skipped" + fi + + # check NO_MEMORY_LIMIT when no limit is set + echo " Testing 'NO_MEMORY_LIMIT' value..." + if ! ( eval $(docker run --rm ${IMAGE_NAME} /usr/bin/cgroup-limits) + echo "NO_MEMORY_LIMIT=$NO_MEMORY_LIMIT" + [ "$NO_MEMORY_LIMIT" == 'true' ] ); then + echo "NO_MEMORY_LIMIT not set to true." + return 1 + fi + + # check default memory in bytes + echo " Testing 'MEMORY_LIMIT_IN_BYTES' value..." + if ! ( eval $(docker run --rm ${IMAGE_NAME} /usr/bin/cgroup-limits) + echo "MEMORY_LIMIT_IN_BYTES=$MEMORY_LIMIT_IN_BYTES" + # This value can be different, but it must be very big (comparing to 10TB) + [ "$MEMORY_LIMIT_IN_BYTES" -gt 10000000000000 ] ); then + echo "MEMORY_LIMIT_IN_BYTES not greater than 10000000000000." + return 1 + fi } check_result() { - local result="$1" - if [[ "$result" != "0" ]]; then - echo "STI image '${IMAGE_NAME}' test FAILED (exit code: ${result})" - exit $result - fi + local result="$1" + if [[ "$result" != "0" ]]; then + echo "S2I image '${IMAGE_NAME}' test FAILED (exit code: ${result})" + exit $result + fi } # Verify the 'usage' script is working properly when running the base image with 'docker run ...' test_docker_run_usage check_result $? + +# Verify the cgroup-limits script works as expected +test_cgroup_limits +check_result $? + +echo "Tests for '${IMAGE_NAME}' succeeded." + +# vim: set tabstop=2:shiftwidth=2:expandtab: