Commit 41c54939 authored by Kirk Webb's avatar Kirk Webb

The revived Plab interface is here!

Lots of updates to the plab backend, including improved plab <-> elab node
id translation and update handling.  Includes support for the current PLC
API, and the new pl_conf node manager interface API.  Several more db library
routines were ported from the perl library to the python one to support the
new code (mostly the node_id tracking stuff).  Fixes to the client side and
also a rootball creation cleanup (binaries removed from the CVS repo).

There are also enhancements to the experiment view page for experiments
including plab nodes: site and widearea hostname are now displayed along
with the other node information.

Note that the way setup timeout for vnodes is calculated has been changed a
bit.  Instead of using a hardwired base timeout, the base timeout is now
based on the reload_waittime database field, which comes from the 'OS'
(e.g., FBSD-JAIL, RHL-PLAB) the vnode runs.

The default max duration for a plab slice created through the plab_ez interface
is set to 1 year, and linktest is currently disabled and hidden through
the ez interface.

There is still work to do, but this checkin brings with it a functional
plab portal!
parent 2d003fcc
...@@ -2285,6 +2285,7 @@ outfiles="$outfiles Makeconf GNUmakefile \ ...@@ -2285,6 +2285,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/fetchtar.proxy tbsetup/webfrisbeekiller \ tbsetup/fetchtar.proxy tbsetup/webfrisbeekiller \
tbsetup/plab/GNUmakefile tbsetup/plab/libplab.py \ tbsetup/plab/GNUmakefile tbsetup/plab/libplab.py \
tbsetup/plab/mod_dslice.py tbsetup/plab/mod_PLC.py \ tbsetup/plab/mod_dslice.py tbsetup/plab/mod_PLC.py \
tbsetup/plab/mod_PLCNM.py \
tbsetup/plab/plabslice tbsetup/plab/plabnode tbsetup/plab/plabrenewd \ tbsetup/plab/plabslice tbsetup/plab/plabnode tbsetup/plab/plabrenewd \
tbsetup/plab/plabmetrics tbsetup/plab/plabstats \ tbsetup/plab/plabmetrics tbsetup/plab/plabstats \
tbsetup/plab/plabmonitord tbsetup/plab/plablinkdata \ tbsetup/plab/plabmonitord tbsetup/plab/plablinkdata \
......
...@@ -723,6 +723,7 @@ outfiles="$outfiles Makeconf GNUmakefile \ ...@@ -723,6 +723,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/fetchtar.proxy tbsetup/webfrisbeekiller \ tbsetup/fetchtar.proxy tbsetup/webfrisbeekiller \
tbsetup/plab/GNUmakefile tbsetup/plab/libplab.py \ tbsetup/plab/GNUmakefile tbsetup/plab/libplab.py \
tbsetup/plab/mod_dslice.py tbsetup/plab/mod_PLC.py \ tbsetup/plab/mod_dslice.py tbsetup/plab/mod_PLC.py \
tbsetup/plab/mod_PLCNM.py \
tbsetup/plab/plabslice tbsetup/plab/plabnode tbsetup/plab/plabrenewd \ tbsetup/plab/plabslice tbsetup/plab/plabnode tbsetup/plab/plabrenewd \
tbsetup/plab/plabmetrics tbsetup/plab/plabstats \ tbsetup/plab/plabmetrics tbsetup/plab/plabstats \
tbsetup/plab/plabmonitord tbsetup/plab/plablinkdata \ tbsetup/plab/plabmonitord tbsetup/plab/plablinkdata \
......
...@@ -25,8 +25,24 @@ from libtestbed import * ...@@ -25,8 +25,24 @@ from libtestbed import *
# #
# Debug vars. # Debug vars.
# #
verbose = 0; verbose = 0
debug = 0; debug = 0
# Constants
TBOPSPID = "emulab-ops"
NODEDEAD_PID = TBOPSPID
NODEDEAD_EID = "hwdown"
TB_NODEHISTORY_OP_MOVE = "move"
# Node Log Types
TB_NODELOGTYPE_MISC = "misc"
TB_NODELOGTYPES = (TB_NODELOGTYPE_MISC, )
TB_DEFAULT_NODELOGTYPE = TB_NODELOGTYPE_MISC
# Node History Stuff.
TB_NODEHISTORY_OP_FREE = "free"
TB_NODEHISTORY_OP_ALLOC = "alloc"
TB_NODEHISTORY_OP_MOVE = "move"
# #
# DB variables. # DB variables.
...@@ -90,7 +106,7 @@ def DBQuery(queryPat, querySub = (), asDict = False): ...@@ -90,7 +106,7 @@ def DBQuery(queryPat, querySub = (), asDict = False):
if ret == None: if ret == None:
return () return ()
return ret return ret
except MySQLdb.MySQLError: except MySQLdb.MySQLError, e:
tries -= 1 tries -= 1
if tries == 0: if tries == 0:
break break
...@@ -100,6 +116,7 @@ def DBQuery(queryPat, querySub = (), asDict = False): ...@@ -100,6 +116,7 @@ def DBQuery(queryPat, querySub = (), asDict = False):
__dbConnection.ping() __dbConnection.ping()
except MySQLdb.MySQLError: except MySQLdb.MySQLError:
pass pass
tbmsg = queryPat % cursor.connection.literal(querySub) tbmsg = queryPat % cursor.connection.literal(querySub)
tbmsg += "\n\n" tbmsg += "\n\n"
tbmsg += "".join(traceback.format_exception(*sys.exc_info())) tbmsg += "".join(traceback.format_exception(*sys.exc_info()))
...@@ -112,6 +129,157 @@ def DBQueryFatal(*args): ...@@ -112,6 +129,157 @@ def DBQueryFatal(*args):
raise RuntimeError, "DBQueryFatal failed" raise RuntimeError, "DBQueryFatal failed"
return ret return ret
def DBQueryWarn(*args):
return DBQuery(*args)
def DBQuoteSpecial(str):
TBDBConnect()
return __dbConnection.escape_string(str)
#
# Map UID to DB UID (login). Does a DB check to make sure user is known to
# the DB (user obviously has a regular account), and that account will
# always match what the DB says. Redundant, I know. But consider it a
# sanity (or consistency) check.
#
# usage: UNIX2DBUID(int uid)
# returns username if the UID is okay.
# raises a UserError exception if the UID is bogus.
#
class UserError(StandardError): pass # XXX: need better suite of exceptions
def UNIX2DBUID (unix_uid):
qres = \
DBQueryFatal("select uid from users where unix_uid=%s",
(unix_uid))
if not len(qres):
raise UserError, "*** %s not a valid Emulab user!" % uid
pwname = pwd.getpwuid(unix_uid)[0]
dbuser = qres[0][0]
if dbuser != pwname:
raise UserError, "*** %s (passwd file) does not match %s (db)" % \
(pwname, dbuser)
return dbuser
#
# Helper. Test if numeric. Convert to dbuid if numeric.
#
def MapNumericUID(uid):
name = ""
try:
uid = int(uid)
name = UNIX2DBUID(uid)
except ValueError:
name = uid
pass
return name
#
# Return the IDX for a current experiment.
#
# usage: TBExptIDX(char $pid, char *gid, int \$idx)
# returns 1 if okay.
# returns 0 if error.
#
class UnknownExptID(StandardError): pass # XXX: need better suite of exceptions
def TBExptIDX(pid,eid):
qres = \
DBQueryWarn("select idx from experiments "
"where pid=%s and eid=%s",
(pid, eid))
if not len(qres):
raise UnknownExptID, "Experiment %s/%s unknown!" % (pid,eid)
idx = qres[0][0]
return int(idx)
#
# Insert a Log entry for a node.
#
# usage: TBSetNodeLogEntry(char *node, char *uid, char *type, char *message)
# Returns 1 if okay.
# Returns 0 if failed.
#
def TBSetNodeLogEntry(node, dbuid, type, message):
if not TBValidNodeName(node) or not TBValidNodeLogType(type):
return 0
return DBQueryWarn("insert into nodelog "
"values "
"(%s, NULL, %s, %s, %s, now())",
(node, type, dbuid, message))
#
# Validate a node name.
#
# usage: TBValidNodeName(char *name)
# Returns 1 if the node is valid.
# Returns 0 if not.
#
def TBValidNodeName(node):
qres = \
DBQueryWarn("select node_id from nodes where node_id=%s",
(node))
if len(qres) == 0:
return 0
return 1
#
# Validate a node log type.
#
# usage: TBValidNodeLogType(char *type)
# Returns 1 if the type string is valid.
# Returns 0 if not.
#
def TBValidNodeLogType(type):
if type in TB_NODELOGTYPES:
return 1
return 0
#
# Mark a Phys node as down. Cannot use next reserve since the pnode is not
# going to go through the free path.
#
# usage: MarkPhysNodeDown(char *nodeid)
#
def MarkPhysNodeDown(pnode):
pid = NODEDEAD_PID;
eid = NODEDEAD_EID;
DBQueryFatal("lock tables reserved write")
DBQueryFatal("update reserved set "
" pid=%s,eid=%s,rsrv_time=now() "
"where node_id=%s",
(pid, eid, pnode))
DBQueryFatal("unlock tables")
TBSetNodeHistory(pnode, TB_NODEHISTORY_OP_MOVE, os.getuid(), pid, eid)
return
def TBSetNodeHistory(nodeid, op, uid, pid, eid):
exptidx = 0
try:
exptidx = TBExptIDX(pid, eid)
except:
print "*** WARNING: No such experiment %s/%s!" % (pid,eid)
return 0
try:
uid = int(uid)
# val = <expr> ? TrueRet : FalseRet
uid = uid == 0 and "root" or UNIX2DBUID(uid)
pass
except ValueError:
pass
return DBQueryWarn("insert into node_history set "
" history_id=0, node_id=%s, op=%s, "
" uid=%s, stamp=UNIX_TIMESTAMP(now()), "
" exptidx=%s",
(nodeid,op,uid,exptidx))
def TBSiteVarExists(name): def TBSiteVarExists(name):
name = DBQuoteSpecial(name) name = DBQuoteSpecial(name)
...@@ -142,9 +310,3 @@ def TBGetSiteVar(name): ...@@ -142,9 +310,3 @@ def TBGetSiteVar(name):
raise RuntimeException, \ raise RuntimeException, \
"*** attempted to fetch unknown site variable name!" "*** attempted to fetch unknown site variable name!"
def DBQuoteSpecial(str):
TBDBConnect()
return __dbConnection.escape_string(str)
...@@ -929,10 +929,18 @@ elsif (@vnodelist) { ...@@ -929,10 +929,18 @@ elsif (@vnodelist) {
my $pnode = $vnode2pnode{$node}; my $pnode = $vnode2pnode{$node};
my $islocal= exists($nodes{$pnode}); my $islocal= exists($nodes{$pnode});
my $wstart = $waitstart{$node}; my $wstart = $waitstart{$node};
my $maxwait = 90 + (40 * $pnodevcount{$pnode});
my $curallocstate; my $curallocstate;
my $actual_state; my $actual_state;
#
# Base the maxwait for vnodes on the reboot_waittime field for
# their respective OSIDs, with some slop time that scales up
# as a function of the number of vnodes on the parent pnode.
#
my $osid = $osids{$node};
my $reboot_time = $reboot_waittime{$osid};
my $maxwait = $reboot_time + (40 * $pnodevcount{$pnode});
TBGetNodeAllocState($node, \$curallocstate); TBGetNodeAllocState($node, \$curallocstate);
# #
......
...@@ -17,7 +17,7 @@ SUBDIRS = libdslice etc ...@@ -17,7 +17,7 @@ SUBDIRS = libdslice etc
SBIN_STUFF = plabslice plabnode plabrenewd plabmetrics plabstats \ SBIN_STUFF = plabslice plabnode plabrenewd plabmetrics plabstats \
plabmonitord plablinkdata plabdist plabhttpd plabdiscover plabmonitord plablinkdata plabdist plabhttpd plabdiscover
LIB_STUFF = libplab.py mod_dslice.py mod_PLC.py LIB_STUFF = libplab.py mod_dslice.py mod_PLC.py mod_PLCNM.py
LIBEXEC_STUFF = webplabstats LIBEXEC_STUFF = webplabstats
......
This diff is collapsed.
This diff is collapsed.
...@@ -97,7 +97,7 @@ my $logfile = "$TB/log/plabmonitord"; ...@@ -97,7 +97,7 @@ my $logfile = "$TB/log/plabmonitord";
my @oldnodes = (); my @oldnodes = ();
my $LOOPSLEEP = 1800; # 1/2 hour between successive loops. my $LOOPSLEEP = 1800; # 1/2 hour between successive loops.
my $PAUSETIME = 120; # 2 minute pause after running vnode_setup my $PAUSETIME = 120; # 2 minute pause after running vnode_setup
my $SETUPWAIT = 960; # how long to wait for vnode to setup. my $SETUPWAIT = 300; # how long to wait for vnode to setup.
my $BATCHNUM = 40; # degree of parallelization my $BATCHNUM = 40; # degree of parallelization
# #
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# All rights reserved. # All rights reserved.
# #
import sys import sys, os
sys.path.append("@prefix@/lib") sys.path.append("@prefix@/lib")
import getopt import getopt
from libtestbed import * from libtestbed import *
......
...@@ -326,6 +326,10 @@ my ($pid, $eid, $vname); ...@@ -326,6 +326,10 @@ my ($pid, $eid, $vname);
TBDebugTimeStamp("vnodesetup calling into libsetup"); TBDebugTimeStamp("vnodesetup calling into libsetup");
if ($doplab) { if ($doplab) {
# Need to be real root for vnodeplabsetup to work
# since it runs subcommands via system() that need to be
# root.
$UID = 0;
($pid, $eid, $vname) = vnodeplabsetup($vnodeid); ($pid, $eid, $vname) = vnodeplabsetup($vnodeid);
} }
else { else {
......
...@@ -23,11 +23,10 @@ ALLSCRIPTS = $(ULEESCRIPTS) $(OSSCRIPTS) $(EESCRIPTS) ...@@ -23,11 +23,10 @@ ALLSCRIPTS = $(ULEESCRIPTS) $(OSSCRIPTS) $(EESCRIPTS)
THISDIR = $(PWD) THISDIR = $(PWD)
# #
# Linux binaries the tarball needs # Root of tree containing stock package stuff that is needed
# in the plab vserver environment to support Emulab (e.g. sshd)
# #
BINARIES = $(SRCDIR)/tmcc $(SRCDIR)/suidperl $(SRCDIR)/tcsh \ PKGSRCTREE = /share/plab/pkgroot
$(SRCDIR)/gzip
ALLBINARIES = $(BINARIES)
# #
# Configuration, or other files necessary for tarball # Configuration, or other files necessary for tarball
...@@ -58,7 +57,7 @@ $(ROOTBALLNAME): copyfiles ...@@ -58,7 +57,7 @@ $(ROOTBALLNAME): copyfiles
chown -R 0:0 plabroot chown -R 0:0 plabroot
tar cf - --numeric-owner -C plabroot . | bzip2 -c -9 > $(ROOTBALLNAME) tar cf - --numeric-owner -C plabroot . | bzip2 -c -9 > $(ROOTBALLNAME)
copyfiles: $(ALLSCRIPTS) $(ALLBINARIES) $(ALLCONFS) $(ALLCERTS) mkdirtree copyfiles: $(ALLSCRIPTS) $(ALLCONFS) $(ALLCERTS) $(PKGSRCTREE) mkdirtree
(cd ../common/config; $(MAKE) script-install DESTDIR=$(THISDIR)/plabroot) (cd ../common/config; $(MAKE) script-install DESTDIR=$(THISDIR)/plabroot)
$(INSTALL_PROGRAM) $(ULEESCRIPTS) plabroot/usr/local/etc/emulab $(INSTALL_PROGRAM) $(ULEESCRIPTS) plabroot/usr/local/etc/emulab
chmod u+s plabroot/usr/local/etc/emulab/vnodesetup chmod u+s plabroot/usr/local/etc/emulab/vnodesetup
...@@ -69,17 +68,11 @@ copyfiles: $(ALLSCRIPTS) $(ALLBINARIES) $(ALLCONFS) $(ALLCERTS) mkdirtree ...@@ -69,17 +68,11 @@ copyfiles: $(ALLSCRIPTS) $(ALLBINARIES) $(ALLCONFS) $(ALLCERTS) mkdirtree
$(INSTALL_PROGRAM) $(EESCRIPTS) plabroot/etc $(INSTALL_PROGRAM) $(EESCRIPTS) plabroot/etc
$(INSTALL) -m 440 $(TESTBED_SRCDIR)/tmcd/plab/sudoers \ $(INSTALL) -m 440 $(TESTBED_SRCDIR)/tmcd/plab/sudoers \
plabroot/etc/sudoers plabroot/etc/sudoers
ln -fs suidperl plabroot/usr/bin/sperl5.8.0
$(INSTALL_PROGRAM) -s $(SRCDIR)/tmcc \
plabroot/usr/local/etc/emulab/tmcc.bin
$(INSTALL_PROGRAM) -s -m 4511 $(SRCDIR)/suidperl plabroot/usr/bin
$(INSTALL_PROGRAM) -s $(SRCDIR)/tcsh plabroot/bin
$(INSTALL_PROGRAM) -s $(SRCDIR)/gzip plabroot/bin
ln -fs gzip plabroot/bin/gunzip
$(INSTALL_DATA) /usr/testbed/etc/pcplab.pem \ $(INSTALL_DATA) /usr/testbed/etc/pcplab.pem \
plabroot/usr/local/etc/emulab/client.pem plabroot/usr/local/etc/emulab/client.pem
$(INSTALL_DATA) /usr/testbed/etc/emulab.pem \ $(INSTALL_DATA) /usr/testbed/etc/emulab.pem \
plabroot/usr/local/etc/emulab plabroot/usr/local/etc/emulab
cp -pR $(PKGSRCTREE)/ plabroot
echo "@BOSSNODE@" > plabroot/usr/local/etc/emulab/bossnode echo "@BOSSNODE@" > plabroot/usr/local/etc/emulab/bossnode
cp /dev/null plabroot/usr/local/etc/emulab/isrem cp /dev/null plabroot/usr/local/etc/emulab/isrem
......
...@@ -132,6 +132,21 @@ sub doboot() ...@@ -132,6 +132,21 @@ sub doboot()
if (tmcc(TMCCCMD_STATE, "ISUP") < 0) { if (tmcc(TMCCCMD_STATE, "ISUP") < 0) {
fatal("Error sneding ISUP to Emulab Control!"); fatal("Error sneding ISUP to Emulab Control!");
} }
#
# After everything is setup, run any startup command.
#
# Note that this mechanism is legacy, and will be replaced
# by the program agent once the event system becomes available
# on plab vnodes.
#
if (-x "$RCDIR/rc.startcmd") {
TBDebugTimeStamp("running $RCDIR/rc.startcmd");
system("$RCDIR/rc.startcmd boot");
if ($?) {
fatal("Error running $RCDIR/rc.startcmd");
}
}
} }
# #
...@@ -215,6 +230,8 @@ sub doplabconfig() ...@@ -215,6 +230,8 @@ sub doplabconfig()
print RC "/sbin/syslogd\n"; print RC "/sbin/syslogd\n";
# Start sshd # Start sshd
print RC "/usr/sbin/useradd -u 22 -g 22 -d /var/empty ".
"-c \"sshd separation account\" -s /nonexistent sshd\n";
print RC "/etc/init.d/sshd restart\n"; print RC "/etc/init.d/sshd restart\n";
} }
else { else {
......
...@@ -508,6 +508,12 @@ function SPITFORM($formfields, $errors) ...@@ -508,6 +508,12 @@ function SPITFORM($formfields, $errors)
# Run linktest, and level. # Run linktest, and level.
# #
if (STUDLY() || $EXPOSELINKTEST) { if (STUDLY() || $EXPOSELINKTEST) {
if (isset($view['hide_linktest'])) {
if ($formfields[exp_linktest]) {
echo "<input type='hidden' name='formfields[exp_linktest]'
value='$formfields[exp_linktest]'\n";
}
} else {
echo "<tr> echo "<tr>
<td><a href='$TBDOCBASE/doc/docwrapper.php3?". <td><a href='$TBDOCBASE/doc/docwrapper.php3?".
"docname=linktest.html'>Linktest</a> Option:</td> "docname=linktest.html'>Linktest</a> Option:</td>
...@@ -528,6 +534,7 @@ function SPITFORM($formfields, $errors) ...@@ -528,6 +534,7 @@ function SPITFORM($formfields, $errors)
"docname=linktest.html'><b>Whats this?</b></a>)"; "docname=linktest.html'><b>Whats this?</b></a>)";
echo " </td> echo " </td>
</tr>\n"; </tr>\n";
}
} }
# #
......
...@@ -34,8 +34,8 @@ LOGGEDINORDIE($uid); ...@@ -34,8 +34,8 @@ LOGGEDINORDIE($uid);
unset($view); unset($view);
if (isset($view_style) && $view_style == "plab") { if (isset($view_style) && $view_style == "plab") {
$view['hide_proj'] = $view['hide_group'] = $view['hide_swap'] = $view['hide_proj'] = $view['hide_group'] = $view['hide_swap'] =
$view['hide_preload'] = $view['hide_batch'] = $view['quiet'] = $view['hide_preload'] = $view['hide_batch'] = $view['hide_linktest'] =
$view['plab_ns_message'] = 1; $view['quiet'] = $view['plab_ns_message'] = 1;
} }
include("beginexp_form.php3"); include("beginexp_form.php3");
......
...@@ -46,6 +46,12 @@ function SPITFORM($advanced,$formfields, $errors = array()) { ...@@ -46,6 +46,12 @@ function SPITFORM($advanced,$formfields, $errors = array()) {
global $TBBASE; global $TBBASE;
global $plab_types, $plab_type_descr; global $plab_types, $plab_type_descr;
#
# Default autoswap time - very long...
#
$aswapunits = 168; # 1 week (in hours)
$aswaptime = 52; # 52 weeks == 1 year
# #
# Header/footer view options # Header/footer view options
# #
...@@ -183,6 +189,8 @@ function SPITFORM($advanced,$formfields, $errors = array()) { ...@@ -183,6 +189,8 @@ function SPITFORM($advanced,$formfields, $errors = array()) {
echo "<input type='hidden' name='formfields[canfail]' value='Yep'>\n"; echo "<input type='hidden' name='formfields[canfail]' value='Yep'>\n";
echo "<input type='hidden' name='formfields[type]' value='pcplab'>\n"; echo "<input type='hidden' name='formfields[type]' value='pcplab'>\n";
echo "<input type='hidden' name='formfields[resusage]' value='3'>\n"; echo "<input type='hidden' name='formfields[resusage]' value='3'>\n";
echo "<input type='hidden' name='formfields[units]' value='$aswapunits'>\n";
echo "<input type='hidden' name='formfields[when]' value='$aswaptime'>\n";
} }
# #
...@@ -286,11 +294,11 @@ function SPITFORM($advanced,$formfields, $errors = array()) { ...@@ -286,11 +294,11 @@ function SPITFORM($advanced,$formfields, $errors = array()) {
# #
# Auto-swap # Auto-swap
# #
if (!$formfields['when']) { if (!$formfields['when']) {
$when = "never"; $when = "never";
} else { } else {
$when = $formfields['when']; $when = $formfields['when'];
} }
echo "<tr> echo "<tr>
<td><a href='plab_ez_footnote7.html' <td><a href='plab_ez_footnote7.html'
target='emulabfootnote'>Auto-terminate</a> slice after: target='emulabfootnote'>Auto-terminate</a> slice after:
...@@ -477,6 +485,9 @@ function MAKENS($formfields) { ...@@ -477,6 +485,9 @@ function MAKENS($formfields) {
"&formfields[exp_noidleswap_reason]=" . "&formfields[exp_noidleswap_reason]=" .
urlencode("PlanetLab experiment"); urlencode("PlanetLab experiment");
# XXX: until we want to use linktest on plab
$url .= "&formfields[exp_linktest]=0";
# #
# Batched? # Batched?
# #
...@@ -487,10 +498,14 @@ function MAKENS($formfields) { ...@@ -487,10 +498,14 @@ function MAKENS($formfields) {
# #
# Determine the auto-swap time # Determine the auto-swap time
# #
if ($formfields['when'] && ($formfields['when'] != 'never')) { if ($formfields['when']) {
$swaptime = $formfields['when'] * $formfields['units']; if (strcmp($formfields['when'], 'never') == 0) {
$url .= "&formfields[exp_autoswap]=1"; $url .= "&formfields[exp_autoswap]=0";
$url .= "&formfields[exp_autoswap_timeout]=$swaptime"; } else {
$swaptime = $formfields['when'] * $formfields['units'];
$url .= "&formfields[exp_autoswap]=1";
$url .= "&formfields[exp_autoswap_timeout]=$swaptime";
}
} }
# #
...@@ -524,7 +539,7 @@ function MAKENS($formfields) { ...@@ -524,7 +539,7 @@ function MAKENS($formfields) {
} }
if ($formfields['startupcmd']) { if ($formfields['startupcmd']) {
$nsgen_args .= "-v Startup='$formfields[startupcmd]' "; $nsgen_args .= "-v Startup='$formfields[startupcmd]' ";
} }
# #
# Note: We run this as nobody on purpose - this is really dumb, but later # Note: We run this as nobody on purpose - this is really dumb, but later
...@@ -545,7 +560,7 @@ function CHECKFORM($formfields) { ...@@ -545,7 +560,7 @@ function CHECKFORM($formfields) {
if (!preg_match("/^\d+$/",$formfields['count'],$matches)) { if (!preg_match("/^\d+$/",$formfields['count'],$matches)) {
$errors['count'] = "Number of nodes must be a positive integer"; $errors['count'] = "Number of nodes must be a positive integer";
} }
if ($formfields['when'] && ($formfields['when'] != "never") && if ($formfields['when'] && (strcmp($formfields['when'],"never") != 0) &&
(!preg_match("/^\d*(\.\d+)?$/",$formfields['when'],$matches))) { (!preg_match("/^\d*(\.\d+)?$/",$formfields['when'],$matches))) {
$errors['when'] = "Auto-terminate time must be a positive decimal " . $errors['when'] = "Auto-terminate time must be a positive decimal " .
"or 'never'"; "or 'never'";
......
...@@ -1221,6 +1221,21 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1221,6 +1221,21 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
} }
} }
#
# Discover whether to show or hide certain columns
#
$colcheck_query_result =
DBQueryFatal("SELECT sum(oi.OS = 'Windows') as winoscount, ".
" sum(nt.isplabdslice) as plabcount ".
"from reserved as r ".
"left join nodes as n on n.node_id=r.node_id ".
"left join os_info as oi on n.def_boot_osid=oi.osid ".
"left join node_types as nt on n.type = nt.type ".
"WHERE r.eid='$eid' and r.pid='$pid'");
$colcheckrow = mysql_fetch_array($colcheck_query_result);
$anywindows = $colcheckrow[winoscount];
$anyplab = $colcheckrow[plabcount];
if ($showlastlog) { if ($showlastlog) {
# #
# We need to extract, for each node, just the latest nodelog message. # We need to extract, for each node, just the latest nodelog message.
...@@ -1242,12 +1257,14 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1242,12 +1257,14 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
# every reserved node. # every reserved node.
# #
$query_result = $query_result =
DBQueryFatal("SELECT r.*,n.*,nt.isvirtnode,oi.OS,tip.tipname, ". DBQueryFatal("SELECT r.*,n.*,nt.isvirtnode,nt.isplabdslice, ".
" oi.OS,tip.tipname,wa.site,wa.hostname, ".
" ns.status as nodestatus, ". " ns.status as nodestatus, ".
" date_format(rsrv_time,\"%Y-%m-%d&nbsp;%T\") as rsrvtime, ". " date_format(rsrv_time,\"%Y-%m-%d&nbsp;%T\") as rsrvtime, ".
"nl.reported,nl.entry ". "nl.reported,nl.entry ".
"from reserved as r ". "from reserved as r ".
"left join nodes as n on n.node_id=r.node_id ". "left join nodes as n on n.node_id=r.node_id ".
"left join widearea_nodeinfo as wa on wa.node_id=n.phys_nodeid ".
"left join node_types as nt on nt.type=n.type ". "left join node_types as nt on nt.type=n.type ".
"left join node_status as ns on ns.node_id=r.node_id ". "left join node_status as ns on ns.node_id=r.node_id ".
"left join os_info as oi on n.def_boot_osid=oi.osid ". "left join os_info as oi on n.def_boot_osid=oi.osid ".
...@@ -1262,11 +1279,13 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1262,11 +1279,13 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
} }
else { else {
$query_result = $query_result =
DBQueryFatal("SELECT r.*,n.*,nt.isvirtnode,oi.OS,tip.tipname, ". DBQueryFatal("SELECT r.*,n.*,nt.isvirtnode,nt.isplabdslice, ".
" oi.OS,tip.tipname,wa.site,wa.hostname, ".
" ns.status as nodestatus, ". " ns.status as nodestatus, ".
" date_format(rsrv_time,\"%Y-%m-%d&nbsp;%T\") as rsrvtime ". " date_format(rsrv_time,\"%Y-%m-%d&nbsp;%T\") as rsrvtime ".
"from reserved as r ". "from reserved as r ".
"left join nodes as n on n.node_id=r.node_id ". "left join nodes as n on n.node_id=r.node_id ".
"left join widearea_nodeinfo as wa on wa.node_id=n.phys_nodeid ".
"left join node_types as nt on nt.type=n.type ". "left join node_types as nt on nt.type=n.type ".
"left join node_status as ns on ns.node_id=r.node_id ". "left join node_status as ns on ns.node_id=r.node_id ".
"left join os_info as oi on n.def_boot_osid=oi.osid ". "left join os_info as oi on n.def_boot_osid=oi.osid ".
...@@ -1288,6 +1307,13 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1288,6 +1307,13 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
<th><a href=\"$SCRIPT_NAME?pid=$pid&eid=$eid". <th><a href=\"$SCRIPT_NAME?pid=$pid&eid=$eid".
"&sortby=vname&showclass=$showclass\"> "&sortby=vname&showclass=$showclass\">
Name</a></th>\n"; Name</a></th>\n";
# Only show 'Site' column if there are plab nodes.
if ($anyplab) {
echo " <th>Site</th>
<th>Widearea<br>Hostname</th>\n";
}
if ($pid == $TBOPSPID) { if ($pid == $TBOPSPID) {
echo "<th>Reserved<br> echo "<th>Reserved<br>
<a href=\"$SCRIPT_NAME?pid=$pid&eid=$eid". <a href=\"$SCRIPT_NAME?pid=$pid&eid=$eid".
...@@ -1305,17 +1331,12 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1305,17 +1331,12 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
echo " <th>Last Log<br>Time</th> echo " <th>Last Log<br>Time</th>
<th>Last Log Message</th>\n"; <th>Last Log Message</th>\n";
} }
echo " <th><a href=\"docwrapper.php3?docname=ssh-mime.html\">SSH</a></th> echo " <th><a href=\"docwrapper.php3?docname=ssh-mime.html\">SSH</a></th>
<th><a href=\"faq.php3#tiptunnel\">Console</a></th> . <th><a href=\"faq.php3#tiptunnel\">Console</a></th> .
<th>Log</th>"; <th>Log</th>";
# Only put out a RDP column header if there are any Windows nodes. # Only put out a RDP column header if there are any Windows nodes.
$windows_query_result = DBQueryFatal("SELECT r.pid,r.eid,n.node_id,oi.OS ".
"from reserved as r ".
"left join nodes as n on n.node_id=r.node_id ".
"left join os_info as oi on n.def_boot_osid=oi.osid ".
"WHERE r.eid='$eid' and r.pid='$pid' and oi.OS='Windows'");
$anywindows = mysql_num_rows($windows_query_result);
if ($anywindows) { if ($anywindows) {
echo " <th> echo " <th>
<a href=\"docwrapper.php3?docname=rdp-mime.html\">RDP</a> <a href=\"docwrapper.php3?docname=rdp-mime.html\">RDP</a>
...@@ -1331,11 +1352,14 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1331,11 +1352,14 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {
$vname = $row[vname]; $vname = $row[vname];
$rsrvtime= $row[rsrvtime]; $rsrvtime= $row[rsrvtime];
$type = $row[type]; $type = $row[type];
$wasite = $row[site];
$wahost = $row[hostname];
$def_boot_osid = $row[def_boot_osid]; $def_boot_osid = $row[def_boot_osid];
$startstatus = $row[startstatus]; $startstatus = $row[startstatus];
$status = $row[nodestatus]; $status = $row[nodestatus];
$bootstate = $row[eventstate]; $bootstate = $row[eventstate];
$isvirtnode = $row[isvirtnode]; $isvirtnode = $row[isvirtnode];
$isplabdslice = $row[isplabdslice];
$tipname = $row[tipname]; $tipname = $row[tipname];
$iswindowsnode = $row[OS]=='Windows'; $iswindowsnode = $row[OS]=='Windows';
$idlehours = TBGetNodeIdleTime($node_id); $idlehours = TBGetNodeIdleTime($node_id);
...@@ -1358,6 +1382,16 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) { ...@@ -1358,6 +1382,16 @@ function SHOWNODES($pid, $eid, $sortby, $showclass) {