Verified Commit bf295171 authored by Peter Stanko's avatar Peter Stanko
Browse files

Removed project pre/post/sched config from DB and moved to file

parent eb129b17
......@@ -626,10 +626,7 @@ id: string, +
project: {id:string, name: string}, +
test_files_source: string, +
file_whitelist: string, +
pre_submit_script: string, +
post_submit_script: string, +
submission_parameters: string, +
submission_scheduler_config: string, +
submissions_allowed_from: string, + (dátum)
submissions_allowed_to: string, + (dátum)
archive_from: string, + (dátum)
......@@ -640,10 +637,7 @@ archive_from: string, + (dátum)
project: {id:string, name: string}, +
test_files_source: string, +
file_whitelist: string, +
pre_submit_script: string, +
post_submit_script: string, +
submission_parameters: string, +
submission_scheduler_config: string, +
submissions_allowed_from: string, + (dátum)
submissions_allowed_to: string, + (dátum)
archive_from: string, + (dátum)}
......
......@@ -15,9 +15,7 @@ def create_project(factory, test_course, name: str, submit_configurable=False):
file_whitelist="*.*",
test_files_source='git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git',
test_files_subdir=name,
pre_submit_script="",
post_submit_script="",
submission_scheduler_config="",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() + timedelta(days=300),
......
......@@ -14,9 +14,7 @@ def create_project(factory, test_course, name: str):
file_whitelist="*.*",
test_files_source='git@gitlab.fi.muni.cz:xstanko2/kontr2-tests.git',
test_files_subdir=name,
pre_submit_script="",
post_submit_script="",
submission_scheduler_config="",
config_subdir="kontr2",
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() + timedelta(days=10),
......
......@@ -12,9 +12,7 @@ from portal.tools import time
def get_project(factory: DataFactory, course: Course, num: int):
project_config = dict(
file_whitelist="main.cpp",
pre_submit_script="python for kontr pre",
post_submit_script="python for kontr post",
submission_scheduler_config="python for sub Q",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time(),
submissions_allowed_to=time.current_time() + timedelta(days=2),
......@@ -65,9 +63,7 @@ def init_dev_data(app: Flask, db: SQLAlchemy):
file_whitelist="*.*",
test_files_source='https://gitlab.fi.muni.cz/grp-kontr2/testing/hello-test-files',
test_files_subdir='',
pre_submit_script="python for kontr pre",
post_submit_script="python for kontr post",
submission_scheduler_config="python for sub Q",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() + timedelta(days=10),
......@@ -81,9 +77,7 @@ def init_dev_data(app: Flask, db: SQLAlchemy):
file_whitelist="main.cpp\nfunc.hpp\nfunc.cpp",
test_files_source='https://gitlab.fi.muni.cz/grp-kontr2/testing/hello-test-files',
test_files_subdir='',
pre_submit_script="python for kontr pre",
post_submit_script="python for kontr post",
submission_scheduler_config="python for sub Q",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() + timedelta(days=10),
......@@ -96,9 +90,7 @@ def init_dev_data(app: Flask, db: SQLAlchemy):
file_whitelist="main.c",
test_files_source='https://gitlab.fi.muni.cz/grp-kontr2/testing/test-repo',
test_files_subdir='',
pre_submit_script="python for kontr pre",
post_submit_script="python for kontr post",
submission_scheduler_config="python for sub Q",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() - timedelta(minutes=1),
......
pre:
post: !include post-config.yml
scheduler:
repo_max_size: 10000000 # 10 MB
repo_visibility: private # it is required that repository should be private
\ No newline at end of file
......@@ -207,9 +207,7 @@ class DataFactory:
file_whitelist="*.*",
test_files_source='https://gitlab.fi.muni.cz/grp-kontr2/testing/hello-test-files',
test_files_subdir='',
pre_submit_script="python for kontr pre",
post_submit_script="python for kontr post",
submission_scheduler_config="python for sub Q",
config_subdir='kontr2',
submission_parameters="{\"type\":\"text\"}",
submissions_allowed_from=time.current_time() - timedelta(days=1),
submissions_allowed_to=time.current_time() + timedelta(days=10),
......
......@@ -10,11 +10,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini010
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -25,11 +22,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini011
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -40,11 +34,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini012
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -55,11 +46,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini02
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -70,11 +58,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini03
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -85,11 +70,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini04
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -100,11 +82,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini05
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -115,11 +94,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini06
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -130,11 +106,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini07
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -145,11 +118,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini08
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......@@ -160,11 +130,8 @@ projects:
config:
test_files_source: git@gitlab.fi.muni.cz:xstanko2/pb071-mini-template.git
file_whitelist: '*.*'
pre_submit_script: ''
post_submit_script: ''
test_files_subdir: mini09
submission_parameters: '{"type":"text"}'
submission_scheduler_config: ''
submissions_allowed_from: '2019-04-08T20:40:00+00:00'
submissions_allowed_to: '2020-02-03T20:40:00+00:00'
archive_from: '2020-03-04T20:40:00+00:00'
......
......@@ -5,6 +5,7 @@ import logging
import os
from typing import Union
import yaml
from authlib.flask.client import OAuth
from celery import Celery
from flask import Flask
......@@ -19,6 +20,7 @@ from portal.storage import Storage
from portal.tools.is_api_adapter import IsApiFactory
from portal.tools.ldap_client import LDAPWrapper
from portal.tools.paths import ROOT_DIR
from portal.tools.yaml_extend import YAMLIncludeLoader, construct_include
db = SQLAlchemy()
jwt = JWTManager()
......@@ -45,6 +47,7 @@ def configure_app(app: Flask, env: str = None,
app.config.from_object(config_object)
_load_portal_local(app, env, ignore_local)
app.config['PORTAL_ENV'] = config_type
return app
......@@ -117,6 +120,9 @@ def create_app(environment: str = None):
Returns(Flask): Flask application instance
"""
app = Flask(__name__)
yaml.add_constructor(u'!include', construct_include, YAMLIncludeLoader)
# app configuration
configure_app(app, env=environment)
_log_config(app)
......
......@@ -4,6 +4,7 @@ Models module where all of the models are specified
import logging
import uuid
from pathlib import Path
from typing import List
import sqlalchemy as sa
......@@ -463,19 +464,16 @@ class Project(db.Model, EntityBase, NamedMixin):
@hybrid_property
def is_archived(self) -> bool:
return self.state() == ProjectState.ARCHIVED
return self.state == ProjectState.ARCHIVED
def set_config(self, **kwargs):
"""Sets project configuration
Keyword Args:
test_files_source(str): Repository URL
file_whitelist(str): Filter string for whitelist
pre_submit_script(str): Pre submit script used in the submissions processing
post_submit_script(str): Post submit script used in the submissions processing
config_subdir(str): Where to look for the configuration (pre, post, scheduler)
submission_parameters(str):
Schema that defines all the parameters that should be passed to submission
submission_scheduler_config(str):
Configuration for the submissions scheduler
submissions_allowed_from(time):
Time from all the submissions are allowed from
submissions_allowed_to(time):
......@@ -483,9 +481,8 @@ class Project(db.Model, EntityBase, NamedMixin):
archive_from(time):
Archive all submissions from
"""
ALLOWED = ('test_files_source', 'file_whitelist', 'pre_submit_script',
'post_submit_script', 'test_files_subdir',
'submission_parameters', 'submission_scheduler_config')
ALLOWED = ('test_files_source', 'file_whitelist', 'config_subdir', 'config_file',
'submission_parameters')
for k, w in kwargs.items():
if k in ALLOWED:
setattr(self.config, k, w)
......@@ -530,35 +527,27 @@ class ProjectConfig(db.Model, EntityBase):
test_files_source: Test files source location: git repository
test_files_commit_hash: Full SHA-1 hash of the latest revision of project's test_files
file_whitelist: whitelisted files
pre_submit_script: Pre submit script used in the submissions processing component
post_submit_script: Post submit script used in the submissions processing component
submission_parameters: Post submit script used in the submissions processing component
submission_scheduler_config: Post submit script used in the submissions scheduler
"""
UPDATABLE = ['submissions_cancellation_period', 'test_files_commit_hash',
'test_files_source', 'test_files_subdir', 'file_whitelist',
'pre_submit_script', 'post_submit_script', 'submission_scheduler_config',
UPDATABLE = ['submissions_cancellation_period', 'test_files_commit_hash', 'config_file',
'test_files_source', 'test_files_subdir', 'file_whitelist', 'config_subdir',
'submissions_allowed_from', 'submissions_allowed_to', 'archive_from']
BASE_PARAMS = ['id', *UPDATABLE]
LISTABLE = ['id', 'assignment_url']
__tablename__ = 'projectConfig'
id = db.Column(db.String(length=36), default=lambda: str(
uuid.uuid4()), primary_key=True)
id = db.Column(db.String(length=36), default=lambda: str(uuid.uuid4()), primary_key=True)
project_id = db.Column(db.String(36), db.ForeignKey(
'project.id', ondelete='cascade'), nullable=False)
project = db.relationship(
"Project", back_populates="config", uselist=False)
project = db.relationship("Project", back_populates="config", uselist=False)
submissions_cancellation_period = db.Column(db.Integer)
test_files_source = db.Column(db.String(600)) # a git repository URL
test_files_subdir = db.Column(db.String(50)) # git subdir
test_files_commit_hash = db.Column(db.String(128)) # hash of the latest revision of test_files
file_whitelist = db.Column(db.Text)
pre_submit_script = db.Column(YAMLEncodedDict)
post_submit_script = db.Column(YAMLEncodedDict)
config_subdir = db.Column(db.String(50), default='kontr2', nullable=True)
config_file = db.Column(db.String(50), default='config.yml', nullable=True)
submission_parameters = db.Column(YAMLEncodedDict)
submission_scheduler_config = db.Column(YAMLEncodedDict)
_submissions_allowed_from = db.Column(db.TIMESTAMP(timezone=True))
_submissions_allowed_to = db.Column(db.TIMESTAMP(timezone=True))
_archive_from = db.Column(db.TIMESTAMP(timezone=True))
......@@ -573,6 +562,12 @@ class ProjectConfig(db.Model, EntityBase):
seconds = time.strip_seconds(self._submissions_allowed_from)
return seconds
@property
def config_path(self) -> Path:
cfg_file = self.config_file or 'config.yml'
cfg_sub = self.config_subdir or 'kontr2'
return Path(cfg_sub) / cfg_file
@hybrid_property
def submissions_allowed_to(self):
"""Gets from which date all the submissions are allowed to
......@@ -827,11 +822,11 @@ class Submission(db.Model, EntityBase):
state = db.Column(db.Enum(SubmissionState, name='SubmissionState'), nullable=False)
note = db.Column(JSONEncodedDict())
source_hash = db.Column(db.String(64))
user_id = db.Column(db.String(36), db.ForeignKey(
'user.id', ondelete='cascade'), nullable=False, index=True)
user_id = db.Column(db.String(36), db.ForeignKey('user.id', ondelete='cascade'),
nullable=False, index=True)
user = db.relationship("User", back_populates="submissions", uselist=False)
project_id = db.Column(db.String(36), db.ForeignKey(
'project.id', ondelete='cascade'), nullable=False, index=True)
project_id = db.Column(db.String(36), db.ForeignKey('project.id', ondelete='cascade'),
nullable=False, index=True)
project = db.relationship("Project", uselist=False)
review = db.relationship("Review", back_populates="submission", cascade="all, delete-orphan",
passive_deletes=True, uselist=False)
......@@ -1036,8 +1031,8 @@ class Worker(Client, EntityBase):
UPDATABLE = ['url', 'tags', 'portal_secret', 'state']
BASE_PARAMS = ['id', *UPDATABLE]
__tablename__ = 'worker'
id = db.Column(db.String(length=36), db.ForeignKey('client.id'), default=lambda: str(
uuid.uuid4()), primary_key=True)
id = db.Column(db.String(length=36), db.ForeignKey('client.id'),
default=lambda: str(uuid.uuid4()), primary_key=True)
url = db.Column(db.String(250), nullable=False)
tags = db.Column(db.Text()) # set by a Worker at init
portal_secret = db.Column(db.String(64)) # set by a Worker at init
......@@ -1112,7 +1107,7 @@ projects_groups = db.Table("projects_groups", db.Model.metadata,
Client.roles = db.relationship("Role", secondary="clients_roles")
User.groups = db.relationship("Group", secondary="users_groups")
Project.groups = db.relationship(
"Group", secondary="projects_groups", back_populates='projects')
Project.groups = db.relationship("Group", secondary="projects_groups",
back_populates='projects')
sa.orm.configure_mappers()
import logging
from typing import Dict
from gitlab.v4 import objects
from portal.async_celery import tasks
from portal.database import Project
......@@ -10,41 +13,13 @@ from portal.service.projects import ProjectService
log = logging.getLogger(__name__)
def _check_gl_repo_size(gl_project, project):
max_repo_size = project.config.submission_scheduler_config.get('repo_max_size')
if max_repo_size:
repo_size = gl_project.statistics['repository_size']
if repo_size > max_repo_size:
raise errors.SubmissionRefusedError(f"Your repository is bigger than the limit:"
f" {repo_size} > {max_repo_size}")
else:
log.debug(f"[CHECK] Your repository size is within the limit: "
f"{repo_size} > {max_repo_size}")
else:
log.debug("[CHECK] Max repo size has not been set - skip")
return True
def _check_gl_repo_visibility(gl_project, project):
required_repo_visibility = project.config.submission_scheduler_config.get('repo_visibility')
if required_repo_visibility:
repo_visibility = gl_project.visibility
if required_repo_visibility != repo_visibility:
raise errors.SubmissionRefusedError(f"Your repository visibility "
f"is not {required_repo_visibility}."
f" Actual: {repo_visibility}")
else:
log.debug(f"[CHECK] Your repository visibility is correct - "
f"{repo_visibility}")
else:
log.debug("[CHECK] Required repo visibility has not been set - skip")
return True
class ProjectsFacade(GeneralCRUDFacade):
def __init__(self):
super().__init__(ProjectService, 'Project')
def _project_config(self, project: Project) -> Dict:
return self._services.storage.project_config(project=project)
def find_all(self, course: Course, *args, **kwargs):
course_perm = self.permissions(course=course)
if course_perm.check.view_course_full():
......@@ -139,8 +114,8 @@ class ProjectsFacade(GeneralCRUDFacade):
def _check_gitlab_params(self, client: Client, project: Project):
gl_repo = self.services.kontr_gitlab.build_repo_name(client, project)
gl_project = self._services.kontr_gitlab.get_project(gl_repo)
_check_gl_repo_size(gl_project, project)
_check_gl_repo_visibility(gl_project, project)
self._check_gl_repo_size(gl_project, project)
self._check_gl_repo_visibility(gl_project, project)
return True
def delete(self, project: Project):
......@@ -152,3 +127,41 @@ class ProjectsFacade(GeneralCRUDFacade):
for submission in project.submissions:
self._facades.submissions.archive(submission)
self._service(project).archive()
def _check_gl_repo_size(self, gl_project, project: Project):
config = self._project_config(project=project)
if not config or 'scheduler' not in config.keys():
log.debug("[CHECK] Scheduler config not set or config is None - skip")
return True
max_repo_size = config['scheduler'].get('repo_max_size')
if max_repo_size:
repo_size = gl_project.statistics['repository_size']
if repo_size > max_repo_size:
raise errors.SubmissionRefusedError(f"Your repository is bigger than the limit:"
f" {repo_size} > {max_repo_size}")
else:
log.debug(f"[CHECK] Your repository size is within the limit: "
f"{repo_size} > {max_repo_size}")
else:
log.debug("[CHECK] Max repo size has not been set - skip")
return True
def _check_gl_repo_visibility(self, gl_project: objects.Project, project: Project):
# TODO: CRITICAL - Rewrite
config = self._project_config(project=project)
if not config or 'scheduler' not in config.keys():
log.debug("[CHECK] Scheduler config not set or config is None - skip")
return True
required_repo_visibility = config['scheduler'].get('repo_visibility')
if required_repo_visibility:
repo_visibility = gl_project.visibility
if required_repo_visibility != repo_visibility:
raise errors.SubmissionRefusedError(f"Your repository visibility "
f"is not {required_repo_visibility}."
f" Actual: {repo_visibility}")
else:
log.debug(f"[CHECK] Your repository visibility is correct - "
f"{repo_visibility}")
else:
log.debug("[CHECK] Required repo visibility has not been set - skip")
return True
......@@ -2,7 +2,7 @@ from flask import request
from flask_jwt_extended import jwt_required
from flask_restplus import Namespace
from portal import logger
from portal import logger, tools
from portal.database.enums import ClientType
from portal.rest import rest_helpers
from portal.rest.custom_resource import CustomResource
......@@ -137,6 +137,25 @@ class ProjectConfigResource(CustomResource):
return '', 204
@projects_namespace.route('/courses/<string:cid>/projects/<string:pid>/process_config')
@projects_namespace.param('cid', 'Course id')
@projects_namespace.param('pid', 'Project id')
@projects_namespace.response(404, 'Course not found')
@projects_namespace.response(404, 'Project not found')
class ProjectProcessConfig(CustomResource):
@jwt_required
# @projects_namespace.response(200, 'Config of the project', model=config_schema)
# @projects_namespace.response(200, 'Config of the project', model=config_schema_reduced)
def get(self, cid: str, pid: str):
course = self.find.course(cid)
project = self.find.project(course, pid)
# authorization
log.debug(f"[REST] Get project submission processing config in {project.log_name}"
f" by {self.client.log_name}")
config = self.services.storage.project_config(project)
return tools.create_response(config, type='yaml')
@projects_namespace.route('/courses/<string:cid>/projects/<string:pid>/test-files-refresh')
@projects_namespace.param('cid', 'Course id')
@projects_namespace.param('pid', 'Project id')
......
......@@ -202,10 +202,10 @@ class ProjectConfigSchema(BaseSchema, Schema):
test_files_source = fields.Str(allow_none=True)
test_files_subdir = fields.Str(allow_none=True)
file_whitelist = fields.Str(allow_none=True)
pre_submit_script = fields.Str(allow_none=True)
post_submit_script = fields.Str(allow_none=True)
config_subdir = fields.Str(allow_none=True)
config_file = fields.Str(allow_none=True)
config_path = fields.Str(allow_none=True)
submission_parameters = fields.Str(allow_none=True)
submission_scheduler_config = fields.Str(allow_none=True)
submissions_allowed_from = fields.LocalDateTime(allow_none=True)
submissions_allowed_to = fields.LocalDateTime(allow_none=True)
archive_from = fields.LocalDateTime(allow_none=True)
......
......@@ -214,5 +214,15 @@ class GitlabAuthorizationError(PortalAPIError):
super().__init__(code=401, message=message)
class SchemaParseError(PortalError):
class SchemaParseError(PortalServiceError):
pass
def error(message, error_class=PortalServiceError):
log.error(f"{error_class}: {message}")
raise error_class(message)
def api_error(message, code=400, error_class=PortalAPIError):
log.error(f"{error_class}[{code}]: {message}")
raise error_class(message=message, code=code)
......@@ -153,9 +153,8 @@ class ResourceDefinitionService(GeneralService):
Returns(Dict): Project dump
"""
schema = _extract_params(project, self._project_params)
config_params = ['test_files_source', 'file_whitelist', 'pre_submit_script',
'post_submit_script', 'test_files_subdir',
'submission_parameters', 'submission_scheduler_config']
config_params = ['test_files_source', 'file_whitelist', 'config_subdir',
'test_files_subdir', 'submission_parameters']
config = project.config
schema['config'] = _extract_params(config, config_params)
for param in self._timed_params:
......
import time
from typing import Optional
from typing import Optional, Union, Dict
import flask