Пример #1
0
def build_jupyter_task(task_uuid):
    """Function called by the celery task to build Jupyter image.

    Builds a Jupyter (docker image) given the arguments, the logs
    produced by the user provided script are forwarded to a SocketIO
    server and namespace defined in the orchest internals config.

    Args:
        task_uuid:

    Returns:

    """
    with requests.sessions.Session() as session:

        try:
            update_jupyter_build_status("STARTED", session, task_uuid)

            # Prepare the project snapshot with the correctly placed
            # dockerfile, scripts, etc.
            build_context = prepare_build_context(task_uuid)

            # Use the agreed upon pattern for the docker image name.
            docker_image_name = _config.JUPYTER_IMAGE_NAME

            if not os.path.exists(__JUPYTER_BUILD_FULL_LOGS_DIRECTORY):
                os.mkdir(__JUPYTER_BUILD_FULL_LOGS_DIRECTORY)
            # place the logs in the celery container
            complete_logs_path = os.path.join(
                __JUPYTER_BUILD_FULL_LOGS_DIRECTORY, docker_image_name
            )

            status = SioStreamedTask.run(
                # What we are actually running/doing in this task,
                task_lambda=lambda user_logs_fo: build_docker_image(
                    docker_image_name,
                    build_context,
                    task_uuid,
                    user_logs_fo,
                    complete_logs_path,
                ),
                identity="jupyter",
                server=_config.ORCHEST_SOCKETIO_SERVER_ADDRESS,
                namespace=_config.ORCHEST_SOCKETIO_JUPYTER_BUILDING_NAMESPACE,
                # note: using task.is_aborted() could be an option but
                # it was giving some issues related to
                # multithreading/processing, moreover, also just passing
                # the task_uuid to this function is less information to
                # rely on, which is good.
                abort_lambda=lambda: AbortableAsyncResult(task_uuid).is_aborted(),
            )

            # cleanup
            os.system('rm -rf "%s"' % build_context["snapshot_path"])

            update_jupyter_build_status(status, session, task_uuid)

        # Catch all exceptions because we need to make sure to set the
        # build state to failed.
        except Exception as e:
            update_jupyter_build_status("FAILURE", session, task_uuid)
            raise e
        finally:
            filters = {
                "label": [
                    "_orchest_jupyter_build_is_intermediate=1",
                    f"_orchest_jupyter_build_task_uuid={task_uuid}",
                ]
            }

            # Artifacts of this build (intermediate containers, images,
            # etc.)
            cleanup_docker_artifacts(filters)

    # The status of the Celery task is SUCCESS since it has finished
    # running. Not related to the actual state of the build, e.g.
    # FAILURE.
    return "SUCCESS"
Пример #2
0
def build_environment_task(task_uuid, project_uuid, environment_uuid,
                           project_path):
    """Function called by the celery task to build an environment.

    Builds an environment (docker image) given the arguments, the logs produced by the user provided script
    are forwarded to a SocketIO server and namespace defined in the orchest internals config.

    Args:
        task_uuid:
        project_uuid:
        environment_uuid:
        project_path:

    Returns:

    """
    with requests.sessions.Session() as session:

        try:
            update_environment_build_status("STARTED", session, task_uuid)

            # prepare the project snapshot with the correctly placed dockerfile, scripts, etc.
            build_context = prepare_build_context(task_uuid, project_uuid,
                                                  environment_uuid,
                                                  project_path)

            # use the agreed upon pattern for the docker image name
            docker_image_name = _config.ENVIRONMENT_IMAGE_NAME.format(
                project_uuid=project_uuid, environment_uuid=environment_uuid)

            if not os.path.exists(__ENV_BUILD_FULL_LOGS_DIRECTORY):
                os.mkdir(__ENV_BUILD_FULL_LOGS_DIRECTORY)
            # place the logs in the celery container
            complete_logs_path = os.path.join(__ENV_BUILD_FULL_LOGS_DIRECTORY,
                                              docker_image_name)

            status = SioStreamedTask.run(
                # what we are actually running/doing in this task
                task_lambda=lambda user_logs_fo: build_docker_image(
                    docker_image_name,
                    build_context,
                    task_uuid,
                    user_logs_fo,
                    complete_logs_path,
                ),
                identity=f"{project_uuid}-{environment_uuid}",
                server=_config.ORCHEST_SOCKETIO_SERVER_ADDRESS,
                namespace=_config.ORCHEST_SOCKETIO_ENV_BUILDING_NAMESPACE,
                # note: using task.is_aborted() could be an option but
                # it was giving some issues related
                # to multithreading/processing, moreover,
                # also just passing the task_uuid to this function is less information
                # to rely on, which is good
                abort_lambda=lambda: AbortableAsyncResult(task_uuid).
                is_aborted(),
            )

            # cleanup
            os.system('rm -rf "%s"' % build_context)

            update_environment_build_status(status, session, task_uuid)

        # catch all exceptions because we need to make sure to set the build state to failed
        except Exception as e:
            update_environment_build_status("FAILURE", session, task_uuid)
            raise e
        finally:
            filters = {
                "label": [
                    "_orchest_env_build_is_intermediate=1",
                    f"_orchest_env_build_task_uuid={task_uuid}",
                ]
            }

            # artifacts of this build (intermediate containers, images, etc.)
            cleanup_env_build_docker_artifacts(filters)

            # see if outdated images of this environment can be cleaned up
            url = (
                f"{CONFIG_CLASS.ORCHEST_API_ADDRESS}"
                f"/environment-images/dangling/{project_uuid}/{environment_uuid}"
            )
            session.delete(url)

    return status
