editimageid.php3 14.8 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
#
3
# Copyright (c) 2000-2014 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 27
include_once("osiddefs.php3");
include_once("imageid_defs.php");
include_once("osinfo_defs.php");
28 29

#
30
# Only known and logged in users.
31
#
32 33 34
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
35
$doespcvm  = 0;
36 37

#
38 39 40 41 42 43 44 45
# Verify page arguments.
#
$reqargs = RequiredPageArguments("image",      PAGEARG_IMAGE);
$optargs = OptionalPageArguments("submit",     PAGEARG_STRING,
				 "formfields", PAGEARG_ARRAY);

# Need these below.
$imageid = $image->imageid();
46 47 48
if ($image->ezid()) {
    $osinfo = OSinfo::Lookup($imageid);
}
49

50
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
51
# Verify permission.
52
#
53
if (!$image->AccessCheck($this_user, $TB_IMAGEID_MODIFYINFO)) {
54
    USERERROR("You do not have permission to access ImageID $imageid!", 1);
55 56
}

57 58 59 60 61
#
# Standard Testbed Header
#
PAGEHEADER("Edit Image Descriptor");

62
#
63 64 65
# Need a list of node types. We join this over the nodes table so that
# we get a list of just the nodes that currently in the testbed, not
# just in the node_types table.
66
#
67 68
$types_result =
    DBQueryFatal("select distinct n.type from nodes as n ".
69 70 71
		 "left join node_type_attributes as a on a.type=n.type ".
		 "where a.attrkey='imageable' and ".
		 "      a.attrvalue!='0'");
72 73 74 75 76 77 78 79 80 81
$types_array = array();
while ($row = mysql_fetch_array($types_result)) {
    $types_array[] = $row["type"];
}

#
# Special hack to specify subOSes that can run on vnodes 
# -- see SetupReload in os_setup
#
$types_array[] = "pcvm";
82

83
$osid_result =
84
    DBQueryFatal("select o.osid,v.vers,o.osname,o.pid from os_info as o ".
85 86 87 88
		 "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");
89

90
#
91 92
# Spit the form out using the array of data.
#
93
function SPITFORM($image, $formfields, $errors)
94
{
95
    global $uid, $isadmin, $types_array, $defaults, $osid_result, $doespcvm;
96
    global $TBDB_IMAGEID_IMAGENAMELEN, $TBDB_NODEIDLEN;
Russ Fish's avatar
Russ Fish committed
97

98 99 100 101 102 103 104 105 106 107 108 109
    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)) {
110 111
            # XSS prevention.
	    $message = CleanString($message);
112 113 114 115 116 117 118 119 120
	    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";
    }
121 122 123 124
    # XSS prevention.
    while (list ($key, $val) = each ($formfields)) {
	$formfields[$key] = CleanString($val);
    }
125

126 127
    # Must encode the imageid since Rob started using plus signs in
    # the names.
128
    $url = CreateURL("editimageid", $image);
129 130
    echo "<br>
          <table align=center border=1> 
131
          <form action='$url' method=post>\n";
132 133

    #
Russ Fish's avatar
Russ Fish committed
134
    # Image Name
135 136 137
    #
    echo "<tr>
              <td>ImageID:</td>
138
              <td class=left>" . $defaults["imagename"] . "</td>
139 140 141 142 143 144 145
          </tr>\n";

    #
    # Project
    #
    echo "<tr>
              <td>Project:</td>
146
              <td class=left>" . $defaults["pid"] . "</td>
147 148 149 150 151 152 153
          </tr>\n";

    #
    # Group
    # 
    echo "<tr>
              <td>Group:</td>
154
              <td class=left>" . $defaults["gid"] . "</td>
155 156 157 158 159 160 161
          </tr>\n";

    #
    # Image Name:
    #
    echo "<tr>
              <td>Descriptor Name:</td>
162
              <td class=left>" . $defaults["imagename"] . "</td>
163 164 165 166 167 168
          </tr>\n";

    #
    # Description
    #
    echo "<tr>
Russ Fish's avatar
Russ Fish committed
169 170
              <td>Description:<br>
                  (a short pithy sentence)</td>
171 172 173
              <td class=left>
                  <input type=text
                         name=\"formfields[description]\"
174
                         value=\"" . $formfields["description"] . "\"
