Add a synthetic .git directory containing the commit sha so that 'git rev-parse HEAD' works from inside builds

This commit is contained in:
Joseph Schorr 2014-10-10 17:20:07 -04:00
parent 49f8629566
commit 07f3bd6f8c
2 changed files with 48 additions and 8 deletions

View file

@ -3,6 +3,7 @@ import io
import os.path import os.path
import tarfile import tarfile
import base64 import base64
from StringIO import StringIO
from github import Github, UnknownObjectException, GithubException from github import Github, UnknownObjectException, GithubException
from tempfile import SpooledTemporaryFile from tempfile import SpooledTemporaryFile
@ -297,14 +298,50 @@ class GithubBuildTrigger(BuildTrigger):
# Seek to position 0 to make tarfile happy # Seek to position 0 to make tarfile happy
tarball.seek(0) tarball.seek(0)
# Pull out the name of the subdir that GitHub generated # Pull out the name of the subdir that GitHub generated.
with tarfile.open(fileobj=tarball) as archive: with tarfile.open(fileobj=tarball) as archive:
tarball_subdir = archive.getnames()[0] tarball_subdir = archive.getnames()[0]
tarball_subdir_info = archive.getmember(tarball_subdir)
# Seek to position 0 to make boto multipart happy # Seek to position 0 to make tarfile happy
tarball.seek(0) tarball.seek(0)
dockerfile_id = user_files.store_file(tarball, TARBALL_MIME) with SpooledTemporaryFile(CHUNK_SIZE) as updated_tarball:
def add_entry(arch, dir_path, base_info, contents=None):
info = tarfile.TarInfo(dir_path)
info.uid = base_info.uid
info.gid = base_info.gid
info.uname = base_info.uname
info.gname = base_info.gname
info.mode = base_info.mode
info.mtime = base_info.mtime
info.type = tarfile.REGTYPE if contents else tarfile.DIRTYPE
if contents:
info.size = len(contents)
arch.addfile(info, fileobj=StringIO(contents) if contents else None)
with tarfile.open(fileobj=updated_tarball, mode='w|gz') as updated_archive:
# Copy existing members of the tar to the updated archive.
with tarfile.open(fileobj=tarball) as archive:
for tar_info in archive:
if tar_info.isreg():
updated_archive.addfile(tar_info, archive.extractfile(tar_info.name))
else:
updated_archive.addfile(tar_info)
# Add the synthetic .git directory to the tarball, containing the commit_sha.
add_entry(updated_archive, tarball_subdir + '/.git/HEAD', tarball_subdir_info,
contents=commit_sha)
add_entry(updated_archive, tarball_subdir + '/.git/objects/', tarball_subdir_info)
add_entry(updated_archive, tarball_subdir + '/.git/refs/', tarball_subdir_info)
# Seek to position 0 to make boto multipart happy
updated_tarball.seek(0)
dockerfile_id = user_files.store_file(updated_tarball, TARBALL_MIME)
logger.debug('Successfully prepared job') logger.debug('Successfully prepared job')

View file

@ -38,8 +38,7 @@ TIMEOUT_PERIOD_MINUTES = 20
CACHE_EXPIRATION_PERIOD_HOURS = 24 CACHE_EXPIRATION_PERIOD_HOURS = 24
NO_TAGS = ['<none>:<none>'] NO_TAGS = ['<none>:<none>']
RESERVATION_TIME = (TIMEOUT_PERIOD_MINUTES + 5) * 60 RESERVATION_TIME = (TIMEOUT_PERIOD_MINUTES + 5) * 60
DOCKER_BASE_URL = None # Set this if you want to use a different docker URL/socket. DOCKER_BASE_URL = os.environ.get('DOCKER_HOST', None)
def matches_system_error(status_str): def matches_system_error(status_str):
""" Returns true if the given status string matches a known system error in the """ Returns true if the given status string matches a known system error in the
@ -521,8 +520,12 @@ class DockerfileBuildWorker(Worker):
repository_build.uuid) repository_build.uuid)
# Lookup and save the version of docker being used. # Lookup and save the version of docker being used.
docker_cl = Client(base_url = DOCKER_BASE_URL) try:
docker_version = docker_cl.version().get('Version', '') docker_cl = Client(base_url = DOCKER_BASE_URL)
docker_version = docker_cl.version().get('Version', '')
except ConnectionError as exc:
raise WorkerUnhealthyException(exc.message)
dash = docker_version.find('-') dash = docker_version.find('-')
# Strip any -tutum or whatever off of the version. # Strip any -tutum or whatever off of the version.