Bug 1432390 - Directly call the docker API over its unix socket instead of calling `docker build`. r=dustin

This allows to avoid writing out a tar file to then extract it to feed
it to `docker build`. This is essentially what the image-builder docker
image does, except it uses a temporary file for the tar.

--HG--
extra : rebase_source : 8275d737e02714fc198d3ba3d3e62e3f18d8e0bf
This commit is contained in:
Mike Hommey 2018-01-24 15:55:31 +09:00
Родитель 378f47ff49
Коммит f5386c6b51
2 изменённых файлов: 3 добавлений и 61 удалений

Просмотреть файл

@ -8,10 +8,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import json
import os
import subprocess
import tarfile
import tempfile
import which
from io import BytesIO
from taskgraph.util import docker
@ -81,26 +78,9 @@ def build_image(name, args=None):
tag = docker.docker_image(name, by_tag=True)
docker_bin = which.which('docker')
# Verify that Docker is working.
try:
subprocess.check_output([docker_bin, '--version'])
except subprocess.CalledProcessError:
raise Exception('Docker server is unresponsive. Run `docker ps` and '
'check that Docker is running')
# We obtain a context archive and build from that. Going through the
# archive creation is important: it normalizes things like file owners
# and mtimes to increase the chances that image generation is
# deterministic.
fd, context_path = tempfile.mkstemp()
os.close(fd)
try:
docker.create_context_tar(GECKO, image_dir, context_path, name, args)
docker.build_from_context(docker_bin, context_path, name, tag)
finally:
os.unlink(context_path)
buf = BytesIO()
docker.stream_context_tar(GECKO, image_dir, buf, '', args)
docker.post_to_docker(buf.getvalue(), '/build', nocache=1, t=tag)
print('Successfully built %s and tagged with %s' % (name, tag))

Просмотреть файл

@ -9,11 +9,7 @@ import json
import os
import re
import requests_unixsocket
import shutil
import subprocess
import sys
import tarfile
import tempfile
import urllib
import urlparse
import yaml
@ -261,40 +257,6 @@ def stream_context_tar(topsrcdir, context_dir, out_file, prefix, args=None):
return writer.hexdigest()
def build_from_context(docker_bin, context_path, prefix, tag=None):
"""Build a Docker image from a context archive.
Given the path to a `docker` binary, a image build tar.gz (produced with
``create_context_tar()``, a prefix in that context containing files, and
an optional ``tag`` for the produced image, build that Docker image.
"""
d = tempfile.mkdtemp()
try:
with tarfile.open(context_path, 'r:gz') as tf:
tf.extractall(d)
# If we wanted to do post-processing of the Dockerfile, this is
# where we'd do it.
args = [
docker_bin,
'build',
# Use --no-cache so we always get the latest package updates.
'--no-cache',
]
if tag:
args.extend(['-t', tag])
args.append('.')
res = subprocess.call(args, cwd=os.path.join(d, prefix))
if res:
raise Exception('error building image')
finally:
shutil.rmtree(d)
@memoize
def image_paths():
"""Return a map of image name to paths containing their Dockerfile.