diff options
Diffstat (limited to 'config/servicewatchdog')
-rw-r--r-- | config/servicewatchdog/services_servicewatchdog.php | 211 | ||||
-rw-r--r-- | config/servicewatchdog/services_servicewatchdog_add.php | 117 | ||||
-rw-r--r-- | config/servicewatchdog/servicewatchdog.inc | 83 | ||||
-rw-r--r-- | config/servicewatchdog/servicewatchdog.xml | 72 | ||||
-rw-r--r-- | config/servicewatchdog/servicewatchdog_cron.php | 13 |
5 files changed, 496 insertions, 0 deletions
diff --git a/config/servicewatchdog/services_servicewatchdog.php b/config/servicewatchdog/services_servicewatchdog.php new file mode 100644 index 00000000..920fd1bb --- /dev/null +++ b/config/servicewatchdog/services_servicewatchdog.php @@ -0,0 +1,211 @@ +<?php +/* + services_servicewatchdog.php + Copyright (C) 2013 Jim Pingle + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-services-servicewatchdog +##|*NAME=Services: Service Watchdog +##|*DESCR=Allow access to the 'Services: Service Watchdog' page. +##|*MATCH=services_servicewatchdog.php* +##|-PRIV + +require("guiconfig.inc"); +require_once("functions.inc"); +require_once("service-utils.inc"); +require_once("servicewatchdog.inc"); + +if (!is_array($config['installedpackages']['servicewatchdog']['item'])) + $config['installedpackages']['servicewatchdog']['item'] = array(); + +$a_pwservices = &$config['installedpackages']['servicewatchdog']['item']; + +/* if a custom message has been passed along, lets process it */ +if ($_GET['savemsg']) + $savemsg = $_GET['savemsg']; + +if ($_GET['act'] == "del") { + if ($a_pwservices[$_GET['id']]) { + unset($a_pwservices[$_GET['id']]); + servicewatchdog_cron_job(); + write_config(); + header("Location: services_servicewatchdog.php"); + exit; + } +} + +if (isset($_POST['del_x'])) { + /* delete selected services */ + if (is_array($_POST['pwservices']) && count($_POST['pwservices'])) { + foreach ($_POST['pwservices'] as $servicei) { + unset($a_pwservices[$servicei]); + } + servicewatchdog_cron_job(); + write_config(); + header("Location: services_servicewatchdog.php"); + exit; + } +} else { + /* yuck - IE won't send value attributes for image buttons, while Mozilla does - so we use .x/.y to find move button clicks instead... */ + unset($movebtn); + foreach ($_POST as $pn => $pd) { + if (preg_match("/move_(\d+)_x/", $pn, $matches)) { + $movebtn = $matches[1]; + break; + } + } + /* move selected services before this service */ + if (isset($movebtn) && is_array($_POST['pwservices']) && count($_POST['pwservices'])) { + $a_pwservices_new = array(); + + /* copy all services < $movebtn and not selected */ + for ($i = 0; $i < $movebtn; $i++) { + if (!in_array($i, $_POST['pwservices'])) + $a_pwservices_new[] = $a_pwservices[$i]; + } + + /* copy all selected services */ + for ($i = 0; $i < count($a_pwservices); $i++) { + if ($i == $movebtn) + continue; + if (in_array($i, $_POST['pwservices'])) + $a_pwservices_new[] = $a_pwservices[$i]; + } + + /* copy $movebtn service */ + if ($movebtn < count($a_pwservices)) + $a_pwservices_new[] = $a_pwservices[$movebtn]; + + /* copy all services > $movebtn and not selected */ + for ($i = $movebtn+1; $i < count($a_pwservices); $i++) { + if (!in_array($i, $_POST['pwservices'])) + $a_pwservices_new[] = $a_pwservices[$i]; + } + $a_pwservices = $a_pwservices_new; + servicewatchdog_cron_job(); + write_config(); + header("Location: services_servicewatchdog.php"); + return; + } +} + +$closehead = false; +$pgtitle = array(gettext("Services"),gettext("Service Watchdog")); +include("head.inc"); + +?> +<script type="text/javascript" src="/javascript/domTT/domLib.js"></script> +<script type="text/javascript" src="/javascript/domTT/domTT.js"></script> +<script type="text/javascript" src="/javascript/domTT/behaviour.js"></script> +<script type="text/javascript" src="/javascript/domTT/fadomatic.js"></script> + +<link type="text/css" rel="stylesheet" href="/javascript/chosen/chosen.css" /> +</head> +<body link="#000000" vlink="#000000" alink="#000000"> +<?php include("fbegin.inc"); ?> +<form action="services_servicewatchdog.php" method="post" name="iform"> +<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js"></script> +<?php if ($savemsg) print_info_box($savemsg); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="services to monitor"> +<tr><td><div id="mainarea"> +<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0" summary="main area"> +<tr><td colspan="8" align="center"> +<?php echo gettext("This page allows you to select services to be monitored so that they may be automatically restarted if they crash or are stopped."); ?> +<br/><br/> +</td></tr> +<tr id="frheader"> +<td width="5%" class="list"> </td> +<td width="30%" class="listhdrr"><?=gettext("Service Name");?></td> +<td width="60%" class="listhdrr"><?=gettext("Description");?></td> +<td width="5%" class="list"> +<table border="0" cellspacing="0" cellpadding="1" summary="buttons"> + <tr><td width="17"> + <?php if (count($a_pwservices) == 0): ?> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" title="<?=gettext("delete selected services");?>" border="0" alt="delete" /> + <?php else: ?> + <input name="del" type="image" src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" title="<?=gettext("delete selected services"); ?>" onclick="return confirm('<?=gettext("Do you really want to delete the selected services?");?>')" /> + <?php endif; ?> + </td> + <td><a href="services_servicewatchdog_add.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" title="<?=gettext("add new service"); ?>" alt="add" /></a></td> + </tr> +</table> +</td> +</tr> + +<?php +$nservices = $i = 0; +foreach ($a_pwservices as $thisservice): +?> + <tr valign="top" id="fr<?=$nservices;?>"> + <td class="listt"><input type="checkbox" id="frc<?=$nservices;?>" name="pwservices[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nservices;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;" /></td> + <td class="listlr" onclick="fr_toggle(<?=$nservices;?>)" id="frd<?=$nservices;?>" ondblclick="document.location='services_servicewatchdog_add.php?id=<?=$nservices;?>';"> + <?=$thisservice['name'];?> + </td> + <td class="listr" onclick="fr_toggle(<?=$nservices;?>)" id="frd<?=$nservices;?>" ondblclick="document.location='services_servicewatchdog_add.php?id=<?=$nservices;?>';"> + <?=$thisservice['description'];?> + </td> + <td valign="middle" class="list" nowrap> + <table border="0" cellspacing="0" cellpadding="1" summary="add"> + <tr> + <td><input onmouseover="fr_insline(<?=$nservices;?>, true)" onmouseout="fr_insline(<?=$nservices;?>, false)" name="move_<?=$i;?>" src="/themes/<?= $g['theme']; ?>/images/icons/icon_left.gif" title="<?=gettext("move selected services before this service");?>" height="17" type="image" width="17" border="0" /></td> + <td align="center" valign="middle"><a href="services_servicewatchdog.php?act=del&id=<?=$i;?>" onclick="return confirm('<?=gettext("Do you really want to delete this service?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" title="<?=gettext("delete service");?>" alt="delete" /></a></td> + </tr> + </table> + </td></tr> +<?php $i++; $nservices++; endforeach; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list" valign="middle" nowrap> + <table border="0" cellspacing="0" cellpadding="1" summary="add"> + <tr> + <td><?php if ($nservices == 0): ?><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_left_d.gif" width="17" height="17" title="<?=gettext("move selected services to end"); ?>" border="0" alt="move" /><?php else: ?><input name="move_<?=$i;?>" type="image" src="/themes/<?= $g['theme']; ?>/images/icons/icon_left.gif" width="17" height="17" title="<?=gettext("move selected services to end");?>" border="0" alt="move" /><?php endif; ?></td> + </tr> + <tr> + <td width="17"> + <?php if (count($a_pwservices) == 0): ?> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" title="<?=gettext("delete selected services");?>" border="0" alt="delete" /> + <?php else: ?> + <input name="del" type="image" src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" title="<?=gettext("delete selected services"); ?>" onclick="return confirm('<?=gettext("Do you really want to delete the selected services?");?>')" /> + <?php endif; ?> + </td> + <td><a href="services_servicewatchdog_add.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" title="<?=gettext("add new service"); ?>" alt="add" /></a></td> + </tr> + </table> + </td> + </tr> + <tr><td></td><td colspan="3"> + <?php echo gettext("Click to select a service and use the arrows to re-order them in the list. Higher services are checked first."); ?> + </td><td></td></tr> + </table> +</div></td></tr> +</table> +</form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/servicewatchdog/services_servicewatchdog_add.php b/config/servicewatchdog/services_servicewatchdog_add.php new file mode 100644 index 00000000..11e5e284 --- /dev/null +++ b/config/servicewatchdog/services_servicewatchdog_add.php @@ -0,0 +1,117 @@ +<?php +/* + services_servicewatchdog_add.php + Copyright (C) 2013 Jim Pingle + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-services-servicewatchdog-add +##|*NAME=Services: Add Service Watchdog Services +##|*DESCR=Allow access to the 'Add Service Watchdog Services' page. +##|*MATCH=services_servicewatchdog.php-add* +##|-PRIV + +require("guiconfig.inc"); +require_once("service-utils.inc"); +require_once("servicewatchdog.inc"); + +if (!is_array($config['installedpackages']['servicewatchdog']['item'])) { + $config['installedpackages']['servicewatchdog']['item'] = array(); +} +$a_pwservices = &$config['installedpackages']['servicewatchdog']['item']; +// Pre-load "cron" into this array to blacklist it from being offered as a choice. +$a_pwservice_names = array("cron"); +foreach ($a_pwservices as $svc) { + $a_pwservice_names[] = $svc['name']; +} +$system_services = get_services(); + +unset($input_errors); + +if ($_POST) { + if (!is_numeric($_POST['svcid'])) + + + if (!isset($system_services[$_POST['svcid']])) { + $input_errors[] = gettext("The supplied service appears to be invalid."); + } + + if (!$input_errors) { + $a_pwservices[] = $system_services[$_POST['svcid']]; + servicewatchdog_cron_job(); + write_config(); + + header("Location: services_servicewatchdog.php"); + return; + } +} + +$closehead = false; +$pgtitle = array(gettext("Services"),gettext("servicewatchdog"), gettext("Add")); +include("head.inc"); + +?> +<link type="text/css" rel="stylesheet" href="/pfCenter/javascript/chosen/chosen.css" /> +<script src="/pfCenter/javascript/chosen/chosen.proto.js" type="text/javascript"></script> +</head> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> + +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<form action="services_servicewatchdog_add.php" method="post" name="iform" id="iform"> +<table width="100%" border="0" cellpadding="6" cellspacing="0" summary="add monitored service"> +<tr> + <td colspan="2" valign="top" class="listtopic"><?=gettext("Add Service Entry"); ?></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Service to Add:"); ?></td> + <td width="78%" class="vtable"> + <select name="svcid" class="formselect" id="svcid"> +<?php $i=0; + foreach ($system_services as $svc): ?> + <?php if (!servicewatchdog_is_service_watched($svc)): ?> + <?php $svc['description'] = empty($svc['description']) ? get_pkg_descr($svc['name']) : $svc['description']; ?> + <option value="<?= $i ?>"><?=$svc['name'];?>: <?= strlen($svc['description']) > 50 ? substr($svc['description'], 0, 50) . "..." : $svc['description'];?></option> + <?php endif; + $i++; ?> +<?php endforeach; ?> + </select> + </td> +</tr> +<tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Add"); ?>" /> <input type="button" class="formbtn" value="<?=gettext("Cancel"); ?>" onclick="history.back()" /> + </td> +</tr> +</table> +</form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/servicewatchdog/servicewatchdog.inc b/config/servicewatchdog/servicewatchdog.inc new file mode 100644 index 00000000..1bdb1ce9 --- /dev/null +++ b/config/servicewatchdog/servicewatchdog.inc @@ -0,0 +1,83 @@ +<?php +require_once("config.inc"); +require_once("services.inc"); +require_once("service-utils.inc"); +require_once("util.inc"); + +function servicewatchdog_service_matches($svc1, $svc2) { + /* If the arrays are equal, it must be the same service. */ + if ($svc1 == $svc2) + return true; + /* If the names are different, they must not be the same. */ + if ($svc1['name'] != $svc2['name']) + return false; + switch ($svc1['name']) { + case "openvpn": + if (($svc1['mode'] == $svc2['mode']) && ($svc1['vpnid'] == $svc2['vpnid'])) + return true; + else + return false; + break; + case "captiveportal": + if ($svc1['zone'] == $svc2['zone']) + return true; + else + return false; + break; + default: + /* Other services must be the same if the name matches. */ + return true; + } +} + +function servicewatchdog_is_service_watched($svc) { + global $config; + if (!is_array($config['installedpackages']['servicewatchdog']['item'])) { + $config['installedpackages']['servicewatchdog']['item'] = array(); + } + $a_pwservices = &$config['installedpackages']['servicewatchdog']['item']; + $blacklisted_services = array("cron"); + + if (empty($svc['name']) || in_array($svc['name'], $blacklisted_services)) + return true; + + foreach ($a_pwservices as $a_svc) { + if (servicewatchdog_service_matches($svc, $a_svc)) + return true; + } + return false; +} + +function servicewatchdog_cron_job() { + global $config; + if (!is_array($config['installedpackages']['servicewatchdog']['item'])) { + $config['installedpackages']['servicewatchdog']['item'] = array(); + } + $a_pwservices = &$config['installedpackages']['servicewatchdog']['item']; + + if (count($a_pwservices) > 0) { + // Add the cron job if it doesn't exist. + install_cron_job("/usr/local/pkg/servicewatchdog_cron.php", true, "*/1"); + } else { + // Remove the cron job + install_cron_job("/usr/local/pkg/servicewatchdog_cron.php", false, "*/1"); + } +} + +function servicewatchdog_check_services() { + global $config; + if (!is_array($config['installedpackages']['servicewatchdog']['item'])) { + $config['installedpackages']['servicewatchdog']['item'] = array(); + } + $a_pwservices = &$config['installedpackages']['servicewatchdog']['item']; + + foreach ($a_pwservices as $svc) { + if (!get_service_status($svc)) { + $descr = strlen($svc['description']) > 50 ? substr($svc['description'], 0, 50) . "..." : $svc['description']; + log_error("Service Watchdog detected service {$svc['name']} stopped. Restarting {$svc['name']} ({$descr})"); + service_control_start($svc['name'], $svc); + } + } +} + +?>
\ No newline at end of file diff --git a/config/servicewatchdog/servicewatchdog.xml b/config/servicewatchdog/servicewatchdog.xml new file mode 100644 index 00000000..5e1ce309 --- /dev/null +++ b/config/servicewatchdog/servicewatchdog.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* ========================================================================== */ +/* + servicewatchdog.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2013 Jim Pingle + All rights reserved. +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Service Watchdog</description> + <requirements>None</requirements> + <faq>Monitors for stopped services and restarts them.</faq> + <name>Service Watchdog</name> + <version>1.4</version> + <title>Services: Service Watchdog</title> + <include_file>/usr/local/pkg/servicewatchdog.inc</include_file> + <menu> + <name>Service Watchdog</name> + <tooltiptext></tooltiptext> + <section>Services</section> + <url>/services_servicewatchdog.php</url> + </menu> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/servicewatchdog/services_servicewatchdog.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/servicewatchdog/services_servicewatchdog_add.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>755</chmod> + <item>http://www.pfsense.com/packages/config/servicewatchdog/servicewatchdog_cron.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/servicewatchdog/servicewatchdog.inc</item> + </additional_files_needed> +</packagegui>
\ No newline at end of file diff --git a/config/servicewatchdog/servicewatchdog_cron.php b/config/servicewatchdog/servicewatchdog_cron.php new file mode 100644 index 00000000..004afd97 --- /dev/null +++ b/config/servicewatchdog/servicewatchdog_cron.php @@ -0,0 +1,13 @@ +#!/usr/local/bin/php -f +<?php +require_once("globals.inc"); +require_once("servicewatchdog.inc"); + +global $g; + +/* Do nothing at bootup. */ +if ($g['booting'] || file_exists("{$g['varrun_path']}/booting")) + return; + +servicewatchdog_check_services(); +?>
\ No newline at end of file |