gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r33122 - in eclectic: . gplmt-ui


From: gnunet
Subject: [GNUnet-SVN] r33122 - in eclectic: . gplmt-ui
Date: Tue, 22 Apr 2014 18:03:11 +0200

Author: otarabai
Date: 2014-04-22 18:03:10 +0200 (Tue, 22 Apr 2014)
New Revision: 33122

Added:
   eclectic/gplmt-ui/data.sql
   eclectic/gplmt-ui/diff
   eclectic/gplmt-ui/schema.sql
Removed:
   eclectic/gplmt-ui/zabbix.diff
Modified:
   eclectic/gplmt-ui/README
   eclectic/installation-guide.tex
Log:
Fixed eclectic zabbix diff file


Modified: eclectic/gplmt-ui/README
===================================================================
--- eclectic/gplmt-ui/README    2014-04-22 11:29:18 UTC (rev 33121)
+++ eclectic/gplmt-ui/README    2014-04-22 16:03:10 UTC (rev 33122)
@@ -1,4 +1,8 @@
 GPLMT Web UI
 ============
 
-This is a diff which has to be applied against Zabbix version 2.2
\ No newline at end of file
+This is a diff which has to be applied against Zabbix version 2.0.4
+
+schema.sql and data.sql to be applied to Zabbix mysql database
+
+See ../installation-guide.pdf for more details

