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 tarfile
import base64
from StringIO import StringIO
from github import Github, UnknownObjectException, GithubException
from tempfile import SpooledTemporaryFile
@ -297,14 +298,50 @@ class GithubBuildTrigger(BuildTrigger):
# Seek to position 0 to make tarfile happy
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:
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)
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')

View file

@ -38,8 +38,7 @@ TIMEOUT_PERIOD_MINUTES = 20
CACHE_EXPIRATION_PERIOD_HOURS = 24
NO_TAGS = ['<none>:<none>']
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):
""" Returns true if the given status string matches a known system error in the
@ -521,8 +520,12 @@ class DockerfileBuildWorker(Worker):
repository_build.uuid)
# Lookup and save the version of docker being used.
docker_cl = Client(base_url = DOCKER_BASE_URL)
docker_version = docker_cl.version().get('Version', '')
try:
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('-')
# Strip any -tutum or whatever off of the version.