Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorYasin <mohammed-yasin.rahman@lip6.fr>
Thu, 18 Dec 2014 14:23:04 +0000 (15:23 +0100)
committerYasin <mohammed-yasin.rahman@lip6.fr>
Thu, 18 Dec 2014 14:23:04 +0000 (15:23 +0100)
24 files changed:
README
forge/__init__.py [new file with mode: 0644]
forge/forms.py [new file with mode: 0644]
forge/models.py [new file with mode: 0644]
forge/script [new submodule]
forge/tasks.py [new file with mode: 0644]
forge/templates/create-course.html [new file with mode: 0644]
forge/templates/createCourse.html [new file with mode: 0644]
forge/templates/createLab.html [new file with mode: 0644]
forge/templates/labDetails.html [new file with mode: 0644]
forge/templates/list.html [new file with mode: 0644]
forge/templates/listCourse.html [new file with mode: 0644]
forge/templates/mainView.html [new file with mode: 0644]
forge/tests.py [new file with mode: 0644]
forge/views.py [new file with mode: 0644]
manifoldapi/manifoldproxy.py
portal/actions.py
portal/registrationview.py
portal/static/css/onelab.css
portal/static/img/bg-experiment.jpg [new file with mode: 0644]
portal/static/js/myslice.js
portal/templates/fed4fire/fed4fire_home-view.html
portal/templates/onelab/onelab_home-view.html
ui/topmenu.py

diff --git a/README b/README
index 3530ed2..9d39aa6 100644 (file)
--- a/README
+++ b/README
@@ -14,6 +14,7 @@ $ apt-get install python-django-south
 $ apt-get install python-pip or sudo easy_install pip==1.4.1
 $ pip install requests
 $ pip install djangorestframework
+$ pip install django-celery
 * git clone git://git.onelab.eu/myslice.git
 -- or --
 * git clone ssh://yourlogin@git.onelab.eu/git/myslice.git
