template = NULL; return; } $this->template = mysql_fetch_array($query_result); # # Underlying experiment for easy access. # $pid = $this->pid(); $eid = $this->eid(); if (! ($experiment = Experiment::LookupByPidEid($pid, $eid))) { $this->template = NULL; return; } $this->experiment = $experiment; } # Hmm, how does one cause an error in a php constructor? function IsValid() { return !is_null($this->template); } # Do class level lookup. function Lookup($guid, $vers) { $foo = new Template($guid, $vers); if ($foo->IsValid()) return $foo; return null; } # Do class level lookup for the root template. function LookupRoot($guid) { $foo = new Template($guid, 1); if ($foo->IsValid()) return $foo; return null; } # Look up by pid,eid is which also unique across templates. function LookupbyEid($pid, $eid) { $query_result = DBQueryWarn("select guid,vers from experiment_templates ". "where pid='$pid' and eid='$eid'"); if (!$query_result || !mysql_num_rows($query_result)) return null; $row = mysql_fetch_array($query_result); $guid = $row['guid']; $vers = $row['vers']; $foo = new Template($guid, $vers); if ($foo->IsValid()) return $foo; return null; } # # Refresh a template instance by reloading from the DB. # function Refresh() { if (! $this->IsValid()) return -1; $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryWarn("select * from experiment_templates ". "where guid='$guid' and vers='$vers'"); if (!$query_result || !mysql_num_rows($query_result)) { $this->template = NULL; return -1; } $this->template = mysql_fetch_array($query_result); return 0; } # accessors function guid() { return (is_null($this->template) ? -1 : $this->template['guid']); } function vers() { return (is_null($this->template) ? -1 : $this->template['vers']); } function pid() { return (is_null($this->template) ? -1 : $this->template['pid']); } function gid() { return (is_null($this->template) ? -1 : $this->template['gid']); } function eid() { return (is_null($this->template) ? -1 : $this->template['eid']); } function tid() { return (is_null($this->template) ? -1 : $this->template['tid']); } function uid() { return (is_null($this->template) ? -1 : $this->template['uid']); } function path() { if (!$this->experiment) return -1; $experiment = $this->experiment; return $experiment->path(); } function IsHidden() { return (is_null($this->template) ? -1 : $this->template['hidden']); } function IsActive() { return (is_null($this->template) ? -1 : $this->template['active']); } function created() { return (is_null($this->template) ? -1 : $this->template['created']); } function description() { return (is_null($this->template) ? -1 : $this->template['description']); } function parent_guid() { return (is_null($this->template) ? -1 :$this->template['parent_guid']); } function parent_vers() { return (is_null($this->template) ? -1 :$this->template['parent_vers']); } function child_vers() { return (is_null($this->template) ? -1 :$this->template['child_vers']); } # The root template has no parent guid. function IsRoot() { if (is_null($this->template)) return -1; return is_null($this->template['parent_guid']); } # Return the underlying experiment for this template. function GetExperiment() { return $this->experiment; } # Return the unixgid for operating on this template. function UnixGID() { $experiment = $this->experiment; return $experiment->UnixGID(); } function AccessCheck($user, $access_type) { global $TB_EXPT_READINFO; global $TB_EXPT_MODIFY; global $TB_EXPT_DESTROY; global $TB_EXPT_UPDATE; global $TB_EXPT_MIN; global $TB_EXPT_MAX; global $TBDB_TRUST_USER; global $TBDB_TRUST_LOCALROOT; global $TBDB_TRUST_GROUPROOT; global $TBDB_TRUST_PROJROOT; $mintrust = $TB_EXPT_READINFO; if ($access_type < $TB_EXPT_MIN || $access_type > $TB_EXPT_MAX) { TBERROR("Invalid access type: $access_type!", 1); } # # Admins do whatever they want! # if (ISADMIN()) { return 1; } $pid = $this->pid(); $gid = $this->gid(); $uid = $user->uid(); if ($access_type == $TB_EXPT_READINFO) { $mintrust = $TBDB_TRUST_USER; } else { $mintrust = $TBDB_TRUST_LOCALROOT; } # # Either proper permission in the group, or group_root in the project. # This lets group_roots muck with other peoples experiments, including # those in groups they do not belong to. # return TBMinTrust(TBGrpTrust($uid, $pid, $gid), $mintrust) || TBMinTrust(TBGrpTrust($uid, $pid, $pid), $TBDB_TRUST_GROUPROOT); } # # Display a template in its own table. # function Show() { $guid = $this->guid(); $vers = $this->vers(); $pid = $this->pid(); $gid = $this->gid(); $uid = $this->uid(); $tid = $this->tid(); $created = $this->created(); $description = $this->description(); $path = $this->path(); if (! ($user = User::Lookup($uid))) { TBERROR("Could not lookup object for user $uid", 1); } $showuser_url = CreateURL("showuser", $user); # # We need the metadata guid/version for the TID and description since # they are mungable metadata. # $tid_metadata = $this->LookupMetadataByName("TID"); $desc_metadata = $this->LookupMetadataByName("description"); if ($tid_metadata == NULL) { TBERROR("Could not find Metadata 'TID' for $guid/$vers", 1); } if ($desc_metadata == NULL) { TBERROR("Could not find Metadata 'description' for $guid/$vers",1); } $tid_guid = $tid_metadata->guid(); $tid_vers = $tid_metadata->vers(); $desc_guid = $desc_metadata->guid(); $desc_vers = $desc_metadata->vers(); # # Generate the table. # echo "

Details

