Skip to content

Commit

Permalink
Merge pull request #3535 from vyos/mergify/bp/sagitta/pr-3530
Browse files Browse the repository at this point in the history
T6406: Container CPU limits (backport #3530)
  • Loading branch information
c-po authored May 28, 2024
2 parents 6954288 + d180595 commit 9d0a453
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
18 changes: 18 additions & 0 deletions interface-definitions/container.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,24 @@
</leafNode>
</children>
</tagNode>
<leafNode name="cpu-quota">
<properties>
<help>This limits the number of CPU resources the container can use</help>
<valueHelp>
<format>u32:0</format>
<description>Unlimited</description>
</valueHelp>
<valueHelp>
<format>txt</format>
<description>Amount of CPU time the container can use in amount of cores (up to three decimals)</description>
</valueHelp>
<constraint>
<regex>(0|[1-9]\d*)(\.\d{1,3})?</regex>
</constraint>
<constraintErrorMessage>Container CPU limit must be a (decimal) number in range 0 to number of threads</constraintErrorMessage>
</properties>
<defaultValue>0</defaultValue>
</leafNode>
<leafNode name="memory">
<properties>
<help>Memory (RAM) available to this container</help>
Expand Down
16 changes: 16 additions & 0 deletions smoketest/scripts/cli/test_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ def test_basic(self):
# 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, 'cpu-quota', '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'
Expand Down
8 changes: 8 additions & 0 deletions smoketest/scripts/system/test_kernel_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,13 @@ def test_vfio(self):
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)
9 changes: 8 additions & 1 deletion src/conf_mode/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import os

from decimal import Decimal
from hashlib import sha256
from ipaddress import ip_address
from ipaddress import ip_network
Expand Down Expand Up @@ -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 '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:
if len(container_config['network']) > 1:
raise ConfigError(f'Only one network can be specified for container "{name}"!')
Expand Down Expand Up @@ -257,6 +263,7 @@ def verify(container):

def generate_run_arguments(name, container_config):
image = container_config['image']
cpu_quota = container_config['cpu_quota']
memory = container_config['memory']
shared_memory = container_config['shared_memory']
restart = container_config['restart']
Expand Down Expand Up @@ -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 {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}'

Expand Down

0 comments on commit 9d0a453

Please sign in to comment.