editnodetype.php3 26 KB
Newer Older
1 2
<?php
#
3
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24
#
include("defs.php3");
25 26
include_once("imageid_defs.php");
include_once("osinfo_defs.php");
27
include_once("osiddefs.php3");
28 29 30 31 32 33 34 35

#
# No PAGEHEADER since we spit out a Location header later. See below.
#

#
# Only known and logged in users can end experiments.
#
36 37 38
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
39 40 41 42 43

if (! $isadmin) {
    USERERROR("You do not have permission to edit node types!", 1);
}

44 45
$optargs = OptionalPageArguments("submit",     PAGEARG_STRING,
				 "formfields", PAGEARG_ARRAY,
46 47 48 49 50

				 # Send new_type=1 to create new nodetype.
				 "new_type",   PAGEARG_STRING,
				 # Optional if new_type, required if not.
				 "node_type",  PAGEARG_STRING,
51 52
				 # Optional if new_type
				 "node_class", PAGEARG_STRING,
53 54

				 # Attribute creation and deletion.
55 56 57 58
				 "deletes",    PAGEARG_ARRAY,
				 "attributes", PAGEARG_ARRAY,
				 "newattribute_type",  PAGEARG_STRING,
				 "newattribute_name",  PAGEARG_STRING,
59
				 "newattribute_value", PAGEARG_ANYTHING);
Russ Fish's avatar
Russ Fish committed
60
if (!isset($node_type)) { $node_type = ""; }
61
if (!isset($node_class)) { $node_class = "pc"; }
Russ Fish's avatar
Russ Fish committed
62
if (!isset($attributes)) { $attributes = array(); }
Russ Fish's avatar
Russ Fish committed
63
if (!isset($deletes)) { $deletes = array(); }
64

65 66 67 68 69 70
$emulab_ops = Project::LookupByPid("emulab-ops");
$freebsd_mfs = OSinfo::LookupByName($emulab_ops,"FREEBSD-MFS");
$rhl_std = OSinfo::LookupByName($emulab_ops, "RHL-STD");
$fbsd_std = OSinfo::LookupByName($emulab_ops,"FBSD-STD");
$frisbee_mfs = OSinfo::LookupByName($emulab_ops,"FRISBEE-MFS");

71 72 73
# The default image comes from a site variable to avoid hardwiring here.
$default_imagename = TBGetSiteVar("general/default_imagename");

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
# And is now a comma separated list for multi image load.
$default_imageids = preg_split('/,/', $default_imagename);

for ($i = 0; $i != count($default_imageids); $i++) {
    $image = Image::LookupByName($emulab_ops, $default_imageids[$i]);
    if ($image == null) {
	PAGEERROR("You must add images from Utah into your database" .
		  " before adding a nodetype. ".
		  "See installation documentation for details!",1);
    }
    $default_imageids[$i] = $image->imageid();
}
$default_imagename = join(',', $default_imageids);

if ($freebsd_mfs == null || 
89 90
    $rhl_std == null || $fbsd_std == null || $frisbee_mfs == null) {
    PAGEERROR("You must add images from Utah into your database" .
Leigh Stoller's avatar
Leigh Stoller committed
91 92
              " before adding a nodetype. ".
	      "See installation documentation for details!",1);
93 94
}

95
# This belongs elsewhere!
96 97 98 99 100
$initial_switch_attributes = array(
    array("attrkey" => "imageable", "attrvalue" => "0",
	  "attrtype" => "boolean"),
    array("attrkey" => "rebootable", "attrvalue" => "0",
	  "attrtype" => "boolean"),
101 102
    array("attrkey" => "forwarding_protocols", "attrvalue" => "ethernet",
	  "attrtype" => "string"),
103 104
    );

