Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Thu, 27 Mar 2014 10:51:28 +0000 (11:51 +0100)
committerCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Thu, 27 Mar 2014 10:51:28 +0000 (11:51 +0100)
plugins/scheduler2/__init__.py
plugins/scheduler2/static/js/scheduler2.js
portal/sliceresourceview.py
portal/templates/documentationview.html
portal/templates/fed4fire/old._widget-topmenu.html [deleted file]
portal/templates/fed4fire/old.home-view.html [deleted file]
portal/templates/slice-resource-view.html
rest/__init__.py
rest/create.py
rest/update.py

index a1057a4..0be022c 100755 (executable)
@@ -11,8 +11,11 @@ class Scheduler2 (Plugin):
         self.query=query\r
         self.query_all_resources = query_all_resources\r
         self.query_all_resources_uuid = query_all_resources.query_uuid\r
+\r
         self.query_lease = query_lease\r
-        query_lease.query_uuid if query_lease else None\r
+        self.query_lease_uuid = query_lease.query_uuid\r
+\r
+        #query_lease.query_uuid if query_lease else None\r
 \r
         #granularity in minutes\r
         granularity = 10\r
index dd0c8f8..7c6c323 100755 (executable)
@@ -48,6 +48,7 @@ var schdlr_PartsInOneHour = 6;
          *     applied, which allows to maintain chainability of calls\r
          */\r
         init: function (options, element) {\r
+            this.classname="scheduler2";\r
             // Call the parent constructor, see FAQ when forgotten\r
             this._super(options, element);\r
 \r
@@ -113,18 +114,21 @@ var schdlr_PartsInOneHour = 6;
             var totalCell = "";\r
             for (var i = 0; i < totalColums; i++) totalCell +="<td></td>"; \r
             var srt_body = "";\r
-\r
+            \r
             $.each(SchedulerResources, function (i, group) {\r
+                console.log(group.groupName);\r
                 //var groupTR = $("#ShedulerNodes tbody").html('<tr><td class="no-image verticalIndex" rowspan="' + group.resources.length + '"><div class="verticalText">' + group.groupName + '</div></td><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
-                var groupTR = $("#ShedulerNodes tbody").html('<tr><td class="no-image verticalIndex" rowspan="' + 30 + '"><div class="verticalText">' + group.groupName + '</div></td><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
+                //var groupTR = $("#ShedulerNodes tbody").html('<tr><td class="no-image verticalIndex" rowspan="' + 30 + '"><div class="verticalText">' + group.groupName + '</div></td><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
+                var groupTR = $("#ShedulerNodes tbody").html('<tr><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
                 \r
-                $.each(group.resources.slice(0,30), function (i, resource) {\r
+                //$.each(group.resources.slice(0,30), function (i, resource) {\r
+                $.each(group.resources, function (i, resource) {\r
                     if (i == 0) {\r
                         //$("#ShedulerNodes tbody tr:first").append('<td class="info fixed">' + resource.hostname + '</td>');\r
-                        $(groupTR).find("#schdlr_frstTD").html(resource.hostname);\r
+                        $(groupTR).find("#schdlr_frstTD").html(resource.urn);\r
                         //$(srt_body).html("<tr>" + totalCell + "</tr>");\r
                     } else {\r
-                        $(groupTR).find("tr:last").after('<tr><td class="info fixed">' + resource.hostname + '</td></tr>');\r
+                        $(groupTR).find("tr:last").after('<tr><td class="info fixed">' + resource.urn + '</td></tr>');\r
                         //$(srt_body).find("tr:last").after("<tr>" + totalCell + "</tr>");\r
                     }\r
                     srt_body += "<tr>" + totalCell + "</tr>";\r
@@ -181,6 +185,7 @@ var schdlr_PartsInOneHour = 6;
             //data is empty on load\r
         },\r
         on_all_resources_new_record: function (data) {\r
+            //console.log(data);\r
             var tmpGroup = lookup(SchedulerResources, 'groupName', data.type);\r
             if (tmpGroup == null) {\r
                 tmpGroup = { groupName: data.type, resources: [] };\r
@@ -204,12 +209,12 @@ var schdlr_PartsInOneHour = 6;
         },\r
         /* all_resources QUERY HANDLERS End */\r
         /* lease QUERY HANDLERS Start */\r
-        on_lease_clear_records: function (data) { alert('clear_records'); },\r
-        on_lease_query_in_progress: function (data) { alert('query_in_progress'); },\r
-        on_lease_new_record: function (data) { alert('new_record'); },\r
-        on_lease_query_done: function (data) { alert('query_done'); },\r
+        on_lease_clear_records: function (data) { console.log('clear_records'); },\r
+        on_lease_query_in_progress: function (data) { console.log('lease_query_in_progress'); },\r
+        on_lease_new_record: function (data) { console.log('lease_new_record'); },\r
+        on_lease_query_done: function (data) { console.log('lease_query_done'); },\r
         //another plugin has modified something, that requires you to update your display. \r
-        on_lease_field_state_changed: function (data) { alert('query_done'); },\r
+        on_lease_field_state_changed: function (data) { console.log('lease_field_state_changed'); },\r
         /* lease QUERY HANDLERS End */\r
 \r
 \r
index bdffa3f..7d4ab08 100644 (file)
@@ -17,6 +17,7 @@ from plugins.querytable              import QueryTable
 from plugins.googlemap               import GoogleMap
 from plugins.queryupdater            import QueryUpdater
 from plugins.testbeds                import TestbedsPlugin
+from plugins.scheduler2              import Scheduler2
 
 from myslice.theme import ThemeView
 
@@ -56,15 +57,23 @@ class SliceResourceView (LoginRequiredView, ThemeView):
         main_query_init_key = 'urn'
         aq = AnalyzedQuery(main_query, metadata=metadata)
         page.enqueue_query(main_query, analyzed_query=aq)
+        sq_resource    = aq.subquery('resource')
+        sq_lease       = aq.subquery('lease')
 
         query_resource_all = Query.get('resource').select(resource_fields)
         page.enqueue_query(query_resource_all)
 
-        sq_resource    = aq.subquery('resource')
-        sq_lease       = aq.subquery('lease')
+        # leases query
+        lease_md = metadata.details_by_object('lease')
+        lease_fields = [column['name'] for column in lease_md['column']]
+
+        query_all_lease = Query.get('lease').select(lease_fields)
+        page.enqueue_query(query_all_lease)
+
+        print "!!!!!!!!!!   query leases = ",query_all_lease
 
         # --------------------------------------------------------------------------
-        # RESOURCES
+        # RESOURCES LIST
         # resources as a list using datatable plugin
  
         list_resources = QueryTable(
@@ -83,7 +92,7 @@ class SliceResourceView (LoginRequiredView, ThemeView):
         )
 
         # --------------------------------------------------------------------------
-        # RESOURCES
+        # RESOURCES MAP
         # the resources part is made of a Tabs (Geographic, List), 
 
         map_resources  = GoogleMap(
@@ -105,6 +114,20 @@ class SliceResourceView (LoginRequiredView, ThemeView):
             zoom       = 4,
         )
 
+        # --------------------------------------------------------------------------
+        # LEASES Nitos Scheduler
+        # Display the leases reservation timeslots of the resources
+
+        resources_as_scheduler2 = Scheduler2( 
+            page       = page,
+            domid      = 'scheduler',
+            title      = 'Scheduler',
+            # this is the query at the core of the slice list
+            query = sq_resource,
+            query_all_resources = query_resource_all,
+            query_lease = query_all_lease,
+        )
+
         # --------------------------------------------------------------------------
         # QueryUpdater (Pending Operations)
  
@@ -125,7 +148,6 @@ class SliceResourceView (LoginRequiredView, ThemeView):
 
         network_md = metadata.details_by_object('network')
         network_fields = [column['name'] for column in network_md['column']]
-        print "sliceresourceview.py ====> ",network_fields
 
         query_network = Query.get('network').select(network_fields)
         page.enqueue_query(query_network)
@@ -150,6 +172,7 @@ class SliceResourceView (LoginRequiredView, ThemeView):
         template_env['list_resources'] = list_resources.render(self.request)
         template_env['filter_testbeds'] = filter_testbeds.render(self.request)
         template_env['map_resources'] = map_resources.render(self.request)
+        template_env['scheduler'] = resources_as_scheduler2.render(self.request)
         template_env['pending_resources'] = pending_resources.render(self.request)
         template_env["theme"] = self.theme
         template_env["username"] = request.user
index 6c757ed..41d540d 100644 (file)
@@ -12,8 +12,8 @@
 
 <h3>Users</h3>
 <ul>
-<li><h4>Who is a User?</h4></li>
-<p>A user is an experimenter who registers to the onelab portal and able to use all the facilites that the portal has to offer. However, a user does not
+<li><h4>Who is a user?</h4></li>
+<p>A user is an experimenter who registers to the OneLab portal and able to use all the facilites that the portal has to offer. However, a user does not
 have the right to do any admin operation such as managing slices, users and resources.</p>
 
 
@@ -38,14 +38,14 @@ have the right to do any admin operation such as managing slices, users and reso
 <p>Once you register, you can login to your account with limited access. It means that you can view your account details, modify your name and password. You can also view other pages. However, you will not be able to see any slices as well as resources before your account validation. But you can <a href="/portal/slice_request/">Request Slice</a> before being validated. Therefore, the PI will validate your account as well as your requested slice. Once validated, you will be able to see your slice and if you click on your slice, you will be able to see resources in that slice and you can reserve nodes and start your experiment.</p>
 
 <li><h4>How can I get access to a slice?</h4></li>
-<p>If you are a completely new user, you have to <a href="/portal/slice_request/">Request Slice</a>. It is upto the PI of your authority to accept/reject your slice request. </br>On the other hand, if you are a new user to the portal but you already have an account in Onelab SFA registry and you have access to slices, you will be able to see all your slices once your account is validated by the PI.</p> 
+<p>If you are a completely new user, you have to <a href="/portal/slice_request/">Request Slice</a>. It is upto the PI of your authority to accept/reject your slice request. </br>On the other hand, if you are a new user to the portal but you already have an account in OneLab SFA registry and you have access to slices, you will be able to see all your slices once your account is validated by the PI.</p> 
 
 <li><h4>I forgot my password, how to recover it?</h4></li>
 <p>If you have an account in the portal but you forgot the password, you can always <a href="/portal/pass_reset/">Reset your password</a>.</p></ul>
 
 <h3>Managers</h3>
 <ul>
-<li><h4>Who is a Manager?</h4></li>
+<li><h4>Who is a manager?</h4></li>
 <p>A manager is the Principal Investigator (PI) of the institution. Each PI has authority over his own institution. A PI can add, delete, validate users/ 
 slices that belong to his institution.</p>
 
@@ -53,7 +53,7 @@ slices that belong to his institution.</p>
 <p>In <a href="/portal/validate">Requests</a> page you will be able to see all the users that registered under your authority and the slices that users of your authority has requested. Therefore, pending users/slices are those users and slices that are yet to be validated. You can validate/reject these requests based on the policy of your institution.</p>
 
 <li><h4>How can I manage the users/slices that belong to my institution?</h4></li>
-<p>In <a href="/portal/institution">Instution</a> page, under Users tab, you will be able to see all the users that belong to your authority. You can delete the users that you don't want anymore. Under Slices tab, you will be able to see all the slices that belong to your authority. You can renew/delete the slices based on your requirements. As a PI you can also <a href="/portal/slice_request/">Create Slice</a>. Just fill the form of request slice and the slice will be automatically validated if it is requested by a PI. </p>
+<p>In <a href="/portal/institution">Instution</a> page, under "Users" tab, you will be able to see all the users that belong to your authority. You can delete the users that you don't want anymore. Under "Slices" tab, you will be able to see all the slices that belong to your authority. You can renew/delete the slices based on your requirements. As a PI you can also <a href="/portal/slice_request/">Create Slice</a>. Just fill the form of request slice and the slice will be automatically validated if it is requested by a PI. </p>
 
 </ul>
 </div>
diff --git a/portal/templates/fed4fire/old._widget-topmenu.html b/portal/templates/fed4fire/old._widget-topmenu.html
deleted file mode 100644 (file)
index 4b2ae0e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-{% insert_str prelude "js/bootstrap.js" %}
-{% insert_str prelude "css/bootstrap.css" %}
-{% insert_str prelude "css/topmenu.css" %}
-{% insert_str prelude "js/logout.js" %}
-<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
-  <div class="navbar-header">
-    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-myslice-collapse">
-      <span class="sr-only">Toggle navigation</span>
-      <span class="icon-bar"></span>
-      <span class="icon-bar"></span>
-      <span class="icon-bar"></span>
-    </button>
-    <a class="navbar-brand" href="/"><img src="{{ STATIC_URL }}img/f4f-logo.png" height="30" alt="Fed4Fire logo" /></a>
-     <a href="/" alt="Home" class="logoTxt">Fed4Fire Portal</a>
-  </div>
-  <div class="collapse navbar-collapse navbar-myslice-collapse topmenu">
-    <ul class="nav navbar-nav">
-       {% for d in topmenu_items %} 
-       {% if d.dropdown %}
-       {% if d.is_active %} <li class='active'> {% else %} <li class='other'> {% endif %}
-         <a class="dropdown-toggle" data-toggle="dropdown" href="{{ d.href }}">{{ d.label }}<b class="caret"></b></a>
-         <ul class="dropdown-menu">
-           {% for dd in d.contents %}
-           <li class='{% if dd.is_active %}active{% else %}other{% endif %}{% if dd.disabled %} disabled{%endif%}'
-           {% if dd.domid %} id='{{dd.domid}}'{% endif %}>
-           <a href="{{ dd.href }}"> {{ dd.label }} </a> </li>
-           {% endfor %}
-         </ul>
-        </li>
-        {% else %} 
-       <li class='{% if d.is_active %}active{% else %}other{% endif %}{% if d.disabled %} disabled{%endif%}'
-       {% if d.domid %} id='{{d.domid}}'{% endif %}>
-       <a href="{{ d.href }}"> {{ d.label }} </a> </li>
-    {% endif %}
-    {% endfor %}
-</div>
-
-
diff --git a/portal/templates/fed4fire/old.home-view.html b/portal/templates/fed4fire/old.home-view.html
deleted file mode 100644 (file)
index bc018a4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{# fine for either layout-unfold1.html (logged in) or layout-unfold2.html (needs a login prompt) #}
-{% extends layout_1_or_2 %}
-{% block unfold_margin %}
-{% include 'fed4fire/_widget-login.html' %}
-{% endblock unfold_margin %}
-
-{% block unfold_main %}
-<div class='well-lg f4f-title'>
-  <h2 style="font-weight: bold;">Welcome to Fed4Fire portal !</h2>
-  <h4>New to Fed4fire? Please <a href="/portal/register">register</a> or learn more about <a href="http://fed4fire.eu/" target="_blank">the project</a>.</h3>
-</div>
-<div class='well'>
-<p>
-A federation of experimentation facilities will significantly accelerate Future Internet research. Fed4FIRE will deliver open and easily accessible facilities to the FIRE experimentation communities, which focus on fixed and wireless infrastructures, services and applications, and combinations thereof. 
-</p>
-<p>This UI server is connected to the manifold backend running at <code>{{ MANIFOLD_URL }}</code>.</p>
-</div>
-{% endblock unfold_main %}
index 69f8bc1..3831a5e 100644 (file)
@@ -64,7 +64,7 @@
                 {{map_resources}}
                        </div>
                        <div id="scheduler-tab" class="panel" style="height:370px;display:none;">
-                {{scheduler_leases}}
+                {{scheduler}}
                        </div>
                        <div id="pending" class="panel" style="height:370px;display:none;">
                 {{pending_resources}}
index bdf3ee0..98b9d08 100644 (file)
@@ -40,10 +40,24 @@ class ObjectRequest(object):
             self.filters['disabled'] = '0'
             self.filters['gateway_type'] = 'sfa'
             self.filters['platform'] = '!myslice'
+        elif(self.type.startswith('local:')):
+            # XXX TODO: find a generic Query to get the fields like 
+            # select column.name from local:object where table == local:user
+            table = self.type.split(':')
+            table = table[1]
+            if table == "user":
+                self.id = table + '_id'
+                self.fields = ['user_id', 'email', 'password', 'config','status'];
+            elif table == "account":
+                # XXX TODO: Multiple key for account = (platform_id, user_id)
+                self.id = None
+                self.fields = ['platform_id', 'user_id', 'auth_type', 'config'];
+            elif table == "platform":
+                self.id = 'platform'
+                self.fields = ['platform', 'platform_longname', 'platform_url', 'platform_description','gateway_type'];
         else :
             self.setKey()
             self.setLocalFields()
-        
     
     def setKey(self):
         # What about key formed of multiple fields???
@@ -94,7 +108,7 @@ class ObjectRequest(object):
     
     def get(self):
         query = Query.get(self.type)
-        if (self.id not in self.fields) :
+        if (self.id is not None) and (self.id not in self.fields) :
             query.select(self.fields + [self.id])
         else :
             query.select(self.fields)
@@ -114,10 +128,14 @@ class ObjectRequest(object):
     def update(self):
         query = Query.update(self.type)
         query = self.applyFilters(query, True)
-        print ">>>>>",self.params
+
+        print "rest/__init__ self = ",self
+        print "rest/__init__ params = ",self.params
         
         if self.params :
-            query.set({ 'resource' : self.params})
+            print "query = ",query
+            query.set(self.params)
+#            query.set({ 'resource' : self.params})
 #             for param in self.params :
                 
         else:
index e95a6e7..afb62b7 100644 (file)
@@ -29,7 +29,8 @@ def dispatch(request, object_type, object_name):
         if el[0].startswith('filters'):
             o.filters[el[0][8:-1]] = el[1]
         elif el[0].startswith('params'):
-            o.params[el[0][7:-1]] = el[1]
+            #o.params[el[0][7:-1]] = el[1]
+            o.params.append({el[0][7:-1]:el[1]})
         elif el[0].startswith('fields'):
             o.fields=req_items.getlist('fields[]')
         elif el[0].startswith('options'):
index d2dd71e..f81c63e 100644 (file)
@@ -34,8 +34,10 @@ def dispatch(request, object_type, object_name):
             #print "#======>", el[0][7:8]
             #print "#======>", el[0][10:-1]
             print "#======> 1 ", el[1]
-            o.params = req_items.getlist('params[]')
-            
+            #o.params = req_items.getlist('params[]')
+            #o.params.append({el[0]:el[1]})
+            o.params.append({el[0][7:-1]:el[1]})
+            print "o.params = ",o.params
             
         elif el[0].startswith('fields'):
             o.fields=req_items.getlist('fields[]')
@@ -51,5 +53,5 @@ def dispatch(request, object_type, object_name):
             return error('an error has occurred')
  
     except Exception, e:
-        return error(str(e))
+        return error("exception:"+str(e))