diff --git a/data/model/build.py b/data/model/build.py index 1b7355af7..605259e14 100644 --- a/data/model/build.py +++ b/data/model/build.py @@ -1,13 +1,15 @@ import json - -from peewee import JOIN_LEFT_OUTER +import os from datetime import timedelta, datetime +from peewee import JOIN_LEFT_OUTER + +import features from data.database import (BuildTriggerService, RepositoryBuildTrigger, Repository, Namespace, User, RepositoryBuild, BUILD_PHASE, db_for_update, db_random_func) from data.model import (InvalidBuildTriggerException, InvalidRepositoryBuildException, db_transaction, user as user_model) - +from data.model.helpers.build_helper import _get_config_expand PRESUMED_DEAD_BUILD_AGE = timedelta(days=15) PHASES_NOT_ALLOWED_TO_CANCEL_FROM = (BUILD_PHASE.PUSHING, BUILD_PHASE.COMPLETE, @@ -15,8 +17,9 @@ PHASES_NOT_ALLOWED_TO_CANCEL_FROM = (BUILD_PHASE.PUSHING, BUILD_PHASE.COMPLETE, ARCHIVABLE_BUILD_PHASES = [BUILD_PHASE.COMPLETE, BUILD_PHASE.ERROR, BUILD_PHASE.CANCELLED] + def update_build_trigger(trigger, config, auth_token=None): - trigger.config = json.dumps(config or {}) + trigger.config = json.dumps(_get_config_expand(config or {})) if auth_token is not None: trigger.auth_token = auth_token trigger.save() @@ -29,10 +32,12 @@ def create_build_trigger(repo, service_name, auth_token, user, pull_robot=None, auth_token=auth_token, connected_user=user, pull_robot=pull_robot, - config=json.dumps(config)) + config=json.dumps(_get_config_expand(config))) return trigger + + def get_build_trigger(trigger_uuid): try: return (RepositoryBuildTrigger @@ -168,6 +173,7 @@ def update_phase(build_uuid, phase): def create_cancel_build_in_queue(build, build_queue): """ A function to cancel a build before it leaves the queue """ + def cancel_build(): cancelled = False @@ -184,6 +190,7 @@ def create_cancel_build_in_queue(build, build_queue): def create_cancel_build_in_manager(build, build_canceller): """ A function to cancel the build before it starts to push """ + def cancel_build(): if build.phase in PHASES_NOT_ALLOWED_TO_CANCEL_FROM: return False @@ -239,4 +246,3 @@ def get_archivable_build(): return RepositoryBuild.get(id=found_id) except RepositoryBuild.DoesNotExist: return None - diff --git a/data/model/helpers/__init__.py b/data/model/helpers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/data/model/helpers/build_helper.py b/data/model/helpers/build_helper.py new file mode 100644 index 000000000..7de9da254 --- /dev/null +++ b/data/model/helpers/build_helper.py @@ -0,0 +1,44 @@ +import os + + +def _get_config_expand(config): + """ Get config with both context and dockerfile_path written to it """ + if config and "subdir" in config and "context" not in config: + config_expand = dict(config) + config_expand["context"] = _create_context(config["subdir"]) + config_expand["dockerfile_path"] = _create_dockerfile_path(config["subdir"]) + return config_expand + return config or {} + + +def _create_context(current_subdir): + """ Create context from current subdir """ + if current_subdir.endswith("Dockerfile"): + context, _ = os.path.split(current_subdir) + if context == "": + return os.path.sep + + return context + + if current_subdir == "": + current_subdir = os.path.sep + current_subdir + + if current_subdir[len(current_subdir) - 1] != os.path.sep: + current_subdir += os.path.sep + + context, _ = os.path.split(current_subdir) + return context + + +def _create_dockerfile_path(current_subdir): + """ Create dockefile path from current subdir """ + if current_subdir.endswith("Dockerfile"): + return current_subdir + + if current_subdir == "": + current_subdir = os.path.sep + current_subdir + + if current_subdir[len(current_subdir) - 1] != os.path.sep: + current_subdir += os.path.sep + + return current_subdir + "Dockerfile" diff --git a/data/model/helpers/test/test_build_helper.py b/data/model/helpers/test/test_build_helper.py new file mode 100644 index 000000000..cfb792d6f --- /dev/null +++ b/data/model/helpers/test/test_build_helper.py @@ -0,0 +1,30 @@ +import pytest + +from data.model.helpers.build_helper import _get_config_expand + + +@pytest.mark.parametrize('org_config,expected', [ + # Empty config + (None, {}), + + # No subdir in config + ({}, {}), + + ({"subdir": ""}, {"context": "/", "dockerfile_path": "/Dockerfile", "subdir": ""}), + ({"subdir": "/"}, {"context": "/", "dockerfile_path": "/Dockerfile", "subdir": "/"}), + ({"subdir": "/Dockerfile"}, {"context": "/", "dockerfile_path": "/Dockerfile", "subdir": "/Dockerfile"}), + ({"subdir": "a"}, {"context": "a", "dockerfile_path": "a/Dockerfile", "subdir": "a"}), + ({"subdir": "Dockerfile"}, {"context": "/", "dockerfile_path": "Dockerfile", "subdir": "Dockerfile"}), + ({"subdir": "server.Dockerfile"}, + {"context": "/", "dockerfile_path": "server.Dockerfile", "subdir": "server.Dockerfile"}), + ({"subdir": "/a/b/Dockerfile"}, + {"context": "/a/b", "dockerfile_path": "/a/b/Dockerfile", "subdir": "/a/b/Dockerfile"}), + ({"subdir": "/a/b/server.Dockerfile"}, + {"context": "/a/b", "dockerfile_path": "/a/b/server.Dockerfile", "subdir": "/a/b/server.Dockerfile"}), + ({"subdir": "a/b/Dockerfile"}, {"context": "a/b", "dockerfile_path": "a/b/Dockerfile", "subdir": "a/b/Dockerfile"}), + ({"subdir": "a/b/server.Dockerfile"}, + {"context": "a/b", "dockerfile_path": "a/b/server.Dockerfile", "subdir": "a/b/server.Dockerfile"}), + ({"subdir": "/a/b/c", "context": "slime"}, {"context": "slime", "subdir": "/a/b/c"}), +]) +def test_super_user_build_endpoints(org_config, expected): + assert _get_config_expand(org_config) == expected