Inject docker.APIClient into methods that need them
Creating a new client with 'auto' version causes repeated
unnecessary network requests to discover version of docker daemon.
Testing is easier this way, since we can inject a mocked docker
client more easily
MODIFY
repo2docker/app.py
repo2docker/app.py
@@ -697,13 +697,11 @@ class Repo2Docker(Application):
return port
def start(self):
- """Start execution of repo2docker"""
- # Check if r2d can connect to docker daemon
+ """Start execution of repo2docker""" # Check if r2d can connect to docker daemon
if self.build:
try:
- client = docker.APIClient(version='auto',
+ api_client = docker.APIClient(version='auto',
**kwargs_from_env())
- del client
except DockerException as e:
print("Docker client initialization error. Check if docker is"
" running on the host.")
@@ -759,7 +757,7 @@ class Repo2Docker(Application):
self.log.info('Using %s builder\n', bp.__class__.__name__,
extra=dict(phase='building'))
- for l in picked_buildpack.build(self.output_image_spec,
+ for l in picked_buildpack.build(api_client, self.output_image_spec,
self.build_memory_limit, build_args):
if 'stream' in l:
self.log.info(l['stream'],

MODIFY
repo2docker/buildpacks/base.py
repo2docker/buildpacks/base.py
@@ -449,7 +449,7 @@ class BuildPack:
appendix=self.appendix,
)
- def build(self, image_spec, memory_limit, build_args, cache_from):
+ def build(self, client, image_spec, memory_limit, build_args, cache_from):
tarf = io.BytesIO()
tar = tarfile.open(fileobj=tarf, mode='w')
dockerfile_tarinfo = tarfile.TarInfo("Dockerfile")
@@ -489,8 +489,6 @@ class BuildPack:
}
if memory_limit:
limits['memory'] = memory_limit
- client = docker.APIClient(version='auto',
- **docker.utils.kwargs_from_env())
for line in client.build(
fileobj=tarf,
tag=image_spec,

MODIFY
repo2docker/buildpacks/docker.py
repo2docker/buildpacks/docker.py
@@ -19,7 +19,7 @@ class DockerBuildPack(BuildPack):
with open(Dockerfile) as f:
return f.read()
- def build(self, image_spec, memory_limit, build_args, cache_from):
+ def build(self, client, image_spec, memory_limit, build_args, cache_from):
"""Build a Docker image based on the Dockerfile in the source repo."""
limits = {
# Always disable memory swap for building, since mostly
@@ -28,7 +28,6 @@ class DockerBuildPack(BuildPack):
}
if memory_limit:
limits['memory'] = memory_limit
- client = docker.APIClient(version='auto', **docker.utils.kwargs_from_env())
for line in client.build(
path=os.getcwd(),
dockerfile=self.binder_path(self.dockerfile),

MODIFY
repo2docker/buildpacks/legacy/__init__.py
repo2docker/buildpacks/legacy/__init__.py
@@ -83,7 +83,7 @@ class LegacyBinderDockerBuildPack(DockerBuildPack):
'legacy/python3.frozen.yml': '/tmp/python3.frozen.yml',
}
- def build(self, image_spec, memory_limit, build_args, cache_from):
+ def build(self, client, image_spec, memory_limit, build_args, cache_from):
"""Build a legacy Docker image."""
with open(self.dockerfile, 'w') as f:
f.write(self.render())
@@ -94,7 +94,7 @@ class LegacyBinderDockerBuildPack(DockerBuildPack):
env_file,
)
shutil.copy(src_path, env_file)
- return super().build(image_spec, memory_limit, build_args, cache_from)
+ return super().build(client, image_spec, memory_limit, build_args, cache_from)
def detect(self):
"""Check if current repo should be built with the Legacy BuildPack.

Inject docker.APIClient into methods that need them

- Creating a new client with 'auto' version causes repeated
  unnecessary network requests to discover version of docker daemon.
- Testing is easier this way, since we can inject a mocked docker
  client more easily