Merge branch 'ent-11830-reemplazar-sistema-de-websocket-gotty-actual' into 'develop'

11830 adding package preparation for rpm gotty

See merge request artica/pandorafms!6462
This commit is contained in:
Rafael Ameijeiras 2023-10-10 13:32:20 +00:00
commit b2019fad9a
30 changed files with 1724 additions and 718 deletions

1
extras/pandora_gotty/.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
src/pandora_gotty filter=lfs diff=lfs merge=lfs -text

2
extras/pandora_gotty/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.rpm
*.deb

View File

@ -0,0 +1,8 @@
FROM rockylinux:8
RUN dnf install -y rpm-build rpmdevtools
RUN rpmdev-setuptree
RUN mkdir /root/pandora_gotty
WORKDIR /root/pandora_gotty
#CMD bash build.sh

View File

@ -0,0 +1,6 @@
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y dh-make debhelper build-essential
RUN mkdir /root/pandora_gotty
WORKDIR /root/pandora_gotty

View File

@ -0,0 +1 @@
To create the .deb and .rpm package need to hace docker installed on main system and execit `build_all_docker.sh`

View File

@ -0,0 +1,11 @@
#Build RPM
docker build -t pandora_gotty_builder_rpm -f Dockerfile-RPM . || exit 1
docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_rpm /root/pandora_gotty/build_rpm.sh || exit 1
#Buikd DEB
docker build -t pandora_gotty_builder_deb -f Dockerfile-deb . || exit 1
docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_deb /root/pandora_gotty/build_deb.sh || exit 1
echo " - Done"
pwd
ls -l | grep -E "(\.deb|\.rpm)"

View File

@ -0,0 +1,17 @@
#!/bin/bash
#DEB
cd deb
VERSION=$(grep 'Version:' pandora_gotty/DEBIAN/control | awk '{print $2}')
mkdir -p pandora_gotty/usr/bin
mkdir -p pandora_gotty/etc/pandora_gotty
cp -a ../src/pandora_gotty pandora_gotty/usr/bin
cp -a ../src/pandora_gotty.conf pandora_gotty/etc/pandora_gotty
curl -SsL --output pandora_gotty/usr/bin/pandora_gotty_exec http://192.168.50.31/installers/installers/Linux/x86_64/pandora_gotty_exec
chmod +x pandora_gotty/usr/bin/pandora_gotty_exec
dpkg-deb --build pandora_gotty
mv pandora_gotty.deb ../
rm -rf pandora_gotty/usr/
rm -rf pandora_gotty/etc/
cd ..
mv pandora_gotty.deb pandora_gotty_${VERSION}.deb
chmod 777 pandora_gotty_${VERSION}.deb

View File

@ -0,0 +1,15 @@
#!/bin/bash
#RPM
VERSION=$(grep '%define version' pandora_gotty.spec | awk '{print $3}')
mkdir -p pandora_gotty-${VERSION}
cp src/pandora_gotty pandora_gotty-${VERSION}/
cp src/pandora_gotty.conf pandora_gotty-${VERSION}/
curl -SsL --output pandora_gotty-${VERSION}/pandora_gotty_exec http://192.168.50.31/installers/installers/Linux/x86_64/pandora_gotty_exec
chmod +x pandora_gotty-${VERSION}/pandora_gotty_exec
tar -cvzf pandora_gotty-${VERSION}.tar.gz pandora_gotty-${VERSION}/*
mv pandora_gotty-${VERSION}.tar.gz ${HOME}/rpmbuild/SOURCES/
rm -rf ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty*
rpmbuild -ba pandora_gotty.spec
rm -rf pandora_gotty-${VERSION}
mv ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* .
chmod 777 *.rpm

3
extras/pandora_gotty/deb/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.deb
**/usr
**/etc

View File

@ -0,0 +1,5 @@
pandora_gotty (1.0-1) stable; urgency=low
* Initial release.
-- PandoraFMS Mon, 18 Sep 2023 00:00:00 +0000

View File

@ -0,0 +1,9 @@
Source: pandora_gotty
Section: utils
Version: 1.0.0
Priority: optional
Maintainer: PandoraFMS
Build-Depends: debhelper (>= 12)
Package: pandora-gotty
Architecture: amd64
Description: pandora_gotty for Pandora FMS.

View File

@ -0,0 +1,41 @@
%define name pandora_gotty
%define version 1.0
%define release 1%{?dist}
Summary: pandora_gptty for Pandora FMS
Name: %{name}
Version: %{version}
Release: %{release}
License: GPL
Vendor: PandoraFMS
Source0: %{name}-%{version}.tar.gz
URL: https://pandorafms.com
Group: System/Monitoring
Packager: PandoraFMS
BuildArch: x86_64
Provides: %{name}-%{version}
%description
pandora_gotty for Pandora FMS.
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
mkdir -p %{buildroot}/etc/pandora_gotty/
cp %{name} $RPM_BUILD_ROOT/%{_bindir}
cp pandora_gotty_exec $RPM_BUILD_ROOT/%{_bindir}
cp pandora_gotty.conf %{buildroot}/etc/pandora_gotty/
%clean
rm -Rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%config(noreplace) /etc/pandora_gotty/pandora_gotty.conf
%{_bindir}/%{name}
%{_bindir}/pandora_gotty_exec
%changelog
* Mon Sep 18 2023 PandoraFMS - 1.0-1
- Initial RPM release