105
$initial_attributes = array(
106 107
    array("attrkey" => "adminmfs_osid", "attrvalue" => $freebsd_mfs->osid(),
	  "attrtype" => "integer"),
108 109 110 111 112 113 114 115
    array("attrkey" => "bios_waittime", "attrvalue" => "60",
	  "attrtype" => "integer"),
    array("attrkey" => "bootdisk_unit", "attrvalue" => "0",
	  "attrtype" => "integer"),
    array("attrkey" => "control_interface", "attrvalue" => "ethX",
	  "attrtype" => "string"),
    array("attrkey" => "control_network", "attrvalue" => "X",
	  "attrtype" => "integer"),
116
    array("attrkey" => "default_imageid",
117
	  "attrvalue" => $default_imagename,
118
	  "attrtype" => "string"),
119 120
    array("attrkey" => "default_osid", "attrvalue" => $rhl_std->osid(),
	  "attrtype" => "integer"),
121 122
    array("attrkey" => "delay_capacity", "attrvalue" => "2",
	  "attrtype" => "integer"),
123 124 125 126
    array("attrkey" => "delay_osid", "attrvalue" => $fbsd_std->osid(),
	  "attrtype" => "integer"),
    array("attrkey" => "diskloadmfs_osid", "attrvalue" => $frisbee_mfs->osid(),
	  "attrtype" => "integer"),
127 128 129 130 131 132 133 134
    array("attrkey" => "disksize", "attrvalue" => "0.00",
	  "attrtype" => "float"),
    array("attrkey" => "disktype", "attrvalue" => "ad",
	  "attrtype" => "string"),
    array("attrkey" => "frequency", "attrvalue" => "XXX",
	  "attrtype" => "integer"),
    array("attrkey" => "imageable", "attrvalue" => "1",
	  "attrtype" => "boolean"),
135 136
    array("attrkey" => "jail_osid", "attrvalue" =>  $fbsd_std->osid(),
	  "attrtype" => "integer"),
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    array("attrkey" => "max_interfaces", "attrvalue" => "X",
	  "attrtype" => "integer"),
    array("attrkey" => "memory", "attrvalue" => "XXX",
	  "attrtype" => "integer"),
    array("attrkey" => "power_delay", "attrvalue" => "60",
	  "attrtype" => "integer"),
    array("attrkey" => "processor", "attrvalue" => "PIII",
	  "attrtype" => "string"),
    array("attrkey" => "rebootable", "attrvalue" => "1",
	  "attrtype" => "boolean"),
    array("attrkey" => "simnode_capacity", "attrvalue" => "650",
	  "attrtype" => "integer"),
    array("attrkey" => "trivlink_maxspeed", "attrvalue" => "400000",
	  "attrtype" => "integer"),
    array("attrkey" => "virtnode_capacity", "attrvalue" => "20",
	  "attrtype" => "integer"),
    );

155 156 157 158 159 160 161 162 163
$initial_device_attributes = array(
    array("attrkey" => "default_osid", "attrvalue" => $rhl_std->osid(),
	  "attrtype" => "integer"),
    array("attrkey" => "imageable", "attrvalue" => "0",
	  "attrtype" => "boolean"),
    array("attrkey" => "rebootable", "attrvalue" => "0",
	  "attrtype" => "boolean"),
    );

