Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorLoic Baron <loic.baron@lip6.fr>
Mon, 18 Apr 2016 09:16:40 +0000 (11:16 +0200)
committerLoic Baron <loic.baron@lip6.fr>
Mon, 18 Apr 2016 09:16:40 +0000 (11:16 +0200)
13 files changed:
activity/__init__.py
manifoldapi/manifoldproxy.py
manifoldapi/static/js/manifold.js
plugins/filter_status/static/js/filter_status.js
plugins/querytable/static/js/querytable.js
portal/actions.py
portal/static/img/bg-smartfire.png
portal/templates/onelab/onelab_home-view.html [new file with mode: 0644]
portal/templates/onelab/onelab_manual-delegation.html [new file with mode: 0644]
portal/templates/slice-resource-view.html
portal/templates/slice-tab-experiment.html
portal/templates/user_request_email.html
rest/sfa_api.py

index be5779d..4a7d5c3 100644 (file)
@@ -67,12 +67,12 @@ def logWrite(request, action, message, objects = None):
         "facility"      : None,
         "testbed"       : None,
     }
-    
+   
     if objects is not None:
         for o in objects :
             if (o in log) :
                 log[o] = objects[o]
-    
+
     try :
         result = urllib2.urlopen(server, urllib.urlencode(log))
         logger.info("===============>> activity: {} <{}> {}".format(action, request.user,message))
index 636e2db..458c084 100644 (file)
@@ -8,8 +8,8 @@ from django.http                import HttpResponse, HttpResponseForbidden
 #from manifoldapi.manifoldquery import ManifoldQuery
 from manifold.core.query        import Query
 from manifold.core.result_value import ResultValue
-from manifoldapi.manifoldapi    import ManifoldAPI
-from manifoldapi.manifoldresult import ManifoldException
+from manifoldapi    import ManifoldAPI
+from manifoldresult import ManifoldException
 
 # from unfold.sessioncache import SessionCache
 
index b8bd502..305231e 100644 (file)
@@ -1715,7 +1715,7 @@ case TYPE_LIST_OF_VALUES:
                 // 
                 // +) If a reservable node is added to the slice, then it should have a corresponding lease
                 // XXX Not always a resource
-                var is_reservable = (record.exclusive == true);
+                var is_reservable = (record.exclusive == 'true' || record.exclusive == true);
                 if (is_reservable) {
                     // var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
 
index 7a30100..676d3ee 100644 (file)
             filter_status = this.dataset['status'];
             self.select_tab(filter_status);
 
+            // manifoldapi/static/js/manifold.js
+            // See this.apply_filters
+
             // ... and communicate the appropriate filters to the manager
             // NOTE: we use the manifold namespace for internal filters 
             if (self.prev_filter_status) {
index 76934e7..c22dbd2 100644 (file)
@@ -90,7 +90,7 @@ QUERYTABLE_BGCOLOR_REMOVED = 2;
                 sPaginationType: 'bootstrap',
                 // Handle the null values & the error : Datatables warning Requested unknown parameter
                 // http://datatables.net/forums/discussion/5331/datatables-warning-...-requested-unknown-parameter/p2
-                aoColumnDefs: [{sDefaultContent: '', aTargets: [ '_all' ]}],
+                aoColumnDefs: [{sDefaultContent: '', aTargets: [ '_all' ], "sType": "mysort"}],
                 // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty
                 // sScrollX: '100%',       /* Horizontal scrolling */
                 bProcessing: true,      /* Loading */
@@ -669,6 +669,66 @@ QUERYTABLE_BGCOLOR_REMOVED = 2;
             return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0';
         });
     };
