示例#1
0
def update_repository(repository_dir, git_url, revision="origin/master"):
    """Get the latest version of a revision or clone the repository"""
    should_clone = True

    if io.exists(repository_dir):
        # If the target directory already exists
        remote_url = None

        try:
            remote_url = get_remote_url(repository_dir)
        except Exception:  # pylint: disable=broad-except
            # If the directory is not a git repository, `get_remote_url` will throw
            pass

        if remote_url == git_url:
            # If the remotes are the same, clean and fetch
            io.execute("git clean -dfx", repository_dir)
            io.execute("git fetch --all", repository_dir)

            # No need to clone
            should_clone = False
        else:
            # If the remotes mismatch, remove the old one
            io.remove(repository_dir)

    if should_clone:
        io.execute(f"git clone {git_url} {repository_dir}")
    io.execute(f"git reset --hard {revision}", repository_dir)
示例#2
0
    def test_remove_should_raise_if_failure(self, shutil_mock, os_mock):
        exception = OSError()
        shutil_mock.rmtree.side_effect = exception

        with self.assertRaises(OSError) as context:
            io.remove("path/to/remove")
        self.assertEqual(exception, context.exception)
        shutil_mock.rmtree.assert_called_once_with("path/to/remove")
        os_mock.remove.assert_not_called()
示例#3
0
def non_blocking_clean(path: str, *, message_prefix: str = None):
    """Try to clean directory/file at path but don't
    raise an error if it fails (only log it)."""
    message = "Error trying to clean temporary directory / file"
    if message_prefix is not None:
        message = message_prefix.strip() + f" {message}"

    try:
        io.remove(path)
        # pylint: disable=broad-except
    except Exception as err:
        Logger.warn({"path": path, "err": str(err)}, message)
示例#4
0
def write_and_deploy_configuration(cluster_name: str,
                                   yaml_config: str) -> None:
    """Write the kubernetes configuration into a local file and
    apply it on the cluster with the cli."""
    output_directory = io.create_temporary_directory()
    yaml_path = os.path.join(output_directory, "config.yaml")

    try:
        io.write(yaml_path, yaml_config)
        cli.apply_config(cluster_name, yaml_path)
    finally:
        io.remove(output_directory)
示例#5
0
def test_remove_directory_with_content():
    fixtures_directory_path = Path(os.path.dirname(__file__), "..",
                                   "__fixtures__").resolve()
    destination_path = Path(os.path.dirname(__file__), "..",
                            "__fixtures__copy").resolve()

    shutil.copytree(fixtures_directory_path, destination_path)

    assert os.path.isdir(destination_path)

    io.remove(destination_path)

    assert not os.path.isdir(destination_path)
示例#6
0
def test_remove_single_file():
    fixtures_directory_path = Path(os.path.dirname(__file__), "..",
                                   "__fixtures__", "example.yaml").resolve()
    destination_path = Path(os.path.dirname(__file__), "..", "__fixtures__",
                            "example_copy.yaml").resolve()

    shutil.copyfile(fixtures_directory_path, destination_path)

    assert os.path.isfile(destination_path)

    io.remove(destination_path)

    assert not os.path.isfile(destination_path)
示例#7
0
 def test_remove_directory_with_content(self, shutil_mock, os_mock):
     shutil_mock.rmtree.side_effect = OSError(errno.ENOTDIR, "some reason")
     io.remove("path/to/remove")
     shutil_mock.rmtree.assert_called_once_with("path/to/remove")
     os_mock.remove.assert_called_once_with("path/to/remove")
示例#8
0
 def test_remove_single_file(self, shutil_mock, os_mock):
     io.remove("path/to/remove")
     shutil_mock.rmtree.assert_called_once_with("path/to/remove")
     os_mock.remove.assert_not_called()