164 165 166
#
# Spit the form out using the array of data.
#
167
function SPITFORM($node_type, $formfields, $attributes, $deletes, $errors)
168
{
169
    global $osid_result, $imageid_result, $mfsosid_result, $new_type;
170
    global $newattribute_name, $newattribute_value, $newattribute_type;
171

172 173 174 175
    #
    # Split default_imageid
    #

176 177 178 179 180 181 182 183 184 185 186 187 188
    if (isset($attributes["default_imageid"])) {
	$default_imageids = preg_split('/,/', $attributes["default_imageid"]);
	for ($i = 0; $i != count($default_imageids); $i++) {
	    $attributes["default_imageid_$i"] = $default_imageids[$i];
	}
	$last_default_imageid_label = "default_imageid_$i";
	$attributes["default_imageid_$i"] = 0;
	unset($attributes["default_imageid"]);
	ksort($attributes);
    } else {
	$attributes["default_imageid_0"] = 0;
	$last_default_imageid_label = "default_imageid_0";
	ksort($attributes);
189 190
    }

191 192 193
    #
    # Standard Testbed Header
    #
194
    if (! isset($new_type)) {
195 196 197 198 199
	PAGEHEADER("Edit Node Type");
    }
    else {
	PAGEHEADER("Create Node Type");
    }
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222

    if ($errors) {
	echo "<table class=nogrid
                     align=center border=0 cellpadding=6 cellspacing=0>
              <tr>
                 <th align=center colspan=2>
                   <font size=+1 color=red>
                      &nbsp;Oops, please fix the following errors!&nbsp;
                   </font>
                 </td>
              </tr>\n";

	while (list ($name, $message) = each ($errors)) {
	    echo "<tr>
                     <td align=right>
                       <font color=red>$name:&nbsp;</font></td>
                     <td align=left>
                       <font color=red>$message</font></td>
                  </tr>\n";
	}
	echo "</table><br>\n";
    }

223 224

    $formargs = "node_type=$node_type";
225
    if (isset($new_type)) {
226 227 228
	$formargs .= "&new_type=1";
    }

229
    echo "<table align=center border=1>
230 231
          <form action=editnodetype.php3?$formargs method=post " .
	  " name=typeform>\n";
232 233

    echo "<tr>
234
              <td colspan=2>Type:</td>\n";
235
    if (isset($new_type)) {
236 237 238 239 240 241 242 243
        echo "<td class=left>
                 <input type=text
                        name=\"node_type\"
                        value=\"" . $node_type . "\"
	                size=10>
             </td>\n";
    } else {
         echo "<td class=left>$node_type</td>
244
          </tr>\n";
245
    }
246 247

    echo "<tr>
248
              <td colspan=2>Class:</td>\n";
249
    if (isset($new_type)) {
250 251 252 253 254 255 256
        echo "<td class=left>
                 <input type=text
                        name=\"formfields[class]\"
                        value=\"" . $formfields['class'] . "\"
	                size=10>
             </td>\n";
    } else {
257
	echo "<td class=left>" . $formfields["class"] . "</td>
258
          </tr>\n";
259
    }
260

261 262 263 264 265 266 267 268 269 270
    echo "<tr>
             <td colspan=2>Architecture:</td>
             <td class=left>
                 <input type=text
                        name=\"formfields[architecture]\"
                        value=\"" . $formfields["architecture"] . "\"
	                size=24>
             </td>
          </tr>\n";

271
    echo "<tr>
272
             <td colspan=2>isvirtnode:</td>
273 274 275
             <td class=left>
                 <input type=text
                        name=\"formfields[isvirtnode]\"
276
                        value=\"" . $formfields["isvirtnode"] . "\"
277 278 279 280
	                size=2>
             </td>
          </tr>\n";

281
    echo "<tr>
282
             <td colspan=2>isjailed:</td>
283 284
             <td class=left>
                 <input type=text
285
                        name=\"formfields[isjailed]\"
286
                        value=\"" . $formfields["isjailed"] . "\"
287 288 289 290 291
	                size=2>
             </td>
          </tr>\n";

    echo "<tr>
292
             <td colspan=2>isdynamic:</td>
293 294 295
             <td class=left>
                 <input type=text
                        name=\"formfields[isdynamic]\"
296
                        value=\"" . $formfields["isdynamic"] . "\"
297 298 299 300
	                size=2>
             </td>
          </tr>\n";

301
    echo "<tr>
302
             <td colspan=2>isremotenode:</td>
303 304 305
             <td class=left>
                 <input type=text
                        name=\"formfields[isremotenode]\"
306
                        value=\"" . $formfields["isremotenode"] . "\"
307 308 309 310 311
	                size=2>
             </td>
          </tr>\n";

    echo "<tr>
312
             <td colspan=2>issubnode:</td>
313 314 315
             <td class=left>
                 <input type=text
                        name=\"formfields[issubnode]\"
316
                        value=\"" . $formfields["issubnode"] . "\"
317 318 319 320 321
	                size=2>
             </td>
          </tr>\n";

    echo "<tr>
322
             <td colspan=2>isplabdslice:</td>
323 324 325
             <td class=left>
                 <input type=text
                        name=\"formfields[isplabdslice]\"
326
                        value=\"" . $formfields["isplabdslice"] . "\"
327 328 329 330 331
	                size=2>
             </td>
          </tr>\n";

    echo "<tr>
332
             <td colspan=2>issimnode:</td>
333 334 335
             <td class=left>
                 <input type=text
                        name=\"formfields[issimnode]\"
336
                        value=\"" . $formfields["issimnode"] . "\"
337 338 339 340
	                size=2>
             </td>
          </tr>\n";

341 342 343 344 345 346 347 348 349 350
    echo "<tr>
             <td colspan=2>isgeninode:</td>
             <td class=left>
                 <input type=text
                        name=\"formfields[isgeninode]\"
                        value=\"" . $formfields["isgeninode"] . "\"
	                size=2>
             </td>
          </tr>\n";

351 352 353 354 355 356 357 358 359 360
    echo "<tr>
             <td colspan=2>isfednode:</td>
             <td class=left>
                 <input type=text
                        name=\"formfields[isfednode]\"
                        value=\"" . $formfields["isfednode"] . "\"
	                size=2>
             </td>
          </tr>\n";

361 362 363 364 365 366 367 368 369 370
    echo "<tr>
             <td colspan=2>isswitch:</td>
             <td class=left>
                 <input type=text
                        name=\"formfields[isswitch]\"
                        value=\"" . $formfields["isswitch"] . "\"
	                size=2>
             </td>
          </tr>\n";

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
    if ($new_type) {
	echo "<tr>
		  <td colspan=2>Restricted?:</td>
		  <td class=left>
		      <input type=checkbox
			     name=\"formfields[restricted]\"
			     value=Yep";

	if (isset($formfields["restricted"]) &&
	    $formfields["restricted"] == "Yep")
	    echo "           checked";
	    
	echo "                       > (Initially restrict nodes to emulab-ops)
		  </td>
	      </tr>\n";
    }
    

389 390 391 392 393 394 395 396 397
    #
    # Now do attributes.
    #
    echo "<tr></tr>
          <tr></tr>
           <td align=center><font size=-1>Delete?</font></td>
           <td align=center colspan=2><b>Node Attributes</b></td></tr>\n";

    while (list ($key, $val) = each ($attributes)) {
398 399 400 401
	if (!isset($deletes[$key])) {
	    # Somehow this doesn't get initialized in the Create Node case.
	    $deletes[$key] = "";
	}
402 403 404 405 406 407
	if ($key == "default_osid" ||
	    $key == "jail_osid" ||
	    $key == "delay_osid") {
	    WRITEOSIDMENU($key, "attributes[$key]", $osid_result, $val,
			  "deletes[$key]", $deletes[$key]);
	}
408 409 410 411 412
	elseif ($key == "adminmfs_osid" ||
		$key == "diskloadmfs_osid") {
	    WRITEOSIDMENU($key, "attributes[$key]", $mfsosid_result, $val,
			  "deletes[$key]", $deletes[$key]);
	}
413 414 415 416 417 418 419
	elseif ($key == $last_default_imageid_label) {
	    WRITEIMAGEIDMENU("$key<sup><b>1</b></sup>", "attributes[$key]", $imageid_result, $val,
			     "deletes[$key]", $deletes[$key]);
	}
	elseif ($key == "default_imageid" || 
    	        substr($key, 0, strlen("default_imageid_")) == "default_imageid_") {
	    WRITEIMAGEIDMENU("$key", "attributes[$key]", $imageid_result, $val,
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
			     "deletes[$key]", $deletes[$key]);
	}
	else {
	    echo "<tr>
                      <td align=center>
                            <input type=checkbox value=checked
                                    name=\"deletes[$key]\" $deletes[$key]></td>
                      <td>${key}:</td>
                      <td class=left>
                          <input type=text
                                 name=\"attributes[$key]\"
                                 value=\"" . $val . "\"></td>
                  </tr>\n";
	}
    }

    #
    # Provide area for adding a new attribute.
    # 
    echo "<tr></tr>
          <tr></tr>
           <td align=center colspan=3><b>Add New Attribute</b></td></tr>\n";

443
    echo "<tr>
444 445 446 447 448 449 450 451 452 453
           <td colspan=2>Attribute Name:</td>
           <td class=left>
               <input type=text name=newattribute_name
                      value=\"$newattribute_name\"></td>
          </tr>\n";
    echo "<tr>
           <td colspan=2>Attribute Value:</td>
           <td class=left>
               <input type=text name=newattribute_value
                      value=\"$newattribute_value\"></td>
454 455
          </tr>\n";

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
    $typenames   = array();
    $typenames[] = "boolean";
    $typenames[] = "integer";
    $typenames[] = "float";
    $typenames[] = "string";
    
    echo "<tr>
           <td colspan=2>Attribute Type:</td>
           <td class=left>\n";

    foreach ($typenames as $i => $type) {
	$checked = "";

	if ($newattribute_type == $type)
	    $checked = "checked";
	
	echo "<input type=radio $checked name=newattribute_type
                     value=$type>$type\n";
    }
    echo "</td></tr>\n";

477
    echo "<tr>
478
              <td colspan=3 align=center>
479 480 481 482 483 484
                 <b><input type=submit name=submit value=Submit></b>
              </td>
          </tr>\n";

    echo "</form>
          </table>\n";
485 486 487 488

    echo "<blockquote>
	      <ol type=1 start=1>
		 <li> To add more than one image, add the first image and 
Grant Ayers's avatar
Grant Ayers committed
489
                      submit the form.  Then add the next, etc.</li>
490 491
              </ol>
              </blockquote>";
492 493
}