+
+    // use sType: "mysort"  for any columns you wish to use these routines
+    // http://datatables.net/forums/discussion/7546/alpha-numeric-sort
+    jQuery.fn.dataTableExt.oSort['mysort-asc']  = function(a,b) {
+      var r = new RegExp("<([a-zA-Z]+).*?>(.*?)</\\1>");
+      if (r.exec(a) != null){
+        a = r.exec(a)[2];
+      }
+      if (r.exec(b) != null){
+        b = r.exec(b)[2];
+      }
+      a = a.replace(/[^A-Za-z0-9]/, "");
+      b = b.replace(/[^A-Za-z0-9]/, "");
+      var re = new RegExp("^([a-zA-Z]*)(.*)");
+      var x = re.exec(a);
+      var y = re.exec(b);
+     
+      // you might want to force the first portion to lowercase
+      // for case insensitive matching
+      // x[1] = x[1].toLowerCase();
+      // y[1] = y[1].toLowerCase();
+     
+      if (x[1] > y[1]) return 1;
+      if (x[1] < y[1]) return -1;
+     
+      // if you want to force the 2nd part to only be numeric:
+      x[2] = parseInt(x[2]);
+      y[2] = parseInt(y[2]);
+     
+      return ((x[2] < y[2]) ? -1 : ((x[2] > y[2]) ?  1 : 0));
+    };
+      
+    jQuery.fn.dataTableExt.oSort['mysort-desc'] = function(a,b) {
+      var r = new RegExp("<([a-zA-Z]+).*?>(.*?)</\\1>");
+      if (r.exec(a) != null){
+        a = r.exec(a)[2];
+      }
+      if (r.exec(b) != null){
+        b = r.exec(b)[2];
+      }
+      a = a.replace(/[^A-Za-z0-9]/, "");
+      b = b.replace(/[^A-Za-z0-9]/, "");
+      var re = new RegExp("^([a-zA-Z]*)(.*)");
+      var x = re.exec(a);
+      var y = re.exec(b);
+     
+      // you might want to force the first portion to lowercase
+      // for case insensitive matching
+      // x[1] = x[1].toLowerCase();
+      // y[1] = y[1].toLowerCase();
+     
+      if (x[1] > y[1]) return -1;
+      if (x[1] < y[1]) return 1;
+     
+      // if you want to force the 2nd part to only be numeric:
+      x[2] = parseInt(x[2]);
+      y[2] = parseInt(y[2]);
+     
+       return ((x[2] < y[2]) ?  1 : ((x[2] > y[2]) ? -1 : 0));
+    };
     
     
 
index e0dc131..f0bea38 100644 (file)
@@ -4,6 +4,7 @@ from manifoldapi.manifoldapi        import execute_query,execute_admin_query
 from portal.models                  import PendingUser, PendingSlice, PendingAuthority, PendingProject, PendingJoin
 from unfold.page                    import Page
 
+import hashlib
 import json
 
 from django.contrib.auth.models     import User
@@ -1285,7 +1286,8 @@ def create_pending_user(wsgi_request, request, user_detail):
     msg.send()
    
     # saves the user to django auth_user table [needed for password reset]
-    user = User.objects.create_user(request['email'].split('@')[-1], request['email'], request['password'])
+    # Django username must be less than 30 char so we use a hash
+    user = User.objects.create_user(hashlib.sha1(request['email']).hexdigest(), request['email'], request['password'])
 
     # Creating a manifold user
     user_id = manifold_add_user(wsgi_request, request)