\n"; echo "\n"; ShowItem("GUID", MakeLink("template", "guid=$guid&version=$vers", "$guid/$vers")); ShowItem("ID", MakeAnchor(CreateURL("template_metadata", $this) . "&action=modify". "&metadata=${tid_guid}/${tid_vers}", $tid)); ShowItem("Project", MakeLink("project", "pid=$pid", $pid)); ShowItem("Group", $gid); ShowItem("Creator", MakeAnchor($showuser_url, $uid)); ShowItem("Created", $created); echo "\n"; echo "\n"; $onmouseover = MakeMouseOver($description); if (strlen($description) > 40) { $description = substr($description, 0, 40) . " ... "; } ShowItem("Description", MakeAnchor(CreateURL("template_metadata", $this) . "&action=modify". "&metadata=${desc_guid}/${desc_vers}", $description, $onmouseover)); if (! $this->IsRoot()) { $parent_guid = $this->parent_guid(); $parent_vers = $this->parent_vers(); ShowItem("Parent Template", MakeLink("template", "guid=$parent_guid&version=$parent_vers", "$parent_guid/$parent_vers")); } echo "
Datastore Directory
$path
\n"; } # # Page header; spit back some html for the typical page header. # function PageHeader() { $guid = $this->guid(); $vers = $this->vers(); $html = "Template " . MakeLink("template", "guid=$guid&version=$vers", "$guid/$vers") . ""; return $html; } # # Display template parameters and default values in a table # function ShowParameters() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select p.name,p.value, ". " p.metadata_guid,p.metadata_vers, ". " m.value as description ". " from experiment_template_parameters as p ". "left join experiment_template_metadata_items as m ". " on m.guid=p.metadata_guid and ". " m.vers=p.metadata_vers ". "where p.parent_guid='$guid' and ". " p.parent_vers='$vers'"); if (!$query_result || !mysql_num_rows($query_result)) return 0; echo "

Parameters

\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; $metadata_guid = $row['metadata_guid']; $metadata_vers = $row['metadata_vers']; $description = $row['description']; if (!isset($value)) { $value = " "; } echo ""; if (is_null($description)) { $url = CreateURL("template_metadata", $this); echo "\n"; } else { $onmouseover = MakeMouseOver($description); if (strlen($description) > 30) { $description = substr($description, 0, 30) . " ... "; } $url = CreateURL("template_metadata", $this); echo "\n"; } echo "\n"; } echo "
Name Default Value Description
$name $value". "Click to add$description
\n"; return 1; } # # Display template metadata and values in a table # function ShowMetadata() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select i.* from experiment_template_metadata as m ". "left join experiment_template_metadata_items as i on ". " m.metadata_guid=i.guid and m.metadata_vers=i.vers ". "where m.parent_guid='$guid' and ". " m.parent_vers='$vers' and ". " m.internal=0 and m.hidden=0"); if (! mysql_num_rows($query_result)) return 0; echo "

Metadata

\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; $metadata_guid = $row['guid']; $metadata_vers = $row['vers']; $onmouseover = ""; if (!isset($value) || $value == "") { $value = " "; } else { $onmouseover = MakeMouseOver($value); if (strlen($value) > 40) { $value = substr($value, 0, 40) . " ... "; } } $meta_url = CreateURL("template_metadata", $this) . "&metadata=${metadata_guid}/${metadata_vers}"; echo "\n"; } echo "
Edit Delete Name Value
modify delete $name $value
\n"; return 1; } # # Show the instance list for a template. # function ShowInstances() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select e.*,count(r.node_id) as nodes, ". " round(minimum_nodes+.1,0) as min_nodes ". "from experiment_template_instances as i ". "left join experiments as e on e.idx=i.exptidx ". "left join reserved as r on e.pid=r.pid and ". " e.eid=r.eid ". "where e.pid is not null and ". " (i.parent_guid='$guid' and ". " i.parent_vers='$vers') ". "group by e.pid,e.eid order by e.state,e.eid"); if (! mysql_num_rows($query_result)) return; echo "

Template Instances

\n"; echo "\n"; $idlemark = "*"; $stalemark = "?"; while ($row = mysql_fetch_array($query_result)) { $pid = $row['pid']; $eid = $row['eid']; $state = $row['state']; $nodes = $row['nodes']; $minnodes = $row['min_nodes']; $ignore = $row['idle_ignore']; $name = $row['expt_name']; if (! ($experiment = Experiment::LookupByPidEid($pid, $eid))) { TBERROR("Could not map $pid/$eid to its object", 1); } $idlehours = $experiment->IdleTime(); $stale = $experiment->IdleStale(); if ($nodes == 0) { $nodes = "$minnodes"; } elseif ($row["swap_requests"] > 0) { $nodes .= $idlemark; } $idlestr = $idlehours; if ($idlehours > 0) { if ($stale) { $idlestr .= $stalemark; } if ($ignore) { $idlestr = "($idlestr)"; } } elseif ($idlehours == -1) { $idlestr = " "; } echo "\n"; } echo "
EID State Nodes
$eid $state $nodes
\n"; } # # Show the historical instance list for a template. # function ShowHistory($expand) { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select i.*,r.archive_tag ". " from experiment_template_instances as i ". "left join experiment_stats as s on ". " s.exptidx=i.exptidx ". "left join experiment_resources as r on ". " r.idx=s.rsrcidx ". "where (i.parent_guid='$guid' and ". " i.parent_vers='$vers') ". "order by i.start_time"); if (! mysql_num_rows($query_result)) return 0; echo "

