Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Kontr 2.0
Portal API Backend
Commits
bf295171
Verified
Commit
bf295171
authored
May 12, 2019
by
Peter Stanko
Browse files
Removed project pre/post/sched config from DB and moved to file
parent
eb129b17
Changes
24
Hide whitespace changes
Inline
Side-by-side
docs/prirucka.adoc
View file @
bf295171
...
...
@@ -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)}
...
...
management/data/data_c.py
View file @
bf295171
...
...
@@ -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
),
...
...
management/data/data_cpp.py
View file @
bf295171
...
...
@@ -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
),
...
...
management/data/data_dev.py
View file @
bf295171
...
...
@@ -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
\n
func.hpp
\n
func.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
),
...
...
management/data/resources/test_files/kontr2/config.yml
0 → 100644
View file @
bf295171
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
management/data/resources/test_files/kontr2/post-config.yml
0 → 100644
View file @
bf295171
foo
:
bar
\ No newline at end of file
management/data/shared.py
View file @
bf295171
...
...
@@ -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
),
...
...
management/resources/c_resource.yml
View file @
bf295171
...
...
@@ -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'
...
...
portal/__init__.py
View file @
bf295171
...
...
@@ -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
)
...
...
portal/database/models.py
View file @
bf295171
...
...
@@ -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
()
portal/facade/projects_facade.py
View file @
bf295171
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
portal/rest/projects.py
View file @
bf295171
...
...
@@ -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'
)
...
...
portal/rest/schemas.py
View file @
bf295171
...
...
@@ -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
)
...
...
portal/service/errors.py
View file @
bf295171
...
...
@@ -214,5 +214,15 @@ class GitlabAuthorizationError(PortalAPIError):
super
().
__init__
(
code
=
401
,
message
=
message
)
class
SchemaParseError
(
PortalError
):
class
SchemaParseError
(
Portal
Service
Error
):
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
)
portal/service/resource_definition.py
View file @
bf295171
...
...
@@ -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
:
...
...
portal/service/storage.py
View file @
bf295171
import
time
from
typing
import
Optional
from
typing
import
Optional
,
Union
,
Dict
import
flask