index f5340fc..7089931 100644 (file)
Binary files a/portal/static/img/bg-smartfire.png and b/portal/static/img/bg-smartfire.png differ
diff --git a/portal/templates/onelab/onelab_home-view.html b/portal/templates/onelab/onelab_home-view.html
new file mode 100644 (file)
index 0000000..c98ee91
--- /dev/null
@@ -0,0 +1,151 @@
+{% extends "layout_base.html" %}
+{% load portal_filters %}
+
+{% block content %}
+<!-- <div class="row">
+{% widget '_widget-news.html' %}
+</div> -->
+{% if username %}
+
+{% block head %} 
+<script type="text/javascript" src="https://java.com/js/dtjava.js"></script>
+{% endblock head %}
+
+{% widget "_widget-no_credentials.html" %}
+<div class="container dashboard">
+       <div class="row">
+           <div class="col-md-12" id="credentials_msg" style="display:none;">
+       {%if 'no_creds'  in user_cred %}
+       <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
+       {%endif%}
+       {%if 'creds_expired'  in user_cred %}
+       <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
+    {%endif%}
+        </div>
+    </div>
+    <div class="row">
+        <div class="col-sm-4">
+            <h3>
+                <a href="/portal/slice_request/"><img src="{{ STATIC_URL }}img/icon_slices_small.png" alt="" />EXPERIMENT</a>
+            </h3>
+            <div>
+                <span class="glyphicon glyphicon-cog"></span> <a href="/portal/project_request/">Create/Join project</a>
+            </div>
+            <div class="dashboard-create-slice">
+                <span class="glyphicon glyphicon-plus"></span> <a href="/portal/slice_request/">Create slice</a>
+            </div>
+            <div class="projects-tree">
+                Your projects and slices
+                <span title="A <b>slice</b> is a set of testbed resources on which you can conduct an experiment. 
+                Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
+                However, on the Fed4FIRE portal, you will only see slices that you have created through Fed4FIRE. If you have created slices elsewhere, 
+                those slices will not appear here. <br /><br /> A <b>project</b> is a sub-authority under the responsability of your institution gathering users, 
+                who will be able to create slices for their experiments." class="glyphicon glyphicon-info-sign">&nbsp;</span> 
+             
+                <div id="home-project-tree"><img class="projects-loading" src="{{ STATIC_URL }}img/loading.gif" alt="Loading projects" /></div>
+            </div>
+            {% include theme|add:"_jfed_button.html" %}
+        </div>
+        <div class="col-sm-4">
+            <div class="row">
+                <div class="col-sm-12">
+                    <h3>
+                        <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_small.png" alt="" /></a><a href="/portal/account/">ACCOUNT</a>
+                    </h3>
+                    {% if person.last_name %}
+                    <p>
+                        {{person.first_name}} {{person.last_name}}
+                    </p>
+                    {% endif %}
+                    <p>
+                        <span class="glyphicon glyphicon-user"></span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+                    </p>
+                </div>
+            </div>
+            <div class="row">
+                <div class="col-sm-12">
+                    <h3>
+                        <a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color_small.png" alt="" /></a><a href="/portal/institution">MANAGEMENT</a>
+                    </h3>
+                   
+                    <div>
+                        <span class="glyphicon glyphicon-ok"></span> <a href="/portal/institution#requests">Validate Requests</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="col-sm-4">
+            <div class="row">
+                <div class="col-sm-12">
+                    <h3>
+                        <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support_small.png" alt="" /></a><a href="/portal/support">SUPPORT</a>
+                    </h3>
+                    <p>
+                        <span class="glyphicon glyphicon-envelope"></span> <a href="/portal/contact/">Contact</a>
+                    </p>
+                    <p>
+                        <span class="glyphicon glyphicon-book"></span> <a href="http://doc.onelab.eu" target="_blank">Documentation & Tutorials</a>
+                    </p>
+                    {% include theme|add:"_dashboard_links.html" %}
+                </div>
+            </div>            
+        </div>
+    </div>
+</div>
+{% else %}
+<div class="container-fluid home">
+       <div class="">
+        <div class="col-sm-2"></div>
+        {% widget '_slogan.html' %}
+        <div class="col-sm-5 col-sm-offset-1">
+            <div class="row">
+                {% widget '_widget-login-user.html' %}
+            </div>
+        </div>
+        <div class="col-sm-1"></div>
+               </div>
+        </div>
+
+<script type="text/javascript">
+       $(document).ready(function() {
+        localStorage.clear();
+    });
+</script>
+
+{% endif %}
+
+
+<script type="text/javascript">
+   var config = {
+       java8_jnlp: 'http://jfed.iminds.be/jfed-f4f-java8.jnlp',
+       java7_jnlp: 'http://jfed.iminds.be/jfed-f4f-java7.jnlp'
+   };
+
+   var certkey = "{{jfed_identity}}";
+
+       $(document).ready(function() {
+           {%if 'no_creds' in user_cred or 'creds_expired' in user_cred %}
+        localStorage.clear();
+        /*
+        $.post("/cache/clear/", function( data ) {
+        });
+        */
+        {% endif %}
+               $('a.home-tab').click(function() {
+                       $('ul.nav-tabs li').removeClass('active');
+                       $(this).parent().addClass('active');
+                       $('div.home-panel').hide();
+                       $('div#'+$(this).data('panel')).show();
+               });
+               
+    });
+</script>
+<script src='https://authority.ilabt.iminds.be/js/jquery/jquery-ui.min.js'></script>
+<script src="//java.com/js/dtjava.js"></script>
+<script src='https://authority.ilabt.iminds.be/js/jfed_webstart_f4fportal.js'></script>
+<link rel='stylesheet' href='https://authority.ilabt.iminds.be/js/jquery/jquery-ui.css' />
+
+{% if theme == 'onelab' %}
+{% widget "_widget-monitor.html" %}
+{% endif %}
+{% endblock %}
diff --git a/portal/templates/onelab/onelab_manual-delegation.html b/portal/templates/onelab/onelab_manual-delegation.html
new file mode 100644 (file)
index 0000000..f0d479c
--- /dev/null
@@ -0,0 +1,102 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+<div class="col-md-8">
+       <br>
+       <h2>Manual Delegation</h2>
+       <h3>Install SFA</h3>
+       
+       <p>
+               In order to delegate your credentials to the OneLab portal, you need to install SFA tools.<br>
+       </p>
+       <p>
+               <strong>[Requirement: python 2.7 or higher]</strong>
+       </p>
+       <h4>For Mac and Linux</h4>
+       <p class="command">
+               $ sudo easy_install pip<br>
+               $ sudo pip install sfa
+       </p>
+       <h4>For Windows</h4>
+       <p>Please download <a target="_blank" href="https://bootstrap.pypa.io/get-pip.py">get-pip.py</a></p>
+       <p class="command">
+               $ python get-pip.py<br>
+               $ pip install sfa
+       </p>
+
+       <p>
+       To get more information about pip, please visit: <a target="_blank" href="https://pip.pypa.io/en/latest/installing.html">https://pip.pypa.io/en/latest/installing.html</a>
+       </p>
+       <p>
+       More details about SFA is available at the following address:
+       <a target="_blank" href="http://svn.planet-lab.org/wiki/SFATutorialInstall#installingthroughpipfromPyPI">Installing SFA</a>
+       </p>
+       
+       <h3>Configuring SFA</h3>
+       
+       <p>
+               Once SFA tools are successfully installed, you need to configure the SFA client aka SFI
+       </p>
+       <p class="command">
+               $ mkdir ~/.sfi <br>
+               $ cd ~/.sfi <br>
+               $ cp ~/.ssh/id_rsa ~/.sfi/user-hrn.pkey
+       </p>
+       
+       <p>
+               Here, 'user-hrn' is your SFA hrn. If e.g., your OneLab account email is mohammed-yasin.rahman at upmc.fr, then your user-hrn is <b><i>'onelab.upmc.mohammed-yasin_rahman'.</i></b></p>
+       <p>
+               In this example, a user-hrn is built using the root authority i.e, <b><i>'onelab'</i></b> followed by a <b>'.'</b> then the sub authority i.e., <b><i>'upmc'</i></b>
+               followed by a <b>'.'</b> and then the last fragment in the hrn is made of the local part of your email adress i.e., <b><i>'mohammed-yasin_rahman'</i></b> 
+               (with dots replaced with underscores).
+       </p>
+
+       <p>
+               Next, you will setup your ~/.sfi/sfi_config. The following represents the sfi_config file for a OneLab user:
+       </p>
+       
+       <p class="command">
+               [sfi]<br>
+               auth = onelab.upmc<br>
+               user = onelab.upmc.mohammed-yasin_rahman<br>
+               registry = http://portal.onelab.eu:6080/<br>
+               sm = http://sfa3.planet-lab.eu:12346/<br>
+       </p>
+
+       <p>
+               Here again, <b><i>'user'</i></b> is your user-hrn, and <b><i>'auth'</i></b> is the authority that you belong to, in most cases you should just drop the last part of your hrn.
+       </p>
+       <p>
+               Add the the following to sfi_config for delegating credentials to OneLab portal:
+       </p>    
+       <p class="command">
+               [myslice]<br>
+               <br>
+               backend  = http://portal.onelab.eu:7080<br>
+               delegate = onelab.myslice<br>
+               platform = myslice<br>
+               username = mohammed-yasin.rahman@lip6.fr
+       </p>
+       <p>
+               Test the SFA layer:
+       </p>
+       <p class="command">
+               $ sfi.py version
+       </p>
+       <p>
+               And finally delegate your credentials to the portal
+       </p>
+       <p class="command">
+               $ sfi.py myslice
+       </p>
+       <p>
+       The complete tutorial is available at the following address:
+       <a target="_blank" href="http://trac.myslice.info/wiki/InstallSfa">http://trac.myslice.info/wiki/InstallSfa</a>
+       </p>
+       
+       <br />
+       
+</div>
+{% endblock %}
+
index cbd8d1b..0a5d65e 100644 (file)
@@ -33,7 +33,7 @@ $(document).ready(function() {
                </div>
        
                <div class="row">
-                       <div class="col-md-8">
+                       <div class="col-md-9">
                                {{ filter_status }}
                        </div>
                        <div class="col-md-1">
@@ -55,7 +55,7 @@ $(document).ready(function() {
                          <li class="active"><a href="#resourcelist" role="tab" data-toggle="tab">Table</a></li>
                          <li> <a href="#resourcemap" role="tab" data-toggle="tab">Map</a></li>
                          <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li>
-                         <!--<li> <a href="#resourcesasap" role="tab" data-toggle="tab">ASAP</a></li> -->
+                         <!-- <li> <a href="#resourcesasap" role="tab" data-toggle="tab">ASAP</a></li> -->
                        </ul>
                        </div>
                </div>
@@ -94,9 +94,9 @@ $(document).ready(function() {
                                <div class="tab-pane" id="resourcescheduler">
                        {{scheduler}}
                                </div>
-                                       <!-- <div class="tab-pane" id="resourcesasap">
+                                       <div class="tab-pane" id="resourcesasap">
                        {{asap}}
-                               </div> -->
+                               </div>
 
                                <!--
                                <div id="reserved" class="tab-pane" style="height:370px;display:none;">
index 1af5661..be351fb 100644 (file)
@@ -14,6 +14,7 @@ $(document).ready(function() {
     {% for platform in platforms %}
     // /sfa/Describe?hrn=onelab.upmc.projectx.slicex&platform[]={{platform}}&type=slice
     $.post("/sfa/Describe",{'hrn':'{{slicename}}', 'type':'slice', 'platform':['{{platform}}']}, function( data ) {
+        console.log(data);
         if('parsed' in data['{{platform}}'] && 'rspec' in data['{{platform}}']['parsed']){
             rspec = data['{{platform}}']['parsed']['rspec'];
             if('node' in rspec){
index 0702a92..204c293 100644 (file)
@@ -1,4 +1,4 @@
-<img src="{{current_site}}/static/img/{{theme.logo}}" width="80px">    
+<img src="{{current_site}}/static/img/{{theme.logo}}"> 
 <br>
 <h1>NEW USER REQUEST</h1>
 <br>
index cacf7fe..0a84093 100644 (file)
@@ -280,6 +280,7 @@ def sfa_client(request, method, hrn=None, urn=None, object_type=None, rspec=None
                             # ListResources(slice_hrn)
                             api_options['geni_slice_urn'] = urn
                             result = server.ListResources([object_cred], api_options)
+                            logger.debug(result)
                             dict_result = xmltodict.parse(result['value'])
                         # else GetVersion = v3
                         else: