keep the explicit setting of memory_limit only in 3 pages
[plewww.git] / planetlab / nodes / node_downloads.php
1 <?php
2
3   // cleaned up, keep only the actions related to downloading stuff
4   // REQUIRED : node_id=node_id
5   // (*) action='download-node-floppy' : 
6   // (*) action='download-node-iso' : 
7   // (*) action='download-node-usb' : 
8   //                            : same as former downloadconf.php with download unset
9   //     if in addition POST contains a non-empty field 'download' :
10   //                            : performs actual node-dep download
11   // (*) action='download-generic-iso':
12   // (*) action='download-generic-usb':
13   //                            : performs actual generic download
14
15 ini_set("memory_limit","256M");
16
17 // Require login
18 require_once 'plc_login.php';
19
20 // Get session and API handles
21 require_once 'plc_session.php';
22 global $plc, $api;
23
24 // Common functions
25 require_once 'plc_functions.php';
26 require_once 'details.php';
27
28 // NOTE: this function exits() after it completes its job, 
29 // simply returning leads to html decorations being added around the contents
30 function deliver_and_unlink ($filename) {
31   
32   // for security reasons we want to be able to unlink the resulting file once downloaded
33   // so simply redirecting through a header("Location:") is not good enough
34
35   $size= filesize($filename);
36
37   // headers
38   header ("Content-Type: application/octet-stream");
39   header ("Content-Transfer-Encoding: binary");
40   header ("Content-Disposition: attachment; filename=" . basename($filename) );
41   header ("Content-Length: " . $size );
42   // for getting IE to work properly
43   // from princeton cvs new_plc_www/planetlab/nodes/downloadconf.php 1.2->1.3
44   header ("Pragma: hack");
45   header ("Cache-Control: public, must-revalidate");
46
47   // turn off output buffering
48   ob_end_flush();
49   // outputs the whole file contents without copying it to memory
50   readfile($filename);
51  
52   // unlink the file
53   if (! unlink ($filename) ) {
54     // cannot unlink, but how can we notify this ?
55     // certainly not by printing
56   }
57   exit();
58 }
59
60 function show_download_confirm_button ($api, $node_id, $action, $can_gen_config, $show_details) {
61
62   if( $can_gen_config ) {
63     if ($show_details) {
64       $preview=$api->GetBootMedium($node_id,"node-preview","");
65       print ("<hr />");
66       print ("<h3 class='node_download'>Configuration file contents</h3>");
67       print ("<pre>\n$preview</pre>\n");
68       print ("<hr />");
69     }
70     $action_labels = array ('download-node-floppy' => 'textual node config (for floppy)' ,
71                             'download-node-iso' => 'ISO image',
72                             'download-node-usb' => 'USB image' );
73     
74     $format = $action_labels [ $action ] ;
75     print( "<div id='download_button'> <form method='post' action='node_downloads.php'>");
76     print ("<input type='hidden' name='node_id' value='$node_id'>");
77     print ("<input type='hidden' name='action' value='$action'>");
78     print ("<input type='hidden' name='download' value='1'>");
79     print( "<input type='submit' value='Download $format'>" );
80     print( "</form></div>\n" );
81   } else {
82     echo "<p><font color=red>Configuration file cannot be created until missing values above are updated.</font>";
83   }
84 }
85
86 // check arguments
87
88 if (empty($_POST['node_id'])) {
89   plc_redirect (l_nodes());
90  } else {
91   $node_id = intval($_POST['node_id']);
92 }
93
94 $action=$_POST['action'];
95
96 switch ($action) {
97
98  case "download-generic-iso":
99  case "download-generic-usb":
100    
101    if ($action=="download-generic-iso") {
102      $boot_action="generic-iso";
103    } else {
104      $boot_action="generic-usb";
105    }
106
107    // place the result in a random-named sub dir for clear filenames
108    $filename = $api->GetBootMedium ($node_id, $boot_action, "%d/%n-%p-%a-%v%s");
109    $error=$api->error();
110    // NOTE. for some reason, GetBootMedium sometimes does not report an error but the
111    // file is not created - this happens e.g. when directory owmer/modes are wrong 
112    // in this case we get an empty filename
113    // see /etc/httpd/logs/error_log in this case
114    if (empty($error) && empty($filename)) {
115      $error="Unexpected error from GetBootMedium - probably wrong directory modes";
116    }    
117    if (! empty($error)) {
118      print ("<div class='plc-error'> $error </div>\n");
119      print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
120      return ;
121    } else {
122      deliver_and_unlink ($filename);
123      exit();
124    }
125    break;
126
127    // ACTION: download-node
128    // from former downloadconf.php
129    
130  case "download-node-floppy":
131  case "download-node-iso":
132  case "download-node-usb":
133  case "download-node-usb-partition":
134
135    
136    $nodes = $api->GetNodes( array( $node_id ) );
137    $node = $nodes[0];
138
139    // non-admin people need to be affiliated with the right site
140    if( ! plc_is_admin() ) {
141      $node_site_id = $node['site_id'];
142      $in_site = plc_in_site($node_site_id);
143      if( ! $in_site) {
144        $error= "Insufficient permission. You cannot create configuration files for this node.";
145      }
146    }
147
148    $hostname= $node['hostname'];
149    // search for the primary interface
150    $interfaces = $api->GetInterfaces( array( "node_id" => $node_id, "is_primary"=>true ), NULL );
151    
152    $can_gen_config= 1;
153
154    if ( ! $interfaces ) {
155      $can_gen_config= 0;
156    } else {
157      $interface = $interfaces[0];
158      if ( $node['hostname'] == "" ) {
159        $can_gen_config= 0;
160        $node['hostname']= plc_warning("Missing");
161      }
162      
163      # fields to check
164      $fields= array("method","ip");
165      if ( $interface['method'] == "static" ) 
166        $fields = array_merge ( $fields, array("gateway","netmask","network","broadcast","dns1"));
167      foreach( $fields as $field ) {
168        if( $interface[$field] == "" ) {
169          $can_gen_config= 0;
170          $interface[$field]= plc_warning("Missing");
171        }
172      }
173
174      if(    $interface['method'] != "static" 
175          && $interface['method'] != "dhcp" ) {
176        $can_gen_config= 0;
177        $interface['method']= "<i>Unknown method</i>";
178      }
179    }
180
181    $download= $_POST['download'];
182    
183    if( $can_gen_config && !empty($download) ) {
184      switch ($action) {
185      case 'download-node-floppy':
186        $boot_action='node-floppy'; 
187        $location = "%d/%n-%v-rename-into-plnode%s";
188        $options = array();
189        break;
190      case 'download-node-iso':
191        $boot_action='node-iso';
192        $location = "%d/%n-%a-%v%s";
193        $options = array();
194        break;
195      case 'download-node-usb':
196        $boot_action='node-usb';
197        $location = "%d/%n-%a-%v%s";
198        $options = array();
199        break;
200      case "download-node-usb-partition":
201        $boot_action='node-usb';
202        $location = "%d/%n-%a-%v-partition%s";
203        $options = array('partition');
204        break;
205      }   
206
207      $filename=$api->GetBootMedium($node_id,$boot_action,$location,$options);
208      $error=$api->error();
209      if (empty($error) && empty($filename)) {
210        $error="Unexpected error from GetBootMedium - probably wrong directory modes";
211      }    
212      if (! empty($error)) {
213        print ("<div class='plc-error'> $error </div>\n");
214        print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
215        return ;
216      } else {
217        deliver_and_unlink ($filename);
218        exit();
219      }
220    }
221
222    drupal_set_title("Download boot medium for $hostname");
223
224    $header= <<<EOF
225 <p class='node_download'>
226 <span class='bold'>WARNING:</span> Downloading a new boot medium
227 for this node will generate <span class='bold'>a new node key</span>, and any 
228 formerly downloaded boot medium for that node will become <span class='bold'>outdated</span>.
229 <br/>
230 <br/>
231 In order to create a configuration file for this node using this page,
232 the interface settings must be up to date. Below is summary of these
233 values. 
234 </p>
235
236 EOF;
237
238    echo $header;
239
240    show_download_confirm_button($api, $node_id, $action, $can_gen_config, false);
241    print ("<hr />");
242    print ("<h3 class='node_download'>Current node configuration</h3>");
243
244    $details = new PlekitDetails (false);
245    $details->start();
246
247    if( ! $interface ) {
248      print ("<center>");
249      print (plc_warning("This node has no configured primary interface."));
250      print ("You can add one " . href(l_interface_add($node_id), "here "));
251      print ("</center>");
252    } else {
253      $details->tr(l_node_t($node_id,"Node details"),"center");
254      $details->th_td("node_id",$node_id);
255      $details->th_td("Hostname",$node['hostname']);
256
257      $interface_id = $interface['interface_id'];
258      $details->tr(l_interface_t($interface_id,"Interface Details"),"center");
259      $details->th_td("Method",$interface['method']);
260      $details->th_td("IP",$interface['ip']);
261
262      if( $interface['method'] == "static" ) {
263        $details->th_td("Gateway",$interface['gateway']);
264        $details->th_td("Network mask",$interface['netmask']);
265        $details->th_td("Network address",$interface['network']);
266        $details->th_td("Broadcast address",$interface['broadcast']);
267        $details->th_td("DNS 1",$interface['dns1']);
268        if ($interface['dns2'])
269          $details->th_td("DNS 2",$interface['dns2']);
270       }
271
272      $details->tr(href(l_interface_tags($interface_id),"Interface extra settings (tags)"),"center");
273      $interface_id = $interface['interface_id'];
274      $settings=$api->GetInterfaceTags(array("interface_id" => array($interface_id)));
275      if ( ! $settings) {
276        $details->tr("no tag set","center");
277      } else foreach ($settings as $setting) {
278        $category=$setting['category'];
279        $name=$setting['tagname'];
280        $value=$setting['value'];
281        $details->th_td($category . " " . $name,$value);
282      }
283    }
284    $details->end();
285
286  show_download_confirm_button($api, $node_id, $action, $can_gen_config, true);
287  break;
288  
289  default:
290    drupal-set_error("Unkown action $action in node_downloads.php");
291    plc_redirect (l_node($node_id));
292    break;
293  }
294
295 ?>