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
* 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
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
//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
},\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
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
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(
)
# --------------------------------------------------------------------------
- # RESOURCES
+ # RESOURCES MAP
# the resources part is made of a Tabs (Geographic, List),
map_resources = GoogleMap(
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)
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)
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
<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>
<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>
<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>
+++ /dev/null
-{% 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>
-
-
+++ /dev/null
-{# 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 %}
{{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}}
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???
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)
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:
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'):
#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[]')
return error('an error has occurred')
except Exception, e:
- return error(str(e))
+ return error("exception:"+str(e))