fix, really sort on hostnames and not on the 'AU'
[plewww.git] / planetlab / nodes / nodes.php
index 8e13d37..b2c51a7 100644 (file)
@@ -1,13 +1,11 @@
 <?php
 
-// $Id$
-
 // Require login
 require_once 'plc_login.php';
 
 // Get session and API handles
 require_once 'plc_session.php';
-global $plc, $api, $adm;
+global $plc, $api;
 
 // Print header
 require_once 'plc_drupal.php';
@@ -15,12 +13,23 @@ include 'plc_header.php';
 
 // Common functions
 require_once 'plc_functions.php';
-require_once 'plc_minitabs.php';
-require_once 'plc_tables.php';
+require_once 'plc_objects.php';
+require_once 'plc_peers.php';
+require_once 'plc_visibletags2.php';
+require_once 'linetabs.php';
+require_once 'table2.php';
+require_once 'nifty.php';
+require_once 'toggle.php';
+require_once 'columns.php';
+
+// keep css separate for now
+drupal_set_html_head('
+<link href="/planetlab/css/my_slice.css" rel="stylesheet" type="text/css" />
+');
 
-// find person roles
-$_person= $plc->person;
-$_roles= $_person['role_ids'];
+
+ini_set("memory_limit","64M");
+//error_reporting(0);
 
 // -------------------- 
 // recognized URL arguments
@@ -28,14 +37,20 @@ $peerscope=$_GET['peerscope'];
 $pattern=$_GET['pattern'];
 $site_id=intval($_GET['site_id']);
 $slice_id=intval($_GET['slice_id']);
+$person_id=intval($_GET['person_id']);
 
 // --- decoration
 $title="Nodes";
-$tabs=array("Old page"=>l_nodes(),
-           "Logout"=>"/planetlab/logout.php");
+$tabs=array();
+$tabs []= tab_nodes();
+if (count (plc_my_site_ids()) == 1) {
+    $tabs []= tab_nodes_mysite();
+} else {
+    $tabs []= tab_nodes_all_mysite();
+}
+$tabs []= tab_nodes_local();
 
 // -------------------- 
-$peer_filter=array();
 $node_filter=array();
 
 //////////////////
@@ -43,20 +58,162 @@ $node_filter=array();
 function node_status ($node) {
 
   $messages=array();
-  
-  // do all this stuff on local nodes only
-  if ( ! $node['peer_id'] ) {
-    // check that the node has keys
-    if (count($node['interface_ids']) == 0) {
-      $messages [] = "No interface";
-    }
+  if ($node['node_type'] != 'regular' && $node['node_type'] != 'reservable' ) 
+    $messages []= $node['node_type'];
+
+  // checks on local nodes only
+  if ( ( ! $node['peer_id']) ) {
+    // has it got interfaces 
+    if (count($node['interface_ids']) == 0) 
+      $messages []= "No interface";
   }
-  return plc_make_table('plc-warning',$messages);
+  return plc_vertical_table($messages,'plc-warning');
+}
+
+
+if (plc_is_admin()) 
+       $default_configuration = "ID:f|hostname:f|ST:f|AU:f|RES:f";
+else
+       $default_configuration = "hostname:f|ST:f|AU:f|RES:f";
+
+//$extra_default = "LCN|DN|R|L|OS|MS|SN";
+$column_configuration = "";
+$slice_column_configuration = "";
+$show_configuration = "";
+
+
+$PersonTags=$api->GetPersonTags (array('person_id'=>$plc->person['person_id']));
+//print_r($PersonTags);
+foreach ($PersonTags as $ptag) {
+        if ($ptag['tagname'] == 'columnconf')
+        {
+                $column_configuration = $ptag['value'];
+                $conf_tag_id = $ptag['person_tag_id'];
+        }
+       if ($ptag['tagname'] == 'showconf')
+        {
+                $show_configuration = $ptag['value'];
+                $show_tag_id = $ptag['person_tag_id'];
+        }
+}
+
+//print("column configuration = ".$column_configuration);
+
+$nodesconf_exists = false;
+if ($column_configuration == "")
+{
+        $column_configuration = "nodes;default";
+        $nodesconf_exists = true;
+}
+else {
+        $slice_conf = explode(";",$column_configuration);
+        for ($i=0; $i<count($slice_conf); $i++ ) {
+                if ($slice_conf[$i] == "nodes")
+                {
+                        $i++;
+                        $slice_column_configuration = $slice_conf[$i];
+                        $nodesconf_exists = true;
+                        break;
+                }
+                else
+                {
+                        $i++;
+                        $slice_column_configuration = $slice_conf[$i];
+                }
+        }
 }
 
+if ($nodesconf_exists == false)
+        $column_configuration = $column_configuration.";nodes;default";
+//panos: need to define an "empty" configuration here (for the moment A column
+//will be added by default the first time
+
+
+if ($slice_column_configuration == "" || $slice_column_configuration == "default")
+        $full_configuration = $default_configuration;
+       
+else
+        $full_configuration = $default_configuration."|".$slice_column_configuration;
+
+//print("full configuration = ".$full_configuration);
+
+// fetch nodes 
+$node_fixed_columns=array('node_type','site_id','boot_state','last_contact','interface_ids','peer_id', 'slice_ids');
+
+$fix_columns = array();
+if (plc_is_admin()) 
+$fix_columns[]=array('tagname'=>'node_id', 'header'=>'ID', 'type'=>'string', 'title'=>'The ID the node');
+$fix_columns[]=array('tagname'=>'hostname', 'header'=>'hostname', 'type'=>'string', 'title'=>'The name of the node');
+$fix_columns[]=array('tagname'=>'peer_id', 'header'=>'AU', 'type'=>'string', 'title'=>'Authority');
+$fix_columns[]=array('tagname'=>'run_level', 'header'=>'ST', 'type'=>'string', 'title'=>'Status');
+$fix_columns[]=array('tagname'=>'node_type', 'header'=>'RES', 'type'=>'string', 'title'=>'Reservable');
+
+
+$visibletags = new VisibleTags ($api, 'node');
+$visibletags->columns();
+$tag_columns = $visibletags->headers();
+
+//columns that are not defined as extra myslice tags
+$extra_columns = array();
+//MyPLC columns
+$extra_columns[]=array('tagname'=>'sitename', 'header'=>'SN', 'type'=>'string', 'title'=>'Site name', 'fetched'=>true, 'source'=>'myplc');
+$extra_columns[]=array('tagname'=>'domain', 'header'=>'DN', 'type'=>'string', 'title'=>'Toplevel domain name', 'fetched'=>true, 'source'=>'myplc');
+$extra_columns[]=array('tagname'=>'ipaddress', 'header'=>'IP', 'type'=>'string', 'title'=>'IP Address', 'fetched'=>true, 'source'=>'myplc');
+$extra_columns[]=array('tagname'=>'fcdistro', 'header'=>'OS', 'type'=>'string', 'title'=>'Operating system', 'fetched'=>false, 'source'=>'myplc');
+$extra_columns[]=array('tagname'=>'date_created', 'header'=>'DA', 'source'=>'myplc', 'type'=>'date', 'title'=>'Date added', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'arch', 'header'=>'A', 'source'=>'myplc', 'type'=>'string', 'title'=>'Architecture', 'fetched'=>false);
+if (plc_is_admin()) { 
+$extra_columns[]=array('tagname'=>'deployment', 'header'=>'DL', 'source'=>'myplc', 'type'=>'string', 'title'=>'Deployment', 'fetched'=>false);
+}
+
+//CoMon Live data
+//NOTE: Uncomment these lines if CoMon provides information for your nodes
+
+if (MYSLICE_COMON_AVAILABLE)
+{
+$extra_columns[]=array('tagname'=>'bwlimit', 'header'=>'BW', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Bandwidth limit', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'numcores', 'header'=>'CC', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Number of CPU Cores', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'cpuspeed', 'header'=>'CR', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'CPU clock rate', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'disksize', 'header'=>'DS', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Disk size', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'gbfree', 'header'=>'DF', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Currently available disk space', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'memsize', 'header'=>'MS', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Memory size', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'numslices', 'header'=>'SM', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Number of slices in memory', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'uptime', 'header'=>'UT', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Continuous uptime until now', 'fetched'=>false);
+}
+
+//TopHat Live data
+
+if (MYSLICE_TOPHAT_AVAILABLE)
+{
+$extra_columns[]=array('tagname'=>'asn', 'header'=>'AS', 'source'=>'tophat', 'type'=>'string', 'title'=>'AS Number', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'city', 'header'=>'LCY', 'source'=>'tophat', 'type'=>'string', 'title'=>'City', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'region', 'header'=>'LRN', 'source'=>'tophat', 'type'=>'string', 'title'=>'Region', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'country', 'header'=>'LCN', 'source'=>'tophat', 'type'=>'string', 'title'=>'Country', 'fetched'=>false);
+$extra_columns[]=array('tagname'=>'continent', 'header'=>'LCT', 'source'=>'tophat', 'type'=>'string', 'title'=>'Continent', 'fetched'=>false);
+//$extra_columns[]=array('tagname'=>'hopcount', 'header'=>'HC', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Hop count from reference node', 'fetched'=>false);
+////$extra_columns[]=array('tagname'=>'rtt', 'header'=>'RTT', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Round trip time from reference node', 'fetched'=>false);
+////$extra_columns[]=array('tagname'=>'agents', 'header'=>'MA', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located measurement agents', 'fetched'=>true);
+////$extra_columns[]=array('tagname'=>'agents_sonoma', 'header'=>'MAS', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located SONoMA agents', 'fetched'=>true);
+////$extra_columns[]=array('tagname'=>'agents_etomic', 'header'=>'MAE', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located ETOMIC agents', 'fetched'=>true);
+////$extra_columns[]=array('tagname'=>'agents_tdmi', 'header'=>'MAT', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located TDMI agents', 'fetched'=>true);
+////$extra_columns[]=array('tagname'=>'agents_dimes', 'header'=>'MAD', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located DIMES agents', 'fetched'=>true);
+}
 
-// fetch nodes - set pattern in the url for server-side filtering
-$node_columns=array('hostname','node_type','site_id','node_id','boot_state','interface_ids','peer_id');
+
+$ConfigureColumns =new PlekitColumns($full_configuration, $fix_columns, $tag_columns, $extra_columns);
+
+$visiblecolumns = $ConfigureColumns->node_tags();
+
+$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
+
+//$visibletags = new VisibleTags ($api, 'node');
+//$visiblecolumns = $visibletags->column_names();
+//print("<p>OLD");
+//print_r($visiblecolumns);
+//$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
+
+
+// server-side filtering - set pattern in $_GET for filtering on hostname
 if ($pattern) {
   $node_filter['hostname']=$pattern;
   $title .= " matching " . $pattern;
@@ -65,16 +222,17 @@ if ($pattern) {
  }
 
 // server-side selection on peerscope
-list ( $peer_filter, $peer_label) = plc_peer_info($api,$_GET['peerscope']);
-$node_filter=array_merge($node_filter,$peer_filter);
+$peerscope=new PeerScope($api,$_GET['peerscope']);
+$node_filter=array_merge($node_filter,$peerscope->filter());
+$title .= ' - ' . $peerscope->label();
 
 if ($site_id) {
-  $sites=$api->GetSites(array($site_id),array("name","login_base"));
+  $sites=$api->GetSites(array($site_id));
   $site=$sites[0];
   $name=$site['name'];
   $login_base=$site['login_base'];
   $title .= t_site($site);
-  $tabs = array_merge($tabs,tabs_site($site));
+  $tabs []= tab_site($site);
   $node_filter['site_id']=array($site_id);
 }
 
@@ -82,13 +240,46 @@ if ($slice_id) {
   $slices=$api->GetSlices(array($slice_id),array('node_ids','name'));
   $slice=$slices[0];
   $title .= t_slice($slice);
-  $tabs = array_merge($tabs,tabs_slice($slice));
+  $tabs []= tab_slice($slice);
   $node_filter['node_id'] = $slice['node_ids'];
  }
 
+// person_id is set : this is mostly oriented towards people managing several sites
+if ($person_id) {
+  // avoid doing a useless call to GetPersons if the person_id is already known though $plc,
+  // as this is mostly done for the 'all my sites nodes' link
+  if ($person_id == plc_my_person_id()) { 
+    $person=plc_my_person();
+    $site_ids = plc_my_site_ids();
+  } else {
+    // fetch the person's site_ids
+    $persons = $api->GetPersons(array('person_id'=>$person_id),array('person_id','email','site_ids'));
+    $person=$persons[0];
+    $site_ids=$person['site_ids'];
+  }
+  $title .= t_person($person);
+  $node_filter['site_id']=$site_ids;
+ }
+
 // go
+//print("getting nodes ".$node_columns);
+//print_r($node_columns);
 $nodes=$api->GetNodes($node_filter,$node_columns);
 
+//print("<p> GOT NODES </p>");
+//print_r($nodes);
+
+$ConfigureColumns->fetch_live_data($nodes);
+
+$show_columns_message = TRUE;
+$show_conf = explode(";",$show_configuration);
+foreach ($show_conf as $ss) {
+  if ($ss =="columns")
+    $show_columns_message = FALSE;
+}
+
+
+
 // build site_ids - interface_ids
 $site_ids=array();
 $interface_ids=array();
@@ -103,9 +294,7 @@ $interface_filter=array('is_primary'=>TRUE,'interface_id'=>$interface_ids);
 $interfaces=$api->GetInterfaces($interface_filter,$interface_columns);
 
 $interface_hash=array();
-foreach ($interfaces as $interface) {
-    $interface_hash[$interface['node_id']]=$interface;
-}
+foreach ($interfaces as $interface) $interface_hash[$interface['node_id']]=$interface;
 
 // fetch related sites
 $site_columns=array('site_id','login_base');
@@ -113,69 +302,119 @@ $site_filter=array('site_id'=>$site_ids);
 $sites=$api->GetSites($site_filter,$site_columns);
 
 $site_hash=array();
-foreach ($sites as $site) {
-    $site_hash[$site['site_id']]=$site;
-}
+foreach ($sites as $site) $site_hash[$site['site_id']]=$site;
 
 // --------------------
 drupal_set_title($title);
 
-plc_tabs($tabs);
+plekit_linetabs($tabs);
 
 if ( ! $nodes ) {
   drupal_set_message ('No node found');
   return;
  }
   
-$columns = array ("Peer"=>"string",
-                 "Region"=>"string",
-                 "Site"=>"string",
-                 "State"=>"string",
-                 "Hostname"=>"string",
-                 "IP"=>"IPAddress",
-                 "Type"=>"string",
-                 "?"=>"string",
-                 "Int"=>"int",
-                 "Float"=>"float");
+$nifty=new PlekitNifty ('','objects-list','big');
+$nifty->start();
+$headers = array (); 
+$notes=array();
+$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";
+
+$info_header = array();
+$short="?"; $long="extra status info"; $type='string'; 
+$info_header[$short]=array('type'=>$type,'title'=>$long, 'label'=>'?', 'header'=>'?', 'visible'=>true); 
+//$notes []= "$short = $long";
+//$info_header["?"] = "none";
+$headers = array_merge($ConfigureColumns->get_headers(),$info_header);
+
+$layout_help='
+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('nodes-layout',
+                               "Node table layout",
+                               array('visible'=>NULL, 
+                                    'info-text'=>$layout_help,
+                                    'info-visible'=>$show_columns_message));
+$toggle_nodes->start();
+print("<div id='debug'></div>");
+print("<input type='hidden' id='slice_id' value='nodes' />");
+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='defaultConf' value='".$default_configuration."'></input>");
+
+////////// end
+
+$ConfigureColumns->configuration_panel_html(true);
+$ConfigureColumns->javascript_init();
+$toggle_nodes->end();
+
+$table_options = array('notes'=>$notes,
+                       'search_width'=>15,
+                       'pagesize'=>20,
+                        'configurable'=>true);
 
 # initial sort on hostnames
-plc_table_start("nodes",$columns,4);
+$table=new PlekitTable ("nodes",$headers,2, $table_options);
+$table->start();
 
-$peer_hash = plc_peer_get_hash ($api);
+$peers = new Peers ($api);
 // write rows
-$fake1=1; $fake2=3.14; $fake_i=0;
 foreach ($nodes as $node) {
-    $hostname=$node['hostname'];
-    $node_id=$node['node_id'];
-    $site_id=$node['site_id'];
-    $site=$site_hash[$site_id];
-    $login_base = $site['login_base'];
-    $node_id=$node['node_id'];
-    $ip=$interface_hash[$node['node_id']]['ip'];
-    $interface_id=$interface_hash[$node['node_id']]['interface_id'];
-    $shortname = plc_peer_shortname ($peer_hash,$node['peer_id']);
-    $node_type = $node['node_type'];
-
-    plc_table_row_start($hostname);
-    plc_table_cell ($shortname);
-    plc_table_cell (topdomain($hostname));
-    plc_table_cell (l_site2($site_id,$login_base));
-    plc_table_cell ($node['boot_state']);
-    plc_table_cell (l_node2($node_id,$hostname));
-    plc_table_cell (l_interface2($interface_id,$ip));
-    plc_table_cell ($node_type);
-    plc_table_cell (node_status($node));
-    plc_table_cell ($fake1);
-    plc_table_cell ($fake2);
-    plc_table_row_end();
-                                
-    if ($fake_i % 5 == 0) $fake1 += 3; 
-    if ($fake_i % 3 == 0) $fake2 +=5; else $fake2 -= $fake_i;
-    $fake_i += 1;
+  //$node_obj = new Node ($node);
+
+  $hostname=$node['hostname'];
+  $node_id=$node['node_id'];
+  $site_id=$node['site_id'];
+  $site=$site_hash[$site_id];
+  $login_base = $site['login_base'];
+  $ip=$interface_hash[$node['node_id']]['ip'];
+  $interface_id=$interface_hash[$node['node_id']]['interface_id'];
+  $peer_id=$node['peer_id'];
+  
+  $table->row_start();
+  $table->cell($node['node_id'], array('display'=>'none'));
+  if (plc_is_admin()) $table->cell(l_node_t($node_id,$node_id));
+  $table->cell (l_node_t($node_id,$hostname));
+  $peers->cell ($table,$peer_id);
+
+  //prefetch some columns
+  $node['domain'] = topdomain($hostname);
+  $node['sitename'] = l_site_t($site_id,$login_base);
+  if ($interface_id)
+       $node['ipaddress'] = l_interface_t($interface_id,$ip);
+  else
+       $node['ipaddress'] = "n/a";
+
+  list($label,$class) = Node::status_label_class_($node);
+  $table->cell ($label,array('class'=>$class));
+  $table->cell( ($node['node_type']=='reservable')?reservable_mark():"" );
+  //$table->cell (count($node['slice_ids']));
+  //foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
+  $ConfigureColumns->cells($table, $node);
+  $table->cell (node_status($node));
+  $table->row_end();
+  
 }
 
-plc_table_end();
+$table->end();
+$nifty->end();
+
+
+//plekit_linetabs ($tabs,"bottom");
+
+// Print footer
+include 'plc_footer.php';
 
-plc_table_notes();
 ?>