Skip to content

Commit e2fef06

Browse files
committed
Merge pull request #570 from docker/build_limits
Build limits
2 parents 2eadd58 + 8c32677 commit e2fef06

File tree

4 files changed

+118
-80
lines changed

4 files changed

+118
-80
lines changed

docker/client.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,22 @@
2424
import requests.exceptions
2525
import six
2626

27+
from . import constants
28+
from . import errors
2729
from .auth import auth
2830
from .unixconn import unixconn
2931
from .ssladapter import ssladapter
3032
from .utils import utils, check_resource
31-
from . import errors
3233
from .tls import TLSConfig
3334

3435

3536
if not six.PY3:
3637
import websocket
3738

38-
DEFAULT_DOCKER_API_VERSION = '1.18'
39-
DEFAULT_TIMEOUT_SECONDS = 60
40-
STREAM_HEADER_SIZE_BYTES = 8
41-
4239

4340
class Client(requests.Session):
4441
def __init__(self, base_url=None, version=None,
45-
timeout=DEFAULT_TIMEOUT_SECONDS, tls=False):
42+
timeout=constants.DEFAULT_TIMEOUT_SECONDS, tls=False):
4643
super(Client, self).__init__()
4744

4845
if tls and not base_url.startswith('https://'):
@@ -70,7 +67,7 @@ def __init__(self, base_url=None, version=None,
7067

7168
# version detection needs to be after unix adapter mounting
7269
if version is None:
73-
self._version = DEFAULT_DOCKER_API_VERSION
70+
self._version = constants.DEFAULT_DOCKER_API_VERSION
7471
elif isinstance(version, six.string_types):
7572
if version.lower() == 'auto':
7673
self._version = self._retrieve_server_version()
@@ -218,7 +215,7 @@ def _multiplexed_buffer_helper(self, response):
218215
if len(buf[walker:]) < 8:
219216
break
220217
_, length = struct.unpack_from('>BxxxL', buf[walker:])
221-
start = walker + STREAM_HEADER_SIZE_BYTES
218+
start = walker + constants.STREAM_HEADER_SIZE_BYTES
222219
end = start + length
223220
walker = end
224221
yield buf[start:end]
@@ -236,7 +233,7 @@ def _multiplexed_response_stream_helper(self, response):
236233
socket.settimeout(None)
237234

238235
while True:
239-
header = response.raw.read(STREAM_HEADER_SIZE_BYTES)
236+
header = response.raw.read(constants.STREAM_HEADER_SIZE_BYTES)
240237
if not header:
241238
break
242239
_, length = struct.unpack('>BxxxL', header)
@@ -310,11 +307,18 @@ def attach_socket(self, container, params=None, ws=False):
310307
def build(self, path=None, tag=None, quiet=False, fileobj=None,
311308
nocache=False, rm=False, stream=False, timeout=None,
312309
custom_context=False, encoding=None, pull=True,
313-
forcerm=False, dockerfile=None):
310+
forcerm=False, dockerfile=None, container_limits=None):
314311
remote = context = headers = None
312+
container_limits = container_limits or {}
315313
if path is None and fileobj is None:
316314
raise TypeError("Either path or fileobj needs to be provided.")
317315

316+
for key in container_limits.keys():
317+
if key not in constants.CONTAINER_LIMITS_KEYS:
318+
raise errors.DockerException(
319+
'Invalid container_limits key {0}'.format(key)
320+
)
321+
318322
if custom_context:
319323
if not fileobj:
320324
raise TypeError("You must specify fileobj with custom_context")
@@ -357,8 +361,9 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
357361
'rm': rm,
358362
'forcerm': forcerm,
359363
'pull': pull,
360-
'dockerfile': dockerfile
364+
'dockerfile': dockerfile,
361365
}
366+
params.update(container_limits)
362367

363368
if context is not None:
364369
headers = {'Content-Type': 'application/tar'}

docker/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
DEFAULT_DOCKER_API_VERSION = '1.18'
2+
DEFAULT_TIMEOUT_SECONDS = 60
3+
STREAM_HEADER_SIZE_BYTES = 8
4+
CONTAINER_LIMITS_KEYS = [
5+
'memory', 'memswap', 'cpushares', 'cpusetcpus'
6+
]

docs/api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ correct value (e.g `gzip`).
6565
* pull (bool): Downloads any updates to the FROM image in Dockerfiles
6666
* forcerm (bool): Always remove intermediate containers, even after unsuccessful builds
6767
* dockerfile (str): path within the build context to the Dockerfile
68+
* container_limits (dict): A dictionary of limits applied to each container
69+
created by the build process. Valid keys:
70+
- memory (int): set memory limit for build
71+
- memswap (int): Total memory (memory + swap), -1 to disable swap
72+
- cpushares (int): CPU shares (relative weight)
73+
- cpusetcpus (str): CPUs in which to allow exection, e.g., `"0-3"`, `"0,1"`
6874

6975
**Returns** (generator): A generator of the build output
7076

0 commit comments

Comments
 (0)