Skip to content

Commit 5bf2ead

Browse files
Exposes CPU limit
1 parent 9766c95 commit 5bf2ead

File tree

3 files changed

+80
-15
lines changed

3 files changed

+80
-15
lines changed

repo2docker/app.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,28 @@ def _default_log_level(self):
9797
"""
9898
)
9999

100+
extra_build_kwargs = Dict(
101+
{},
102+
help="""
103+
extra kwargs to limit CPU quota when building a docker image.
104+
Dictionary that allows the user to set the desired runtime flag
105+
to configure the amount of access to CPU resources your container has.
106+
Reference https://docs.docker.com/config/containers/resource_constraints/#cpu
107+
""",
108+
config=True
109+
)
110+
111+
extra_run_kwargs = Dict(
112+
{},
113+
help="""
114+
extra kwargs to limit CPU quota when running a docker image.
115+
Dictionary that allows the user to set the desired runtime flag
116+
to configure the amount of access to CPU resources your container has.
117+
Reference https://docs.docker.com/config/containers/resource_constraints/#cpu
118+
""",
119+
config=True
120+
)
121+
100122
default_buildpack = Any(
101123
PythonBuildPack,
102124
config=True,
@@ -499,15 +521,20 @@ def start_container(self):
499521
'mode': 'rw'
500522
}
501523

502-
container = client.containers.run(
503-
self.output_image_spec,
524+
run_kwargs = dict(
504525
publish_all_ports=self.all_ports,
505526
ports=ports,
506527
detach=True,
507528
command=run_cmd,
508529
volumes=container_volumes,
509530
environment=self.environment
510531
)
532+
533+
run_kwargs.update(self.extra_run_kwargs)
534+
535+
container = client.containers.run(
536+
self.output_image_spec, **run_kwargs)
537+
511538
while container.status == 'created':
512539
time.sleep(0.5)
513540
container.reload()
@@ -636,7 +663,8 @@ def build(self):
636663
self.output_image_spec,
637664
self.build_memory_limit,
638665
build_args,
639-
self.cache_from):
666+
self.cache_from,
667+
self.extra_build_kwargs):
640668
if 'stream' in l:
641669
self.log.info(l['stream'],
642670
extra=dict(phase='building'))

repo2docker/buildpacks/base.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import sys
1010
import xml.etree.ElementTree as ET
1111

12+
from traitlets import Dict
13+
1214
TEMPLATE = r"""
1315
FROM buildpack-deps:bionic
1416
@@ -463,7 +465,7 @@ def render(self):
463465
appendix=self.appendix,
464466
)
465467

466-
def build(self, client, image_spec, memory_limit, build_args, cache_from):
468+
def build(self, client, image_spec, memory_limit, build_args, cache_from, extra_build_kwargs):
467469
tarf = io.BytesIO()
468470
tar = tarfile.open(fileobj=tarf, mode='w')
469471
dockerfile_tarinfo = tarfile.TarInfo("Dockerfile")
@@ -503,17 +505,22 @@ def _filter_tar(tar):
503505
}
504506
if memory_limit:
505507
limits['memory'] = memory_limit
506-
for line in client.build(
507-
fileobj=tarf,
508-
tag=image_spec,
509-
custom_context=True,
510-
buildargs=build_args,
511-
decode=True,
512-
forcerm=True,
513-
rm=True,
514-
container_limits=limits,
515-
cache_from=cache_from
516-
):
508+
509+
build_kwargs = dict(
510+
fileobj=tarf,
511+
tag=image_spec,
512+
custom_context=True,
513+
buildargs=build_args,
514+
decode=True,
515+
forcerm=True,
516+
rm=True,
517+
container_limits=limits,
518+
cache_from=cache_from,
519+
)
520+
521+
build_kwargs.update(extra_build_kwargs)
522+
523+
for line in client.build(**build_kwargs):
517524
yield line
518525

519526

tests/unit/test_app.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from tempfile import TemporaryDirectory
22
from unittest.mock import patch
33

4+
import docker
45
import escapism
56

67
from repo2docker.app import Repo2Docker
@@ -72,3 +73,32 @@ def test_local_dir_image_name(repo_with_content):
7273
assert app.output_image_spec.startswith(
7374
'r2d' + escapism.escape(upstream, escape_char='-').lower()
7475
)
76+
77+
78+
def test_build_kwargs(repo_with_content):
79+
upstream, sha1 = repo_with_content
80+
argv = [upstream]
81+
app = make_r2d(argv)
82+
app.extra_build_kwargs = {'somekey': "somevalue"}
83+
84+
with patch.object(docker.APIClient, 'build') as builds:
85+
builds.return_value = []
86+
app.build()
87+
builds.assert_called_once()
88+
args, kwargs = builds.call_args
89+
assert 'somekey' in kwargs
90+
assert kwargs['somekey'] == "somevalue"
91+
92+
93+
def test_run_kwargs(repo_with_content):
94+
upstream, sha1 = repo_with_content
95+
argv = [upstream]
96+
app = make_r2d(argv)
97+
app.extra_run_kwargs = {'somekey': "somevalue"}
98+
99+
with patch.object(docker.DockerClient, 'containers') as containers:
100+
app.start_container()
101+
containers.run.assert_called_once()
102+
args, kwargs = containers.run.call_args
103+
assert 'somekey' in kwargs
104+
assert kwargs['somekey'] == "somevalue"

0 commit comments

Comments
 (0)