Source code for pyfarm.master.user_interface.jobtypes

# No shebang line, this module is meant to be imported
#
# Copyright 2014 Ambient Entertainment GmbH & Co. KG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Jobtypes
============

UI endpoints allowing seeing and manipulating jobtypes via the web interface
"""

try:
    from httplib import (
        NOT_FOUND, INTERNAL_SERVER_ERROR, SEE_OTHER, BAD_REQUEST)
except ImportError:  # pragma: no cover
    from http.client import (
        NOT_FOUND, INTERNAL_SERVER_ERROR, SEE_OTHER, BAD_REQUEST)

from flask import render_template, request, redirect, flash, url_for

from sqlalchemy import desc, func, sql

from pyfarm.models.jobtype import JobType, JobTypeVersion
from pyfarm.models.software import (
    JobTypeSoftwareRequirement, Software, SoftwareVersion)
from pyfarm.master.application import db

[docs]def jobtypes(): return render_template("pyfarm/user_interface/jobtypes.html", jobtypes=JobType.query)
[docs]def jobtype(jobtype_id): """ UI endpoint for a single jobtype. Allows showing and updating the jobtype """ jobtype = JobType.query.filter_by(id=jobtype_id).first() if not jobtype: return (render_template( "pyfarm/error.html", error="Jobtype %s not found" % jobtype_id), NOT_FOUND) if request.method == "POST": with db.session.no_autoflush: jobtype.description = request.form["description"] new_version = JobTypeVersion(jobtype=jobtype) new_version.max_batch = request.form["max_batch"].strip() or\ sql.null() new_version.batch_contiguous =\ ("batch_contiguous" in request.form and request.form["batch_contiguous"] == "true") new_version.no_automatic_start_time =\ ("no_automatic_start_time" in request.form and request.form["no_automatic_start_time"] == "true") new_version.classname = request.form["classname"] new_version.code = request.form["code"] max_version, = db.session.query(func.max( JobTypeVersion.version)).filter_by(jobtype=jobtype).first() new_version.version = (max_version or 0) + 1 previous_version = JobTypeVersion.query.filter_by( jobtype=jobtype).order_by(desc(JobTypeVersion.version)).first() if previous_version: for requirement in previous_version.software_requirements: new_requirement = JobTypeSoftwareRequirement() new_requirement.jobtype_version = new_version new_requirement.software = requirement.software new_requirement.min_version = requirement.min_version new_requirement.max_version = requirement.max_version db.session.add(new_requirement) db.session.add(jobtype) db.session.add(new_version) db.session.commit() flash("Jobtype %s updated to version %s" % (jobtype.name, new_version.version)) return redirect(url_for("single_jobtype_ui", jobtype_id=jobtype.id), SEE_OTHER) else: latest_version = JobTypeVersion.query.filter_by( jobtype=jobtype).order_by(desc(JobTypeVersion.version)).first() if not latest_version: return (render_template( "pyfarm/error.html", error="Jobtype %s has no versions" % jobtype_id), INTERNAL_SERVER_ERROR) return render_template("pyfarm/user_interface/jobtype.html", jobtype=jobtype, latest_version=latest_version, software_items=Software.query)
[docs]def remove_jobtype_software_requirement(jobtype_id, software_id): with db.session.no_autoflush: jobtype = JobType.query.filter_by(id=jobtype_id).first() if not jobtype: return (render_template( "pyfarm/error.html", error="Jobtype %s not found" % jobtype_id), NOT_FOUND) previous_version = JobTypeVersion.query.filter_by( jobtype=jobtype).order_by(desc(JobTypeVersion.version)).first() if not previous_version: return (render_template( "pyfarm/error.html", error="Jobtype %s has no versions" % jobtype_id), INTERNAL_SERVER_ERROR) new_version = JobTypeVersion(jobtype=jobtype) new_version.max_batch = previous_version.max_batch or sql.null() new_version.batch_contiguous = previous_version.batch_contiguous new_version.no_automatic_start_time =\ previous_version.no_automatic_start_time new_version.classname = previous_version.classname new_version.code = previous_version.code new_version.version = previous_version.version + 1 for requirement in previous_version.software_requirements: if requirement.software_id != software_id: new_requirement = JobTypeSoftwareRequirement() new_requirement.jobtype_version = new_version new_requirement.software = requirement.software new_requirement.min_version = requirement.min_version new_requirement.max_version = requirement.max_version db.session.add(new_requirement) db.session.commit() flash("Software requirement has been removed from jobtype %s" % jobtype.name) return redirect(url_for("single_jobtype_ui", jobtype_id=jobtype.id), SEE_OTHER)
[docs]def add_jobtype_software_requirement(jobtype_id): with db.session.no_autoflush: jobtype = JobType.query.filter_by(id=jobtype_id).first() if not jobtype: return (render_template( "pyfarm/error.html", error="Jobtype %s not found" % jobtype_id), NOT_FOUND) previous_version = JobTypeVersion.query.filter_by( jobtype=jobtype).order_by(desc(JobTypeVersion.version)).first() if not previous_version: return (render_template( "pyfarm/error.html", error="Jobtype %s has no versions" % jobtype_id), INTERNAL_SERVER_ERROR) new_version = JobTypeVersion(jobtype=jobtype) new_version.max_batch = previous_version.max_batch or sql.null() new_version.batch_contiguous = previous_version.batch_contiguous new_version.no_automatic_start_time =\ previous_version.no_automatic_start_time new_version.classname = previous_version.classname new_version.code = previous_version.code new_version.version = previous_version.version + 1 for requirement in previous_version.software_requirements: retained_requirement = JobTypeSoftwareRequirement() retained_requirement.jobtype_version = new_version retained_requirement.software = requirement.software retained_requirement.min_version = requirement.min_version retained_requirement.max_version = requirement.max_version db.session.add(retained_requirement) new_requirement = JobTypeSoftwareRequirement() new_requirement.jobtype_version = new_version new_requirement_software = Software.query.filter_by( id=request.form["software"]).first() if not new_requirement_software: return (render_template( "pyfarm/error.html", error="Software %s not found" % request.form["software"]), NOT_FOUND) new_requirement.software = new_requirement_software if request.form["minimum_version"] != "": min_version = SoftwareVersion.query.filter_by( id=request.form["minimum_version"]).first() if not min_version: return (render_template( "pyfarm/error.html", error="Software version %s not " "found" % request.form["minimum_version"]), NOT_FOUND) if min_version.software != new_requirement_software: return (render_template( "pyfarm/error.html", error="Software version %s does " "not belong to software %s" % (min_version.version, new_requirement_software.software)), BAD_REQUEST) new_requirement.min_version = min_version if request.form["maximum_version"] != "": max_version = SoftwareVersion.query.filter_by( id=request.form["maximum_version"]).first() if not max_version: return (render_template( "pyfarm/error.html", error="Software version %s not " "found" % request.form["maximum_version"]), NOT_FOUND) if max_version.software != new_requirement_software: return (render_template( "pyfarm/error.html", error="Software version %s does " "not belong to software %s" % (max_version.version, new_requirement_software.software)), BAD_REQUEST) new_requirement.max_version = max_version db.session.add(new_version) db.session.add(new_requirement) db.session.commit() flash("Software requirement has been added to jobtype %s" % jobtype.name) return redirect(url_for("single_jobtype_ui", jobtype_id=jobtype.id), SEE_OTHER)
[docs]def remove_jobtype(jobtype_id): with db.session.no_autoflush: jobtype = JobType.query.filter_by(id=jobtype_id).first() if not jobtype: return (render_template( "pyfarm/error.html", error="Jobtype %s not found" % jobtype_id), NOT_FOUND) for version in jobtype.versions: if version.jobs.count() > 0: return (render_template( "pyfarm/error.html", error="Jobtype %s cannot be deleted " "because there are still jobs referencing it. Please " "delete those jobs first." % jobtype.name), BAD_REQUEST) db.session.delete(jobtype) db.session.commit() return redirect(url_for("jobtypes_index_ui"), SEE_OTHER)
[docs]def create_jobtype(): if request.method == "GET": return render_template("pyfarm/user_interface/jobtype_create.html", jobtypes=JobType.query, software_items=Software.query) else: with db.session.no_autoflush: jobtype = JobType() jobtype.name = request.form["name"] jobtype.description = request.form["description"] jobtype_version = JobTypeVersion() jobtype_version.jobtype = jobtype jobtype_version.version = 1 jobtype_version.max_batch = request.form["max_batch"].strip() or\ sql.null() jobtype_version.batch_contiguous =\ ("batch_contiguous" in request.form and request.form["batch_contiguous"] == "true") jobtype_version.no_automatic_start_time =\ ("no_automatic_start_time" in request.form and request.form["no_automatic_start_time"] == "true") jobtype_version.classname = request.form["classname"] jobtype_version.code = request.form["code"] requirements = zip(request.form.getlist("software"), request.form.getlist("min_version"), request.form.getlist("min_version")) for requirement_tuple in requirements: software = Software.query.filter_by( id=int(requirement_tuple[0])).first() if not software: return (render_template( "pyfarm/error.html", error="Software %s not found" % requirement_tuple[0]), NOT_FOUND) requirement = JobTypeSoftwareRequirement() requirement.software = software requirement.jobtype_version = jobtype_version if requirement_tuple[1] != "": minimum_version = SoftwareVersion.query.filter_by( id=int(requirement_tuple[1])).first() if not minimum_version: return (render_template( "pyfarm/error.html", error="Software version %s not " "found" % requirement_tuple[1]), NOT_FOUND) if minimum_version.software != software: return (render_template( "pyfarm/error.html", error="Software version %s " "does not belong to software %s" % (minimum_version.version, software.software)), BAD_REQUEST) requirement.min_version = minimum_version if requirement_tuple[2] != "": maximum_version = SoftwareVersion.query.filter_by( id=int(requirement_tuple[2])).first() if not maximum_version: return (render_template( "pyfarm/error.html", error="Software version %s not " "found" % requirement_tuple[2]), NOT_FOUND) if maximum_version.software != software: return (render_template( "pyfarm/error.html", error="Software version %s " "does not belong to software %s" % (maximum_version.version, software.software)), BAD_REQUEST) requirement.max_version = maximum_version db.session.add(requirement) db.session.add(jobtype) db.session.add(jobtype_version) db.session.commit() flash("Jobtype %s created" % jobtype.name) return redirect(url_for('jobtypes_index_ui'), SEE_OTHER)
[docs]def update_jobtype_notification_templates(jobtype_id): with db.session.no_autoflush: jobtype = JobType.query.filter_by(id=jobtype_id).first() if not jobtype: return (render_template( "pyfarm/error.html", error="Jobtype %s not found" % jobtype_id), NOT_FOUND) if "success_subject" in request.form: if request.form["success_subject"].strip() != "": jobtype.success_subject = request.form["success_subject"] else: jobtype.success_subject = sql.null() if "success_body" in request.form: if request.form["success_body"].strip() != "": jobtype.success_body = request.form["success_body"] else: jobtype.success_body = sql.null() if "failure_subject" in request.form: if request.form["failure_subject"].strip() != "": jobtype.fail_subject = request.form["failure_subject"] else: jobtype.fail_subject = sql.null() if "failure_body" in request.form: if request.form["failure_body"].strip() != "": jobtype.fail_body = request.form["failure_body"] else: jobtype.fail_body = sql.null() db.session.add(jobtype) db.session.commit() flash("Notification templates for jobtype %s updated" % jobtype.name) return redirect(url_for("single_jobtype_ui", jobtype_id=jobtype.id), SEE_OTHER)