2
extras/pandora_gotty/src/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*rpm
bin/*

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3758eddb64db79c6ea1dac4cb200ee8ec86ef3f51723dad5be4365a1315b952b
size 13642854

View File

@ -0,0 +1,29 @@
//Pandora Gotty config file
// [bool] Permit clients to write to the TTY
permit_write = true
// [bool] Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB)
permit_arguments = true
// [bool] Enable random URL generation
enable_random_url = true
// [int] Default length of random strings appended to URL
// To enable random URL generation, set `true` to `enable_random_url`
random_url_length = 32
// [bool] Enable TLS/SSL
// enable_tls = false
// [string] Default TLS certificate file path
// tls_crt_file = "~/.gotty.crt"
// [string] Default TLS key file path
// tls_key_file = "~/.gotty.key"
// [bool] Enable client certificate authentication
// enable_tls_client_auth = false
// [string] Certificate file of CA for client certificates
// tls_ca_crt_file = "~/.gotty.ca.crt"

View File

@ -0,0 +1,110 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "PandoraFMS Team"
__copyright__ = "Copyright 2023, PandoraFMS"
#__credits__ = ["Rob Knight", "Peter Maxwell", "Gavin Huttley", "Matthew Wakefield"]
__maintainer__ = "Projects/QA department"
__status__ = "Prod"
__version__ = "1.0"
import sys, argparse, signal, re, datetime, subprocess
info= f"""
SSH and TELNET helper for pandora_gotty.
Version: {__version__}
"""
parser = argparse.ArgumentParser(description= info, formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('exec_cmd',
help='Aplication to be executed, avalibles: ssh or telnet',type=str, choices=['ssh', 'telnet'])
parser.add_argument('address',
help='IP addres or dns name to connect', type=str, default="")
parser.add_argument('port',
help='Port to connect', type=int, default=23)
parser.add_argument('user',
help='Username, only requiered for ssh connection', type=str, default="", nargs='?')
args = parser.parse_args()
# Define a function to handle the SIGINT signal
def sigint_handler(signal, frame):
print ('\nInterrupted by user', file=sys.stderr)
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
# Define a function to handle the SIGTERM signal
def sigterm_handler(signum, frame):
print("Received SIGTERM signal.", file=sys.stderr)
sys.exit(0)
signal.signal(signal.SIGTERM, sigterm_handler)
# Functions
def is_valid_add(add:str):
# Regular expression to match an IP address
ip_pattern = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
# Regular expression to match a DNS name (domain name)
dns_pattern = r'^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if re.match(ip_pattern, add) or re.match(dns_pattern, add):
return True
else:
print(f"Error not valid address: {add}", file=sys.stderr)
return False
def is_valid_username(username:str):
# Regular expression to match a valid Linux username
username_pattern = r'^[a-zA-Z_][a-zA-Z0-9_]{0,31}$'
if re.match(username_pattern, username) is not None:
return True
else:
print(f"Error not valid username: {username}", file=sys.stderr)
return False
def exec_ssh (user:str, add:str, port:int):
# Previus checks
if is_valid_username(user) == False:
return False
if is_valid_add(add) == False:
return False
if port == 0 :
return False
try:
print("> Starting SSH connection...")
ssh_command = f"ssh {user}@{add} -p {port}"
subprocess.run(ssh_command, shell=True)
except subprocess.CalledProcessError as e:
raise SystemExit(e)
return True
def exec_telnet (add:str, port:int):
# Previus checks
if is_valid_add(add) == False:
return False
try:
print("> Starting Telnet connection...")
ssh_command = f"telnet -E {add} {port}"
subprocess.run(ssh_command, shell=True)
except subprocess.CalledProcessError as e:
raise SystemExit(e)
return True
# Main
if __name__ == "__main__":
if args.exec_cmd == "ssh":
exec_ssh(args.user, args.address, args.port)
print ("> ssh session finished")
sys.exit(0)
if args.exec_cmd == "telnet":
exec_telnet(args.address, args.port)
print ("> telnet session finished")
sys.exit(0)
sys.exit(0)

31
pandora_console/cron.php Normal file
View File

@ -0,0 +1,31 @@
<?php
require_once 'include/config.php';
require_once 'include/auth/mysql.php';
require_once 'include/functions.php';
require_once 'include/functions_db.php';
global $config;
if ((bool) $config['enterprise_installed'] === true) {
return;
}
// Load classes.
require_once 'include/class/DiscoveryConsoleTask.php';
require_once 'include/class/ConsoleSupervisor.php';
db_process_sql_update(
'tconfig',
['value' => get_system_time()],
['token' => 'cron_last_run']
);
$tasks = new DiscoveryConsoleTask();
$tasks->run();
if (is_reporting_console_node() === true) {
$supervisor = new ConsoleSupervisor();
$supervisor->run();
}

View File

@ -31,6 +31,7 @@ global $config;
require_once $config['homedir'].'/include/functions_agents.php';
require_once $config['homedir'].'/godmode/wizards/Wizard.main.php';
require_once $config['homedir'].'/include/functions_cron_task.php';
/**
@ -78,91 +79,78 @@ function quickShell()
return;
}
$form_sent = get_parameter('form-sent', false);
$method = get_parameter('method', null);
$setup_anchor = html_print_anchor(
[
'href' => 'index.php?sec=gsetup&sec2=godmode/setup/setup&section=quickshell',
'content' => __('GoTTY setup'),
],
true
);
if ((bool) $config['gotty_ssh_enabled'] === false
&& (bool) $config['gotty_telnet_enabled'] === false
) {
ui_print_warning_message(__('Please, enable GoTTY in %s', $setup_anchor));
return;
}
$agent_id = get_parameter('id_agente', 0);
$username = get_parameter('username', null);
$method = get_parameter('method', null);
$method_port = get_parameter('port', null);
// Retrieve main IP Address.
$address = agents_get_address($agent_id);
$agent_address = agents_get_address($agent_id);
ui_require_css_file('wizard');
ui_require_css_file('discovery');
// Settings.
// WebSocket host, where client should connect.
if (isset($config['ws_port']) === false) {
config_update_value('ws_port', 8080);
// Build URL args.
if ($method === 'ssh') {
// SSH.
$args .= '&arg='.$agent_address.'&arg='.$method_port.'&arg='.$username;
} else if ($method == 'telnet') {
// Telnet.
$args .= '&arg='.$agent_address.'&arg='.$method_port;
}
if (empty($config['ws_proxy_url']) === true) {
$ws_url = 'http://'.$_SERVER['SERVER_ADDR'].':'.$config['ws_port'];
} else {
preg_match('/\/\/(.*)/', $config['ws_proxy_url'], $matches);
if (isset($_SERVER['HTTPS']) === true) {
$ws_url = 'https://'.$matches[1];
} else {
$ws_url = 'http://'.$matches[1];
}
}
// Gotty settings. Internal communication (WS).
if (isset($config['gotty_host']) === false) {
config_update_value('gotty_host', '127.0.0.1');
}
if (isset($config['gotty_telnet_port']) === false) {
config_update_value('gotty_telnet_port', 8082);
}
if (isset($config['gotty_ssh_port']) === false) {
config_update_value('gotty_ssh_port', 8081);
}
// Context to allow self-signed certs.
$context = stream_context_create(
[
'http' => [ 'method' => 'GET'],
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]
);
$connectionURL = buildConnectionURL($method);
$gotty_addr = $connectionURL.$args;
// Username. Retrieve from form.
if (empty($username) === true) {
if ($form_sent === false) {
// No username provided, ask for it.
$wiz = new Wizard();
$test = curl($ws_url, []);
if ($test === false) {
ui_print_error_message(__('WebService engine has not been started, please check documentation.'));
$wiz->printForm(
[
'form' => [
'method' => 'POST',
'action' => '#',
'id' => 'retry_form',
],
]
);
$method_fields = [];
html_print_action_buttons(
html_print_submit_button(
__('Retry'),
'submit',
false,
[
'icon' => 'next',
'form' => 'retry_form',
],
true
)
);
return;
if ($config['gotty_telnet_enabled']) {
$method_fields['telnet'] = __('Telnet');
$port_value = 23;
}
if ($config['gotty_ssh_enabled']) {
$method_fields['ssh'] = __('SSH');
$port_value = 22;
}
$method_script = "
var wizard = document.querySelector('.wizard');
p=22;
wizard.querySelector('ul > li').classList.remove('invisible_important');
wizard.querySelector('ul > li').classList.add('visible');
if(this.value == 'telnet') {
p=23;
wizard.querySelector('ul > li').classList.remove('visible');
wizard.querySelector('ul > li').classList.add('invisible_important');
$('#text-username').prop('required', false);
} else {
$('#text-username').prop('required', true);
}
$('#text-port').val(p);";
$wiz->printForm(
[
'form' => [
@ -175,8 +163,9 @@ function quickShell()
[
'label' => __('Username'),
'arguments' => [
'type' => 'text',
'name' => 'username',
'type' => 'text',
'name' => 'username',
'required' => true,
],
],
[
@ -185,7 +174,7 @@ function quickShell()
'type' => 'text',
'id' => 'port',
'name' => 'port',
'value' => 22,
'value' => $port_value,
],
],
[
@ -193,13 +182,17 @@ function quickShell()
'arguments' => [
'type' => 'select',
'name' => 'method',
'fields' => [
'ssh' => __('SSH'),
'telnet' => __('Telnet'),
],
'script' => "p=22; if(this.value == 'telnet') { p=23; } $('#text-port').val(p);",
'fields' => $method_fields,
'script' => $method_script,
],
],
[
'arguments' => [
'type' => 'hidden',
'name' => 'form-sent',
'value' => true,
],
]
],
],
false,
@ -221,119 +214,71 @@ function quickShell()
return;
}
// Initialize Gotty Client.
$host = $config['gotty_host'];
if ($method == 'ssh') {
// SSH.
$port = $config['gotty_ssh_port'];
$command_arguments = "var args = '?arg=".$username.'@'.$address;
$command_arguments .= '&arg=-p '.$method_port."';";
} else if ($method == 'telnet') {
// Telnet.
$port = $config['gotty_telnet_port'];
$username = preg_replace('/[^a-zA-Z0-9\-\.]/', '', $username);
$command_arguments = "var args = '?arg=-l ".$username;
$command_arguments .= '&arg='.$address;
$command_arguments .= '&arg='.$method_port."&arg=-E';";
} else {
ui_print_error_message(__('Please use SSH or Telnet.'));
return;
// Check gotty connection before trying to load iframe.
$ch = curl_init($gotty_addr);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Maximum time for the entire request.
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
// Maximum time to establish a connection.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
$response = curl_exec($ch);
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
if ($responseCode !== 200) {
ui_print_error_message(__('Connection error. Please check your settings at %s', $setup_anchor));
exit;
}
// If rediretion is enabled, we will try to connect using
// http:// or https:// endpoint.
$test = get_headers($ws_url, false, $context);
if ($test === false) {
if (empty($wiz) === true) {
$wiz = new Wizard();
}
ui_print_error_message(__('WebService engine has not been started, please check documentation.'));
echo $wiz->printGoBackButton('#');
return;
}
// Check credentials.
$auth_str = '';
$gotty_url = $host.':'.$port;
if (empty($config['gotty_user']) === false
&& empty($config['gotty_pass']) === false
) {
$auth_str = io_safe_output($config['gotty_user']);
$auth_str .= ':'.io_output_password($config['gotty_pass']);
$gotty_url = $auth_str.'@'.$host.':'.$port;
}
$r = file_get_contents('http://'.$gotty_url.'/js/hterm.js');
if (empty($r) === true) {
if (empty($wiz) === true) {
$wiz = new Wizard();
}
ui_print_error_message(__('WebService engine is not working properly, please check documentation.'));
echo $wiz->printGoBackButton('#');
return;
}
// Override gotty client settings.
if (empty($auth_str) === true) {
$r .= "var gotty_auth_token = '';";
} else {
$r .= "var gotty_auth_token = '";
$r .= $auth_str."';";
}
// Set websocket target and method.
$gotty = file_get_contents('http://'.$gotty_url.'/js/gotty.js');
$url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';";
if (empty($config['ws_proxy_url']) === true) {
$new = "var url = (httpsEnabled ? 'wss://' : 'ws://')";
$new .= " + window.location.host + ':";
$new .= $config['ws_port'].'/'.$method."';";
} else {
$new = "var url = '";
$new .= $config['ws_proxy_url'].'/'.$method."';";
}
// Update firefox issue.
$original = ' this.iframe_.src = \'#\';';
$trick = 'this.iframe_.src = \'javascript:\';';
$r = str_replace($original, $trick, $r);
// Update url.
$gotty = str_replace($url, $new, $gotty);
// Update websocket arguments.
$args = 'var args = window.location.search;';
$new = $command_arguments;
// Update arguments.
$gotty = str_replace($args, $new, $gotty);
?>
<style>#terminal {
height: 650px;
width: 100%;
margin: 0px;
padding: 0;
display: flex;
flex-direction: column;
min-height: calc(100vh - 205px);
}
#terminal > iframe {
width:100%;
height:100%;
position: relative!important;
flex-grow: 1;
border: 0px;
}
</style>
<div id="terminal"></div>
<script type="text/javascript">
<?php echo $r; ?>
</script>
<script type="text/javascript">
<?php echo $gotty; ?>
</script>
<div id="terminal"><iframe id="gotty-iframe" src="<?php echo $gotty_addr; ?>"></iframe></div>
<?php
}
/**
* Build Connection URL based on provided connection method.
*
* @param string $method Connection method (SSH/Telnet).
*
* @return string
*/
function buildConnectionURL($method)
{
global $config;
$address = (empty($config['gotty_addr']) === true) ? $_SERVER['SERVER_ADDR'] : $config['gotty_addr'];
$use_ssl = ($method === 'ssh') ? $config['gotty_ssh_use_ssl'] : $config['gotty_telnet_use_ssl'];
$protocol = ((bool) $use_ssl === true) ? 'https://' : 'http://';
return $protocol.$address.':'.$config['gotty_port'].'/'.$config['gotty_connection_hash'].'/?arg='.$method;
}
/**
* Provide an interface where configure all settings.
*
@ -347,116 +292,108 @@ function quickShellSettings()
ui_require_css_file('discovery');
// Gotty settings. Internal communication (WS).
if (isset($config['gotty_ssh_enabled']) === false) {
config_update_value('gotty_ssh_enabled', 1);
}
if (isset($config['gotty_telnet_enabled']) === false) {
config_update_value('gotty_telnet_enabled', 0);
}
if (isset($config['gotty_host']) === false) {
config_update_value('gotty_host', '127.0.0.1');
}
if (isset($config['gotty_telnet_port']) === false) {
config_update_value('gotty_telnet_port', 8082);
if (isset($config['gotty_port']) === false) {
config_update_value('gotty_port', 8080);
}
if (isset($config['gotty_ssh_port']) === false) {
config_update_value('gotty_ssh_port', 8081);
}
$changes = 0;
$critical = 0;
// Parser.
if (get_parameter('update_config', false) !== false) {
// Gotty settings. Internal communication (WS).
$gotty = get_parameter(
'gotty',
''
$gotty_ssh_enabled = get_parameter(
'gotty_ssh_enabled',
0
);
$gotty_host = get_parameter(
'gotty_host',
''
$gotty_telnet_enabled = get_parameter(
'gotty_telnet_enabled',
0
);
$gotty_ssh_port = get_parameter(
'gotty_ssh_port',
''
);
$gotty_telnet_port = get_parameter(
'gotty_telnet_port',
$gotty_addr = get_parameter(
'gotty_addr',
''
);
$gotty_user = get_parameter(
'gotty_user',
$gotty_port = get_parameter(
'gotty_port',
''
);
$gotty_pass = get_parameter(
'gotty_pass',
''
$gotty_ssh_use_ssl = get_parameter(
'gotty_ssh_use_ssl',
false
);
$gotty_pass = io_input_password($gotty_pass);
$gotty_telnet_use_ssl = get_parameter(
'gotty_telnet_use_ssl',
false
);
$changes = 0;
$critical = 0;
if ($config['gotty'] != $gotty) {
config_update_value('gotty', $gotty);
$changes++;
$critical++;
if ($config['gotty_ssh_enabled'] != $gotty_ssh_enabled) {
config_update_value('gotty_ssh_enabled', $gotty_ssh_enabled);
}
if ($config['gotty_host'] != $gotty_host) {
config_update_value('gotty_host', $gotty_host);
$changes++;
if ($config['gotty_telnet_enabled'] != $gotty_telnet_enabled) {
config_update_value('gotty_telnet_enabled', $gotty_telnet_enabled);
}
if ($config['gotty_telnet_port'] != $gotty_telnet_port) {
config_update_value('gotty_telnet_port', $gotty_telnet_port);
$changes++;
if ($config['gotty_addr'] != $gotty_addr) {
config_update_value('gotty_addr', $gotty_addr);
}
if ($config['gotty_ssh_port'] != $gotty_ssh_port) {
config_update_value('gotty_ssh_port', $gotty_ssh_port);
$changes++;
if ($config['gotty_port'] != $gotty_port) {
// Mark gotty for restart (should kill the process in the current port).
if ($config['restart_gotty_next_cron_port'] === ''
|| $config['restart_gotty_next_cron_port'] === null
) {
config_update_value('restart_gotty_next_cron_port', $config['gotty_port']);
}
config_update_value('gotty_port', $gotty_port);
}
if ($config['gotty_user'] != $gotty_user) {
config_update_value('gotty_user', $gotty_user);
$changes++;
$critical++;
if ($config['gotty_ssh_use_ssl'] != $gotty_ssh_use_ssl) {
config_update_value('gotty_ssh_use_ssl', $gotty_ssh_use_ssl);
}
if ($config['gotty_pass'] != $gotty_pass) {
$gotty_pass = io_input_password($gotty_pass);
config_update_value('gotty_pass', $gotty_pass);
$changes++;
$critical++;
if ($config['gotty_telnet_use_ssl'] != $gotty_telnet_use_ssl) {
config_update_value('gotty_telnet_use_ssl', $gotty_telnet_use_ssl);
}
cron_task_start_gotty();
}
if ($changes > 0) {
$msg = __('%d Updated', $changes);
if ($critical > 0) {
$msg = __(
'%d Updated, please restart WebSocket engine service',
$changes
);
}
ui_print_success_message($msg);
}
// Form. Using old style.
echo '<fieldset class="margin-bottom-10">';
echo '<legend>'.__('Quickshell').'</legend>';
echo '<legend>'.__('GoTTY general parameters').'</legend>';
$t = new StdClass();
$t->data = [];
$t->width = '100%';
$t->class = 'filter-table-adv';
$t->data = [];
$t->style = [];
$t->style[0] = 'width: 50%;';
$general_table = new StdClass();
$general_table->data = [];
$general_table->width = '100%';
$general_table->class = 'filter-table-adv';
$general_table->data = [];
$general_table->style = [];
$general_table->style[0] = 'width: 50%;';
$t->data[0][] = html_print_label_input_block(
__('Gotty path'),
$general_table->data[0][] = html_print_label_input_block(
__('Address'),
html_print_input_text(
'gotty',
$config['gotty'],
'gotty_addr',
$config['gotty_addr'],
'',
30,
100,
@ -464,11 +401,11 @@ function quickShellSettings()
)
);
$t->data[0][] = html_print_label_input_block(
__('Gotty host'),
$general_table->data[0][] = html_print_label_input_block(
__('Port'),
html_print_input_text(
'gotty_host',
$config['gotty_host'],
'gotty_port',
$config['gotty_port'],
'',
30,
100,
@ -476,79 +413,154 @@ function quickShellSettings()
)
);
$t->data[1][] = html_print_label_input_block(
__('Gotty ssh port'),
html_print_input_text(
'gotty_ssh_port',
$config['gotty_ssh_port'],
'',
30,
100,
html_print_table($general_table);
echo '</fieldset>';
echo '<fieldset class="margin-bottom-10">';
echo '<legend>'.__('GoTTY SSH connection parameters').'</legend>';
$ssh_table = new StdClass();
$ssh_table->data = [];
$ssh_table->width = '100%';
$ssh_table->class = 'filter-table-adv';
$ssh_table->data = [];
$ssh_table->style = [];
$ssh_table->style[0] = 'width: 50%;';
$ssh_table->data[0][] = html_print_label_input_block(
__('Enable SSH method'),
html_print_checkbox_switch(
'gotty_ssh_enabled',
1,
$config['gotty_ssh_enabled'],
true
)
);
$t->data[1][] = html_print_label_input_block(
__('Gotty telnet port'),
html_print_input_text(
'gotty_telnet_port',
$config['gotty_telnet_port'],
'',
30,
100,
true
$ssh_table->data[1][] = html_print_label_input_block(
__('Use SSL'),
html_print_checkbox_switch(
'gotty_ssh_use_ssl',
1,
$config['gotty_ssh_use_ssl'],
true,
$disable_agentaccess
)
);
$hidden = new stdClass();
$hidden->data = [];
$hidden->width = '100%';
$hidden->class = 'filter-table-adv';
$hidden->data = [];
$hidden->style[0] = 'width: 50%;';
// Test.
$row = [];
$test_start = '<span id="test-gotty-spinner-ssh" class="invisible">&nbsp;'.html_print_image('images/spinner.gif', true).'</span>';
$test_start .= '&nbsp;<span id="test-gotty-message-ssh" class="invisible"></span>';
$hidden->data[0][] = html_print_label_input_block(
__('Gotty user'),
html_print_input_text(
'gotty_user',
$config['gotty_user'],
'',
30,
100,
true
)
);
$hidden->data[0][] = html_print_label_input_block(
__('Gotty password'),
html_print_input_password(
'gotty_pass',
io_output_password($config['gotty_pass']),
'',
30,
100,
true
)
);
html_print_table($t);
ui_print_toggle(
$ssh_table->data[3][] = html_print_button(
__('Test'),
'test-gotty-ssh',
false,
'handleTestSSH()',
[
'content' => html_print_table($hidden, true),
'name' => __('Advanced options'),
'clean' => false,
'main_class' => 'no-border-imp',
'container_class' => 'no-border-imp',
]
);
'icon' => 'cog',
'mode' => 'secondary',
'style' => 'width: 115px;',
],
true
).$test_start;
html_print_table($ssh_table);
echo '</fieldset>';
echo '<fieldset class="margin-bottom-10">';
echo '<legend>'.__('GoTTY telnet connection parameters').'</legend>';
$telnet_table = new StdClass();
$telnet_table->data = [];
$telnet_table->width = '100%';
$telnet_table->class = 'filter-table-adv';
$telnet_table->data = [];
$telnet_table->style = [];
$telnet_table->style[0] = 'width: 50%;';
$telnet_table->data[0][] = html_print_label_input_block(
__('Enable telnet method'),
html_print_checkbox_switch(
'gotty_telnet_enabled',
1,
$config['gotty_telnet_enabled'],
true
)
);
$telnet_table->data[1][] = html_print_label_input_block(
__('Use SSL'),
html_print_checkbox_switch(
'gotty_telnet_use_ssl',
1,
$config['gotty_telnet_use_ssl'],
true
)
);
// Test.
$row = [];
$test_start = '<span id="test-gotty-spinner-telnet" class="invisible">&nbsp;'.html_print_image('images/spinner.gif', true).'</span>';
$test_start .= '&nbsp;<span id="test-gotty-message-telnet" class="invisible"></span>';
$telnet_table->data[3][] = html_print_button(
__('Test'),
'test-gotty-telnet',
false,
'handleTestTelnet()',
[
'icon' => 'cog',
'mode' => 'secondary',
'style' => 'width: 115px;',
],
true
).$test_start;
html_print_table($telnet_table);
html_print_input_hidden('update_config', 1);
echo '</fieldset>';
}
// This extension is usefull only if the agent has associated IP.
if (is_ajax() === true) {
$method = (string) get_parameter('method', '');
if (empty($method) === false) {
$address = buildConnectionURL($method);
$ch = curl_init($address);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Maximum time for the entire request.
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
// Maximum time to establish a connection.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
curl_exec($ch);
$response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response_code === 200) {
$result = ['status' => 'success'];
} else {
$result = ['status' => 'error'];
}
echo json_encode($result);
return;
}
$result = ['status' => 'error'];
return;
}
// This extension is useful only if the agent has associated IP.
$agent_id = get_parameter('id_agente');
if (empty($agent_id) === false
&& get_parameter('sec2', '') == 'operation/agentes/ver_agente'
@ -573,4 +585,136 @@ if (empty($agent_id) === false
}
}
echo '<script>';
echo 'var server_addr = "'.$_SERVER['SERVER_ADDR'].'";';
echo "function checkAddressReachability(method, callback) {
$.ajax({
url: 'ajax.php',
data: {
page: 'extensions/quick_shell',
method
},
type: 'GET',
async: false,
dataType: 'json',
success: function (data) {
if (data.status === 'success') {
callback(true);
} else {
callback(false);
}
},
error: function () {
callback(false);
}
});
}";
$handle_test_telnet = "var handleTestTelnet = function (event) {
var gotty_addr = $('input#text-gotty_addr').val();
var gotty_port = $('input#text-gotty_port').val();
var gotty_telnet_use_ssl = $('input#checkbox-gotty_telnet_use_ssl').is(':checked');
if (gotty_addr === '') {
url = (gotty_telnet_use_ssl ? 'https://' : 'http://') + server_addr + ':' + gotty_port;
} else {
url = (gotty_telnet_use_ssl ? 'https://' : 'http://') + gotty_addr + ':' + gotty_port;
}
var showLoadingImage = function () {
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon cog rotation secondary mini');
}
var showSuccessImage = function () {
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon tick secondary mini');
}
var showFailureImage = function () {
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon fail secondary mini');
}
var hideMessage = function () {
$('span#test-gotty-message-telnet').hide();
}
var showMessage = function () {
$('span#test-gotty-message-telnet').show();
}
var changeTestMessage = function (message) {
$('span#test-gotty-message-telnet').text(message);
}
var errorMessage = '".__('Unable to connect.')."';
hideMessage();
showLoadingImage();
checkAddressReachability('telnet', function(isReachable) {
if (isReachable) {
showSuccessImage();
hideMessage();
} else {
showFailureImage();
changeTestMessage(errorMessage);
showMessage();
}
});
};";
$handle_test_ssh = "var handleTestSSH = function (event) {
var gotty_addr = $('input#text-gotty_addr').val();
var gotty_port = $('input#text-gotty_port').val();
var gotty_ssh_use_ssl = $('input#checkbox-gotty_ssh_use_ssl').is(':checked');
if (gotty_addr === '') {
url = (gotty_ssh_use_ssl ? 'https://' : 'http://') + server_addr + ':' + gotty_port;
} else {
url = (gotty_ssh_use_ssl ? 'https://' : 'http://') + gotty_addr + ':' + gotty_port;
}
var showLoadingImage = function () {
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon cog rotation secondary mini');
}
var showSuccessImage = function () {
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon tick secondary mini');
}
var showFailureImage = function () {
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon fail secondary mini');
}
var hideMessage = function () {
$('span#test-gotty-message-ssh').hide();
}
var showMessage = function () {
$('span#test-gotty-message-ssh').show();
}
var changeTestMessage = function (message) {
$('span#test-gotty-message-ssh').text(message);
}
var errorMessage = '".__('Unable to connect.')."';
hideMessage();
showLoadingImage();
checkAddressReachability('ssh', function(isReachable) {
if (isReachable) {
showSuccessImage();
hideMessage();
} else {
showFailureImage();
changeTestMessage(errorMessage);
showMessage();
}
});
};";
echo $handle_test_ssh;
echo $handle_test_telnet;
echo '</script>';
extensions_add_godmode_function('quickShellSettings');

View File

@ -1708,6 +1708,7 @@ enterprise/godmode/wizards/Cloud.class.php
enterprise/images/wizard/applications.png
enterprise/images/wizard/cloud.png
enterprise/images/wizard/consoletasks.png
pandora_websocket_engine
operation/incidents/configure_integriaims_incident.php
operation/incidents/dashboard_detail_integriaims_incident.php
operation/incidents/incident_statistics.php

View File

@ -486,8 +486,8 @@ if ($access_console_node === true) {
$sub2['godmode/setup/setup&section=notifications']['text'] = __('Notifications');
$sub2['godmode/setup/setup&section=notifications']['refr'] = 0;
$sub2['godmode/setup/setup&section=websocket_engine']['text'] = __('Websocket Engine');
$sub2['godmode/setup/setup&section=websocket_engine']['refr'] = 0;
$sub2['godmode/setup/setup&section=quickshell']['text'] = __('QuickShell');
$sub2['godmode/setup/setup&section=quickshell']['refr'] = 0;
$sub2['godmode/setup/setup&section=external_tools']['text'] = __('External Tools');
$sub2['godmode/setup/setup&section=external_tools']['refr'] = 0;

View File

@ -221,13 +221,13 @@ $buttons['notifications'] = [
).'</a>',
];
$buttons['websocket_engine'] = [
$buttons['quickshell'] = [
'active' => false,
'text' => '<a href="'.ui_get_full_url('index.php?sec=gsetup&sec2=godmode/setup/setup&section=websocket_engine').'">'.html_print_image(
'text' => '<a href="'.ui_get_full_url('index.php?sec=gsetup&sec2=godmode/setup/setup&section=quickshell').'">'.html_print_image(
'images/websocket_small.png',
true,
[
'title' => __('Websocket engine'),
'title' => __('QuickShell'),
'class' => 'invert_filter',
]
).'</a>',
@ -325,9 +325,9 @@ switch ($section) {
$subpage = __('Notifications');
break;
case 'websocket_engine':
$buttons['websocket_engine']['active'] = true;
$subpage = __('Pandora Websocket Engine');
case 'quickshell':
$buttons['quickshell']['active'] = true;
$subpage = __('QuickShell');
$help_header = 'quickshell_settings';
break;
@ -454,8 +454,8 @@ switch ($section) {
include_once $config['homedir'].'/godmode/setup/setup_notifications.php';
break;
case 'websocket_engine':
include_once $config['homedir'].'/godmode/setup/setup_websocket_engine.php';
case 'quickshell':
include_once $config['homedir'].'/godmode/setup/setup_quickshell.php';
break;
case 'external_tools':

View File

@ -0,0 +1,53 @@
<?php
/**
* Settings for Pandora Websocket engine.
*
* @category UI file
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* 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 for version 2.
* 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.
* ============================================================================
*/
global $config;
$url = ui_get_full_url(
'index.php?sec=gsetup&sec2=godmode/setup/setup&amp;section=quickshell&amp;pure='.$config['pure']
);
echo '<form class="max_floating_element_size" id="form_setup" method="post" action="'.$url.'">';
if (function_exists('quickShellSettings') === true) {
quickShellSettings();
}
$action_btns = html_print_submit_button(
__('Update'),
'update_button',
false,
[ 'icon' => 'update' ],
true
);
html_print_action_buttons(
$action_btns
);
echo '</form>';

