summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dashboard/src/api/models.py29
-rw-r--r--dashboard/src/booking/views.py11
-rw-r--r--dashboard/src/templates/base.html5
-rw-r--r--dashboard/src/workflow/models.py23
-rw-r--r--dashboard/tox.ini21
5 files changed, 71 insertions, 18 deletions
diff --git a/dashboard/src/api/models.py b/dashboard/src/api/models.py
index e4016aa..b14ea2f 100644
--- a/dashboard/src/api/models.py
+++ b/dashboard/src/api/models.py
@@ -604,7 +604,7 @@ class SnapshotConfig(TaskConfig):
def get_task(task_id):
- for taskclass in [AccessRelation, SoftwareRelation, HostHardwareRelation, HostNetworkRelation]:
+ for taskclass in [AccessRelation, SoftwareRelation, HostHardwareRelation, HostNetworkRelation, SnapshotRelation]:
try:
ret = taskclass.objects.get(task_id=task_id)
return ret
@@ -704,6 +704,33 @@ class SnapshotRelation(TaskRelation):
class JobFactory(object):
@classmethod
+ def reimageHost(cls, new_image, booking, host):
+ """
+ This method will make all necessary changes to make a lab
+ reimage a host.
+ """
+ job = Job.objects.get(booking=booking)
+ # make hardware task new
+ hardware_relation = HostHardwareRelation.objects.get(host=host, job=job)
+ hardware_relation.config.set_image(new_image.lab_id)
+ hardware_relation.config.save()
+ hardware_relation.status = JobStatus.NEW
+
+ # re-apply networking after host is reset
+ net_relation = HostNetworkRelation.objects.get(host=host, job=job)
+ net_relation.status = JobStatus.NEW
+
+ # re-apply ssh access after host is reset
+ ssh_relation = AccessRelation.objects.get(job=job, config__access_type="ssh")
+ ssh_relation.status = JobStatus.NEW
+
+ # save them all at once to reduce the chance
+ # of a lab polling and only seeing partial change
+ hardware_relation.save()
+ net_relation.save()
+ ssh_relation.save()
+
+ @classmethod
def makeSnapshotTask(cls, image, booking, host):
relation = SnapshotRelation()
job = Job.objects.get(booking=booking)
diff --git a/dashboard/src/booking/views.py b/dashboard/src/booking/views.py
index 3be9c7b..1e14b8e 100644
--- a/dashboard/src/booking/views.py
+++ b/dashboard/src/booking/views.py
@@ -23,7 +23,7 @@ from account.models import Lab
from booking.models import Booking
from booking.stats import StatisticsManager
from booking.forms import HostReImageForm
-from api.models import HostHardwareRelation, JobStatus
+from api.models import JobFactory
from workflow.views import login
from booking.forms import QuickBookingForm
from booking.quick_deployer import create_from_form, drop_filter
@@ -179,12 +179,9 @@ def booking_modify_image(request, booking_id):
return HttpResponse("unauthorized")
new_image = Image.objects.get(id=form.cleaned_data['image_id'])
host = Host.objects.get(id=form.cleaned_data['host_id'])
- relation = HostHardwareRelation.objects.get(host=host, job__booking=booking)
- config = relation.config
- config.set_image(new_image.lab_id)
- config.save()
- relation.status = JobStatus.NEW
- relation.save()
+ host.config.image = new_image
+ host.config.save()
+ JobFactory.reimageHost(new_image, booking, host)
return HttpResponse(new_image.name)
return HttpResponse("error")
diff --git a/dashboard/src/templates/base.html b/dashboard/src/templates/base.html
index f7fa7cd..02c67dc 100644
--- a/dashboard/src/templates/base.html
+++ b/dashboard/src/templates/base.html
@@ -158,11 +158,6 @@
class="fa fa-fw"></i>Booking Statistics</a>
</li>
<li>
- <a href="{% url 'api-root' %}"><i
- class="fa fa-fw"></i>API
- </a>
- </li>
- <li>
<a href="{% url 'account:my-account' %}"><i
class="fa fa-fw"></i>Account
</a>
diff --git a/dashboard/src/workflow/models.py b/dashboard/src/workflow/models.py
index 4e79546..beaaee4 100644
--- a/dashboard/src/workflow/models.py
+++ b/dashboard/src/workflow/models.py
@@ -61,15 +61,25 @@ class BookingAuthManager():
def parse_gerrit_url(self, url):
project_leads = []
try:
- parts = url.split("/")
+ halfs = url.split("?")
+ parts = halfs[0].split("/")
+ args = halfs[1].split(";")
if "http" in parts[0]: # the url include http(s)://
parts = parts[2:]
- if "f=INFO.yaml" not in parts[-1].split(";"):
+ if "f=INFO.yaml" not in args:
return None
if "gerrit.opnfv.org" not in parts[0]:
return None
+ try:
+ i = args.index("a=blob")
+ args[i] = "a=blob_plain"
+ except ValueError:
+ pass
+ # recreate url
+ halfs[1] = ";".join(args)
+ halfs[0] = "/".join(parts)
# now to download and parse file
- url = "https://" + "/".join(parts)
+ url = "https://" + "?".join(halfs)
info_file = requests.get(url, timeout=15).text
info_parsed = yaml.load(info_file)
ptl = info_parsed.get('project_lead')
@@ -138,8 +148,11 @@ class BookingAuthManager():
return True # admin override for this user
if repo.BOOKING_INFO_FILE not in repo.el:
return False # INFO file not provided
- ptl_info = self.parse_url(repo.BOOKING_INFO_FILE)
- return ptl_info and ptl_info == booking.owner.userprofile.email_addr
+ ptl_info = self.parse_url(repo.el.get(repo.BOOKING_INFO_FILE))
+ for ptl in ptl_info:
+ if ptl['email'] == booking.owner.userprofile.email_addr:
+ return True
+ return False
class WorkflowStep(object):
diff --git a/dashboard/tox.ini b/dashboard/tox.ini
new file mode 100644
index 0000000..3d01e10
--- /dev/null
+++ b/dashboard/tox.ini
@@ -0,0 +1,21 @@
+[tox]
+envlist = flake8
+skipsdist = True
+
+[testenv]
+deps = -rrequirements.txt
+basepython = python3
+
+# Store flake8 config here intead of .flake8
+[flake8]
+ignore =
+ # Ignore 'line-too-long' warnings
+ E501
+exclude =
+ src/manage.py
+
+[testenv:flake8]
+deps =
+ -rrequirements.txt
+ flake8
+commands = flake8 src/