diff --git a/forge/__init__.py b/forge/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/forge/forms.py b/forge/forms.py
new file mode 100644 (file)
index 0000000..402b3c3
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding:utf-8 -*-
+
+from django import forms
+from models import Lab, Course
+from django.db import models
+
+class LabForm(forms.ModelForm):
+       title = forms.CharField(label= "Title")
+       subject = forms.FileField(label="Subject of the lab")
+       class Meta:
+               model = Lab
+
+class courseForm(forms.Form):
+       lab = forms.ModelChoiceField(queryset= Lab.objects.all(), empty_label="Select a Lab")
+       nbEnv = forms.IntegerField(min_value=0, label="Number of environment")
+       subnet = forms.CharField(initial='10.1.0.0/16')
+
diff --git a/forge/models.py b/forge/models.py
new file mode 100644 (file)
index 0000000..e0b3ace
--- /dev/null
@@ -0,0 +1,118 @@
+# -*- coding:utf-8 -*-
+
+from django.db import models
+
+# Used for automatically delete file
+from django.dispatch import receiver
+import os
+
+# Class to describe a service set on a host
+class Service(models.Model):
+       serviceName = models.CharField(max_length=50)
+       servicePort = models.CharField(max_length=10)
+       host = models.ForeignKey('Host')
+
+       def __unicode__(self):
+               if self.servicePort != u'':
+                       return u"%s on %s" % (self.serviceName, self.servicePort)
+               else:
+                       return u"%s" % self.serviceName
+
+# Class to describe an interface available on a host
+class Interface(models.Model):
+       ip = models.CharField(max_length=16)
+       name = models.CharField(max_length=40)
+       host = models.ForeignKey('Host')
+
+       def __unicode__(self):
+               return u"%s -> %s" % (self.name, self.ip)
+
+# Class to describe a host
+class Host(models.Model):
+       TYPE_CHOICES = (
+               ('PUB', 'Public'),
+               ('PRIV', 'Private'),
+               ('COM', 'Common'),
+       )
+       hostname = models.CharField(max_length=100)
+       hostType = models.CharField(max_length=20, choices=TYPE_CHOICES, default='PRIV')
+       pleSlice = models.ForeignKey('Slice')
+       latitude = models.FloatField()
+       longitude = models.FloatField()
+
+       def __unicode__(self):
+               return u"%s %s" % (self.hostname, self.hostType)
+
+# Class to describe a slice (sliceName and reference to environment)
+class Slice(models.Model):
+       sliceName = models.CharField(max_length=50)
+       environment = models.ForeignKey('Environment')
+
+       def __unicode__(self):
+               return u"%s" % self.sliceName
+
+# Class to describe a student environment (sshKey and reference to a course)
+class Environment(models.Model):
+       sshKey = models.FileField(upload_to='ict_education/keys')
+       course = models.ForeignKey('Course')
+       confFile = models.FileField(upload_to='ict_education/xmlFiles')
+       linkFile = models.FileField(upload_to='ict_education/xmlFiles')
+       ready = models.BooleanField(default=False)
+
+# function used to automatically delete the stored file when deleting the model from the database
+@receiver(models.signals.post_delete, sender = Environment)
+def environment_delete_ssh_key(sender, instance, **kwargs):
+       if instance.sshKey:
+               if os.path.isfile(instance.sshKey.path):
+                       os.remove(instance.sshKey.path)
+       if instance.confFile:
+               if os.path.isfile(instance.confFile.path):
+                       os.remove(instance.confFile.path)
+       if instance.linkFile:
+               if os.path.isfile(instance.linkFile.path):
+                       os.remove(instance.linkFile.path)
+
+# Class to describe a course (ie a set of environment) (reference to lab, mainKey used by the teacher to access all node)
+class Course(models.Model):
+       lab = models.ForeignKey('Lab')
+       mainKey = models.FileField(upload_to='ict_education/keys', null = True)
+       ready = models.BooleanField(default=False)
+       sliceName = models.CharField(max_length=50)
+       
+       def __unicode__(self):
+               return u"%s %s" % (self.lab, self.sliceName)
+
+# function used to automatically delete the stored file when deleting the model from the database
+@receiver(models.signals.post_delete, sender = Course)
+def course_delete_main_ssh_key(sender, instance, **kwargs):
+       if instance.mainKey:
+               if os.path.isfile(instance.mainKey.path):
+                       os.remove(instance.mainKey.path)
+
+# Class to describe a lab
+class Lab(models.Model):
+       title = models.CharField(max_length=100)
+       author = models.CharField(max_length=40)
+       subject = models.FileField(upload_to='ict_education/Labs/subjects')
+       configurationFile = models.FileField(upload_to='ict_education/Labs/xmlFiles')
+       linkFile = models.FileField(upload_to='ict_education/Labs/xmlFiles')
+
+       def __unicode__(self):
+               return u"%s %s" % (self.title, self.author)
+
+# function used to automatically delete the stored file when deleting the model from the database
+@receiver(models.signals.post_delete, sender = Lab)
+def lab_delete_files(sender, instance, **kwargs):
+       # Remove the subject
+       if instance.subject:
+               if os.path.isfile(instance.subject.path):
+                       os.remove(instance.subject.path)
+       # Remove the configuration file
+       if instance.configurationFile:
+               if os.path.isfile(instance.configurationFile.path):
+                       os.remove(instance.configurationFile.path)
+       # Remove the link file
+       if instance.linkFile:
+               if os.path.isfile(instance.linkFile.path):
+                       os.remove(instance.linkFile.path)
+
diff --git a/forge/script b/forge/script
new file mode 160000 (submodule)
index 0000000..c0c898f
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit c0c898f8ded230e9a144df9e02d547004613fa8e
diff --git a/forge/tasks.py b/forge/tasks.py
new file mode 100644 (file)
index 0000000..cf3b996
--- /dev/null
@@ -0,0 +1,145 @@
+# -*- coding:utf-8 -*-
+from django.core.files import File
+from celery import task, current_task
+from djcelery.models import TaskState
+from xmlrpclib import Fault
+
+from forge.models import *
+
+import forge.script.Auth as Auth
+import time
+
+# Import class used to create the environment
+from forge.script.request import TransformRawXml
+from forge.script.openvswitch import TransformXml
+
+# Import the settings
+from django.conf import settings
+
+@task()
+def taskInstallEnvironment(env):
+       env.ready = False
+       env.save()
+       #TODO Change directory location
+       curDir = os.getcwd()
+       os.chdir('./ict_education/script/')
+       try:
+               xml = TransformXml(confFile = curDir+env.confFile.url, linkFile = curDir+env.linkFile.url, keyFile = curDir+env.course.mainKey.url)
+               xml.clearConf()
+               xml.setSliceConf()
+               xml.setLinks()
+               xml.setRoutes()
+               xml.setServices()
+       except Exception, why:
+               print why
+       os.chdir(curDir)
+       env.ready = True
+       env.save()
+
+@task()
+def taskDeleteCourse(course):
+       environments = course.environment_set.all()
+       #TODO Change directory location
+       curDir = os.getcwd()
+       os.chdir('./ict_education/script/')
+       for env in environments:
+               try:
+                       xml = TransformXml(confFile = curDir+env.confFile.url, linkFile = curDir+env.linkFile.url, keyFile = curDir+env.course.mainKey.url)
+                       xml.clearConf()
+               except Exception, why:
+                       print why
+       try:
+               rawXml = TransformRawXml(sliceName=course.sliceName)
+               rawXml.deleteSlice()
+       except Fault, why:
+               print "I got an xmlrpc Fault"
+               print why
+       os.chdir(curDir)
+       course.delete()
+
+@task()
+def taskRenewSlice(course):
+       rawXml = TransformRawXml(sliceName=course.sliceName)
+       rawXml.renewSlice()
+
+@task()
+def taskCreateCourse(form):
+       newCourse = Course()
+       newCourse.lab = Lab.objects.get(id=form.cleaned_data['lab'].id)
+       newCourse.ready = False
+       newCourse.sliceName = form.cleaned_data['sliceName']
+       newCourse.save()
+       #TODO Change directory location
+       curDir = os.getcwd()
+       os.chdir('./ict_education/script/')
+       if form.cleaned_data['keyLocation'] == '':
+               keyLocation = None
+       else:
+               keyLocation = form.cleaned_data['keyLocation']
+       if form.cleaned_data['url'] == '':
+               sliceUrl = 'http://onelab.eu'
+       else:
+               sliceUrl = form.cleaned_data['url']
+       if form.cleaned_data['description'] == '':
+               sliceDescription = 'Slice used for educational purpose'
+       else:
+               sliceDescription = form.cleaned_data['url']
+       try:
+               rawXml = TransformRawXml(confFile = settings.MEDIA_ROOT+newCourse.lab.configurationFile.name, linkFile = settings.MEDIA_ROOT+newCourse.lab.linkFile.name, subnet = form.cleaned_data['subnet'], sliceName = form.cleaned_data['sliceName'], nbEnv = form.cleaned_data['nbEnv'], sliceUrl = sliceUrl, sliceDescription = sliceDescription, mainKeyPriv = keyLocation)
+               rawXml.setSlice()
+               newCourse.mainKey.save(rawXml.mainKeyPriv.split('/')[-1], File(open(rawXml.mainKeyPriv)))
+               newCourse.save()
+               i = 0
+               for environment in rawXml.envList:
+                       newEnv = Environment()
+                       newEnv.ready = False
+                       newEnv.course = newCourse
+                       newEnv.sshKey.save(rawXml.envKeyPriv[i].split('/')[-1], File(open(rawXml.envKeyPriv[i])))
+                       newEnv.confFile.save(rawXml.envConfFile[i].split('/')[-1], File(open(rawXml.envConfFile[i])))
+                       newEnv.linkFile.save(rawXml.envLinkFile[i].split('/')[-1], File(open(rawXml.envLinkFile[i])))
+                       newEnv.save()
+                       i += 1
+                       for plSlice in environment:
+                               newSlice = Slice()
+                               newSlice.sliceName = plSlice.slice_name
+                               newSlice.environment = newEnv
+                               newSlice.save()
+                               for host in plSlice.hosts:
+                                       newHost = Host()
+                                       nodeSelected = ''
+                                       for env in rawXml.nodeList:
+                                               for node in env:
+                                                       if node['hostname'] == host.url:
+                                                               nodeselected = node
+                                                               break
+                                               if nodeSelected != '':
+                                                       break
+                                       newHost.hostname = host.url
+                                       newHost.pleSlice = newSlice
+                                       newHost.latitude = nodeSelected['latitude']
+                                       newHost.longitude = nodeSelected['longitude']
+                                       newHost.save()
+                                       for serviceName, port in host.services.services:
+                                               newService = Service()
+                                               newService.serviceName = serviceName
+                                               newService.servicePort = str(port)
+                                               newService.host = newHost
+                                               newService.save()
+                                       for device in host.devices:
+                                               newInterface = Interface()
+                                               newInterface.ip = device.ip
+                                               newInterface.name = device.id_dev
+                                               newInterface.host = newHost
+                                               newInterface.save()
+                       newEnv.ready = True
+                       newEnv.save()
+               os.chdir(curDir)
+               newCourse.ready = True
+               newCourse.save()
+       except Exception, why:
+               print "An error occured deleting the environment"
+               print why
+               rawXml = TransformRawXml(sliceName=newCourse.sliceName)
+               rawXml.deleteSlice()
+               raise Exception('Global Fault')
+       return 0
diff --git a/forge/templates/create-course.html b/forge/templates/create-course.html
new file mode 100644 (file)
index 0000000..5b06bfb
--- /dev/null
@@ -0,0 +1,10 @@
+<div class="col-md-2">
+</div>
+<div class="col-md-8">
+       <form action="." method="post" enctype="multipart/form-data">
+               {{ form.as_p }}
+               <p><input type="submit" value="Create Class" /></p>
+       </form>
+</div>
+<div class="col-md-2">
+</div>
diff --git a/forge/templates/createCourse.html b/forge/templates/createCourse.html
new file mode 100644 (file)
index 0000000..26b5b1d
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8"/>
+               <title>Create a new Class</title>
+       </head>
+       <body>
+               <form action="{% url "ict_education.views.createCourse" %}" method="post" enctype="multipart/form-data">
+                       {% csrf_token %}
+                       {{ form.as_p }}
+                       <p><input type="submit" value="Create Class" /></p>
+               </form>
+       </body>
+</html>
diff --git a/forge/templates/createLab.html b/forge/templates/createLab.html
new file mode 100644 (file)
index 0000000..2a0b67d
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8">
+               <title>Create a new Lab</title>
+       </head>
+       <body>
+       <!-- List of existing labs -->
+       {% if labs %}
+               <ul>
+               {% for lab in labs %}
+                       <li>{{ lab }} 
+                               <a href="/ict_education/lab-details/{{ lab.id }}">Lab details</a>
+                               <a href="/ict_education/delete-lab/{{ lab.id }}">Delete Lab</a>
+                       </li>
+               {% endfor %}
+               </ul>
+       {% else %}
+               <p>No lab</p>
+       {% endif %}
+
+               <!-- Upload form. Note enctype attribute! -->
+               <form action="{% url "ict_education.views.createLab" %}" method="post" enctype="multipart/form-data">
+                       {% csrf_token %}
+                       {{ form.as_p }}
+                       <p><input type="submit" value="Add Lab" /></p>
+               </form>
+       </body>
+</html>
diff --git a/forge/templates/labDetails.html b/forge/templates/labDetails.html
new file mode 100644 (file)
index 0000000..0ab10cc
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8"/>
+               <title>Details of lab {{ lab.title }}</title>
+       </head>
+       <body>
+               <h1>{{ lab.title }}</h1>
+               <h2>{{ lab.author }}</h2>
+               <p><a href="{{ lab.subject.url }}">Subject</a></p>
+               <p><a href="{{ lab.configurationFile.url }}">Configuration File</a><p>
+               <p><a href="{{ lab.linkFile.url }}">{{ lab.linkFile.name }}</a></p>
+       </body>
+</html>
diff --git a/forge/templates/list.html b/forge/templates/list.html
new file mode 100644 (file)
index 0000000..42c2579
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8">
+               <title>Minimal Django File Upload Example</title>
+       </head>
+       <body>
+       <!-- List of uploaded documents -->
+       {% if documents %}
+               <ul>
+               {% for document in documents %}
+                       <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>
+               {% endfor %}
+               </ul>
+       {% else %}
+               <p>No documents.</p>
+       {% endif %}
+
+               <!-- Upload form. Note enctype attribute! -->
+               <form action="{% url "ict_education.views.list" %}" method="post" enctype="multipart/form-data">
+                       {% csrf_token %}
+                       <p>{{ form.non_field_errors }}</p>
+                       <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
+                       <p>
+                               {{ form.docfile.errors }}
+                               {{ form.docfile }}
+                       </p>
+                       <p><input type="submit" value="Upload" /></p>
+               </form>
+       </body>
+</html>
diff --git a/forge/templates/listCourse.html b/forge/templates/listCourse.html
new file mode 100644 (file)
index 0000000..0c51059
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8"/>
+               <title>List of all your class</title>
+       </head>
+       <body>
+               {% if courses %}
+                       <ul>
+                       {% for course, environments in courses %}
+                               
+                               {% if course.ready %}
+                                       <ul>
+                                       <li><a href=" {{ course.mainKey.url }}">Main SSH Key</a></li>
+                                       {# <li>{{ course.id }}</li> #}
+                                       <li><a href=" {{ course.lab.subject.url }}">Subject</a></li>
+                                       <li><a href="/ict_education/delete-course/{{ course.id }}">Delete Course</a></li>
+                                       <li><a href="/ict_education/renew-slice/{{ course.id }}">Renew-Slice</a></li>
+                                       <ul>
+                                       {% for environment, slices  in environments %}
+                                               {% if environment.ready %}
+                                                       <li>Environment <a href="/ict_education/install-env/{{ environment.id }}">Re-install environment</a></li>
+                                                       <li><a href=" {{ environment.sshKey.url }}">SSH Key</a></li>
+                                                       <ul>
+                                                       {% for pleSlice, hosts in slices %}
+                                                               <li>{{ pleSlice.sliceName }}</li>
+                                                               <ul>
+                                                               {% for host, services, interfaces in hosts %}
+                                                                       <li>Hostname : {{ host.hostname }} Type : {{ host.hostType }}</li>
+                                                                       <ul>
+                                                                       {% if services %}
+                                                                               <li>Service List :</li>
+                                                                               <ul>
+                                                                               {% for service in services %}
+                                                                                       {% if service.servicePort == '' %}
+                                                                                               <li>{{ service.serviceName }}</li>
+                                                                                       {% else %}
+                                                                                               <li>{{ service.serviceName }} on {{ service.servicePort }}</li>
+                                                                                       {% endif %}
+                                                                               {% endfor %}
+                                                                               </ul>
+                                                                       {% endif %}
+                                                                       {% if interfaces %}
+                                                                               <li>Interface List :</li>
+                                                                               <ul>
+                                                                               {% for interface in interfaces %}
+                                                                                       <li>{{ interface.name }} : {{ interface.ip }}</li>
+                                                                               {% endfor %}
+                                                                               </ul>
+                                                                       {% endif %}
+                                                                       </ul>
+                                                               {% endfor %}
+                                                               </ul>
+                                                       {% endfor %}
+                                                       </ul>
+                                               {% else %}
+                                                       <ul>Now installing this environment</ul>
+                                                       <li>Environment <a href="/ict_education/install-env/{{ environment.id }}">Re-install environment</a></li>
+                                               {% endif %}
+                                       {% endfor %}
+                                       </ul>
+                               {% else %}
+                                       <li>Course not ready</li>
+                                       <li>{{ course.ready }}</li>
+                               {% endif %}
+                               </ul>
+                       {% endfor %}
+                       </ul>
+               {% else %}
+                       <p>You have not created a class yet</p>
+               {% endif %}
+       </body>
+</html>
diff --git a/forge/templates/mainView.html b/forge/templates/mainView.html
new file mode 100644 (file)
index 0000000..6f5ae31
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset="utf-8"/>
+               <title>ICT Education</title>
+       </head>
+       <body>
+       <!-- List of available action -->
+               <p><a href="create-lab">Create a new lab</a></p>
+               <p><a href="create-class">Create a new course</a></p>
+               <p><a href="list-course">List of your course</a></p>
+
+       </body>
+</html
diff --git a/forge/tests.py b/forge/tests.py
new file mode 100644 (file)
index 0000000..501deb7
--- /dev/null
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)
diff --git a/forge/views.py b/forge/views.py
new file mode 100644 (file)
index 0000000..6e5cc84
--- /dev/null
@@ -0,0 +1,132 @@
+# -*- coding:utf-8 -*-
+# Create your views here.
+
+# Several import from the django facilities
+from django.template import RequestContext
+from django.shortcuts import render, get_object_or_404, render_to_response, redirect
+from django.template import RequestContext
+from django.core.urlresolvers import reverse
+from django.core.files import File
+
+# Import of the forms and models
+from forge.models import *
+from forge.forms import *
+
+# Import of the task and TaskState (used to link task in the database)
+from forge.tasks import *
+from djcelery.models import TaskState
+
+# Import the settings
+from django.conf import settings
+
+import os
+
+# Import class used to create the environment
+from forge.script.request import TransformRawXml
+
+from myslice.theme import ThemeView
+from unfold.loginrequired import FreeAccessView
+
+class CreateCourseViev (FreeAccessView, ThemeView):
+       template_name = 'create-course.html'
+
+       def get (self, request, slicename, state=None):
+               username = self.request.user
+               split_slicename = slicename.split('.')
+               ple_slicename = split_slicename[0] + '8' + split_slicename[1] + '_' + split_slicename[2]
+               if not Course.objects.get(sliceName = ple_slicename).exists():
+                       if request.method == 'POST':
+                               form = courseForm(request.POST)
+                               if form.is_valid():
+                                       result = taskCreateCourse.delay(form)
+                       else:
+                               labs = Lab.objects.all()
+                               form = courseForm()
+               return render_to_response(self.template, { 'theme' : self.theme,'slicename':slicename, 'ple_slicename':ple_slicename, 'username':username, 'form': form }, context_instance=RequestContext(request))
+
+def mainView(request):
+       return render(request, 'mainView.html', locals())
+
+
+def createLab(request):
+       if request.method == 'POST':
+               form = LabForm(request.POST, request.FILES)
+               if form.is_valid():
+                       newLab = Lab(
+                               title = form['title'].value(),
+                               author = form['author'].value(),
+                               subject = request.FILES['subject'],
+                               configurationFile = request.FILES['configurationFile'],
+                               linkFile = request.FILES['linkFile'],
+                       )
+                       newLab.save()
+       else:
+               form = LabForm()
+       labs = Lab.objects.all()
+       return render_to_response('createLab.html', {'labs': labs, 'form':form}, context_instance=RequestContext(request))
+
+def labDetails(request, id):
+       try:
+               lab = Lab.objects.get(id=id)
+       except Lab.DoesNotExist:
+               raise Http404
+       return render(request, 'labDetails.html', locals())
+
+def deleteLab(request, id):
+       try:
+               lab = Lab.objects.get(id=id)
+       except Lab.DoesNotExist:
+               raise Http404
+       lab.delete()
+       return redirect('forge.views.createLab')
+
+def createCourse(request):
+       if request.method == 'POST':
+               form = courseForm(request.POST)
+               if form.is_valid():
+                       result = taskCreateCourse.delay(form)
+       else:
+               labs = Lab.objects.all()
+               form = courseForm()
+       return render(request, 'createCourse.html', locals())
+
+def installEnvironment(request, id):
+       task = taskInstallEnvironment.delay(Environment.objects.get(id=id))
+       return redirect('forge.views.listCourse')
+
+def renewSlice(request, id):
+       task = taskRenewSlice.delay(Course.objects.get(id=id))
+       return redirect('forge.views.listCourse')
+
+def deleteCourse(request, id):
+       task = taskDeleteCourse.delay(Course.objects.get(id=id))
+       return redirect('forge.views.listCourse')
+
+def listCourse(request):
+       courses = Course.objects.all()
+       environments = Environment.objects.all()
+       slices = Slice.objects.all()
+       hosts = Host.objects.all()
+       services = Service.objects.all()
+       renderCourses = []
+       for course in courses:
+               renderEnvironment = []
+               if course.ready:
+                       for environment in course.environment_set.all():
+                               renderSlice = []
+                               for pleSlice in environment.slice_set.all():
+                                       renderHost = []
+                                       for host in pleSlice.host_set.all():
+                                               renderService = []
+                                               for service in host.service_set.all():
+                                                       renderService.append(service)
+                                               renderInterface = []
+                                               for interface in host.interface_set.all():
+                                                       renderInterface.append(interface)
+                                               renderHost.append([host, renderService, renderInterface])
+                                       renderSlice.append([pleSlice, renderHost])
+                               renderEnvironment.append([environment, renderSlice])
+               renderCourses.append([course, renderEnvironment])
+
+       
+       return render(request, 'listCourse.html', {'courses': renderCourses})
index 9897b50..9385bfa 100644 (file)
@@ -59,6 +59,7 @@ with the query passed using POST"""
             manifold_api_session_auth = {'AuthMethod': 'password', 'Username': admin_user, 'AuthString': admin_password}
         else:
             if 'manifold' in request.session:
+                print '===> manifoldproxy.proxy: before auth', manifold_query
                 manifold_api_session_auth = request.session['manifold']['auth']
             else:
                 json_answer=json.dumps({'code':0,'value':[]})
index d934671..7bd4143 100644 (file)
@@ -25,6 +25,8 @@ import activity.slice
 # Get the list of authorities
 
 def authority_get_pis(request, authority_hrn):
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
     query = Query.get('authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users')
     results = execute_admin_query(request, query)
     print "authority_get_pis = %s" % results
@@ -49,7 +51,9 @@ def authority_get_pi_emails(request, authority_hrn):
         return ['support@onelab.eu']
     else:
         pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ]
-        query = Query.get('user').filter_by('user_hrn', 'included', pi_user_hrns).select('user_email')
+
+        # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+        query = Query.get('myslice:user').filter_by('user_hrn', 'included', pi_user_hrns).select('user_email')
         results = execute_admin_query(request, query)
         return [result['user_email'] for result in results]
 
@@ -95,8 +99,10 @@ def clear_user_creds(request, user_email):
 def is_pi(wsgi_request, user_hrn, authority_hrn):
     # XXX could be done in a single query !
 
-    # select pi_authorities from user where user_hrn == "ple.upmc.jordan_auge"
-    query = Query.get('user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities')
+    # seauthorities from user where user_hrn == "ple.upmc.jordan_auge"
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities')
     results = execute_admin_query(wsgi_request, query)
     if not results:
         # XXX Warning ?
@@ -108,7 +114,9 @@ def is_pi(wsgi_request, user_hrn, authority_hrn):
 # SFA get record
 
 def sfa_get_user(request, user_hrn, pub):
-    query_sfa_user = Query.get('user').filter_by('user_hrn', '==', user_hrn)
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query_sfa_user = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn)
     result_sfa_user = execute_admin_query(request, query_sfa_user)
     return result_sfa_user                        
 
@@ -116,11 +124,15 @@ def sfa_update_user(request, user_hrn, user_params):
     # user_params: keys [public_key] 
     if 'email' in user_params:
         user_params['user_email'] = user_params['email']
-    query = Query.update('user').filter_by('user_hrn', '==', user_hrn).set(user_params).select('user_hrn')
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query = Query.update('myslice:user').filter_by('user_hrn', '==', user_hrn).set(user_params).select('user_hrn')
     results = execute_admin_query(request,query)
     return results
 
 def sfa_add_authority(request, authority_params):
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
     query = Query.create('authority').set(authority_params).select('authority_hrn')
     results = execute_query(request, query)
     print "sfa_add_auth results=",results
@@ -130,10 +142,14 @@ def sfa_add_authority(request, authority_params):
 
 def sfa_add_user_to_slice(request, user_hrn, slice_params):
 # UPDATE myslice:slice SET researcher=['ple.upmc.jordan_auge','ple.inria.thierry_parmentelat','ple.upmc.loic_baron','ple.upmc.ciro_scognamiglio','ple.upmc.mohammed-yasin_rahman','ple.upmc.azerty'] where slice_hrn=='ple.upmc.myslicedemo'
-    query_current_users = Query.get('slice').select('user').filter_by('slice_hrn','==',slice_params['hrn'])
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query_current_users = Query.get('myslice:slice').select('user').filter_by('slice_hrn','==',slice_params['hrn'])
     results_current_users = execute_query(request, query_current_users)
     slice_params['researcher'] = slice_params['researcher'] | results_current_users
-    query = Query.update('slice').filter_by('user_hrn', '==', user_hrn).set(slice_params).select('slice_hrn')
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query = Query.update('myslice:slice').filter_by('user_hrn', '==', user_hrn).set(slice_params).select('slice_hrn')
     results = execute_query(request, query)
 # Also possible but not supported yet
 # UPDATE myslice:user SET slice=['ple.upmc.agent','ple.upmc.myslicedemo','ple.upmc.tophat'] where user_hrn=='ple.upmc.azerty'
@@ -590,7 +606,8 @@ def create_slice(wsgi_request, request):
     user_hrn = request.get('user_hrn', None)
     user_hrns = list([user_hrn]) if user_hrn else list()
     
-    user_query  = Query().get('user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    user_query  = Query().get('myslice:user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
     user_details_sfa = execute_admin_query(wsgi_request, user_query)
     if not user_details_sfa:
         raise Exception, "User %s doesn't exist, validate user before validating slice" % user_hrn
@@ -612,6 +629,7 @@ def create_slice(wsgi_request, request):
     }
     # ignored in request: id, timestamp,  number_of_nodes, type_of_nodes, purpose
 
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
     query = Query.create('myslice:slice').set(slice_params).select('slice_hrn')
     results = execute_query(wsgi_request, query)
     if not results:
@@ -752,7 +770,8 @@ def sfa_create_user(wsgi_request, request, namespace = None, as_admin = False):
     if namespace is not None:
         query = Query.create('%s:user' % namespace).set(sfa_user_params).select('user_hrn')
     else:
-        query = Query.create('user').set(sfa_user_params).select('user_hrn')
+        # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+        query = Query.create('myslice:user').set(sfa_user_params).select('user_hrn')
 
     if as_admin:
         results = execute_admin_query(wsgi_request, query)
index e55e30f..353f534 100644 (file)
@@ -41,6 +41,7 @@ class RegistrationView (FreeAccessView, ThemeView):
         """
         errors = []
         authority_hrn = None