Template History (Swapins)

\n"; echo "\n"; $idlemark = "*"; $stalemark = "?"; while ($row = mysql_fetch_array($query_result)) { $pid = $row['pid']; $eid = $row['eid']; $uid = $row['uid']; $start = $row['start_time']; $stop = $row['stop_time']; $exptidx = $row['exptidx']; $idx = $row['idx']; $tag = $row['archive_tag']; if (! isset($stop)) { $stop = " "; } $expandit = ((isset($expand) && $expand == $idx) ? 1 : 0); echo "\n"; echo " \n"; echo " \n"; echo " \n"; echo " "; echo " \n"; if ($expandit) { $instance = new TemplateInstance($exptidx); echo "\n"; echo " \n"; echo "\n"; echo " \n"; echo "\n"; } } echo "
Expand EID UID Start Time Stop Time Show Archive Export Replay Load DBs
"; if ($expandit) { echo "". "c\n"; } else { echo "". "e\n"; } echo " $eid$uid $start $stop". MakeLink("instance", "instance=$exptidx", "Show"); echo " i". MakeLink("export", "instance=$exptidx", "Show"); echo " ". MakeLink("swapin", "guid=$guid&version=$vers". "&replay_instance_idx=$exptidx", "Show"); echo " ". MakeLink("analyze", "instance=$exptidx", "Show"); echo "
 \n"; $instance->ShowRunList(0); echo "