175 176 177 178 179 180 181 182 183
	                 size=50>
              </td>
          </tr>\n";

    #
    # Load Partition
    #
    echo "<tr>
              <td>Load Partition:</td>
184
              <td class=left>" . $defaults["loadpart"] . "</td>
185 186 187 188 189 190 191
          </tr>\n";

    #
    # Load Length
    #
    echo "<tr>
              <td>Load Partition:</td>
192
              <td class=left>" . $defaults["loadlength"] . "</td>
193 194 195 196 197
          </tr>\n";

    echo "<tr>
             <td>Partition 1 OS: </td>
             <td class=\"left\">";
198
    if (isset($defaults["part1_osid"]))
199
	SpitOSIDLink($defaults["part1_osid"], $defaults["part1_vers"]);
200 201 202 203 204 205 206 207
    else
	echo "No OS";
    echo "   </td>
          </tr>\n";
    
    echo "<tr>
             <td>Partition 2 OS: </td>
             <td class=\"left\">";
208
    if (isset($defaults["part2_osid"]))
209
	SpitOSIDLink($defaults["part2_osid"], $defaults["part2_vers"]);
210 211 212 213 214 215 216 217
    else
	echo "No OS";
    echo "   </td>
          </tr>\n";

    echo "<tr>
             <td>Partition 3 OS: </td>
             <td class=\"left\">";
218
    if (isset($defaults["part3_osid"]))
219
	SpitOSIDLink($defaults["part3_osid"], $defaults["part3_vers"]);
220 221 222 223 224 225 226 227
    else
	echo "No OS";
    echo "   </td>
          </tr>\n";

    echo "<tr>
             <td>Partition 4 OS: </td>
             <td class=\"left\">";
228
    if (isset($defaults["part4_osid"]))
229
	SpitOSIDLink($defaults["part4_osid"], $defaults["part4_vers"]);
230 231 232 233 234 235 236 237
    else
	echo "No OS";
    echo "   </td>
          </tr>\n";
    
    echo "<tr>
             <td>Boot OS: </td>
             <td class=\"left\">";
238
    if (isset($defaults["default_osid"]))
239
	SpitOSIDLink($defaults["default_osid"], $defaults["default_vers"]);
240 241 242 243 244 245 246 247 248
    else
	echo "No OS";
    echo "   </td>
          </tr>\n";
    
    #
    # Path to image.
    #
    echo "<tr>
Russ Fish's avatar
Russ Fish committed
249
              <td>Filename (full path) of Image:</td>
250 251 252
              <td class=left>
                  <input type=text
                         name=\"formfields[path]\"
253
                         value=\"" . $formfields["path"] . "\"
254 255 256 257 258 259 260 261 262 263 264
	                 size=50>
              </td>
          </tr>\n";

    #
    # Node Types.
    #
    echo "<tr>
              <td>Node Types:</td>
              <td>\n";

265
    foreach ($types_array as $type) {
266 267
        $checked = "";

268 269
        if (isset($formfields["mtype_$type"]) &&
	    $formfields["mtype_$type"] == "Yep") {
270
	    $checked = "checked";
271 272 273 274

	    if ("mtype_$type" == "mtype_pcvm") {
		$doespcvm = 1;
	    }
275
	}
276 277 278 279 280 281 282 283 284 285 286 287 288
    
        echo "<input $checked type=checkbox
                     value=Yep name=\"formfields[mtype_$type]\">
                     $type &nbsp
              </input>\n";
    }
    echo "    </td>
          </tr>\n";

    #
    # Shared?
    #
    echo "<tr>
Russ Fish's avatar
Russ Fish committed
289 290
  	      <td>Shared?:<br>
                  (available to all subgroups)</td>
291
              <td class=left>". ($defaults["shared"] ? "Yes" : "No") . "</td>
292 293 294 295 296 297
          </tr>\n";

    #
    # Global?
    #
    echo "<tr>
Russ Fish's avatar
Russ Fish committed
298 299
  	      <td>Global?:<br>
                      (available to all projects)</td>
300
              <td class=left>". ($defaults["global"] ? "Yes" : "No") . "</td>
301 302
          </tr>\n";