+        # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
         authorities_query = Query.get('authority').select('name', 'authority_hrn')
         authorities = execute_admin_query(wsgi_request, authorities_query)
         if authorities is not None:
@@ -52,6 +53,7 @@ class RegistrationView (FreeAccessView, ThemeView):
         page.add_js_files  ( [ "js/jquery.validate.js", "js/my_account.register.js", "js/jquery.qtip.min.js","js/jquery-ui.js" ] )
         page.add_css_files ( [ "css/onelab.css", "css/registration.css", "css/jquery.qtip.min.css" ] )
         page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
+        page.expose_js_metadata()
         print "############ BREAKPOINT 2 #################"
         if method == 'POST':
             reg_form = {}
@@ -116,7 +118,9 @@ class RegistrationView (FreeAccessView, ThemeView):
             # Does the user exist in sfa? [query is very slow!!]
             #user_query  = Query().get('user').select('user_hrn','user_email')
             # XXX Test based on the user_hrn is quick
-            user_query  = Query().get('user').select('user_hrn','user_email').filter_by('user_hrn','==',user_request['user_hrn'])
+
+            # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+            user_query  = Query().get('myslice:user').select('user_hrn','user_email').filter_by('user_hrn','==',user_request['user_hrn'])
             user_details_sfa = execute_admin_query(wsgi_request, user_query)
 
             for user in user_details_sfa:
@@ -191,7 +195,7 @@ class RegistrationView (FreeAccessView, ThemeView):
             print "############ BREAKPOINT B #################"
 
         template_env = {
-          'topmenu_items': topmenu_items_live('Register', page),
+          #'topmenu_items': topmenu_items_live('Register', page),
           'errors': errors,
           'authorities': authorities,
           'theme': self.theme
index 0b238d9..27c6b47 100644 (file)
@@ -715,7 +715,7 @@ div.home {
     line-height:1.2em;
     letter-spacing:0.3pt;
     min-height:500px;
-    background-image: url('../img/bg-experiment.png');
+    background-image: url('../img/bg-experiment.jpg');
     background-repeat:no-repeat;
     background-size:cover;
     background-position:center top;
diff --git a/portal/static/img/bg-experiment.jpg b/portal/static/img/bg-experiment.jpg
new file mode 100644 (file)
index 0000000..1fc35c1
Binary files /dev/null and b/portal/static/img/bg-experiment.jpg differ
index d9593af..85c7ac8 100644 (file)
@@ -114,17 +114,44 @@ var myslice = {
                }
                return this.user;
        },
+    loadSlices: function(slices) {
+        if (typeof(slices) == "undefined"){
 
+            if(myslice.user != null && typeof(myslice.user.slices) != "undefined" && myslice.user.slices.length>0){
+                slices == myslice.user.slices
+            }
+        }
+        // myslice.user is in LocalStorage
+        if(typeof(slices) != "undefined"){
+            /*
+                Launch queries to get the resources and leases in Manifold Cache
+            */
+            $.post("/rest/resource/", function( data ) {
+            });
+            $.post("/rest/lease/", function( data ) {
+            });
+
+            $.each( slices, function(i, val) {
+                /*
+                Launch a Query for each slice to get resources and leases in Manifold Cache
+                */
+                $.post("/rest/slice/", { 'filters': { 'slice_hrn' : val } }, function(data) {
+                });
+            });
+        }
+
+    },
        login: function(fn) {
         user = localStorage.getItem('user');
         if($.isEmptyObject(user)){
-                   $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) {
+            // REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+                   $.post("/rest/myslice:user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) {
                            //myslice.user = new user(data[0]);
                            localStorage.setItem('user', JSON.stringify(data[0]));
+                myslice.loadSlices(data[0].slices);
                    });
         }
        },
