checkpoint with timeslots
[plewww.git] / planetlab / slices / slice.php
index de6098e..0d587ef 100644 (file)
@@ -16,6 +16,8 @@ include 'plc_header.php';
 // Common functions
 require_once 'plc_functions.php';
 require_once 'plc_peers.php';
+require_once 'plc_objects.php';
+require_once 'plc_visibletags.php';
 require_once 'linetabs.php';
 require_once 'table.php';
 require_once 'details.php';
@@ -51,9 +53,7 @@ $name= $slice['name'];
 $expires = date( "d/m/Y", $slice['expires'] );
 $site_id= $slice['site_id'];
 
-//$node_ids=$slice['node_ids'];
 $person_ids=$slice['person_ids'];
-//$slice_tag_ids= $slice['slice_tag_ids'];
 
 // get peers
 $peer_id= $slice['peer_id'];
@@ -65,13 +65,6 @@ $sites= $api->GetSites( array( $site_id ) );
 $site=$sites[0];
 $site_name= $site['name'];
 $max_slices = $site['max_slices'];
-// xxx PIs
-//$pis=$api->GetPersons(...)
-
-// get all persons info
-if (!empty($person_ids))
-  $persons=$api->GetPersons($person_ids,array('email','enabled'));
-
 
 //////////////////////////////////////// building blocks for the renew area
 // Constants
@@ -81,7 +74,7 @@ global $MAX_WEEKS;    $MAX_WEEKS= 8;          // weeks from today
 global $GRACE_DAYS;    $GRACE_DAYS=10;         // days for renewal promoted on top
 global $NOW;           $NOW=mktime();
 