View File

@ -1,195 +0,0 @@
<?php
/**
* Settings for Pandora Websocket engine.
*
* @category UI file
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* 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 for version 2.
* 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.
* ============================================================================
*/
global $config;
$url = ui_get_full_url(
'index.php?sec=gsetup&sec2=godmode/setup/setup&amp;section=websocket_engine&amp;pure='.$config['pure']
);
echo '<form class="max_floating_element_size" id="form_setup" method="post" action="'.$url.'">';
echo '<fieldset class="margin-bottom-10">';
echo '<legend>'.__('WebSocket settings').'</legend>';
$t = new StdClass();
$t->data = [];
$t->width = '100%';
$t->class = 'databox filter-table-adv';
$t->data = [];
$t->data[0][] = html_print_label_input_block(
__('Bind address'),
html_print_input_text(
'ws_bind_address',
$config['ws_bind_address'],
'',
30,
100,
true
)
);
$t->data[0][] = html_print_label_input_block(
__('Bind port'),
html_print_input_text(
'ws_port',
$config['ws_port'],
'',
30,
100,
true
)
);
$t->data[1][] = html_print_label_input_block(
__('WebSocket proxy url'),
html_print_input_text(
'ws_proxy_url',
$config['ws_proxy_url'],
'',
30,
100,
true
)
);
html_print_input_hidden('update_config', 1);
// Test.
$row = [];
$test_start = '<span id="test-gotty-spinner" class="invisible">&nbsp;'.html_print_image('images/spinner.gif', true).'</span>';
$test_start .= '&nbsp;<span id="test-gotty-message" class="invisible"></span>';
$row['gotty_test'] = html_print_label_input_block(
__('Test connection'),
html_print_button(
__('Test'),
'test-gotty',
false,
'handleTest()',
[
'icon' => 'cog',
'mode' => 'secondary mini',
'style' => 'width: 115px;',
],
true
).$test_start,
['div_class' => 'inline_flex row']
);
$t->data['gotty_test'] = $row;
html_print_table($t);
echo '</fieldset>';
if (function_exists('quickShellSettings') === true) {
quickShellSettings();
}
html_print_action_buttons(
html_print_submit_button(
__('Update'),
'update_button',
false,
[ 'icon' => 'update' ],
true
)
);
echo '</form>';
echo '<script>';
echo 'var server_addr = "'.$_SERVER['SERVER_ADDR'].'";';
$handle_test_js = "var handleTest = function (event) {
var ws_proxy_url = $('input#text-ws_proxy_url').val();
var ws_port = $('input#text-ws_port').val();
var httpsEnabled = window.location.protocol == 'https' ? true : false;
if (ws_proxy_url == '') {
ws_url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + ':' + ws_port;
} else {
ws_url = ws_proxy_url;
}
var showLoadingImage = function () {
$('#button-test-gotty').children('div').attr('class', 'subIcon cog rotation secondary mini');
}
var showSuccessImage = function () {
$('#button-test-gotty').children('div').attr('class', 'subIcon tick secondary mini');
}
var showFailureImage = function () {
$('#button-test-gotty').children('div').attr('class', 'subIcon fail secondary mini');
}
var hideMessage = function () {
$('span#test-gotty-message').hide();
}
var showMessage = function () {
$('span#test-gotty-message').show();
}
var changeTestMessage = function (message) {
$('span#test-gotty-message').text(message);
}
var errorMessage = '".__('WebService engine has not been started, please check documentation.')."';
hideMessage();
showLoadingImage();
var ws = new WebSocket(ws_url);
// Catch errors.
ws.onerror = () => {
showFailureImage();
changeTestMessage(errorMessage);
showMessage();
ws.close();
};
ws.onopen = () => {
showSuccessImage();
hideMessage();
ws.close();
};
ws.onclose = (event) => {
changeTestMessage(errorMessage);
hideLoadingImage();
showMessage();
};
}
$('#button-test-ehorus').click(handleTest);";
echo $handle_test_js;
echo '</script>';