-
     getSlices: function(name) {
        
     },
index fed82dc..385f698 100644 (file)
                        window.location="/portal/slice_request/";
                });
 
-        /*
-            Launch queries to get the resources and leases in Manifold Cache
-        */
-            
-        $.post("/rest/resource/", function( data ) {
-        });
-        $.post("/rest/lease/", function( data ) {
-        });
-        
-        /*-------
-        List of slices has been moved in 
-        portal/templates/base.html
-        This is now in localStorage 
-        --------*/
-        // myslice.user is in LocalStorage
-        if(myslice.user.slices.length>0){
-            $.each( myslice.user.slices, function(i, val) {
-                // Launch a Query for each slice to get resources and leases in Manifold Cache
-                $.post("/rest/slice/", { 'filters': { 'slice_hrn' : val } }, function(data) {
-                });
-            });
-        }
+        myslice.loadSlices();
 });
 </script>
 
index 9170b4a..08670c8 100644 (file)
                        window.location="/portal/slice_request/";
                });
 
-        /*
-            Launch queries to get the resources and leases in Manifold Cache
-        */
-            
-        $.post("/rest/resource/", function( data ) {
-        });
-        $.post("/rest/lease/", function( data ) {
-        });
+        myslice.loadSlices();
         
-        /*-------
-        List of slices has been moved in 
-        portal/templates/base.html
-        This is now in localStorage 
-        --------*/
-        // myslice.user is in LocalStorage
-        if(myslice.user.slices.length>0){
-            $.each( myslice.user.slices, function(i, val) {
-                /*
-                Launch a Query for each slice to get resources and leases in Manifold Cache
-                */
-                $.post("/rest/slice/", { 'filters': { 'slice_hrn' : val } }, function(data) {
-                });
-            });
-        }
 });
 </script>
 {# widget "_widget-monitor.html" #}
index 988af27..667711d 100644 (file)
@@ -72,7 +72,9 @@ def topmenu_items_live (current, page):
     request=page.request
     # XXX TODO This should be triggered only when user is logged in
     # We might use local storage instead
-    query_pi_auths = Query.get('user').filter_by('user_hrn', '==', '$user_hrn' ).select('user_hrn','pi_authorities')
+
+    # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+    query_pi_auths = Query.get('myslice:user').filter_by('user_hrn', '==', '$user_hrn' ).select('user_hrn','pi_authorities')
     page.enqueue_query(query_pi_auths)
 #        # even though this plugin does not have any html materialization, the corresponding domid
 #        # must exist because it is searched at init-time to create the JS plugin