def create_job():  # noqa
    r"""Create a new job.

    ---
    post:
      summary: Creates a new job.
      description: >-
        This resource is expecting JSON data with all the necessary information
        of a new job.
      operationId: create_job
      consumes:
       - application/json
      produces:
       - application/json
      parameters:
       - name: job
         in: body
         description: Information needed to instantiate a Job
         required: true
         schema:
           $ref: '#/definitions/JobRequest'
      responses:
        201:
          description: Request succeeded. The job has been launched.
          schema:
            type: object
            properties:
              job_id:
                type: string
          examples:
            application/json:
              {
                "job_id": "cdcf48b1-c2f3-4693-8230-b066e088c6ac"
              }
        400:
          description: >-
            Request failed. The incoming data specification seems malformed.
        500:
          description: >-
            Request failed. Internal controller error. The job could probably
            not have been allocated.
    """
    json_data = request.get_json()
    if not json_data:
        return jsonify({'message': 'Empty request'}), 400

    # Validate and deserialize input
    job_request, errors = job_request_schema.load(json_data)
    if errors:
        return jsonify(errors), 400
    compute_backend = job_request.get(
        'compute_backend',
        current_app.config['DEFAULT_COMPUTE_BACKEND'])
    if compute_backend not in current_app.config['SUPPORTED_COMPUTE_BACKENDS']:
        msg = 'Job submission failed. Backend {} is not supported.'.format(
            compute_backend)
        logging.error(msg, exc_info=True)
        update_workflow_logs(job_request['workflow_uuid'], msg)
        return jsonify({'job': msg}), 500
    job_obj = current_app.config['COMPUTE_BACKENDS'][compute_backend](
        docker_img=job_request['docker_img'],
        cmd=job_request['cmd'],
        env_vars=job_request['env_vars'],
        workflow_uuid=job_request['workflow_uuid'],
        workflow_workspace=str(job_request['workflow_workspace']),
        cvmfs_mounts=job_request['cvmfs_mounts'],
        shared_file_system=job_request['shared_file_system'],
        job_name=job_request.get('job_name', ''),
        kerberos=job_request.get('kerberos', ''),
    )
    backend_jod_id = job_obj.execute()
    if job_obj:
        job = copy.deepcopy(job_request)
        job['status'] = 'started'
        job['restart_count'] = 0
        job['max_restart_count'] = 3
        job['deleted'] = False
        job['obj'] = job_obj
        job['job_id'] = job_obj.job_id
        job['backend_job_id'] = backend_jod_id
        job['compute_backend'] = compute_backend
        JOB_DB[str(job['job_id'])] = job
        current_app.config['JOB_MONITORS'][compute_backend]()
        return jsonify({'job_id': job['job_id']}), 201
    else:
        return jsonify({'job': 'Could not be allocated'}), 500
Beispiel #2
0
def create_job():  # noqa
    r"""Create a new job.

    ---
    post:
      summary: Creates a new job.
      description: >-
        This resource is expecting JSON data with all the necessary information
        of a new job.
      operationId: create_job
      consumes:
       - application/json
      produces:
       - application/json
      parameters:
       - name: job
         in: body
         description: Information needed to instantiate a Job
         required: true
         schema:
           $ref: '#/definitions/JobRequest'
      responses:
        201:
          description: Request succeeded. The job has been launched.
          schema:
            type: object
            properties:
              job_id:
                type: string
          examples:
            application/json:
              {
                "job_id": "cdcf48b1-c2f3-4693-8230-b066e088c6ac"
              }
        400:
          description: >-
            Request failed. The incoming data specification seems malformed.
        500:
          description: >-
            Request failed. Internal controller error. The job could probably
            not have been allocated.
    """
    json_data = request.get_json()
    if not json_data:
        return jsonify({"message": "Empty request"}), 400

    # Validate and deserialize input
    job_request, errors = job_request_schema.load(json_data)
    if errors:
        return jsonify({"message": errors}), 400

    compute_backend = job_request.get(
        "compute_backend", current_app.config["DEFAULT_COMPUTE_BACKEND"]
    )
    job_request.pop("compute_backend", None)
    if compute_backend not in current_app.config["SUPPORTED_COMPUTE_BACKENDS"]:
        msg = "Job submission failed. Backend {} is not supported.".format(
            compute_backend
        )
        logging.error(msg, exc_info=True)
        update_workflow_logs(job_request["workflow_uuid"], msg)
        return jsonify({"job": msg}), 500
    with current_app.app_context():
        job_manager_cls = current_app.config["COMPUTE_BACKENDS"][compute_backend]()
        try:
            job_obj = job_manager_cls(**job_request)
        except REANAKubernetesMemoryLimitExceeded as e:
            return jsonify({"message": e.message}), 403
        except REANAKubernetesWrongMemoryFormat as e:
            return jsonify({"message": e.message}), 400
    try:
        backend_jod_id = job_obj.execute()
    except OperationalError as e:
        msg = f"Job submission failed because of DB connection issues. \n{e}"
        logging.error(msg, exc_info=True)
        return jsonify({"message": msg}), 500
    except Exception as e:
        msg = f"Job submission failed. \n{e}"
        logging.error(msg, exc_info=True)
        return jsonify({"message": msg}), 500
    if job_obj:
        job = copy.deepcopy(job_request)
        job["status"] = "started"
        job["restart_count"] = 0
        job["max_restart_count"] = 3
        job["deleted"] = False
        job["obj"] = job_obj
        job["job_id"] = job_obj.job_id
        job["backend_job_id"] = backend_jod_id
        job["compute_backend"] = compute_backend
        JOB_DB[str(job["job_id"])] = job
        job_monitor_cls = current_app.config["JOB_MONITORS"][compute_backend]()
        job_monitor_cls(
            app=current_app._get_current_object(),
            workflow_uuid=job_request["workflow_uuid"],
        )
        return jsonify({"job_id": job["job_id"]}), 201
    else:
        return jsonify({"job": "Could not be allocated"}), 500