494
if (isset($new_type)) {
495
    #
496
    # Starting a new node type - give some reasonable defaults
497
    #
498 499 500
    $defaults = array("class" => $node_class,
                      "architecture" => "",
                      "isvirtnode" => 0,
501 502
		      "isremotenode" => 0, "issubnode" => 0,
		      "isplabdslice" => 0, "isjailed" => 0, "isdynamic" => 0,
503 504 505 506 507
		      "issimnode" => 0, "isgeninode" => 0, "isfednode" => 0,
                      "isswitch" => ($node_class == "switch" ? 1 : 0));
    if ($node_class == "switch") {
        $initial_attributes = $initial_switch_attributes;
    }
508 509 510
    elseif ($node_class == "device") {
        $initial_attributes = $initial_device_attributes;
    }
511 512 513 514 515 516 517 518 519 520
    $default_attributes = array();
    $attribute_types = array();
    $attribute_deletes = array();
    
    foreach ($initial_attributes as $entry) {
	$default_attributes[$entry['attrkey']] = $entry['attrvalue'];
	$attribute_types[$entry['attrkey']] = $entry['attrtype'];
	$attribute_deletes[$entry['attrkey']] = "";
    }
}
521
elseif (isset($node_type)) {
522
    #
523
    # Editing an existing type - suck the current info out of the
524 525 526 527 528 529 530
    # database.
    #
    if (!preg_match("/^[-\w]+$/", $node_type)) {
	USERERROR("$node_type contains illegal characters!", 1);    
    }
    $query_result =
	DBQueryFatal("select * from node_types where type='$node_type'");
531

532 533 534
    if (($defaults = mysql_fetch_array($query_result)) == 0) {
	USERERROR("$node_type is not a valid node type!", 1);
    }
535 536 537 538 539 540 541
    
    #
    # And the attributes ... needed below.
    #
    $default_attributes = array();
    $attribute_types = array();
    $attribute_deletes = array();
542

543 544 545 546 547 548 549 550
    $query_result =
	DBQueryFatal("select * from node_type_attributes ".
		     "where type='$node_type'");
    while ($row = mysql_fetch_array($query_result)) {
	$default_attributes[$row['attrkey']] = $row['attrvalue'];
	$attribute_types[$row['attrkey']] = $row['attrtype'];
	$attribute_deletes[$row['attrkey']] = "";
    }
551
    $attribute_types["default_imageid"] = "string";
552
}
553 554 555 556
else {
    PAGEARGERROR("Must provide one of node_type or new_type");
    return;
}
557

558
#
559
# We need lists of osids and imageids for selection.
560 561
#
$osid_result =
562 563 564 565 566
    DBQueryFatal("select o.osid,o.osname,o.pid from os_info as o ".
		 "left join os_info_versions as v on ".
		 "     v.osid=o.osid and v.vers=o.version ".
		 "where (v.path='' or v.path is NULL) ".
		 "order by o.pid,o.osname");
567

568
$mfsosid_result =
569 570 571 572 573
    DBQueryFatal("select o.osid,o.osname,o.pid from os_info as o ".
		 "left join os_info_versions as v on ".
		 "     v.osid=o.osid and v.vers=o.version ".
		 "where (v.path is not NULL and v.path!='') or v.mfs=1 ".
		 "order by o.pid,o.osname");
574

575 576
$imageid_result =
    DBQueryFatal("select imageid,imagename,pid from images ".
577
		 "order by pid,imagename");
578
 
579 580 581 582
#
# On first load, display initial values.
#
if (! isset($submit)) {
583 584
    SPITFORM($node_type, $defaults,
	     $default_attributes, $attribute_deletes, 0);
585 586 587 588 589 590 591
    PAGEFOOTER();
    return;
}

#
# We do not allow these to be changed.
#
592
if (!isset($new_type)) {
593 594
    $formfields["class"] = $defaults["class"];
}
595 596

#
597
# Otherwise, must validate and redisplay if errors.
598 599 600
#
$errors  = array();

601 602 603 604
#
# Combine imageids into a comma seperated list
#
$default_imagesids = array();
605
$default_imagesid_once_defined = 0;
606 607 608 609 610
for ($i = 0; isset($attributes["default_imageid_$i"]); $i++) {
    if (!(isset($deletes["default_imageid_$i"]) && $deletes["default_imageid_$i"] == "checked")
        && $attributes["default_imageid_$i"] != 0)
        array_push($default_imagesids, $attributes["default_imageid_$i"]);
    unset($attributes["default_imageid_$i"]);
611 612 613 614 615 616 617
    $default_imagesid_once_defined = 1;
}
if (count($default_imagesids) > 0) {
    $attributes["default_imageid"] = join(',', $default_imagesids);
} elseif ($default_imagesid_once_defined) {
    $attributes["default_imageid"] = "0";
    $deletes["default_imageid"] = "checked";
618 619
}

620 621 622 623 624 625 626 627 628
# Check the attributes.
while (list ($key, $val) = each ($attributes)) {
    # Skip checks if scheduled for deletion
    if (isset($deletes[$key]) && $deletes[$key] == "checked") 
	continue;

    if (!isset($attribute_types[$key])) {
	$errors[$key] = "Unknown Attribute";
	continue;
629
    }
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
    
    if ($val == "") {
	$errors[$key] = "No value provided for $key";
	continue;
    }

    # Probably redundant with the XML keyfields checking...
    $attrtype = $attribute_types[$key];
    if ($attrtype == "") {	# Shouldn't happen...
	$attrtype = $attribute_types[$key] = "integer";
    }
    if (strpos(":boolean:float:integer:string:", ":$attrtype:")===FALSE) {
	$errors[$key] = "Invalid type information: $attrtype";
	continue;
    }

    # New attributes require type and value.
    if (isset($newattribute_name) && $newattribute_name != "" &&
	!(isset($newattribute_type) && $newattribute_type != "")) {
	$errors[$newattribute_name] = "Missing type";
    }
    if (isset($newattribute_name) && $newattribute_name != "" &&
	!(isset($newattribute_value) && $newattribute_value != "")) {
	$errors[$newattribute_name] = "Missing value";
654 655 656
    }
}

657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
#
# If any errors, respit the form with the current values and the
# error messages displayed. Iterate until happy.
# 
if (count($errors)) {
    SPITFORM($node_type, $formfields, $attributes, $deletes, $errors);
    PAGEFOOTER();
    return;
}

#
# Build up argument array to pass along.
#
$args = array();

# Class (only for new types.)
if (isset($new_type) &&
    isset($formfields['class']) && $formfields['class'] != "") {
    $args["new_type"] = "1";
    $args["class"] = $formfields["class"];
}

679 680 681 682
if (isset($formfields['architecture'])) {
    $args["architecture"] = $formfields["architecture"];
}

683
# isvirtnode
684
if (isset($formfields["isvirtnode"]) && $formfields["isvirtnode"] != "") {
685
    $args["isvirtnode"] = $formfields["isvirtnode"];
686 687
}

688
# isjailed
689
if (isset($formfields["isjailed"]) && $formfields["isjailed"] != "") {
690
    $args["isjailed"] = $formfields["isjailed"];
691 692 693
}

# isdynamic
694
if (isset($formfields["isdynamic"]) && $formfields["isdynamic"] != "") {
695
    $args["isdynamic"] = $formfields["isdynamic"];
696 697
}

698
# isremotenode
699
if (isset($formfields["isremotenode"]) && $formfields["isremotenode"] != "") {
700
    $args["isremotenode"] = $formfields["isremotenode"];
701 702 703
}

# issubnode
704
if (isset($formfields["issubnode"]) && $formfields["issubnode"] != "") {
705
    $args["issubnode"] = $formfields["issubnode"];
706 707 708
}

# isplabdslice
709
if (isset($formfields["isplabdslice"]) && $formfields["isplabdslice"] != "") {
710
    $args["isplabdslice"] = $formfields["isplabdslice"];
711 712 713
}

# issimnode
714
if (isset($formfields["issimnode"]) && $formfields["issimnode"] != "") {
715
    $args["issimnode"] = $formfields["issimnode"];
716 717
}

718 719 720 721 722
# isgeninode
if (isset($formfields["isgeninode"]) && $formfields["isgeninode"] != "") {
    $args["isgeninode"] = $formfields["isgeninode"];
}

723 724 725 726 727
# isfednode
if (isset($formfields["isfednode"]) && $formfields["isfednode"] != "") {
    $args["isfednode"] = $formfields["isfednode"];
}

728 729 730 731 732
# isswitch
if (isset($formfields["isswitch"]) && $formfields["isswitch"] != "") {
    $args["isswitch"] = $formfields["isswitch"];
}

733 734 735 736 737 738
# Existing attributes.
foreach ($attributes as $attr_key => $attr_val) {
    if (isset($deletes[$attr_key]) && $deletes[$attr_key] == "checked") 
	$args["delete_${attr_key}"] = "1";
    $attr_type = $attribute_types[$attr_key];
    $args["attr_${attr_type}_${attr_key}"] = $attr_val;
739 740 741
}

#
742
# Form allows for adding a single new attribute, but someday be more fancy.
743
#
744 745 746 747 748 749 750 751 752 753
if (isset($newattribute_name) && $newattribute_name != "" &&
    isset($newattribute_value) && $newattribute_value != "" &&
    isset($newattribute_type) && $newattribute_type != "") {

    $args["new_attr"] = $newattribute_name;
    # The following is matched by wildcards on the other side of XML,
    # including checking its type and value, just like existing attributes.
    $args["attr_${newattribute_type}_$newattribute_name"] = $newattribute_value;
}

754 755 756 757 758 759 760 761
# Restricted checkbox.
$restricted = 0;
if (isset($new_type) &&
    isset($formfields['restricted']) && $formfields['restricted'] == "Yep") {
    $restricted = 1;
}

if (! ($result = SetNodeType($node_type, $restricted, $args, $errors))) {
762 763
    # Always respit the form so that the form fields are not lost.
    # I just hate it when that happens so lets not be guilty of it ourselves.
764
    SPITFORM($node_type, $formfields, $attributes, $deletes, $errors);
765 766 767 768
    PAGEFOOTER();
    return;
}

Russ Fish's avatar
Russ Fish committed
769
PAGEHEADER(isset($new_type) ? "Create" : "Edit" . " Node Type");
770

771
#
772 773
# Spit out a redirect so that the history does not include a post
# in it. The back button skips over the post and to the form.
774
#
775
PAGEREPLACE("editnodetype.php3?node_type=$node_type");
776

777 778 779 780
#
# Standard Testbed Footer
# 
PAGEFOOTER();
781

782
#
783
# Create or edit a nodetype.  (No class for that at present.)
784
#
785
function SetNodeType($node_type, $restricted, $args, &$errors) {
786
    global $suexec_output, $suexec_output_array;
787

788 789 790 791 792 793 794 795
    #
    # Generate a temporary file and write in the XML goo.
    #
    $xmlname = tempnam("/tmp", "editnodetype");
    if (! $xmlname) {
	TBERROR("Could not create temporary filename", 0);
	$errors[] = "Transient error(1); please try again later.";
	return null;
796
    }
797 798 799 800
    if (! ($fp = fopen($xmlname, "w"))) {
	TBERROR("Could not open temp file $xmlname", 0);
	$errors[] = "Transient error(2); please try again later.";
	return null;
801
    }
802 803 804 805 806 807 808 809 810 811 812 813 814 815

    # Add these. Maybe caller should do this?
    $args["node_type"] = $node_type;
    
    fwrite($fp, "<nodetype>\n");
    foreach ($args as $name => $value) {
	fwrite($fp, "<attribute name=\"$name\">");
	fwrite($fp, "  <value>" . htmlspecialchars($value) . "</value>");
	fwrite($fp, "</attribute>\n");
    }
    fwrite($fp, "</nodetype>\n");
    fclose($fp);
    chmod($xmlname, 0666);

816 817 818 819
    # Restricted checkbox.
    $optarg = ($restricted ? "-p" : "");

    $retval = SUEXEC("nobody", "nobody", "webeditnodetype $optarg $xmlname",
820 821 822 823
		     SUEXEC_ACTION_IGNORE);

    if ($retval) {
	if ($retval < 0) {
824
	    $errors[] = "Transient error(3, $retval); please try again later.";
825
	    SUEXECERROR(SUEXEC_ACTION_CONTINUE);
826 827
	}
	else {
828 829 830 831 832 833 834 835 836 837 838 839 840
	    # unlink($xmlname);
	    if (count($suexec_output_array)) {
		for ($i = 0; $i < count($suexec_output_array); $i++) {
		    $line = $suexec_output_array[$i];
		    if (preg_match("/^([-\w]+):\s*(.*)$/",
				   $line, $matches)) {
			$errors[$matches[1]] = $matches[2];
		    }
		    else
			$errors[] = $line;
		}
	    }
	    else
841
		$errors[] = "Transient error(4, $retval); please try again later.";
842
	}
843
	return null;
844
    }
845
    # There are no return value(s) to parse at the end of the output.
846

847 848
    # Unlink this here, so that the file is left behind in case of error.
    # We can then create the nodetype by hand from the xmlfile, if desired.
Leigh Stoller's avatar
Leigh Stoller committed
849
    unlink($xmlname);
850 851
    return true;
}
852 853

?>