feat(build runner): added in context, dockerfile_location
this is a new feature meant to allow people to use any file as a dockerfile and any folder as a context directory
This commit is contained in:
parent
90b130fe16
commit
e6d201e0b0
29 changed files with 531 additions and 111 deletions
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from jsonschema import validate
|
||||
from six import add_metaclass
|
||||
|
@ -290,7 +291,7 @@ class BuildTriggerHandler(object):
|
|||
def get_dockerfile_path(self):
|
||||
""" Returns the normalized path to the Dockerfile found in the subdirectory
|
||||
in the config. """
|
||||
dockerfile_path = self.config.get('subdir') or 'Dockerfile'
|
||||
dockerfile_path = self.config.get('dockerfile_path') or 'Dockerfile'
|
||||
if dockerfile_path[0] == '/':
|
||||
dockerfile_path = dockerfile_path[1:]
|
||||
return dockerfile_path
|
||||
|
@ -303,10 +304,11 @@ class BuildTriggerHandler(object):
|
|||
ref = metadata.get('ref', None)
|
||||
commit_sha = metadata['commit']
|
||||
default_branch = metadata.get('default_branch', None)
|
||||
|
||||
prepared = PreparedBuild(self.trigger)
|
||||
prepared.name_from_sha(commit_sha)
|
||||
prepared.subdirectory = config.get('subdir', None)
|
||||
# TODO: Charlie Tuesday, March 28, 2017 come back and clean up subdirectory.
|
||||
prepared.subdirectory = config.get('dockerfile_path', None)
|
||||
prepared.context = config.get('context', None)
|
||||
prepared.is_manual = is_manual
|
||||
prepared.metadata = metadata
|
||||
|
||||
|
@ -327,3 +329,28 @@ class BuildTriggerHandler(object):
|
|||
namespaces = list(namespaces_dict.values())
|
||||
validate(namespaces, NAMESPACES_SCHEMA)
|
||||
return namespaces
|
||||
|
||||
@classmethod
|
||||
def get_parent_directory_mappings(cls, dockerfile_path, current_paths=None):
|
||||
""" Returns a map of dockerfile_paths to it's possible contexts. """
|
||||
if dockerfile_path == "":
|
||||
return {}
|
||||
|
||||
if dockerfile_path[0] != os.path.sep:
|
||||
dockerfile_path = os.path.sep + dockerfile_path
|
||||
|
||||
dockerfile_path = os.path.normpath(dockerfile_path)
|
||||
all_paths = set()
|
||||
path, _ = os.path.split(dockerfile_path)
|
||||
if path == "":
|
||||
path = os.path.sep
|
||||
|
||||
all_paths.add(path)
|
||||
for i in range(1, len(path.split(os.path.sep))):
|
||||
path, _ = os.path.split(path)
|
||||
all_paths.add(path)
|
||||
|
||||
if current_paths:
|
||||
return dict({dockerfile_path: list(all_paths)}, **current_paths)
|
||||
|
||||
return {dockerfile_path: list(all_paths)}
|
||||
|
|
|
@ -371,17 +371,22 @@ class GithubBuildTrigger(BuildTriggerHandler):
|
|||
raise RepositoryReadException(message)
|
||||
|
||||
path = self.get_dockerfile_path()
|
||||
if not path or not self.filename_is_dockerfile(os.path.basename(path)):
|
||||
if not path:
|
||||
return None
|
||||
|
||||
try:
|
||||
file_info = repo.get_file_contents(path)
|
||||
except GithubException as ghe:
|
||||
# TypeError is needed because directory inputs cause a TypeError
|
||||
except (GithubException, TypeError) as ghe:
|
||||
logger.error("got error from trying to find github file %s" % ghe)
|
||||
return None
|
||||
|
||||
if file_info is None:
|
||||
return None
|
||||
|
||||
if isinstance(file_info, list):
|
||||
return None
|
||||
|
||||
content = file_info.content
|
||||
if file_info.encoding == 'base64':
|
||||
content = base64.b64decode(content)
|
||||
|
|
|
@ -4,11 +4,11 @@ from mock import Mock
|
|||
from buildtrigger.bitbuckethandler import BitbucketBuildTrigger
|
||||
from util.morecollections import AttrDict
|
||||
|
||||
def get_bitbucket_trigger(subdir=''):
|
||||
def get_bitbucket_trigger(dockerfile_path=''):
|
||||
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
|
||||
trigger = BitbucketBuildTrigger(trigger_obj, {
|
||||
'build_source': 'foo/bar',
|
||||
'subdir': subdir,
|
||||
'dockerfile_path': dockerfile_path,
|
||||
'username': 'knownuser'
|
||||
})
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ from github import GithubException
|
|||
from buildtrigger.githubhandler import GithubBuildTrigger
|
||||
from util.morecollections import AttrDict
|
||||
|
||||
def get_github_trigger(subdir=''):
|
||||
def get_github_trigger(dockerfile_path=''):
|
||||
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
|
||||
trigger = GithubBuildTrigger(trigger_obj, {'build_source': 'foo', 'subdir': subdir})
|
||||
trigger = GithubBuildTrigger(trigger_obj, {'build_source': 'foo', 'dockerfile_path': dockerfile_path})
|
||||
trigger._get_client = get_mock_github
|
||||
return trigger
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ from mock import Mock
|
|||
from buildtrigger.gitlabhandler import GitLabBuildTrigger
|
||||
from util.morecollections import AttrDict
|
||||
|
||||
def get_gitlab_trigger(subdir=''):
|
||||
def get_gitlab_trigger(dockerfile_path=''):
|
||||
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
|
||||
trigger = GitLabBuildTrigger(trigger_obj, {
|
||||
'build_source': 'foo/bar',
|
||||
'subdir': subdir,
|
||||
'dockerfile_path': dockerfile_path,
|
||||
'username': 'knownuser'
|
||||
})
|
||||
|
||||
|
|
|
@ -13,3 +13,43 @@ from buildtrigger.basehandler import BuildTriggerHandler
|
|||
])
|
||||
def test_path_is_dockerfile(input, output):
|
||||
assert BuildTriggerHandler.filename_is_dockerfile(input) == output
|
||||
|
||||
|
||||
@pytest.mark.parametrize('input,output', [
|
||||
("", {}),
|
||||
("/a", {"/a": ["/"]}),
|
||||
("a", {"/a": ["/"]}),
|
||||
("/b/a", {"/b/a": ["/b", "/"]}),
|
||||
("b/a", {"/b/a": ["/b", "/"]}),
|
||||
("/c/b/a", {"/c/b/a": ["/c/b", "/c", "/"]}),
|
||||
("/a//b//c", {"/a/b/c": ["/", "/a", "/a/b"]}),
|
||||
("/a", {"/a": ["/"]}),
|
||||
])
|
||||
def test_subdir_path_map_no_previous(input, output):
|
||||
actual_mapping = BuildTriggerHandler.get_parent_directory_mappings(input)
|
||||
for key in actual_mapping:
|
||||
value = actual_mapping[key]
|
||||
actual_mapping[key] = value.sort()
|
||||
for key in output:
|
||||
value = output[key]
|
||||
output[key] = value.sort()
|
||||
|
||||
assert actual_mapping == output
|
||||
|
||||
|
||||
@pytest.mark.parametrize('new_path,original_dictionary,output', [
|
||||
("/a", {}, {"/a": ["/"]}),
|
||||
("b", {"/a": ["some_path", "another_path"]}, {"/a": ["some_path", "another_path"], "/b": ["/"]}),
|
||||
("/a/b/c/d", {"/e": ["some_path", "another_path"]},
|
||||
{"/e": ["some_path", "another_path"], "/a/b/c/d": ["/", "/a", "/a/b", "/a/b/c"]}),
|
||||
])
|
||||
def test_subdir_path_map(new_path, original_dictionary, output):
|
||||
actual_mapping = BuildTriggerHandler.get_parent_directory_mappings(new_path, original_dictionary)
|
||||
for key in actual_mapping:
|
||||
value = actual_mapping[key]
|
||||
actual_mapping[key] = value.sort()
|
||||
for key in output:
|
||||
value = output[key]
|
||||
output[key] = value.sort()
|
||||
|
||||
assert actual_mapping == output
|
||||
|
|
|
@ -16,13 +16,13 @@ def test_list_build_subdirs(bitbucket_trigger):
|
|||
assert bitbucket_trigger.list_build_subdirs() == ["/Dockerfile"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('subdir, contents', [
|
||||
@pytest.mark.parametrize('dockerfile_path, contents', [
|
||||
('/Dockerfile', 'hello world'),
|
||||
('somesubdir/Dockerfile', 'hi universe'),
|
||||
('unknownpath', None),
|
||||
])
|
||||
def test_load_dockerfile_contents(subdir, contents):
|
||||
trigger = get_bitbucket_trigger(subdir)
|
||||
def test_load_dockerfile_contents(dockerfile_path, contents):
|
||||
trigger = get_bitbucket_trigger(dockerfile_path)
|
||||
assert trigger.load_dockerfile_contents() == contents
|
||||
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ def test_handle_trigger_request(github_trigger, payload, expected_error, expecte
|
|||
assert isinstance(github_trigger.handle_trigger_request(request), PreparedBuild)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('subdir, contents', [
|
||||
@pytest.mark.parametrize('dockerfile_path, contents', [
|
||||
('/Dockerfile', 'hello world'),
|
||||
('somesubdir/Dockerfile', 'hi universe'),
|
||||
('unknownpath', None),
|
||||
])
|
||||
def test_load_dockerfile_contents(subdir, contents):
|
||||
trigger = get_github_trigger(subdir)
|
||||
def test_load_dockerfile_contents(dockerfile_path, contents):
|
||||
trigger = get_github_trigger(dockerfile_path)
|
||||
assert trigger.load_dockerfile_contents() == contents
|
||||
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@ def test_list_build_subdirs(gitlab_trigger):
|
|||
assert gitlab_trigger.list_build_subdirs() == ['/Dockerfile']
|
||||
|
||||
|
||||
@pytest.mark.parametrize('subdir, contents', [
|
||||
@pytest.mark.parametrize('dockerfile_path, contents', [
|
||||
('/Dockerfile', 'hello world'),
|
||||
('somesubdir/Dockerfile', 'hi universe'),
|
||||
('unknownpath', None),
|
||||
])
|
||||
def test_load_dockerfile_contents(subdir, contents):
|
||||
trigger = get_gitlab_trigger(subdir)
|
||||
def test_load_dockerfile_contents(dockerfile_path, contents):
|
||||
trigger = get_gitlab_trigger(dockerfile_path)
|
||||
assert trigger.load_dockerfile_contents() == contents
|
||||
|
||||
|
||||
|
|
Reference in a new issue