[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r33105 - in eclectic: . gplmt-ui
From: |
gnunet |
Subject: |
[GNUnet-SVN] r33105 - in eclectic: . gplmt-ui |
Date: |
Thu, 17 Apr 2014 11:25:12 +0200 |
Author: wachs
Date: 2014-04-17 11:25:12 +0200 (Thu, 17 Apr 2014)
New Revision: 33105
Added:
eclectic/gplmt-ui/
eclectic/gplmt-ui/README
eclectic/gplmt-ui/zabbix.diff
Log:
diff for web ui
Added: eclectic/gplmt-ui/README
===================================================================
--- eclectic/gplmt-ui/README (rev 0)
+++ eclectic/gplmt-ui/README 2014-04-17 09:25:12 UTC (rev 33105)
@@ -0,0 +1,4 @@
+GPLMT Web UI
+============
+
+This is a diff which has to be applied against Zabbix version 2.2
\ No newline at end of file
Added: eclectic/gplmt-ui/zabbix.diff
===================================================================
--- eclectic/gplmt-ui/zabbix.diff (rev 0)
+++ eclectic/gplmt-ui/zabbix.diff 2014-04-17 09:25:12 UTC (rev 33105)
@@ -0,0 +1,3212 @@
+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').' »', '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 */;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r33105 - in eclectic: . gplmt-ui,
gnunet <=