4 // This file was created when we decided to make the node page consistent with the other pages
5 // That is to say, we wanted the 'Update' and 'Delete' functions to appear in a drop-down
6 // menu like for the other objects
7 // It appeared after analysis that it was easier to have the following
8 // functions gathered in a single php file
11 // displays current settings and prompt for changes before going to node_actions.php
12 // (*) node_actions.php
13 // (GET) 'del=node_id'
14 // (GET) 'update=node_id' -> actual UpdateNode
15 // (POST) node_id=node_id ng_add=nodegroup_id
17 // (POST) boot_state=boot_state node_id=node_id
18 // (POST) ng_add=nodegroup_id
19 // (*) downloadconf.php
20 // (GET) id=node_id [download=1]
21 // either showed current status, or performed actual config download
23 // in this new version we support only POST behaviour with the following interface
24 // REQUIRED : node_id=node_id
25 // (*) action='prompt-update' : former node_update.php
26 // (*) action='update'
28 // model= : actually updated the node
29 // (*) action='boot-state'
30 // boot_state= : changes bootstate
31 // (*) action='delete' : deletes node
32 // (*) action='download-node-floppy' :
33 // (*) action='download-node-iso' :
34 // (*) action='download-node-usb' :
35 // : same as former downloadconf.php with download unset
36 // if in addition POST contains a non-empty field 'download' :
37 // : performs actual node-dep download
38 // (*) action='download-generic-iso':
39 // (*) action='download-generic-usb':
40 // : performs actual generic download
41 // (*) action='add-in-nodegroup': should include this for compatibility, replaces ng_add,
42 // though I could not figure where it's called
45 // TODO : manage a post field for displaying results of previous page
46 // see the special 'flash' in rails
48 // delivering node-dependant images requires larger memory limit
49 // trial and error, based on the current sizes
50 // generic-ISO 43980800
51 // generic-usb 44720128
58 // Bottom line is, looks like we need in the order of twice the file size
59 // so let's play it safe
60 // Thierry - for 4.2, we need a larger area, was 100 for 4.1
61 ini_set("memory_limit","150M");
64 require_once 'plc_login.php';
66 // Get session and API handles
67 require_once 'plc_session.php';
71 require_once 'plc_functions.php';
72 require_once 'plc_sorts.php';
74 // NOTE: this function exits() after it completes its job,
75 // simply returning leads to html decorations being added around the contents
76 function deliver_and_unlink ($filename) {
78 // for security reasons we want to be able to unlink the resulting file once downloaded
79 // so simply redirecting through a header("Location:") is not good enough
81 $size= filesize($filename);
84 header ("Content-Type: application/octet-stream");
85 header ("Content-Transfer-Encoding: binary");
86 header ("Content-Disposition: attachment; filename=" . basename($filename) );
87 header ("Content-Length: " . $size );
88 // for getting IE to work properly
89 // from princeton cvs new_plc_www/planetlab/nodes/downloadconf.php 1.2->1.3
90 header ("Pragma: hack");
91 header ("Cache-Control: public, must-revalidate");
93 // outputs the whole file contents
94 print (file_get_contents($filename));
97 if (! unlink ($filename) ) {
98 // cannot unlink, but how can we notify this ?
99 // certainly not by printing
104 function show_download_confirm_button ($api, $node_id, $action, $can_gen_config, $show_details) {
106 if( $can_gen_config ) {
108 $preview=$api->GetBootMedium($node_id,"node-preview","");
109 print ("<hr /> <h3>Current node configuration contents</h3>");
110 print ("<pre>\n$preview</pre>\n");
113 $action_labels = array ('download-node-floppy' => 'textual node config (for floppy)' ,
114 'download-node-iso' => 'ISO image',
115 'download-node-usb' => 'USB image' );
117 $format = $action_labels [ $action ] ;
118 print( "<p><form method='post' action='node_actions.php'>\n");
119 print ("<input type='hidden' name='node_id' value='$node_id'>\n");
120 print ("<input type='hidden' name='action' value='$action'>\n");
121 print ("<input type='hidden' name='download' value='1'>\n");
122 print( "<input type='submit' value='Download $format'>\n" );
123 print( "</form>\n" );
125 echo "<p><font color=red>Configuration file cannot be created until missing values above are updated.</font>";
131 if (empty($_POST['node_id'])) {
132 plc_redirect (l_nodes());
134 $node_id = intval($_POST['node_id']);
137 $action=$_POST['action'];
141 // ACTION: prompt-update
142 // from former node_update.php
143 case "prompt-update":
145 require_once('plc_drupal.php');
146 $node_info= $api->GetNodes( array( $node_id ), array( "hostname", "model" ) );
147 drupal_set_title("Updating " . $node_info[0]['hostname']);
148 include 'plc_header.php';
151 echo "<form method=post action='node_actions.php'>\n";
152 echo "<input type=hidden name='node_id' value='$node_id'></input>\n";
153 echo "<input type=hidden name='action' value='update'></input>\n";
154 if( $_POST['error'] ) plc_error(unserialize( $_POST['error']));
155 echo "<p><table cellpadding=2><tbody>\n
156 <tr><th>Hostname: </th><td> <input type=text size=35 name='hostname' value='". $node_info[0]['hostname'] ."'></td></tr>\n
157 <tr><th>Model: </th><td> <input type=text size=35 name='model' value='". $node_info[0]['model'] ."'></td></tr>\n
159 <p><input type=submit value='Update Node'>\n
162 echo "<p><a href='index.php?id=$node_id'>Back to Node</a>\n";
167 // from former node_actions.php
170 $hostname= $_POST['hostname'];
171 $model= $_POST['model'];
173 $fields= array( "hostname"=>$hostname, "model"=>$model );
174 $api->UpdateNode( intval( $node_id ), $fields );
175 $error= $api->error();
177 if( empty( $error ) ) {
178 plc_redirect(l_node($node_id));
180 echo "<font color=red>". $error . "</font>\n" ;
181 echo "<p> Press back to retry</p>";
187 // from former node_actions.php
189 $api->DeleteNode( intval( $node_id ) );
190 plc_redirect(l_nodes());
193 // ACTION: boot-state
194 // from former node_actions.php
196 switch( $_POST['boot_state'] ) {
203 $api->UpdateNode( intval( $node_id ), array( "boot_state" => $_POST['boot_state'] ) );
204 plc_redirect (l_node($node_id));
207 print "<div class='plc-error'> no such boot state " . $_POST['boot_state'] . "</div>";
212 // ACTION: download-generic
213 case "download-generic-iso":
214 case "download-generic-usb":
216 if ($action=="download-generic-iso") {
217 $boot_action="generic-iso";
219 $boot_action="generic-usb";
222 // place the result in a random-named sub dir for clear filenames
223 $filename = $api->GetBootMedium ($node_id, $boot_action, "%d/%n-%p-%a-%v%s");
224 $error=$api->error();
225 // NOTE. for some reason, GetBootMedium sometimes does not report an error but the
226 // file is not created - this happens e.g. when directory owmer/modes are wrong
227 // in this case we get an empty filename
228 // see /etc/httpd/logs/error_log in this case
229 if (empty($error) && empty($filename)) {
230 $error="Unexpected error from GetBootMedium - probably wrong directory modes";
232 if (! empty($error)) {
233 print ("<div class='plc-error'> $error </div>\n");
234 print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
237 deliver_and_unlink ($filename);
242 // ACTION: download-node
243 // from former downloadconf.php
245 case "download-node-floppy":
246 case "download-node-iso":
247 case "download-node-usb":
249 $return= $api->GetNodes( array( $node_id ) );
250 $node_detail= $return[0];
252 // non-admin people need to be affiliated with the right site
253 if( ! plc_is_admin() ) {
254 $node_site_id = $node_detail['site_id'];
255 $in_site = plc_in_site($node_site_id);
257 $error= "Insufficient permission. You cannot create configuration files for this node.";
261 $hostname= $node_detail['hostname'];
262 $return= $api->GetInterfaces( array( "node_id" => $node_id ), NULL );
267 if( count($return) > 0 ) {
268 foreach( $return as $interface_detail ) {
269 if( $interface_detail['is_primary'] == true ) {
276 if( !$has_primary ) {
279 if( $node_detail['hostname'] == "" ) {
281 $node_detail['hostname']= "<i>Missing</i>";
284 $fields= array("method","ip");
285 foreach( $fields as $field ) {
286 if( $interface_detail[$field] == "" ) {
288 $interface_detail[$field]= "<i>Missing</i>";
292 if( $interface_detail['method'] == "static" ) {
293 $fields= array("gateway","netmask","network","broadcast","dns1");
294 foreach( $fields as $field ) {
295 if( $interface_detail[$field] == "" ) {
297 $interface_detail[$field]= "<i>Missing</i>";
302 if( $interface_detail['method'] != "static"
303 && $interface_detail['method'] != "dhcp" ) {
305 $interface_detail['method']= "<i>Unknown method</i>";
309 $download= $_POST['download'];
311 if( $can_gen_config && !empty($download) ) {
313 case 'download-node-floppy':
314 $boot_action='node-floppy';
315 $location = "%d/%n-%v-rename-into-plnode%s";
317 case 'download-node-iso':
318 $boot_action='node-iso';
319 $location = "%d/%n-%a-%v%s";
321 case 'download-node-usb':
322 $boot_action='node-usb';
323 $location = "%d/%n-%a-%v%s";
327 $filename=$api->GetBootMedium($node_id,$boot_action,$location);
328 $error=$api->error();
329 if (empty($error) && empty($filename)) {
330 $error="Unexpected error from GetBootMedium - probably wrong directory modes";
332 if (! empty($error)) {
333 print ("<div class='plc-error'> $error </div>\n");
334 print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
337 deliver_and_unlink ($filename);
342 drupal_set_title("Download boot material for $hostname");
346 WARNING: Creating a new configuration file for this node will generate
347 a new node key, and any existing configuration file will be unusable and
348 must be updated before the node can successfully boot, install, or
351 <p>In order to create a configuration file for this node using this page,
352 all the interface settings must be up to date. Below is summary of these
353 values. Any missing values must be entered before this can be used.
359 show_download_confirm_button($api, $node_id, $action, $can_gen_config, false);
361 print ("<h3>Current interface settings</h3>\n");
364 print( "<table border=\"0\" cellspacing=\"4\">\n" );
366 print( "<tr><th colspan=2><a href='index.php?id=$node_id'>Node Details</a></th></tr>" );
367 print( "<tr><th>node_id:</th>" );
368 print( "<td>$node_id</td></tr>\n" );
369 print( "<tr><th>Hostname:</th>" );
370 print( "<td>" . $node_detail['hostname'] . "</td></tr>\n" );
372 $nn_id = $interface_detail['interface_id'];
373 print( "<tr><th colspan=2><a href='interfaces.php?id=$nn_id'>Interface Details</a></th></tr>" );
375 print( "<tr><th>Method:</th>" );
376 print( "<td>" . $interface_detail['method'] . "</td></tr>\n" );
377 print( "<tr><th>IP:</th>" );
378 print( "<td>" . $interface_detail['ip'] . "</td></tr>\n" );
380 if( $interface_detail['method'] == "static" ) {
381 print( "<tr><th>Gateway:</th>" );
382 print( "<td>" . $interface_detail['gateway'] . "</td></tr>\n" );
383 print( "<tr><th>Network mask:</th>" );
384 print( "<td>" . $interface_detail['netmask'] . "</td></tr>\n" );
385 print( "<tr><th>Network address:</th>" );
386 print( "<td>" . $interface_detail['network'] . "</td></tr>\n" );
387 print( "<tr><th>Broadcast address:</th>" );
388 print( "<td>" . $interface_detail['broadcast'] . "</td></tr>\n" );
389 print( "<tr><th>DNS 1:</th>" );
390 print( "<td>" . $interface_detail['dns1'] . "</td></tr>\n" );
391 print( "<tr><th>DNS 2:</th>" );
392 if( $interface_detail['dns2'] == "" ) {
393 print( "<td><i>Optional, missing</i></td></tr>\n" );
395 print( "<td>" . $interface_detail['dns2'] . "</td></tr>\n" );
399 print ("<tr><th colspan=2><a href='interfaces.php?id=$nn_id'>Additional Settings</a></th></tr>\n");
400 $nn_id = $interface_detail['interface_id'];
401 $settings=$api->GetInterfaceTags(array("interface_id" => array($nn_id)));
402 foreach ($settings as $setting) {
403 $category=$setting['category'];
404 $name=$setting['tagname'];
405 $value=$setting['value'];
406 print (" <tr><th> $category $name </th><td> $value </td></tr>\n");
409 print( "</table>\n" );
411 print( "<p class='plc-warning'>This node has no configured primary interface.</p>\n" );
414 show_download_confirm_button($api, $node_id, $action, $can_gen_config, true);
418 echo "Unkown action <$action>.";
419 plc_redirect (l_node($node_id));