WIP: Start implementation of the build manager/controller. This code is not yet working completely.

This commit is contained in:
Joseph Schorr 2014-11-11 18:23:15 -05:00
parent 2ccbea95a5
commit eacf3f01d2
9 changed files with 576 additions and 0 deletions

86
buildman/buildpack.py Normal file
View file

@ -0,0 +1,86 @@
import tarfile
from tempfile import TemporaryFile, mkdtemp
from zipfile import ZipFile
from util.dockerfileparse import parse_dockerfile, ParsedDockerfile
class BuildPackageException(Exception):
""" Exception raised when retrieving or parsing a build package. """
pass
class BuildPackage(object):
""" Helper class for easy reading and updating of a Dockerfile build pack. """
def __init__(self, requests_file):
self._mime_processors = {
'application/zip': BuildPack.__prepare_zip,
'application/x-zip-compressed': BuildPack.__prepare_zip,
'text/plain': BuildPack.__prepare_dockerfile,
'application/octet-stream': BuildPack.__prepare_dockerfile,
'application/x-tar': BuildPack.__prepare_tarball,
'application/gzip': BuildPack.__prepare_tarball,
'application/x-gzip': BuildPack.__prepare_tarball,
}
c_type = buildpack_resource.headers['content-type']
c_type = c_type.split(';')[0] if ';' in c_type else c_type
if c_type not in self._mime_processors:
raise BuildPackageException('Unknown build package mime type: %s' % c_type)
self._package_directory = None
try:
self._package_directory = self._mime_processors[c_type](requests_file)
except Exception as ex:
raise BuildPackageException(ex.message)
def parse_dockerfile(self, build_subdirectory):
dockerfile_path = os.path.join(self._package_directory, subdirectory, 'Dockerfile')
if not os.path.exists(dockerfile_path):
if subdirectory:
message = 'Build package did not contain a Dockerfile at sub directory %s.' % subdirectory
else:
message = 'Build package did not contain a Dockerfile at the root directory.'
raise BuildPackageException(message)
with open(dockerfile_path, 'r') as dockerfileobj:
return parse_dockerfile(dockerfileobj.read())
@classmethod
def from_url(url):
buildpack_resource = requests.get(buildpack_url, stream=True)
return BuildPackage(buildpack_resource, c_type)
@staticmethod
def __prepare_zip(request_file):
build_dir = mkdtemp(prefix='docker-build-')
# Save the zip file to temp somewhere
with TemporaryFile() as zip_file:
zip_file.write(request_file.content)
to_extract = ZipFile(zip_file)
to_extract.extractall(build_dir)
return build_dir
@staticmethod
def __prepare_dockerfile(request_file):
build_dir = mkdtemp(prefix='docker-build-')
dockerfile_path = os.path.join(build_dir, "Dockerfile")
with open(dockerfile_path, 'w') as dockerfile:
dockerfile.write(request_file.content)
return build_dir
@staticmethod
def __prepare_tarball(request_file):
build_dir = mkdtemp(prefix='docker-build-')
# Save the zip file to temp somewhere
with tarfile.open(mode='r|*', fileobj=request_file.raw) as tar_stream:
safe_extractall(tar_stream, build_dir)
return build_dir