$known_actions []= 'delete-nodegroups';
// expects nodegroup_ids
+//////////////////////////////////////// leases
+$known_actions []= "manage-leases";
+// expects as 'actions' a list of 'action' of the form
+// either [ 'add-leases', [nodenames], slicename, t_from, t_until ]
+// or [ 'delete-leases', lease_id ]
+
////////////////////////////////////////////////////////////
$interface_details= array ('method','type', 'ip', 'gateway', 'network',
'broadcast', 'netmask', 'dns1', 'dns2',
break;
}
+//////////////////////////////////////// leases
+ case 'manage-leases': {
+ $actions=json_decode($_POST['actions']);
+ foreach ($actions as $action) {
+ $todo=$action[0];
+ switch ($todo) {
+ case 'add-leases': {
+ plc_debug('(add) action',$action);
+ break;
+ }
+ case 'delete-leases': {
+ plc_debug('(delete) action',$action);
+ break;
+ }
+ default: {
+ plc_debug('wrong entry',$action);
+ }
+ }
+ }
+
+ /*
+ plc_debug('POST',$_POST);
+ $slicename=$_POST['slicename'];
+ $nodenames=$_POST['nodenames'];
+ $t_from=intval($_POST['t_from']);
+ $t_until=intval($_POST['t_until']);
+ foreach ($nodenames as $nodename) plc_debug('nodename',$nodename);
+ $json=json_decode($_POST['nodenames_json']);
+ plc_debug('json_decode',$json);
+ $api->AddLeases();
+ */
+
+ break;
+ }
+
////////////////////////////////////////
case 'debug': {
/* need to put some place else in CSS ? */
// space for the nodenames
-var x_nodelabel = 200;
+var x_nodelabel = 120;
// right space after the nodename - removed from the above
var x_sep=20;
// height for the (two) rows of timelabels
var attr_timebutton = {'fill':'#bbf', 'stroke': '#338','stroke-width':2,
'stroke-linecap':'round', 'stroke-linejoin':'miter', 'stroke-miterlimit':3};
+// keep consistent with sizes above - need for something nicer
+var timebutton_path = "M1,0L23,0L12,13L1,0";
/* lease dimensions and colors */
/* refrain from using gradient color, seems to not be animated properly */
var attr_lease_other={'fill':"#f88"};
/* other slices name */
-var txt_slice = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#444",
- "font-size": 15 };
+var txt_otherslice = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#444",
+ "font-size": 12 };
////////////////////////////////////////////////////////////
// the scheduler object
-function Scheduler (slicename, axisx, axisy, data) {
+function Scheduler (sliceid, slicename, axisx, axisy, data) {
- // the data only contain slice names, we need this to find our own leases (mine)
+ // the data contains slice names, and lease_id, we need this to find our own leases (mine)
+ this.sliceid=sliceid;
this.slicename=slicename;
this.axisx=axisx;
this.axisy=axisy;
allnodes.click(allnodes_methods.click);
// timeslot buttons
for (var i=0, len=axisx.length; i < len; ++i) {
- var pathspec="M"+left+","+top;
- pathspec+="L"+(left+x_grain)+","+top;
- pathspec+="L"+(left+x_grain/2)+","+(top+y_node);
- pathspec+="L"+left+","+top;
- var timebutton=paper.path(pathspec).attr(attr_timebutton);
+ var timebutton=paper.path(timebutton_path).attr({'translation':left+','+top}).attr(attr_timebutton);
timebutton.from_time=axisx[i][0];
timebutton.scheduler=this;
timebutton.click(timebutton_methods.click);
left += x_nodelabel;
var grain=0;
while (grain < this.nb_grains()) {
- slicename=data[data_index][0];
- duration=data[data_index][1];
+ lease_id=data[data_index][0];
+ slicename=data[data_index][1];
+ duration=data[data_index][2];
var lease=paper.rect (left,top,x_grain*duration,y_node,radius);
+ lease.lease_id=lease_id;
lease.nodename=nodename;
lease.nodelabel=nodelabel;
if (slicename == "") {
}
this.submit = function () {
+ document.body.style.cursor = "wait";
+ var actions=new Array();
for (var i=0, len=this.leases.length; i<len; ++i) {
var lease=this.leases[i];
if (lease.current != lease.initial) {
until_time=this.leases[j].until_time;
++j; ++i;
}
- var method=(lease.current=='free') ? 'DeleteLeases' : 'AddLeases';
- window.console.log(method + "(" +
- "[" + lease.nodename + "]," +
- this.slicename + "," +
- from_time + "," +
- until_time + ')');
+ if (lease.current!='free') { // lease to add
+ actions.push(new Array('add-leases',
+ new Array(lease.nodename),
+ this.slicename,
+ from_time,
+ until_time));
+ } else { // lease to delete
+ actions.push(new Array ('delete-leases',
+ lease.lease_id));
+ }
}
}
+ sliceid=this.sliceid;
+ // once we're done with the side-effect performed in actions.php, we need to refresh this view
+ redirect = function (sliceid) {
+ window.location = '/db/slices/slice.php?id=' + sliceid + '&show_details=0&show_nodes=1&show_nodes_resa=1';
+ }
+ // Ajax.Request comes with prototype
+ var ajax=new Ajax.Request('/planetlab/common/actions.php',
+ {method:'post',
+ parameters:{'action':'manage-leases',
+ 'actions':actions.toJSON()},
+ onSuccess: function(transport) {
+ var response = transport.responseText || "no response text";
+ document.body.style.cursor = "default";
+ alert("Success (sliceid=" + sliceid + ")\n\n" + response);
+ redirect(sliceid);
+ },
+ onFailure: function(){
+ document.body.style.cursor = "default";
+ alert('Something went wrong...')
+ redirect(sliceid);
+ },
+ });
}
this.clear = function () {
/* a text obj to display the name of the slice that owns that lease */
var otherslicelabel = paper.text (lease.attr("x")+lease.attr("width")/2,
// xxx
- lease.attr("y")+lease.attr("height")/2,slicename).attr(txt_slice);
+ lease.attr("y")+lease.attr("height")/2,slicename).attr(txt_otherslice);
/* hide it right away */
otherslicelabel.hide();
/* record it */
axisx.push(getInnerText(cell).split("&"));
});
// leases - expect colspan to describe length in grains
+ // the text contents is expected to be lease_id & slicename
table.getElementsBySelector("tbody>tr>td").each(function (cell) {
- data.push(new Array (getInnerText(cell),cell.colSpan));
+ var cell_data;
+ slice_attributes=getInnerText(cell).split('&');
+ // booked leases come with lease id and slice name
+ if (slice_attributes.length == 2) {
+ // leases is booked : slice_id, slice_name, duration in grains
+ cell_data=new Array (slice_attributes[0], slice_attributes[1], cell.colSpan);
+ } else {
+ cell_data = new Array ('','',cell.colSpan);
+ }
+ data.push(cell_data);
});
- // slicename : the upper-left cell
- var scheduler = new Scheduler (getInnerText(table.getElementsBySelector("thead>tr>td")[0]), axisx, axisy, data);
+ // sliceid & slicename : the upper-left cell
+ var slice_attributes = getInnerText(table.getElementsBySelector("thead>tr>td")[0]).split('&');
+ var sliceid=slice_attributes[0];
+ var slicename=slice_attributes[1];
+ var scheduler = new Scheduler (sliceid,slicename, axisx, axisy, data);
table.hide();
// leases_area is a <div> created by slice.php as a placeholder
scheduler.init ("leases_area");
// (.) type is passed to the javascript table, for sorting (default is 'string')
// minimal list as a start
-$node_fixed_columns = array('hostname','node_id','peer_id','slice_ids_whitelist','run_level','boot_state','last_contact','node_type');
+$node_fixed_columns = array('hostname','node_id','peer_id','slice_ids_whitelist',
+ 'run_level','boot_state','last_contact','node_type');
// create a VisibleTags object : basically the list of tag columns to show
$visibletags = new VisibleTags ($api, 'node');
$visiblecolumns = $visibletags->column_names();
$reservable_nodes=array();
foreach ($nodes as $node) { if ($node['node_type']=='reservable') $reservable_nodes[]=$node; }
+$reservable_mark="-R-";
+$reservable_legend="reservable nodes are marked with " . $reservable_mark;
+
////////////////////
-$count=count($nodes);
-$toggle=new PlekitToggle ('my-slice-nodes',"$count Nodes",
+// outline the number of reservable nodes
+$nodes_message=count_english($nodes,"node");
+if (count($reservable_nodes)) $nodes_message .= " (" . count($reservable_nodes) . " reservable)";
+$toggle=new PlekitToggle ('my-slice-nodes',$nodes_message,
array('bubble'=>
'Manage nodes attached to this slice',
'visible'=>get_arg('show_nodes',false)));
$headers['hostname']='string';
$short="ST"; $long=Node::status_footnote(); $type='string';
$headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
-$short="R"; $long="reservable nodes"; $type='string';
+$short="R"; $long=$reservable_legend; $type='string';
$headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
// the extra tags, configured for the UI
$headers=array_merge($headers,$visibletags->headers());
$run_level=$node['run_level'];
list($label,$class) = Node::status_label_class_($node);
$table->cell ($label,array('class'=>$class));
- $table->cell( ($node['node_type']=='reservable')?"-R-":"" );
+ $table->cell( ($node['node_type']=='reservable')?$reservable_mark:"" );
foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
if ($privileges) $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
$headers['hostname']='string';
$short="ST"; $long=Node::status_footnote(); $type='string';
$headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
- $short="R"; $long="reservable nodes"; $type='string';
+ $short="R"; $long=$reservable_legend; $type='string';
$headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
// the extra tags, configured for the UI
$headers=array_merge($headers,$visibletags->headers());
$table->cell(l_node_obj($node));
list($label,$class) = Node::status_label_class_($node);
$table->cell ($label,array('class'=>$class));
- $table->cell( ($node['node_type']=='reservable')?"-R-":"" );
+ $table->cell( ($node['node_type']=='reservable')?$reservable_mark:"" );
foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
$table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
$table->row_end();
$steps=$duration/$grain;
$start=intval($now/$grain)*$grain;
$end=$now+$duration;
- $lease_columns=array('name','t_from','t_until','hostname','name');
+ $lease_columns=array('lease_id','name','t_from','t_until','hostname','name');
$leases=$api->GetLeases(array(']t_until'=>$now,'[t_from'=>$end,'-SORT'=>'t_from'),$lease_columns);
// hash nodes -> leases
$host_hash=array();
# leases_data is the name used by leases.js to locate this table
echo "<table id='leases_data'>";
# pass the slicename as the [0,0] coordinate as thead>tr>td
- echo "<thead><tr><td>" . $slice['name'] . "</td>";
+ echo "<thead><tr><td>" . $slice['slice_id'] . '&' . $slice['name'] . "</td>";
for ($i=0; $i<$steps; $i++)
// expose in each header cell the full timestamp, and how to display it - use & as a separator*/
echo "<th>" . ($start+$i*$grain) . "&" . strftime("%H:%M",$start+$i*$grain). "</th>";
array_shift($leases);
}*/
$duration=$lease['nuntil']-$counter;
- echo "<td colspan='$duration'>" . $lease['name'] . "</td>";
+ echo "<td colspan='$duration'>" . $lease['lease_id'] . '&' . $lease['name'] . "</td>";
$counter=$lease['nuntil'];
} else {
echo "<td></td>";