aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/api/migrations/0022_merge_20211102_2136.py14
-rw-r--r--src/api/migrations/0023_add_cifile_generated_field.py14
-rw-r--r--src/api/models.py4
-rw-r--r--src/api/views.py15
-rw-r--r--src/dashboard/admin_utils.py29
-rw-r--r--src/resource_inventory/models.py1
6 files changed, 68 insertions, 9 deletions
diff --git a/src/api/migrations/0022_merge_20211102_2136.py b/src/api/migrations/0022_merge_20211102_2136.py
new file mode 100644
index 0000000..bb27ae4
--- /dev/null
+++ b/src/api/migrations/0022_merge_20211102_2136.py
@@ -0,0 +1,14 @@
+# Generated by Django 2.2 on 2021-11-02 21:36
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0019_auto_20210907_1448'),
+ ('api', '0021_auto_20210405_1943'),
+ ]
+
+ operations = [
+ ]
diff --git a/src/api/migrations/0023_add_cifile_generated_field.py b/src/api/migrations/0023_add_cifile_generated_field.py
new file mode 100644
index 0000000..df2b6d7
--- /dev/null
+++ b/src/api/migrations/0023_add_cifile_generated_field.py
@@ -0,0 +1,14 @@
+from django.db import migrations, models
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('api', '0022_merge_20211102_2136'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="CloudInitFile",
+ name="generated",
+ field=models.BooleanField(default=False)
+ ),
+ ]
diff --git a/src/api/models.py b/src/api/models.py
index 8cce5d5..93168f5 100644
--- a/src/api/models.py
+++ b/src/api/models.py
@@ -20,6 +20,7 @@ from django.utils import timezone
import json
import uuid
import yaml
+import re
from booking.models import Booking
from resource_inventory.models import (
@@ -362,7 +363,8 @@ class GeneratedCloudConfig(models.Model):
def _normalize_username(self, username: str) -> str:
# TODO: make usernames posix compliant
- return username
+ s = re.sub(r'\W+', '', username)
+ return s
def _get_ssh_string(self, username: str) -> str:
user = User.objects.get(username=username)
diff --git a/src/api/views.py b/src/api/views.py
index 3a82b96..1516374 100644
--- a/src/api/views.py
+++ b/src/api/views.py
@@ -295,7 +295,7 @@ def resource_ci_userdata(request, lab_name="", job_id="", resource_id="", file_i
"datasource_list": ["None"],
}
- return HttpResponse(yaml.dump(cloud_dict), status=200)
+ return HttpResponse(yaml.dump(cloud_dict, width=float("inf")), status=200)
@csrf_exempt
@@ -310,9 +310,9 @@ def resource_ci_userdata_directory(request, lab_name="", job_id="", resource_id=
files = resource.config.cloud_init_files
files = [{"id": file.id, "priority": file.priority} for file in files.order_by("priority").all()]
- d = {
- 'merge_failures': []
- }
+ d = {}
+
+ merge_failures = []
merger = Merger(
[
@@ -335,9 +335,12 @@ def resource_ci_userdata_directory(request, lab_name="", job_id="", resource_id=
print("Failed to merge file in, as it had invalid content:", f.id)
print("File text was:")
print(f.text)
- d['merge_failures'].append({f.id: str(e)})
+ merge_failures.append({f.id: str(e)})
+
+ if len(merge_failures) > 0:
+ d['merge_failures'] = merge_failures
- file = CloudInitFile.create(text=yaml.dump(d), priority=0)
+ file = CloudInitFile.create(text=yaml.dump(d, width=float("inf")), priority=0)
return HttpResponse(json.dumps([{"id": file.id, "priority": file.priority}]), status=200)
diff --git a/src/dashboard/admin_utils.py b/src/dashboard/admin_utils.py
index b105e96..045caeb 100644
--- a/src/dashboard/admin_utils.py
+++ b/src/dashboard/admin_utils.py
@@ -22,7 +22,8 @@ from resource_inventory.models import (
DiskProfile,
CpuProfile,
RamProfile,
- Interface
+ Interface,
+ CloudInitFile,
)
import json
@@ -50,7 +51,7 @@ from booking.models import Booking
from notifier.manager import NotificationHandler
from api.models import JobFactory
-from api.models import JobStatus
+from api.models import JobStatus, Job, GeneratedCloudConfig
def print_div():
@@ -528,6 +529,30 @@ def extend_booking(booking_id, days=0, hours=0, minutes=0, weeks=0):
booking.save()
+def regenerate_cloud_configs(booking_id):
+ b = Booking.objects.get(id=booking_id)
+ for res in b.resource.get_resources():
+ res.config.cloud_init_files.set(res.config.cloud_init_files.filter(generated=False)) # careful!
+ res.config.save()
+ cif = GeneratedCloudConfig.objects.create(resource_id=res.labid, booking=b, rconfig=res.config)
+ cif.save()
+ cif = CloudInitFile.create(priority=0, text=cif.serialize())
+ cif.save()
+ res.config.cloud_init_files.add(cif)
+ res.config.save()
+
+
+def set_job_new(job_id):
+ j = Job.objects.get(id=job_id)
+ b = j.booking
+ regenerate_cloud_configs(b.id)
+ for task in j.get_tasklist():
+ task.status = JobStatus.NEW
+ task.save()
+ j.status = JobStatus.NEW
+ j.save()
+
+
def docs(function=None, fulltext=False):
"""
Print documentation for a given function in admin_utils.
diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py
index aefd5ce..5d87430 100644
--- a/src/resource_inventory/models.py
+++ b/src/resource_inventory/models.py
@@ -157,6 +157,7 @@ class CloudInitFile(models.Model):
# higher priority is applied later, so "on top" of existing files
priority = models.IntegerField()
+ generated = models.BooleanField(default=False)
@classmethod
def merge_strategy(cls):