-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revamp virtual environments (now reusable!)
Venvs are no longer associated with assignments; instead, assignments can now use a venv to run submissions
- Loading branch information
1 parent
29b07b4
commit 0575701
Showing
18 changed files
with
334 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Django 3.2.25 on 2024-03-29 05:12 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('venvs', '0005_auto_20240328_0033'), | ||
('assignments', '0027_mossresult'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='assignment', | ||
name='venv', | ||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assignments', to='venvs.venv'), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
from django.contrib import admin | ||
|
||
from .models import Virtualenv | ||
from .models import Venv | ||
|
||
# Register your models here. | ||
|
||
|
||
@admin.register(Virtualenv) | ||
class VirtualenvAdmin(admin.ModelAdmin): | ||
list_display = ("assignment", "fully_created", "installing_packages") | ||
@admin.register(Venv) | ||
class VenvAdmin(admin.ModelAdmin): | ||
list_display = ("name", "fully_created", "installing_packages") | ||
list_filter = ("fully_created", "installing_packages") | ||
save_as = True | ||
search_fields = ("assignment__name",) | ||
autocomplete_fields = ("assignment",) | ||
search_fields = ("name",) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from django import forms | ||
|
||
from .models import Venv | ||
|
||
|
||
class VenvForm(forms.ModelForm): | ||
class Meta: | ||
model = Venv | ||
fields = ["name"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Generated by Django 3.2.25 on 2024-03-28 04:33 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('venvs', '0004_alter_virtualenv_id'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Venv', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=255)), | ||
('fully_created', models.BooleanField()), | ||
('installing_packages', models.BooleanField(default=False)), | ||
('package_installation_output', models.CharField(blank=True, default='', max_length=16384)), | ||
], | ||
), | ||
migrations.DeleteModel( | ||
name='Virtualenv', | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,59 @@ | ||
import logging | ||
import subprocess | ||
import sys | ||
|
||
from celery import shared_task | ||
|
||
from ..assignments.models import Assignment | ||
from .models import Virtualenv, VirtualenvCreationError | ||
from django.conf import settings | ||
|
||
from .models import Venv, VenvCreationError, VenvExistsError | ||
|
||
@shared_task | ||
def create_virtualenv(assignment_id): | ||
assignment = Assignment.objects.get(id=assignment_id) | ||
logger = logging.getLogger(__name__) | ||
|
||
if assignment.venv_object_created: | ||
return | ||
|
||
@shared_task | ||
def create_venv(venv_id): | ||
venv = Venv.objects.get(id=venv_id) | ||
|
||
success = False | ||
try: | ||
Virtualenv.create_venv_for_assignment(assignment) | ||
except VirtualenvCreationError: | ||
pass | ||
try: | ||
res = subprocess.run( | ||
[ | ||
sys.executable, | ||
"-m", | ||
"virtualenv", | ||
"-p", | ||
settings.SUBMISSION_PYTHON, | ||
"--", | ||
venv.path, | ||
], | ||
check=False, | ||
stdin=subprocess.DEVNULL, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT, | ||
) | ||
except FileNotFoundError as e: | ||
logger.error("Cannot run processes: %s", e) | ||
raise FileNotFoundError from e | ||
|
||
if res.returncode != 0: | ||
raise VenvCreationError( | ||
"Error creating virtual environment (return code {}): {}".format( | ||
res.returncode, res.stdout | ||
) | ||
) | ||
|
||
venv.fully_created = True | ||
venv.save() | ||
success = True | ||
finally: | ||
if not success: | ||
venv.delete() | ||
|
||
|
||
@shared_task | ||
def install_packages(venv_id, package_names): | ||
venv = Virtualenv.objects.get(id=venv_id) | ||
venv = Venv.objects.get(id=venv_id) | ||
|
||
venv.install_packages(package_names) |
Oops, something went wrong.