+ }
+}
+
+if ($sliceconf_exists == false)
+ $column_configuration = $column_configuration.";".$slice_id.";default";
+
+if ($slice_column_configuration == "")
+ $full_configuration = $default_configuration;
+else
+ $full_configuration = $default_configuration."|".$slice_column_configuration;
+
+
+//instantiate the column configuration class, which prepares the headers array
+$ConfigureColumns =new PlekitColumns($full_configuration, $fix_columns, $tag_columns, $extra_columns);
+
+$visiblecolumns = $ConfigureColumns->node_tags();
+
+$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
+$all_nodes=$api->GetNodes(NULL,$node_columns);
+
+$ConfigureColumns->fetch_live_data($all_nodes);
+
+$show_reservable_info = TRUE;
+$show_layout_info = '1';
+$show_conf = explode(";",$show_configuration);
+foreach ($show_conf as $ss) {
+ if ($ss =="reservable")
+ $show_reservable_info = FALSE;
+ else if ($ss =="columns")
+ $show_layout_info = '0';
+}
+
+$slice_nodes=array();
+$potential_nodes=array();
+$reservable_nodes=array();
+foreach ($all_nodes as $node) {
+ if (in_array($node['node_id'],$slice['node_ids'])) {
+ $slice_nodes[]=$node;
+ if ($node['node_type']=='reservable') $reservable_nodes[]=$node;
+ } else {
+ $potential_nodes[]=$node;
+ }
+}
+if ($profiling) plc_debug_prof('05: nodes',count($slice_nodes));
+////////////////////
+// outline the number of reservable nodes
+$nodes_message=count_english($slice_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')));
+$toggle->start();
+
+
+//////////////////// reservable nodes area
+$leases_info="
+You have attached one or more reservable nodes to your slice.
+Reservable nodes show up with the '$mark' mark.
+Your slivers will be available only during timeslots
+where you have obtained leases.
+You can manage your leases in the tab below.
+<br>
+This feature is still experimental; feedback is appreciated at <a href='mailto:devel@planet-lab.org'>devel@planet-lab.org</a>
+";
+$count=count($reservable_nodes);
+if ($count && $privileges) {
+ // include leases.js only if needed
+ drupal_set_html_head('<script src="/planetlab/slices/leases.js" type="text/javascript" charset="utf-8"></script>');
+
+ // having reservable nodes in white lists looks a bit off scope for now...
+ $toggle_nodes=new PlekitToggle('my-slice-nodes-reserve',
+ "Leases - " . count($reservable_nodes) . " reservable node(s)",
+ array('visible'=>get_arg('show_nodes_resa'),
+ 'info-text'=>$leases_info,
+ 'info-visible'=>$show_reservable_info));
+ $toggle_nodes->start();
+
+ // get settings from environment, otherwise set to defaults
+ // when to start, in hours in the future from now
+ $leases_offset=$_GET['leases_offset'];
+ if ( ! $leases_offset ) $leases_offset=0;
+ // how many timeslots to show
+ $leases_slots=$_GET['leases_slots'];
+ if ( ! $leases_slots ) $leases_slots = 36;
+ // offset in hours (in the future) from now
+ $leases_w = $_GET['leases_w'];
+ if ( ! $leases_w) $leases_w=18;
+ // number of timeslots to display
+
+ $granularity=$api->GetLeaseGranularity();
+
+ // these elements are for passing data to the javascript layer
+ echo "<span class='hidden' id='leases_slicename'>" . $slice['name'] . "</span>";
+ echo "<span class='hidden' id='leases_slice_id'>" . $slice['slice_id']. "</span>";
+ echo "<span class='hidden' id='leases_granularity'>" . $granularity . "</span>";
+ // ditto, and editable - very rough for now
+ echo "<div class='center' id='leases_settings'>";
+ echo "<label id='leases_offset_label' class='leases_label'>start, in hours from now</label>";
+ echo "<input type='text' class='leases_input' id='leases_offset_input' value='$leases_offset' />";
+ echo "<label id='leases_slots_label' class='leases_label'># of timeslots</label>";
+ echo "<input type='text' class='leases_input' id='leases_slots_input' value='$leases_slots' />";
+ echo "<label id='leases_w_label' class='leases_label'>slot width, in pixels</label>";
+ echo "<input type='text' class='leases_input' id='leases_w_input' value='$leases_w' />";
+ echo "</div>";
+
+ // leases_data is the name used by leases.js to locate this place
+ // first population will be triggered by init_scheduler from leases.js
+ echo "<table id='leases_data' class='hidden'></table>";
+
+ // the general layout for the scheduler
+ echo <<< EOF
+<div id='leases_area'></div>
+
+<div id='leases_buttons'>
+ <button id='leases_refresh' type='submit'>Refresh (Pull)</button>
+ <button id='leases_submit' type='submit'>Submit (Push)</button>
+</div>
+EOF;
+
+ $toggle_nodes->end();
+ }
+
+if ($profiling) plc_debug_prof('06: leases',0);
+
+//////////////////// node configuration panel
+if ($first_time_configuration)
+$column_conf_visible = '1';
+else
+$column_conf_visible = '0';
+
+$layout_info='
+This tab allows you to customize the columns in the node tables,
+below. Information on the nodes comes from a variety of monitoring
+sources. If you, as either a user or a provider of monitoring data,
+would like to see additional columns made available, please send us
+your request in mail to <a
+href="mailto:support@myslice.info">support@myslice.info</a>. You can
+find more information about the MySlice project at <a
+href="http://trac.myslice.info">http://trac.myslice.info</a>.
+';
+$toggle_nodes=new PlekitToggle('my-slice-nodes-configuration',
+ "Node table layout",
+ array('info-text'=>$layout_info,
+ 'info-visible'=>$show_layout_info));
+$toggle_nodes->start();
+
+//usort ($table_headers, create_function('$col1,$col2','return strcmp($col1["header"],$col2["header"]);'));
+//print("<p>TABLE HEADERS<p>");
+//print_r($table_headers);
+
+print("<div id='debug'></div>");
+print("<input type='hidden' id='slice_id' value='".$slice['slice_id']."' />");
+print("<input type='hidden' id='person_id' value='".$plc->person['person_id']."' />");
+print("<input type='hidden' id='conf_tag_id' value='".$conf_tag_id."' />");
+print("<input type='hidden' id='show_tag_id' value='".$show_tag_id."' />");
+print("<input type='hidden' id='show_configuration' value='".$show_configuration."' />");
+print("<input type='hidden' id='column_configuration' value='".$slice_column_configuration."' />");
+print("<br><input type='hidden' size=80 id='full_column_configuration' value='".$column_configuration."' />");
+print("<input type='hidden' id='previousConf' value='".$slice_column_configuration."' />");
+print("<input type='hidden' id='defaultConf' value='".$default_configuration."' />");
+
+if ($profiling) plc_debug_prof('07: before configuration_panel',0);
+$ConfigureColumns->configuration_panel_html(true);
+
+if ($profiling) plc_debug_prof('08: before javascript_init',0);
+$ConfigureColumns->javascript_init();
+
+$toggle_nodes->end();
+
+if ($profiling) plc_debug_prof('09: layout',0);
+
+$all_sites=$api->GetSites(NULL, array('site_id','login_base'));
+$site_hash=array();
+foreach ($all_sites as $tmp_site) $site_hash[$tmp_site['site_id']]=$tmp_site['login_base'];
+
+$interface_columns=array('ip','node_id','interface_id');
+$interface_filter=array('is_primary'=>TRUE);
+$interfaces=$api->GetInterfaces($interface_filter,$interface_columns);
+
+$interface_hash=array();
+foreach ($interfaces as $interface) $interface_hash[$interface['node_id']]=$interface;
+
+
+if ($profiling) plc_debug_prof('10: interfaces',count($interfaces));
+
+//////////////////// nodes currently in
+$toggle_nodes=new PlekitToggle('my-slice-nodes-current',
+ count_english($slice_nodes,"node") . " currently in $name",
+ array('visible'=>get_arg('show_nodes_current')));
+$toggle_nodes->start();
+
+$headers=array();
+$notes=array();
+//$notes=array_merge($notes,$visibletags->notes());
+$notes [] = "For information about the different columns please see the <b>node table layout</b> tab above or <b>mouse over</b> the column headers";
+
+/*
+$headers['peer']='string';
+$headers['hostname']='string';
+$short="-S-"; $long=Node::status_footnote(); $type='string';
+ $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
+$short=reservable_mark(); $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());
+
+if ($privileges) $headers[plc_delete_icon()]="none";
+*/
+
+$edit_header = array();
+if ($privileges) $edit_header[plc_delete_icon()]="none";
+$headers = array_merge($ConfigureColumns->get_headers(),$edit_header);
+
+//print("<p>HEADERS<p>");
+//print_r($headers);
+
+$table_options = array('notes'=>$notes,
+ 'search_width'=>15,
+ 'pagesize'=>20,
+ 'configurable'=>true);
+
+$table=new PlekitTable('nodes',$headers,NULL,$table_options);
+
+$form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
+$form->start();
+$table->start();
+if ($slice_nodes) foreach ($slice_nodes as $node) {
+ $table->row_start();
+
+ $table->cell($node['node_id'], array('display'=>'none'));
+
+ $table->cell(l_node_obj($node));
+ $peers->cell($table,$node['peer_id']);
+ $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')?reservable_mark():"" );
+
+ $hostname=$node['hostname'];
+ $ip=$interface_hash[$node['node_id']]['ip'];
+ $interface_id=$interface_hash[$node['node_id']]['interface_id'];
+
+//extra columns
+$node['domain'] = topdomain($hostname);
+$node['sitename'] = l_site_t($node['site_id'],$site_hash[$node['site_id']]);
+if ($interface_id)
+ $node['ipaddress'] = l_interface_t($interface_id,$ip);
+ else
+ $node['ipaddress'] = "n/a";
+
+ //foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
+ $ConfigureColumns->cells($table, $node);
+
+ if ($privileges) $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
+ $table->row_end();
+}
+// actions area
+if ($privileges) {
+
+ // remove nodes