コード例 #1
0
ファイル: config_data.py プロジェクト: aykamko/ob2
def validate_config():
    if config.inst_account_enabled:
        assert config.mailer_enabled, \
            "The inst account forms plugin will not work without the mailer"
        assert config.inst_account_forms_path, \
            "The inst account forms plugin requires inst_account_forms_path"

    if config.groups_enabled:
        assert 1 <= config.group_min_size <= config.group_max_size
    else:
        assert not any([assignment.is_group for assignment in config.assignments]), \
            "Group assignments will not work if groups are not enabled."

    if config.dockergrader_apparmor_profile:
        _validate_apparmor_config(config.dockergrader_apparmor_profile)

    for assignment in config.assignments:
        if not assignment.manual_grading:
            assert get_job(assignment.name), "No job found for %s" % assignment.name

    for array_key in ["github_ta_usernames",
                      "github_webhook_secrets"]:
        assert not isinstance(getattr(config, array_key), basestring)

    assert len(set([a.name for a in config.assignments])) == len(config.assignments)
コード例 #2
0
def validate_config():
    if config.inst_account_enabled:
        assert config.mailer_enabled, \
            "The inst account forms plugin will not work without the mailer"
        assert config.inst_account_forms_path, \
            "The inst account forms plugin requires inst_account_forms_path"

    if config.groups_enabled:
        assert 1 <= config.group_min_size <= config.group_max_size
    else:
        assert not any([assignment.is_group for assignment in config.assignments]), \
            "Group assignments will not work if groups are not enabled."

    if config.dockergrader_apparmor_profile:
        _validate_apparmor_config(config.dockergrader_apparmor_profile)

    for assignment in config.assignments:
        if not assignment.manual_grading:
            assert get_job(assignment.name), "No job found for %s" % assignment.name

    for array_key in ["github_ta_usernames",
                      "github_webhook_secrets"]:
        assert not isinstance(getattr(config, array_key), basestring)

    # The port number should be ommitted if it is the default HTTP/HTTPS port.
    assert not config.web_public_host.endswith(":80")
    assert not config.web_public_host.endswith(":443")


    assert not config.web_public_root == "/", "Set web_public_root to empty string instead."
    assert config.web_public_root == "" or config.web_public_root.startswith("/"), \
            "If the web_public_root is not empty, always include the leading slash."
    assert not config.web_public_root.endswith("/"), "Remove trailing slash from web_public_root"

    assert len(set([a.name for a in config.assignments])) == len(config.assignments)
コード例 #3
0
def validate_config():
    if config.inst_account_enabled:
        assert config.mailer_enabled, \
            "The inst account forms plugin will not work without the mailer"
        assert config.inst_account_forms_path, \
            "The inst account forms plugin requires inst_account_forms_path"

    if config.groups_enabled:
        assert 1 <= config.group_min_size <= config.group_max_size
    else:
        assert not any([assignment.is_group for assignment in config.assignments]), \
            "Group assignments will not work if groups are not enabled."

    if config.dockergrader_apparmor_profile:
        _validate_apparmor_config(config.dockergrader_apparmor_profile)

    for assignment in config.assignments:
        if not assignment.manual_grading:
            assert get_job(
                assignment.name), "No job found for %s" % assignment.name

    for array_key in ["github_ta_usernames", "github_webhook_secrets"]:
        assert not isinstance(getattr(config, array_key), basestring)

    assert len(set([a.name
                    for a in config.assignments])) == len(config.assignments)
