Use a new caching algorithm which can limit the size for the build nodes. Stop treating public images as special. Add a new phase to the builder for pulling.

This commit is contained in:
Jake Moshenko 2014-04-30 18:48:36 -04:00
parent 4e36be1a88
commit 450928674b
5 changed files with 188 additions and 180 deletions

View file

@ -4,23 +4,27 @@ LINE_CONTINUATION_REGEX = re.compile('\s*\\\s*\n')
COMMAND_REGEX = re.compile('([A-Za-z]+)\s(.*)')
COMMENT_CHARACTER = '#'
LATEST_TAG = 'latest'
class ParsedDockerfile(object):
def __init__(self, commands):
self.commands = commands
def get_commands_of_kind(self, kind):
def _get_commands_of_kind(self, kind):
return [command for command in self.commands if command['command'] == kind]
def get_base_image(self):
image_and_tag = self.get_base_image_and_tag()
if not image_and_tag:
def _get_from_image_identifier(self):
from_commands = self._get_commands_of_kind('FROM')
if not from_commands:
return None
return self.base_image_from_repo_identifier(image_and_tag)
return from_commands[-1]['parameters']
@staticmethod
def base_image_from_repo_identifier(image_and_tag):
def parse_image_identifier(image_identifier):
""" Parses a docker image identifier, and returns a tuple of image name and tag, where the tag
is filled in with "latest" if left unspecified.
"""
# Note:
# Dockerfile images references can be of multiple forms:
# server:port/some/path
@ -28,29 +32,34 @@ class ParsedDockerfile(object):
# server/some/path
# server/some/path:tag
# server:port/some/path:tag
parts = image_and_tag.strip().split(':')
parts = image_identifier.strip().split(':')
if len(parts) == 1:
# somepath
return parts[0]
return (parts[0], LATEST_TAG)
# Otherwise, determine if the last part is a port
# or a tag.
if parts[-1].find('/') >= 0:
# Last part is part of the hostname.
return image_and_tag
return (image_identifier, LATEST_TAG)
# Remaining cases:
# server/some/path:tag
# server:port/some/path:tag
return ':'.join(parts[0:-1])
return (':'.join(parts[0:-1]), parts[-1])
def get_base_image_and_tag(self):
from_commands = self.get_commands_of_kind('FROM')
if not from_commands:
return None
def get_base_image(self):
""" Return the base image without the tag name. """
return self.get_image_and_tag()[0]
return from_commands[-1]['parameters']
def get_image_and_tag(self):
""" Returns the image and tag from the FROM line of the dockerfile. """
image_identifier = self._get_from_image_identifier()
if image_identifier is None:
return (None, None)
return self.parse_image_identifier(image_identifier)
def strip_comments(contents):