From 10df4ad8a3d7182363460b8043af2cacf128c893 Mon Sep 17 00:00:00 2001 From: Nicolas Vollmar Date: Mon, 27 May 2024 12:13:39 +0200 Subject: T6406: check for required kernel config (cherry picked from commit 5146cb23fff56e5a84db8c84120b836ceeae47f2) --- smoketest/scripts/system/test_kernel_options.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/smoketest/scripts/system/test_kernel_options.py b/smoketest/scripts/system/test_kernel_options.py index bc7f658b0..4666e98e7 100755 --- a/smoketest/scripts/system/test_kernel_options.py +++ b/smoketest/scripts/system/test_kernel_options.py @@ -120,5 +120,13 @@ class TestKernelModules(unittest.TestCase): tmp = re.findall(f'{option}=(y|m)', self._config_data) self.assertTrue(tmp) + def test_container_cpu(self): + options_to_check = [ + 'CONFIG_CGROUP_SCHED', 'CONFIG_CPUSETS', 'CONFIG_CGROUP_CPUACCT', 'CONFIG_CFS_BANDWIDTH' + ] + for option in options_to_check: + tmp = re.findall(f'{option}=(y|m)', self._config_data) + self.assertTrue(tmp) + if __name__ == '__main__': unittest.main(verbosity=2) -- cgit v1.2.3 From 8007b58f1e0ecfad9ed0cca7ecec725287432439 Mon Sep 17 00:00:00 2001 From: Nicolas Vollmar Date: Mon, 27 May 2024 13:12:54 +0200 Subject: T6406: add container cpu limit option (cherry picked from commit 81dea053e7178b8fea836a85aacde2a38ffb9e09) --- interface-definitions/container.xml.in | 18 ++++++++++++++++++ smoketest/scripts/cli/test_container.py | 16 ++++++++++++++++ src/conf_mode/container.py | 9 ++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 2296a3e9e..4370f5888 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -192,6 +192,24 @@ + + + This limits the number of CPU resources the container can use + + u32:0 + Unlimited + + + txt + Amount of CPU time the container can use in amount of cores (up to three decimals) + + + (0|[1-9]\d*)(\.\d{1,3})? + + Container CPU limit must be a (decimal) number in range 0 to number of threads + + 0 + Memory (RAM) available to this container diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py index 3201883b8..ef31d0f6f 100755 --- a/smoketest/scripts/cli/test_container.py +++ b/smoketest/scripts/cli/test_container.py @@ -91,6 +91,22 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): # Check for running process self.assertEqual(process_named_running(PROCESS_NAME), pid) + def test_cpu_limit(self): + cont_name = 'c2' + + self.cli_set(base_path + ['name', cont_name, 'allow-host-networks']) + self.cli_set(base_path + ['name', cont_name, 'image', cont_image]) + self.cli_set(base_path + ['name', cont_name, 'cpus', '1.25']) + + self.cli_commit() + + pid = 0 + with open(PROCESS_PIDFILE.format(cont_name), 'r') as f: + pid = int(f.read()) + + # Check for running process + self.assertEqual(process_named_running(PROCESS_NAME), pid) + def test_ipv4_network(self): prefix = '192.0.2.0/24' base_name = 'ipv4' diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 91a10e891..2294b8e57 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -16,6 +16,7 @@ import os +from decimal import Decimal from hashlib import sha256 from ipaddress import ip_address from ipaddress import ip_network @@ -127,6 +128,11 @@ def verify(container): f'locally. Please use "add container image {image}" to add it '\ f'to the system! Container "{name}" will not be started!') + if 'cpus' in container_config: + cores = os.cpu_count() + if Decimal(container_config['cpus']) > cores: + raise ConfigError(f'Cannot set limit to more cores than available "{name}"!') + if 'network' in container_config: if len(container_config['network']) > 1: raise ConfigError(f'Only one network can be specified for container "{name}"!') @@ -257,6 +263,7 @@ def verify(container): def generate_run_arguments(name, container_config): image = container_config['image'] + cpus = container_config['cpus'] memory = container_config['memory'] shared_memory = container_config['shared_memory'] restart = container_config['restart'] @@ -333,7 +340,7 @@ def generate_run_arguments(name, container_config): if 'allow_host_pid' in container_config: host_pid = '--pid host' - container_base_cmd = f'--detach --interactive --tty --replace {capabilities} ' \ + container_base_cmd = f'--detach --interactive --tty --replace {capabilities} --cpus {cpus} ' \ f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid} {host_pid}' -- cgit v1.2.3 From d180595aff41d8c23c35937656fbc8fe4d93ad7a Mon Sep 17 00:00:00 2001 From: Nicolas Vollmar Date: Tue, 28 May 2024 08:17:15 +0200 Subject: T6406: rename cpus to cpu (cherry picked from commit 74910564f82e2837cd7eb35ea21f07601e5f8f0d) --- interface-definitions/container.xml.in | 2 +- smoketest/scripts/cli/test_container.py | 2 +- src/conf_mode/container.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 4370f5888..1ad7215e5 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -192,7 +192,7 @@ - + This limits the number of CPU resources the container can use diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py index ef31d0f6f..90f821c60 100755 --- a/smoketest/scripts/cli/test_container.py +++ b/smoketest/scripts/cli/test_container.py @@ -96,7 +96,7 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['name', cont_name, 'allow-host-networks']) self.cli_set(base_path + ['name', cont_name, 'image', cont_image]) - self.cli_set(base_path + ['name', cont_name, 'cpus', '1.25']) + self.cli_set(base_path + ['name', cont_name, 'cpu-quota', '1.25']) self.cli_commit() diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 2294b8e57..ca09dff9f 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -128,9 +128,9 @@ def verify(container): f'locally. Please use "add container image {image}" to add it '\ f'to the system! Container "{name}" will not be started!') - if 'cpus' in container_config: - cores = os.cpu_count() - if Decimal(container_config['cpus']) > cores: + if 'cpu_quota' in container_config: + cores = vyos.cpu.get_core_count() + if Decimal(container_config['cpu_quota']) > cores: raise ConfigError(f'Cannot set limit to more cores than available "{name}"!') if 'network' in container_config: @@ -263,7 +263,7 @@ def verify(container): def generate_run_arguments(name, container_config): image = container_config['image'] - cpus = container_config['cpus'] + cpu_quota = container_config['cpu_quota'] memory = container_config['memory'] shared_memory = container_config['shared_memory'] restart = container_config['restart'] @@ -340,7 +340,7 @@ def generate_run_arguments(name, container_config): if 'allow_host_pid' in container_config: host_pid = '--pid host' - container_base_cmd = f'--detach --interactive --tty --replace {capabilities} --cpus {cpus} ' \ + container_base_cmd = f'--detach --interactive --tty --replace {capabilities} --cpus {cpu_quota} ' \ f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid} {host_pid}' -- cgit v1.2.3