303 304 305 306 307 308 309 310 311 312
    if ($isadmin) {
	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";
313 314 315 316 317 318

	if ($doespcvm) {
	    WRITEOSIDMENU("Default Parent OS",
			  "formfields[def_parentosid]",
			  $osid_result, $formfields["def_parentosid"]);
	}
319 320 321 322 323 324 325 326 327 328 329 330 331
        #
	# Notes
	#
	echo "<tr>
                  <td>Admin Notes:</td>
                  <td class=left>
                      <textarea name=\"formfields[notes]\"
                                rows=4 cols=60>" .
		                   str_replace("\r", "",
						$formfields["notes"]) .
	              "</textarea>
                  </td>
              </tr>\n";
332 333
    }

334 335 336 337 338 339 340 341
    echo "<tr>
              <td align=center colspan=2>
                 <b><input type=submit name=submit value=Submit></b>
              </td>
          </tr>\n";

    echo "</form>
          </table>\n";
342
}
343 344

# Need this below.
345
$defaults = $image->DBData();
346 347 348 349
   
#
# On first load, display a virgin form and exit.
#
Russ Fish's avatar
Russ Fish committed
350
if (!isset($submit)) {
351 352
    # Generate the current types array for the form.
    foreach ($image->Types() as $type) {
353 354
	$defaults["mtype_${type}"] = "Yep";
    }
Leigh B Stoller's avatar
Leigh B Stoller committed
355
    $defaults["def_parentosid"] = "";
356 357 358
    if ($image->ezid() && $osinfo->def_parentosid()) {
	$defaults["def_parentosid"] = $osinfo->def_parentosid();
    }
359

360
    SPITFORM($image, $defaults, 0);
361 362
    PAGEFOOTER();
    return;
363 364
}

365 366 367 368 369 370
#
# Otherwise, must validate and redisplay if errors
#
$errors     = array();
$updates    = array();

371 372 373 374 375 376 377 378
#
# If any errors, respit the form with the current values and the
# error messages displayed. Iterate until happy.
# 
if (count($errors)) {
    SPITFORM($image, $formfields, $errors);
    PAGEFOOTER();
    return;
379 380 381
}

#
382 383
# See what node types this image will work on. Must be at least one!
# Store the valid types in a new array for simplicity.
384
#
385
$mtypes_array = array();
386
foreach ($types_array as $type) {
387 388 389
    #
    # Look for a post variable with name.
    # 
390 391
    if (isset($formfields["mtype_$type"]) &&
	$formfields["mtype_$type"] == "Yep") {
392
	$mtypes_array[] = $type;
393 394 395
	if ("mtype_$type" == "mtype_pcvm") {
	    $doespcvm = 1;
	}
396 397 398 399 400
    }
}
if (! count($mtypes_array)) {
    $errors["Node Types"] = "Must select at least one type";
}
401 402

#
403 404 405
# Build up argument array to pass along.
#
$args = array();
406

407
# Notice that {part*,default}_osid are not editable inputs on this form.
408

409 410 411 412 413 414 415 416 417 418 419
# Skip passing ones that are not changing from the default (DB state.)
if (isset($formfields["description"]) && $formfields["description"] != "" &&
    ($formfields["description"] != $image->description())) {
    $args["description"] = $formfields["description"];
}

if (isset($formfields["path"]) && $formfields["path"] != "" &&
    ($formfields["path"] != $image->path())) {
    $args["path"] = $formfields["path"];
}

420 421 422 423
if (isset($formfields["mbr_version"]) && $formfields["mbr_version"] != "" &&
    $formfields["mbr_version"] != $image->mbr_version()) {
    $args["mbr_version"] = $formfields["mbr_version"];
}
424 425 426 427 428 429 430 431

if (isset($formfields["notes"])) {
    if (!TBvalid_fulltext($formfields["notes"])) {
	$errors["Notes"] = TBFieldErrorString();
    }
    else {
	$args["notes"] = $formfields["notes"];
    }
432
}
433

434 435 436 437 438 439 440
# The mtype_* checkboxes are dynamically generated.
foreach ($mtypes_array as $type) {
    # Filter booleans from checkbox values, send if different.
    $checked = isset($formfields["mtype_$type"]) &&
	strcmp($formfields["mtype_$type"], "Yep") == 0;
    if ($checked != array_search("mtype_$type", $mtypes_array)) {
	$args["mtype_$type"] = $checked ? "1" : "0";
441
    }
442
}
443