View File

@ -160,10 +160,9 @@ class DiscoveryTaskList extends HTML
return $this->enableTask();
}
if (enterprise_installed()) {
// This check only applies to enterprise users.
enterprise_hook('tasklist_checkrunning');
enterprise_hook('tasklist_checkrunning');
if (enterprise_installed()) {
$ret = $this->showListConsoleTask();
} else {
$ret = false;

View File

@ -200,9 +200,7 @@ class ConsoleSupervisor
* NOTIF.CRON.CONFIGURED
*/
if (enterprise_installed()) {
$this->checkCronRunning();
}
$this->checkCronRunning();
/*
* Check if instance is registered.
@ -501,9 +499,7 @@ class ConsoleSupervisor
* NOTIF.CRON.CONFIGURED
*/
if (enterprise_installed()) {
$this->checkCronRunning();
}
$this->checkCronRunning();
/*
* Check if instance is registered.
@ -2651,14 +2647,20 @@ class ConsoleSupervisor
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
$message_conf_cron .= __('Discovery relies on an appropriate cron setup.');
$message_conf_cron .= '. '.__('Please, add the following line to your crontab file:');
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * &lt;user&gt; wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
$message_conf_cron .= str_replace(
ENTERPRISE_DIR.'/meta/',
'',
ui_get_full_url(false)
);
$message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
$message_conf_cron .= '/cron/cron.php &gt;&gt; </pre>';
if (enterprise_installed()) {
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * &lt;user&gt; wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
$message_conf_cron .= str_replace(
ENTERPRISE_DIR.'/meta/',
'',
ui_get_full_url(false)
);
$message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
$message_conf_cron .= '/cron/cron.php &gt;&gt; </pre>';
} else {
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * &lt;user&gt; wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
$message_conf_cron .= ui_get_full_url(false).'cron.php &gt;&gt; </pre>';
}
$message_conf_cron .= $config['homedir'].'/log/cron.log</pre>';
}

View File

@ -0,0 +1,345 @@
<?php
/**
* Extension to schedule tasks on Pandora FMS Console
*
* @category Extensions
* @package Pandora FMS
* @subpackage Enterprise
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* 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 for version 2.
* 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.
* ============================================================================
*/
if ((bool) $config['enterprise_installed'] === true) {
enterprise_include_once('/include/functions_cron.php');
} else {
include_once $config['homedir'].'/include/functions_cron_task.php';
}
/**
* Base class to run scheduled tasks in cron extension
*/
class DiscoveryConsoleTask
{
public const SCHEDULES = [
'no',
'hourly',
'daily',
'weekly',
'monthly',
'yearly',
'custom',
];
/**
* Retrieve scheduled tasks given filters.
*
* @param array $filter Tasks filtered.
*
* @return array List of scheduled tasks.
*/
public function list(array $filter)
{
$tasks = db_get_all_rows_filter(
'tuser_task_scheduled INNER JOIN tuser_task ON tuser_task.id = tuser_task_scheduled.id_user_task',
$filter,
'tuser_task_scheduled.*'
);
if ($tasks === false) {
return [];
}
$tasks = array_map(
function ($item) {
$item['args'] = unserialize($item['args']);
return $item;
},
$tasks
);
return $tasks;
}
/**
* Should execute task.
*
* @param array $task Info task.
*
* @return boolean
*/
private function shouldTaskRun($task)
{
global $config;
if (isset($config['reporting_console_enable']) === true
&& (bool) $config['reporting_console_enable'] === true
) {
$task_info = db_get_row('tuser_task', 'id', $task['id_user_task']);
if (isset($config['reporting_console_node']) === true
&& (bool) $config['reporting_console_node'] === true
) {
if (($task_info['function_name'] !== 'cron_task_generate_report_by_template'
&& $task_info['function_name'] !== 'cron_task_generate_report'
&& $task_info['function_name'] !== 'cron_task_save_report_to_disk')
) {
return false;
}
} else {
if (($task_info['function_name'] === 'cron_task_generate_report_by_template'
|| $task_info['function_name'] === 'cron_task_generate_report'
|| $task_info['function_name'] === 'cron_task_save_report_to_disk')
) {
return false;
}
}
}
return true;
}
/**
* Manage scheduled tasks.
*
* @return void
*/
public function run()
{
global $config;
global $pandora_version;
// Maintenance tasks for tconsole table.
// Must do at every Cron execution.
if (isset($config['id_console']) === true && $config['id_console'] > 0) {
$console_exists = db_get_row('tconsole', 'id_console', $config['id_console']);
if ($console_exists === false) {
db_process_sql_insert(
'tconsole',
[
'id_console' => $config['id_console'],
'description' => $config['console_description'],
'version' => $pandora_version,
'console_type' => ($config['reporting_console_node'] === true) ? 1 : 0,
'timezone' => $config['timezone'],
'public_url' => $config['public_url'],
]
);
} else {
db_process_sql_update(
'tconsole',
[
'description' => $config['console_description'],
'timezone' => $config['timezone'],
'public_url' => $config['public_url'],
'console_type' => (int) $config['reporting_console_node'],
'version' => $pandora_version,
],
[
'id_console' => $config['id_console'],
]
);
}
}
// Maintenance task: schedule daily task to manage GoTTY processes if not defined yet.
// Must do at every Cron execution.
$gotty_ssh_enabled = (bool) $config['gotty_ssh_enabled'];
$gotty_telnet_enabled = (bool) $config['gotty_telnet_enabled'];
if ($gotty_ssh_enabled === true || $gotty_telnet_enabled === true) {
// Create necessary data in task tables when some method of GoTTY is enabled in setup.
if ((bool) $config['enterprise_installed'] === false) {
$call_func_user_task_id = db_get_value_sql('SELECT id FROM `tuser_task` WHERE `function_name` = "cron_task_call_user_function"');
if ($call_func_user_task_id === false) {
db_process_sql("INSERT INTO `tuser_task` (`function_name`, `parameters`, `name`) VALUES ('cron_task_call_user_function','a:1:{i:0;a:2:{s:11:\"description\";s:13:\"Function name\";s:4:\"type\";s:4:\"text\";}}','Call PHP function')");
}
}
$user_function_task_id = db_get_value_sql('SELECT id FROM `tuser_task_scheduled` WHERE `args` LIKE "%cron_task_start_gotty%"');
if ($user_function_task_id === false) {
// Schedule task to manage GoTTY processes daily if it is not scheduled yet.
$this->schedule(
'cron_task_call_user_function',
[
0 => 'cron_task_start_gotty',
'function_name' => 'cron_task_start_gotty',
'internal' => 1,
],
'daily',
0,
0,
strtotime('tomorrow')
);
}
}
// Maintenance task: check whether start GoTTY SSH and Telnet processes are running and start otherwise.
// Must do at every Cron execution.
cron_task_start_gotty(false);
// Do not output anything until is completed. There're session
// operations inside cron_task_run function.
ob_start();
if (cron_task_lock() === false) {
// Cannot continue. Locked.
echo ob_get_clean();
exit;
}
$time = get_system_time();
$scheduled_tasks = db_get_all_rows_in_table('tuser_task_scheduled');
if (!$scheduled_tasks) {
$scheduled_tasks = [];
}
/*
Watch out! First_execution corresponds to next_execution the name
of the bbdd is maintained to ensure integrity.
*/
foreach ($scheduled_tasks as $task) {
$params = unserialize($task['args']);
if ($this->shouldTaskRun($task) === false) {
continue;
}
if ($task['scheduled'] == 'no') {
if (($params['first_execution']) < $time) {
echo date('Y/m/d H:i:s').' Execute once time cron task: ';
echo $task['id'];
echo "\n\n";
cron_task_run($task['id']);
// The task was not scheduled and was executed once.
db_process_sql_delete(
'tuser_task_scheduled',
['id' => $task['id']]
);
}
} else {
if (($params['first_execution']) < $time) {
echo date('Y/m/d H:i:s').' EXECUTED CRON TASK: '.$task['id'];
echo "\n";
echo "\n";
cron_task_run($task['id']);
}
}
}
// Dump to output.
echo ob_get_clean();
// Release the lock.
cron_task_release_lock();
}
/**
* Schedules a discovery console task to be executed by cron.
*
* @param string $function_name Name of the function:
* cron_task_generate_report
* cron_task_generate_report_by_template
* cron_task_save_report_to_disk
* cron_task_do_backup
* cron_task_execute_custom_script
* cron_task_save_xml_report_to_disk
* cron_task_feedback_send_mail
* cron_task_generate_csv_log.
* @param array $arguments Task execution arguments (if needed).
* @param string $schedule Task schedule options:
* 'no',
* 'hourly',
* 'daily',
* 'weekly',
* 'monthly',
* 'yearly',
* 'custom'.
* @param integer $group_id Group id (0 => all).
* @param string|null $id_user User id, if null, current user.
* @param integer|null $time_start When to start, if null, now.
*
* @return boolean Sucessfully scheduled or not.
*/
public function schedule(
string $function_name,
array $arguments=[],
string $schedule='no',
int $group_id=0,
?string $id_user=null,
?int $time_start=null
) {
global $config;
if ($id_user === null) {
$id_user = $config['id_user'];
}
$idUserTask = db_get_value(
'id',
'tuser_task',
'function_name',
$function_name
);
if ($idUserTask === false) {
// Failed to identify function.
return false;
}
if (in_array($schedule, self::SCHEDULES) === false) {
// Failed to schedule. Not a valid schedule option.
return false;
}
if ($time_start === null) {
$time_start = strtotime('now');
}
// Params for send mail with cron.
$parameters = array_merge(
$arguments,
[ 'first_execution' => $time_start ]
);
// Values insert task cron.
$task = [
'id_usuario' => $id_user,
'id_user_task' => $idUserTask,
'args' => serialize($parameters),
'scheduled' => $schedule,
'id_grupo' => $group_id,
];
$result = db_process_sql_insert(
'tuser_task_scheduled',
$task
);
return ($result !== false);
}
}

View File

@ -1497,7 +1497,6 @@ function config_update_config()
$interval_values = implode(',', $interval_values_array);
}
hd($interval_values, true);
if (config_update_value('interval_values', $interval_values, true) === false) {
$error_update[] = __('Delete interval');
}
@ -2034,20 +2033,6 @@ function config_update_config()
}
break;
case 'websocket_engine':
if (config_update_value('ws_bind_address', get_parameter('ws_bind_address'), true) === false) {
$error_update[] = __('WebSocket bind address');
}
if (config_update_value('ws_port', get_parameter('ws_port'), true) === false) {
$error_update[] = __('WebSocket port');
}
if (config_update_value('ws_proxy_url', get_parameter('ws_proxy_url'), true) === false) {
$error_update[] = __('WebSocket proxy url');
}
break;
default:
// Ignore.
break;
@ -2504,6 +2489,18 @@ function config_process_config()
config_update_value('2Fa_auth', '');
}
if (!isset($config['gotty_ssh_enabled'])) {
config_update_value('gotty_ssh_enabled', 1);
}
if (!isset($config['gotty_telnet_enabled'])) {
config_update_value('gotty_telnet_enabled', 0);
}
if (!isset($config['gotty_port'])) {
config_update_value('gotty_port', 8080);
}
if (isset($config['performance_variables_control']) === false) {
config_update_value(
'performance_variables_control',

View File

@ -463,7 +463,6 @@ function cron_list_table()
);
$defined_tasks = db_get_all_rows_sql($sql);
if (!check_acl($config['id_user'], 0, 'PM')) {
$read_tasks = [];
foreach ($defined_tasks as $task) {

View File

@ -0,0 +1,542 @@
<?php
/**
* Schedule tasks on Pandora FMS Console
*
* @category library
* @package Pandora FMS
* @subpackage cron
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* 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 for version 2.
* 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.
* ============================================================================
*/
/**
* Generate a lock system to avoid multiple executions.
*
* @param string $lockfile Filename to use as lock.
*
* @return boolean
*/
function cron_lock(string $lockfile)
{
global $config;
if (empty($lockfile) === true) {
$lockfile = 'cron.lock';
}
$ignore_lock = 0;
// Lock to prevent multiple instances of the cron extension.
$lock = $config['attachment_store'].'/'.$lockfile;
if (file_exists($lock) === true) {
// Lock file exists.
$read_PID = file_get_contents($lock);
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// Windows check.
$processes = explode("\n", shell_exec('tasklist.exe'));
$ignore_lock = 1;
foreach ($processes as $process) {
if (empty($process) === true
|| strpos('===', $process) === 0
) {
continue;
}
$matches = false;
preg_match('/(.*?)\s+(\d+).*$/', $process, $matches);
$pid = $matches[2];
if ((int) $pid === (int) $read_PID) {
$ignore_lock = 0;
break;
}
}
} else {
// Linux check.
if (file_exists('/proc/'.$read_PID) === true) {
// Process with a pid = $pid is running.
// CRON already running: [$read_PID].
$ignore_lock = 0;
} else {
// CRON process [$read_PID] does not exist.
// process not found, ignore $lock.
$ignore_lock = 1;
}
}
// The lock automatically expires after 24 hours.
$lock_mtime = filemtime($lock);
if (($ignore_lock === 0 )
&& ($lock_mtime !== false && $lock_mtime + SECONDS_1DAY > time())
) {
// Locked!
return false;
}
}
// Try to get a lock from DB.
$dblock = db_get_lock($config['dbname'].'.'.$lockfile);
if ($dblock !== 1) {
// Locked!
return false;
}
// Store PID in lock file.
$PID = getmypid();
echo 'CRON running ['.$PID."]\n";
file_put_contents($lock, $PID);
return true;
}
/**
* Check if CRON.task is available to start.
*
* @return boolean True, available. False not available.
*/
function cron_task_lock()
{
return cron_lock('cron.lock');
}
/**
* Release CRON.task lock
*
* @return void
*/
function cron_task_release_lock()
{
global $config;
// Release DB lock.
$dblock = db_release_lock($config['dbname'].'.cron.lock');
unlink($config['attachment_store'].'/cron.lock');
}
/**
* Calculates target schedule time
*
* @param string $scheduled_time Desired scheduled time.
* @param integer $custom_data Custom scheduled time.
* @param integer|null $timestamp Custom timestamp.
*
* @return integer amount of time.
*/
function cron_get_scheduled_time(
string $scheduled_time,
int $custom_data=0,
$timestamp=null
) {
if ($scheduled_time == 'no') {
return 0;
}
if ($scheduled_time == 'hourly') {
return SECONDS_1HOUR;
}
if ($scheduled_time == 'daily') {
return SECONDS_1DAY;
}
if ($scheduled_time == 'weekly') {
return SECONDS_1WEEK;
}
if ($scheduled_time == 'monthly') {
$month = (($timestamp === null) ? date('m') : date('m', $timestamp));
$year = (($timestamp === null) ? date('Y') : date('Y', $timestamp));
$days_month = (cal_days_in_month(
CAL_GREGORIAN,
$month,
$year
) * SECONDS_1DAY);
return $days_month;
}
if ($scheduled_time == 'yearly') {
return SECONDS_1YEAR;
}
if ($scheduled_time == 'custom') {
return $custom_data;
}
return 0;
}
/**
* Run scheduled task.
*
* @param integer $id_user_task Task to be run.
* @param boolean $force_run Force run.
*
* @return void
*/
function cron_task_run(
int $id_user_task,
bool $force_run=false
) {
global $config;
if (isset($config['id_console']) === true && $config['id_console'] > 0) {
$sql = sprintf(
'SELECT *
FROM tuser_task_scheduled
WHERE id=%d AND id_console IN (0, %d)',
$id_user_task,
$config['id_console']
);
$task_scheduled = db_get_row_sql($sql);
if ($task_scheduled !== false) {
db_process_sql_update(
'tconsole',
['last_execution' => time()],
['id_console' => $config['id_console']]
);
}
} else {
$filter = [
'id' => $id_user_task,
'id_console' => 0,
];
$task_scheduled = db_get_row_filter('tuser_task_scheduled', $filter, false);
}
$args = unserialize($task_scheduled['args']);
if ((bool) $config['enterprise_installed'] === false
&& isset($args['function_name']) === true
&& $args['function_name'] !== 'cron_task_start_gotty'
) {
// Only cron_task_start_gotty is allowed to run in non enterprise environments.
return;
}
if ((bool) $config['enterprise_installed'] === true) {
$task = db_get_row('tuser_task', 'id', $task_scheduled['id_user_task']);
} else {
$task = [
'name' => 'Call PHP function',
'function_name' => 'cron_task_call_user_function',
];
}
// Register shutdown function in case of fatal error, like.
register_shutdown_function('cron_task_handle_error', $task_scheduled, $task, $force_run);
if (is_metaconsole() && !defined('METACONSOLE')) {
define('METACONSOLE', 1);
}
if (! function_exists($task['function_name'])) {
return;
}
// If the task is disable, not run.
if ((bool) $task_scheduled['enabled'] === false) {
return;
}
if (session_status() === PHP_SESSION_DISABLED) {
return;
}
$old_user = '';
if (isset($config['id_user']) === false) {
$config['id_user'] = $task_scheduled['id_usuario'];
}
$old_user = $config['id_user'];
$old_session_id = session_id();
$new_session_id = 'cron-'.uniqid();
// Simulate user login.
session_id($new_session_id);
session_start();
$_SESSION['id_usuario'] = $config['id_user'];
session_write_close();
set_time_limit(0);
if ($task['function_name'] == 'cron_task_generate_report_by_template'
|| $task['function_name'] == 'cron_task_generate_report'
) {
// If empty agent position, add it.
if (!isset($args[1])) {
array_splice($args, 1, 0, '');
}
$args[] = $task_scheduled['scheduled'];
}
call_user_func_array(
$task['function_name'],
array_merge(array_values(($args ?? [])), [$id_user_task])
);
if (session_status() === PHP_SESSION_ACTIVE) {
@session_destroy();
}
session_id($old_session_id);
session_start();
$config['id_user'] = $old_user;
$sql = '';
$sql2 = '';
if (!$force_run) {
$period = cron_get_scheduled_time(
$task_scheduled['scheduled'],
$task_scheduled['custom_data']
);
$old_args = unserialize($task_scheduled['args']);
if ($period > 3600) {
$array_explode = explode(
':',
date('H:i', $old_args['first_execution'])
);
$hora_en_segundos = (($array_explode[0] * 3600 ) + ($array_explode[1] * 60));
$array_explode_period = explode(
':',
date('H:i', ($old_args['first_execution'] + $period))
);
$hora_en_segundos2 = (($array_explode_period[0] * 3600 ) + ($array_explode_period[1] * 60));
if ($hora_en_segundos !== $hora_en_segundos2) {
$period = ($period + ($hora_en_segundos - $hora_en_segundos2));
}
}
try {
/*
Calculate the number of periods between last execution and
current time.
*/
$num_of_periods = 0;
if ($period !== 0) {
$num_of_periods = ceil(
(time() - $old_args['first_execution']) / $period
);
}
if ($task_scheduled['scheduled'] == 'monthly') {
$updated_time = $old_args['first_execution'];
// Update updated_time adding the period for each month individually since it is a variable value depending on the number of days a month has.
while ($num_of_periods > 0) {
// Get days of current month.
$monthly_period = cron_get_scheduled_time(
'monthly',
$task_scheduled['custom_data'],
$updated_time
);
$updated_time += $monthly_period;
$num_of_periods--;
}
$old_args['first_execution'] = $updated_time;
} else if ($task_scheduled['scheduled'] == 'weekly') {
$weekly_schedule = json_decode(io_safe_output($old_args['weekly_schedule']), true);
if (empty($weekly_schedule) !== true) {
$datetime = new DateTime('tomorrow');
$nameday = strtolower($datetime->format('l'));
$continue = true;
while ($continue === true) {
if (isset($weekly_schedule[$nameday]) === true) {
$weekly_date = $datetime->format('Y-m-d');
$weekly_time = $weekly_schedule[$nameday][0]['start'];
$old_args['first_execution'] = strtotime($weekly_date.' '.$weekly_time);
$continue = false;
} else {
$datetime->modify('+1 day');
$nameday = strtolower($datetime->format('l'));
}
}
}
} else {
// Add it to next execution.
$old_args['first_execution'] += ($period * $num_of_periods);
}
} catch (Exception $e) {
// If some error (ex $period=0) next execution=current time+period.
$old_args['first_execution'] = (time() + $period);
}
$new_args = serialize($old_args);
}
if ($config['timesource'] == 'sql') {
$sql = sprintf(
'UPDATE tuser_task_scheduled
SET last_run=UNIX_TIMESTAMP()
WHERE id=%d',
$id_user_task
);
} else {
$sql = sprintf(
'UPDATE tuser_task_scheduled
SET last_run= %d
WHERE id=%d',
time(),
$id_user_task
);
}
if (!$force_run) {
$sql2 = "UPDATE tuser_task_scheduled
SET args = '".$new_args."'
WHERE id=".$id_user_task;
}
db_process_sql($sql);
db_process_sql($sql2);
}
/**
* Execuytes custom function defined in PHP.
*
* @param string $function_name Name to execute.
*
* @return void
*/
function cron_task_call_user_function(string $function_name)
{
global $config;
include_once $config['homedir'].'/vendor/autoload.php';
call_user_func($function_name);
}
/**
* Check whether GoTTY SSH and Telnet processes are running and start otherwise.
*
* @param boolean $restart_mode Restart the processes if running.
*
* @return void
*/
function cron_task_start_gotty(bool $restart_mode=true)
{
global $config;
include_once $config['homedir'].'/include/functions_config.php';
$gotty_ssh_enabled = (bool) $config['gotty_ssh_enabled'];
$gotty_telnet_enabled = (bool) $config['gotty_telnet_enabled'];
// Check prev process running and kill it (only if port changed in setup params).
if (empty($config['restart_gotty_next_cron_port']) === false) {
config_update_value('restart_gotty_next_cron_port', '');
$prevProcessRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
if (empty($prevProcessRunning) === false) {
shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
}
}
// Check if gotty is running on the configured port.
$processRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_port']."'");
$start_proc = true;
// If both methods are disabled, do not start process.
if ($gotty_ssh_enabled === false && $gotty_telnet_enabled === false) {
$start_proc = false;
}
if (empty($processRunning) === false) {
// Process is running.
if ($restart_mode === true || $start_proc === false) {
// Stop the process for restarting or in case GoTTY method is disabled in this iteration.
shell_exec("pkill -f 'pandora_gotty.*-p ".$config['gotty_port']."'");
} else {
// Prevent starting if already running and must not be restarted or terminated.
return;
}
}
if ($start_proc === true) {
$logFilePath = $config['homedir'].'/log/gotty_cron_tmp.log';
shell_exec('touch '.$logFilePath);
// Start gotty process and capture the output.
$command = '/usr/bin/nohup /usr/bin/pandora_gotty --config /etc/pandora_gotty/pandora_gotty.conf -p '.$config['gotty_port'].' /usr/bin/pandora_gotty_exec > '.$logFilePath.' 2>&1 &';
shell_exec($command);
} else {
return;
}
$hash_read = false;
// Maximum wait time to read asynchronously the output of the executed commands (seconds).
$maxWaitTime = 10;
// Wait for content to appear in the log file.
$startTime = time();
// Workaround to wait until process inputs data in the log.
while (time() - $startTime < $maxWaitTime) {
if ($start_proc === true) {
// Read command output.
$log_content = file_get_contents($logFilePath);
}
if ($start_proc === true
&& !empty($log_content)
&& $hash_read === false
) {
// Extract the URL from the output.
if (preg_match('/.*?HTTP server is listening at:\s+(\S+)/', $log_content, $matches)) {
$url = $matches[1];
// Extract the hash.
$parts = explode('/', $url);
$hash = array_slice($parts, -2, 1)[0];
config_update_value('gotty_connection_hash', $hash);
$hash_read = true;
}
unlink($logFilePath);
}
if ($start_proc === false || $hash_read === true) {
// As soon as the read has completed, the timing loop will terminate.
break;
}
// Sleep for a short interval before checking again.
usleep(100000);
}
}

View File

@ -1,175 +0,0 @@
#!/bin/bash
# Copyright (c) 2005-2023 Pandora FMS
#
# /etc/init.d/websocket
#
# System startup script for Pandora FMS Console websocket engine
#
# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 90 10
# description: Pandora FMS Console webscoket engine startup script
#
# Comments to support LSB init script conventions
### BEGIN INIT INFO
# Provides: websocket
# Required-Start: $syslog cron
# Should-Start: $network cron mysql
# Required-Stop: $syslog
# Should-Stop: $network
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: Pandora FMS Console websocket engine startup script
# Description: Pandora FMS Console websocket engine startup script
### END INIT INFO
if [ -x /lib/lsb/init-functions ]; then
. /lib/lsb/init-functions
fi
# If you want to run several pandora Console Websocket engines in this machine, just copy
# this script to another name, editing PANDORA_HOME to the new .conf
export WS_ENGINE="/var/www/html/pandora_console/ws.php"
export PHP=/usr/bin/php
export WS_LOG="/var/log/pandora/web_socket.log"
export GOTTY="/tmp/"
# Environment variables
if [[ -z ${PANDORA_RB_PRODUCT_NAME} ]]; then
PANDORA_RB_PRODUCT_NAME="Pandora FMS"
fi
if [[ -z ${PANDORA_RB_COPYRIGHT_NOTICE} ]]; then
PANDORA_RB_COPYRIGHT_NOTICE="Pandora FMS"
fi
export PANDORA_RB_PRODUCT_NAME=$PANDORA_RB_PRODUCT_NAME
export PANDORA_RB_COPYRIGHT_NOTICE=$PANDORA_RB_COPYRIGHT_NOTICE
# Uses a wait limit before sending a KILL signal, before trying to stop
# Pandora FMS Console Websocket engine nicely. Some big systems need some time before close
# all pending tasks / threads.
export MAXWAIT=60
# Check for SUSE status scripts
if [ -f /etc/rc.status ]
then
. /etc/rc.status
rc_reset
else
# Define part of rc functions for non-suse systems
function rc_status () {
RETVAL=$?
case $1 in
-v) RETVAL=0;;
esac
}
function rc_exit () { exit $RETVAL; }
function rc_failed () { RETVAL=${1:-1}; }
RETVAL=0
fi
# This function replace pidof, not working in the same way in different linux distros
function pidof_pandora () {
# This sets COLUMNS to XXX chars, because if command is run
# in a "strech" term, ps aux don't report more than COLUMNS
# characters and this will not work.
COLUMNS=300
PANDORA_PID=`ps aux | grep "$PHP $WS_ENGINE" | grep -v grep | tail -1 | awk '{ print $2 }'`
echo $PANDORA_PID
}
# Main script
if [ ! -x $GOTTY ]
then
echo "Gotty not found in $GOTTY"
rc_failed 5 # program is not installed
rc_exit
fi
if [ ! -f $PHP ]
then
echo "$PHP not found, please install version >= 7.0"
rc_failed 5 # program is not installed
rc_exit
fi
case "$1" in
start)
PANDORA_PID=`pidof_pandora`
if [ ! -z "$PANDORA_PID" ]
then
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is currently running on this machine with PID ($PANDORA_PID)."
rc_exit # running start on a service already running
fi
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
$PHP $WS_ENGINE >> $WS_LOG 2>&1 &
sleep 1
PANDORA_PID=`pidof_pandora`
if [ ! -z "$PANDORA_PID" ]
then
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is now running with PID $PANDORA_PID"
rc_status -v
else
echo "Cannot start $PANDORA_RB_PRODUCT_NAME Console Websocket engine. Aborted."
echo "Check $PANDORA_RB_PRODUCT_NAME log files at $WS_LOG"
rc_failed 7 # program is not running
fi
;;
stop)
PANDORA_PID=`pidof_pandora`
if [ -z "$PANDORA_PID" ]
then
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running, cannot stop it."
rc_exit # running stop on a service already stopped or not running
else
echo "Stopping $PANDORA_RB_PRODUCT_NAME Console Websocket engine"
kill $PANDORA_PID > /dev/null 2>&1
COUNTER=0
while [ $COUNTER -lt $MAXWAIT ]
do
_PID=`pidof_pandora`
if [ "$_PID" != "$PANDORA_PID" ]
then
COUNTER=$MAXWAIT
fi
COUNTER=`expr $COUNTER + 1`
sleep 1
done
# Send a KILL -9 signal to process, if it's alive after 60secs, we need
# to be sure is really dead, and not pretending...
if [ "$_PID" = "$PANDORA_PID" ]
then
kill -9 $PANDORA_PID > /dev/null 2>&1
fi
rc_status -v
fi
;;
status)
PANDORA_PID=`pidof_pandora`
if [ -z "$PANDORA_PID" ]
then
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running."
rc_failed 7 # program is not running
else
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is running with PID $PANDORA_PID."
rc_status
fi
;;
force-reload|restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 { start | stop | restart | status }"
exit 1
esac
rc_exit