\n"; } # # Dump the image map for a template to the output. # function ShowGraph() { $guid = $this->guid(); $vers = $this->vers(); # Make the link unique to force reload on the client side. $now = time(); $query_result = DBQueryFatal("select imap from experiment_template_graphs ". "where parent_guid='$guid'"); if (!mysql_num_rows($query_result)) { USERERROR("Experiment Template $guid is no longer in the DB!", 1); } $row = mysql_fetch_array($query_result); $imap = $row['imap']; echo "
"; echo "
\n"; echo "
\n"; echo "
\n"; echo $imap; echo "\n"; echo "
\n"; echo "
\n"; } # # Dump the NS file into its own iframe. # function ShowNS() { $guid = $this->guid(); $vers = $this->vers(); echo "
"; echo "\n"; echo "
"; } # # Dump the visualization into its own iframe. # function ShowVis($zoom = 1.25, $detail = 1) { $guid = $this->guid(); $pid = $this->pid(); $eid = $this->eid(); # Make the link unique to force reload on the client side. $now = time(); echo "
"; echo "
\n"; echo "
\n"; echo "\n"; echo "
\n"; echo "
\n"; } # # Grab the zoom and detail for the current viz picture, as a default. # function CurrentVisDetails() { $pid = $this->pid(); $eid = $this->eid(); $query_result = DBQueryFatal("select zoom,detail from vis_graphs ". "where pid='$pid' and eid='$eid'"); if (!mysql_num_rows($query_result)) { return array(1.25, 1); } $row = mysql_fetch_array($query_result); $zoom = $row['zoom']; $detail = $row['detail']; return array($zoom, $detail); } # # Grab array of input files for a template, indexed by input_idx. # function InputFiles() { $guid = $this->guid(); $vers = $this->vers(); $input_list = array(); $query_result = DBQueryFatal("select * from experiment_template_inputs ". "where parent_guid='$guid' and parent_vers='$vers'"); while ($row = mysql_fetch_array($query_result)) { $input_idx = $row['input_idx']; $input_query = DBQueryFatal("select input ". " from experiment_template_input_data ". "where idx='$input_idx'"); $input_row = mysql_fetch_array($input_query); $input_list[] = $input_row['input']; } return $input_list; } # # Return number of parameters. # function ParameterCount() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select name,value ". " from experiment_template_parameters ". "where parent_guid='$guid' and ". " parent_vers='$vers'"); return mysql_num_rows($query_result); } # # Return number of metadata items # function MetadataCount() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select internal ". " from experiment_template_metadata as m ". "where m.parent_guid='$guid' and ". " m.parent_vers='$vers' and ". " m.internal=0 and m.hidden=0"); return mysql_num_rows($query_result); } # # Return number of instances # function InstanceCount() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select * from experiment_template_instances as i ". "where (i.parent_guid='$guid' and ". " i.parent_vers='$vers')"); return mysql_num_rows($query_result); } # # Look for a metadata item in a template, by the guid/vers of the # metadata. Returns a class instance (see below). # function LookupMetadataByGUID($metadata_guid, $metadata_vers) { return TemplateMetadata::TemplateLookupByGUID($this, $metadata_guid, $metadata_vers); } # Ditto by name, function LookupMetadataByName($metadata_name) { return TemplateMetadata::TemplateLookupByName($this, $metadata_name); } # Grab the graph data. function GraphImage(&$image) { $guid = $this->guid(); $query_result = DBQueryWarn("select image from experiment_template_graphs ". "where parent_guid='$guid'"); if (!$query_result || !mysql_num_rows($query_result)) { return -1; } $row = mysql_fetch_array($query_result); $image = $row['image']; return 0; } # # Return an array of the formal parameters for a template. # function FormalParameters(&$parameters) { $parameters = array(); $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select name,value ". " from experiment_template_parameters ". "where parent_guid='$guid' and ". " parent_vers='$vers' ". "order by name"); while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; $parameters[$name] = $value; } return 0; } # # Return an array of the formal parameters for a template. # function FormalParameterMouseOvers(&$mouseovers) { $mouseovers = array(); $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select p.name,m.value as description ". " from experiment_template_parameters as p ". "left join experiment_template_metadata_items as m ". " on m.guid=p.metadata_guid and ". " m.vers=p.metadata_vers ". "where p.parent_guid='$guid' and ". " p.parent_vers='$vers'"); while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $description = $row['description']; if (isset($description) && $description != "") { $mouseovers[$name] = MakeMouseOver($description); } } return 0; } # # Find next candidate for a template (modify) TID # function NextTID() { $tid = $this->tid(); $guid = $this->guid(); $query_result = DBQueryFatal("select MAX(vers) from experiment_templates ". "where guid='$guid'"); if (mysql_num_rows($query_result) == 0) { return "T" . substr(md5(uniqid($foo, true)), 0, 10); } $row = mysql_fetch_array($query_result); $foo = $row[0] + 1; return "${tid}-V${foo}"; } # # Return array of template events, ordered by time. # function EventList(&$eventlist) { $eventlist = array(); $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select * from experiment_template_events ". "where parent_guid='$guid' and ". " parent_vers='$vers' ". "order by time"); $i = 0; while ($row = mysql_fetch_array($query_result)) { $eventlist[$i++] = $row; } return 0; } function EventCount() { $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select count(*) from experiment_template_events ". "where parent_guid='$guid' and ". " parent_vers='$vers' "); $row = mysql_fetch_array($query_result); $count = $row[0]; return $count; } function DeleteEvent($vname) { $guid = $this->guid(); $vers = $this->vers(); DBQueryFatal("delete from experiment_template_events ". "where parent_guid='$guid' and ". " parent_vers='$vers' and ". " vname='$vname'"); return 0; } function ModifyEvent($vname, $changes) { $guid = $this->guid(); $vers = $this->vers(); $sets = array(); while (list ($key, $value) = each ($changes)) { $value = addslashes($value); $sets[] = "$key='$value'"; } DBQueryFatal("update experiment_template_events set ". implode(",", $sets) . " ". "where parent_guid='$guid' and ". " parent_vers='$vers' and ". " vname='$vname'"); return 0; } } # # This is the class for a template instance (swapin). # class TemplateInstance { var $template; var $instance; var $experiment; # # Instances are found by their experiment index. # function TemplateInstance($exptidx) { $exptidx = addslashes($exptidx); $query_result = DBQueryFatal("select * ". " from experiment_template_instances ". "where exptidx='$exptidx'"); if (!$query_result || !mysql_num_rows($query_result)) { $this->template = NULL; $this->instance = NULL; return; } $this->instance = mysql_fetch_array($query_result); $this->template = new Template($this->instance['parent_guid'], $this->instance['parent_vers']); $this->experiment = Experiment::Lookup($exptidx); } # Hmm, how does one cause an error in a php constructor? function IsValid() { return !is_null($this->instance); } # Do class level lookup. function LookupByExptidx($exptidx) { $foo = new TemplateInstance($exptidx); if ($foo->IsValid()) return $foo; return null; } # accessors function idx() { return (is_null($this->instance) ? -1 : $this->instance['idx']); } function exptidx() { return (is_null($this->instance) ? -1 : $this->instance['exptidx']); } function runidx() { return (is_null($this->instance) ? -1 : $this->instance['runidx']); } function pid() { return (is_null($this->instance) ? -1 : $this->instance['pid']); } function eid() { return (is_null($this->instance) ? -1 : $this->instance['eid']); } function uid() { return (is_null($this->instance) ? -1 : $this->instance['uid']); } function guid() { return (is_null($this->instance) ? -1 : $this->instance['parent_guid']); } function vers() { return (is_null($this->instance) ? -1 : $this->instance['parent_vers']); } function start_time() { return (is_null($this->instance) ? -1 : $this->instance['start_time']); } function stop_time() { return (is_null($this->instance) ? -1 : $this->instance['stop_time']); } function pause_time() { return (is_null($this->instance) ? -1 : $this->instance['pause_time']); } function template() { return (is_null($this->instance) ? -1 : $this->template); } function GetTemplate() { return $this->template; } function GetExperiment() { return $this->experiment; } # # Load the project object for an experiment. # function Project() { $pid = $this->pid(); if (! ($project = Project::Lookup($pid))) { TBERROR("Could not lookup project $pid!", 1); } return $project; } # Is instance actually running (current experiment). function Instantiated() { return ($this->experiment ? 1 : 0); } # # Show an instance. # function Show($detailed, $withanno = 0) { $exptidx = $this->exptidx(); $runidx = $this->runidx(); $guid = $this->guid(); $vers = $this->vers(); $pid = $this->pid(); $uid = $this->uid(); $start = $this->start_time(); $stop = $this->stop_time(); $template= $this->template(); $pcount = $template->ParameterCount(); if (! ($user = User::Lookup($uid))) { TBERROR("Could not lookup object for user $uid", 1); } $showuser_url = CreateURL("showuser", $user); # If the instance is swapped in, we can provide a link to # experiment. if ($this->experiment) { $showexp_url = CreateURL("showexp", $this->experiment); } echo "
\n"; if ($detailed && $pcount) { echo "\n"; echo ""; echo ""; echo "\n"; echo ""; echo "
\n"; } echo "

Instance Details

