Skip to content

Commit f047760

Browse files
authored
container: T6406: add CLI option for cpu-quota
2 parents 48e5266 + 7491056 commit f047760

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

interface-definitions/container.xml.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,24 @@
192192
</leafNode>
193193
</children>
194194
</tagNode>
195+
<leafNode name="cpu-quota">
196+
<properties>
197+
<help>This limits the number of CPU resources the container can use</help>
198+
<valueHelp>
199+
<format>u32:0</format>
200+
<description>Unlimited</description>
201+
</valueHelp>
202+
<valueHelp>
203+
<format>txt</format>
204+
<description>Amount of CPU time the container can use in amount of cores (up to three decimals)</description>
205+
</valueHelp>
206+
<constraint>
207+
<regex>(0|[1-9]\d*)(\.\d{1,3})?</regex>
208+
</constraint>
209+
<constraintErrorMessage>Container CPU limit must be a (decimal) number in range 0 to number of threads</constraintErrorMessage>
210+
</properties>
211+
<defaultValue>0</defaultValue>
212+
</leafNode>
195213
<leafNode name="memory">
196214
<properties>
197215
<help>Memory (RAM) available to this container</help>

smoketest/scripts/cli/test_container.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,22 @@ def test_basic(self):
9191
# Check for running process
9292
self.assertEqual(process_named_running(PROCESS_NAME), pid)
9393

94+
def test_cpu_limit(self):
95+
cont_name = 'c2'
96+
97+
self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])
98+
self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
99+
self.cli_set(base_path + ['name', cont_name, 'cpu-quota', '1.25'])
100+
101+
self.cli_commit()
102+
103+
pid = 0
104+
with open(PROCESS_PIDFILE.format(cont_name), 'r') as f:
105+
pid = int(f.read())
106+
107+
# Check for running process
108+
self.assertEqual(process_named_running(PROCESS_NAME), pid)
109+
94110
def test_ipv4_network(self):
95111
prefix = '192.0.2.0/24'
96112
base_name = 'ipv4'

smoketest/scripts/system/test_kernel_options.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,13 @@ def test_vfio(self):
120120
tmp = re.findall(f'{option}=(y|m)', self._config_data)
121121
self.assertTrue(tmp)
122122

123+
def test_container_cpu(self):
124+
options_to_check = [
125+
'CONFIG_CGROUP_SCHED', 'CONFIG_CPUSETS', 'CONFIG_CGROUP_CPUACCT', 'CONFIG_CFS_BANDWIDTH'
126+
]
127+
for option in options_to_check:
128+
tmp = re.findall(f'{option}=(y|m)', self._config_data)
129+
self.assertTrue(tmp)
130+
123131
if __name__ == '__main__':
124132
unittest.main(verbosity=2)

src/conf_mode/container.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import os
1818

19+
from decimal import Decimal
1920
from hashlib import sha256
2021
from ipaddress import ip_address
2122
from ipaddress import ip_network
@@ -127,6 +128,11 @@ def verify(container):
127128
f'locally. Please use "add container image {image}" to add it '\
128129
f'to the system! Container "{name}" will not be started!')
129130

131+
if 'cpu_quota' in container_config:
132+
cores = vyos.cpu.get_core_count()
133+
if Decimal(container_config['cpu_quota']) > cores:
134+
raise ConfigError(f'Cannot set limit to more cores than available "{name}"!')
135+
130136
if 'network' in container_config:
131137
if len(container_config['network']) > 1:
132138
raise ConfigError(f'Only one network can be specified for container "{name}"!')
@@ -257,6 +263,7 @@ def verify(container):
257263

258264
def generate_run_arguments(name, container_config):
259265
image = container_config['image']
266+
cpu_quota = container_config['cpu_quota']
260267
memory = container_config['memory']
261268
shared_memory = container_config['shared_memory']
262269
restart = container_config['restart']
@@ -333,7 +340,7 @@ def generate_run_arguments(name, container_config):
333340
if 'allow_host_pid' in container_config:
334341
host_pid = '--pid host'
335342

336-
container_base_cmd = f'--detach --interactive --tty --replace {capabilities} ' \
343+
container_base_cmd = f'--detach --interactive --tty --replace {capabilities} --cpus {cpu_quota} ' \
337344
f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \
338345
f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid} {host_pid}'
339346

0 commit comments

Comments
 (0)