コード例 #4
0
    def _process_job(self, job):
        build_name = job.build_name
        with self.lock:
            self.status = build_name
            self.updated = now()

        # Mark the job as In Progress
        while True:
            try:
                with DbCursor() as c:
                    c.execute('''SELECT source, `commit`, message, job, started FROM builds
                                 WHERE build_name = ? AND status = ? LIMIT 1''',
                              [build_name, QUEUED])
                    row = c.fetchone()
                    if row is None:
                        self._log("Build %s was missing from the database. Skipping." % build_name)
                        return
                    source, commit, message, job_name, started = row
                    owners = get_repo_owners(c, source)
                    owner_emails = {owner: email for owner, (_, _, _, _, _, email)
                                    in get_users_by_ids(c, owners).items()}
                    c.execute("UPDATE builds SET status = ?, updated = ? WHERE build_name = ?",
                              [IN_PROGRESS, now_str(), build_name])
                    break
            except apsw.Error:
                self._log("Exception raised while setting status to IN_PROGRESS. Retrying...",
                          exc=True)
                logging.exception("Failed to retrieve next dockergrader job")

        self._log("Started building %s" % build_name)
        try:
            # if the job doesn't exist for some reason, the resulting TypeError will be caught
            # and logged
            assignment = get_assignment_by_name(job_name)
            due_date = assignment.due_date
            job_handler = get_job(job_name)
            log, score = job_handler(source, commit)
            # Ignore any special encoding inside the log, and just treat it as a bytes
            log = buffer(log)
            min_score, max_score = assignment.min_score, assignment.max_score
            full_score = assignment.full_score
            if score < min_score or score > max_score:
                raise ValueError("A score of %s is not in the acceptable range of %f to %f" %
                                 (str(score), min_score, max_score))
        except JobFailedError as e:
            self._log("Failed %s with JobFailedError" % build_name, exc=True)
            with DbCursor() as c:
                c.execute('''UPDATE builds SET status = ?, updated = ?, log = ?
                             WHERE build_name = ?''', [FAILED, now_str(), str(e), build_name])
            if config.mailer_enabled:
                try:
                    for owner in owners:
                        email = owner_emails.get(owner)
                        if not email:
                            continue
                        subject = "%s failed to complete" % build_name
                        send_template("build_failed", email, subject, build_name=build_name,
                                      job_name=job_name, source=source, commit=commit,
                                      message=message, error_message=str(e))
                except Exception:
                    self._log("Exception raised while reporting JobFailedError", exc=True)
                    logging.exception("Exception raised while reporting JobFailedError")
                else:
                    self._log("JobFailedError successfully reported via email")
            return
        except Exception as e:
            self._log("Exception raised while building %s" % build_name, exc=True)
            logging.exception("Internal error within build %s" % build_name)
            with DbCursor() as c:
                c.execute('''UPDATE builds SET status = ?, updated = ?, log = ?
                             WHERE build_name = ?''',
                          [FAILED, now_str(), "Build failed due to an internal error.", build_name])
            return

        self._log("Autograder build %s complete (score: %s)" % (build_name, str(score)))

        while True:
            try:
                with DbCursor() as c:
                    c.execute('''UPDATE builds SET status = ?, score = ?, updated = ?,
                                 log = ? WHERE build_name = ?''',
                              [SUCCESS, score, now_str(), log, build_name])
                    slipunits = slip_units(due_date, started)
                    affected_users = assign_grade_batch(c, owners, job_name, float(score),
                                                        slipunits, build_name, "Automatic build.",
                                                        "autograder", dont_lower=True)
                    break
            except apsw.Error:
                self._log("Exception raised while assigning grades", exc=True)
                logging.exception("Failed to update build %s after build completed" % build_name)
                return

        if config.mailer_enabled:
            try:
                for owner in owners:
                    email = owner_emails.get(owner)
                    if not email:
                        continue
                    subject = "%s complete - score %s / %s" % (build_name, str(score),
                                                               str(full_score))
                    if owner not in affected_users:
                        subject += " (no effect on grade)"
                    else:
                        if slipunits == 1:
                            subject += " (1 %s used)" % config.slip_unit_name_singular
                        elif slipunits > 0:
                            subject += " (%s slip %s used)" % (str(slipunits),
                                                               config.slip_unit_name_plural)
                    send_template("build_finished", email, subject, build_name=build_name,
                                  job_name=job_name, score=score, full_score=str(full_score),
                                  slipunits=slipunits, log=log, source=source, commit=commit,
                                  message=message, affected=(owner in affected_users))
            except Exception:
                self._log("Exception raised while reporting grade", exc=True)
                logging.exception("Exception raised while reporting grade")
            else:
                self._log("Grade successfully reported via email")