\n"; echo "\n"; ShowItem("Template", MakeLink("template", "guid=$guid&version=$vers", "$guid/$vers")); ShowItem("ID", $exptidx); if ($this->experiment) { ShowItem("Experiment", MakeAnchor($showexp_url, $this->eid())); } ShowItem("Project", MakeLink("project", "pid=$pid", $pid)); ShowItem("Creator", MakeAnchor($showuser_url, $uid)); ShowItem("Started", $start); ShowItem("Stopped", (isset($stop) ? $stop : " ")); ShowItem("Current Run", (isset($runidx) ? $runidx : " ")); echo "
\n"; if ($detailed && $pcount) { echo "
      \n"; $this->ShowBindings(); echo "
\n"; } if ($withanno) { $this->ShowAnnotation(); } if ($detailed) { $this->ShowRunList(1); } echo "
\n"; } # # Page header; spit back some html for the typical page header. # function PageHeader() { $template = $this->template(); $exptidx = $this->exptidx(); $html = $template->PageHeader(); $guid = $this->guid(); $vers = $this->vers(); $eid = $this->eid(); $html .= ", Instance " . MakeLink("instance", "instance=$exptidx", $eid) . ""; return $html; } # # A variant that points to the active experiment. # function ExpPageHeader() { $template = $this->template(); $html = $template->PageHeader(); $guid = $this->guid(); $vers = $this->vers(); $pid = $this->pid(); $eid = $this->eid(); $html .= ", Instance " . MakeLink("project", "pid=$pid", $pid) . "/" . MakeLink("experiment", "pid=$pid&eid=$eid", $eid) . ""; return $html; } # # Ditto for a run, although run should its own class. # function RunPageHeader($runidx) { $template = $this->template(); $exptidx = $this->exptidx(); $html = $this->PageHeader(); $guid = $this->guid(); $vers = $this->vers(); $eid = $this->eid(); $runid = $this->GetRunID($runidx); $html .= ", Run " . MakeAnchor(CreateURL("experimentrun_show", $this, "runidx", $runidx), $runid) . ""; return $html; } # # Show the current bindings. This depends on the state of the instance. # If not swapped in, the instance bindings are current. If swapped in, # the most recent run bindings are current (current run, or last run). # function ShowCurrentBindings() { global $TB_EXPTSTATE_SWAPPED; if ($this->experiment) { $experiment = $this->experiment; if ($experiment->state() == $TB_EXPTSTATE_SWAPPED) { # Show the instance bindings is swapped. return $this->ShowBindings(); } elseif ($this->runidx()) { return $this->ShowRunBindings(); } return $this->ShowLastRunBindings(); } return $this->ShowBindings(); } # # Display instance bindings in a table # function ShowBindings() { $instance_idx = $this->idx(); $query_result = DBQueryWarn("select * from experiment_template_instance_bindings ". "where instance_idx='$instance_idx'"); if (!mysql_num_rows($query_result)) return 0; echo "

Instance Bindings

\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; if (!isset($value)) { $value = " "; } echo "\n"; } echo "
Name Value
$name $value
\n"; return 1; } # # Display run bindings in a table # function ShowRunBindings($runidx = null) { $exptidx = $this->exptidx(); if (! $runidx) { $runidx = $this->runidx(); } $query_result = DBQueryWarn("select * from experiment_run_bindings ". "where exptidx='$exptidx' and runidx='$runidx' ". "order by name"); if (!mysql_num_rows($query_result)) return 0; echo "

Run Bindings

\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; if (!isset($value)) { $value = " "; } echo "\n"; } echo "
Name Value
$name $value
\n"; return 1; } # # Display last run bindings in a table # function ShowLastRunBindings() { return $this->ShowRunBindings($this->LastRunIdx()); } # # Show the run list for an instance. # function ShowRunList($withheader) { $exptidx = $this->exptidx(); $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select * from experiment_runs ". "where exptidx='$exptidx'"); if (! mysql_num_rows($query_result)) return 0; if ($withheader) { echo "

Instance History (Runs)

\n"; } echo "\n"; echo "\n"; while ($rrow = mysql_fetch_array($query_result)) { $runidx = $rrow['idx']; $runid = $rrow['runid']; $start = $rrow['start_time']; $stop = $rrow['stop_time']; $exptidx = $rrow['exptidx']; $start_tag = $rrow['starting_archive_tag']; $end_tag = $rrow['ending_archive_tag']; $description = $rrow['description']; $onmouseover = ""; if (! isset($stop)) { $stop = " "; } if (isset($description) && $description != "") { $onmouseover = MakeMouseOver($description); if (strlen($description) > 30) { $description = substr($description, 0, 30) . " ..."; } } else { $description = "  "; } if (isset($end_tag) && $end_tag != "") { $archive_link = "". "i"; } else { $archive_link = "  "; } echo "\n"; echo " \n"; } echo "
RunID ID Start Time Stop Time Description
". MakeAnchor(CreateURL("experimentrun_show", $this, "runidx", $runidx), "$runid"); echo " $runidx $start $stop $description
\n"; } # # Get the annotation for an instance, or a link to create one. # function GetAnnotation() { $exptidx = $this->exptidx(); $annoname = "__instance_annotation_${exptidx}"; $template = $this->template(); if (($metadata = $template->LookupMetadataByName($annoname))) { return $metadata->value(); } return null; } function GetRunAnnotation($runidx) { $exptidx = $this->exptidx(); $annoname = "__experimentrun_annotation_${exptidx}_${runidx}"; $template = $this->template(); if (($metadata = $template->LookupMetadataByName($annoname))) { return $metadata->value(); } return null; } function SetAnnotation($this_user, $annotation) { $exptidx = $this->exptidx(); $annoname = "__instance_annotation_${exptidx}"; $template = $this->template(); $uid = $this_user->uid(); $foo = rand(); $datafile = "/tmp/${uid}-${foo}.txt"; $guid = $template->guid(); $vers = $template->vers(); $action = ($this->GetAnnotation() ? "modify" : "add"); if (! ($fp = fopen($datafile, "w"))) { TBERROR("Could not create temporary file $datafile", 1); } fwrite($fp, $annotation); fclose($fp); chmod($datafile, 0666); SUEXEC($this_user->uid(), $template->pid(), "webtemplate_metadata -a $action -f $datafile -t annotation ". " $annoname $guid/$vers", SUEXEC_ACTION_CONTINUE); unlink($datafile); return 0; } function SetRunAnnotation($this_user, $runidx, $annotation) { $exptidx = $this->exptidx(); $annoname = "__experimentrun_annotation_${exptidx}_${runidx}"; $template = $this->template(); $uid = $this_user->uid(); $foo = rand(); $datafile = "/tmp/${uid}-${foo}.txt"; $guid = $template->guid(); $vers = $template->vers(); $action = ($this->GetRunAnnotation($runidx) ? "modify" : "add"); if (! ($fp = fopen($datafile, "w"))) { TBERROR("Could not create temporary file $datafile", 1); } fwrite($fp, $annotation); fclose($fp); chmod($datafile, 0666); SUEXEC($this_user->uid(), $template->pid(), "webtemplate_metadata -a $action -f $datafile -t annotation ". " $annoname $guid/$vers", SUEXEC_ACTION_CONTINUE); unlink($datafile); return 0; } # # Display annotation in text box with button to change. # function ShowAnnotation($longform = 0) { $annotation = $this->GetAnnotation(); $cols = ($longform ? 25 : 5); if (! $annotation) { $annotation = ""; } echo "
"; echo "Annotation
\n"; echo "
\n"; echo "
"; echo "\n"; echo "
"; if (! $longform) { echo "\n"; } } function ShowRunAnnotation($runidx) { $annotation = $this->GetRunAnnotation($runidx); if (! $annotation) { $annotation = ""; } echo "
"; echo "Annotation
\n"; echo "
\n"; echo "
"; echo "\n"; echo "
"; echo "\n"; } # # Check if a valid run. # function ValidRun($runidx) { $exptidx = $this->exptidx(); $runidx = addslashes($runidx); $query_result = DBQueryFatal("select * from experiment_runs ". "where exptidx='$exptidx' and idx='$runidx'"); return mysql_num_rows($query_result); } # # Show details for an experiment run # function ShowRun($runidx) { $runidx = addslashes($runidx); $exptidx = $this->exptidx(); $guid = $this->guid(); $vers = $this->vers(); $query_result = DBQueryFatal("select r.* from experiment_runs as r ". "left join experiment_template_instances as i on ". " i.exptidx=r.exptidx ". "where r.exptidx='$exptidx' and r.idx='$runidx'"); if (!mysql_num_rows($query_result)) return; $row = mysql_fetch_array($query_result); $start = $row['start_time']; $stop = $row['stop_time']; $runid = $row['runid']; $start_tag = $row['starting_archive_tag']; $end_tag = $row['ending_archive_tag']; $description = $row['description']; if (!isset($stop)) $stop = " "; echo "
\n"; echo "\n"; echo ""; echo "\n"; $query_result = DBQueryFatal("select * from experiment_run_bindings ". "where exptidx='$exptidx' and runidx='$runidx'"); if (mysql_num_rows($query_result)) { echo "\n"; echo "\n"; } echo "\n"; echo "
\n"; echo "

Run Details

\n"; echo "\n"; ShowItem("Template", MakeLink("template", "guid=$guid&version=$vers", "$guid/$vers")); ShowItem("Instance", MakeLink("instance", "instance=$exptidx", "$exptidx")); ShowItem("ID", $runidx); ShowItem("Started", $start); ShowItem("Stopped", $stop); ShowItem("Start Tag", $start_tag); ShowItem("End Tag", $end_tag); if (isset($description) && $description != "") { echo "\n"; } echo "
Description
\n"; echo "
      \n"; echo "

Run Bindings

\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; if (!isset($value)) { $value = " "; } echo "\n"; } echo "
Name Value
$name $value
\n"; echo "
\n"; $this->ShowRunAnnotation($runidx); $archive_url = "cvsweb/cvsweb.php3/$exptidx/tags/runs/$runid/?instance=$exptidx". "&embedded=1"; echo "

File Archive

\n"; echo "
\n"; } # # Find next candidate for an experiment run. # function NextRunID() { $exptidx = $this->exptidx(); $eid = $this->eid(); $query_result = DBQueryFatal("select MAX(idx) from experiment_runs ". "where exptidx='$exptidx'"); if (mysql_num_rows($query_result) == 0) { return 0; } $row = mysql_fetch_array($query_result); $foo = $row[0] + 1; return "${eid}-R${foo}"; } # # Get runid from a runidx; run needs to be its own class! # function GetRunID($runidx) { $exptidx = $this->exptidx(); $query_result = DBQueryFatal("select r.runid from experiment_runs as r ". "where r.exptidx='$exptidx' and r.idx='$runidx'"); if (!mysql_num_rows($query_result)) return ""; $row = mysql_fetch_array($query_result); return $row[0]; } # # Return an array of the bindings for a template instance. # function Bindings(&$bindings) { $bindings = array(); $guid = $this->guid(); $vers = $this->vers(); $instance_idx = $this->idx(); $query_result = DBQueryFatal("select * ". " from experiment_template_instance_bindings ". "where parent_guid='$guid' and parent_vers='$vers' ". " and instance_idx='$instance_idx' ". "order by name"); while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; $bindings[$name] = $value; } return 0; } # # Return an array of the bindings for a run of template instance. # function RunBindings($runidx, &$bindings) { $bindings = array(); $instance_idx = $this->idx(); $exptidx = $this->exptidx(); $query_result = DBQueryFatal("select * from experiment_run_bindings ". "where exptidx='$exptidx' and runidx='$runidx' ". "order by name"); while ($row = mysql_fetch_array($query_result)) { $name = $row['name']; $value = $row['value']; $bindings[$name] = $value; } return 0; } # # Return in the index of the most recent run. # function LastRunIdx() { $exptidx = $this->exptidx(); $query_result = DBQueryFatal("select idx from experiment_runs ". "where exptidx='$exptidx' ". "order by idx desc limit 1"); if (!mysql_num_rows($query_result)) { return 0; } $row = mysql_fetch_array($query_result); return $row[0]; } # # Show graph stuff, either for entire instance or for a run. Very hacky. # function ShowGraph($graphtype = "pps", $runidx = -1, $src = "all", $dst = "all" ) { $exptidx = $this->exptidx(); $runarg = ($runidx >= 0 ? "&runidx=$runidx" : ""); $srcarg = ""; $dstarg = ""; # Make the link unique to force reload on the client side. $now = time(); $pid = $this->pid(); if ($this->Instantiated()) { $eid = $this->eid(); } else { $template = $this->template(); $eid = $template->eid(); } # # Lets check args! # if (! preg_match("/^[\w]*$/", $graphtype) || ! preg_match("/^[-\d]*$/", $runidx) || ! preg_match("/^[-\w\/]*$/", $src) || ! preg_match("/^[-\w\/]*$/", $dst)) { return ""; } # Pass along the src/dst args to the graphing page. if ($src != "" && $src != "all") $srcarg = "&srcvnode=$src"; if ($dst != "" && $dst != "all") $dstarg = "&dstvnode=$dst"; # # Grab a list of vnode names so that user can select a specific # source and destination. # $query_result = DBQueryFatal("select vname,vnode from virt_lans ". "where pid='$pid' and eid='$eid' and trace_db!=0"); $html = ""; $html .= "
\n"; $html .= "

"; $html .= "
\n"; $html .= " Working ..."; $html .= "
\n"; $html .= "
\n"; $html .= " "; $html .= "Packets\n"; $html .= "\n"; $html .= "        "; $html .= ""; mysql_data_seek($query_result, 0); $html .= "  "; $html .= ""; echo $html; return 0; } function ShowGraphArea($graphtype = "pps", $runidx = -1, $src = "all", $dst = "all") { echo "
\n"; $this->ShowGraph($graphtype, $runidx, $src, $dst); echo "
\n"; } } # # This is the class for metadata. # class TemplateMetadata { var $template; var $metadata; # # # function TemplateMetadata($guid, $vers) { $guid = addslashes($guid); $vers = addslashes($vers); # # Ug. I think the metadata_type field is going to have to move # into the experiment_template_metadata_items table. # $query_result = DBQueryFatal("select i.*,m.metadata_type ". " from experiment_template_metadata_items as i ". "left join experiment_template_metadata as m on ". " m.metadata_guid=i.guid and ". " m.metadata_vers=i.vers ". "where i.guid='$guid' and i.vers='$vers'"); if (!$query_result || !mysql_num_rows($query_result)) { $this->template = NULL; $this->metadata = NULL; return; } $this->metadata = mysql_fetch_array($query_result); $this->template = NULL; } # Hmm, how does one cause an error in a php constructor? function IsValid() { return !is_null($this->metadata); } # Do class level lookup. function Lookup($guid, $vers) { $foo = new TemplateMetadata($guid, $vers); if ($foo->IsValid()) return $foo; return null; } function TemplateLookupByGUID($template, $guid, $vers) { $metadata_guid = addslashes($guid); $metadata_vers = addslashes($vers); $template_guid = $template->guid(); $template_vers = $template->vers(); $query_result = DBQueryFatal("select internal from experiment_template_metadata ". "where parent_guid='$template_guid' and ". " parent_vers='$template_vers' and ". " metadata_guid='$metadata_guid' and ". " metadata_vers='$metadata_vers'"); if (! mysql_num_rows($query_result)) return null; $foo = new TemplateMetadata($guid, $vers); if (! $foo->IsValid()) return null; $foo->template = $template; return $foo; } function TemplateLookupByName($template, $name) { $metadata_name = addslashes($name); $template_guid = $template->guid(); $template_vers = $template->vers(); $query_result = DBQueryFatal("select i.guid,i.vers ". " from experiment_template_metadata as m ". "left join experiment_template_metadata_items as i on ". " i.guid=m.metadata_guid and i.vers=m.metadata_vers ". "where m.parent_guid='$template_guid' and ". " m.parent_vers='$template_vers' and ". " i.name='$metadata_name'"); if (! mysql_num_rows($query_result)) return null; $row = mysql_fetch_array($query_result); $metadata_guid = $row['guid']; $metadata_vers = $row['vers']; $foo = new TemplateMetadata($metadata_guid, $metadata_vers); if (! $foo->IsValid()) return null; $foo->template = $template; return $foo; } # accessors function guid() { return (is_null($this->metadata) ? -1 : $this->metadata['guid']); } function vers() { return (is_null($this->metadata) ? -1 : $this->metadata['vers']); } function name() { return (is_null($this->metadata) ? -1 : $this->metadata['name']); } function value() { return (is_null($this->metadata) ? -1 : $this->metadata['value']); } function type() { return (is_null($this->metadata) ? -1 : $this->metadata['metadata_type']); } function parent_guid() { return (is_null($this->metadata) ? -1 : $this->metadata['parent_guid']); } function parent_vers() { return (is_null($this->metadata) ? -1 : $this->metadata['parent_vers']); } function template_guid() { return (is_null($this->metadata) ? -1 : $this->metadata['template_guid']); } function created() { return (is_null($this->metadata) ? -1 : $this->metadata['created']); } function uid() { return (is_null($this->metadata) ? -1 : $this->metadata['uid']); } # # Display a metadata item in its own table. # function Show() { $metadata_guid = $this->guid(); $metadata_vers = $this->vers(); $created = $this->created(); $metadata_name = $this->name(); $metadata_value = $this->value(); $metadata_type = $this->type(); echo "\n"; ShowItem("GUID", "$metadata_guid/$metadata_vers"); ShowItem("Name", $metadata_name); if (ISADMIN() && isset($metadata_type)) { ShowItem("Type", $metadata_type); } ShowItem("Created", $created); if (! is_null($this->template)) { $template_guid = $template->guid(); $template_vers = $template->vers(); ShowItem("Template", MakeLink("template", "guid=$template_guid&version=$template_vers", "$template_guid/$template_vers")); } if ($this->parent_guid()) { $parent_guid = $this->parent_guid(); $parent_vers = $this->parent_vers(); ShowItem("Parent Version", MakeLink("metadata", "action=show&guid=$parent_guid". "&version=$parent_vers", "$parent_guid/$parent_vers")); } echo "\n"; echo "
Metadata Value
\n"; } } # Helper function function ShowItem($tag, $value, $default = " ") { if (!isset($value)) { $value = $default; } echo "${tag}: $value\n"; } function MakeLink($which, $args, $text) { $page = ""; if ($which == "project") { $page = "showproject.php3"; } elseif ($which == "user") { $page = "showuser.php3"; } elseif ($which == "template") { $page = "template_show.php"; } elseif ($which == "metadata") { $page = "template_metadata.php"; } elseif ($which == "instance") { $page = "instance_show.php"; } elseif ($which == "run") { $page = "experimentrun_show.php"; } elseif ($which == "experiment") { $page = "showexp.php3"; } elseif ($which == "export") { $page = "template_export.php"; } elseif ($which == "analyze") { $page = "template_analyze.php"; } elseif ($which == "swapin") { $page = "template_swapin.php"; } return "$text"; } # # New version of above function, will replace it eventually. # function MakeAnchor($url, $text, $anchor_args = "") { return "$text"; } # # Display a list of templates in its own table. Optional # function SHOWTEMPLATELIST($which, $all, $myuid, $id, $gid = "") { if ($which == "USER") { $where = "t.uid='$id'"; $title = "Current"; } elseif ($which == "PROJ") { $where = "t.pid='$id'"; $title = "Project"; } elseif ($which == "GROUP") { $where = "t.pid='$id' and t.gid='$gid'"; $title = "Group"; } elseif ($which == "TEMPLATE") { $where = "t.guid='$id' or t.parent_guid='$id'"; $title = "Template"; } else { $where = "1"; } if (ISADMIN()) { $query_result = DBQueryFatal("select t.* from experiment_templates as t ". "where ($where) and ". " (t.active!=0 or t.parent_guid is null) ". "order by t.pid,t.guid,vers desc"); } else { $query_result = DBQueryFatal("select t.* from experiment_templates as t ". "left join group_membership as g on g.pid=t.pid and ". " g.gid=t.gid and g.uid='$myuid' ". "where g.uid is not null and ($where) and ". " (t.active!=0 or t.parent_guid is null) ". "order by t.pid,t.guid,vers desc"); } if (mysql_num_rows($query_result)) { echo "

$title Templates

\n"; echo "\n"; # Do not show root template if other templates are active for guid. $lastguid = 0; while ($row = mysql_fetch_array($query_result)) { $guid = $row['guid']; $pid = $row['pid']; $gid = $row['gid']; $tid = $row['tid']; $vers = $row['vers']; if ($guid == $lastguid && $vers == 1) continue; $lastguid = $guid; echo "\n"; } echo "
GUID TID PID/GID
" . MakeLink("template", "guid=$guid&version=$vers", "$guid/$vers") . " $tid " . MakeLink("project", "pid=$pid", "$pid/$gid") ."
\n"; } } # # Slot checking support # function TBvalid_template_description($token) { return TBcheck_dbslot($token, "experiment_templates", "description", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function TBvalid_guid($token) { return TBcheck_dbslot($token, "experiment_templates", "guid", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function TBvalid_template_parameter_description($token) { return TBcheck_dbslot($token, "experiment_templates", "description", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function TBvalid_template_metadata_name($token) { return TBcheck_dbslot($token, "experiment_template_metadata", "name", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function TBvalid_template_metadata_value($token) { return TBcheck_dbslot($token, "experiment_template_metadata", "value", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function TBvalid_template_metadata_type($token) { return TBcheck_dbslot($token, "experiment_template_metadata", "metadata_type", TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR); } function MakeMouseOver($string) { $string = ereg_replace("\n", "
", $string); $string = ereg_replace("\r", "", $string); $string = htmlentities($string); $string = preg_replace("/\'/", "\&\#039;", $string); return "onmouseover=\"return escape('$string')\""; } ?>