示例#9
0
def _differed_build(app_name: str):
    config_dir = None
    app_dir = None

    try:
        # Retrieve app's configuration
        config_dir = config.create_temporary_config_copy()
        config.change_environment(Configuration.get_config_default_branch(), config_dir)
        app_config = config.get_app_config(app_name, config_dir)
        Logger.debug(
            {"app": app_name, "config_directory": config_dir},
            "[/api/builds/:app] Application's configuration retrieved",
        )

        # Retrieve app's repository
        app_dir = git.create_working_repository(app_name, app_config["git"]["origin"])
        git.branch(app_dir, app_config["workflow"][0])
        Logger.debug(
            {"app": app_name, "working_directory": app_dir},
            "[/api/builds/:app] Application's repository retrieved",
        )

        try:
            # Create a new tag
            version = app.get_version(app_dir)
            git_tag = git.tag(app_dir, version)
            Logger.debug(
                {"app": app_name, "tag": git_tag}, "[/api/builds/:app] New tag created",
            )
        except Exception as err:
            # The tag may already exist
            Logger.warn(
                {"app": app_name, "err": err}, "[/api/builds/:app] Error while tagging the app"
            )

        # Build and publish the new docker image
        image_tag = docker.build(app_name, app_dir, app_config)
        Logger.debug(
            {"app": app_name, "image": image_tag}, "[/api/builds/:app] Docker image created"
        )
        docker.push(app_name, image_tag, app_config)
        Logger.debug(
            {"app": app_name, "image": image_tag},
            "[/api/builds/:app] Docker image published on registry",
        )

        # Send the new tag to git
        git.push(app_dir)
        Logger.debug({"app": app_name}, "[/api/builds/:app] Tag pushed to Git")

    except Exception as err:
        Logger.error(
            {"app": app_name, "err": err},
            "[/api/builds/:app] Error while tagging and building the app",
        )

    # Clean up temporary directories
    try:
        if config_dir is not None:
            io.remove(config_dir)
        if app_dir is not None:
            io.remove(app_dir)
    except Exception as err:
        Logger.error({"app": app_name, "err": err}, "[/api/builds/:app] Error during cleanup")
示例#10
0
def test_remove_should_raise_if_failure():
    with pytest.raises(Exception):
        not_existing_path = Path(os.path.dirname(__file__), "..",
                                 "__abcdefg").resolve()

        io.remove(not_existing_path)
示例#11
0
def init_workflow(organization, app):
    """Initialize the workflow of an application."""
    Logger.info(
        {"app": app, "organization": organization},
        "[/api/workflow/init/:org/:app] Workflow initialization started",
    )

    report = None
    try:
        # Retrieve project configuration
        config_dir = config_lib.create_temporary_config_copy()
        config_lib.change_environment(Configuration.get_config_default_branch(), config_dir)
        project_config = config_lib.get_project_config(config_dir)

        git_provider = get_git_provider(project_config)
        report_status, report = workflow_lib.init_workflow(organization, app, git_provider)

        if report_status == workflow_lib.WorkflowInitStatus.FAIL:
            status = HTTPStatus.INTERNAL_SERVER_ERROR
            message = "Workflow initialization failed"
        elif report_status == workflow_lib.WorkflowInitStatus.SUCCESS:
            status = HTTPStatus.OK
            message = "Workflow initialization succeeded"
        else:
            raise ValueError(f"Unexpected status: '{report_status}'")

        # Clean the temporary directory
        try:
            io_lib.remove(config_dir)
        # pylint: disable=broad-except
        except Exception as err:
            Logger.warn(
                {"config_dir": config_dir, "err": err}, "Failed to clean temporary config dir"
            )

        # HTTP Response
        Logger.info(
            {"organization": organization, "app": app, "report": report},
            f"[/api/workflow/init/:org/:app] {message}",
        )
        return (
            {"organization": organization, "app": app, "report": report, "message": message},
            status,
        )
    # pylint: disable=broad-except
    except Exception as err:
        Logger.error(
            {"organization": organization, "app": app, "report": report, "err": str(err)},
            "[/api/workflow/init/:org/:app] Workflow initialization failed",
        )

        # HTTP Response
        return (
            {
                "organization": organization,
                "app": app,
                "err": str(err),
                "message": "Workflow initialization failed",
            },
            HTTPStatus.INTERNAL_SERVER_ERROR,
        )