Пример #3
0
def build_jupyter_image_task(task_uuid: str, image_tag: str):
    """Function called by the celery task to build Jupyter image.

    Builds a Jupyter image given the arguments, the logs produced by the
    user provided script are forwarded to a SocketIO server and
    namespace defined in the orchest internals config.

    Args:
        task_uuid:
        image_tag:

    Returns:

    """
    with requests.sessions.Session() as session:

        try:
            update_jupyter_image_build_status("STARTED", session, task_uuid)

            # Prepare the project snapshot with the correctly placed
            # dockerfile, scripts, etc.
            build_context = prepare_build_context(task_uuid)

            # Use the agreed upon pattern for the image name.
            image_name = _config.JUPYTER_IMAGE_NAME

            if not os.path.exists(__JUPYTER_BUILD_FULL_LOGS_DIRECTORY):
                os.mkdir(__JUPYTER_BUILD_FULL_LOGS_DIRECTORY)
            # place the logs in the celery container
            complete_logs_path = os.path.join(
                __JUPYTER_BUILD_FULL_LOGS_DIRECTORY, image_name)

            status = SioStreamedTask.run(
                # What we are actually running/doing in this task,
                task_lambda=lambda user_logs_fo: build_image(
                    task_uuid,
                    image_name,
                    image_tag,
                    build_context,
                    user_logs_fo,
                    complete_logs_path,
                ),
                identity="jupyter",
                server=_config.ORCHEST_SOCKETIO_SERVER_ADDRESS,
                namespace=_config.
                ORCHEST_SOCKETIO_JUPYTER_IMG_BUILDING_NAMESPACE,
                # note: using task.is_aborted() could be an option but
                # it was giving some issues related to
                # multithreading/processing, moreover, also just passing
                # the task_uuid to this function is less information to
                # rely on, which is good.
                abort_lambda=lambda: AbortableAsyncResult(task_uuid
                                                          ).is_aborted(),
            )

            # cleanup
            rmtree(build_context["snapshot_path"])

            update_jupyter_image_build_status(status, session, task_uuid)

        # Catch all exceptions because we need to make sure to set the
        # build state to failed.
        except Exception as e:
            update_jupyter_image_build_status("FAILURE", session, task_uuid)
            logger.error(e)
            raise e
        finally:
            # We get here either because the task was successful or was
            # aborted, in any case, delete the workflow.
            k8s_custom_obj_api.delete_namespaced_custom_object(
                "argoproj.io",
                "v1alpha1",
                _config.ORCHEST_NAMESPACE,
                "workflows",
                f"image-build-task-{task_uuid}",
            )

    # The status of the Celery task is SUCCESS since it has finished
    # running. Not related to the actual state of the build, e.g.
    # FAILURE.
    return "SUCCESS"