444 445 446 447 448
#
# Mereusers are not allowed to create more than one osid/imageid mapping
# for each machinetype. They cannot actually do that through the EZ form
# since the osid/imageid has to be unique, but it can happen by mixed
# use of the long form and the short form, or with multiple uses of the
449
# long form.
450

451
# Can't check this unless we have at least one mtype!
452
if (!count($mtypes_array) || count($errors)) {
453 454 455 456 457 458
    SPITFORM($image, $formfields, $errors);
    PAGEFOOTER();
    return;
}
    
$typeclause = "type=" . "'$mtypes_array[0]'";
459 460
for ($i = 1; $i < count($mtypes_array); $i++) {
    $typeclause = "$typeclause or type=" . "'$mtypes_array[$i]'";
461
}
462

463
unset($osidclause);
Russ Fish's avatar
Russ Fish committed
464
$osid_array = array();
465 466 467 468 469 470 471 472 473 474 475 476 477
for ($i = 1; $i <= 4; $i++) {
    # Local variable dynamically created.    
    $foo      = "part${i}_osid";

    if (isset($defaults[$foo])) {
	if (isset($osidclause))
	    $osidclause = "$osidclause or osid='" . $defaults[$foo] . "' ";
	else 
	    $osidclause = "osid='" . $defaults[$foo] . "' ";

	$osid_array[] = $defaults[$foo];
    }
}
478 479 480 481 482 483 484 485 486 487 488 489
if (isset($osidclause)) {
    DBQueryFatal("lock tables images write, os_info write, osidtoimageid write");
    $query_result =
	DBQueryFatal("select osidtoimageid.*,images.pid,images.imagename ".
		     " from osidtoimageid ".
		     "left join images on ".
		     " images.imageid=osidtoimageid.imageid ".
		     "where ($osidclause) and ($typeclause) and ".
		     "      images.imageid!='$imageid'");
    DBQueryFatal("unlock tables");

    if (mysql_num_rows($query_result)) {
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
	echo "<center>
              There are other image descriptors that specify the 
	      same OS descriptors for the same node types.<br>
              There must be a
	      unique mapping of OS descriptor to Image descriptor for
              each node type! Perhaps you need to delete one of the
              images below, or create a new OS descriptor to use in
              this new Image descriptor.
              </center><br>\n";

	echo "<table border=1 cellpadding=2 cellspacing=2 align='center'>\n";

	echo "<tr>
                  <td align=center>OSID</td>
                  <td align=center>Type</td>
                  <td align=center>ImageID</td>
             </tr>\n";

	while ($row = mysql_fetch_array($query_result)) {
	    $imageid   = $row['imageid'];
510 511 512 513
	    $url       = CreateURL("showimageid", URLARG_IMAGEID, $imageid);
	    $osid      = $row["osid"];
	    $type      = $row["type"];
	    $imagename = $row["imagename"];
514 515 516 517
	    
	    echo "<tr>
                      <td>$osid</td>
	              <td>$type</td>
518
                      <td><A href='$url'>$imagename</A></td>
519 520 521 522 523 524
	          </tr>\n";
	}
	echo "</table><br><br>\n";
    
	USERERROR("Please check the other Image descriptors and make the ".
		  "necessary changes!", 1);
525
    }
526
}
527

528 529 530 531 532 533 534 535
# Send to the backend for more checking, and eventually, to update the DB.
if (! ($result = Image::EditImageid($image,
				 $args, $errors))) {
    # 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.
    SPITFORM($image, $formfields, $errors);
    PAGEFOOTER();
    return;
536 537
}

538 539 540 541 542 543 544 545 546 547 548
#
# Special case. 
#
if ($isadmin && $doespcvm && $image->ezid() &&
    isset($formfields["def_parentosid"]) &&
    $formfields["def_parentosid"] != "" &&
    TBvalid_osid($formfields["def_parentosid"]) &&
    OSinfo::Lookup($formfields["def_parentosid"])) {
    $osinfo->SetParent($formfields["def_parentosid"]);
}

549
PAGEREPLACE(CreateURL("showimageid", $image));
550

551
#
552
# Dump record in case the redirect fails.
553
# 
554 555
$image->Refresh();
$image->Show();
556 557 558 559 560 561

#
# Standard Testbed Footer
# 
PAGEFOOTER();
?>