Added: eclectic/gplmt-ui/data.sql
===================================================================
--- eclectic/gplmt-ui/data.sql                          (rev 0)
+++ eclectic/gplmt-ui/data.sql  2014-04-22 16:03:10 UTC (rev 33122)
@@ -0,0 +1,54 @@
+-- phpMyAdmin SQL Dump
+-- version 3.4.11.1deb2
+-- http://www.phpmyadmin.net
+--
+-- Host: localhost
+-- Generation Time: Sep 26, 2013 at 04:40 PM
+-- Server version: 5.5.31
+-- PHP Version: 5.4.4-14+deb7u4
+
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+--
+-- Database: `zabbix`
+--
+
+--
+-- Dumping data for table `exp_config`
+--
+
+INSERT INTO `exp_config` (`configid`, `section`, `name`, `label`, 
`description`, `type`, `default_value`, `user_editable`) VALUES
+(1, 'ssh', 'ssh_username', 'SSH username', 'Username for SSH access', 'text', 
'', 1),
+(2, 'ssh', 'ssh_password', 'SSH password', 'Password for SSH access or 
password for the SSH keyfile', 'password', '', 1),
+(3, 'ssh', 'ssh_keyfile', 'SSH keyfile', 'SSH key for login', 'file', '', 1),
+(16, 'gplmt', 'notification', 'Notification', 'Which notification mechanism to 
use: simple, result', 'text', 'result', 0),
+(17, 'gplmt', 'max_parallelism', 'Max Parallelism', 'Number of parallel 
workers, use 0 for unlimited', 'integer', '10', 0),
+(18, 'planetlab', 'slice', 'Planetlab Slice', 'Name of your PlanetLab Slice', 
'text', '', 1),
+(20, 'planetlab', 'api_url', 'PLC/PLE', 'Use PlanetLab Central or PlanetLab 
Europe', 'enum', 'https://www.planet-lab.eu/PLCAPI/', 1),
+(21, 'planetlab', 'username', 'PlanetLab API username', 'Your login to the 
planetlab website\r\nto access the planetlab API', 'text', '', 1),
+(22, 'planetlab', 'password', 'PlanetLab API password', 'Your password for the 
planetlab\r\nwebsite to access the planetlab API', 'password', '', 1),
+(25, 'ssh', 'ssh_transfer', 'SSH Transfer', 'Protocol for put get operations: 
scp, sftp', 'text', 'scp', 0),
+(26, 'ssh', 'ssh_use_known_hosts', 'SSH: Use Known Hosts', 'Use system''s SSH 
"known hosts" file', 'boolean', 'yes', 0),
+(27, 'ssh', 'add_unkown_hostkeys', 'SSH: Add Unknown Hostkeys', 'Add node 
hostkeys automatically', 'boolean', 'yes', 0),
+(28, 'gplmt', 'userdir', 'User Directory', 'User specific directory for 
put/get operations', 'text', '', 0);
+
+INSERT INTO `zabbix`.`exp_config` (`configid`, `section`, `name`, `label`, 
`description`, `type`, `default_value`, `user_editable`) VALUES (NULL, 
'planetlab', 'pl_keyfile', 'Planetlab keyfile', 'Private key file for 
connecting to planetlab nodes', 'file', '', '1'), (NULL, 'planetlab', 
'pl_keyfile_password', 'Planetlab keyfile password', 'Password used to unlock 
private key file (if needed)', 'password', '', '1');
+
+--
+-- Dumping data for table `exp_configenum`
+--
+
+INSERT INTO `exp_configenum` (`id`, `configid`, `label`, `value`) VALUES
+(1, 20, 'Planetlab Central', 'https://www.planet-lab.org/PLCAPI/'),
+(2, 20, 'Planetlab Europe', 'https://www.planet-lab.eu/PLCAPI/');
+
+/*!40101 SET address@hidden */;
+/*!40101 SET address@hidden */;
+/*!40101 SET address@hidden */;

Added: eclectic/gplmt-ui/diff
===================================================================
--- eclectic/gplmt-ui/diff                              (rev 0)
+++ eclectic/gplmt-ui/diff      2014-04-22 16:03:10 UTC (rev 33122)
@@ -0,0 +1,3058 @@
+diff --git conf.php conf.php
+new file mode 100644
+index 0000000..c88d8a6
+--- /dev/null
++++ conf.php
+@@ -0,0 +1,31 @@
++<?php
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('User Configuration');
++$page['file'] = 'conf.php';
++$page['hist_arg'] = array('confid');
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++/*
++ * Actions
++ */
++if(isset($_REQUEST['update']))
++{
++    //print_r($_REQUEST);
++    expconfig_update($_REQUEST);
++}
++
++/*
++ * Display
++ */
++$filesView = new CView('experiments.conf');
++
++$filesView->set('conf', expconfig_getuserconfig());
++
++$filesView->render();
++$filesView->show();
++
++require_once dirname(__FILE__).'/include/page_footer.php';
+diff --git conf/.gitignore conf/.gitignore
+new file mode 100644
+index 0000000..d6cdf1c
+--- /dev/null
++++ conf/.gitignore
+@@ -0,0 +1 @@
++zabbix.conf.php
+diff --git dashboard.php dashboard.php
+index fe17a67..e71abb8 100644
+--- dashboard.php
++++ dashboard.php
+@@ -253,6 +253,11 @@ insert_js('var page_menu='.zbx_jsvalue($menu).";\n".'var 
page_submenu='.zbx_jsva
+  */
+ $leftColumn = array();
+ 
++// Manage monitoring
++$manage_wdgt = new CUIWidget('hat_managemonitoring', 
make_manage_monitoring(), 1);
++$manage_wdgt->setHeader(_('Manage Monitoring'));
++$leftColumn[] = $manage_wdgt;
++
+ // favorite graphs
+ $graph_menu = get_icon('menu', array('menu' => 'graphs'));
+ $fav_grph = new CUIWidget('hat_favgrph', make_favorite_graphs(), 
CProfile::get('web.dashboard.hats.hat_favgrph.state', 1));
+@@ -297,6 +302,12 @@ if ($USER_DETAILS['type'] == USER_TYPE_SUPER_ADMIN) {
+       $rightColumn[] = $zbxStatus;
+ }
+ 
++// run scripts
++$scripts_wdgt = new CUIWidget('hat_runscripts', make_run_scripts(), 1);
++$scripts_wdgt->setHeader(_('Run Scripts'));
++//$scripts_wdgt->setFooter(new CLink(_('Graphs').' &raquo;', 'charts.php', 
'highlight'), true);
++$rightColumn[] = $scripts_wdgt;
++
+ // system status
+ $refresh_menu = new CIcon(_('Menu'), 'iconmenu', 
'create_page_menu(event,"hat_syssum");');
+ $sys_stat = new CUIWidget('hat_syssum', new CSpan(_('Loading...'), 
'textcolorstyles'), CProfile::get('web.dashboard.hats.hat_syssum.state', 1));
+diff --git execute.php execute.php
+new file mode 100644
+index 0000000..0428d3e
+--- /dev/null
++++ execute.php
+@@ -0,0 +1,69 @@
++<?php
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('Deploy & Execute');
++$page['file'] = 'execute.php';
++$page['hist_arg'] = array('execid');
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
++/*$fields = array(
++      'run' =>                array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 
null),
++      'nodes' =>              array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 
'isset({run})'),
++      'usetasklist' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, IN('0,1'), 
'isset({run})'),
++      'tasklist' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, 
'isset({run})'),
++      'cmd' =>   array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 'isset({run})'),
++      'sync' =>   array(T_ZBX_INT, O_OPT, null, null, null)
++);
++check_fields($fields);*/
++
++
++/*
++ * Actions
++ */
++
++if(isset($_REQUEST['run']))
++{
++    $usetasklist = intval($_REQUEST['usetasklist']);
++    $tasklist = intval($_REQUEST['tasklist']);
++
++    $cmd = trim($_REQUEST['cmd']);
++    $cmd_empty = empty($cmd);
++    
++    if($usetasklist == 0 && $cmd_empty)
++        error("Please specify the command to run.");
++    elseif(!isset($_REQUEST['target']))
++        error("Please specify target.");
++    elseif(!isset($_REQUEST['hosts']) || count($_REQUEST['hosts']) == 0)
++        error("Please specify hosts to run");
++    else
++    {
++        $res = exprun_new($_REQUEST['target'], $_REQUEST['hosts'], 
$usetasklist, $tasklist, $cmd);
++        if($res == EXP_ERR_GPLMT_DIR)
++            error("Could not verify GPLMT files, please make sure that they 
exist and write permissions are enabled.");
++        elseif($res == EXP_ERR_PERMISSION)
++            error("Permission error.");
++        elseif($res == EXP_ERR_INVALID_TARGET)
++            error("Invalid target!");
++        else
++            jsRedirect('results.php');
++    }
++}
++
++/*
++ * Display
++ */
++
++$execView = new CView('experiments.execute');
++
++$execView->set('tasklists', exptasklist_getall());
++$execView->set('targets', $exp_targetlist);
++$execView->set('currenttarget', 
isset($_REQUEST['target'])?$_REQUEST['target']:reset($exp_targetlist));
++
++$execView->render();
++$execView->show();
++
++require_once dirname(__FILE__).'/include/page_footer.php';
+diff --git files.php files.php
+new file mode 100644
+index 0000000..5326ccc
+--- /dev/null
++++ files.php
+@@ -0,0 +1,58 @@
++<?php
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('User Files');
++$page['file'] = 'files.php';
++$page['hist_arg'] = array('fileid');
++
++//before any headers are written, check if trying to download
++if(isset($_REQUEST['download']))
++{
++    $filename = $_REQUEST['download'];
++    
++    expfiles_download($filename);
++}
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
++/*$fields = array(
++);
++check_fields($fields);*/
++
++/*
++ * Actions
++ */
++if(isset($_REQUEST['upload']) && isset($_FILES['file']))
++{
++    //some validations
++    if($_FILES["file"]["error"] > 0)
++        error('File upload error: '.$_FILES["file"]["error"]);
++    else
++    {
++        $filename = $_FILES["file"]["name"];
++        $fullpath = expfiles_getnewfilepath($filename);
++        move_uploaded_file($_FILES["file"]["tmp_name"], $fullpath);
++        
++        info("File uploaded successfully.");
++    }
++}
++if(isset($_REQUEST['delete']))
++{
++    if(expfiles_delete($_REQUEST['delete'])) jsRedirect('files.php');
++}
++
++/*
++ * Display
++ */
++$filesView = new CView('experiments.files');
++
++$filesView->set('files', expfiles_getuserfiles());
++
++$filesView->render();
++$filesView->show();
++
++
++require_once dirname(__FILE__).'/include/page_footer.php';
+diff --git images/general/question_mark.png images/general/question_mark.png
+new file mode 100644
+index 
0000000000000000000000000000000000000000..8dee9d00722e31f2c56938ff1e64325fe2f89463
+GIT binary patch
+literal 618
+zcmV-w0+s!VP)<h;3K|address@hidden&`wG00006VoOIv0RI60
+z0RN!9r;`8x010qNS#tmY3zYx>3zY$-s#FjF000McNliru-3bN}3<eTCyMh1!0ryEn
+zK~yNuZPGn#5^)address@hidden)}uBpFD43<address@hidden)ojSQR
+zF1EYWrHz(J6ExJO24Qe21&<Jrk`x0aSNLD=j^lnV)tKlrKil`iaI(4en(ce5e>Wa>
+zC1L?F3IN;tN;address@hidden;@+UBiL|MwS>RVlELY36#GL9%L4uEFVRgHz|&Ag&p-kZI;3
+zt5N^}*xY)}HtlupEL}Z)>address@hidden
+z8T2yWHa*Kll2yaJ{jN^;QVo(-!yH>K(Ti-$<eEW~E9H4hJnTy7Ca_WJvMT`>y_LEw
+zC2_poJ3^tYvG}-1sdA4g1|c4HC9JWa7?nCY4ip2$L!Eu7a=3>CTt4fB+bLkDam=g&
+z!(LlQEGR~;address@hidden;address@hidden>M(qfV*gym#
+z02h1?Y?e8sLmh&J(K)address@hidden|)?A~Aqj7}1+T7aPSR2n<93i}{^2
+z>R?D$cv6_T|D;fA_isF(_4#Ghq>gH`sDB7&hOICGc5`Bwp3QpM(wBCA0DAl<++wDg
+zQ*?v&Wt}p$9(}6z=!dKk*9>~P^;fw6(g>c=sQ*jj7e7}JB#9c$K>z>%07*qoM6N<$
+Eg6%X1fdBvi
+
+literal 0
+HcmV?d00001
+
+diff --git include/blocks.inc.php include/blocks.inc.php
+index 3896140..7b1321a 100644
+--- include/blocks.inc.php
++++ include/blocks.inc.php
+@@ -1401,3 +1401,174 @@ function makeTriggersPopup(array $triggers, array 
$ackParams) {
+ 
+       return $popupTable;
+ }
++
++function make_run_scripts()
++{
++      //create big table
++      $bigTable = new CTableInfo();
++      
++    //create table 1
++    $scriptsTable = new CTableInfo(_('No scripts defined.'));
++    $scriptsTable->setHeader(array(
++          _('Name'),
++          _('Run on Host'),
++          _('Run on Host Group')
++    ));
++    
++    //get list of scripts
++    $scripts = API::Script()->get(array(
++              'output' => array('name')
++      ));
++      
++      //get list of hosts
++      $hosts = API::Host()->get(array(
++              'sortfield' => 'name',
++              'output' => array('name')
++      ));
++      
++      //get list of host groups
++    $hostgroups = API::HostGroup()->get(array(
++              'sortfield' => 'name',
++              'output' => array('name')
++      ));
++      
++      //add rows
++      foreach($scripts as $script)
++      {
++          //create hostgroups combobox & run button
++        $runForm = new CForm('GET', 'scripts_exec.php');
++        $runForm->attr("target", "_blank");
++        $runForm->addItem(new CInput('hidden', 'execute', '1'));
++        $runForm->addItem(new CInput('hidden', 'scriptid', 
$script['scriptid']));
++        
++        $grpsComboBox = new CComboBox('groupid');
++        foreach($hostgroups as $hostgroup)
++            $grpsComboBox->addItem(new CComboItem($hostgroup['groupid'], 
$hostgroup['name']));
++
++        $runForm->addItem($grpsComboBox);
++        $runForm->addItem(new CInput('submit', 'submit', 'Run'));
++        
++        //create hosts combobox & run button
++        $runFormHosts = new CForm('GET', 'scripts_exec.php');
++        $runFormHosts->attr("target", "_blank");
++        $runFormHosts->addItem(new CInput('hidden', 'execute', '1'));
++        $runFormHosts->addItem(new CInput('hidden', 'scriptid', 
$script['scriptid']));
++        
++        $hostsComboBox = new CComboBox('hostid');
++        foreach($hosts as $host)
++            $hostsComboBox->addItem(new CComboItem($host['hostid'], 
$host['name']));
++
++        $runFormHosts->addItem($hostsComboBox);
++        $runFormHosts->addItem(new CInput('submit', 'submit', 'Run'));
++        
++        $scriptsTable->addRow(array(
++                  new CLink($script['name'], 
'scripts.php?form=1&scriptid='.$script['scriptid']),
++                  $runFormHosts,
++                  $runForm
++          ));
++      }
++      
++      //create multiple run form
++      $multForm = new CFormTable(null, 'scripts_exec.php', 'GET');
++      
++      $scriptsCmbbox = new CComboBox('scriptid');
++      foreach($scripts as $script)
++              $scriptsCmbbox->addItem(new CComboItem($script['scriptid'], 
$script['name']));
++      
++      $hostsListBox = new CListBox('hosts[]', null, 15);
++      foreach($hosts as $host)
++        $hostsListBox->addItem(new CComboItem($host['hostid'], 
$host['name']));
++    
++    $multForm->addRow($scriptsCmbbox);
++    $multForm->addRow($hostsListBox);
++    $multForm->attr("target", "_blank");
++    $multForm->addRow(new CInput('hidden', 'execute', '1'), new 
CInput('submit', 'submit', 'Run'));
++    
++    $bigTable->addRow(array(
++      $scriptsTable,
++      $multForm
++    ));
++    
++    return $bigTable;
++}
++
++function template_items_status($template_id)
++{
++      //fetch main template    
++    $options = array(
++              'templateids' => array($template_id),
++              'selectItems' => array('status'),
++              'output' => array('name')
++      );
++
++      $template = API::Template()->get($options);
++      
++      $total = 0;
++      $enabled = 0;
++      
++      foreach($template[0]['items'] as $item)
++      {
++              $total++;
++              if($item['status'] == 0) $enabled++;
++      }
++      
++      return array('total' => $total, 'enabled' => $enabled);
++}
++
++function make_manage_monitoring()
++{
++    $templates = array(10001, 10176, 10177);
++    
++    //fetch important templates
++    $options = array(
++              'templateids' => $templates,
++              'output' => array('name')
++      );
++      $templates = API::Template()->get($options);
++      
++      //create link/unlink all forms
++      $linkAllForm = new CForm('POST', 'manage_monitoring.php');
++      $unlinkAllForm = new CForm('POST', 'manage_monitoring.php');
++      foreach($templates as $temp)
++      {
++              $linkAllForm->addItem(new CInput('hidden', 
'template['.$temp['hostid'].']', $temp['hostid']));
++              $unlinkAllForm->addItem(new CInput('hidden', 
'template['.$temp['hostid'].']', $temp['hostid']));
++      }
++      $linkAllForm->addItem(new CInput('submit', 'submit', 'Enable All'));
++    $linkAllForm->addItem(new CInput('hidden', 'action', 'enable'));
++
++      $unlinkAllForm->addItem(new CInput('submit', 'submit', 'Disable All'));
++    $unlinkAllForm->addItem(new CInput('hidden', 'action', 'disable'));
++      
++      //table that will contain forms
++      $table = new CTable();
++      
++      foreach($templates as $template)
++      {
++              $items_status = template_items_status($template['hostid']);
++              
++          $r = new CRow();
++          $r->addItem(new CLabel($template['name'] . ' [' . 
$items_status['enabled'] . '/' . $items_status['total'] . ']'));
++          
++          $enableForm = new CForm('POST', 'manage_monitoring.php');
++          $enableForm->addItem(new CInput('hidden', 
'template['.$template['hostid'].']', $template['hostid']));
++          $enableForm->addItem(new CInput('submit', 'submit', 'Disable'));
++        $enableForm->addItem(new CInput('hidden', 'action', 'disable'));
++          
++          $disableForm = new CForm('POST', 'manage_monitoring.php');
++        $disableForm->addItem(new CInput('hidden', 
'template['.$template['hostid'].']', $template['hostid']));
++      $disableForm->addItem(new CInput('submit', 'submit', 'Enable'));
++      $disableForm->addItem(new CInput('hidden', 'action', 'enable'));
++
++          $r->addItem($enableForm);        
++          $r->addItem($disableForm);
++          
++          $table->addRow($r);
++      }
++      $totalRows = new CRow();
++      $totalRows->addItem($linkAllForm);
++      $totalRows->addItem($unlinkAllForm);
++      $table->addRow($totalRows);
++      
++      return $table;
++}
+diff --git include/classes/import/CXmlImport18.php 
include/classes/import/CXmlImport18.php
+index b03a3bc..b101cbf 100644
+--- include/classes/import/CXmlImport18.php
++++ include/classes/import/CXmlImport18.php
+@@ -1003,7 +1003,7 @@ class CXmlImport18 {
+                               $host_db['groups'] = array();
+                               $groups_to_parse = array();
+                               foreach ($groups as $group) {
+-                                      $groups_to_parse[] = array('name' => 
$group->nodeValue);
++                                      $groups_to_parse[] = array('name' => 
trim($group->nodeValue));
+                               }
+                               if (empty($groups_to_parse)) {
+                                       $groups_to_parse[] = array('name' => 
ZBX_DEFAULT_IMPORT_HOST_GROUP);
+@@ -1134,6 +1134,7 @@ class CXmlImport18 {
+ 
+                                       $templateLinkage = array();
+                                       foreach ($templates as $template) {
++                                              $template->nodeValue = 
trim($template->nodeValue);
+                                               $options = array(
+                                                       'filter' => 
array('host' => $template->nodeValue),
+                                                       'output' => 
API_OUTPUT_SHORTEN,
+diff --git include/experiments/conf.php include/experiments/conf.php
+new file mode 100644
+index 0000000..9bef025
+--- /dev/null
++++ include/experiments/conf.php
+@@ -0,0 +1,9 @@
++<?php
++
++$GLOBALS['GPLMT_DIR'] = '/home/omar/workspace/gnunet-planetlab/gplmt/';
++
++$GLOBALS['GPLMT_TASKLISTS_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/tasklists/';
++$GLOBALS['GPLMT_CONF_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/configurations/';
++$GLOBALS['GPLMT_NODES_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/nodes/';
++$GLOBALS['GPLMT_RESULTS_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/results/';
++$GLOBALS['GPLMT_FILES_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/files/';
+diff --git include/experiments/config.php include/experiments/config.php
+new file mode 100644
+index 0000000..1e4ed5a
+--- /dev/null
++++ include/experiments/config.php
+@@ -0,0 +1,106 @@
++<?php
++
++function expconfig_update($data)
++{
++    //get user editable config
++    $editable = expconfig_getuserconfig();
++    
++    foreach($data as $k => $v)
++    {
++        if(!isset($editable[$k])) continue;
++        $v = trim($v);
++        $enabled = ($v != '');
++        
++        if(($editable[$k]['type'] == 'file') && $enabled)
++            $v = expfiles_getuserdir().exp_cleanfilename($v);
++        
++        expdb_update('exp_userconfig',
++            array('value' => $v, 'enabled' => strval($enabled)),
++            array('configid' => $k, 'userid' => CWebUser::$data['userid']));
++    }
++    
++    expconfig_writefile();
++}
++
++function expconfig_getconfigbyname($configname)
++{
++    $uid = CWebUser::$data['userid'];
++    $sql = "SELECT exp_userconfig.value, exp_userconfig.enabled
++        FROM exp_config, exp_userconfig
++        WHERE exp_config.configid = exp_userconfig.configid
++        AND exp_config.name = '$configname'
++        AND exp_userconfig.userid = $uid";
++    $result = DBfetchArray(DBselect($sql));
++    if(count($result) == 0) return null;
++    if(!$result[0]['enabled']) return null;
++    return $result[0]['value'];
++}
++
++function expconfig_getuserconfig($editableOnly = true)
++{
++    $uid = CWebUser::$data['userid'];
++    $sql = "SELECT u.configid, c.section, c.name, c.label, c.description, 
c.type, u.value
++            FROM exp_config c, exp_userconfig u
++            WHERE c.configid = u.configid
++            AND c.user_editable = 1
++            AND u.userid = $uid
++            ORDER BY c.section, c.configid";
++    return DBfetchArrayAssoc(DBselect($sql), 'configid');
++}
++
++function expconfig_getenum($configid)
++{
++    return expdb_select('exp_configenum', array('configid' => $configid));
++}
++
++function expconfig_writefile()
++{
++    $uid = CWebUser::$data['userid'];
++    $sql = "SELECT c.section, c.name, u.value
++            FROM exp_config c, exp_userconfig u
++            WHERE c.configid = u.configid
++            AND u.enabled = 1
++            AND u.userid = $uid
++            ORDER BY c.section";
++    $conf = DBfetchArray(DBselect($sql));
++    
++    $filename = $GLOBALS['GPLMT_CONF_DIR'].strval($uid);
++    $f = fopen($filename, 'w+');
++    $current_sec = '';
++    
++    foreach($conf as $c)
++    {
++        if($c['section'] != $current_sec)
++        {
++            $current_sec = $c['section'];
++            fwrite($f, "[$current_sec]\n");
++        }
++        $k = $c['name'];
++        $v = $c['value'];
++        fwrite($f, "$k = $v\n");
++    }
++    fclose($f);
++}
++
++function expconfig_verifyuserconfig()
++{
++    $uid = CWebUser::$data['userid'];
++    $default_config = expdb_select('exp_config', array(), 'configid');
++    $user_config = expdb_select('exp_userconfig', array('userid' => $uid), 
'configid');
++    
++    if(count($default_config) == count($user_config)) return;
++    
++    foreach($default_config as $dc_k => $dc)
++    {
++        if(isset($user_config[$dc_k])) continue;
++        
++        $newval = $dc['default_value'];
++        if($dc['name'] == 'userdir') //special cases, user specific
++            $newval = expfiles_getuserdir();
++        $enabled = strval(($newval != ''));
++        
++        expdb_insert('exp_userconfig',
++            array('configid' => $dc_k, 'userid' => $uid, 'value' => $newval, 
'enabled' => $enabled));
++    }
++    expconfig_writefile();
++}
+diff --git include/experiments/db.php include/experiments/db.php
+new file mode 100644
+index 0000000..14f1b7c
+--- /dev/null
++++ include/experiments/db.php
+@@ -0,0 +1,85 @@
++<?php
++
++function expdb_genwhere($where)
++{
++    if(sizeof($where) == 0) return '';
++    
++    $where_str = ' WHERE ';
++    
++    $first = true;
++    foreach($where as $k => $v)
++    {
++        if(!$first) $where_str .= ' AND ';
++        else $first = false;
++        $where_str .= $k.'=';
++        if(is_string($v))
++            $where_str .= ("'".mysql_real_escape_string(trim($v))."'");
++        else
++            $where_str .= $v;
++    }
++    
++    return $where_str;
++}
++
++function expdb_insert($table, $data)
++{
++    $keys_str = implode(',', array_keys($data));
++    
++    $vals = array();
++    foreach($data as $v)
++    {
++        if(is_string($v)) $vals[] = 
"'".mysql_real_escape_string(trim($v))."'";
++        else $vals[] = $v;
++    }
++    
++    $vals_str = implode(',', $vals);
++    
++    $sql = "INSERT INTO $table ($keys_str) VALUES ($vals_str)";
++    
++    DBexecute($sql);
++    return mysql_insert_id(); #TODO: mysql specific, need to be changed to be 
generic
++}
++
++function expdb_update($table, $data, $where)
++{
++    $set_str = '';
++    $first = true;
++    foreach($data as $k => $v)
++    {
++        if(!$first) $set_str .= ',';
++        else $first = false;
++        $set_str .= $k.'=';
++        if(is_string($v))
++            $set_str .= ("'".mysql_real_escape_string(trim($v))."'");
++        else
++            $set_str .= $v;
++    }
++    
++    $where_str = expdb_genwhere($where);
++    
++    $sql = "UPDATE $table SET $set_str $where_str";
++    
++    return DBexecute($sql);
++}
++
++
++function expdb_select($table, $where, $assocField = null)
++{
++    $where_str = expdb_genwhere($where);
++    
++    $sql = "SELECT * FROM $table $where_str";
++    
++    if($assocField)
++        return DBfetchArrayAssoc(DBselect($sql), $assocField);
++    else
++        return DBfetchArray(DBselect($sql));
++}
++
++function expdb_delete($table, $where)
++{
++    $where_str = expdb_genwhere($where);
++    
++    $sql = "DELETE FROM $table $where_str";
++    
++    return DBexecute($sql);
++}
+diff --git include/experiments/files.php include/experiments/files.php
+new file mode 100644
+index 0000000..a2f5fe8
+--- /dev/null
++++ include/experiments/files.php
+@@ -0,0 +1,82 @@
++<?php
++
++/*
++ * Get the full path for the directory containing the user personal file
++ */
++function expfiles_getuserdir()
++{
++    $uid = CWebUser::$data['userid'];
++    $dir = $GLOBALS['GPLMT_FILES_DIR'].strval($uid).'/';
++    if(!file_exists($dir)) mkdir($dir);
++    return $dir;
++}
++
++/*
++ * Returns an array with the names of files inside the user personal directory
++ */
++function expfiles_getuserfiles()
++{
++    $dirpath = expfiles_getuserdir();
++    
++    $res = scandir($dirpath);
++    $res = array_diff($res, array('.', '..'));
++    return $res;
++}
++
++/*
++ * Given a file name for a new file to be uploaded, returns a full path 
++ * with the same or modified filename if already exists
++ */
++function expfiles_getnewfilepath($filename = 'new')
++{
++    $filename = exp_cleanfilename($filename);
++    $dirpath = expfiles_getuserdir();
++    
++    $parts = explode('.', $filename);
++    $orig = $parts[0];
++    
++    $counter = 0;
++    while(file_exists($dirpath.implode('.', $parts)))
++    {
++        $parts[0] = $orig.strval($counter);
++        $counter++;
++    }
++    
++    return $dirpath.implode('.', $parts);
++}
++
++function expfiles_delete($filename)
++{
++    $filename = exp_cleanfilename($filename);
++    $fullpath = expfiles_getuserdir().$filename;
++    if(file_exists($fullpath)) unlink($fullpath);
++    return true;
++}
++
++function expfiles_download($filename)
++{
++    $filename = exp_cleanfilename($filename);
++    $fullpath = expfiles_getuserdir().$filename;
++    if(!file_exists($fullpath))
++    {
++        error("File doesn't exist");
++        return false;
++    }
++    
++    $size = filesize($fullpath);
++    $mime_type="application/force-download";
++    
++    //@ob_end_clean();
++    
++    header('Content-Type: ' . $mime_type);
++    header('Content-Disposition: attachment; filename="'.$filename.'"');
++    header("Content-Transfer-Encoding: binary");
++    header('Accept-Ranges: bytes');
++    header("Cache-control: private");
++    header('Pragma: private');
++    header('Content-Length: ' . $size);
++    ob_clean();
++    flush();
++    readfile($fullpath); 
++    exit;
++}
+diff --git include/experiments/inc.php include/experiments/inc.php
+new file mode 100644
+index 0000000..0823b39
+--- /dev/null
++++ include/experiments/inc.php
+@@ -0,0 +1,50 @@
++<?php
++
++require_once dirname(__FILE__).'/conf.php';
++require_once dirname(__FILE__).'/db.php';
++require_once dirname(__FILE__).'/tasklist.php';
++require_once dirname(__FILE__).'/run.php';
++require_once dirname(__FILE__).'/files.php';
++require_once dirname(__FILE__).'/config.php';
++require_once dirname(__FILE__).'/nodes.php';
++require_once dirname(__FILE__).'/targets.php';
++
++define('EXP_OK', '0');
++define('EXP_ERR_GPLMT_DIR', '1');
++define('EXP_ERR_PERMISSION', '2');
++define('EXP_ERR_INVALID_TARGET', '3');
++
++
++function exp_cleanfilename($filename)
++{
++    return preg_replace("/[^a-z0-9\.]/", "", strtolower($filename));
++}
++
++
++function exp_gettargets()
++{
++    $cmd = 'python '.$GLOBALS['GPLMT_DIR'].'gplmt/Targets.py';
++    $res = array();
++    exec($cmd, $res);
++    return $res;
++}
++
++function exp_verifygplmtdir()
++{
++    if(!file_exists($GLOBALS['GPLMT_DIR'].'gplmt.py'))
++    {
++        error('GPLMT path invalid!');
++        return false;
++    }
++    
++    if(!file_exists($GLOBALS['GPLMT_TASKLISTS_DIR'])) 
mkdir($GLOBALS['GPLMT_TASKLISTS_DIR']);
++    if(!file_exists($GLOBALS['GPLMT_CONF_DIR'])) 
mkdir($GLOBALS['GPLMT_CONF_DIR']);
++    if(!file_exists($GLOBALS['GPLMT_NODES_DIR'])) 
mkdir($GLOBALS['GPLMT_NODES_DIR']);
++    if(!file_exists($GLOBALS['GPLMT_RESULTS_DIR'])) 
mkdir($GLOBALS['GPLMT_RESULTS_DIR']);
++    if(!file_exists($GLOBALS['GPLMT_FILES_DIR'])) 
mkdir($GLOBALS['GPLMT_FILES_DIR']);
++    
++    return true;
++}
++
++exp_verifygplmtdir();
++expconfig_verifyuserconfig();
+diff --git include/experiments/nodes.php include/experiments/nodes.php
+new file mode 100644
+index 0000000..08a4f22
+--- /dev/null
++++ include/experiments/nodes.php
+@@ -0,0 +1,88 @@
++<?php
++
++function expnodes_getbyrunid($run_id)
++{
++    $run_id = mysql_real_escape_string($run_id);
++    
++    $sql = "SELECT exp_host.hostid, exp_host.host
++            FROM exp_runnode, exp_host
++            WHERE exp_runnode.hostid = exp_host.hostid
++            AND exp_runnode.runid = $run_id";
++    
++    return DBfetchArray(DBselect($sql));
++}
++
++function expnodes_writefile($nodes, $run_id)
++{
++    $nodes_file = $GLOBALS['GPLMT_NODES_DIR'].$run_id;
++    
++    $f = fopen($nodes_file, 'w+');
++    foreach($nodes as $n) fwrite($f, "$n\n");
++    fclose($f);
++}
++
++function expnodes_gethosts($target)
++{
++    $userid = CWebUser::$data['userid'];
++    return expdb_select('exp_host', array('userid' => $userid, 'target' => 
$target));
++}
++
++function expnodes_gethostbyid($hostid)
++{
++    $res = expdb_select('exp_host', array('hostid' => $hostid));
++    if(count($res) == 0) return null;
++    return $res[0];
++}
++
++function expnodes_gethostinterface($hostid)
++{
++    $h = API::Host()->get(array(
++        'hostids' => $hostid,
++        'output' => array(),
++        'selectInterfaces' => API_OUTPUT_EXTEND
++    ));
++    
++    if(count($h) == 0) return '';
++    foreach($h[0]['interfaces'] as $i)
++    {
++        if($i['main'] == 1)
++        {
++            if($i['useip'] == 1) return $i['ip'];
++            else return $i['dns'];
++        }
++    }
++}
++
++function expnodes_getzabbixnodes()
++{
++    $hosts = API::Host()->get(array(
++        'output' => array('hostid', 'host'),
++        'selectInterfaces' => API_OUTPUT_EXTEND
++    ));
++    
++    $nodes = array();
++    
++    foreach($hosts as $h)
++    {
++        $n = array();
++        $n['hostid'] = $h['hostid'];
++        $n['host'] = $h['host'];
++        
++        foreach($h['interfaces'] as $i)
++        {
++            if($i['main'] == 1)
++            {
++                $n['interfaceid'] = $i['interfaceid'];
++                if($i['useip'] == 1) $n['interface'] = $i['ip'];
++                else $n['interface'] = $i['dns'];
++                
++                break;
++            }
++        }
++        
++        $nodes[] = $n;
++    }
++    
++    return $nodes;
++}
++
+diff --git include/experiments/run.php include/experiments/run.php
+new file mode 100644
+index 0000000..c0d0700
+--- /dev/null
++++ include/experiments/run.php
+@@ -0,0 +1,290 @@
++<?php
++
++define('EXP_STATUS_FAILED', -1);
++define('EXP_STATUS_NOT_STARTED', 0);
++define('EXP_STATUS_RUNNING', 1);
++define('EXP_STATUS_DONE_WITH_ERRORS', 2);
++define('EXP_STATUS_DONE_SUCCESSFULLY', 10);
++
++function exprun_getstatusstring($status)
++{
++    switch($status)
++    {
++        case -1:
++            return "Failed";
++        case 0:
++            return "Not started";
++        case 1:
++            return "Running";
++        case 2:
++            return "Done with errors";
++        case 10:
++            return "Done successfully";
++        default:
++            return "Undefined status";
++    }
++}
++
++function exprun_getall($extended = false, $string_status = true)
++{
++    exprun_updateresults(); //update database with any new results
++
++    $where['userid'] = intval(CWebUser::$data['userid']);
++
++    $res = expdb_select('exp_run', $where);
++    
++    for($i = 0; $i < sizeof($res); $i++)
++    {
++        $sql = "SELECT exp_runnode.*, exp_host.host as interface FROM 
exp_runnode, exp_host
++                WHERE exp_runnode.runid = ".$res[$i]['runid']."
++                AND exp_runnode.hostid = exp_host.hostid
++                ORDER BY exp_runnode.status DESC, exp_runnode.percentage 
DESC, exp_host.host ASC";
++        $nodes = DBfetchArray(DBselect($sql));
++        
++        if($string_status)
++            $res[$i]['status'] = exprun_getstatusstring($res[$i]['status']);
++        
++        for($j = 0; $j < sizeof($nodes); $j++)
++        {
++            if($string_status)
++                $nodes[$j]['status'] = 
exprun_getstatusstring($nodes[$j]['status']);
++        }
++        
++        $res[$i]['nodes'] = $nodes;
++    }
++    
++    return $res;
++}
++
++function exprun_updateresults()
++{
++    $running = expdb_select('exp_run', array('status' => 1));
++    foreach($running as $r)
++    {
++        $updates = exprun_parseresult($r['runid']);
++        expdb_update('exp_run', array('status' => $updates['status'], 
'percentage' => $updates['percentage']), array('runid' => $r['runid']));
++        foreach($updates['nodes_results'] as $nr)
++        {
++            expdb_update('exp_runnode',
++                array('status' => $nr['status'], 'percentage' => 
$nr['percentage'], 'log' => $nr['log']),
++                array('runid' => $r['runid'], 'hostid' => $nr['hostid']));
++        }
++    }
++}
++
++function exprun_pidrunning($pid)
++{
++    $cmd = "ps --no-headers -p ".$pid;
++    $res = exec($cmd);
++    return !empty($res);
++}
++
++function exprun_calculatestatus($percentage, $running, $failure)
++{
++    if($percentage < 100) $status = ($running) ? EXP_STATUS_RUNNING : 
EXP_STATUS_FAILED;
++    else $status = ($failure) ? EXP_STATUS_DONE_WITH_ERRORS : 
EXP_STATUS_DONE_SUCCESSFULLY;
++    return $status;
++}
++
++function exprun_parseresult($run_id)
++{
++    $prog = 0;
++    $total = 1;
++    $failure = false;
++    $nodes_results = array();
++    
++    //Read metadata
++    $meta = exprun_getbyid($run_id);
++    
++    //Check if the process is already running
++    $running = exprun_pidrunning($meta['pid']);
++
++    $results_file = $GLOBALS['GPLMT_RESULTS_DIR'].$run_id;
++    if(file_exists($results_file))
++    {
++        //Read nodes from DB
++        $nodes = expnodes_getbyrunid($run_id);
++
++        //Read loaded tasks (if available)
++        if($meta['usetasklist'])
++            $tasks = exec('grep -Po "(?<=Loaded )\d+(?= tasks)" 
'.$results_file);
++        else
++            $tasks = 1;
++        if(!empty($tasks))
++        {
++            $tasks = intval($tasks);
++
++            $total = count($nodes) * $tasks;
++
++            //for each node, calculate progress from result output    
++            foreach($nodes as $n)
++            {
++                $node_failure = false;
++                $interface = $n['host'];
++
++                $res = array();
++                exec('grep -Po "'.$interface.'\s*\| .* \| \K.*" 
'.$results_file, $res); //final result
++                if(count($res) > 0)
++                {
++                    if(trim($res[0]) != 'success')
++                    {
++                        $failure = true;
++                        $node_failure = true;
++                    }
++                    $node_prog = $tasks;
++                }
++                else
++                {
++                    //tasks completed for node
++                    $tasks_completed = array();
++                    exec('grep -Po "'.$interface.' : Task \'.*\' completed" 
'.$results_file, $tasks_completed);
++                    $node_prog = count($tasks_completed);
++                }
++                
++                //get all node logs
++                $node_log_arr = array();
++                exec("grep -E '^$interface' $results_file", $node_log_arr);
++                $node_log = implode("\n", $node_log_arr);
++                
++                $node_perc = $node_prog * 100 / $tasks;
++                $nodes_results[] = array('status' => 
exprun_calculatestatus($node_perc, $running, $node_failure),
++                                    'percentage' => ($running) ? $node_perc : 
100,
++                                    'log' => $node_log,
++                                    'hostid' => $n['hostid']);
++                $prog += $node_prog;
++            }
++        }
++    }
++    
++    $perc = $prog * 100 / $total; //percentage done
++    $status = exprun_calculatestatus($perc, $running, $failure); //total 
status
++    
++    return array('status' => $status, 'percentage' => ($running) ? $perc : 
100, 'nodes_results' => $nodes_results);
++}
++
++function exprun_new($target, $params, $usetasklist, $tasklist, $cmd)
++{
++    if(!exp_verifygplmtdir()) return EXP_ERR_GPLMT_DIR;
++    if($usetasklist == 1 && exptasklist_allowed($tasklist) == 0) return 
EXP_ERR_PERMISSION;
++    
++    //create run record
++    $run_data = array();
++    $run_data['usetasklist'] = $usetasklist;
++    if($usetasklist == 1)
++        $run_data['tasklistid'] = $tasklist;
++    else
++        $run_data['command'] = $cmd;
++    $run_data['userid'] = intval(CWebUser::$data['userid']);
++    $run_data['target'] = $target;
++    
++    $run_id = expdb_insert('exp_run', $run_data);
++
++    //create run-nodes records
++    switch($target)
++    {
++        case 'ssh':
++        case 'planetlab':
++            $hostnames = array();
++            foreach($params as $h) //get hostnames and save to DB
++            {
++                $hostinfo = expnodes_gethostbyid($h); $hostnames[] = 
$hostinfo['host'];
++                expdb_insert('exp_runnode', array('runid' => $run_id, 
'hostid' => $h, 'target' => $target));
++            }
++            //write GPLMT nodes file
++            expnodes_writefile($hostnames, $run_id);
++            break;
++            
++        default: //invalid target
++            expdb_delete('exp_run', array('runid' => $run_id));
++            return EXP_ERR_INVALID_TARGET;
++    }
++    
++    exprun_gplmt($run_id);
++    
++    return EXP_OK;
++}
++
++function exprun_getbyid($run_id)
++{
++    $res = expdb_select('exp_run', array('runid' => $run_id));
++    return $res[0];
++}
++
++function exprun_rerun($run_id)
++{
++    $meta = exprun_getbyid($run_id);
++    if(exprun_pidrunning($meta['pid'])) return;
++    
++    exprun_gplmt($run_id);
++}
++
++function exprun_checkpermission($run_id)
++{
++    if(CWebUser::$data['type'] == 3) return true;
++    
++    $res = expdb_select('exp_run', array('userid' => 
CWebUser::$data['userid'], 'runid' => $run_id));
++    
++    return (sizeof($res) > 0);
++}
++
++function exprun_interrupt($run_id)
++{
++    $meta = exprun_getbyid($run_id);
++    
++    if(!exprun_checkpermission($run_id)) return;
++    
++    $cmd = "kill -15 ".$meta['pid'];
++    exec($cmd);
++}
++
++function exprun_delete($run_id)
++{
++    $meta = exprun_getbyid($run_id);    
++
++    //check permissions
++    if(!exprun_checkpermission($run_id)) return;
++    
++    //check if tool still running
++    if(exprun_pidrunning($meta['pid'])) return;
++
++    $n = $GLOBALS['GPLMT_NODES_DIR'].$run_id;
++    if(file_exists($n)) unlink($n);
++    $r = $GLOBALS['GPLMT_RESULTS_DIR'].$run_id;
++    if(file_exists($r)) unlink($r);
++    
++    expdb_delete('exp_run', array('runid' => $run_id));
++    expdb_delete('exp_runnode', array('runid' => $run_id));
++}
++
++function exprun_verifyid($run_id)
++{
++    $res = expdb_select('exp_run', array('runid' => $run_id));
++    return (sizeof($res) > 0);
++}
++
++function exprun_gplmt($run_id)
++{
++    $run_data = exprun_getbyid($run_id);
++    if($run_data['usetasklist'])
++        $tasklist_data = exptasklist_getbyid($run_data['tasklistid']);
++    
++    //compose and run command
++    $cmd = 'python -u '.$GLOBALS['GPLMT_DIR'].'gplmt.py -V'; // GPLMT
++    $cmd .= ' -c '.$GLOBALS['GPLMT_CONF_DIR'].CWebUser::$data['userid']; // 
Conf file
++    $cmd .= ' -n '.$GLOBALS['GPLMT_NODES_DIR'].$run_id; // Nodes file
++    if($run_data['target'] == 'ssh')
++        $cmd .= ' -t remote_ssh';
++    elseif($run_data['target'] == 'planetlab')
++        $cmd .= ' -t planetlab';
++    if($run_data['usetasklist'])
++        $cmd .= ' -l 
'.$GLOBALS['GPLMT_TASKLISTS_DIR'].$tasklist_data['fsname']; // Tasklist file
++    else
++        $cmd .= " -C '".$run_data['command']."'"; // Command to run
++    $cmd .= ' > '.$GLOBALS['GPLMT_RESULTS_DIR'].$run_id; // Results file
++    $cmd .= ' 2>&1 & echo $!'; // Redirect stderr, run in background and get 
pid
++    
++    $pid = system($cmd);
++
++    expdb_update("exp_run", array('fullcommand' => $cmd, 'pid' => $pid, 
'status' => EXP_STATUS_RUNNING), array('runid' => $run_id));
++}
++
+diff --git include/experiments/targets.php include/experiments/targets.php
+new file mode 100644
+index 0000000..3e3cc79
+--- /dev/null
++++ include/experiments/targets.php
+@@ -0,0 +1,184 @@
++<?php
++
++require_once 'XML/RPC2/Client.php';
++
++$exp_targetlist = array(
++    'SSH' => 'ssh',
++    'Planetlab' => 'planetlab');
++
++/*
++ * Planetlab
++ */
++
++function exppl_getauth()
++{
++    $pl_user = expconfig_getconfigbyname('username');
++    if(!$pl_user) fatal_error('Please specify planetlab username in config');
++    $pl_pass = expconfig_getconfigbyname('password');
++    if(!$pl_pass) fatal_error('Please specify planetlab password in config');
++    
++    return array(
++        "AuthMethod" => 'password',
++        "Username" => $pl_user,
++        "AuthString" => $pl_pass
++        );
++}
++
++function exppl_getclient()
++{
++    $pl_api = expconfig_getconfigbyname('api_url');
++    if(!$pl_api) fatal_error('Please specify planetlab API in config');
++    
++    return XML_RPC2_Client::create($pl_api, array('sslverify' => false));
++}
++
++function exppl_getslicename()
++{
++    $pl_slice = expconfig_getconfigbyname('slice');
++    if(!$pl_slice) fatal_error('Please specify planetlab slice in config');
++    return $pl_slice;
++}
++
++function exppl_getAvailableNodes($page_offset, $page_size, $hostfilter = null)
++{
++    $page_offset = intval($page_offset);
++    $page_size = intval($page_size);
++
++    $pl_slice = exppl_getslicename();
++    $auth = exppl_getauth();
++    $client = exppl_getclient();
++    
++    //get node IDs in slice (for negation)
++    try
++    {
++        $res = $client->GetSlices($auth, $pl_slice, array('node_ids')); 
$node_ids = $res[0]['node_ids'];
++    }
++    catch (XML_RPC2_FaultException $e)
++    {
++        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
++    }
++    
++    $filter = array('~node_id' => $node_ids,
++                    '-SORT' => 'hostname',
++                    '-OFFSET' => $page_offset,
++                    '-LIMIT' => $page_size);
++    if($hostfilter) $filter['hostname'] = "*$hostfilter*";
++    
++    try
++    {
++        return $client->GetNodes($auth, $filter, array('hostname', 
'node_id'));
++    }
++    catch (XML_RPC2_FaultException $e)
++    {
++        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
++    }
++}
++
++function exppl_getSliceNodes()
++{
++    $pl_slice = exppl_getslicename();
++    $auth = exppl_getauth();
++    $client = exppl_getclient();
++
++    //get node IDs
++    try
++    {
++        $res = $client->GetSlices($auth, $pl_slice, array('node_ids')); 
$node_ids = $res[0]['node_ids'];
++    }
++    catch (XML_RPC2_FaultException $e)
++    {
++        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
++    }
++    
++    //get node hostnames + IDs
++    try
++    {
++        $res = $client->GetNodes($auth, $node_ids, array('hostname', 
'node_id'));
++    }
++    catch (XML_RPC2_FaultException $e)
++    {
++        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
++    }
++    $res = exppl_updateSliceNodesDB($res);
++    return $res;
++}
++
++function exppl_updateSliceNodes($nodes)
++{
++    $pl_slice = exppl_getslicename();
++    $auth = exppl_getauth();
++    $client = exppl_getclient();
++    
++    try
++    {
++        $client->UpdateSlice($auth, $pl_slice, array('nodes' => 
array_map('intval', array_values($nodes))));
++    }
++    catch (XML_RPC2_FaultException $e)
++    {
++        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
++    }
++}
++
++function exppl_updateSliceNodesDB($nodes)
++{
++    if(!is_array($nodes)) return;
++    
++    $userid = CWebUser::$data['userid'];
++    
++    // No delete so as not to break previous runs
++    // Insert new hosts not seen before
++    
++    for($i = 0; $i < count($nodes); $i++)
++    {
++        if(!exppl_getHostByPLNodeId($nodes[$i]['node_id'])) //Does not exist
++            $nodes[$i]['hostid'] = expdb_insert('exp_host', array('userid' => 
$userid, 'host' => $nodes[$i]['hostname'], 'target' => 'planetlab', 'pl_nodeid' 
=> $nodes[$i]['node_id']));
++        else
++            { $res = exppl_getHostByPLNodeId($nodes[$i]['node_id']); 
$nodes[$i]['hostid'] = $res['hostid']; }
++    }
++    
++    return $nodes;
++}
++
++function exppl_getHostByPLNodeId($pl_nodeid)
++{
++    $res = expdb_select('exp_host', array('pl_nodeid' => $pl_nodeid));
++    if(count($res) == 0) return null;
++    return $res[0];
++}
++
++/*
++ * SSH
++ */
++
++function expssh_updatehosts($hostlist)
++{
++    if(!is_array($hostlist)) return;
++    
++    $userid = CWebUser::$data['userid'];
++    
++    $old_hostlist = array();
++    $new_hostlist = array();
++    foreach($hostlist as $h)
++    {
++        $hc = mysql_real_escape_string(trim($h));
++        if(!$hc) continue;
++        if(is_numeric($hc))
++            $old_hostlist[] = $hc;
++        else //added hosts value is the host itself not an ID
++            $new_hostlist[] = $hc;
++    }
++    
++    //look for deleted hosts
++    if(count($old_hostlist) > 0)
++    {
++        $sql = 'DELETE FROM exp_host
++            WHERE userid = '.$userid
++            .' AND target = "ssh"'
++            .' AND hostid NOT IN ('.implode(',', $old_hostlist).')';
++        DBexecute($sql);
++    }
++    
++    //look for new hosts
++    foreach($new_hostlist as $h)
++        expdb_insert('exp_host', array('userid' => $userid, 'host' => $h, 
'target' => 'ssh'));
++}
+diff --git include/experiments/tasklist.php include/experiments/tasklist.php
+new file mode 100644
+index 0000000..adf432c
+--- /dev/null
++++ include/experiments/tasklist.php
+@@ -0,0 +1,292 @@
++<?php
++
++require_once dirname(__FILE__).'/files.php';
++
++//default XML elements (for creating empty nods)
++$exptasklist_defaults = array();
++$exptasklist_defaults['sequence'] = new SimpleXMLElement('<sequence 
name=""></sequence>');
++$exptasklist_defaults['run'] = new SimpleXMLElement('<run 
name=""><command></command><arguments></arguments><timeout>0</timeout><expected_return_code>0</expected_return_code><expected_output></expected_output><stop_on_fail>false</stop_on_fail></run>');
++$exptasklist_defaults['run_per_host'] = new SimpleXMLElement('<run_per_host 
name=""><command_file></command_file><output_prefix></output_prefix><timeout>0</timeout><expected_return_code>0</expected_return_code><expected_output></expected_output><stop_on_fail>false</stop_on_fail></run_per_host>');
++$exptasklist_defaults['put'] = new SimpleXMLElement('<put 
name=""><source></source><destination></destination><stop_on_fail>false</stop_on_fail></put>');
++$exptasklist_defaults['get'] = new SimpleXMLElement('<get 
name=""><source></source><destination>./</destination><stop_on_fail>false</stop_on_fail></get>
 ');
++
++function exptasklist_addall()
++{
++    $sql = "SELECT * FROM exp_tasklist";
++    $indb = DBfetchArrayAssoc(DBSelect($sql), 'fsname');
++    
++    $indir = scandir($GLOBALS['GPLMT_TASKLISTS_DIR']);
++    
++    foreach($indir as $i)
++    {
++        if(substr($i, -4) != '.xml') continue;
++        if(isset($indb[$i])) continue;
++        $name = str_replace('_', ' ', $i);
++        $name = str_replace('.xml', '', $name);
++        
++        expdb_insert('exp_tasklist', array('name' => $name, 'fsname' => $i, 
'userid' => CWebUser::$data['userid'], 'shared' => 1));
++    }
++}
++
++function exptasklist_getall($editable = false)
++{
++    $sql = "SELECT exp_tasklist.*, CONCAT_WS(' ', users.name, users.surname) 
as username
++            FROM exp_tasklist INNER JOIN users ON exp_tasklist.userid = 
users.userid";
++    if(!(CWebUser::$data['type'] == 3)) //not super admin
++    {
++        $sql .= ' WHERE exp_tasklist.userid = '.CWebUser::$data['userid'];
++        if(!$editable)
++            $sql .= ' OR exp_tasklist.shared = 1';
++    }
++    
++    return DBfetchArray(DBselect($sql));
++}
++
++function exptasklist_getbyid($tasklistid)
++{
++    $res = expdb_select('exp_tasklist', array('tasklistid' => $tasklistid));
++    if(count($res) == 0) return null;
++    return $res[0];
++}
++
++function exptasklist_getcontent($tasklistid)
++{
++    $tl_row = exptasklist_getbyid($tasklistid);
++    if(!$tl_row) return null;
++    $file = $GLOBALS['GPLMT_TASKLISTS_DIR'].$tl_row['fsname'];
++    if(!file_exists($file)) return null;
++    return file_get_contents($file);
++}
++
++/**
++ * Given a tasklist id, returns 0, 1 or 2 for No access, read, read/write 
respectively
++ *
++ * @return int
++ */
++function exptasklist_allowed($tasklistid)
++{
++    $tl_row = exptasklist_getbyid($tasklistid);
++    if(!$tl_row) return 0;
++    if(CWebUser::$data['type'] == 3 || $tl_row['userid'] == 
CWebUser::$data['userid']) return 2;
++    if($tl_row['shared']) return 1;
++    return 0;
++}
++
++function exptasklist_delete($tid)
++{
++    $meta = exptasklist_getbyid($tid);
++    if(!$meta)
++    {
++        error("Invalid tasklist ID");
++        return false;
++    }
++    $fullFileName = $GLOBALS['GPLMT_TASKLISTS_DIR'].$meta['fsname'];
++    
++    //delete from DB
++    expdb_delete('exp_tasklist', array('tasklistid' => $tid));
++    
++    //delete file
++    if(file_exists($fullFileName)) unlink($fullFileName);
++    
++    return true;
++}
++
++function exptasklist_sxmlappend(SimpleXMLElement $to, SimpleXMLElement $from)
++{
++    $toDom = dom_import_simplexml($to);
++    $fromDom = dom_import_simplexml($from);
++    $newDom = $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, 
true));
++    return simplexml_import_dom($newDom);
++}
++
++function exptasklist_constructxml($data)
++{
++    global $exptasklist_defaults;
++    
++    $xml = new SimpleXMLElement('<?xml version="1.0" 
encoding="UTF-8"?><tasklist></tasklist>');
++    $xml->addAttribute('xsi:noNamespaceSchemaLocation', 
"../tasklist_schema.xsd", "http://www.w3.org/2001/XMLSchema-instance";);
++    $xml->addChild('options');
++
++    //name
++    if(empty($data['name']))
++    {
++        error("Missing name field");
++        return false;
++    }
++    $name = $data['name'];
++    $xml->addAttribute('name', $name);
++    
++    //target
++    /*if(!empty($data['target']))
++        $xml->options->addChild('target', $data['target']);*/
++
++    //log dir
++    if(!empty($data['logdir']))
++        $xml->options->addChild('log_dir', $data['logdir']);
++    
++    //index for node components
++    $nodesIndex = array();
++    
++    foreach($data as $k => $v)
++    {
++        $parts = explode('_', $k); // field name consists of field type + the 
path to the field (e.g. command_2_1)
++        $parts_count = count($parts);
++        if($parts_count == 1 || $parts_count > 3) continue;
++        
++        $field = str_replace('$', '_', $parts[0]);
++        $value = trim($v);
++        $index = implode('_', array_slice($parts, 1));
++        
++        if($field == 'type') //should be the first field in the node, its type
++        {
++            if(!array_key_exists($value, $exptasklist_defaults)) continue; 
//invalid type
++            
++            if($parts_count == 2) $parent = $xml;
++            else $parent = $nodesIndex[$parts[1]];
++            
++            $newXml = $exptasklist_defaults[$value];
++            if($value != 'sequence')
++            {
++                $newXml['id'] = $parts[$parts_count - 1]; //GPLMT doesn't 
accept ID in sequence but mandatory for others
++                $newXml['name'] = $newXml['id']; //Name is also mandatory, so 
we set it by the ID unless we get a name from the user later
++            }
++            $newXml['enabled'] = 'false'; //Disabled by default unless we get 
the enabled flag from form
++            
++            $nodesIndex[$index] = exptasklist_sxmlappend($parent, $newXml);
++            
++            
++            continue;
++        }
++        
++        if(!array_key_exists($index, $nodesIndex)) continue; //problem or 
data element that is not related to the XML
++        if($field == 'name' && empty($value)) continue;
++        
++        $subxml = $nodesIndex[$index];
++        $type = $subxml->getName();
++        
++        //validations:
++        switch($field)
++        {
++            //bool
++            case 'enabled': case 'stop_on_fail':
++                $value = strtolower($value);
++                if($value != 'yes' && $value != 'no')
++                {
++                    error("Value for $field should be true or false!");
++                    return false;
++                }
++                $value = ($value == 'yes') ? 'true' : 'false';
++                break;
++            
++            //int
++            case 'timeout': case 'expected_return_code':
++                if(!is_numeric($value))
++                {
++                    error("Value for $field should be an integer!");
++                    return false;
++                }
++                break;
++
++            //file
++            case 'source':
++                if($type == 'put')
++                {
++                    $value = exp_cleanfilename($value);
++                }
++                break;
++            case 'destination':
++                if($type == 'get')
++                {
++                    $value = './';
++                }
++                break;
++        }
++        
++        //writing values
++        switch($field)
++        {
++            //attributes
++            case 'enabled': case 'name':
++                $subxml[$field] = $value;
++                break;
++            
++            case 'command': case 'arguments': case 'timeout': case 
'expected_return_code': case 'expected_output':
++            case 'stop_on_fail': case 'command_file': case 'output_prefix': 
case 'source': case 'destination':
++                $subxml->$field = $value;
++                break;
++            
++            default:
++                error("Unknown field: $field");
++        }
++    }
++    
++    //save the resulting XML to file (formatted)
++    $dom = dom_import_simplexml($xml)->ownerDocument;
++    $dom->formatOutput = true;
++    return $dom->saveXML();
++}
++
++function exptasklist_add($data)
++{
++    $xml = exptasklist_constructxml($data);
++    if(!$xml) return false;
++    
++    //name
++    $name = $data['name'];
++    
++    //description
++    $description = empty($data['description']) ? '' : $data['description'];
++    
++    //shared
++    $shared = false;
++    $shared = (!empty($data['shared']) && ($data['shared'] == 'yes'));
++    
++    //create new fsname
++    $fsname = str_replace(' ', '_', $name);
++    $fsname = str_replace('\\', '_', $fsname);
++    $counter = 0;
++    while(file_exists($GLOBALS['GPLMT_TASKLISTS_DIR'].$fsname.'.xml'))
++    {
++        $fsname .= strval($counter);
++        $counter++;
++    }
++    $fsname .= '.xml';
++    
++    //user ID
++    $userid = CWebUser::$data['userid'];
++    
++    //save to file
++    file_put_contents($GLOBALS['GPLMT_TASKLISTS_DIR'].$fsname, $xml);
++    
++    //save to DB
++    expdb_insert('exp_tasklist',
++        array('name' => $name, 'description' => $description, 'fsname' => 
$fsname, 'userid' => $userid, 'shared' => intval($shared)));
++    
++    return true;
++}
++
++function exptasklist_update($tasklistid, $data)
++{
++    $meta = exptasklist_getbyid($tasklistid); //get task meta data from db
++    
++    $xml = exptasklist_constructxml($data);
++    if(!$xml) return false;
++    
++    //name
++    $name = $data['name'];
++    
++    //description
++    $description = empty($data['description']) ? '' : $data['description'];
++    
++    //shared
++    $shared = false;
++    $shared = (!empty($data['shared']) && ($data['shared'] == 'yes'));
++    
++    file_put_contents($GLOBALS['GPLMT_TASKLISTS_DIR'].$meta['fsname'], $xml);
++    
++    //update DB
++    expdb_update('exp_tasklist', array('name' => $name, 'description' => 
$description, 'shared' => intval($shared)),
++        array('tasklistid' => $tasklistid));
++    
++    return true;
++}
+diff --git include/menu.inc.php include/menu.inc.php
+index 6e27065..51b0d56 100644
+--- include/menu.inc.php
++++ include/menu.inc.php
+@@ -281,6 +281,38 @@ $ZBX_MENU = array(
+                       )
+               )
+       ),
++      'experiment' => array(
++              'label'                         => _('Experiments'),
++              'user_type'                     => USER_TYPE_ZABBIX_ADMIN,
++              'node_perm'                     => PERM_READ_WRITE,
++              'default_page_id'       => 0,
++              'pages' => array(
++                      array(
++                              'url' => 'execute.php',
++                              'label' => _('Deploy & Execute')
++                      ),
++                      array(
++                              'url' => 'results.php',
++                              'label' => _('Results')
++                      ),
++                      array(
++                              'url' => 'targets.php',
++                              'label' => _('Targets')
++                      ),
++                      array(
++                              'url' => 'tasklist.php',
++                              'label' => _('Tasklists')
++                      ),
++                      array(
++                              'url' => 'files.php',
++                              'label' => _('Files')
++                      ),
++                      array(
++                              'url' => 'conf.php',
++                              'label' => _('Configuration')
++                      )
++              )
++      ),
+       'login' => array(
+               'label'                                 => _('Login'),
+               'user_type'                             => 0,
+diff --git include/views/administration.script.list.php 
include/views/administration.script.list.php
+index bb42f3f..aab1244 100644
+--- include/views/administration.script.list.php
++++ include/views/administration.script.list.php
+@@ -40,9 +40,18 @@ $scriptsTable->setHeader(array(
+       make_sorting_header(_('Commands'), 'command'),
+       _('User group'),
+       _('Host group'),
+-      _('Host access')
++      _('Host access'),
++      _('Run on Host Group')
+ ));
+ 
++//get list of host groups
++$hostgroups = API::HostGroup()->get(array(
++              'not_proxy_host' => 1,
++              'sortfield' => 'name',
++              'editable' => true,
++              'output' => array('name')
++      ));
++
+ foreach ($this->data['scripts'] as $script) {
+       $scriptid = $script['scriptid'];
+ 
+@@ -72,6 +81,18 @@ foreach ($this->data['scripts'] as $script) {
+               $scriptExecuteOn = '';
+       }
+ 
++    //create hostgroups combobox
++    $runForm = new CForm('GET', 'scripts_exec.php');
++    $runForm->addItem(new CInput('hidden', 'execute', '1'));
++    $runForm->addItem(new CInput('hidden', 'scriptid', $script['scriptid']));
++    
++    $grpsComboBox = new CComboBox('groupid');
++    foreach($hostgroups as $hostgroup)
++        $grpsComboBox->addItem(new CComboItem($hostgroup['groupid'], 
$hostgroup['name']));
++
++    $runForm->addItem($grpsComboBox);
++    $runForm->addItem(new CInput('submit', 'submit', 'Run'));
++
+       $scriptsTable->addRow(array(
+               new CCheckBox('scripts['.$script['scriptid'].']', 'no', null, 
$script['scriptid']),
+               new CLink($script['name'], 
'scripts.php?form=1&scriptid='.$script['scriptid']),
+@@ -80,7 +101,8 @@ foreach ($this->data['scripts'] as $script) {
+               zbx_nl2br(htmlspecialchars($script['command'], ENT_COMPAT, 
'UTF-8')),
+               ('' == $script['userGroupName']) ? _('All') : 
$script['userGroupName'],
+               ('' == $script['hostGroupName']) ? _('All') : 
$script['hostGroupName'],
+-              ((PERM_READ_WRITE == $script['host_access']) ? _('Write') : 
_('Read'))
++              ((PERM_READ_WRITE == $script['host_access']) ? _('Write') : 
_('Read')),
++              $runForm
+       ));
+ }
+ 
+diff --git include/views/experiments.conf.php 
include/views/experiments.conf.php
+new file mode 100644
+index 0000000..0af85d5
+--- /dev/null
++++ include/views/experiments.conf.php
+@@ -0,0 +1,66 @@
++<?php
++
++$conf = $this->get('conf');
++
++$cWidget = new CWidget();
++
++$cForm = new CForm('post');
++$cTable = new CTableInfo();
++
++$current_section = '';
++foreach($conf as $c)
++{
++    if($c['section'] != $current_section)
++    {
++        $current_section = $c['section'];
++        $cTable->addRow(strtoupper($current_section));
++    }
++    
++    switch($c['type'])
++    {
++        case 'text': case 'integer':
++            $cInput = new CTextBox($c['configid'], $c['value']);
++            break;
++        
++        case 'password':
++            $cInput = new CPassBox($c['configid'], $c['value'], 20);
++            break;
++        
++        case 'boolean':
++            $cHidden = new CInput('hidden', $c['configid'], 'no');
++            $cChkbox = new CCheckBox($c['configid'], $c['value']);
++            $cInput = array($cHidden, $cChkbox);
++            break;
++        
++        case 'file':
++            $userfiles = expfiles_getuserfiles();
++            $selectedfile = '';
++            if(!empty($c['value'])) $selectedfile = basename($c['value']);
++            $cInput = new CComboBox($c['configid']);
++            $cInput->addItem('', '');
++            foreach($userfiles as $uf)
++                $cInput->addItem($uf, $uf, ($selectedfile == $uf)?'yes':null);
++            break;
++
++        case 'enum':
++            $options = expconfig_getenum($c['configid']);
++            $cInput = new CComboBox($c['configid']);
++            foreach($options as $o)
++                $cInput->addItem($o['value'], $o['label'], ($c['value'] == 
$o['value'])?'yes':null);
++            break;
++
++        default:
++            $cInput = new CLabel('Invalid type');
++            break;
++    }
++    
++    $help_image = new CImg('images/general/question_mark.png');
++    $help_image->attr('title', $c['description']);
++    
++    $cTable->addRow(array($c['label'], array($cInput, $help_image)));
++}
++$cTable->addRow(new CSubmit('update', 'Update'));
++
++$cForm->addItem($cTable);
++$cWidget->addItem($cForm);
++return $cWidget;
+diff --git include/views/experiments.execute.php 
include/views/experiments.execute.php
+new file mode 100644
+index 0000000..bc87ce3
+--- /dev/null
++++ include/views/experiments.execute.php
+@@ -0,0 +1,100 @@
++<?php
++
++$targets = $this->get('targets');
++$currenttarget = $this->get('currenttarget');
++
++//Main Form
++$exec_frm = new CForm();
++$exec_frm->setName('web.experiment.execute.php.');
++$exec_frm->attr('id', 'mainfrm');
++
++//Main table
++$main_table = new CTable();
++
++//Row 1 - Targets
++$targets_cmb = new CComboBox('target');
++foreach($targets as $k => $v)
++    $targets_cmb->addItem($v, $k, ($v == $currenttarget)?'yes':null);
++$targets_cmb->attr('onchange', "jQuery('#mainfrm').submit();");
++
++$main_table->addRow(new CRow(array(
++    'Select Target:',
++    $targets_cmb)));
++
++//Row 2 - Target settings
++$settings_enabled = false;
++switch($currenttarget)
++{
++    case 'ssh':
++        $settings_enabled = true;
++        
++        $sshhosts = expnodes_gethosts('ssh');
++        $sshhosts_tb = new CTweenBox($exec_frm, 'hosts');
++        foreach($sshhosts as $sh)
++            $sshhosts_tb->addItem($sh['hostid'], $sh['host'], true);
++        
++        $settings_elm = $sshhosts_tb->get('Selected:', 'Excluded:');
++        
++        break;
++    
++    case 'planetlab':
++        $settings_enabled = true;
++        
++        $plhosts = exppl_getSliceNodes();
++        $plhosts_tb = new CTweenBox($exec_frm, 'hosts');
++        foreach($plhosts as $ph)
++            $plhosts_tb->addItem($ph['hostid'], $ph['hostname'], true);
++        
++        $settings_elm = $plhosts_tb->get('Selected:', 'Excluded:');
++    
++        break;
++    
++    default:
++        $settings_enabled = true;
++        $settings_elm = 'Invalid Target. WHY?';
++        break;
++}
++if($settings_enabled)
++    $main_table->addRow(new CRow(array(
++        'Target Settings:',
++        $settings_elm)));
++
++//Row 3 - Tasklists
++$tasklists = $this->get('tasklists');
++
++$tasklists_tbl = new CTable();
++
++$tasklists_rad1 = new CRadioButton('usetasklist', '1', 'input radio', null, 
true);
++$tasklists_rad2 = new CRadioButton('usetasklist', '0', 'input radio');
++$tasklists_cmb = new CComboBox('tasklist');
++foreach($tasklists as $t)
++    $tasklists_cmb->addItem($t['tasklistid'], $t['name']);
++$tasklists_txt = new CTextBox('cmd');
++
++
++$tasklists_tbl->addRow(
++array(
++new CDiv(array(
++$tasklists_rad1, 'Tasklist:')),
++$tasklists_cmb));
++$tasklists_tbl->addRow(
++array(
++new CDiv(array(
++$tasklists_rad2, 'Command:')),
++$tasklists_txt));
++
++$main_table->addRow(new CRow(array(
++    'Select Tasklist / Command:',
++    $tasklists_tbl
++)));
++
++
++$exec_frm->addItem($main_table);
++
++/*
++ * footer
++ */
++$run_submit = array(new CSubmit('run', 'Run'));
++$exec_frm->addItem(makeFormFooter($run_submit));
++
++return $exec_frm;
+diff --git include/views/experiments.files.php 
include/views/experiments.files.php
+new file mode 100644
+index 0000000..1fd1203
+--- /dev/null
++++ include/views/experiments.files.php
+@@ -0,0 +1,30 @@
++<?php
++
++$files = $this->get('files');
++
++$fWidget = new CWidget();
++
++$uploadForm = new CForm('post', null, 'multipart/form-data');
++$uploadForm->addItem(new CInput('file', 'file'));
++$uploadForm->addItem(new CSubmit('upload', 'Upload file'));
++//add maximum size note
++
++$fWidget->addPageHeader('USER FILES', $uploadForm);
++
++$files_tbl = new CTableInfo('No files added yet.');
++$files_tbl->setHeader(array('File name', ''));
++foreach($files as $f)
++{
++    //download link
++    $download_lnk = new CLink($f, '?download='.$f);
++    
++    //delete link
++    $delete_lnk = new CLink('delete', '?delete='.$f);
++    
++    $files_tbl->addRow(array($download_lnk, $delete_lnk));
++    //TODO: add delete, download
++}
++
++$fWidget->addItem($files_tbl);
++
++return $fWidget;
+diff --git include/views/experiments.results.php 
include/views/experiments.results.php
+new file mode 100644
+index 0000000..2591b41
+--- /dev/null
++++ include/views/experiments.results.php
+@@ -0,0 +1,63 @@
++<?php
++
++//Main table
++$main_table = new CTableInfo();
++
++$results = $this->get('results');
++$runid = $this->get('runid'); //if set, one of the runs is selected
++
++$main_table->setHeader(array('', 'Status', 'Started On', 'Target', 
'Percentage completed', '', ''));
++
++foreach($results as $r)
++{
++    $div_actions = new CDiv();
++    if($r['status'] == 'Running')
++        $div_actions->addItem(new CLink('interrupt', 
'results.php?interrupt='.$r['runid']));
++    else
++    {
++        $div_actions->addItem(new CLink('delete', 
'results.php?delete='.$r['runid']));
++        //$div_actions->addItem(new CButtonDelete('Are you sure you want to 
delete?', $r['runid']));
++        $div_actions->addItem(' | ');
++        $div_actions->addItem(new CLink('re-run', 
'results.php?rerun='.$r['runid']));
++    }
++    
++    //nodes table
++    $nodes_table = new CTableInfo();
++    foreach($r['nodes'] as $n)
++    {
++        $nodes_table->addRow(new CRow(array(
++            $n['interface'],
++            $n['status'],
++            $n['percentage'].'%',
++            new CLink('log', 
'results.php?runid='.$r['runid'].'&hostid='.$n['hostid'])
++        )));
++    }
++    
++    $main_row = array(
++        new CButton(null, '+/-', 
"javascript:jQuery('#".$r['runid']."').toggle();"),
++        $r['status'],
++        $r['startedon'],
++        $r['target'],
++        $r['percentage'].'%',
++        new CLink('log', 'results.php?runid='.$r['runid']),
++        $div_actions
++        );
++    $main_table->addRow(new CRow($main_row));
++    $hidden_col = new CCol($nodes_table, null, count($main_row));
++    $hidden_col->attr('id', $r['runid']);
++    if(empty($runid) || $runid != $r['runid'])
++        $hidden_col->attr('style', 'display:none;');
++    $main_table->addRow(new CRow($hidden_col));
++}
++
++$log = $this->get('log');
++
++if(!empty($log))
++{
++    $res_txt = new CTextArea(null, $log, array('rows' => substr_count($log, 
"\n") + 1, 'readonly' => 1));
++    $res_txt->attr('style', 'width:100%;font-size:15px;');
++    
++    return new CDiv(array($main_table, 'RESULT:', $res_txt));
++}
++else
++    return $main_table;
+diff --git include/views/experiments.targets.php 
include/views/experiments.targets.php
+new file mode 100644
+index 0000000..af46fba
+--- /dev/null
++++ include/views/experiments.targets.php
+@@ -0,0 +1,90 @@
++<?php
++$targetlist = $this->get('targetlist');
++$default_target = reset($targetlist);
++$selected_target = $this->get('selected_target');
++if(!$selected_target) $selected_target = $default_target;
++
++//Main form
++$main_frm = new CForm();
++$main_frm->setName('web.experiment.targets.php.');
++$main_frm->attr('id', 'mainfrm');
++
++//Main table
++$main_table = new CTable();
++
++//Row 1 - Targets
++$targets_cmb = new CComboBox('target');
++foreach($targetlist as $k => $v)
++    $targets_cmb->addItem($v, $k, ($v == $selected_target)?'yes':null);
++$targets_cmb->attr('onchange', "jQuery('#mainfrm').submit();");
++$main_table->addRow(array('Target:', $targets_cmb));
++
++//Row 2 - Target edit
++switch($selected_target)
++{
++    case 'ssh':
++        $ssh_lst = new CListBox('sshhosts[]', null, 12);
++        $sshhosts = $this->get('sshhosts');
++        foreach($sshhosts as $sh)
++            $ssh_lst->addItem($sh['hostid'], $sh['host']);
++        
++        $del_btn = new CButton('delsshhost', 'Remove', 
"jQuery('select[name=\"sshhosts[]\"]').find(':selected').remove()");
++        
++        $add_txt = new CTextBox('newsshhost', null, 30);
++        $add_btn =  new CButton('addsshhost', 'Add', 
"jQuery('select[name=\"sshhosts[]\"]').append('<option>'+jQuery('input[name=newsshhost]').val()+'</option>');jQuery('input[name=newsshhost]').val('')");
++        
++        $submit_btn = new CSubmit('apply', 'Apply');
++        $submit_btn->attr('onclick', "jQuery('select[name=\"sshhosts[]\"] 
option').attr('selected', 'yes')");
++        
++        $main_table->addRow(array('SSH:', array($ssh_lst, $del_btn)));
++        $main_table->addRow(array('', array($add_txt, $add_btn)));
++        $main_table->addRow(array('', $submit_btn));
++        
++        break;
++    
++    case 'planetlab':
++        $pagesize = 20;
++        $pageoffset = intval($this->get('ploffset'));
++        if(!$pageoffset || $pageoffset < 0) $pageoffset = 0;
++        $hostfilter = $this->get('plfilter');
++        if(!$hostfilter) $hostfilter = null;
++        $slicename = exppl_getslicename();
++        $slicenodes = exppl_getSliceNodes();
++        $availnodes = exppl_getAvailableNodes($pageoffset, $pagesize, 
$hostfilter);
++    
++        $pl_tb = new CTweenBox($main_frm, 'plnodes');
++        foreach($slicenodes as $sn)
++            $pl_tb->addItem($sn['node_id'], $sn['hostname'], true);
++        foreach($availnodes as $an)
++            $pl_tb->addItem($an['node_id'], $an['hostname']);
++        
++        $filter_frm = new CForm('get');
++        $filter_frm->attr('id', 'filterfrm');
++        $filter_tb = new CTextBox('plfilter', $hostfilter);
++        $filter_tb->attr('id', 'plfilter');
++        $filter_btn = new CSubmit('filter', 'Filter', 
'jQuery("#ploffset").val(0)');
++        $page_tb = new CTextBox('ploffset', $pageoffset, 2);
++        $page_tb->attr('id', 'ploffset');
++        $prev_btn = new CSubmit('plprev', '<<', 
'jQuery("#ploffset").val(parseInt(jQuery("#ploffset").val(), 10) - 
1);jQuery("#filterfrm").submit();');
++        $next_btn = new CSubmit('plnext', '>>', 
'jQuery("#ploffset").val(parseInt(jQuery("#ploffset").val(), 10) + 
1);jQuery("#filterfrm").submit();');
++        $clear_btn = new CSubmit('plclear', 'Clear', 
'jQuery("#ploffset").val(0);jQuery("#plfilter").val("")');
++        $filter_tbl = new CTable();
++        $filter_tbl->addRow(array(array($prev_btn, $page_tb, $next_btn)));
++        $filter_tbl->addRow(array(array('Filter:', $filter_tb, $filter_btn)));
++        $filter_tbl->addRow(array($clear_btn));
++        $filter_frm->addItem($filter_tbl);
++        
++        $pl_tbl = new CTable();
++        $pl_tbl->addRow(array($pl_tb->get($slicename, 'Available'), 
$filter_frm));
++        
++        $submit_btn = new CSubmit('apply', 'Apply');
++        
++        $main_table->addRow(array('Planetlab', $pl_tbl));
++        $main_table->addRow(array('', $submit_btn));
++        
++        break;
++}
++
++$main_frm->addItem($main_table);
++
++return $main_frm;
+diff --git include/views/experiments.tasklist.edit.php 
include/views/experiments.tasklist.edit.php
+new file mode 100644
+index 0000000..152cf29
+--- /dev/null
++++ include/views/experiments.tasklist.edit.php
+@@ -0,0 +1,318 @@
++<?php
++
++$new = $this->get('new');
++
++if($new)
++    $xml = new SimpleXMLElement('<?xml version="1.0" 
encoding="UTF-8"?><tasklist></tasklist>');
++else
++    $xml = $this->get('xml');
++
++//$targets = $this->get('targets');
++$tid = $this->get('tid');
++if($new)
++    $meta = array();
++else
++    $meta = $this->get('meta');
++$exptasklist_defaults = $this->get('exptasklist_defaults');
++
++function tlview_parseseq($xml, $postfix)
++{
++    $seq_tbl = new CTableInfo('');
++    $seq_tbl->attr('id', "table$postfix");
++    
++    //Top Row:
++    $btns_div = new CDiv();
++    //Delete button
++    $del_btn = new CButton('delete', 'delete', 'javascript: 
jQuery("#row'.$postfix.'").remove()');
++    //Type (hidden)
++    $type_hdn = new CInput('hidden', 'type'.$postfix, 'sequence');
++    $btns_div->addItem($type_hdn);
++    //Add runs
++    $run_cmb = new CComboBox('run');
++    $run_cmb->attr('id', "runs$postfix");
++    $run_cmb->addItem('run', 'run');
++    $run_cmb->addItem('run_per_host', 'run_per_host');
++    $run_cmb->addItem('put', 'put');
++    $run_cmb->addItem('get', 'get');
++    $btns_div->addItem($run_cmb);
++    $js = 'javascript: '; //javascript used to add runs under this sequence
++    $js .= 'if (typeof window.counter'.$postfix.' === "undefined") 
window.counter'.$postfix.' = '.(count($xml->children())+1).';';
++    $js .= 'new_node(jQuery("#runs'.$postfix.'").val(), 
"'.$postfix.'_"+counter'.$postfix.', "table'.$postfix.'", 
counter'.$postfix.'%2);';
++    $js .= 'counter'.$postfix.'++;';
++    $add_btn = new CButton('add', 'Add', $js);
++    $btns_div->addItem($add_btn);
++    //Move up
++    $mvup_btn = new CButton('mvup', 'Move UP', 'javascript: 
p=jQuery("#row'.$postfix.'").prev(); if(p.attr("id")) 
jQuery("#row'.$postfix.'").insertBefore(p);');
++    $btns_div->addItem($mvup_btn);
++    //Move down
++    $mvdown_btn = new CButton('mvdown', 'Move DOWN', 'javascript: 
n=jQuery("#row'.$postfix.'").next(); if(n.attr("id")) 
jQuery("#row'.$postfix.'").insertAfter(n);');
++    $btns_div->addItem($mvdown_btn);
++    
++    $seq_tbl->addRow(array($del_btn, $btns_div));
++    
++    //Sequence attributes
++    
++    //Name attribute
++    $name_tb = new CInput('text', 'name'.$postfix, (string)$xml['name']);
++    $name_tb->addStyle('width: 50em;');
++    $seq_tbl->addRow(array('Name:', $name_tb));
++    
++    //Enabled attribute
++    $enabled_chb = new CCheckBox('enabled'.$postfix, 
(((string)$xml['enabled']) == 'false')?'no':'yes');
++    $seq_tbl->addRow(array('Enabled:', $enabled_chb));
++    
++    
++    $counter = 1;
++    foreach($xml->children() as $c)
++    {
++        $name = trim($c->getName());
++        $row_postfix = $postfix.'_'.$counter;
++        $seq_tbl->addRow(tlview_parserun($name, $c, $row_postfix));
++        $counter++;
++    }
++    
++    //print "<script>var counter$postfix = $counter</script>";
++    
++    return new CRow(array('Sequence:', $seq_tbl), null, "row$postfix");
++}
++function tlview_parserun($type, $xml, $postfix)
++{
++    $run_tbl = new CTableInfo('');
++    
++    //common elements
++    
++    //Top Row:
++    $btns_div = new CDiv();
++    //Delete button
++    $del_btn = new CButton('delete', 'delete', 'javascript: 
jQuery("#row'.$postfix.'").remove()');
++    //Type (hidden)
++    $type_hdn = new CInput('hidden', 'type'.$postfix, $type);
++    $btns_div->addItem($type_hdn);
++    //Move up
++    $mvup_btn = new CButton('mvup', 'Move UP', 'javascript: 
p=jQuery("#row'.$postfix.'").prev(); if(p.attr("id")) 
jQuery("#row'.$postfix.'").insertBefore(p);');
++    $btns_div->addItem($mvup_btn);
++    //Move down
++    $mvdown_btn = new CButton('mvdown', 'Move DOWN', 'javascript: 
n=jQuery("#row'.$postfix.'").next(); if(n.attr("id")) 
jQuery("#row'.$postfix.'").insertAfter(n);');
++    $btns_div->addItem($mvdown_btn);
++    
++    $run_tbl->addRow(array($del_btn, $btns_div));
++    
++    //Name attribute
++    $name_tb = new CInput('text', 'name'.$postfix, (string)$xml['name']);
++    $name_tb->addStyle('width: 50em;');
++    $run_tbl->addRow(array('Name:', $name_tb));
++    
++    //Enabled attribute
++    $enabled_chb = new CCheckBox('enabled'.$postfix, 
(((string)$xml['enabled']) == 'false')?'no':'yes');
++    $run_tbl->addRow(array('Enabled:', $enabled_chb));
++    
++    switch($type)
++    {
++        case 'run':
++            //command
++            $cmd_tb = new CInput('text', 'command'.$postfix, 
(string)$xml->command);
++            $cmd_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Command:', $cmd_tb));
++            
++            //arguments
++            $args_tb = new CInput('text', 'arguments'.$postfix, 
(string)$xml->arguments);
++            $args_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Arguments:', $args_tb));
++            
++            //timeout
++            $timeout_tb = new CInput('text', 'timeout'.$postfix, 
(string)$xml->timeout);
++            $run_tbl->addRow(array('Timeout:', $timeout_tb));
++            
++            //expected_return_code
++            $expected_return_code_tb = new CInput('text', 
'expected$return$code'.$postfix, (string)$xml->expected_return_code);
++            $run_tbl->addRow(array('Expected Return Code:', 
$expected_return_code_tb));
++            
++            //expected_output
++            $expected_output_tb = new CInput('text', 
'expected$output'.$postfix, (string)$xml->expected_output);
++            $expected_output_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Expected Output:', $expected_output_tb));
++            
++            break;
++        case 'run_per_host':
++            //command_file
++            $command_file_tb = new CInput('text', 'command$file'.$postfix, 
(string)$xml->command_file);
++            $command_file_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Command File:', $command_file_tb));
++            
++            //output_prefix
++            $output_prefix_tb = new CInput('text', 'output$prefix'.$postfix, 
(string)$xml->output_prefix);
++            $output_prefix_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Output Prefix:', $output_prefix_tb));
++            
++            //timeout
++            $timeout_tb = new CInput('text', 'timeout'.$postfix, 
(string)$xml->timeout);
++            $run_tbl->addRow(array('Timeout:', $timeout_tb));
++            
++            //expected_return_code
++            $expected_return_code_tb = new CInput('text', 
'expected$return$code'.$postfix, (string)$xml->expected_return_code);
++            $run_tbl->addRow(array('Expected Return Code:', 
$expected_return_code_tb));
++            
++            //expected_output
++            $expected_output_tb = new CInput('text', 
'expected$output'.$postfix, (string)$xml->expected_output);
++            $expected_output_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Expected Output:', $expected_output_tb));
++        
++            break;
++        case 'put':
++            //source
++            $userfiles = expfiles_getuserfiles();
++            $selectedfile = '';
++            if(!empty($xml->source)) $selectedfile = 
basename((string)$xml->source);
++            $source_cmb = new CComboBox('source'.$postfix);
++            foreach($userfiles as $uf)
++                $source_cmb->addItem($uf, $uf, ($selectedfile == 
$uf)?'yes':null);
++            $run_tbl->addRow(array('Source:', $source_cmb));
++            
++            //destination
++            $destination_tb = new CInput('text', 'destination'.$postfix, 
(string)$xml->destination);
++            $destination_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Destination:', $destination_tb));
++        
++            break;
++        case 'get':
++            //source
++            $source_tb = new CInput('text', 'source'.$postfix, 
(string)$xml->source);
++            $source_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Source:', $source_tb));
++            
++            //destination (removed because now all files should go to the 
user specific folder)
++            /*$destination_tb = new CInput('text', 'destination'.$postfix, 
(string)$xml->destination);
++            $destination_tb->addStyle('width: 50em;');
++            $run_tbl->addRow(array('Destination:', $destination_tb));*/
++            break;
++    }
++    
++    //Stop on fail
++    $stop_on_fail_chb = new CCheckBox('stop$on$fail'.$postfix, 
(((string)$xml->stop_on_fail) == 'false')?'no':'yes');
++    $run_tbl->addRow(array('Stop on fail:', $stop_on_fail_chb));
++    
++    return new CRow(array("$type:", $run_tbl), null, "row$postfix");
++    return $run_tbl;
++}
++
++//print_r($xml);
++
++if($new)
++    $main_frm = new CForm('post', 'tasklist.php?new=new');
++else
++    $main_frm = new CForm('post', 'tasklist.php?tid='.$tid);
++$main_tbl = new CTableInfo('');
++$main_tbl->attr('id', 'table_main');
++
++//Top Row:
++$btns_div = new CDiv();
++//'Add run' (all types)
++$run_cmb = new CComboBox('run');
++$run_cmb->attr('id', 'runs_main');
++$run_cmb->addItem('sequence', 'sequence');
++$run_cmb->addItem('run', 'run');
++$run_cmb->addItem('run_per_host', 'run_per_host');
++$run_cmb->addItem('put', 'put');
++$run_cmb->addItem('get', 'get');
++$btns_div->addItem($run_cmb);
++$add_btn = new CButton('add', 'Add', "javascript: 
new_node(jQuery('#runs_main').val(), '_'+counter, 'table_main', counter%2); 
counter++;");
++$btns_div->addItem($add_btn);
++
++$main_tbl->addRow(array('', $btns_div));
++
++//name attribute
++$name_tb = new CInput('text', 'name', (string)$xml['name']);
++$name_tb->addStyle('width: 50em;');
++$main_tbl->addRow(array('Name:', $name_tb));
++
++//description
++$desc_ta = new CTextArea('description', 
(empty($meta['description']))?'':$meta['description']);
++$main_tbl->addRow(array('Description:', $desc_ta));
++
++//shared
++$shared_chb = new CCheckBox('shared', (empty($meta['shared']))?'no':'yes');
++$main_tbl->addRow(array('Shared:', $shared_chb));
++
++//option 1 - Target
++/*$selected_target = 
isset($xml->options->target)?trim((string)$xml->options->target):'remote_ssh';
++$target_cmb = new CComboBox('target');
++foreach($targets as $t)
++    $target_cmb->addItem($t, $t, ($selected_target == $t)?'yes':null);
++$main_tbl->addRow(array('Target:', $target_cmb));*/
++
++//option 2 - Log dir
++$log_dir = 
isset($xml->options->log_dir)?trim((string)$xml->options->log_dir):'';
++$log_dir_tb = new CInput('text', 'log$dir', $log_dir);
++$log_dir_tb->addStyle('width: 50em;');
++$main_tbl->addRow(array('Log Dir:', $log_dir_tb));
++
++$counter = 1;
++foreach($xml->children() as $c)
++{
++    $name = trim($c->getName());
++    if($name == 'sequence')
++    {
++        $main_tbl->addRow(tlview_parseseq($c, '_'.$counter));
++        $counter++;
++    }
++    elseif($name == 'run' || $name == 'run_per_host' || $name == 'put' || 
$name == 'get')
++    {
++        $main_tbl->addRow(tlview_parserun($name, $c, '_'.$counter));
++        $counter++;
++    }
++}
++
++$main_frm->addItem($main_tbl);
++
++//$main_frm->addItem(new CInput('hidden', 'tid', $tid));
++if($new)
++    $main_frm->addItem(new CSubmit('add', 'Add'));
++else
++    $main_frm->addItem(new CSubmit('update', 'Update'));
++
++/*print "TESTING:<br/>";
++$tmp = tlview_parserun('run', $default_run, '_100');
++print $tmp->toString();
++print "END TESTING";*/
++
++
++?>
++
++<script>
++var counter = <?=$counter?>;
++
++function new_node(type, postfix, table_id, parity)
++{
++var html = '';
++switch(type)
++{
++case 'sequence':
++html = '<?php print tlview_parseseq($exptasklist_defaults["sequence"], 
"%placeholder%"); ?>';
++break;
++case 'run':
++html = '<?php print tlview_parserun("run", $exptasklist_defaults["run"], 
"%placeholder%"); ?>';
++break;
++case 'run_per_host':
++html = '<?php print tlview_parserun("run_per_host", 
$exptasklist_defaults["run_per_host"], "%placeholder%"); ?>';
++break;
++case 'put':
++html = '<?php print tlview_parserun("put", $exptasklist_defaults["put"], 
"%placeholder%"); ?>';
++break;
++case 'get':
++html = '<?php print tlview_parserun("get", $exptasklist_defaults["get"], 
"%placeholder%"); ?>';
++break;
++}
++
++html = html.replace(/%placeholder%/g, postfix);
++jQuery('#'+table_id).append(html);
++var cl = (parity == 0)?'even_row':'odd_row';
++jQuery('#row'+postfix).addClass(cl);
++jQuery('#row'+postfix).attr('origclass', cl);
++jQuery('#name'+postfix).focus();
++}
++
++</script>
++
++<?php
++
++return $main_frm;
+diff --git include/views/experiments.tasklist.php 
include/views/experiments.tasklist.php
+new file mode 100644
+index 0000000..e6e0ed8
+--- /dev/null
++++ include/views/experiments.tasklist.php
+@@ -0,0 +1,41 @@
++<?php
++
++$tasklists = $this->get('tasklists');
++
++$tlWidget = new CWidget();
++
++$createForm = new CForm('get');
++$createForm->addItem(new CSubmit('new', 'Create tasklist'));
++
++$tlWidget->addPageHeader('CONFIGURATION OF TASKLISTS', $createForm);
++
++//main form
++$tlForm = new CForm('get');
++$tlForm->setName('tasklistForm');
++
++//main table
++$tlTable = new CTableInfo('No tasklists defined.');
++$tlTable->setHeader(array('Name', 'Description', 'User', 'Shared', ''));
++
++foreach($tasklists as $tl)
++{
++    //Name link
++    $name_lnk = new CLink($tl['name'], '?tid='.$tl['tasklistid']);
++    
++    //Delete link
++    $del_btn = new CButtonDelete('Are you sure you want to delete this 
tasklist?', $tl['tasklistid']);
++    
++    $tlTable->addRow(array(
++        $name_lnk,
++        ($tl['description'])?$tl['description']:'',
++        $tl['username'],
++        ($tl['shared'])?'Yes':'No',
++        $del_btn
++        ));
++}
++
++$tlForm->addItem($tlTable);
++
++$tlWidget->addItem($tlForm);
++
++return $tlWidget;
+diff --git include/views/general.script.execute-parallel.php 
include/views/general.script.execute-parallel.php
+new file mode 100644
+index 0000000..4bc5aca
+--- /dev/null
++++ include/views/general.script.execute-parallel.php
+@@ -0,0 +1,54 @@
++<?php
++/*
++** Zabbix
++** Copyright (C) 2000-2011 Zabbix SIA
++**
++** This program is free software; you can redistribute it and/or modify
++** it under the terms of the GNU General Public License as published by
++** the Free Software Foundation; either version 2 of the License, or
++** (at your option) any later version.
++**
++** This program 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 General Public License for more details.
++**
++** You should have received a copy of the GNU General Public License
++** along with this program; if not, write to the Free Software
++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
++**/
++
++
++//javascript item
++$js = new CJSscript();
++
++$numHosts = count($this->data['hosts']);
++
++$js->addItem("<div id=\"counter\" 
style=\"font-size:20px;padding:5px;\">0/$numHosts</div>");
++$js->addItem("<div id=\"content\"></div>");
++$js->addItem("<script type=\"text/javascript\" 
src=\"js/jquery/jquery.js\"></script>");
++$js->addItem("<script type=\"text/javascript\">");
++$js->addItem("var hosts = new Array();");
++$js->addItem("var ctr = 0;");
++
++for($i = 0; $i < $numHosts; $i++)
++{
++    $host = $this->data['hosts'][$i];
++    $js->addItem("hosts[$i] = ".$host['hostid'].";");
++}
++
++$sid = $this->data['sid'];
++$scriptid = $this->data['scriptid'];
++$js->addItem("for(var i=0;i<$numHosts;i++){
++    $.ajax({
++    url: 
\"scripts_exec.php?sid=$sid&execute=1&scriptid=$scriptid&strip=1&hostid=\"+hosts[i],
++    async: true,
++    success: function(data) { $('#content').append(data); ctr++; 
$('#counter').html(ctr+'/$numHosts') }
++    });
++}");
++
++
++//$js->addItem();
++$js->addItem("</script>");
++
++return $js;
+diff --git include/views/general.script.execute.php 
include/views/general.script.execute.php
+index 5f8d2f6..19eaec8 100644
+--- include/views/general.script.execute.php
++++ include/views/general.script.execute.php
+@@ -27,8 +27,17 @@ $scriptForm->setName('scriptForm');
+ 
+ // append tabs to form
+ $scriptTab = new CTabView();
+-$scriptTab->addTab('scriptTab', _s('Result of "%s"', 
$this->data['info']['name']), new CSpan($this->data['message'], 'pre 
fixedfont'));
++$body = new CSpan($this->data['message'],'pre fixedfont');
++if(isset($this->data['error']))
++{
++    $body = new CList(null, "messages");
++    $body->addItem(new CListItem($this->data['error'], "error"));
++}
++
++//    $scriptTab->addTab('errorTab', _s('ERROR'), new 
CSpan($this->data['error'], 'pre fixedfont'));
++$scriptTab->addTab('scriptTab', _s('Result of "%s" ON 
'.$this->data['host']['name'], $this->data['info']['name']), $body);
+ $scriptForm->addItem($scriptTab);
+ 
+ $scriptWidget->addItem($scriptForm);
++$scriptWidget->addItem(BR());
+ return $scriptWidget;
+diff --git js/main.js js/main.js
+index 4f14d4d..2bceabb 100644
+--- js/main.js
++++ js/main.js
+@@ -103,7 +103,7 @@ var PageRefresh = {
+  * Main menu
+  */
+ var MMenu = {
+-      menus:                  {'empty': 0, 'view': 0, 'cm': 0, 'reports': 0, 
'config': 0, 'admin': 0},
++      menus:                  {'empty': 0, 'view': 0, 'cm': 0, 'reports': 0, 
'config': 0, 'admin': 0, 'experiment':0},
+       def_label:              null,
+       sub_active:     false,
+       timeout_reset:  null,
+diff --git manage_monitoring.php manage_monitoring.php
+new file mode 100644
+index 0000000..a01bbfa
+--- /dev/null
++++ manage_monitoring.php
+@@ -0,0 +1,61 @@
++<?php
++/*
++** Zabbix
++** Copyright (C) 2000-2011 Zabbix SIA
++**
++** This program is free software; you can redistribute it and/or modify
++** it under the terms of the GNU General Public License as published by
++** the Free Software Foundation; either version 2 of the License, or
++** (at your option) any later version.
++**
++** This program 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 General Public License for more details.
++**
++** You should have received a copy of the GNU General Public License
++** along with this program; if not, write to the Free Software
++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
++**/
++
++require_once 'include/config.inc.php';
++require_once 'include/hosts.inc.php';
++require_once 'include/items.inc.php';
++require_once 'include/forms.inc.php';
++
++$page['title'] = _('Manage Monitoring');
++$page['file'] = 'manage_monitoring.php';
++
++define('ZBX_PAGE_NO_MENU', 1);
++
++// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
++$fields = array(
++      'template'      =>      array(T_ZBX_INT,        O_OPT,  P_SYS,          
DB_ID,  true),
++      'action'                =>      array(T_ZBX_STR,        O_OPT,  
NOT_EMPTY,      null,   true),
++);
++check_fields($fields);
++
++$templates = array_keys($_REQUEST['template']);
++
++//fetch template
++$options = array(
++      'templateids' => $templates,
++      'selectItems' => array(),
++      'output' => array('name')
++);
++$templates = API::Template()->get($options);
++
++//pull all item ids in array
++$all_items = array();
++foreach($templates as $temp)
++{
++      foreach($temp['items'] as $item)
++              $all_items[] = $item['itemid'];
++}
++
++//perform action
++DBstart();
++$go_result = ($_REQUEST['action'] == 
'disable')?disable_item($all_items):activate_item($all_items);
++$go_result = DBend($go_result);
++
++jsRedirect('dashboard.php');
+diff --git results.php results.php
+new file mode 100644
+index 0000000..6cf8a87
+--- /dev/null
++++ results.php
+@@ -0,0 +1,101 @@
++<?php
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('Experiment Results');
++$page['file'] = 'results.php';
++$page['hist_arg'] = array('resid');
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
++$fields = array(
++    'runid' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
++    'hostid' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
++    'delete' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
++    'interrupt' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
++    'rerun' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null)
++);
++check_fields($fields);
++
++/*
++ * Actions
++ */
++
++if(isset($_REQUEST['delete']))
++{
++    if(exprun_checkpermission($_REQUEST['delete']))
++    {
++        exprun_delete($_REQUEST['delete']);    
++        jsRedirect('results.php');
++    }
++    else
++        error("No permission to delete.");
++}
++
++if(isset($_REQUEST['interrupt']))
++{
++    if(exprun_checkpermission($_REQUEST['interrupt']))
++    {
++        exprun_interrupt($_REQUEST['interrupt']);
++        jsRedirect('results.php');
++    }
++    else
++        error("No permission to interrupt.");
++}
++
++if(isset($_REQUEST['rerun']))
++{
++    if(exprun_checkpermission($_REQUEST['rerun']))
++    {
++        exprun_rerun($_REQUEST['rerun']);
++        jsRedirect('results.php');
++    }
++    else
++        error("No permission to rerun.");
++}
++
++/*
++ * Display
++ */
++$resView = new CView('experiments.results');
++
++$results = exprun_getall(true);
++$resView->set('results', $results);
++
++if(isset($_REQUEST['runid']))
++{
++    if(exprun_verifyid($_REQUEST['runid']))
++    {
++        foreach($results as $r) //get the specific run that we want to 
display the log for
++        {
++            if($r['runid'] == $_REQUEST['runid'])
++            {
++                $run = $r;
++                break;
++            }
++        }
++        
++        $sep = 
"\n=================================================================\n";
++        $log = '';
++        foreach($run['nodes'] as $n)
++        {
++            if(isset($_REQUEST['hostid']) && $n['hostid'] == 
$_REQUEST['hostid']) //print the log of only a specific host
++            {
++                $log = $n['log'];
++                break;
++            }
++            else
++                $log .= $n['log'].$sep;
++        }
++        
++        $resView->set('log', $log);
++        $resView->set('runid', $run['runid']);
++    }
++}
++
++$resView->render();
++$resView->show();
++
++require_once dirname(__FILE__).'/include/page_footer.php';
+diff --git scripts_exec.php scripts_exec.php
+index d40b5a0..94775ee 100644
+--- scripts_exec.php
++++ scripts_exec.php
+@@ -27,23 +27,28 @@ $page['file'] = 'scripts_exec.php';
+ 
+ define('ZBX_PAGE_NO_MENU', 1);
+ 
+-require_once ('include/page_header.php');
++$strip = isset($_REQUEST['strip']);
++if(!$strip)
++    require_once ('include/page_header.php');
+ 
+ // VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
+ $fields = array(
+-      'hostid' =>             array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'isset({execute})'),
++      'hostid' =>             array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'!isset({groupid})&&!isset({hosts})'),
+       'scriptid' =>   array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'isset({execute})'),
++      'groupid' =>    array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,       
'!isset({hostid})&&!isset({hosts})'),
++      'hosts' =>              array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,       
'!isset({hostid})&&!isset({groupid})'),
+       'execute' =>    array(T_ZBX_INT, O_OPT, P_ACT, IN('0,1'),       null)
+ );
+ check_fields($fields);
+ 
+-if (isset($_REQUEST['execute'])) {
+-      $scriptid = get_request('scriptid');
+-      $hostid = get_request('hostid');
+-
+-      $data = array(
++function execute_script($scriptid, $hostid)
++{
++    global $strip;
++    
++    $data = array(
+               'message' => '',
+-              'info' => DBfetch(DBselect('SELECT s.name FROM scripts s WHERE 
s.scriptid='.$scriptid))
++              'info' => DBfetch(DBselect('SELECT s.name FROM scripts s WHERE 
s.scriptid='.$scriptid)),
++              'host' => DBfetch(DBselect('SELECT h.name FROM hosts h WHERE 
h.hostid='.$hostid))
+       );
+ 
+       $result = API::Script()->execute(array('hostid' => $hostid, 'scriptid' 
=> $scriptid));
+@@ -53,8 +58,10 @@ if (isset($_REQUEST['execute'])) {
+               $isErrorExist = true;
+       }
+       elseif ($result['response'] == 'failed') {
+-              error($result['value']);
+-              $isErrorExist = true;
++          if($strip) $data['error'] = $result['value'];
++              else
++                  error($result['value']);
++          $isErrorExist = true;
+       }
+       else {
+               $data['message'] = $result['value'];
+@@ -70,4 +77,46 @@ if (isset($_REQUEST['execute'])) {
+       $scriptView->show();
+ }
+ 
+-require_once 'include/page_footer.php';
++if (isset($_REQUEST['execute'])) {
++      $scriptid = get_request('scriptid');
++      
++      if(isset($_REQUEST['groupid']) || isset($_REQUEST['hosts']))
++      {
++              if(isset($_REQUEST['groupid']))
++              {
++                      $groupid = get_request('groupid');
++                      
++                      $hosts = API::Host()->get(array(
++                              'groupids' => array($groupid),
++                              'editable' => 1,
++                              'output' => API_OUTPUT_EXTEND
++                      ));
++              }
++              else
++              {
++                      $hosts = API::Host()->get(array(
++                              'hostids' => get_request('hosts'),
++                              'editable' => 1,
++                              'output' => API_OUTPUT_EXTEND
++                      ));
++              }
++              
++              $data = array();
++              $data['hosts'] = $hosts;
++              $data['scriptid'] = $scriptid;
++              $data['sid'] = get_request('sid');
++              
++              $scriptView = new CView('general.script.execute-parallel', 
$data);
++      $scriptView->render();
++      $scriptView->show();
++              
++      }
++      elseif(isset($_REQUEST['hostid']))
++      {
++          $hostid = get_request('hostid');
++      execute_script($scriptid, $hostid);
++      }
++}
++
++if(!$strip)
++    require_once 'include/page_footer.php';
+diff --git targets.php targets.php
+new file mode 100644
+index 0000000..0d5e121
+--- /dev/null
++++ targets.php
+@@ -0,0 +1,50 @@
++<?php
++
++error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('Target Configuration');
++$page['file'] = 'targets.php';
++$page['hist_arg'] = array('targetid');
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++/*
++ * Actions
++ */
++//print_r($_REQUEST);
++
++if(isset($_REQUEST['target']) && isset($_REQUEST['apply']))
++{
++    switch($_REQUEST['target'])
++    {
++        case 'ssh':
++            if(isset($_REQUEST['sshhosts']))
++                expssh_updatehosts($_REQUEST['sshhosts']);
++        
++            break;
++        
++        case 'planetlab':
++            if(isset($_REQUEST['plnodes']) && is_array($_REQUEST['plnodes']))
++                exppl_updateSliceNodes($_REQUEST['plnodes']);
++            break;
++    }
++}
++
++/*
++ * Display
++ */
++$targetsView = new CView('experiments.targets');
++
++$targetsView->set('targetlist', $exp_targetlist);
++if(isset($_REQUEST['target'])) $targetsView->set('selected_target', 
$_REQUEST['target']);
++$targetsView->set('sshhosts', expnodes_gethosts('ssh'));
++if(isset($_REQUEST['ploffset'])) $targetsView->set('ploffset', 
$_REQUEST['ploffset']);
++if(isset($_REQUEST['plfilter']) && trim($_REQUEST['plfilter']) != '') 
$targetsView->set('plfilter', $_REQUEST['plfilter']);
++
++$targetsView->render();
++$targetsView->show();
++
++require_once dirname(__FILE__).'/include/page_footer.php';
+diff --git tasklist.php tasklist.php
+new file mode 100644
+index 0000000..fa43c0d
+--- /dev/null
++++ tasklist.php
+@@ -0,0 +1,104 @@
++<?php
++
++require_once dirname(__FILE__).'/include/config.inc.php';
++require_once dirname(__FILE__).'/include/experiments/inc.php';
++
++$page['title'] = _('Tasklists');
++$page['file'] = 'tasklist.php';
++$page['hist_arg'] = array('taskid');
++
++require_once dirname(__FILE__).'/include/page_header.php';
++
++// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
++/*$fields = array(
++      'tid' =>                array(T_ZBX_INT, O_OPT, P_SYS, null, null),
++);
++check_fields($fields);*/
++
++
++/*
++ * Actions
++ */
++if(isset($_REQUEST['tid']) && isset($_REQUEST['update']))
++{
++    $tid = intval($_REQUEST['tid']);
++    if(exptasklist_allowed($tid) == 2) //check user permission (read/write)
++        exptasklist_update($tid, $_REQUEST);
++    else
++        error("Permission denied!");
++}
++if(isset($_REQUEST['add']))
++{
++    if(exptasklist_add($_REQUEST))
++        jsRedirect('tasklist.php');
++}
++if(isset($_REQUEST['delete']))
++{
++    $tid = intval(substr($_REQUEST['delete'], 1));
++    
++    if(exptasklist_allowed($tid) == 2)
++    {
++        if(exptasklist_delete($tid))
++            jsRedirect('tasklist.php');
++    }
++    else
++        error("Permission denied!");
++}
++
++
++/*
++ * Display
++ */
++if(isset($_REQUEST['tid']))
++{
++    $tid = intval($_REQUEST['tid']);
++    if(exptasklist_allowed($tid) > 0) //check user permission (read or 
read/write)
++    {
++        //Get tasklist metadata
++        $meta = exptasklist_getbyid($tid);
++        //Get tasklist XML content
++        $xml = exptasklist_getcontent($tid);
++        if($xml)
++        {
++            $tlView = new CView('experiments.tasklist.edit');
++
++            $tlView->set('tid', $tid);
++            $tlView->set('xml', simplexml_load_string($xml));
++            //$tlView->set('targets', exp_gettargets());
++            $tlView->set('meta', $meta);
++            $tlView->set('exptasklist_defaults', $exptasklist_defaults);
++            $tlView->set('userfiles', expfiles_getuserfiles());
++
++            $tlView->render();
++            $tlView->show();
++
++        }
++        else
++            error("Error while loading tasklist!");
++    }
++    else
++        error("Permission denied!");
++}
++elseif(isset($_REQUEST['new']))
++{
++    $tlView = new CView('experiments.tasklist.edit');
++    
++    $tlView->set('new', true);
++    //$tlView->set('targets', exp_gettargets());
++    $tlView->set('exptasklist_defaults', $exptasklist_defaults);
++    $tlView->set('userfiles', expfiles_getuserfiles());
++    
++    $tlView->render();
++    $tlView->show();
++}
++else
++{
++    $tlView = new CView('experiments.tasklist');
++    
++    $tlView->set('tasklists', exptasklist_getall(true));
++    
++    $tlView->render();
++    $tlView->show();
++}
++
++require_once dirname(__FILE__).'/include/page_footer.php';

Added: eclectic/gplmt-ui/schema.sql
===================================================================
--- eclectic/gplmt-ui/schema.sql                                (rev 0)
+++ eclectic/gplmt-ui/schema.sql        2014-04-22 16:03:10 UTC (rev 33122)
@@ -0,0 +1,139 @@
+-- phpMyAdmin SQL Dump
+-- version 3.4.11.1deb2
+-- http://www.phpmyadmin.net
+--
+-- Host: localhost
+-- Generation Time: Sep 26, 2013 at 04:39 PM
+-- Server version: 5.5.31
+-- PHP Version: 5.4.4-14+deb7u4
+
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+--
+-- Database: `zabbix`
+--
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_config`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_config` (
+  `configid` int(11) NOT NULL AUTO_INCREMENT,
+  `section` varchar(100) COLLATE utf8_bin NOT NULL,
+  `name` varchar(200) COLLATE utf8_bin NOT NULL,
+  `label` varchar(100) COLLATE utf8_bin NOT NULL,
+  `description` text COLLATE utf8_bin,
+  `type` varchar(100) COLLATE utf8_bin NOT NULL,
+  `default_value` varchar(500) COLLATE utf8_bin NOT NULL,
+  `user_editable` tinyint(1) NOT NULL,
+  PRIMARY KEY (`configid`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=29 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_configenum`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_configenum` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `configid` int(11) NOT NULL,
+  `label` text COLLATE utf8_bin NOT NULL,
+  `value` text COLLATE utf8_bin NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_host`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_host` (
+  `hostid` int(11) NOT NULL AUTO_INCREMENT,
+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
+  `userid` int(11) NOT NULL,
+  `host` text COLLATE utf8_bin NOT NULL,
+  `pl_nodeid` int(11) DEFAULT NULL,
+  PRIMARY KEY (`hostid`,`target`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1580 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_run`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_run` (
+  `runid` int(11) NOT NULL AUTO_INCREMENT,
+  `startedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `usetasklist` tinyint(1) NOT NULL DEFAULT '1',
+  `tasklistid` int(11) DEFAULT NULL,
+  `command` varchar(200) COLLATE utf8_bin DEFAULT NULL,
+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
+  `pid` int(11) DEFAULT NULL,
+  `userid` int(11) NOT NULL,
+  `status` int(11) NOT NULL DEFAULT '0',
+  `percentage` double NOT NULL DEFAULT '0',
+  `fullcommand` text COLLATE utf8_bin,
+  PRIMARY KEY (`runid`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=75 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_runnode`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_runnode` (
+  `runid` int(11) NOT NULL,
+  `hostid` int(11) NOT NULL,
+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
+  `status` int(11) NOT NULL DEFAULT '0',
+  `percentage` double NOT NULL DEFAULT '0',
+  `log` text COLLATE utf8_bin NOT NULL,
+  PRIMARY KEY (`runid`,`hostid`,`target`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_tasklist`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_tasklist` (
+  `tasklistid` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(100) COLLATE utf8_bin NOT NULL,
+  `description` text COLLATE utf8_bin,
+  `fsname` varchar(100) COLLATE utf8_bin NOT NULL,
+  `userid` int(11) NOT NULL,
+  `shared` tinyint(1) NOT NULL,
+  PRIMARY KEY (`tasklistid`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=24 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `exp_userconfig`
+--
+
+CREATE TABLE IF NOT EXISTS `exp_userconfig` (
+  `configid` int(11) NOT NULL,
+  `userid` int(11) NOT NULL,
+  `value` varchar(500) COLLATE utf8_bin NOT NULL,
+  `enabled` tinyint(1) NOT NULL,
+  PRIMARY KEY (`configid`,`userid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET address@hidden */;
+/*!40101 SET address@hidden */;
+/*!40101 SET address@hidden */;

Deleted: eclectic/gplmt-ui/zabbix.diff
===================================================================
--- eclectic/gplmt-ui/zabbix.diff       2014-04-22 11:29:18 UTC (rev 33121)
+++ eclectic/gplmt-ui/zabbix.diff       2014-04-22 16:03:10 UTC (rev 33122)
@@ -1,3212 +0,0 @@
-diff --git a/zabbix/data.sql b/zabbix/data.sql
-new file mode 100644
-index 0000000..c2b36b6
---- /dev/null
-+++ b/zabbix/data.sql
-@@ -0,0 +1,54 @@
-+-- phpMyAdmin SQL Dump
-+-- version 3.4.11.1deb2
-+-- http://www.phpmyadmin.net
-+--
-+-- Host: localhost
-+-- Generation Time: Sep 26, 2013 at 04:40 PM
-+-- Server version: 5.5.31
-+-- PHP Version: 5.4.4-14+deb7u4
-+
-+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-+SET time_zone = "+00:00";
-+
-+
-+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-+/*!40101 SET NAMES utf8 */;
-+
-+--
-+-- Database: `zabbix`
-+--
-+
-+--
-+-- Dumping data for table `exp_config`
-+--
-+
-+INSERT INTO `exp_config` (`configid`, `section`, `name`, `label`, 
`description`, `type`, `default_value`, `user_editable`) VALUES
-+(1, 'ssh', 'ssh_username', 'SSH username', 'Username for SSH access', 'text', 
'', 1),
-+(2, 'ssh', 'ssh_password', 'SSH password', 'Password for SSH access or 
password for the SSH keyfile', 'password', '', 1),
-+(3, 'ssh', 'ssh_keyfile', 'SSH keyfile', 'SSH key for login', 'file', '', 1),
-+(16, 'gplmt', 'notification', 'Notification', 'Which notification mechanism 
to use: simple, result', 'text', 'result', 0),
-+(17, 'gplmt', 'max_parallelism', 'Max Parallelism', 'Number of parallel 
workers, use 0 for unlimited', 'integer', '10', 0),
-+(18, 'planetlab', 'slice', 'Planetlab Slice', 'Name of your PlanetLab Slice', 
'text', '', 1),
-+(20, 'planetlab', 'api_url', 'PLC/PLE', 'Use PlanetLab Central or PlanetLab 
Europe', 'enum', 'https://www.planet-lab.eu/PLCAPI/', 1),
-+(21, 'planetlab', 'username', 'PlanetLab API username', 'Your login to the 
planetlab website\r\nto access the planetlab API', 'text', '', 1),
-+(22, 'planetlab', 'password', 'PlanetLab API password', 'Your password for 
the planetlab\r\nwebsite to access the planetlab API', 'password', '', 1),
-+(25, 'ssh', 'ssh_transfer', 'SSH Transfer', 'Protocol for put get operations: 
scp, sftp', 'text', 'scp', 0),
-+(26, 'ssh', 'ssh_use_known_hosts', 'SSH: Use Known Hosts', 'Use system''s SSH 
"known hosts" file', 'boolean', 'yes', 0),
-+(27, 'ssh', 'add_unkown_hostkeys', 'SSH: Add Unknown Hostkeys', 'Add node 
hostkeys automatically', 'boolean', 'yes', 0),
-+(28, 'gplmt', 'userdir', 'User Directory', 'User specific directory for 
put/get operations', 'text', '', 0);
-+
-+INSERT INTO `zabbix`.`exp_config` (`configid`, `section`, `name`, `label`, 
`description`, `type`, `default_value`, `user_editable`) VALUES (NULL, 
'planetlab', 'pl_keyfile', 'Planetlab keyfile', 'Private key file for 
connecting to planetlab nodes', 'file', '', '1'), (NULL, 'planetlab', 
'pl_keyfile_password', 'Planetlab keyfile password', 'Password used to unlock 
private key file (if needed)', 'password', '', '1');
-+
-+--
-+-- Dumping data for table `exp_configenum`
-+--
-+
-+INSERT INTO `exp_configenum` (`id`, `configid`, `label`, `value`) VALUES
-+(1, 20, 'Planetlab Central', 'https://www.planet-lab.org/PLCAPI/'),
-+(2, 20, 'Planetlab Europe', 'https://www.planet-lab.eu/PLCAPI/');
-+
-+/*!40101 SET address@hidden */;
-+/*!40101 SET address@hidden */;
-+/*!40101 SET address@hidden */;
-diff --git a/zabbix/frontends/php/conf.php b/zabbix/frontends/php/conf.php
-new file mode 100644
-index 0000000..c88d8a6
---- /dev/null
-+++ b/zabbix/frontends/php/conf.php
-@@ -0,0 +1,31 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('User Configuration');
-+$page['file'] = 'conf.php';
-+$page['hist_arg'] = array('confid');
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+/*
-+ * Actions
-+ */
-+if(isset($_REQUEST['update']))
-+{
-+    //print_r($_REQUEST);
-+    expconfig_update($_REQUEST);
-+}
-+
-+/*
-+ * Display
-+ */
-+$filesView = new CView('experiments.conf');
-+
-+$filesView->set('conf', expconfig_getuserconfig());
-+
-+$filesView->render();
-+$filesView->show();
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/frontends/php/dashboard.php 
b/zabbix/frontends/php/dashboard.php
-index fe17a67..e71abb8 100644
---- a/zabbix/frontends/php/dashboard.php
-+++ b/zabbix/frontends/php/dashboard.php
-@@ -253,6 +253,11 @@ insert_js('var page_menu='.zbx_jsvalue($menu).";\n".'var 
page_submenu='.zbx_jsva
-  */
- $leftColumn = array();
- 
-+// Manage monitoring
-+$manage_wdgt = new CUIWidget('hat_managemonitoring', 
make_manage_monitoring(), 1);
-+$manage_wdgt->setHeader(_('Manage Monitoring'));
-+$leftColumn[] = $manage_wdgt;
-+
- // favorite graphs
- $graph_menu = get_icon('menu', array('menu' => 'graphs'));
- $fav_grph = new CUIWidget('hat_favgrph', make_favorite_graphs(), 
CProfile::get('web.dashboard.hats.hat_favgrph.state', 1));
-@@ -297,6 +302,12 @@ if ($USER_DETAILS['type'] == USER_TYPE_SUPER_ADMIN) {
-       $rightColumn[] = $zbxStatus;
- }
- 
-+// run scripts
-+$scripts_wdgt = new CUIWidget('hat_runscripts', make_run_scripts(), 1);
-+$scripts_wdgt->setHeader(_('Run Scripts'));
-+//$scripts_wdgt->setFooter(new CLink(_('Graphs').' &raquo;', 'charts.php', 
'highlight'), true);
-+$rightColumn[] = $scripts_wdgt;
-+
- // system status
- $refresh_menu = new CIcon(_('Menu'), 'iconmenu', 
'create_page_menu(event,"hat_syssum");');
- $sys_stat = new CUIWidget('hat_syssum', new CSpan(_('Loading...'), 
'textcolorstyles'), CProfile::get('web.dashboard.hats.hat_syssum.state', 1));
-diff --git a/zabbix/frontends/php/execute.php 
b/zabbix/frontends/php/execute.php
-new file mode 100644
-index 0000000..0428d3e
---- /dev/null
-+++ b/zabbix/frontends/php/execute.php
-@@ -0,0 +1,69 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('Deploy & Execute');
-+$page['file'] = 'execute.php';
-+$page['hist_arg'] = array('execid');
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
-+/*$fields = array(
-+      'run' =>                array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 
null),
-+      'nodes' =>              array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 
'isset({run})'),
-+      'usetasklist' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, IN('0,1'), 
'isset({run})'),
-+      'tasklist' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, 
'isset({run})'),
-+      'cmd' =>   array(T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, 'isset({run})'),
-+      'sync' =>   array(T_ZBX_INT, O_OPT, null, null, null)
-+);
-+check_fields($fields);*/
-+
-+
-+/*
-+ * Actions
-+ */
-+
-+if(isset($_REQUEST['run']))
-+{
-+    $usetasklist = intval($_REQUEST['usetasklist']);
-+    $tasklist = intval($_REQUEST['tasklist']);
-+
-+    $cmd = trim($_REQUEST['cmd']);
-+    $cmd_empty = empty($cmd);
-+    
-+    if($usetasklist == 0 && $cmd_empty)
-+        error("Please specify the command to run.");
-+    elseif(!isset($_REQUEST['target']))
-+        error("Please specify target.");
-+    elseif(!isset($_REQUEST['hosts']) || count($_REQUEST['hosts']) == 0)
-+        error("Please specify hosts to run");
-+    else
-+    {
-+        $res = exprun_new($_REQUEST['target'], $_REQUEST['hosts'], 
$usetasklist, $tasklist, $cmd);
-+        if($res == EXP_ERR_GPLMT_DIR)
-+            error("Could not verify GPLMT files, please make sure that they 
exist and write permissions are enabled.");
-+        elseif($res == EXP_ERR_PERMISSION)
-+            error("Permission error.");
-+        elseif($res == EXP_ERR_INVALID_TARGET)
-+            error("Invalid target!");
-+        else
-+            jsRedirect('results.php');
-+    }
-+}
-+
-+/*
-+ * Display
-+ */
-+
-+$execView = new CView('experiments.execute');
-+
-+$execView->set('tasklists', exptasklist_getall());
-+$execView->set('targets', $exp_targetlist);
-+$execView->set('currenttarget', 
isset($_REQUEST['target'])?$_REQUEST['target']:reset($exp_targetlist));
-+
-+$execView->render();
-+$execView->show();
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/frontends/php/files.php b/zabbix/frontends/php/files.php
-new file mode 100644
-index 0000000..5326ccc
---- /dev/null
-+++ b/zabbix/frontends/php/files.php
-@@ -0,0 +1,58 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('User Files');
-+$page['file'] = 'files.php';
-+$page['hist_arg'] = array('fileid');
-+
-+//before any headers are written, check if trying to download
-+if(isset($_REQUEST['download']))
-+{
-+    $filename = $_REQUEST['download'];
-+    
-+    expfiles_download($filename);
-+}
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
-+/*$fields = array(
-+);
-+check_fields($fields);*/
-+
-+/*
-+ * Actions
-+ */
-+if(isset($_REQUEST['upload']) && isset($_FILES['file']))
-+{
-+    //some validations
-+    if($_FILES["file"]["error"] > 0)
-+        error('File upload error: '.$_FILES["file"]["error"]);
-+    else
-+    {
-+        $filename = $_FILES["file"]["name"];
-+        $fullpath = expfiles_getnewfilepath($filename);
-+        move_uploaded_file($_FILES["file"]["tmp_name"], $fullpath);
-+        
-+        info("File uploaded successfully.");
-+    }
-+}
-+if(isset($_REQUEST['delete']))
-+{
-+    if(expfiles_delete($_REQUEST['delete'])) jsRedirect('files.php');
-+}
-+
-+/*
-+ * Display
-+ */
-+$filesView = new CView('experiments.files');
-+
-+$filesView->set('files', expfiles_getuserfiles());
-+
-+$filesView->render();
-+$filesView->show();
-+
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/frontends/php/images/general/question_mark.png 
b/zabbix/frontends/php/images/general/question_mark.png
-new file mode 100644
-index 0000000..8dee9d0
-Binary files /dev/null and 
b/zabbix/frontends/php/images/general/question_mark.png differ
-diff --git a/zabbix/frontends/php/include/blocks.inc.php 
b/zabbix/frontends/php/include/blocks.inc.php
-index 3896140..7b1321a 100644
---- a/zabbix/frontends/php/include/blocks.inc.php
-+++ b/zabbix/frontends/php/include/blocks.inc.php
-@@ -1401,3 +1401,174 @@ function makeTriggersPopup(array $triggers, array 
$ackParams) {
- 
-       return $popupTable;
- }
-+
-+function make_run_scripts()
-+{
-+      //create big table
-+      $bigTable = new CTableInfo();
-+      
-+    //create table 1
-+    $scriptsTable = new CTableInfo(_('No scripts defined.'));
-+    $scriptsTable->setHeader(array(
-+          _('Name'),
-+          _('Run on Host'),
-+          _('Run on Host Group')
-+    ));
-+    
-+    //get list of scripts
-+    $scripts = API::Script()->get(array(
-+              'output' => array('name')
-+      ));
-+      
-+      //get list of hosts
-+      $hosts = API::Host()->get(array(
-+              'sortfield' => 'name',
-+              'output' => array('name')
-+      ));
-+      
-+      //get list of host groups
-+    $hostgroups = API::HostGroup()->get(array(
-+              'sortfield' => 'name',
-+              'output' => array('name')
-+      ));
-+      
-+      //add rows
-+      foreach($scripts as $script)
-+      {
-+          //create hostgroups combobox & run button
-+        $runForm = new CForm('GET', 'scripts_exec.php');
-+        $runForm->attr("target", "_blank");
-+        $runForm->addItem(new CInput('hidden', 'execute', '1'));
-+        $runForm->addItem(new CInput('hidden', 'scriptid', 
$script['scriptid']));
-+        
-+        $grpsComboBox = new CComboBox('groupid');
-+        foreach($hostgroups as $hostgroup)
-+            $grpsComboBox->addItem(new CComboItem($hostgroup['groupid'], 
$hostgroup['name']));
-+
-+        $runForm->addItem($grpsComboBox);
-+        $runForm->addItem(new CInput('submit', 'submit', 'Run'));
-+        
-+        //create hosts combobox & run button
-+        $runFormHosts = new CForm('GET', 'scripts_exec.php');
-+        $runFormHosts->attr("target", "_blank");
-+        $runFormHosts->addItem(new CInput('hidden', 'execute', '1'));
-+        $runFormHosts->addItem(new CInput('hidden', 'scriptid', 
$script['scriptid']));
-+        
-+        $hostsComboBox = new CComboBox('hostid');
-+        foreach($hosts as $host)
-+            $hostsComboBox->addItem(new CComboItem($host['hostid'], 
$host['name']));
-+
-+        $runFormHosts->addItem($hostsComboBox);
-+        $runFormHosts->addItem(new CInput('submit', 'submit', 'Run'));
-+        
-+        $scriptsTable->addRow(array(
-+                  new CLink($script['name'], 
'scripts.php?form=1&scriptid='.$script['scriptid']),
-+                  $runFormHosts,
-+                  $runForm
-+          ));
-+      }
-+      
-+      //create multiple run form
-+      $multForm = new CFormTable(null, 'scripts_exec.php', 'GET');
-+      
-+      $scriptsCmbbox = new CComboBox('scriptid');
-+      foreach($scripts as $script)
-+              $scriptsCmbbox->addItem(new CComboItem($script['scriptid'], 
$script['name']));
-+      
-+      $hostsListBox = new CListBox('hosts[]', null, 15);
-+      foreach($hosts as $host)
-+        $hostsListBox->addItem(new CComboItem($host['hostid'], 
$host['name']));
-+    
-+    $multForm->addRow($scriptsCmbbox);
-+    $multForm->addRow($hostsListBox);
-+    $multForm->attr("target", "_blank");
-+    $multForm->addRow(new CInput('hidden', 'execute', '1'), new 
CInput('submit', 'submit', 'Run'));
-+    
-+    $bigTable->addRow(array(
-+      $scriptsTable,
-+      $multForm
-+    ));
-+    
-+    return $bigTable;
-+}
-+
-+function template_items_status($template_id)
-+{
-+      //fetch main template    
-+    $options = array(
-+              'templateids' => array($template_id),
-+              'selectItems' => array('status'),
-+              'output' => array('name')
-+      );
-+
-+      $template = API::Template()->get($options);
-+      
-+      $total = 0;
-+      $enabled = 0;
-+      
-+      foreach($template[0]['items'] as $item)
-+      {
-+              $total++;
-+              if($item['status'] == 0) $enabled++;
-+      }
-+      
-+      return array('total' => $total, 'enabled' => $enabled);
-+}
-+
-+function make_manage_monitoring()
-+{
-+    $templates = array(10001, 10176, 10177);
-+    
-+    //fetch important templates
-+    $options = array(
-+              'templateids' => $templates,
-+              'output' => array('name')
-+      );
-+      $templates = API::Template()->get($options);
-+      
-+      //create link/unlink all forms
-+      $linkAllForm = new CForm('POST', 'manage_monitoring.php');
-+      $unlinkAllForm = new CForm('POST', 'manage_monitoring.php');
-+      foreach($templates as $temp)
-+      {
-+              $linkAllForm->addItem(new CInput('hidden', 
'template['.$temp['hostid'].']', $temp['hostid']));
-+              $unlinkAllForm->addItem(new CInput('hidden', 
'template['.$temp['hostid'].']', $temp['hostid']));
-+      }
-+      $linkAllForm->addItem(new CInput('submit', 'submit', 'Enable All'));
-+    $linkAllForm->addItem(new CInput('hidden', 'action', 'enable'));
-+
-+      $unlinkAllForm->addItem(new CInput('submit', 'submit', 'Disable All'));
-+    $unlinkAllForm->addItem(new CInput('hidden', 'action', 'disable'));
-+      
-+      //table that will contain forms
-+      $table = new CTable();
-+      
-+      foreach($templates as $template)
-+      {
-+              $items_status = template_items_status($template['hostid']);
-+              
-+          $r = new CRow();
-+          $r->addItem(new CLabel($template['name'] . ' [' . 
$items_status['enabled'] . '/' . $items_status['total'] . ']'));
-+          
-+          $enableForm = new CForm('POST', 'manage_monitoring.php');
-+          $enableForm->addItem(new CInput('hidden', 
'template['.$template['hostid'].']', $template['hostid']));
-+          $enableForm->addItem(new CInput('submit', 'submit', 'Disable'));
-+        $enableForm->addItem(new CInput('hidden', 'action', 'disable'));
-+          
-+          $disableForm = new CForm('POST', 'manage_monitoring.php');
-+        $disableForm->addItem(new CInput('hidden', 
'template['.$template['hostid'].']', $template['hostid']));
-+      $disableForm->addItem(new CInput('submit', 'submit', 'Enable'));
-+      $disableForm->addItem(new CInput('hidden', 'action', 'enable'));
-+
-+          $r->addItem($enableForm);        
-+          $r->addItem($disableForm);
-+          
-+          $table->addRow($r);
-+      }
-+      $totalRows = new CRow();
-+      $totalRows->addItem($linkAllForm);
-+      $totalRows->addItem($unlinkAllForm);
-+      $table->addRow($totalRows);
-+      
-+      return $table;
-+}
-diff --git a/zabbix/frontends/php/include/experiments/conf.php 
b/zabbix/frontends/php/include/experiments/conf.php
-new file mode 100644
-index 0000000..9bef025
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/conf.php
-@@ -0,0 +1,9 @@
-+<?php
-+
-+$GLOBALS['GPLMT_DIR'] = '/home/omar/workspace/gnunet-planetlab/gplmt/';
-+
-+$GLOBALS['GPLMT_TASKLISTS_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/tasklists/';
-+$GLOBALS['GPLMT_CONF_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/configurations/';
-+$GLOBALS['GPLMT_NODES_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/nodes/';
-+$GLOBALS['GPLMT_RESULTS_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/results/';
-+$GLOBALS['GPLMT_FILES_DIR'] = $GLOBALS['GPLMT_DIR'].'contrib/files/';
-diff --git a/zabbix/frontends/php/include/experiments/config.php 
b/zabbix/frontends/php/include/experiments/config.php
-new file mode 100644
-index 0000000..1e4ed5a
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/config.php
-@@ -0,0 +1,106 @@
-+<?php
-+
-+function expconfig_update($data)
-+{
-+    //get user editable config
-+    $editable = expconfig_getuserconfig();
-+    
-+    foreach($data as $k => $v)
-+    {
-+        if(!isset($editable[$k])) continue;
-+        $v = trim($v);
-+        $enabled = ($v != '');
-+        
-+        if(($editable[$k]['type'] == 'file') && $enabled)
-+            $v = expfiles_getuserdir().exp_cleanfilename($v);
-+        
-+        expdb_update('exp_userconfig',
-+            array('value' => $v, 'enabled' => strval($enabled)),
-+            array('configid' => $k, 'userid' => CWebUser::$data['userid']));
-+    }
-+    
-+    expconfig_writefile();
-+}
-+
-+function expconfig_getconfigbyname($configname)
-+{
-+    $uid = CWebUser::$data['userid'];
-+    $sql = "SELECT exp_userconfig.value, exp_userconfig.enabled
-+        FROM exp_config, exp_userconfig
-+        WHERE exp_config.configid = exp_userconfig.configid
-+        AND exp_config.name = '$configname'
-+        AND exp_userconfig.userid = $uid";
-+    $result = DBfetchArray(DBselect($sql));
-+    if(count($result) == 0) return null;
-+    if(!$result[0]['enabled']) return null;
-+    return $result[0]['value'];
-+}
-+
-+function expconfig_getuserconfig($editableOnly = true)
-+{
-+    $uid = CWebUser::$data['userid'];
-+    $sql = "SELECT u.configid, c.section, c.name, c.label, c.description, 
c.type, u.value
-+            FROM exp_config c, exp_userconfig u
-+            WHERE c.configid = u.configid
-+            AND c.user_editable = 1
-+            AND u.userid = $uid
-+            ORDER BY c.section, c.configid";
-+    return DBfetchArrayAssoc(DBselect($sql), 'configid');
-+}
-+
-+function expconfig_getenum($configid)
-+{
-+    return expdb_select('exp_configenum', array('configid' => $configid));
-+}
-+
-+function expconfig_writefile()
-+{
-+    $uid = CWebUser::$data['userid'];
-+    $sql = "SELECT c.section, c.name, u.value
-+            FROM exp_config c, exp_userconfig u
-+            WHERE c.configid = u.configid
-+            AND u.enabled = 1
-+            AND u.userid = $uid
-+            ORDER BY c.section";
-+    $conf = DBfetchArray(DBselect($sql));
-+    
-+    $filename = $GLOBALS['GPLMT_CONF_DIR'].strval($uid);
-+    $f = fopen($filename, 'w+');
-+    $current_sec = '';
-+    
-+    foreach($conf as $c)
-+    {
-+        if($c['section'] != $current_sec)
-+        {
-+            $current_sec = $c['section'];
-+            fwrite($f, "[$current_sec]\n");
-+        }
-+        $k = $c['name'];
-+        $v = $c['value'];
-+        fwrite($f, "$k = $v\n");
-+    }
-+    fclose($f);
-+}
-+
-+function expconfig_verifyuserconfig()
-+{
-+    $uid = CWebUser::$data['userid'];
-+    $default_config = expdb_select('exp_config', array(), 'configid');
-+    $user_config = expdb_select('exp_userconfig', array('userid' => $uid), 
'configid');
-+    
-+    if(count($default_config) == count($user_config)) return;
-+    
-+    foreach($default_config as $dc_k => $dc)
-+    {
-+        if(isset($user_config[$dc_k])) continue;
-+        
-+        $newval = $dc['default_value'];
-+        if($dc['name'] == 'userdir') //special cases, user specific
-+            $newval = expfiles_getuserdir();
-+        $enabled = strval(($newval != ''));
-+        
-+        expdb_insert('exp_userconfig',
-+            array('configid' => $dc_k, 'userid' => $uid, 'value' => $newval, 
'enabled' => $enabled));
-+    }
-+    expconfig_writefile();
-+}
-diff --git a/zabbix/frontends/php/include/experiments/db.php 
b/zabbix/frontends/php/include/experiments/db.php
-new file mode 100644
-index 0000000..14f1b7c
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/db.php
-@@ -0,0 +1,85 @@
-+<?php
-+
-+function expdb_genwhere($where)
-+{
-+    if(sizeof($where) == 0) return '';
-+    
-+    $where_str = ' WHERE ';
-+    
-+    $first = true;
-+    foreach($where as $k => $v)
-+    {
-+        if(!$first) $where_str .= ' AND ';
-+        else $first = false;
-+        $where_str .= $k.'=';
-+        if(is_string($v))
-+            $where_str .= ("'".mysql_real_escape_string(trim($v))."'");
-+        else
-+            $where_str .= $v;
-+    }
-+    
-+    return $where_str;
-+}
-+
-+function expdb_insert($table, $data)
-+{
-+    $keys_str = implode(',', array_keys($data));
-+    
-+    $vals = array();
-+    foreach($data as $v)
-+    {
-+        if(is_string($v)) $vals[] = 
"'".mysql_real_escape_string(trim($v))."'";
-+        else $vals[] = $v;
-+    }
-+    
-+    $vals_str = implode(',', $vals);
-+    
-+    $sql = "INSERT INTO $table ($keys_str) VALUES ($vals_str)";
-+    
-+    DBexecute($sql);
-+    return mysql_insert_id(); #TODO: mysql specific, need to be changed to be 
generic
-+}
-+
-+function expdb_update($table, $data, $where)
-+{
-+    $set_str = '';
-+    $first = true;
-+    foreach($data as $k => $v)
-+    {
-+        if(!$first) $set_str .= ',';
-+        else $first = false;
-+        $set_str .= $k.'=';
-+        if(is_string($v))
-+            $set_str .= ("'".mysql_real_escape_string(trim($v))."'");
-+        else
-+            $set_str .= $v;
-+    }
-+    
-+    $where_str = expdb_genwhere($where);
-+    
-+    $sql = "UPDATE $table SET $set_str $where_str";
-+    
-+    return DBexecute($sql);
-+}
-+
-+
-+function expdb_select($table, $where, $assocField = null)
-+{
-+    $where_str = expdb_genwhere($where);
-+    
-+    $sql = "SELECT * FROM $table $where_str";
-+    
-+    if($assocField)
-+        return DBfetchArrayAssoc(DBselect($sql), $assocField);
-+    else
-+        return DBfetchArray(DBselect($sql));
-+}
-+
-+function expdb_delete($table, $where)
-+{
-+    $where_str = expdb_genwhere($where);
-+    
-+    $sql = "DELETE FROM $table $where_str";
-+    
-+    return DBexecute($sql);
-+}
-diff --git a/zabbix/frontends/php/include/experiments/files.php 
b/zabbix/frontends/php/include/experiments/files.php
-new file mode 100644
-index 0000000..a2f5fe8
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/files.php
-@@ -0,0 +1,82 @@
-+<?php
-+
-+/*
-+ * Get the full path for the directory containing the user personal file
-+ */
-+function expfiles_getuserdir()
-+{
-+    $uid = CWebUser::$data['userid'];
-+    $dir = $GLOBALS['GPLMT_FILES_DIR'].strval($uid).'/';
-+    if(!file_exists($dir)) mkdir($dir);
-+    return $dir;
-+}
-+
-+/*
-+ * Returns an array with the names of files inside the user personal directory
-+ */
-+function expfiles_getuserfiles()
-+{
-+    $dirpath = expfiles_getuserdir();
-+    
-+    $res = scandir($dirpath);
-+    $res = array_diff($res, array('.', '..'));
-+    return $res;
-+}
-+
-+/*
-+ * Given a file name for a new file to be uploaded, returns a full path 
-+ * with the same or modified filename if already exists
-+ */
-+function expfiles_getnewfilepath($filename = 'new')
-+{
-+    $filename = exp_cleanfilename($filename);
-+    $dirpath = expfiles_getuserdir();
-+    
-+    $parts = explode('.', $filename);
-+    $orig = $parts[0];
-+    
-+    $counter = 0;
-+    while(file_exists($dirpath.implode('.', $parts)))
-+    {
-+        $parts[0] = $orig.strval($counter);
-+        $counter++;
-+    }
-+    
-+    return $dirpath.implode('.', $parts);
-+}
-+
-+function expfiles_delete($filename)
-+{
-+    $filename = exp_cleanfilename($filename);
-+    $fullpath = expfiles_getuserdir().$filename;
-+    if(file_exists($fullpath)) unlink($fullpath);
-+    return true;
-+}
-+
-+function expfiles_download($filename)
-+{
-+    $filename = exp_cleanfilename($filename);
-+    $fullpath = expfiles_getuserdir().$filename;
-+    if(!file_exists($fullpath))
-+    {
-+        error("File doesn't exist");
-+        return false;
-+    }
-+    
-+    $size = filesize($fullpath);
-+    $mime_type="application/force-download";
-+    
-+    //@ob_end_clean();
-+    
-+    header('Content-Type: ' . $mime_type);
-+    header('Content-Disposition: attachment; filename="'.$filename.'"');
-+    header("Content-Transfer-Encoding: binary");
-+    header('Accept-Ranges: bytes');
-+    header("Cache-control: private");
-+    header('Pragma: private');
-+    header('Content-Length: ' . $size);
-+    ob_clean();
-+    flush();
-+    readfile($fullpath); 
-+    exit;
-+}
-diff --git a/zabbix/frontends/php/include/experiments/inc.php 
b/zabbix/frontends/php/include/experiments/inc.php
-new file mode 100644
-index 0000000..0823b39
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/inc.php
-@@ -0,0 +1,50 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/conf.php';
-+require_once dirname(__FILE__).'/db.php';
-+require_once dirname(__FILE__).'/tasklist.php';
-+require_once dirname(__FILE__).'/run.php';
-+require_once dirname(__FILE__).'/files.php';
-+require_once dirname(__FILE__).'/config.php';
-+require_once dirname(__FILE__).'/nodes.php';
-+require_once dirname(__FILE__).'/targets.php';
-+
-+define('EXP_OK', '0');
-+define('EXP_ERR_GPLMT_DIR', '1');
-+define('EXP_ERR_PERMISSION', '2');
-+define('EXP_ERR_INVALID_TARGET', '3');
-+
-+
-+function exp_cleanfilename($filename)
-+{
-+    return preg_replace("/[^a-z0-9\.]/", "", strtolower($filename));
-+}
-+
-+
-+function exp_gettargets()
-+{
-+    $cmd = 'python '.$GLOBALS['GPLMT_DIR'].'gplmt/Targets.py';
-+    $res = array();
-+    exec($cmd, $res);
-+    return $res;
-+}
-+
-+function exp_verifygplmtdir()
-+{
-+    if(!file_exists($GLOBALS['GPLMT_DIR'].'gplmt.py'))
-+    {
-+        error('GPLMT path invalid!');
-+        return false;
-+    }
-+    
-+    if(!file_exists($GLOBALS['GPLMT_TASKLISTS_DIR'])) 
mkdir($GLOBALS['GPLMT_TASKLISTS_DIR']);
-+    if(!file_exists($GLOBALS['GPLMT_CONF_DIR'])) 
mkdir($GLOBALS['GPLMT_CONF_DIR']);
-+    if(!file_exists($GLOBALS['GPLMT_NODES_DIR'])) 
mkdir($GLOBALS['GPLMT_NODES_DIR']);
-+    if(!file_exists($GLOBALS['GPLMT_RESULTS_DIR'])) 
mkdir($GLOBALS['GPLMT_RESULTS_DIR']);
-+    if(!file_exists($GLOBALS['GPLMT_FILES_DIR'])) 
mkdir($GLOBALS['GPLMT_FILES_DIR']);
-+    
-+    return true;
-+}
-+
-+exp_verifygplmtdir();
-+expconfig_verifyuserconfig();
-diff --git a/zabbix/frontends/php/include/experiments/nodes.php 
b/zabbix/frontends/php/include/experiments/nodes.php
-new file mode 100644
-index 0000000..08a4f22
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/nodes.php
-@@ -0,0 +1,88 @@
-+<?php
-+
-+function expnodes_getbyrunid($run_id)
-+{
-+    $run_id = mysql_real_escape_string($run_id);
-+    
-+    $sql = "SELECT exp_host.hostid, exp_host.host
-+            FROM exp_runnode, exp_host
-+            WHERE exp_runnode.hostid = exp_host.hostid
-+            AND exp_runnode.runid = $run_id";
-+    
-+    return DBfetchArray(DBselect($sql));
-+}
-+
-+function expnodes_writefile($nodes, $run_id)
-+{
-+    $nodes_file = $GLOBALS['GPLMT_NODES_DIR'].$run_id;
-+    
-+    $f = fopen($nodes_file, 'w+');
-+    foreach($nodes as $n) fwrite($f, "$n\n");
-+    fclose($f);
-+}
-+
-+function expnodes_gethosts($target)
-+{
-+    $userid = CWebUser::$data['userid'];
-+    return expdb_select('exp_host', array('userid' => $userid, 'target' => 
$target));
-+}
-+
-+function expnodes_gethostbyid($hostid)
-+{
-+    $res = expdb_select('exp_host', array('hostid' => $hostid));
-+    if(count($res) == 0) return null;
-+    return $res[0];
-+}
-+
-+function expnodes_gethostinterface($hostid)
-+{
-+    $h = API::Host()->get(array(
-+        'hostids' => $hostid,
-+        'output' => array(),
-+        'selectInterfaces' => API_OUTPUT_EXTEND
-+    ));
-+    
-+    if(count($h) == 0) return '';
-+    foreach($h[0]['interfaces'] as $i)
-+    {
-+        if($i['main'] == 1)
-+        {
-+            if($i['useip'] == 1) return $i['ip'];
-+            else return $i['dns'];
-+        }
-+    }
-+}
-+
-+function expnodes_getzabbixnodes()
-+{
-+    $hosts = API::Host()->get(array(
-+        'output' => array('hostid', 'host'),
-+        'selectInterfaces' => API_OUTPUT_EXTEND
-+    ));
-+    
-+    $nodes = array();
-+    
-+    foreach($hosts as $h)
-+    {
-+        $n = array();
-+        $n['hostid'] = $h['hostid'];
-+        $n['host'] = $h['host'];
-+        
-+        foreach($h['interfaces'] as $i)
-+        {
-+            if($i['main'] == 1)
-+            {
-+                $n['interfaceid'] = $i['interfaceid'];
-+                if($i['useip'] == 1) $n['interface'] = $i['ip'];
-+                else $n['interface'] = $i['dns'];
-+                
-+                break;
-+            }
-+        }
-+        
-+        $nodes[] = $n;
-+    }
-+    
-+    return $nodes;
-+}
-+
-diff --git a/zabbix/frontends/php/include/experiments/run.php 
b/zabbix/frontends/php/include/experiments/run.php
-new file mode 100644
-index 0000000..c0d0700
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/run.php
-@@ -0,0 +1,290 @@
-+<?php
-+
-+define('EXP_STATUS_FAILED', -1);
-+define('EXP_STATUS_NOT_STARTED', 0);
-+define('EXP_STATUS_RUNNING', 1);
-+define('EXP_STATUS_DONE_WITH_ERRORS', 2);
-+define('EXP_STATUS_DONE_SUCCESSFULLY', 10);
-+
-+function exprun_getstatusstring($status)
-+{
-+    switch($status)
-+    {
-+        case -1:
-+            return "Failed";
-+        case 0:
-+            return "Not started";
-+        case 1:
-+            return "Running";
-+        case 2:
-+            return "Done with errors";
-+        case 10:
-+            return "Done successfully";
-+        default:
-+            return "Undefined status";
-+    }
-+}
-+
-+function exprun_getall($extended = false, $string_status = true)
-+{
-+    exprun_updateresults(); //update database with any new results
-+
-+    $where['userid'] = intval(CWebUser::$data['userid']);
-+
-+    $res = expdb_select('exp_run', $where);
-+    
-+    for($i = 0; $i < sizeof($res); $i++)
-+    {
-+        $sql = "SELECT exp_runnode.*, exp_host.host as interface FROM 
exp_runnode, exp_host
-+                WHERE exp_runnode.runid = ".$res[$i]['runid']."
-+                AND exp_runnode.hostid = exp_host.hostid
-+                ORDER BY exp_runnode.status DESC, exp_runnode.percentage 
DESC, exp_host.host ASC";
-+        $nodes = DBfetchArray(DBselect($sql));
-+        
-+        if($string_status)
-+            $res[$i]['status'] = exprun_getstatusstring($res[$i]['status']);
-+        
-+        for($j = 0; $j < sizeof($nodes); $j++)
-+        {
-+            if($string_status)
-+                $nodes[$j]['status'] = 
exprun_getstatusstring($nodes[$j]['status']);
-+        }
-+        
-+        $res[$i]['nodes'] = $nodes;
-+    }
-+    
-+    return $res;
-+}
-+
-+function exprun_updateresults()
-+{
-+    $running = expdb_select('exp_run', array('status' => 1));
-+    foreach($running as $r)
-+    {
-+        $updates = exprun_parseresult($r['runid']);
-+        expdb_update('exp_run', array('status' => $updates['status'], 
'percentage' => $updates['percentage']), array('runid' => $r['runid']));
-+        foreach($updates['nodes_results'] as $nr)
-+        {
-+            expdb_update('exp_runnode',
-+                array('status' => $nr['status'], 'percentage' => 
$nr['percentage'], 'log' => $nr['log']),
-+                array('runid' => $r['runid'], 'hostid' => $nr['hostid']));
-+        }
-+    }
-+}
-+
-+function exprun_pidrunning($pid)
-+{
-+    $cmd = "ps --no-headers -p ".$pid;
-+    $res = exec($cmd);
-+    return !empty($res);
-+}
-+
-+function exprun_calculatestatus($percentage, $running, $failure)
-+{
-+    if($percentage < 100) $status = ($running) ? EXP_STATUS_RUNNING : 
EXP_STATUS_FAILED;
-+    else $status = ($failure) ? EXP_STATUS_DONE_WITH_ERRORS : 
EXP_STATUS_DONE_SUCCESSFULLY;
-+    return $status;
-+}
-+
-+function exprun_parseresult($run_id)
-+{
-+    $prog = 0;
-+    $total = 1;
-+    $failure = false;
-+    $nodes_results = array();
-+    
-+    //Read metadata
-+    $meta = exprun_getbyid($run_id);
-+    
-+    //Check if the process is already running
-+    $running = exprun_pidrunning($meta['pid']);
-+
-+    $results_file = $GLOBALS['GPLMT_RESULTS_DIR'].$run_id;
-+    if(file_exists($results_file))
-+    {
-+        //Read nodes from DB
-+        $nodes = expnodes_getbyrunid($run_id);
-+
-+        //Read loaded tasks (if available)
-+        if($meta['usetasklist'])
-+            $tasks = exec('grep -Po "(?<=Loaded )\d+(?= tasks)" 
'.$results_file);
-+        else
-+            $tasks = 1;
-+        if(!empty($tasks))
-+        {
-+            $tasks = intval($tasks);
-+
-+            $total = count($nodes) * $tasks;
-+
-+            //for each node, calculate progress from result output    
-+            foreach($nodes as $n)
-+            {
-+                $node_failure = false;
-+                $interface = $n['host'];
-+
-+                $res = array();
-+                exec('grep -Po "'.$interface.'\s*\| .* \| \K.*" 
'.$results_file, $res); //final result
-+                if(count($res) > 0)
-+                {
-+                    if(trim($res[0]) != 'success')
-+                    {
-+                        $failure = true;
-+                        $node_failure = true;
-+                    }
-+                    $node_prog = $tasks;
-+                }
-+                else
-+                {
-+                    //tasks completed for node
-+                    $tasks_completed = array();
-+                    exec('grep -Po "'.$interface.' : Task \'.*\' completed" 
'.$results_file, $tasks_completed);
-+                    $node_prog = count($tasks_completed);
-+                }
-+                
-+                //get all node logs
-+                $node_log_arr = array();
-+                exec("grep -E '^$interface' $results_file", $node_log_arr);
-+                $node_log = implode("\n", $node_log_arr);
-+                
-+                $node_perc = $node_prog * 100 / $tasks;
-+                $nodes_results[] = array('status' => 
exprun_calculatestatus($node_perc, $running, $node_failure),
-+                                    'percentage' => ($running) ? $node_perc : 
100,
-+                                    'log' => $node_log,
-+                                    'hostid' => $n['hostid']);
-+                $prog += $node_prog;
-+            }
-+        }
-+    }
-+    
-+    $perc = $prog * 100 / $total; //percentage done
-+    $status = exprun_calculatestatus($perc, $running, $failure); //total 
status
-+    
-+    return array('status' => $status, 'percentage' => ($running) ? $perc : 
100, 'nodes_results' => $nodes_results);
-+}
-+
-+function exprun_new($target, $params, $usetasklist, $tasklist, $cmd)
-+{
-+    if(!exp_verifygplmtdir()) return EXP_ERR_GPLMT_DIR;
-+    if($usetasklist == 1 && exptasklist_allowed($tasklist) == 0) return 
EXP_ERR_PERMISSION;
-+    
-+    //create run record
-+    $run_data = array();
-+    $run_data['usetasklist'] = $usetasklist;
-+    if($usetasklist == 1)
-+        $run_data['tasklistid'] = $tasklist;
-+    else
-+        $run_data['command'] = $cmd;
-+    $run_data['userid'] = intval(CWebUser::$data['userid']);
-+    $run_data['target'] = $target;
-+    
-+    $run_id = expdb_insert('exp_run', $run_data);
-+
-+    //create run-nodes records
-+    switch($target)
-+    {
-+        case 'ssh':
-+        case 'planetlab':
-+            $hostnames = array();
-+            foreach($params as $h) //get hostnames and save to DB
-+            {
-+                $hostnames[] = expnodes_gethostbyid($h)['host'];
-+                expdb_insert('exp_runnode', array('runid' => $run_id, 
'hostid' => $h, 'target' => $target));
-+            }
-+            //write GPLMT nodes file
-+            expnodes_writefile($hostnames, $run_id);
-+            break;
-+            
-+        default: //invalid target
-+            expdb_delete('exp_run', array('runid' => $run_id));
-+            return EXP_ERR_INVALID_TARGET;
-+    }
-+    
-+    exprun_gplmt($run_id);
-+    
-+    return EXP_OK;
-+}
-+
-+function exprun_getbyid($run_id)
-+{
-+    $res = expdb_select('exp_run', array('runid' => $run_id));
-+    return $res[0];
-+}
-+
-+function exprun_rerun($run_id)
-+{
-+    $meta = exprun_getbyid($run_id);
-+    if(exprun_pidrunning($meta['pid'])) return;
-+    
-+    exprun_gplmt($run_id);
-+}
-+
-+function exprun_checkpermission($run_id)
-+{
-+    if(CWebUser::$data['type'] == 3) return true;
-+    
-+    $res = expdb_select('exp_run', array('userid' => 
CWebUser::$data['userid'], 'runid' => $run_id));
-+    
-+    return (sizeof($res) > 0);
-+}
-+
-+function exprun_interrupt($run_id)
-+{
-+    $meta = exprun_getbyid($run_id);
-+    
-+    if(!exprun_checkpermission($run_id)) return;
-+    
-+    $cmd = "kill -15 ".$meta['pid'];
-+    exec($cmd);
-+}
-+
-+function exprun_delete($run_id)
-+{
-+    $meta = exprun_getbyid($run_id);    
-+
-+    //check permissions
-+    if(!exprun_checkpermission($run_id)) return;
-+    
-+    //check if tool still running
-+    if(exprun_pidrunning($meta['pid'])) return;
-+
-+    $n = $GLOBALS['GPLMT_NODES_DIR'].$run_id;
-+    if(file_exists($n)) unlink($n);
-+    $r = $GLOBALS['GPLMT_RESULTS_DIR'].$run_id;
-+    if(file_exists($r)) unlink($r);
-+    
-+    expdb_delete('exp_run', array('runid' => $run_id));
-+    expdb_delete('exp_runnode', array('runid' => $run_id));
-+}
-+
-+function exprun_verifyid($run_id)
-+{
-+    $res = expdb_select('exp_run', array('runid' => $run_id));
-+    return (sizeof($res) > 0);
-+}
-+
-+function exprun_gplmt($run_id)
-+{
-+    $run_data = exprun_getbyid($run_id);
-+    if($run_data['usetasklist'])
-+        $tasklist_data = exptasklist_getbyid($run_data['tasklistid']);
-+    
-+    //compose and run command
-+    $cmd = 'python -u '.$GLOBALS['GPLMT_DIR'].'gplmt.py -V'; // GPLMT
-+    $cmd .= ' -c '.$GLOBALS['GPLMT_CONF_DIR'].CWebUser::$data['userid']; // 
Conf file
-+    $cmd .= ' -n '.$GLOBALS['GPLMT_NODES_DIR'].$run_id; // Nodes file
-+    if($run_data['target'] == 'ssh')
-+        $cmd .= ' -t remote_ssh';
-+    elseif($run_data['target'] == 'planetlab')
-+        $cmd .= ' -t planetlab';
-+    if($run_data['usetasklist'])
-+        $cmd .= ' -l 
'.$GLOBALS['GPLMT_TASKLISTS_DIR'].$tasklist_data['fsname']; // Tasklist file
-+    else
-+        $cmd .= " -C '".$run_data['command']."'"; // Command to run
-+    $cmd .= ' > '.$GLOBALS['GPLMT_RESULTS_DIR'].$run_id; // Results file
-+    $cmd .= ' 2>&1 & echo $!'; // Redirect stderr, run in background and get 
pid
-+    
-+    $pid = system($cmd);
-+
-+    expdb_update("exp_run", array('fullcommand' => $cmd, 'pid' => $pid, 
'status' => EXP_STATUS_RUNNING), array('runid' => $run_id));
-+}
-+
-diff --git a/zabbix/frontends/php/include/experiments/targets.php 
b/zabbix/frontends/php/include/experiments/targets.php
-new file mode 100644
-index 0000000..3e3cc79
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/targets.php
-@@ -0,0 +1,184 @@
-+<?php
-+
-+require_once 'XML/RPC2/Client.php';
-+
-+$exp_targetlist = array(
-+    'SSH' => 'ssh',
-+    'Planetlab' => 'planetlab');
-+
-+/*
-+ * Planetlab
-+ */
-+
-+function exppl_getauth()
-+{
-+    $pl_user = expconfig_getconfigbyname('username');
-+    if(!$pl_user) fatal_error('Please specify planetlab username in config');
-+    $pl_pass = expconfig_getconfigbyname('password');
-+    if(!$pl_pass) fatal_error('Please specify planetlab password in config');
-+    
-+    return array(
-+        "AuthMethod" => 'password',
-+        "Username" => $pl_user,
-+        "AuthString" => $pl_pass
-+        );
-+}
-+
-+function exppl_getclient()
-+{
-+    $pl_api = expconfig_getconfigbyname('api_url');
-+    if(!$pl_api) fatal_error('Please specify planetlab API in config');
-+    
-+    return XML_RPC2_Client::create($pl_api, array('sslverify' => false));
-+}
-+
-+function exppl_getslicename()
-+{
-+    $pl_slice = expconfig_getconfigbyname('slice');
-+    if(!$pl_slice) fatal_error('Please specify planetlab slice in config');
-+    return $pl_slice;
-+}
-+
-+function exppl_getAvailableNodes($page_offset, $page_size, $hostfilter = null)
-+{
-+    $page_offset = intval($page_offset);
-+    $page_size = intval($page_size);
-+
-+    $pl_slice = exppl_getslicename();
-+    $auth = exppl_getauth();
-+    $client = exppl_getclient();
-+    
-+    //get node IDs in slice (for negation)
-+    try
-+    {
-+        $node_ids = $client->GetSlices($auth, $pl_slice, 
array('node_ids'))[0]['node_ids'];
-+    }
-+    catch (XML_RPC2_FaultException $e)
-+    {
-+        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
-+    }
-+    
-+    $filter = array('~node_id' => $node_ids,
-+                    '-SORT' => 'hostname',
-+                    '-OFFSET' => $page_offset,
-+                    '-LIMIT' => $page_size);
-+    if($hostfilter) $filter['hostname'] = "*$hostfilter*";
-+    
-+    try
-+    {
-+        return $client->GetNodes($auth, $filter, array('hostname', 
'node_id'));
-+    }
-+    catch (XML_RPC2_FaultException $e)
-+    {
-+        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
-+    }
-+}
-+
-+function exppl_getSliceNodes()
-+{
-+    $pl_slice = exppl_getslicename();
-+    $auth = exppl_getauth();
-+    $client = exppl_getclient();
-+
-+    //get node IDs
-+    try
-+    {
-+        $node_ids = $client->GetSlices($auth, $pl_slice, 
array('node_ids'))[0]['node_ids'];
-+    }
-+    catch (XML_RPC2_FaultException $e)
-+    {
-+        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
-+    }
-+    
-+    //get node hostnames + IDs
-+    try
-+    {
-+        $res = $client->GetNodes($auth, $node_ids, array('hostname', 
'node_id'));
-+    }
-+    catch (XML_RPC2_FaultException $e)
-+    {
-+        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
-+    }
-+    $res = exppl_updateSliceNodesDB($res);
-+    return $res;
-+}
-+
-+function exppl_updateSliceNodes($nodes)
-+{
-+    $pl_slice = exppl_getslicename();
-+    $auth = exppl_getauth();
-+    $client = exppl_getclient();
-+    
-+    try
-+    {
-+        $client->UpdateSlice($auth, $pl_slice, array('nodes' => 
array_map('intval', array_values($nodes))));
-+    }
-+    catch (XML_RPC2_FaultException $e)
-+    {
-+        fatal_error($e->getFaultCode() . ' : ' . $e->getFaultString());
-+    }
-+}
-+
-+function exppl_updateSliceNodesDB($nodes)
-+{
-+    if(!is_array($nodes)) return;
-+    
-+    $userid = CWebUser::$data['userid'];
-+    
-+    // No delete so as not to break previous runs
-+    // Insert new hosts not seen before
-+    
-+    for($i = 0; $i < count($nodes); $i++)
-+    {
-+        if(!exppl_getHostByPLNodeId($nodes[$i]['node_id'])) //Does not exist
-+            $nodes[$i]['hostid'] = expdb_insert('exp_host', array('userid' => 
$userid, 'host' => $nodes[$i]['hostname'], 'target' => 'planetlab', 'pl_nodeid' 
=> $nodes[$i]['node_id']));
-+        else
-+            $nodes[$i]['hostid'] = 
exppl_getHostByPLNodeId($nodes[$i]['node_id'])['hostid'];
-+    }
-+    
-+    return $nodes;
-+}
-+
-+function exppl_getHostByPLNodeId($pl_nodeid)
-+{
-+    $res = expdb_select('exp_host', array('pl_nodeid' => $pl_nodeid));
-+    if(count($res) == 0) return null;
-+    return $res[0];
-+}
-+
-+/*
-+ * SSH
-+ */
-+
-+function expssh_updatehosts($hostlist)
-+{
-+    if(!is_array($hostlist)) return;
-+    
-+    $userid = CWebUser::$data['userid'];
-+    
-+    $old_hostlist = array();
-+    $new_hostlist = array();
-+    foreach($hostlist as $h)
-+    {
-+        $hc = mysql_real_escape_string(trim($h));
-+        if(!$hc) continue;
-+        if(is_numeric($hc))
-+            $old_hostlist[] = $hc;
-+        else //added hosts value is the host itself not an ID
-+            $new_hostlist[] = $hc;
-+    }
-+    
-+    //look for deleted hosts
-+    if(count($old_hostlist) > 0)
-+    {
-+        $sql = 'DELETE FROM exp_host
-+            WHERE userid = '.$userid
-+            .' AND target = "ssh"'
-+            .' AND hostid NOT IN ('.implode(',', $old_hostlist).')';
-+        DBexecute($sql);
-+    }
-+    
-+    //look for new hosts
-+    foreach($new_hostlist as $h)
-+        expdb_insert('exp_host', array('userid' => $userid, 'host' => $h, 
'target' => 'ssh'));
-+}
-diff --git a/zabbix/frontends/php/include/experiments/tasklist.php 
b/zabbix/frontends/php/include/experiments/tasklist.php
-new file mode 100644
-index 0000000..5e45902
---- /dev/null
-+++ b/zabbix/frontends/php/include/experiments/tasklist.php
-@@ -0,0 +1,287 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/files.php';
-+
-+//default XML elements (for creating empty nods)
-+$exptasklist_defaults = array();
-+$exptasklist_defaults['sequence'] = new SimpleXMLElement('<sequence 
name=""></sequence>');
-+$exptasklist_defaults['run'] = new SimpleXMLElement('<run 
name=""><command></command><arguments></arguments><timeout>0</timeout><expected_return_code>0</expected_return_code><expected_output></expected_output><stop_on_fail>false</stop_on_fail></run>');
-+$exptasklist_defaults['run_per_host'] = new SimpleXMLElement('<run_per_host 
name=""><command_file></command_file><output_prefix></output_prefix><timeout>0</timeout><expected_return_code>0</expected_return_code><expected_output></expected_output><stop_on_fail>false</stop_on_fail></run_per_host>');
-+$exptasklist_defaults['put'] = new SimpleXMLElement('<put 
name=""><source></source><destination></destination><stop_on_fail>false</stop_on_fail></put>');
-+$exptasklist_defaults['get'] = new SimpleXMLElement('<get 
name=""><source></source><destination>./</destination><stop_on_fail>false</stop_on_fail></get>
 ');
-+
-+function exptasklist_addall()
-+{
-+    $sql = "SELECT * FROM exp_tasklist";
-+    $indb = DBfetchArrayAssoc(DBSelect($sql), 'fsname');
-+    
-+    $indir = scandir($GLOBALS['GPLMT_TASKLISTS_DIR']);
-+    
-+    foreach($indir as $i)
-+    {
-+        if(substr($i, -4) != '.xml') continue;
-+        if(isset($indb[$i])) continue;
-+        $name = str_replace('_', ' ', $i);
-+        $name = str_replace('.xml', '', $name);
-+        
-+        expdb_insert('exp_tasklist', array('name' => $name, 'fsname' => $i, 
'userid' => CWebUser::$data['userid'], 'shared' => 1));
-+    }
-+}
-+
-+function exptasklist_getall($editable = false)
-+{
-+    $sql = "SELECT exp_tasklist.*, CONCAT_WS(' ', users.name, users.surname) 
as username
-+            FROM exp_tasklist INNER JOIN users ON exp_tasklist.userid = 
users.userid";
-+    if(!(CWebUser::$data['type'] == 3)) //not super admin
-+    {
-+        $sql .= ' WHERE exp_tasklist.userid = '.CWebUser::$data['userid'];
-+        if(!$editable)
-+            $sql .= ' OR exp_tasklist.shared = 1';
-+    }
-+    
-+    return DBfetchArray(DBselect($sql));
-+}
-+
-+function exptasklist_getbyid($tasklistid)
-+{
-+    $res = expdb_select('exp_tasklist', array('tasklistid' => $tasklistid));
-+    if(count($res) == 0) return null;
-+    return $res[0];
-+}
-+
-+function exptasklist_getcontent($tasklistid)
-+{
-+    $tl_row = exptasklist_getbyid($tasklistid);
-+    if(!$tl_row) return null;
-+    $file = $GLOBALS['GPLMT_TASKLISTS_DIR'].$tl_row['fsname'];
-+    if(!file_exists($file)) return null;
-+    return file_get_contents($file);
-+}
-+
-+/**
-+ * Given a tasklist id, returns 0, 1 or 2 for No access, read, read/write 
respectively
-+ *
-+ * @return int
-+ */
-+function exptasklist_allowed($tasklistid)
-+{
-+    $tl_row = exptasklist_getbyid($tasklistid);
-+    if(!$tl_row) return 0;
-+    if(CWebUser::$data['type'] == 3 || $tl_row['userid'] == 
CWebUser::$data['userid']) return 2;
-+    if($tl_row['shared']) return 1;
-+    return 0;
-+}
-+
-+function exptasklist_delete($tid)
-+{
-+    $meta = exptasklist_getbyid($tid);
-+    if(!$meta)
-+    {
-+        error("Invalid tasklist ID");
-+        return false;
-+    }
-+    $fullFileName = $GLOBALS['GPLMT_TASKLISTS_DIR'].$meta['fsname'];
-+    
-+    //delete from DB
-+    expdb_delete('exp_tasklist', array('tasklistid' => $tid));
-+    
-+    //delete file
-+    if(file_exists($fullFileName)) unlink($fullFileName);
-+    
-+    return true;
-+}
-+
-+function exptasklist_sxmlappend(SimpleXMLElement $to, SimpleXMLElement $from)
-+{
-+    $toDom = dom_import_simplexml($to);
-+    $fromDom = dom_import_simplexml($from);
-+    $newDom = $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, 
true));
-+    return simplexml_import_dom($newDom);
-+}
-+
-+function exptasklist_constructxml($data)
-+{
-+    global $exptasklist_defaults;
-+    
-+    $xml = new SimpleXMLElement('<?xml version="1.0" 
encoding="UTF-8"?><tasklist></tasklist>');
-+    $xml->addAttribute('xsi:noNamespaceSchemaLocation', 
"../tasklist_schema.xsd", "http://www.w3.org/2001/XMLSchema-instance";);
-+    $xml->addChild('options');
-+
-+    //name
-+    if(empty($data['name']))
-+    {
-+        error("Missing name field");
-+        return false;
-+    }
-+    $name = $data['name'];
-+    $xml->addAttribute('name', $name);
-+    
-+    //target
-+    /*if(!empty($data['target']))
-+        $xml->options->addChild('target', $data['target']);*/
-+
-+    //log dir
-+    if(!empty($data['logdir']))
-+        $xml->options->addChild('log_dir', $data['logdir']);
-+    
-+    //index for node components
-+    $nodesIndex = array();
-+    
-+    foreach($data as $k => $v)
-+    {
-+        $parts = explode('_', $k);
-+        $parts_count = count($parts);
-+        if($parts_count == 1 || $parts_count > 3) continue;
-+        
-+        $field = str_replace('$', '_', $parts[0]);
-+        $value = trim($v);
-+        $index = implode('_', array_slice($parts, 1));
-+        
-+        if($field == 'type') //initial field in the node
-+        {
-+            if(!array_key_exists($value, $exptasklist_defaults)) continue; 
//invalid type
-+            
-+            if($parts_count == 2) $parent = $xml;
-+            else $parent = $nodesIndex[$parts[1]];
-+            
-+            $newXml = $exptasklist_defaults[$value];
-+            if($value != 'sequence') $newXml['id'] = $parts[$parts_count - 
1]; //GPLMT doesn't accept ID in sequence but mandatory for others
-+            $newXml['enabled'] = 'false'; //Disabled by default unless we get 
the enabled flag from form
-+            
-+            $nodesIndex[$index] = exptasklist_sxmlappend($parent, $newXml);
-+            
-+            
-+            continue;
-+        }
-+        
-+        if(!array_key_exists($index, $nodesIndex)) continue; //problem or 
data element that is not related to the XML
-+        
-+        $subxml = $nodesIndex[$index];
-+        $type = $subxml->getName();
-+        
-+        //validations:
-+        switch($field)
-+        {
-+            //bool
-+            case 'enabled': case 'stop_on_fail':
-+                $value = strtolower($value);
-+                if($value != 'yes' && $value != 'no')
-+                {
-+                    error("Value for $field should be true or false!");
-+                    return false;
-+                }
-+                $value = ($value == 'yes') ? 'true' : 'false';
-+                break;
-+            
-+            //int
-+            case 'timeout': case 'expected_return_code':
-+                if(!is_numeric($value))
-+                {
-+                    error("Value for $field should be an integer!");
-+                    return false;
-+                }
-+                break;
-+
-+            //file
-+            case 'source':
-+                if($type == 'put')
-+                {
-+                    $value = exp_cleanfilename($value);
-+                }
-+                break;
-+            case 'destination':
-+                if($type == 'get')
-+                {
-+                    $value = './';
-+                }
-+                break;
-+        }
-+        
-+        //writing values
-+        switch($field)
-+        {
-+            //attributes
-+            case 'enabled': case 'name':
-+                $subxml[$field] = $value;
-+                break;
-+            
-+            case 'command': case 'arguments': case 'timeout': case 
'expected_return_code': case 'expected_output':
-+            case 'stop_on_fail': case 'command_file': case 'output_prefix': 
case 'source': case 'destination':
-+                $subxml->$field = $value;
-+                break;
-+            
-+            default:
-+                error("Unknown field: $field");
-+        }
-+    }
-+    
-+    //save the resulting XML to file (formatted)
-+    $dom = dom_import_simplexml($xml)->ownerDocument;
-+    $dom->formatOutput = true;
-+    return $dom->saveXML();
-+}
-+
-+function exptasklist_add($data)
-+{
-+    $xml = exptasklist_constructxml($data);
-+    if(!$xml) return false;
-+    
-+    //name
-+    $name = $data['name'];
-+    
-+    //description
-+    $description = empty($data['description']) ? '' : $data['description'];
-+    
-+    //shared
-+    $shared = false;
-+    $shared = (!empty($data['shared']) && ($data['shared'] == 'yes'));
-+    
-+    //create new fsname
-+    $fsname = str_replace(' ', '_', $name);
-+    $fsname = str_replace('\\', '_', $fsname);
-+    $counter = 0;
-+    while(file_exists($GLOBALS['GPLMT_TASKLISTS_DIR'].$fsname.'.xml'))
-+    {
-+        $fsname .= strval($counter);
-+        $counter++;
-+    }
-+    $fsname .= '.xml';
-+    
-+    //user ID
-+    $userid = CWebUser::$data['userid'];
-+    
-+    //save to file
-+    file_put_contents($GLOBALS['GPLMT_TASKLISTS_DIR'].$fsname, $xml);
-+    
-+    //save to DB
-+    expdb_insert('exp_tasklist',
-+        array('name' => $name, 'description' => $description, 'fsname' => 
$fsname, 'userid' => $userid, 'shared' => intval($shared)));
-+    
-+    return true;
-+}
-+
-+function exptasklist_update($tasklistid, $data)
-+{
-+    $meta = exptasklist_getbyid($tasklistid); //get task meta data from db
-+    
-+    $xml = exptasklist_constructxml($data);
-+    if(!$xml) return false;
-+    
-+    //name
-+    $name = $data['name'];
-+    
-+    //description
-+    $description = empty($data['description']) ? '' : $data['description'];
-+    
-+    //shared
-+    $shared = false;
-+    $shared = (!empty($data['shared']) && ($data['shared'] == 'yes'));
-+    
-+    file_put_contents($GLOBALS['GPLMT_TASKLISTS_DIR'].$meta['fsname'], $xml);
-+    
-+    //update DB
-+    expdb_update('exp_tasklist', array('name' => $name, 'description' => 
$description, 'shared' => intval($shared)),
-+        array('tasklistid' => $tasklistid));
-+    
-+    return true;
-+}
-diff --git a/zabbix/frontends/php/include/menu.inc.php 
b/zabbix/frontends/php/include/menu.inc.php
-index 6e27065..51b0d56 100644
---- a/zabbix/frontends/php/include/menu.inc.php
-+++ b/zabbix/frontends/php/include/menu.inc.php
-@@ -281,6 +281,38 @@ $ZBX_MENU = array(
-                       )
-               )
-       ),
-+      'experiment' => array(
-+              'label'                         => _('Experiments'),
-+              'user_type'                     => USER_TYPE_ZABBIX_ADMIN,
-+              'node_perm'                     => PERM_READ_WRITE,
-+              'default_page_id'       => 0,
-+              'pages' => array(
-+                      array(
-+                              'url' => 'execute.php',
-+                              'label' => _('Deploy & Execute')
-+                      ),
-+                      array(
-+                              'url' => 'results.php',
-+                              'label' => _('Results')
-+                      ),
-+                      array(
-+                              'url' => 'targets.php',
-+                              'label' => _('Targets')
-+                      ),
-+                      array(
-+                              'url' => 'tasklist.php',
-+                              'label' => _('Tasklists')
-+                      ),
-+                      array(
-+                              'url' => 'files.php',
-+                              'label' => _('Files')
-+                      ),
-+                      array(
-+                              'url' => 'conf.php',
-+                              'label' => _('Configuration')
-+                      )
-+              )
-+      ),
-       'login' => array(
-               'label'                                 => _('Login'),
-               'user_type'                             => 0,
-diff --git a/zabbix/frontends/php/include/views/administration.script.list.php 
b/zabbix/frontends/php/include/views/administration.script.list.php
-index bb42f3f..aab1244 100644
---- a/zabbix/frontends/php/include/views/administration.script.list.php
-+++ b/zabbix/frontends/php/include/views/administration.script.list.php
-@@ -40,9 +40,18 @@ $scriptsTable->setHeader(array(
-       make_sorting_header(_('Commands'), 'command'),
-       _('User group'),
-       _('Host group'),
--      _('Host access')
-+      _('Host access'),
-+      _('Run on Host Group')
- ));
- 
-+//get list of host groups
-+$hostgroups = API::HostGroup()->get(array(
-+              'not_proxy_host' => 1,
-+              'sortfield' => 'name',
-+              'editable' => true,
-+              'output' => array('name')
-+      ));
-+
- foreach ($this->data['scripts'] as $script) {
-       $scriptid = $script['scriptid'];
- 
-@@ -72,6 +81,18 @@ foreach ($this->data['scripts'] as $script) {
-               $scriptExecuteOn = '';
-       }
- 
-+    //create hostgroups combobox
-+    $runForm = new CForm('GET', 'scripts_exec.php');
-+    $runForm->addItem(new CInput('hidden', 'execute', '1'));
-+    $runForm->addItem(new CInput('hidden', 'scriptid', $script['scriptid']));
-+    
-+    $grpsComboBox = new CComboBox('groupid');
-+    foreach($hostgroups as $hostgroup)
-+        $grpsComboBox->addItem(new CComboItem($hostgroup['groupid'], 
$hostgroup['name']));
-+
-+    $runForm->addItem($grpsComboBox);
-+    $runForm->addItem(new CInput('submit', 'submit', 'Run'));
-+
-       $scriptsTable->addRow(array(
-               new CCheckBox('scripts['.$script['scriptid'].']', 'no', null, 
$script['scriptid']),
-               new CLink($script['name'], 
'scripts.php?form=1&scriptid='.$script['scriptid']),
-@@ -80,7 +101,8 @@ foreach ($this->data['scripts'] as $script) {
-               zbx_nl2br(htmlspecialchars($script['command'], ENT_COMPAT, 
'UTF-8')),
-               ('' == $script['userGroupName']) ? _('All') : 
$script['userGroupName'],
-               ('' == $script['hostGroupName']) ? _('All') : 
$script['hostGroupName'],
--              ((PERM_READ_WRITE == $script['host_access']) ? _('Write') : 
_('Read'))
-+              ((PERM_READ_WRITE == $script['host_access']) ? _('Write') : 
_('Read')),
-+              $runForm
-       ));
- }
- 
-diff --git a/zabbix/frontends/php/include/views/experiments.conf.php 
b/zabbix/frontends/php/include/views/experiments.conf.php
-new file mode 100644
-index 0000000..0af85d5
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.conf.php
-@@ -0,0 +1,66 @@
-+<?php
-+
-+$conf = $this->get('conf');
-+
-+$cWidget = new CWidget();
-+
-+$cForm = new CForm('post');
-+$cTable = new CTableInfo();
-+
-+$current_section = '';
-+foreach($conf as $c)
-+{
-+    if($c['section'] != $current_section)
-+    {
-+        $current_section = $c['section'];
-+        $cTable->addRow(strtoupper($current_section));
-+    }
-+    
-+    switch($c['type'])
-+    {
-+        case 'text': case 'integer':
-+            $cInput = new CTextBox($c['configid'], $c['value']);
-+            break;
-+        
-+        case 'password':
-+            $cInput = new CPassBox($c['configid'], $c['value'], 20);
-+            break;
-+        
-+        case 'boolean':
-+            $cHidden = new CInput('hidden', $c['configid'], 'no');
-+            $cChkbox = new CCheckBox($c['configid'], $c['value']);
-+            $cInput = array($cHidden, $cChkbox);
-+            break;
-+        
-+        case 'file':
-+            $userfiles = expfiles_getuserfiles();
-+            $selectedfile = '';
-+            if(!empty($c['value'])) $selectedfile = basename($c['value']);
-+            $cInput = new CComboBox($c['configid']);
-+            $cInput->addItem('', '');
-+            foreach($userfiles as $uf)
-+                $cInput->addItem($uf, $uf, ($selectedfile == $uf)?'yes':null);
-+            break;
-+
-+        case 'enum':
-+            $options = expconfig_getenum($c['configid']);
-+            $cInput = new CComboBox($c['configid']);
-+            foreach($options as $o)
-+                $cInput->addItem($o['value'], $o['label'], ($c['value'] == 
$o['value'])?'yes':null);
-+            break;
-+
-+        default:
-+            $cInput = new CLabel('Invalid type');
-+            break;
-+    }
-+    
-+    $help_image = new CImg('images/general/question_mark.png');
-+    $help_image->attr('title', $c['description']);
-+    
-+    $cTable->addRow(array($c['label'], array($cInput, $help_image)));
-+}
-+$cTable->addRow(new CSubmit('update', 'Update'));
-+
-+$cForm->addItem($cTable);
-+$cWidget->addItem($cForm);
-+return $cWidget;
-diff --git a/zabbix/frontends/php/include/views/experiments.execute.php 
b/zabbix/frontends/php/include/views/experiments.execute.php
-new file mode 100644
-index 0000000..bc87ce3
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.execute.php
-@@ -0,0 +1,100 @@
-+<?php
-+
-+$targets = $this->get('targets');
-+$currenttarget = $this->get('currenttarget');
-+
-+//Main Form
-+$exec_frm = new CForm();
-+$exec_frm->setName('web.experiment.execute.php.');
-+$exec_frm->attr('id', 'mainfrm');
-+
-+//Main table
-+$main_table = new CTable();
-+
-+//Row 1 - Targets
-+$targets_cmb = new CComboBox('target');
-+foreach($targets as $k => $v)
-+    $targets_cmb->addItem($v, $k, ($v == $currenttarget)?'yes':null);
-+$targets_cmb->attr('onchange', "jQuery('#mainfrm').submit();");
-+
-+$main_table->addRow(new CRow(array(
-+    'Select Target:',
-+    $targets_cmb)));
-+
-+//Row 2 - Target settings
-+$settings_enabled = false;
-+switch($currenttarget)
-+{
-+    case 'ssh':
-+        $settings_enabled = true;
-+        
-+        $sshhosts = expnodes_gethosts('ssh');
-+        $sshhosts_tb = new CTweenBox($exec_frm, 'hosts');
-+        foreach($sshhosts as $sh)
-+            $sshhosts_tb->addItem($sh['hostid'], $sh['host'], true);
-+        
-+        $settings_elm = $sshhosts_tb->get('Selected:', 'Excluded:');
-+        
-+        break;
-+    
-+    case 'planetlab':
-+        $settings_enabled = true;
-+        
-+        $plhosts = exppl_getSliceNodes();
-+        $plhosts_tb = new CTweenBox($exec_frm, 'hosts');
-+        foreach($plhosts as $ph)
-+            $plhosts_tb->addItem($ph['hostid'], $ph['hostname'], true);
-+        
-+        $settings_elm = $plhosts_tb->get('Selected:', 'Excluded:');
-+    
-+        break;
-+    
-+    default:
-+        $settings_enabled = true;
-+        $settings_elm = 'Invalid Target. WHY?';
-+        break;
-+}
-+if($settings_enabled)
-+    $main_table->addRow(new CRow(array(
-+        'Target Settings:',
-+        $settings_elm)));
-+
-+//Row 3 - Tasklists
-+$tasklists = $this->get('tasklists');
-+
-+$tasklists_tbl = new CTable();
-+
-+$tasklists_rad1 = new CRadioButton('usetasklist', '1', 'input radio', null, 
true);
-+$tasklists_rad2 = new CRadioButton('usetasklist', '0', 'input radio');
-+$tasklists_cmb = new CComboBox('tasklist');
-+foreach($tasklists as $t)
-+    $tasklists_cmb->addItem($t['tasklistid'], $t['name']);
-+$tasklists_txt = new CTextBox('cmd');
-+
-+
-+$tasklists_tbl->addRow(
-+array(
-+new CDiv(array(
-+$tasklists_rad1, 'Tasklist:')),
-+$tasklists_cmb));
-+$tasklists_tbl->addRow(
-+array(
-+new CDiv(array(
-+$tasklists_rad2, 'Command:')),
-+$tasklists_txt));
-+
-+$main_table->addRow(new CRow(array(
-+    'Select Tasklist / Command:',
-+    $tasklists_tbl
-+)));
-+
-+
-+$exec_frm->addItem($main_table);
-+
-+/*
-+ * footer
-+ */
-+$run_submit = array(new CSubmit('run', 'Run'));
-+$exec_frm->addItem(makeFormFooter($run_submit));
-+
-+return $exec_frm;
-diff --git a/zabbix/frontends/php/include/views/experiments.files.php 
b/zabbix/frontends/php/include/views/experiments.files.php
-new file mode 100644
-index 0000000..1fd1203
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.files.php
-@@ -0,0 +1,30 @@
-+<?php
-+
-+$files = $this->get('files');
-+
-+$fWidget = new CWidget();
-+
-+$uploadForm = new CForm('post', null, 'multipart/form-data');
-+$uploadForm->addItem(new CInput('file', 'file'));
-+$uploadForm->addItem(new CSubmit('upload', 'Upload file'));
-+//add maximum size note
-+
-+$fWidget->addPageHeader('USER FILES', $uploadForm);
-+
-+$files_tbl = new CTableInfo('No files added yet.');
-+$files_tbl->setHeader(array('File name', ''));
-+foreach($files as $f)
-+{
-+    //download link
-+    $download_lnk = new CLink($f, '?download='.$f);
-+    
-+    //delete link
-+    $delete_lnk = new CLink('delete', '?delete='.$f);
-+    
-+    $files_tbl->addRow(array($download_lnk, $delete_lnk));
-+    //TODO: add delete, download
-+}
-+
-+$fWidget->addItem($files_tbl);
-+
-+return $fWidget;
-diff --git a/zabbix/frontends/php/include/views/experiments.results.php 
b/zabbix/frontends/php/include/views/experiments.results.php
-new file mode 100644
-index 0000000..2591b41
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.results.php
-@@ -0,0 +1,63 @@
-+<?php
-+
-+//Main table
-+$main_table = new CTableInfo();
-+
-+$results = $this->get('results');
-+$runid = $this->get('runid'); //if set, one of the runs is selected
-+
-+$main_table->setHeader(array('', 'Status', 'Started On', 'Target', 
'Percentage completed', '', ''));
-+
-+foreach($results as $r)
-+{
-+    $div_actions = new CDiv();
-+    if($r['status'] == 'Running')
-+        $div_actions->addItem(new CLink('interrupt', 
'results.php?interrupt='.$r['runid']));
-+    else
-+    {
-+        $div_actions->addItem(new CLink('delete', 
'results.php?delete='.$r['runid']));
-+        //$div_actions->addItem(new CButtonDelete('Are you sure you want to 
delete?', $r['runid']));
-+        $div_actions->addItem(' | ');
-+        $div_actions->addItem(new CLink('re-run', 
'results.php?rerun='.$r['runid']));
-+    }
-+    
-+    //nodes table
-+    $nodes_table = new CTableInfo();
-+    foreach($r['nodes'] as $n)
-+    {
-+        $nodes_table->addRow(new CRow(array(
-+            $n['interface'],
-+            $n['status'],
-+            $n['percentage'].'%',
-+            new CLink('log', 
'results.php?runid='.$r['runid'].'&hostid='.$n['hostid'])
-+        )));
-+    }
-+    
-+    $main_row = array(
-+        new CButton(null, '+/-', 
"javascript:jQuery('#".$r['runid']."').toggle();"),
-+        $r['status'],
-+        $r['startedon'],
-+        $r['target'],
-+        $r['percentage'].'%',
-+        new CLink('log', 'results.php?runid='.$r['runid']),
-+        $div_actions
-+        );
-+    $main_table->addRow(new CRow($main_row));
-+    $hidden_col = new CCol($nodes_table, null, count($main_row));
-+    $hidden_col->attr('id', $r['runid']);
-+    if(empty($runid) || $runid != $r['runid'])
-+        $hidden_col->attr('style', 'display:none;');
-+    $main_table->addRow(new CRow($hidden_col));
-+}
-+
-+$log = $this->get('log');
-+
-+if(!empty($log))
-+{
-+    $res_txt = new CTextArea(null, $log, array('rows' => substr_count($log, 
"\n") + 1, 'readonly' => 1));
-+    $res_txt->attr('style', 'width:100%;font-size:15px;');
-+    
-+    return new CDiv(array($main_table, 'RESULT:', $res_txt));
-+}
-+else
-+    return $main_table;
-diff --git a/zabbix/frontends/php/include/views/experiments.targets.php 
b/zabbix/frontends/php/include/views/experiments.targets.php
-new file mode 100644
-index 0000000..af46fba
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.targets.php
-@@ -0,0 +1,90 @@
-+<?php
-+$targetlist = $this->get('targetlist');
-+$default_target = reset($targetlist);
-+$selected_target = $this->get('selected_target');
-+if(!$selected_target) $selected_target = $default_target;
-+
-+//Main form
-+$main_frm = new CForm();
-+$main_frm->setName('web.experiment.targets.php.');
-+$main_frm->attr('id', 'mainfrm');
-+
-+//Main table
-+$main_table = new CTable();
-+
-+//Row 1 - Targets
-+$targets_cmb = new CComboBox('target');
-+foreach($targetlist as $k => $v)
-+    $targets_cmb->addItem($v, $k, ($v == $selected_target)?'yes':null);
-+$targets_cmb->attr('onchange', "jQuery('#mainfrm').submit();");
-+$main_table->addRow(array('Target:', $targets_cmb));
-+
-+//Row 2 - Target edit
-+switch($selected_target)
-+{
-+    case 'ssh':
-+        $ssh_lst = new CListBox('sshhosts[]', null, 12);
-+        $sshhosts = $this->get('sshhosts');
-+        foreach($sshhosts as $sh)
-+            $ssh_lst->addItem($sh['hostid'], $sh['host']);
-+        
-+        $del_btn = new CButton('delsshhost', 'Remove', 
"jQuery('select[name=\"sshhosts[]\"]').find(':selected').remove()");
-+        
-+        $add_txt = new CTextBox('newsshhost', null, 30);
-+        $add_btn =  new CButton('addsshhost', 'Add', 
"jQuery('select[name=\"sshhosts[]\"]').append('<option>'+jQuery('input[name=newsshhost]').val()+'</option>');jQuery('input[name=newsshhost]').val('')");
-+        
-+        $submit_btn = new CSubmit('apply', 'Apply');
-+        $submit_btn->attr('onclick', "jQuery('select[name=\"sshhosts[]\"] 
option').attr('selected', 'yes')");
-+        
-+        $main_table->addRow(array('SSH:', array($ssh_lst, $del_btn)));
-+        $main_table->addRow(array('', array($add_txt, $add_btn)));
-+        $main_table->addRow(array('', $submit_btn));
-+        
-+        break;
-+    
-+    case 'planetlab':
-+        $pagesize = 20;
-+        $pageoffset = intval($this->get('ploffset'));
-+        if(!$pageoffset || $pageoffset < 0) $pageoffset = 0;
-+        $hostfilter = $this->get('plfilter');
-+        if(!$hostfilter) $hostfilter = null;
-+        $slicename = exppl_getslicename();
-+        $slicenodes = exppl_getSliceNodes();
-+        $availnodes = exppl_getAvailableNodes($pageoffset, $pagesize, 
$hostfilter);
-+    
-+        $pl_tb = new CTweenBox($main_frm, 'plnodes');
-+        foreach($slicenodes as $sn)
-+            $pl_tb->addItem($sn['node_id'], $sn['hostname'], true);
-+        foreach($availnodes as $an)
-+            $pl_tb->addItem($an['node_id'], $an['hostname']);
-+        
-+        $filter_frm = new CForm('get');
-+        $filter_frm->attr('id', 'filterfrm');
-+        $filter_tb = new CTextBox('plfilter', $hostfilter);
-+        $filter_tb->attr('id', 'plfilter');
-+        $filter_btn = new CSubmit('filter', 'Filter', 
'jQuery("#ploffset").val(0)');
-+        $page_tb = new CTextBox('ploffset', $pageoffset, 2);
-+        $page_tb->attr('id', 'ploffset');
-+        $prev_btn = new CSubmit('plprev', '<<', 
'jQuery("#ploffset").val(parseInt(jQuery("#ploffset").val(), 10) - 
1);jQuery("#filterfrm").submit();');
-+        $next_btn = new CSubmit('plnext', '>>', 
'jQuery("#ploffset").val(parseInt(jQuery("#ploffset").val(), 10) + 
1);jQuery("#filterfrm").submit();');
-+        $clear_btn = new CSubmit('plclear', 'Clear', 
'jQuery("#ploffset").val(0);jQuery("#plfilter").val("")');
-+        $filter_tbl = new CTable();
-+        $filter_tbl->addRow(array(array($prev_btn, $page_tb, $next_btn)));
-+        $filter_tbl->addRow(array(array('Filter:', $filter_tb, $filter_btn)));
-+        $filter_tbl->addRow(array($clear_btn));
-+        $filter_frm->addItem($filter_tbl);
-+        
-+        $pl_tbl = new CTable();
-+        $pl_tbl->addRow(array($pl_tb->get($slicename, 'Available'), 
$filter_frm));
-+        
-+        $submit_btn = new CSubmit('apply', 'Apply');
-+        
-+        $main_table->addRow(array('Planetlab', $pl_tbl));
-+        $main_table->addRow(array('', $submit_btn));
-+        
-+        break;
-+}
-+
-+$main_frm->addItem($main_table);
-+
-+return $main_frm;
-diff --git a/zabbix/frontends/php/include/views/experiments.tasklist.edit.php 
b/zabbix/frontends/php/include/views/experiments.tasklist.edit.php
-new file mode 100644
-index 0000000..152cf29
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.tasklist.edit.php
-@@ -0,0 +1,318 @@
-+<?php
-+
-+$new = $this->get('new');
-+
-+if($new)
-+    $xml = new SimpleXMLElement('<?xml version="1.0" 
encoding="UTF-8"?><tasklist></tasklist>');
-+else
-+    $xml = $this->get('xml');
-+
-+//$targets = $this->get('targets');
-+$tid = $this->get('tid');
-+if($new)
-+    $meta = array();
-+else
-+    $meta = $this->get('meta');
-+$exptasklist_defaults = $this->get('exptasklist_defaults');
-+
-+function tlview_parseseq($xml, $postfix)
-+{
-+    $seq_tbl = new CTableInfo('');
-+    $seq_tbl->attr('id', "table$postfix");
-+    
-+    //Top Row:
-+    $btns_div = new CDiv();
-+    //Delete button
-+    $del_btn = new CButton('delete', 'delete', 'javascript: 
jQuery("#row'.$postfix.'").remove()');
-+    //Type (hidden)
-+    $type_hdn = new CInput('hidden', 'type'.$postfix, 'sequence');
-+    $btns_div->addItem($type_hdn);
-+    //Add runs
-+    $run_cmb = new CComboBox('run');
-+    $run_cmb->attr('id', "runs$postfix");
-+    $run_cmb->addItem('run', 'run');
-+    $run_cmb->addItem('run_per_host', 'run_per_host');
-+    $run_cmb->addItem('put', 'put');
-+    $run_cmb->addItem('get', 'get');
-+    $btns_div->addItem($run_cmb);
-+    $js = 'javascript: '; //javascript used to add runs under this sequence
-+    $js .= 'if (typeof window.counter'.$postfix.' === "undefined") 
window.counter'.$postfix.' = '.(count($xml->children())+1).';';
-+    $js .= 'new_node(jQuery("#runs'.$postfix.'").val(), 
"'.$postfix.'_"+counter'.$postfix.', "table'.$postfix.'", 
counter'.$postfix.'%2);';
-+    $js .= 'counter'.$postfix.'++;';
-+    $add_btn = new CButton('add', 'Add', $js);
-+    $btns_div->addItem($add_btn);
-+    //Move up
-+    $mvup_btn = new CButton('mvup', 'Move UP', 'javascript: 
p=jQuery("#row'.$postfix.'").prev(); if(p.attr("id")) 
jQuery("#row'.$postfix.'").insertBefore(p);');
-+    $btns_div->addItem($mvup_btn);
-+    //Move down
-+    $mvdown_btn = new CButton('mvdown', 'Move DOWN', 'javascript: 
n=jQuery("#row'.$postfix.'").next(); if(n.attr("id")) 
jQuery("#row'.$postfix.'").insertAfter(n);');
-+    $btns_div->addItem($mvdown_btn);
-+    
-+    $seq_tbl->addRow(array($del_btn, $btns_div));
-+    
-+    //Sequence attributes
-+    
-+    //Name attribute
-+    $name_tb = new CInput('text', 'name'.$postfix, (string)$xml['name']);
-+    $name_tb->addStyle('width: 50em;');
-+    $seq_tbl->addRow(array('Name:', $name_tb));
-+    
-+    //Enabled attribute
-+    $enabled_chb = new CCheckBox('enabled'.$postfix, 
(((string)$xml['enabled']) == 'false')?'no':'yes');
-+    $seq_tbl->addRow(array('Enabled:', $enabled_chb));
-+    
-+    
-+    $counter = 1;
-+    foreach($xml->children() as $c)
-+    {
-+        $name = trim($c->getName());
-+        $row_postfix = $postfix.'_'.$counter;
-+        $seq_tbl->addRow(tlview_parserun($name, $c, $row_postfix));
-+        $counter++;
-+    }
-+    
-+    //print "<script>var counter$postfix = $counter</script>";
-+    
-+    return new CRow(array('Sequence:', $seq_tbl), null, "row$postfix");
-+}
-+function tlview_parserun($type, $xml, $postfix)
-+{
-+    $run_tbl = new CTableInfo('');
-+    
-+    //common elements
-+    
-+    //Top Row:
-+    $btns_div = new CDiv();
-+    //Delete button
-+    $del_btn = new CButton('delete', 'delete', 'javascript: 
jQuery("#row'.$postfix.'").remove()');
-+    //Type (hidden)
-+    $type_hdn = new CInput('hidden', 'type'.$postfix, $type);
-+    $btns_div->addItem($type_hdn);
-+    //Move up
-+    $mvup_btn = new CButton('mvup', 'Move UP', 'javascript: 
p=jQuery("#row'.$postfix.'").prev(); if(p.attr("id")) 
jQuery("#row'.$postfix.'").insertBefore(p);');
-+    $btns_div->addItem($mvup_btn);
-+    //Move down
-+    $mvdown_btn = new CButton('mvdown', 'Move DOWN', 'javascript: 
n=jQuery("#row'.$postfix.'").next(); if(n.attr("id")) 
jQuery("#row'.$postfix.'").insertAfter(n);');
-+    $btns_div->addItem($mvdown_btn);
-+    
-+    $run_tbl->addRow(array($del_btn, $btns_div));
-+    
-+    //Name attribute
-+    $name_tb = new CInput('text', 'name'.$postfix, (string)$xml['name']);
-+    $name_tb->addStyle('width: 50em;');
-+    $run_tbl->addRow(array('Name:', $name_tb));
-+    
-+    //Enabled attribute
-+    $enabled_chb = new CCheckBox('enabled'.$postfix, 
(((string)$xml['enabled']) == 'false')?'no':'yes');
-+    $run_tbl->addRow(array('Enabled:', $enabled_chb));
-+    
-+    switch($type)
-+    {
-+        case 'run':
-+            //command
-+            $cmd_tb = new CInput('text', 'command'.$postfix, 
(string)$xml->command);
-+            $cmd_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Command:', $cmd_tb));
-+            
-+            //arguments
-+            $args_tb = new CInput('text', 'arguments'.$postfix, 
(string)$xml->arguments);
-+            $args_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Arguments:', $args_tb));
-+            
-+            //timeout
-+            $timeout_tb = new CInput('text', 'timeout'.$postfix, 
(string)$xml->timeout);
-+            $run_tbl->addRow(array('Timeout:', $timeout_tb));
-+            
-+            //expected_return_code
-+            $expected_return_code_tb = new CInput('text', 
'expected$return$code'.$postfix, (string)$xml->expected_return_code);
-+            $run_tbl->addRow(array('Expected Return Code:', 
$expected_return_code_tb));
-+            
-+            //expected_output
-+            $expected_output_tb = new CInput('text', 
'expected$output'.$postfix, (string)$xml->expected_output);
-+            $expected_output_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Expected Output:', $expected_output_tb));
-+            
-+            break;
-+        case 'run_per_host':
-+            //command_file
-+            $command_file_tb = new CInput('text', 'command$file'.$postfix, 
(string)$xml->command_file);
-+            $command_file_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Command File:', $command_file_tb));
-+            
-+            //output_prefix
-+            $output_prefix_tb = new CInput('text', 'output$prefix'.$postfix, 
(string)$xml->output_prefix);
-+            $output_prefix_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Output Prefix:', $output_prefix_tb));
-+            
-+            //timeout
-+            $timeout_tb = new CInput('text', 'timeout'.$postfix, 
(string)$xml->timeout);
-+            $run_tbl->addRow(array('Timeout:', $timeout_tb));
-+            
-+            //expected_return_code
-+            $expected_return_code_tb = new CInput('text', 
'expected$return$code'.$postfix, (string)$xml->expected_return_code);
-+            $run_tbl->addRow(array('Expected Return Code:', 
$expected_return_code_tb));
-+            
-+            //expected_output
-+            $expected_output_tb = new CInput('text', 
'expected$output'.$postfix, (string)$xml->expected_output);
-+            $expected_output_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Expected Output:', $expected_output_tb));
-+        
-+            break;
-+        case 'put':
-+            //source
-+            $userfiles = expfiles_getuserfiles();
-+            $selectedfile = '';
-+            if(!empty($xml->source)) $selectedfile = 
basename((string)$xml->source);
-+            $source_cmb = new CComboBox('source'.$postfix);
-+            foreach($userfiles as $uf)
-+                $source_cmb->addItem($uf, $uf, ($selectedfile == 
$uf)?'yes':null);
-+            $run_tbl->addRow(array('Source:', $source_cmb));
-+            
-+            //destination
-+            $destination_tb = new CInput('text', 'destination'.$postfix, 
(string)$xml->destination);
-+            $destination_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Destination:', $destination_tb));
-+        
-+            break;
-+        case 'get':
-+            //source
-+            $source_tb = new CInput('text', 'source'.$postfix, 
(string)$xml->source);
-+            $source_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Source:', $source_tb));
-+            
-+            //destination (removed because now all files should go to the 
user specific folder)
-+            /*$destination_tb = new CInput('text', 'destination'.$postfix, 
(string)$xml->destination);
-+            $destination_tb->addStyle('width: 50em;');
-+            $run_tbl->addRow(array('Destination:', $destination_tb));*/
-+            break;
-+    }
-+    
-+    //Stop on fail
-+    $stop_on_fail_chb = new CCheckBox('stop$on$fail'.$postfix, 
(((string)$xml->stop_on_fail) == 'false')?'no':'yes');
-+    $run_tbl->addRow(array('Stop on fail:', $stop_on_fail_chb));
-+    
-+    return new CRow(array("$type:", $run_tbl), null, "row$postfix");
-+    return $run_tbl;
-+}
-+
-+//print_r($xml);
-+
-+if($new)
-+    $main_frm = new CForm('post', 'tasklist.php?new=new');
-+else
-+    $main_frm = new CForm('post', 'tasklist.php?tid='.$tid);
-+$main_tbl = new CTableInfo('');
-+$main_tbl->attr('id', 'table_main');
-+
-+//Top Row:
-+$btns_div = new CDiv();
-+//'Add run' (all types)
-+$run_cmb = new CComboBox('run');
-+$run_cmb->attr('id', 'runs_main');
-+$run_cmb->addItem('sequence', 'sequence');
-+$run_cmb->addItem('run', 'run');
-+$run_cmb->addItem('run_per_host', 'run_per_host');
-+$run_cmb->addItem('put', 'put');
-+$run_cmb->addItem('get', 'get');
-+$btns_div->addItem($run_cmb);
-+$add_btn = new CButton('add', 'Add', "javascript: 
new_node(jQuery('#runs_main').val(), '_'+counter, 'table_main', counter%2); 
counter++;");
-+$btns_div->addItem($add_btn);
-+
-+$main_tbl->addRow(array('', $btns_div));
-+
-+//name attribute
-+$name_tb = new CInput('text', 'name', (string)$xml['name']);
-+$name_tb->addStyle('width: 50em;');
-+$main_tbl->addRow(array('Name:', $name_tb));
-+
-+//description
-+$desc_ta = new CTextArea('description', 
(empty($meta['description']))?'':$meta['description']);
-+$main_tbl->addRow(array('Description:', $desc_ta));
-+
-+//shared
-+$shared_chb = new CCheckBox('shared', (empty($meta['shared']))?'no':'yes');
-+$main_tbl->addRow(array('Shared:', $shared_chb));
-+
-+//option 1 - Target
-+/*$selected_target = 
isset($xml->options->target)?trim((string)$xml->options->target):'remote_ssh';
-+$target_cmb = new CComboBox('target');
-+foreach($targets as $t)
-+    $target_cmb->addItem($t, $t, ($selected_target == $t)?'yes':null);
-+$main_tbl->addRow(array('Target:', $target_cmb));*/
-+
-+//option 2 - Log dir
-+$log_dir = 
isset($xml->options->log_dir)?trim((string)$xml->options->log_dir):'';
-+$log_dir_tb = new CInput('text', 'log$dir', $log_dir);
-+$log_dir_tb->addStyle('width: 50em;');
-+$main_tbl->addRow(array('Log Dir:', $log_dir_tb));
-+
-+$counter = 1;
-+foreach($xml->children() as $c)
-+{
-+    $name = trim($c->getName());
-+    if($name == 'sequence')
-+    {
-+        $main_tbl->addRow(tlview_parseseq($c, '_'.$counter));
-+        $counter++;
-+    }
-+    elseif($name == 'run' || $name == 'run_per_host' || $name == 'put' || 
$name == 'get')
-+    {
-+        $main_tbl->addRow(tlview_parserun($name, $c, '_'.$counter));
-+        $counter++;
-+    }
-+}
-+
-+$main_frm->addItem($main_tbl);
-+
-+//$main_frm->addItem(new CInput('hidden', 'tid', $tid));
-+if($new)
-+    $main_frm->addItem(new CSubmit('add', 'Add'));
-+else
-+    $main_frm->addItem(new CSubmit('update', 'Update'));
-+
-+/*print "TESTING:<br/>";
-+$tmp = tlview_parserun('run', $default_run, '_100');
-+print $tmp->toString();
-+print "END TESTING";*/
-+
-+
-+?>
-+
-+<script>
-+var counter = <?=$counter?>;
-+
-+function new_node(type, postfix, table_id, parity)
-+{
-+var html = '';
-+switch(type)
-+{
-+case 'sequence':
-+html = '<?php print tlview_parseseq($exptasklist_defaults["sequence"], 
"%placeholder%"); ?>';
-+break;
-+case 'run':
-+html = '<?php print tlview_parserun("run", $exptasklist_defaults["run"], 
"%placeholder%"); ?>';
-+break;
-+case 'run_per_host':
-+html = '<?php print tlview_parserun("run_per_host", 
$exptasklist_defaults["run_per_host"], "%placeholder%"); ?>';
-+break;
-+case 'put':
-+html = '<?php print tlview_parserun("put", $exptasklist_defaults["put"], 
"%placeholder%"); ?>';
-+break;
-+case 'get':
-+html = '<?php print tlview_parserun("get", $exptasklist_defaults["get"], 
"%placeholder%"); ?>';
-+break;
-+}
-+
-+html = html.replace(/%placeholder%/g, postfix);
-+jQuery('#'+table_id).append(html);
-+var cl = (parity == 0)?'even_row':'odd_row';
-+jQuery('#row'+postfix).addClass(cl);
-+jQuery('#row'+postfix).attr('origclass', cl);
-+jQuery('#name'+postfix).focus();
-+}
-+
-+</script>
-+
-+<?php
-+
-+return $main_frm;
-diff --git a/zabbix/frontends/php/include/views/experiments.tasklist.php 
b/zabbix/frontends/php/include/views/experiments.tasklist.php
-new file mode 100644
-index 0000000..e6e0ed8
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/experiments.tasklist.php
-@@ -0,0 +1,41 @@
-+<?php
-+
-+$tasklists = $this->get('tasklists');
-+
-+$tlWidget = new CWidget();
-+
-+$createForm = new CForm('get');
-+$createForm->addItem(new CSubmit('new', 'Create tasklist'));
-+
-+$tlWidget->addPageHeader('CONFIGURATION OF TASKLISTS', $createForm);
-+
-+//main form
-+$tlForm = new CForm('get');
-+$tlForm->setName('tasklistForm');
-+
-+//main table
-+$tlTable = new CTableInfo('No tasklists defined.');
-+$tlTable->setHeader(array('Name', 'Description', 'User', 'Shared', ''));
-+
-+foreach($tasklists as $tl)
-+{
-+    //Name link
-+    $name_lnk = new CLink($tl['name'], '?tid='.$tl['tasklistid']);
-+    
-+    //Delete link
-+    $del_btn = new CButtonDelete('Are you sure you want to delete this 
tasklist?', $tl['tasklistid']);
-+    
-+    $tlTable->addRow(array(
-+        $name_lnk,
-+        ($tl['description'])?$tl['description']:'',
-+        $tl['username'],
-+        ($tl['shared'])?'Yes':'No',
-+        $del_btn
-+        ));
-+}
-+
-+$tlForm->addItem($tlTable);
-+
-+$tlWidget->addItem($tlForm);
-+
-+return $tlWidget;
-diff --git 
a/zabbix/frontends/php/include/views/general.script.execute-parallel.php 
b/zabbix/frontends/php/include/views/general.script.execute-parallel.php
-new file mode 100644
-index 0000000..4bc5aca
---- /dev/null
-+++ b/zabbix/frontends/php/include/views/general.script.execute-parallel.php
-@@ -0,0 +1,54 @@
-+<?php
-+/*
-+** Zabbix
-+** Copyright (C) 2000-2011 Zabbix SIA
-+**
-+** This program is free software; you can redistribute it and/or modify
-+** it under the terms of the GNU General Public License as published by
-+** the Free Software Foundation; either version 2 of the License, or
-+** (at your option) any later version.
-+**
-+** This program 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 General Public License for more details.
-+**
-+** You should have received a copy of the GNU General Public License
-+** along with this program; if not, write to the Free Software
-+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
-+**/
-+
-+
-+//javascript item
-+$js = new CJSscript();
-+
-+$numHosts = count($this->data['hosts']);
-+
-+$js->addItem("<div id=\"counter\" 
style=\"font-size:20px;padding:5px;\">0/$numHosts</div>");
-+$js->addItem("<div id=\"content\"></div>");
-+$js->addItem("<script type=\"text/javascript\" 
src=\"js/jquery/jquery.js\"></script>");
-+$js->addItem("<script type=\"text/javascript\">");
-+$js->addItem("var hosts = new Array();");
-+$js->addItem("var ctr = 0;");
-+
-+for($i = 0; $i < $numHosts; $i++)
-+{
-+    $host = $this->data['hosts'][$i];
-+    $js->addItem("hosts[$i] = ".$host['hostid'].";");
-+}
-+
-+$sid = $this->data['sid'];
-+$scriptid = $this->data['scriptid'];
-+$js->addItem("for(var i=0;i<$numHosts;i++){
-+    $.ajax({
-+    url: 
\"scripts_exec.php?sid=$sid&execute=1&scriptid=$scriptid&strip=1&hostid=\"+hosts[i],
-+    async: true,
-+    success: function(data) { $('#content').append(data); ctr++; 
$('#counter').html(ctr+'/$numHosts') }
-+    });
-+}");
-+
-+
-+//$js->addItem();
-+$js->addItem("</script>");
-+
-+return $js;
-diff --git a/zabbix/frontends/php/include/views/general.script.execute.php 
b/zabbix/frontends/php/include/views/general.script.execute.php
-index 5f8d2f6..19eaec8 100644
---- a/zabbix/frontends/php/include/views/general.script.execute.php
-+++ b/zabbix/frontends/php/include/views/general.script.execute.php
-@@ -27,8 +27,17 @@ $scriptForm->setName('scriptForm');
- 
- // append tabs to form
- $scriptTab = new CTabView();
--$scriptTab->addTab('scriptTab', _s('Result of "%s"', 
$this->data['info']['name']), new CSpan($this->data['message'], 'pre 
fixedfont'));
-+$body = new CSpan($this->data['message'],'pre fixedfont');
-+if(isset($this->data['error']))
-+{
-+    $body = new CList(null, "messages");
-+    $body->addItem(new CListItem($this->data['error'], "error"));
-+}
-+
-+//    $scriptTab->addTab('errorTab', _s('ERROR'), new 
CSpan($this->data['error'], 'pre fixedfont'));
-+$scriptTab->addTab('scriptTab', _s('Result of "%s" ON 
'.$this->data['host']['name'], $this->data['info']['name']), $body);
- $scriptForm->addItem($scriptTab);
- 
- $scriptWidget->addItem($scriptForm);
-+$scriptWidget->addItem(BR());
- return $scriptWidget;
-diff --git a/zabbix/frontends/php/js/main.js b/zabbix/frontends/php/js/main.js
-index 4f14d4d..2bceabb 100644
---- a/zabbix/frontends/php/js/main.js
-+++ b/zabbix/frontends/php/js/main.js
-@@ -103,7 +103,7 @@ var PageRefresh = {
-  * Main menu
-  */
- var MMenu = {
--      menus:                  {'empty': 0, 'view': 0, 'cm': 0, 'reports': 0, 
'config': 0, 'admin': 0},
-+      menus:                  {'empty': 0, 'view': 0, 'cm': 0, 'reports': 0, 
'config': 0, 'admin': 0, 'experiment':0},
-       def_label:              null,
-       sub_active:     false,
-       timeout_reset:  null,
-diff --git a/zabbix/frontends/php/manage_monitoring.php 
b/zabbix/frontends/php/manage_monitoring.php
-new file mode 100644
-index 0000000..a01bbfa
---- /dev/null
-+++ b/zabbix/frontends/php/manage_monitoring.php
-@@ -0,0 +1,61 @@
-+<?php
-+/*
-+** Zabbix
-+** Copyright (C) 2000-2011 Zabbix SIA
-+**
-+** This program is free software; you can redistribute it and/or modify
-+** it under the terms of the GNU General Public License as published by
-+** the Free Software Foundation; either version 2 of the License, or
-+** (at your option) any later version.
-+**
-+** This program 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 General Public License for more details.
-+**
-+** You should have received a copy of the GNU General Public License
-+** along with this program; if not, write to the Free Software
-+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
-+**/
-+
-+require_once 'include/config.inc.php';
-+require_once 'include/hosts.inc.php';
-+require_once 'include/items.inc.php';
-+require_once 'include/forms.inc.php';
-+
-+$page['title'] = _('Manage Monitoring');
-+$page['file'] = 'manage_monitoring.php';
-+
-+define('ZBX_PAGE_NO_MENU', 1);
-+
-+// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
-+$fields = array(
-+      'template'      =>      array(T_ZBX_INT,        O_OPT,  P_SYS,          
DB_ID,  true),
-+      'action'                =>      array(T_ZBX_STR,        O_OPT,  
NOT_EMPTY,      null,   true),
-+);
-+check_fields($fields);
-+
-+$templates = array_keys($_REQUEST['template']);
-+
-+//fetch template
-+$options = array(
-+      'templateids' => $templates,
-+      'selectItems' => array(),
-+      'output' => array('name')
-+);
-+$templates = API::Template()->get($options);
-+
-+//pull all item ids in array
-+$all_items = array();
-+foreach($templates as $temp)
-+{
-+      foreach($temp['items'] as $item)
-+              $all_items[] = $item['itemid'];
-+}
-+
-+//perform action
-+DBstart();
-+$go_result = ($_REQUEST['action'] == 
'disable')?disable_item($all_items):activate_item($all_items);
-+$go_result = DBend($go_result);
-+
-+jsRedirect('dashboard.php');
-diff --git a/zabbix/frontends/php/results.php 
b/zabbix/frontends/php/results.php
-new file mode 100644
-index 0000000..6cf8a87
---- /dev/null
-+++ b/zabbix/frontends/php/results.php
-@@ -0,0 +1,101 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('Experiment Results');
-+$page['file'] = 'results.php';
-+$page['hist_arg'] = array('resid');
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
-+$fields = array(
-+    'runid' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
-+    'hostid' =>   array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
-+    'delete' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
-+    'interrupt' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null),
-+    'rerun' =>    array(T_ZBX_INT, O_OPT, P_SYS|P_ACT, null, null)
-+);
-+check_fields($fields);
-+
-+/*
-+ * Actions
-+ */
-+
-+if(isset($_REQUEST['delete']))
-+{
-+    if(exprun_checkpermission($_REQUEST['delete']))
-+    {
-+        exprun_delete($_REQUEST['delete']);    
-+        jsRedirect('results.php');
-+    }
-+    else
-+        error("No permission to delete.");
-+}
-+
-+if(isset($_REQUEST['interrupt']))
-+{
-+    if(exprun_checkpermission($_REQUEST['interrupt']))
-+    {
-+        exprun_interrupt($_REQUEST['interrupt']);
-+        jsRedirect('results.php');
-+    }
-+    else
-+        error("No permission to interrupt.");
-+}
-+
-+if(isset($_REQUEST['rerun']))
-+{
-+    if(exprun_checkpermission($_REQUEST['rerun']))
-+    {
-+        exprun_rerun($_REQUEST['rerun']);
-+        jsRedirect('results.php');
-+    }
-+    else
-+        error("No permission to rerun.");
-+}
-+
-+/*
-+ * Display
-+ */
-+$resView = new CView('experiments.results');
-+
-+$results = exprun_getall(true);
-+$resView->set('results', $results);
-+
-+if(isset($_REQUEST['runid']))
-+{
-+    if(exprun_verifyid($_REQUEST['runid']))
-+    {
-+        foreach($results as $r) //get the specific run that we want to 
display the log for
-+        {
-+            if($r['runid'] == $_REQUEST['runid'])
-+            {
-+                $run = $r;
-+                break;
-+            }
-+        }
-+        
-+        $sep = 
"\n=================================================================\n";
-+        $log = '';
-+        foreach($run['nodes'] as $n)
-+        {
-+            if(isset($_REQUEST['hostid']) && $n['hostid'] == 
$_REQUEST['hostid']) //print the log of only a specific host
-+            {
-+                $log = $n['log'];
-+                break;
-+            }
-+            else
-+                $log .= $n['log'].$sep;
-+        }
-+        
-+        $resView->set('log', $log);
-+        $resView->set('runid', $run['runid']);
-+    }
-+}
-+
-+$resView->render();
-+$resView->show();
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/frontends/php/scripts_exec.php 
b/zabbix/frontends/php/scripts_exec.php
-index d40b5a0..94775ee 100644
---- a/zabbix/frontends/php/scripts_exec.php
-+++ b/zabbix/frontends/php/scripts_exec.php
-@@ -27,23 +27,28 @@ $page['file'] = 'scripts_exec.php';
- 
- define('ZBX_PAGE_NO_MENU', 1);
- 
--require_once ('include/page_header.php');
-+$strip = isset($_REQUEST['strip']);
-+if(!$strip)
-+    require_once ('include/page_header.php');
- 
- // VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
- $fields = array(
--      'hostid' =>             array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'isset({execute})'),
-+      'hostid' =>             array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'!isset({groupid})&&!isset({hosts})'),
-       'scriptid' =>   array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,           
'isset({execute})'),
-+      'groupid' =>    array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,       
'!isset({hostid})&&!isset({hosts})'),
-+      'hosts' =>              array(T_ZBX_INT, O_OPT, P_SYS, DB_ID,       
'!isset({hostid})&&!isset({groupid})'),
-       'execute' =>    array(T_ZBX_INT, O_OPT, P_ACT, IN('0,1'),       null)
- );
- check_fields($fields);
- 
--if (isset($_REQUEST['execute'])) {
--      $scriptid = get_request('scriptid');
--      $hostid = get_request('hostid');
--
--      $data = array(
-+function execute_script($scriptid, $hostid)
-+{
-+    global $strip;
-+    
-+    $data = array(
-               'message' => '',
--              'info' => DBfetch(DBselect('SELECT s.name FROM scripts s WHERE 
s.scriptid='.$scriptid))
-+              'info' => DBfetch(DBselect('SELECT s.name FROM scripts s WHERE 
s.scriptid='.$scriptid)),
-+              'host' => DBfetch(DBselect('SELECT h.name FROM hosts h WHERE 
h.hostid='.$hostid))
-       );
- 
-       $result = API::Script()->execute(array('hostid' => $hostid, 'scriptid' 
=> $scriptid));
-@@ -53,8 +58,10 @@ if (isset($_REQUEST['execute'])) {
-               $isErrorExist = true;
-       }
-       elseif ($result['response'] == 'failed') {
--              error($result['value']);
--              $isErrorExist = true;
-+          if($strip) $data['error'] = $result['value'];
-+              else
-+                  error($result['value']);
-+          $isErrorExist = true;
-       }
-       else {
-               $data['message'] = $result['value'];
-@@ -70,4 +77,46 @@ if (isset($_REQUEST['execute'])) {
-       $scriptView->show();
- }
- 
--require_once 'include/page_footer.php';
-+if (isset($_REQUEST['execute'])) {
-+      $scriptid = get_request('scriptid');
-+      
-+      if(isset($_REQUEST['groupid']) || isset($_REQUEST['hosts']))
-+      {
-+              if(isset($_REQUEST['groupid']))
-+              {
-+                      $groupid = get_request('groupid');
-+                      
-+                      $hosts = API::Host()->get(array(
-+                              'groupids' => array($groupid),
-+                              'editable' => 1,
-+                              'output' => API_OUTPUT_EXTEND
-+                      ));
-+              }
-+              else
-+              {
-+                      $hosts = API::Host()->get(array(
-+                              'hostids' => get_request('hosts'),
-+                              'editable' => 1,
-+                              'output' => API_OUTPUT_EXTEND
-+                      ));
-+              }
-+              
-+              $data = array();
-+              $data['hosts'] = $hosts;
-+              $data['scriptid'] = $scriptid;
-+              $data['sid'] = get_request('sid');
-+              
-+              $scriptView = new CView('general.script.execute-parallel', 
$data);
-+      $scriptView->render();
-+      $scriptView->show();
-+              
-+      }
-+      elseif(isset($_REQUEST['hostid']))
-+      {
-+          $hostid = get_request('hostid');
-+      execute_script($scriptid, $hostid);
-+      }
-+}
-+
-+if(!$strip)
-+    require_once 'include/page_footer.php';
-diff --git a/zabbix/frontends/php/targets.php 
b/zabbix/frontends/php/targets.php
-new file mode 100644
-index 0000000..0d5e121
---- /dev/null
-+++ b/zabbix/frontends/php/targets.php
-@@ -0,0 +1,50 @@
-+<?php
-+
-+error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('Target Configuration');
-+$page['file'] = 'targets.php';
-+$page['hist_arg'] = array('targetid');
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+/*
-+ * Actions
-+ */
-+//print_r($_REQUEST);
-+
-+if(isset($_REQUEST['target']) && isset($_REQUEST['apply']))
-+{
-+    switch($_REQUEST['target'])
-+    {
-+        case 'ssh':
-+            if(isset($_REQUEST['sshhosts']))
-+                expssh_updatehosts($_REQUEST['sshhosts']);
-+        
-+            break;
-+        
-+        case 'planetlab':
-+            if(isset($_REQUEST['plnodes']) && is_array($_REQUEST['plnodes']))
-+                exppl_updateSliceNodes($_REQUEST['plnodes']);
-+            break;
-+    }
-+}
-+
-+/*
-+ * Display
-+ */
-+$targetsView = new CView('experiments.targets');
-+
-+$targetsView->set('targetlist', $exp_targetlist);
-+if(isset($_REQUEST['target'])) $targetsView->set('selected_target', 
$_REQUEST['target']);
-+$targetsView->set('sshhosts', expnodes_gethosts('ssh'));
-+if(isset($_REQUEST['ploffset'])) $targetsView->set('ploffset', 
$_REQUEST['ploffset']);
-+if(isset($_REQUEST['plfilter']) && trim($_REQUEST['plfilter']) != '') 
$targetsView->set('plfilter', $_REQUEST['plfilter']);
-+
-+$targetsView->render();
-+$targetsView->show();
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/frontends/php/tasklist.php 
b/zabbix/frontends/php/tasklist.php
-new file mode 100644
-index 0000000..fa43c0d
---- /dev/null
-+++ b/zabbix/frontends/php/tasklist.php
-@@ -0,0 +1,104 @@
-+<?php
-+
-+require_once dirname(__FILE__).'/include/config.inc.php';
-+require_once dirname(__FILE__).'/include/experiments/inc.php';
-+
-+$page['title'] = _('Tasklists');
-+$page['file'] = 'tasklist.php';
-+$page['hist_arg'] = array('taskid');
-+
-+require_once dirname(__FILE__).'/include/page_header.php';
-+
-+// VAR        TYPE    OPTIONAL        FLAGS   VALIDATION      EXCEPTION
-+/*$fields = array(
-+      'tid' =>                array(T_ZBX_INT, O_OPT, P_SYS, null, null),
-+);
-+check_fields($fields);*/
-+
-+
-+/*
-+ * Actions
-+ */
-+if(isset($_REQUEST['tid']) && isset($_REQUEST['update']))
-+{
-+    $tid = intval($_REQUEST['tid']);
-+    if(exptasklist_allowed($tid) == 2) //check user permission (read/write)
-+        exptasklist_update($tid, $_REQUEST);
-+    else
-+        error("Permission denied!");
-+}
-+if(isset($_REQUEST['add']))
-+{
-+    if(exptasklist_add($_REQUEST))
-+        jsRedirect('tasklist.php');
-+}
-+if(isset($_REQUEST['delete']))
-+{
-+    $tid = intval(substr($_REQUEST['delete'], 1));
-+    
-+    if(exptasklist_allowed($tid) == 2)
-+    {
-+        if(exptasklist_delete($tid))
-+            jsRedirect('tasklist.php');
-+    }
-+    else
-+        error("Permission denied!");
-+}
-+
-+
-+/*
-+ * Display
-+ */
-+if(isset($_REQUEST['tid']))
-+{
-+    $tid = intval($_REQUEST['tid']);
-+    if(exptasklist_allowed($tid) > 0) //check user permission (read or 
read/write)
-+    {
-+        //Get tasklist metadata
-+        $meta = exptasklist_getbyid($tid);
-+        //Get tasklist XML content
-+        $xml = exptasklist_getcontent($tid);
-+        if($xml)
-+        {
-+            $tlView = new CView('experiments.tasklist.edit');
-+
-+            $tlView->set('tid', $tid);
-+            $tlView->set('xml', simplexml_load_string($xml));
-+            //$tlView->set('targets', exp_gettargets());
-+            $tlView->set('meta', $meta);
-+            $tlView->set('exptasklist_defaults', $exptasklist_defaults);
-+            $tlView->set('userfiles', expfiles_getuserfiles());
-+
-+            $tlView->render();
-+            $tlView->show();
-+
-+        }
-+        else
-+            error("Error while loading tasklist!");
-+    }
-+    else
-+        error("Permission denied!");
-+}
-+elseif(isset($_REQUEST['new']))
-+{
-+    $tlView = new CView('experiments.tasklist.edit');
-+    
-+    $tlView->set('new', true);
-+    //$tlView->set('targets', exp_gettargets());
-+    $tlView->set('exptasklist_defaults', $exptasklist_defaults);
-+    $tlView->set('userfiles', expfiles_getuserfiles());
-+    
-+    $tlView->render();
-+    $tlView->show();
-+}
-+else
-+{
-+    $tlView = new CView('experiments.tasklist');
-+    
-+    $tlView->set('tasklists', exptasklist_getall(true));
-+    
-+    $tlView->render();
-+    $tlView->show();
-+}
-+
-+require_once dirname(__FILE__).'/include/page_footer.php';
-diff --git a/zabbix/zabbix.sql b/zabbix/zabbix.sql
-new file mode 100644
-index 0000000..7e43628
---- /dev/null
-+++ b/zabbix/zabbix.sql
-@@ -0,0 +1,139 @@
-+-- phpMyAdmin SQL Dump
-+-- version 3.4.11.1deb2
-+-- http://www.phpmyadmin.net
-+--
-+-- Host: localhost
-+-- Generation Time: Sep 26, 2013 at 04:39 PM
-+-- Server version: 5.5.31
-+-- PHP Version: 5.4.4-14+deb7u4
-+
-+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-+SET time_zone = "+00:00";
-+
-+
-+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-+/*!40101 SET NAMES utf8 */;
-+
-+--
-+-- Database: `zabbix`
-+--
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_config`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_config` (
-+  `configid` int(11) NOT NULL AUTO_INCREMENT,
-+  `section` varchar(100) COLLATE utf8_bin NOT NULL,
-+  `name` varchar(200) COLLATE utf8_bin NOT NULL,
-+  `label` varchar(100) COLLATE utf8_bin NOT NULL,
-+  `description` text COLLATE utf8_bin,
-+  `type` varchar(100) COLLATE utf8_bin NOT NULL,
-+  `default_value` varchar(500) COLLATE utf8_bin NOT NULL,
-+  `user_editable` tinyint(1) NOT NULL,
-+  PRIMARY KEY (`configid`)
-+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=29 ;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_configenum`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_configenum` (
-+  `id` int(11) NOT NULL AUTO_INCREMENT,
-+  `configid` int(11) NOT NULL,
-+  `label` text COLLATE utf8_bin NOT NULL,
-+  `value` text COLLATE utf8_bin NOT NULL,
-+  PRIMARY KEY (`id`)
-+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_host`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_host` (
-+  `hostid` int(11) NOT NULL AUTO_INCREMENT,
-+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
-+  `userid` int(11) NOT NULL,
-+  `host` text COLLATE utf8_bin NOT NULL,
-+  `pl_nodeid` int(11) DEFAULT NULL,
-+  PRIMARY KEY (`hostid`,`target`)
-+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1580 ;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_run`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_run` (
-+  `runid` int(11) NOT NULL AUTO_INCREMENT,
-+  `startedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-+  `usetasklist` tinyint(1) NOT NULL DEFAULT '1',
-+  `tasklistid` int(11) DEFAULT NULL,
-+  `command` varchar(200) COLLATE utf8_bin DEFAULT NULL,
-+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
-+  `pid` int(11) DEFAULT NULL,
-+  `userid` int(11) NOT NULL,
-+  `status` int(11) NOT NULL DEFAULT '0',
-+  `percentage` double NOT NULL DEFAULT '0',
-+  `fullcommand` text COLLATE utf8_bin,
-+  PRIMARY KEY (`runid`)
-+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=75 ;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_runnode`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_runnode` (
-+  `runid` int(11) NOT NULL,
-+  `hostid` int(11) NOT NULL,
-+  `target` varchar(200) COLLATE utf8_bin NOT NULL,
-+  `status` int(11) NOT NULL DEFAULT '0',
-+  `percentage` double NOT NULL DEFAULT '0',
-+  `log` text COLLATE utf8_bin NOT NULL,
-+  PRIMARY KEY (`runid`,`hostid`,`target`)
-+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_tasklist`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_tasklist` (
-+  `tasklistid` int(11) NOT NULL AUTO_INCREMENT,
-+  `name` varchar(100) COLLATE utf8_bin NOT NULL,
-+  `description` text COLLATE utf8_bin,
-+  `fsname` varchar(100) COLLATE utf8_bin NOT NULL,
-+  `userid` int(11) NOT NULL,
-+  `shared` tinyint(1) NOT NULL,
-+  PRIMARY KEY (`tasklistid`)
-+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=24 ;
-+
-+-- --------------------------------------------------------
-+
-+--
-+-- Table structure for table `exp_userconfig`
-+--
-+
-+CREATE TABLE IF NOT EXISTS `exp_userconfig` (
-+  `configid` int(11) NOT NULL,
-+  `userid` int(11) NOT NULL,
-+  `value` varchar(500) COLLATE utf8_bin NOT NULL,
-+  `enabled` tinyint(1) NOT NULL,
-+  PRIMARY KEY (`configid`,`userid`)
-+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-+
-+/*!40101 SET address@hidden */;
-+/*!40101 SET address@hidden */;
-+/*!40101 SET address@hidden */;

Modified: eclectic/installation-guide.tex
===================================================================
--- eclectic/installation-guide.tex     2014-04-22 11:29:18 UTC (rev 33121)
+++ eclectic/installation-guide.tex     2014-04-22 16:03:10 UTC (rev 33122)
@@ -200,7 +200,7 @@
 \begin{lstlisting}
 $ cd
 $ sudo chqrp -R www-data gplmt/
-$ wget http://gnunet.org/zabbix/diff.tar.gz
+$ wget http://gnunet.org/eclectic/diff.tar.gz
 $ tar xvzf diff.tar.gz
 $ mysql -u<username> -p<password> zabbix < gplmt-gui/schema.sql # Replace 
<username> and <password>
 $ mysql -u<username> -p<password> zabbix < data.sql




reply via email to

[Prev in Thread] Current Thread [Next in Thread]