newimageid_ez.php3 43.2 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
#
3
# Copyright (c) 2000-2015 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/>.
# 
# }}}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
23
#
24
include("defs.php3");
25 26
include_once("imageid_defs.php");
include_once("osinfo_defs.php");
27
include_once("node_defs.php");
28
include_once("osiddefs.php3");
29

30 31
#
# XXX
32 33
# In this form, we make the images:imagename and the os_info:osname the same!
# Currently, TBDB_OSID_OSNAMELEN is shorter than TBDB_IMAGEID_IMAGENAMELEN
34
# and that causes problems since we use the same id for both tables. For
35
# now, test for the shorter of the two.
36
# 
37 38 39 40 41 42 43 44 45 46 47 48
#
# Only known and logged in users.
#
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$dbid      = $this_user->dbid();
$isadmin   = ISADMIN();

#
# Verify page arguments.
#
$optargs = OptionalPageArguments("submit",       PAGEARG_STRING,
49
				 "imagetype",    PAGEARG_STRING,
50 51
				 "canceled",     PAGEARG_BOOLEAN,
				 "confirmed",    PAGEARG_BOOLEAN,
52
				 "ec2",		 PAGEARG_BOOLEAN,
53 54 55
				 "node",	 PAGEARG_NODE,
				 "baseimage",    PAGEARG_IMAGE,
				 "baseosinfo",   PAGEARG_OSINFO,
56
				 "formfields",   PAGEARG_ARRAY);
57

58 59 60 61 62
# Flag to import an EC2 image.
if (!isset($ec2)) {
    $ec2 = 0;
}

63 64 65 66 67 68 69 70 71 72
#
# If starting from a specific node we can derive the type and possibly
# the baseimage from it. 
#
if (isset($node)) {
    #
    # If we can find the running osid, then we can setup the page instead
    # of having the user figure it out. Note that only makes sense for
    # EZ images.
    #
73
    $baseimage = $node->def_boot_image();
74 75 76 77
    #
    # Try for at least an osinfo if no image.
    #
    if (! $baseimage) {
78
	$baseosinfo = $node->def_boot_osinfo();
79
    }
80
    else {
81
	$baseosinfo = $baseimage->OSinfo();
82
    }
83 84
}
elseif (isset($baseimage)) {
85
    $baseosinfo = $baseimage->OSinfo();
86
}
87
elseif ($ec2) {
88 89 90 91 92 93 94 95
    $imagetype = "xen";
}
if (isset($baseosinfo) && $baseosinfo->def_parentosid()) {
    $def_parentosinfo = OSinfo::Lookup($baseosinfo->def_parentosid());
    if (! $def_parentosinfo) {
	TBERROR("Could not lookup osinfo object for parent " .
		$baseosinfo->def_parentosid(), 1);
    }
96
}
97

98
#
99 100
# Try to determine what kind of image so we can tailor the form
# a little bit for openvz and xen.
101
#
102 103 104
if (!isset($imagetype) && isset($def_parentosinfo)) {
    if ($def_parentosinfo->FeatureSupported("xen-host")) {
	$imagetype = "xen";
105
    }
106
    else {
107
	$imagetype = "openvz";
108
    }
109 110 111 112 113 114 115 116 117 118 119
}
$title  = "EZ Form";

#
# Options for using this page with different types of nodes.
#
if (!isset($imagetype)) {
    #
    # Generic PC image.
    #
    $view  = array('hide_upload' => 1);
120 121
    $help_message = 
          "See the
122
          <a href=$WIKIDOCURL/Tutorial#CustomOS>
123
          tutorial</a> for more info on creating/using custom Images.";
124 125
    # Default to imagezip ndz files
    $filename_extension = "ndz";
126
}
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
else {
    $view = array('hide_partition' => 1,
		  'hide_upload' => 1);
    
    if ($imagetype == "openvz") {
	$title = "OpenVZ Form";

	$view['hide_mbr']        = 1;
	$view['hide_concurrent'] = 1;
	$view['hide_footnotes']  = 1;
	$view['hide_wholedisk']  = 1;
    }
    # Default to imagezip ndz files
    $filename_extension = "ndz";
}

143 144 145 146 147 148
#
# If we are lucky enough to get a baseimage, do not show footnotes.
#
if (isset($baseimage)) {
    $view['hide_footnotes'] = 1;
}
149

150 151 152
#
# Standard Testbed Header
#
153
PAGEHEADER("Create a new Image Descriptor ($title)");
154 155 156 157

#
# See what projects the uid can do this in.
#
158
$projlist = $this_user->ProjectAccessList($TB_PROJECT_MAKEIMAGEID);
159 160 161 162 163 164 165

if (! count($projlist)) {
    USERERROR("You do not appear to be a member of any Projects in which ".
	      "you have permission to create new Image descriptors.", 1);
}

#
166
# Need a list of node types. We join this over the nodes table so that
167
# we get a list of just the nodes that are currently in the testbed, not
168
# just in the node_types table. Limit by class if given.
169
#
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
$types_list = array();

if (isset($imagetype) && $imagetype == "openvz") {
    $types_list['pcvm'] = 1;
}
else {
    $types_result =
	DBQueryFatal("select distinct n.type from nodes as n ".
		     "left join node_types as nt on n.type=nt.type ".
		     "left join node_type_attributes as a on a.type=n.type ".
		     "where a.attrkey='imageable' and nt.class='pc' and ".
		     "      a.attrvalue!='0' and n.role='testnode'");

    while ($row = mysql_fetch_array($types_result)) {
        $types_list[$row["type"]] = 1;
185
    }
186 187
    if (isset($imagetype) && $imagetype == "xen") {
	$types_list['pcvm'] = 1;
188
    }
189 190
}

191
#
192 193
# Spit the form out using the array of data.
#
194 195
function SPITFORM($formfields, $errors)
{
196 197 198
    global $projlist, $isadmin, $types_list, $osid_oslist, $osid_opmodes,
	$osid_featurelist, $filename_extension, $help_message, $askxen;
    global $node;
199
    global $TBDB_OSID_OSNAMELEN, $TBDB_NODEIDLEN;
200
    global $TBDB_OSID_VERSLEN, $TBBASE, $TBPROJ_DIR, $TBGROUP_DIR;
201
    global $WIKIDOCURL;
202
    global $view, $ec2, $baseimage;
203
    
204 205 206
    #
    # Explanation of the $view argument: used to turn on and off display of
    # various parts of the form, so that it can be used for different types
207
    # of nodes. It's an associative array, with contents like:'hide_partition'.
208 209 210
    # In general, when an option is hidden, it is replaced with a hidden
    # field from $formfields
    #
211 212 213
    if ($help_message) {
        echo "<center><b>$help_message</b></center>\n";
    }
214 215 216 217 218 219 220

    if ($isadmin) {
	echo "<center>
               Administrators get to use the
               <a href='newimageid.php3'>long form</a>.
              </center>\n";
    }
221 222
    
    if ($errors) {
223 224
	echo "<table class=nogrid
                     align=center border=0 cellpadding=6 cellspacing=0>
225
              <tr>
226
                 <th align=center colspan=2>
227
                   <font size=+1 color=red>
228
                      &nbsp;Oops, please fix the following errors!&nbsp;
229 230 231 232 233
                   </font>
                 </td>
              </tr>\n";

	while (list ($name, $message) = each ($errors)) {
234 235
            # XSS prevention.
	    $message = CleanString($message);
236
	    echo "<tr>
237 238 239 240
                     <td align=right>
                       <font color=red>$name:&nbsp;</font></td>
                     <td align=left>
                       <font color=red>$message</font></td>
241 242 243 244
                  </tr>\n";
	}
	echo "</table><br>\n";
    }
245 246 247 248
    # XSS prevention.
    while (list ($key, $val) = each ($formfields)) {
	$formfields[$key] = CleanString($val);
    }
249 250 251 252

    echo "<SCRIPT LANGUAGE=JavaScript>
              function SetPrefix(theform) 
              {
253 254 255 256
                  var pidx   = theform['formfields[pid]'].selectedIndex;
                  var pid    = theform['formfields[pid]'].options[pidx].value;
                  var gidx   = theform['formfields[gid]'].selectedIndex;
                  var gid    = theform['formfields[gid]'].options[gidx].value;
257
                  var shared = theform['formfields[shared]'].checked;
258 259 260 261 262 263 264
          \n";
    if ($isadmin)
	echo     "var global = theform['formfields[global]'].checked;";
    else
	echo     "var global = 0;";

    echo         "if (pid == '') {
265
                      theform['formfields[path]'].value = '$TBPROJ_DIR';
266 267 268
                  }
                  else if (theform['formfields[imagename]'].value == '') {
		      theform['formfields[imagename]'].defaultValue = '';
269 270 271 272 273 274 275

                      if (global) {
    	                  theform['formfields[path]'].value =
                                  '/usr/testbed/images/';
                      }
		      else if (gid == '' || gid == pid || shared) {
    	                  theform['formfields[path]'].value =
276
                                  '$TBPROJ_DIR/' + pid + '/images/';
277 278 279
                      }
                      else {
    	                  theform['formfields[path]'].value =
280
                                  '$TBGROUP_DIR/' + pid + '/' + gid + '/images/';
281
                      }
282 283
                  }
                  else if (theform['formfields[imagename]'].value != '') {
284 285
                      var filename =
                           theform['formfields[imagename]'].value + '/';
286 287 288 289 290 291 292

                      if (global) {
    	                  theform['formfields[path]'].value =
                                  '/usr/testbed/images/' + filename;
                      }
		      else if (gid == '' || gid == pid || shared) {
    	                  theform['formfields[path]'].value =
293
                                  '$TBPROJ_DIR/' + pid + '/images/' + filename;
294 295 296
                      }
                      else {
    	                  theform['formfields[path]'].value =
297
                                  '$TBGROUP_DIR/' + pid + '/' + gid + '/images/' +
298 299
                                  filename;
                      }
300 301 302 303 304 305 306 307 308 309 310
                  }
              }
          </SCRIPT>\n";

    echo "<br>
          <table align=center border=1> 
          <tr>
             <td align=center colspan=2>
                 <em>(Fields marked with * are required)</em>
             </td>
          </tr>
311 312 313
          <form action='newimageid_ez.php3' enctype=\"multipart/form-data\"
              method=post name=idform>\n";

314
    # Carry along stuff ...
315 316 317 318
    if (isset($node)) {
	$id = $node->node_id();
	echo "<input type=hidden name=node_id value='$id'>";
    }
319 320 321
    if ($ec2) {
	echo "<input type=hidden name=ec2 value=true>";
    }
322 323 324 325 326 327
    if (isset($baseimage)) {
        $id = $baseimage->imageid();
	$version = $baseimage->version();
	echo "<input type=hidden name=baseimage value='$id'>";
	echo "<input type=hidden name=version value='$version'>";
    }
328 329 330 331 332 333 334 335 336 337 338 339
    #
    # Select Project
    #
    echo "<tr>
              <td>*Select Project:</td>
              <td><select name=\"formfields[pid]\"
                          onChange='SetPrefix(idform);'>
                      <option value=''>Please Select &nbsp</option>\n";
    
    while (list($project) = each($projlist)) {
	$selected = "";

340
	if ($formfields["pid"] == $project)
341 342 343 344 345 346 347 348
	    $selected = "selected";
	
	echo "        <option $selected value='$project'>$project </option>\n";
    }
    echo "       </select>";
    echo "    </td>
          </tr>\n";

349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    #
    # Select a group
    # 
    echo "<tr>
              <td >Group:</td>
              <td><select name=\"formfields[gid]\"
                          onChange='SetPrefix(idform);'>
                    <option value=''>Default Group </option>\n";

    reset($projlist);
    while (list($project, $grouplist) = each($projlist)) {
	for ($i = 0; $i < count($grouplist); $i++) {
	    $group    = $grouplist[$i];

	    if (strcmp($project, $group)) {
		$selected = "";

366 367 368 369
		if (isset($formfields["gid"]) &&
		    isset($formfields["pid"]) &&
		    strcmp($formfields["pid"], $project) == 0 &&
		    strcmp($formfields["gid"], $group) == 0)
370 371 372 373 374 375 376 377 378 379 380
		    $selected = "selected";
		
		echo "<option $selected value=\"$group\">
                           $project/$group</option>\n";
	    }
	}
    }
    echo "     </select>
             </td>
          </tr>\n";

381
    #
382
    # Image Name
383 384 385 386 387 388 389
    #
    echo "<tr>
              <td>*Descriptor Name (no blanks):</td>
              <td class=left>
                  <input type=text
                         onChange='SetPrefix(idform);'
                         name=\"formfields[imagename]\"
390
                         value=\"" . $formfields["imagename"] . "\"
391 392
	                 size=$TBDB_OSID_OSNAMELEN
                         maxlength=$TBDB_OSID_OSNAMELEN>
393 394 395 396 397 398 399 400 401 402 403 404
              </td>
          </tr>\n";

    #
    # Description
    #
    echo "<tr>
              <td>*Description:<br>
                  (a short pithy sentence)</td>
              <td class=left>
                  <input type=text
                         name=\"formfields[description]\"
405
                         value=\"" . $formfields["description"] . "\"
406 407 408 409 410 411 412
	                 size=50>
              </td>
          </tr>\n";

    #
    # Load Partition
    #
413
    if (isset($view["hide_partition"])) {
414 415 416 417 418 419 420
	spithidden($formfields, 'loadpart');
    } else {
	echo "<tr>
		  <td>*Which DOS Partition[<b>1</b>]:<br>
		      (DOS partitions are numbered 1-4)</td>
		  <td><select name=\"formfields[loadpart]\">
			      <option value=X>Please Select </option>\n";
421

422 423
	for ($i = 1; $i <= 4; $i++) {
	    $selected = "";
424

425
	    if (strcmp($formfields["loadpart"], "$i") == 0)
426
		$selected = "selected";
Russ Fish's avatar
Russ Fish committed
427

428 429 430 431 432
	    echo "        <option $selected value=$i>$i </option>\n";
	}
	echo "       </select>";
	echo "    </td>
	      </tr>\n";
433 434 435 436 437
    }

    #
    # Select an OS
    # 
438
    if (isset($view["hide_os"])) {
439
	spithidden($formfields, 'OS');
440 441 442 443
    } else {
	echo "<tr>
		 <td>*Operating System:<br>
		    (OS that is on the partition)</td>
444
		 <td><select name=\"formfields[OS]\">
445
		       <option value=none>Please Select </option>\n";
446

447 448
	while (list ($os, $userokay) = each($osid_oslist)) {
	    $selected = "";
449

450 451
	    if (!$userokay && !$isadmin)
		continue;
452

453 454
	    if (isset($formfields["OS"]) &&
		strcmp($formfields["OS"], $os) == 0)
455
		$selected = "selected";
456

457
	    echo "<option $selected value=$os>$os &nbsp; </option>\n";
458 459 460 461
	}
	echo "       </select>
		 </td>
	      </tr>\n";
462 463 464 465 466
    }

    #
    # Version String
    #
467
    if (isset($view["hide_version"])) {
468
	spithidden($formfields, 'version');
469 470 471 472 473 474
    } else {
	echo "<tr>
		  <td>*OS Version:<br>
		      (eg: 4.3, 7.2, etc.)</td>
		  <td class=left>
		      <input type=text
475 476
			     name=\"formfields[version]\"
			     value=\"" . $formfields["version"] . "\"
477 478 479 480 481
			     size=$TBDB_OSID_VERSLEN
			     maxlength=$TBDB_OSID_VERSLEN>
		  </td>
	      </tr>\n";
    }
482 483 484 485

    #
    # Path to image.
    #
486 487
    $style = ($isadmin ? "" : "style='display:none;'");
    echo "<tr $style>
488
              <td>Directory for Image:<br>
489
                  (must reside in $TBPROJ_DIR)</td>
490 491 492
              <td class=left>
                  <input type=text
                         name=\"formfields[path]\"
493
                         value=\"" . $formfields["path"] . "\"
494 495 496 497
	                 size=50>
              </td>
          </tr>\n";

498
    #
Chad Barb's avatar
Chad Barb committed
499
    # Node to Snapshot image from.
500
    #
501 502 503 504 505 506 507 508 509 510 511 512
    if ($ec2) {
	echo "<tr>
		  <td>EC2 User@Node Info:</td>
		  <td class=left>
		      <input type=text
			     name=\"formfields[ec2_info]\"
			     value=\"" . $formfields["ec2_info"] . "\"
			     size=64>
		  </td>
	      </tr>\n";
    }
    elseif (isset($view["hide_snapshot"])) {
513 514 515 516 517 518
	spithidden($formfields, 'node');
    } else {
	echo "<tr>
		  <td>Node to Obtain Snapshot from[<b>2</b>]:</td>
		  <td class=left>
		      <input type=text
519 520
			     name=\"formfields[node_id]\"
			     value=\"" . $formfields["node_id"] . "\"
521 522 523 524
			     size=$TBDB_NODEIDLEN maxlength=$TBDB_NODEIDLEN>
		  </td>
	      </tr>\n";
    }
525
    
526

527 528 529
    #
    # OS Features.
    # 
530
    if (isset($view["hide_features"])) {
531 532 533 534 535 536 537 538
        reset($osid_featurelist);
        while (list ($feature, $userokay) = each($osid_featurelist)) {
            spithidden($formfields, "os_feature_$feature");
        }
    } else {
	echo "<tr>
		  <td>OS Features[<b>3</b>]:</td>
		  <td>";
539

540 541 542 543 544 545
	reset($osid_featurelist);
	while (list ($feature, $userokay) = each($osid_featurelist)) {
	    $checked = "";
	    
	    if (!$userokay && !$isadmin)
		continue;
546

547 548 549
	    if (isset($formfields["os_feature_$feature"]) &&
		! strcmp($formfields["os_feature_$feature"], "checked"))
		$checked = "checked";
550

551 552 553 554 555 556
	    echo "<input $checked type=checkbox value=checked
			 name=\"formfields[os_feature_$feature]\">
		       $feature &nbsp\n";
	}
	echo "    </td>
	      </tr>\n";
557 558
    }

559 560 561
    #
    # Operational Mode
    # 
562
    if (isset($view["hide_opmode"])) {
563 564 565 566 567 568
	spithidden($formfields, 'op_mode');
    } else {
	echo "<tr>
		 <td>*Operational Mode[<b>4</b>]:</td>
		 <td><select name=\"formfields[op_mode]\">
		       <option value=none>Please Select </option>\n";
569

570 571
	while (list ($mode, $userokay) = each($osid_opmodes)) {
	    $selected = "";
572

573 574
	    if (!$userokay && !$isadmin)
		continue;
575

576 577
	    if (isset($formfields["op_mode"]) &&
		strcmp($formfields["op_mode"], $mode) == 0)
578
		$selected = "selected";
579

580
	    echo "<option $selected value=$mode>$mode &nbsp; </option>\n";
581 582 583 584
	}
	echo "       </select>
		 </td>
	      </tr>\n";
585 586
    }

587 588 589
    #
    # Node Types.
    #
590
    if (!isset($view["hide_footnotes"])) {
591
	$footnote = "[<b>5</b>]";
592 593
    } else {
	$footnote = "";
594
    }
595
    echo "<tr>
596
              <td>Node Types${footnote}:</td>
597 598
              <td>\n";

599
    foreach ($types_list as $type => $value) {
600 601
        $checked = "";

602 603 604 605
        if ((isset($formfields["mtype_$type"]) &&
	     $formfields["mtype_$type"] == "Yep") ||
	    (isset($formfields["mtype_all"]) &&
	     $formfields["mtype_all"] == "Yep")) {
606
	    $checked = "checked";
607
	}
608 609 610 611 612 613 614 615 616
    
        echo "<input $checked type=checkbox
                     value=Yep name=\"formfields[mtype_$type]\">
                     $type &nbsp
              </input>\n";
    }
    echo "    </td>
          </tr>\n";

617 618 619
    #
    # Whole Disk Image
    #
620
    if (isset($view["hide_wholedisk"]) && $view["hide_wholedisk"]) {
621 622 623 624 625 626 627 628 629
	spithidden($formfields, 'wholedisk');
    } else {
	echo "<tr>
		  <td>Whole Disk Image?[<b>6</b>]:</td>
		  <td class=left>
		      <input type=checkbox
			     name=\"formfields[wholedisk]\"
			     value=Yep";

630 631
	if (isset($formfields["wholedisk"]) &&
	    strcmp($formfields["wholedisk"], "Yep") == 0)
632 633 634 635 636 637
	    echo "           checked";
	    
	echo "                       > Yes
		  </td>
	      </tr>\n";
    }
638 639 640 641

    #
    # Maxiumum concurrent loads
    #
642
    if (isset($view["hide_concurrent"])) {
643 644 645 646 647 648 649
	spithidden($formfields, 'max_concurrent');
    } else {
	echo "<tr>
		  <td>Maximum concurrent loads[<b>7</b>]:</td>
		  <td class=left>
		      <input type=text
			     name=\"formfields[max_concurrent]\"
650
			     value=\"" . $formfields["max_concurrent"] . "\"
651 652 653
			     size=4 maxlength=4>
		  </td>
	      </tr>\n";
654

655
    }
656

657 658 659 660
    if (isset($view["hide_mbr"])) {
	spithidden($formfields, 'mbr_version');
    }
    else {
661 662 663 664 665 666 667 668 669 670 671
	echo "<tr>
	          <td>MBR Version:<br>
		  <td class=left>
		      <input type=text
			     name=\"formfields[mbr_version]\"
			     value=\"" . $formfields["mbr_version"] . "\"
			     size= maxlength=2>
		  </td>
	      </tr>\n";
    }

672 673 674
    #
    # Shared?
    #
675
    if (isset($view["hide_snapshot"])) {
676 677 678 679 680 681 682 683 684 685 686
	spithidden($formfields, 'shared');
    } else {
	echo "<tr>
		  <td>Shared?:<br>
		      (available to all subgroups)</td>
		  <td class=left>
		      <input type=checkbox
			     onClick='SetPrefix(idform);'
			     name=\"formfields[shared]\"
			     value=Yep";

687 688
	if (isset($formfields["shared"]) &&
	    strcmp($formfields["shared"], "Yep") == 0)
689 690 691 692 693 694 695 696 697 698
	    echo "           checked";
	    
	echo "                       > Yes
		  </td>
	      </tr>\n";
    }

    #
    # Upload an image file
    #
699 700 701 702
    if (isset($view["hide_upload"])) {
	;
    }
    else {
703 704 705 706 707 708 709 710 711
	echo "<tr>
		  <td>Upload a file:</td>
		  <td class=left>
		      <input type=file
			     name=\"upload_file\"
			     value=''
			     size=35></tr>";

    }
712

713 714
    if ($isadmin) {
        #
715
        # Global?
716 717
        #
	echo "<tr>
718
  	          <td>Global?:<br>
719 720 721
                      (available to all projects)</td>
                  <td class=left>
                      <input type=checkbox
722 723
                             onClick='SetPrefix(idform);'
                             name=\"formfields[global]\"
724 725
                             value=Yep";

726 727
	if (isset($formfields["global"]) &&
	    strcmp($formfields["global"], "Yep") == 0)
728 729 730 731 732 733
	    echo "           checked";
	
	echo "                       > Yes
                  </td>
              </tr>\n";
    }
734 735 736
    #
    # Reboot waittime. 
    # 
737 738 739 740 741
    if (!isset($view["hide_footnotes"])) {
	$footnote = "[<b>8</b>]";
    } else {
	$footnote = "";
    }
742
    echo "<tr>
743
	      <td>Reboot Waittime (seconds)${footnote}:</td>
744 745 746 747 748 749 750
	      <td class=left>
		  <input type=text
		         name=\"formfields[reboot_waittime]\"
			 value=\"" . $formfields["reboot_waittime"] . "\"
			 size=4 maxlength=4>
   	      </td>
	  </tr>\n";
751

752 753 754 755 756 757 758 759 760 761 762 763 764
    if (isset($formfields["def_parentosid"]) &&
	$formfields["def_parentosid"] != "") {
	$osinfo = OSInfo::Lookup($formfields["def_parentosid"]);
	$osname = $osinfo->osname();
	$url    = CreateURL("showosinfo", $osinfo);

	echo "<tr>
	          <td>Parent OS:</td> 
		  <input type=hidden
		         name=\"formfields[def_parentosid]\"
			 value=\"" . $formfields["def_parentosid"] . "\">
  	          <td class=left><a href='$url'>$osname</a></td>
	  </tr>\n";
765

766 767 768 769 770 771 772 773 774 775 776
	if ($ec2) {
	    echo "<tr>
	  	    <td>Package:</td>
		    <td class=left>
		        <input type=checkbox
		  	       name=\"formfields[package]\"
			       value=Yep";

	    if (isset($formfields["package"]) &&
		strcmp($formfields["package"], "Yep") == 0)
		echo "           checked";
777
	    
778
	    echo "         > Yes (XEN only, and only if you know what this means!)
779 780
		  </td>
	      </tr>\n";
781
	}
782 783
    }

784 785 786 787 788 789 790 791 792
    echo "<tr>
              <td align=center colspan=2>
                  <b><input type=submit name=submit value=Submit></b>
              </td>
          </tr>\n";

    echo "</form>
          </table>\n";

793 794 795 796 797 798
    if (isset($view["hide_footnotes"])) {
	echo "<center><blockquote>
	      <b>In general, you should leave the default settings alone!</b>
              </blockquote></center>\n";
    }
    else {
799
	echo "<blockquote>
800 801 802 803 804
	      <ol type=1 start=1>
		 <li> If you don't know what partition you have customized,
		      here are some guidelines:
		     <ul>
			<li> if you customized one of our standard Linux
805 806
                             (RHL*) or Fedora images (FC*) then it is
                             partition 2.
807 808
			</li>
			<li> if you customized one of our standard BSD
809
			     images (FBSD*) then it is partition 1.
810
			</li>
Russ Fish's avatar
Russ Fish committed
811
			<li> if you customized one of our standard Windows XP
812 813 814
			     images then it is partition 1, and make sure
                             you check the <em>Whole Disk Image</em> box.
			</li>
815 816 817 818 819 820 821 822 823 824 825 826 827 828
			<li> otherwise, feel free to ask us!
			</li>
		     </ul>
		 </li>
		 <li> If you already have a node customized, enter that node
		      name (pcXXX) and a snapshot will automatically be made of
		      its disk contents into the specified Image File. 
		      Notification of completion will be sent to you via email. 
		 </li>
		 <li> Guidelines for setting OS features for your OS:
		      (Most images should mark all four of these.)
		    <ul>
		      <li> Mark ping and/or ssh if they are supported. 
		      </li>
829 830 831
		      <li> If you use one of our standard Linux, Fedora or
                           FreeBSD kernels, or started from our kernel
                           configs, mark ipod.
Russ Fish's avatar
Russ Fish committed
832
			   ipod is not supported on Windows XP.
833
		      </li>
834
		      <li> If it is based on one of our standard Linux, Fedora,
Russ Fish's avatar
Russ Fish committed
835
			   FreeBSD, or Windows XP images (or otherwise
836
			   sends its own ISUP notification), mark isup.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
837
                      </li>
838
		      <li> If it is based on one of our standard Linux, Fedora,
Leigh B. Stoller's avatar
Leigh B. Stoller committed
839
			   FreeBSD, or Windows XP images, mark linktest.
840
		      </li>
841 842 843 844 845 846
		      <li> If it is based on an image with
			   <a href=$WIKIDOCURL/EmulabStorage#section-9>
			   blockstore support</a>, then mark the loc-bstore
			   and/or rem-bstore checkboxes (indicating local
			   and remote blockstore support, respectively).
		      </li>
847 848 849 850 851 852
		    </ul>
		 </li>
		 <li> Guidelines for setting Operational Mode for your OS:
		      (Most images should use " . TBDB_DEFAULT_OSID_OPMODE . ")
		    <ul>
		      <li> If it is based on a testbed image (one of our
853 854 855
			   Linux, Fedora, FreeBSD, or Windows XP images)
                           use the same op_mode as that image.
                           Select it from the
856 857 858 859 860 861 862 863 864
			   <a href=\"$TBBASE/showosid_list.php3\"
			   >OS Descriptor List</a> to find out).
		      </li>
		      <li> If not, use MINIMAL. 
		      </li>
		    </ul>
		 </li>
		 <li> Specify the node types that this image will be able
		      to work on (can be loaded on and expected to work).
865 866 867 868 869 870 871 872 873 874 875 876
		      Typically, images of newer OS versions will work on all
		      of the \"pc\" types.  However, older versions of OSes
		      may only work on the older hardware types (pc600, pc850,
		      pc2000).  To make this type selection process easier,
		      when you take a snapshot of an existing node that you
		      have customized (see 2. above), the system will restrict
		      the types to those allowed for the \"base\" image (the
		      one originally loaded, that you have customized).  If
		      you need to override this restriction and add a type
		      that is not allowed in the current image, you will have
		      to contact us.  If you have any questions, free to ask
		      us!
877 878 879 880 881 882 883 884
		 </li>
		 <li> If you need to snapshot the entire disk (including the MBR),
		      check this option. <b>Most users will not need to check this
		      option. Please ask us first to make sure</b>.
		 </li>
		 <li> If your image contains software that is only licensed to run
		      on a limited number of nodes at a time, you can put this
		      number here. Most users will want to leave this option blank.
885 886 887 888 889
                 </li>
		 <li> Leave this field <b>blank</b> unless you know what you
                      are doing, or you have an explicit problem with images
                      taking too long to boot. <b>Please talk to us first!</b>
                 </li>
890
	      </ol>
891
	      </blockquote>\n";
892 893 894 895 896 897 898 899 900 901 902 903
    }
}

#
# If the given field is defined in the given set of fields, spit out a hidden
# form element for it
#
function spithidden($formfields, $field) {
    if (isset($formfields[$field])) {
	echo "<input type=hidden name=formfields[$field] value='" .
	     $formfields[$field] . "'>\n";
    }
904 905 906 907 908
}

#
# On first load, display a virgin form and exit.
#
909
if (!isset($submit)) {
910
    $defaults = array();
911 912 913 914 915
    $defaults["pid"]		 = "";
    $defaults["gid"]		 = "";
    $defaults["imagename"]	 = "";
    $defaults["description"]	 = "";
    $defaults["path"]		 = "$TBPROJ_DIR/";
916
    $defaults["node_id"]	 = (isset($node) ? $node->node_id() : "");
917 918 919
    $defaults["max_concurrent"]	 = "";
    $defaults["shared"]		 = "No";
    $defaults["global"]		 = "No";
920 921 922
    $defaults["OS"]	 	 = "";
    $defaults["version"]	 = "";
    $defaults["wholedisk"]	 = "No";
923
    $defaults["reboot_waittime"] = "";
924
    $defaults["mbr_version"]     = "";
925
    $defaults["noexport"]        = "No";
926

927 928 929 930
    #
    # Use the base image to seed the form.
    #
    if (isset($baseimage)) {
931
	$baseosinfo = $baseimage->OSinfo();
932 933 934 935 936 937
	if (! $baseosinfo) {
	    TBERROR("Could not lookup osinfo object for image " .
		    $baseimage->imageid(), 1);
	}
	$defaults["loadpart"]    = $baseimage->loadpart();
	if ($baseimage->loadpart() == 0 && $baseimage->loadlength() == 4) {
938 939
	    $loadpart = ($baseimage->part1_osid() ? 1 : 2);
	    $defaults["loadpart"]    = $loadpart;
940 941 942
	    $defaults["wholedisk"]   = "Yep";
	}
	$defaults["mbr_version"]     = $baseimage->mbr_version();
943
	$defaults["noexport"]        = ($baseimage->noexport() ? "Yes" : "No");
944 945 946 947 948 949 950
	#
	# Same types as the parent.
	#
	foreach ($baseimage->Types() as $type) {
	    $defaults["mtype_${type}"] = "Yep";
	}
    }
951
    elseif (isset($imagetype) && $imagetype == "openvz") {
952 953
	$defaults["loadpart"]    = "1";
	$defaults["wholedisk"]   = "Yep";
954
	$defaults["mtype_pcvm"]  = "Yep";
955
    }
956
    else {
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
	# Defaults for PC-type nodes
	$defaults["loadpart"] = "X";
	# mtype_all is a "fake" variable which makes all
	# mtypes checked in the virgin form.
	$defaults["mtype_all"] = "Yep";
    }
    
    if (isset($baseosinfo)) {
	#
	# Same features as the parent.
	#
	if ($baseosinfo->osfeatures()) {
	    foreach (preg_split("/,/", $baseosinfo->osfeatures()) as $feature) {
		$defaults["os_feature_${feature}"] = "checked";
	    }
	}
	$defaults["reboot_waittime"] = $baseosinfo->reboot_waittime();
	$defaults["OS"]	 	     = $baseosinfo->OS();
	$defaults["version"]	     = $baseosinfo->version();
	$defaults["op_mode"]         = $baseosinfo->op_mode();
	$defaults["description"]     = "Copy of " . $baseosinfo->osname();

Leigh B Stoller's avatar
Leigh B Stoller committed
979 980 981 982 983 984 985
	if ($baseosinfo->def_parentosid()) {
	    $def_parentosinfo = OSinfo::Lookup($baseosinfo->def_parentosid());
	    if (! $def_parentosinfo) {
		TBERROR("Could not lookup osinfo object for parent " .
			$baseosinfo->def_parentosid(), 1);
	    }
	    $defaults["def_parentosid"]   = $def_parentosinfo->osid();
986 987
	}
    }
988 989
    elseif (isset($imagetype) && $imagetype == "openvz") {
	$defaults["op_mode"]             = TBDB_PCVM_OPMODE;
990 991 992
	$defaults["reboot_waittime"]     = "240";
	$defaults["os_feature_ping"]	 = "checked";
	$defaults["os_feature_ssh"]	 = "checked";
993 994
	$defaults["os_feature_isup"]	 = "checked";
	$defaults["os_feature_linktest"] = "checked";
995
	$defaults["package"]             = "No";
996

997 998 999 1000 1001 1002 1003
	#
        # XXX Need to fix this.
        # 
	$def_parentosinfo = OSinfo::LookupByName("emulab-ops",
						 "FEDORA15-OPENVZ-STD");
	if (! $def_parentosinfo) {
	    TBERROR("Could not lookup osinfo object for FEDORA15-OPENVZ-STD",1);
1004
	}
1005 1006 1007 1008 1009 1010
	$defaults["def_parentosid"]   = $def_parentosinfo->osid();
    }
    elseif (isset($imagetype) && $imagetype == "xen") {
	#
        # XXX Need to fix this.
        # 
1011
	$def_parentosinfo = OSinfo::LookupByName("emulab-ops", "XEN43-64-STD");
1012
	if (! $def_parentosinfo) {
1013 1014 1015
	    $def_parentosinfo = OSinfo::LookupByName("emulab-ops",
						     "XEN41-64-STD");
	    TBERROR("Could not lookup osinfo object for XEN image", 1);
1016 1017
	}
	$defaults["def_parentosid"]   = $def_parentosinfo->osid();
1018 1019

	if ($ec2) {
1020 1021 1022
	    $defaults["package"]  = "Yep";
	    $defaults["op_mode"]  = TBDB_ALWAYSUP_OPMODE;
	    $defaults["loadpart"] = 2;
1023
	}
1024 1025 1026 1027 1028
	else {
	    $defaults["os_feature_ipod"]	 = "checked";
	    $defaults["os_feature_isup"]	 = "checked";
	    $defaults["os_feature_linktest"]     = "checked";
	}
1029 1030 1031
	$defaults["reboot_waittime"]     = "240";
	$defaults["os_feature_ping"]	 = "checked";
	$defaults["os_feature_ssh"]	 = "checked";
1032
    }
1033
    else {
Russ Fish's avatar
Russ Fish committed
1034
	# Defaults for PC-type nodes
1035
	$defaults["op_mode"]  = TBDB_DEFAULT_OSID_OPMODE;
1036 1037 1038 1039
	$defaults["os_feature_ping"]	 = "checked";
	$defaults["os_feature_ssh"]	 = "checked";
	$defaults["os_feature_ipod"]	 = "checked";
	$defaults["os_feature_isup"]	 = "checked";
1040
	$defaults["os_feature_linktest"] = "checked";
1041
    }
1042

1043 1044 1045
    #
    # For users that are in one project and one subgroup, it is usually
    # the case that they should use the subgroup, and since they also tend
1046
    # to be in the naive portion of our users, give them some help.
1047 1048 1049
    # 
    if (count($projlist) == 1) {
	list($project, $grouplist) = each($projlist);
1050

1051
	if (count($grouplist) <= 2) {
1052
	    $defaults["pid"] = $project;
1053 1054 1055 1056 1057
	    if (count($grouplist) == 1 || strcmp($project, $grouplist[0]))
		$group = $grouplist[0];
	    else {
		$group = $grouplist[1];
	    }
1058
	    $defaults["gid"] = $group;
1059 1060
	    
	    if (!strcmp($project, $group))
1061
		$defaults["path"]     = "$TBPROJ_DIR/$project/images/";
1062
	    else
1063
		$defaults["path"]     = "$TBGROUP_DIR/$project/$group/images/";
1064 1065 1066
	}
	reset($projlist);
    }
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
    elseif (isset($node)) {
	#
	# Use the current pid/eid of the experiment the node is in.
	#
	$experiment = $node->Reservation();
	if ($experiment) {
	    $defaults["pid"] = $experiment->pid();
	    $defaults["gid"] = $experiment->gid();
	}
    }
1077 1078

    #
1079
    # Allow formfields that are already set to override defaults.
1080 1081 1082 1083 1084 1085 1086
    #
    if (isset($formfields)) {
	while (list ($field, $value) = each ($formfields)) {
	    $defaults[$field] = $formfields[$field];
	}
    }

1087 1088 1089 1090 1091 1092 1093 1094
    SPITFORM($defaults, 0);
    PAGEFOOTER();
    return;
}

#
# Otherwise, must validate and redisplay if errors
#
1095
$errors  = array();
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127

# Be friendly about the required form field names.
if (!isset($formfields["imagename"]) ||
    strcmp($formfields["imagename"], "") == 0) {
    $errors["Descriptor Name"] = "Missing Field";
}

if (!isset($formfields["description"]) ||
    strcmp($formfields["description"], "") == 0) {
    $errors["Descriptor Name"] = "Missing Field";
}

if (!isset($formfields["loadpart"]) ||
    strcmp($formfields["loadpart"], "X") == 0) {
    $errors["Starting DOS Partion"] = "Missing Field";
}

if (!isset($formfields["OS"]) ||
    strcmp($formfields["OS"], "X") == 0) {
    $errors["Operating System"] = "Missing Field";
}

if (!isset($formfields["version"]) ||
    strcmp($formfields["version"], "X") == 0) {
    $errors["Operating System"] = "Missing Field";
}

if (!isset($formfields["op_mode"]) ||
    strcmp($formfields["op_mode"], "none") == 0) {
    $errors["Operational Mode"] = "Missing Field";
}

1128 1129
$project = null;
$group   = null;
1130 1131 1132

#
# Project:
1133 1134 1135
#
if (!isset($formfields["pid"]) ||
    strcmp($formfields["pid"], "") == 0) {
1136 1137
    $errors["Project"] = "Not Selected";
}
1138 1139
elseif (!TBvalid_pid($formfields["pid"])) {
    $errors["Project"] = "Invalid project name";
1140
}
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
elseif (! ($project = Project::Lookup($formfields["pid"]))) {
    $errors["Project"] = "Invalid project name";
}

if (isset($formfields["gid"]) && $formfields["gid"] != "") {
    if ($formfields["pid"] == $formfields["gid"] && $project) {
	$group = $project->DefaultGroup();
    }
    elseif (!TBvalid_gid($formfields["gid"])) {
	$errors["Group"] = "Invalid group name";
1151
    }
1152 1153 1154
    elseif ($project &&
	    ! ($group = $project->LookupSubgroupByName($formfields["gid"]))) {
	$errors["Group"] = "Invalid group name";
1155 1156
    }
}
1157 1158
elseif ($project) {
    $group = $project->DefaultGroup();
1159 1160
}

1161 1162 1163 1164 1165
# Permission check if we managed to get a proper group above.
if ($group &&
    ! $group->AccessCheck($this_user, $TB_PROJECT_MAKEIMAGEID)) {
    $errors["Project"] = "Not enough permission";
}
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178

#
# EC2 Checks
#
if ($ec2) {
    if (!isset($formfields["ec2_info"]) ||
	strcmp($formfields["ec2_info"], "") == 0) {
	$errors["EC2 Info"] = "Missing Field";
    }
    if (!preg_match("/^[-\w\@\.\+]+$/", $formfields["ec2_info"])) {
	$errors["EC2 Info"] = "Illegal characters";
    }
}
1179
 
1180
#
1181
# Build up argument array to pass along.
1182
#
1183 1184
$args = array();

1185 1186 1187 1188 1189 1190 1191
# Ignore the form for this ...
if (isset($formfields["def_parentosid"]) &&
    $formfields["def_parentosid"] != "") {
    $osinfo = OSinfo::Lookup($formfields["def_parentosid"]);
    $args["def_parentosid"] = $osinfo->pid() . "," . $osinfo->osname();
}

1192 1193
if (isset($formfields["pid"]) && $formfields["pid"] != "") {
    $args["pid"] = $pid = $formfields["pid"];
1194 1195
}

1196 1197
if (isset($formfields["gid"]) && $formfields["gid"] != "") {
    $args["gid"] = $gid = $formfields["gid"];
1198
}
1199 1200 1201

if (isset($formfields["imagename"]) && $formfields["imagename"] != "") {
    $args["imagename"] = $imaganame = $formfields["imagename"];
1202 1203
}

1204 1205
if (isset($formfields["description"]) && $formfields["description"] != "") {
    $args["description"] = $formfields["description"];
1206
}
1207 1208

if (isset($formfields["loadpart"]) &&
Russ Fish's avatar
Russ Fish committed
1209
    $formfields["loadpart"] != "X" && $formfields["loadpart"] != "") {
1210
    $args["loadpart"] = $formfields["loadpart"];
1211
}
1212 1213 1214 1215

if (isset($formfields["OS"]) &&
    $formfields["OS"] != "none" && $formfields["OS"] != "") {
    $args["OS"] = $formfields["OS"];
1216
}
1217 1218 1219

if (isset($formfields["version"]) && $formfields["version"] != "") {
    $args["version"]	= $formfields["version"];
1220
}
1221

1222 1223
if (isset($formfields["path"]) && $formfields["path"] != "") {
    $args["path"] = $formfields["path"];
1224
}
1225 1226 1227

if (isset($formfields["node_id"]) && $formfields["node_id"] != "") {
    $args["node_id"] = $formfields["node_id"];
1228 1229
}

1230 1231
if (isset($formfields["op_mode"]) && $formfields["op_mode"] != "") {
    $args["op_mode"] = $formfields["op_mode"];
1232 1233
}

1234 1235 1236
# Filter booleans from checkboxes to 0 or 1.
if (isset($formfields["wholedisk"])) {
   $args["wholedisk"] = strcmp($formfields["wholedisk"], "Yep") ? 0 : 1;
1237
}
1238 1239
if (isset($formfields["shared"])) {
   $args["shared"] = strcmp($formfields["shared"], "Yep") ? 0 : 1;
1240
}
1241 1242
if (isset($formfields["global"])) {
   $args["global"] = strcmp($formfields["global"], "Yep") ? 0 : 1;
1243
}
1244 1245 1246
if (isset($formfields["noexport"]) && $formfields["noexport"] == "Yep") {
    $args["noexport"] = 1;
}
1247 1248 1249 1250

if (isset($formfields["max_concurrent"]) &&
    $formfields["max_concurrent"] != "") {
    $args["max_concurrent"] = $formfields["max_concurrent"];
1251
}