-
+////////////////////////////////////////////////////////////
 // make the renew area on top and open if the expiration time is less than 10 days from now
 function renew_needed ($slice) {
   global $DAY, $NOW, $GRACE_DAYS;
@@ -96,12 +89,14 @@ function renew_area ($slice,$site,$visible) {
   global $DAY, $WEEK, $MAX_WEEKS, $GRACE_DAYS, $NOW;
  
   $current_exp=$slice['expires'];
+  $current_text = gmstrftime("%A %b-%d-%y %T %Z", $current_exp);
   $max_exp= $NOW + ($MAX_WEEKS * $WEEK); // seconds since epoch
+  $max_text = gmstrftime("%A %b-%d-%y %T %Z", $max_exp);
 
   // xxx some extra code needed to enable this area only if the slice description is OK:
   // description and url must be non void
   $toggle=
-    new PlekitToggle('renew',"Renew this slice",
+    new PlekitToggle('renew',"Expires $current_text - Renew this slice",
                     array("bubble"=>
                           "Enter this zone if you wish to renew your slice",
                           'visible'=>$visible));
@@ -129,7 +124,7 @@ EOF;
     $selectors = array();
     foreach ( array ( 1 => "One more week", 
                      2 => "Two more weeks", 
-                     3 => "Two more weeks", 
+                     3 => "Three more weeks", 
                      4 => "One more month" ) as $weeks => $text ) {
       $candidate_exp = $current_exp + $weeks*$WEEK;
       if ( $candidate_exp < $max_exp) {
@@ -142,8 +137,9 @@ EOF;
 
     if ( empty( $selectors ) ) {
       print <<< EOF
-<div class='plc-warning renewal'>
-Slice cannot be renewed any further into the future, try again closer to expiration date.
+<div class='my-slice-renewal'>
+Slices annot be renewed more than $MAX_WEEKS weeks from now, i.e. not beyond $max_text. 
+For this reason, the current slice cannot be renewed any further into the future, try again closer to expiration date.
 </div>
 EOF;
      } else {
@@ -173,7 +169,7 @@ EOF;
   $toggle->end();
 }
 
-////////// 
+////////////////////////////////////////////////////////////
 
 $am_in_slice = in_array(plc_my_person_id(),$person_ids);
 
@@ -183,7 +179,8 @@ if ($am_in_slice) {
   drupal_set_title("Slice " . $name);
 }
 
-$privileges = ( $local_peer && (plc_is_admin()  || $am_in_slice));
+$privileges = ( $local_peer && (plc_is_admin()  || plc_is_pi() || $am_in_slice));
+$tags_privileges = $privileges || plc_is_admin();
 
 $tabs=array();
 $tabs [] = tab_nodes_slice($slice_id);
@@ -195,7 +192,7 @@ if ($privileges) {
                          'method'=>'post',
                          'values'=>array('action'=>'delete-slice','slice_id'=>$slice_id),
                          'bubble'=>"Delete slice $name",
-                         'confirm'=>'Are you sure to delete $name');
+                         'confirm'=>"Are you sure to delete slice $name");
 
   $tabs["Events"]=array_merge(tablook_event(),
                              array('url'=>l_event("Slice","slice",$slice_id),
@@ -263,15 +260,18 @@ $details->form_end();
 $toggle->end();
 
 //////////////////// persons
-$persons=$api->GetPersons(array('person_id'=>$slice['person_ids']));
-// just propose to add everyone else, 
+$person_columns = array('email','person_id','first_name','last_name','roles');
+// get persons in slice
+if (!empty($person_ids))
+  $persons=$api->GetPersons(array('person_id'=>$slice['person_ids']),$person_columns);
+// just propose to add everyone else
+// xxx this is maybe too much for admins as it slows stuff down 
 // as regular persons can see only a fraction of the db anyway
-if (empty($persons))
-    $potential_persons=$api->GetPersons();
-else
-    $potential_persons=
-        $api->GetPersons(array('~person_id'=>$slice['person_ids'],'peer_id'=>NULL),
-                         array('email','person_id','first_name','last_name','roles'));
+$potential_persons=
+  $api->GetPersons(array('~person_id'=>$slice['person_ids'],
+                        'peer_id'=>NULL,
+                        'enabled'=>true),
+                  $person_columns);
 $count=count($persons);
 
 $toggle=
@@ -341,7 +341,7 @@ if ($privileges) {
     $headers['first']='string';
     $headers['last']='string';
     $headers['R']='string';
-    $headers['Add']="none";
+    $headers['+']="none";
     $options = array('notes_area'=>false,
                     'search_width'=>15,
                     'pagesize'=>8);
@@ -374,14 +374,24 @@ if ($privileges) {
 }
 $toggle->end();
 
-//////////////////// nodes
+//////////////////////////////////////////////////////////// Nodes
+// the nodes details to display here
+// (1) we search for the tag types for which 'category' matches 'node*/ui*'
+// all these tags will then be tentatively displayed in this area
+// (2) further information can also be optionally specified in the category:
+//     (.) we split the category with '/' and search for assignments of the form var=value
+//     (.) header can be set to supersede the column header (default is tagname)
+//     (.) rank can be used for ordering the columns (default is tagname)
+//     (.) type is passed to the javascript table, for sorting (default is 'string')
+
 // minimal list as a start
-$node_columns = array('hostname','node_id','arch');
+$node_fixed_columns = array('hostname','node_id','peer_id','slice_ids_whitelist','run_level','boot_state','last_contact');
+// create a VisibleTags object : basically the list of tag columns to show
+$visibletags = new VisibleTags ($api, 'node');
+$visiblecolumns = $visibletags->column_names();
+$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
 $nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),$node_columns);
-if (empty($nodes))
-    $potential_nodes=$api->GetNodes();
-else
-    $potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_columns);
+$potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_columns);
 $count=count($nodes);
 
 $toggle=new PlekitToggle ('my-slice-nodes',"$count Nodes",
@@ -398,22 +408,34 @@ $toggle_nodes=new PlekitToggle('my-slice-nodes-current',
 $toggle_nodes->start();
 
 $headers=array();
+$notes=array();
+$headers['peer']='string';
 $headers['hostname']='string';
-$headers['arch']='string';
+$short="ST"; $long=Node::status_footnote(); $type='string'; 
+       $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
+// the extra tags
+$headers=array_merge($headers,$visibletags->headers());
+$notes=array_merge($notes,$visibletags->notes());
+
 if ($privileges) $headers[plc_delete_icon()]="none";
 
-$table_options = array('notes_area'=>false,
+$table_options = array('notes'=>$notes,
                        'search_width'=>15,
                        'pagesize'=>20);
-$table=new PlekitTable('nodes',$headers,'0',$table_options);
+$table=new PlekitTable('nodes',$headers,'1',$table_options);
 
 $form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
 $form->start();
 $table->start();
 if ($nodes) foreach ($nodes as $node) {
   $table->row_start();
+  $peers->cell($table,$node['peer_id']);
   $table->cell(l_node_obj($node));
-  $table->cell($node['arch']);
+  $run_level=$node['run_level'];
+  list($label,$class) = Node::status_label_class_($node);
+  $table->cell ($label,array('class'=>$class));
+  foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
+
   if ($privileges) $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
   $table->row_end();
 }
@@ -433,10 +455,19 @@ $toggle_nodes->end();
 
 ////////// nodes to add
 if ($privileges) {
+  $new_potential_nodes = array();
+  if ($potential_nodes) foreach ($potential_nodes as $node) {
+      $emptywl=empty($node['slice_ids_whitelist']);
+      $inwl = (!emptywl) and in_array($slice['slice_id'],$node['slice_ids_whitelist']);
+      if ($emptywl or $inwl)
+       $new_potential_nodes[]=$node;
+  }
+  $potential_nodes=$new_potential_nodes;
+
   $count=count($potential_nodes);
   $toggle_nodes=new PlekitToggle('my-slice-nodes-add',
                                 "$count more nodes available",
-                                array('visible'=>get_arg('show_persons_add',false)));
+                                array('visible'=>get_arg('show_nodes_add',false)));
   $toggle_nodes->start();
 
   if ( ! $potential_nodes ) {
@@ -444,9 +475,15 @@ if ($privileges) {
     echo "<p class='not-relevant'>No node to add</p>";
   } else {
     $headers=array();
+    $notes=array();
+    $headers['peer']='string';
     $headers['hostname']='string';
-    $headers['arch']='string';
-    $headers['Add']="none";
+    $short="ST"; $long=Node::status_footnote(); $type='string'; 
+       $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
+    // the extra tags
+    $headers=array_merge($headers,$visibletags->headers());
+    $notes=array_merge($notes,$visibletags->notes());
+    $headers['+']="none";
     
     $table=new PlekitTable('add_nodes',$headers,'1', $table_options);
     $form=new PlekitForm(l_actions(),
@@ -455,8 +492,11 @@ if ($privileges) {
     $table->start();
     if ($potential_nodes) foreach ($potential_nodes as $node) {
        $table->row_start();
+       $peers->cell($table,$node['peer_id']);
        $table->cell(l_node_obj($node));
-       $table->cell($node['arch']);
+       list($label,$class) = Node::status_label_class_($node);
+       $table->cell ($label,array('class'=>$class));
+       foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
        $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
        $table->row_end();
       }
@@ -474,7 +514,7 @@ if ($privileges) {
 $toggle->end();
 
 //////////////////////////////////////////////////////////// Tags
-if ( $local_peer ) {
+//if ( $local_peer ) {
   $tags=$api->GetSliceTags (array('slice_id'=>$slice_id));
   function get_tagname ($tag) { return $tag['tagname'];}
   $tagnames = array_map ("get_tagname",$tags);
@@ -489,7 +529,7 @@ if ( $local_peer ) {
     "Value"=>"string",
     "Node"=>"string",
     "NodeGroup"=>"string");
-  if ($privileges) $headers[plc_delete_icon()]="none";
+  if ($tags_privileges) $headers[plc_delete_icon()]="none";
   
   $table_options=array("notes_area"=>false,"pagesize_area"=>false,"search_width"=>10);
   $table=new PlekitTable("slice_tags",$headers,'0',$table_options);
@@ -520,11 +560,11 @@ if ( $local_peer ) {
       $table->cell($tag['value']);
       $table->cell($node_name);
       $table->cell($nodegroup_name);
-      if ($privileges) $table->cell ($form->checkbox_html('slice_tag_ids[]',$tag['slice_tag_id']));
+      if ($tags_privileges) $table->cell ($form->checkbox_html('slice_tag_ids[]',$tag['slice_tag_id']));
       $table->row_end();
     }
   }
-  if ($privileges) {
+  if ($tags_privileges) {
     $table->tfoot_start();
     $table->row_start();
     $table->cell($form->submit_html ("delete-slice-tags","Remove selected"),
@@ -535,7 +575,7 @@ if ( $local_peer ) {
     function tag_selector ($tag) {
       return array("display"=>$tag['tagname'],"value"=>$tag['tag_type_id']);
     }
-    $all_tags= $api->GetTagTypes( array ("category"=>"slice*"), array("tagname","tag_type_id"));
+    $all_tags= $api->GetTagTypes( array ("category"=>"slice*","-SORT"=>"+tagname"), array("tagname","tag_type_id"));
     $selector_tag=array_map("tag_selector",$all_tags);
     
     function node_selector($node) { 
@@ -558,10 +598,10 @@ if ( $local_peer ) {
     $table->row_end();
   }
     
-  $form->end();
   $table->end();
+  $form->end();
   $toggle->end();
-}
+//}
 
 
 //////////////////////// renew slice