updates to init script to work better after install.
updated automate fxn, and
monitor-server.cron will run automate & sync from install time.
echo "Performing Findbad Nodes"
#########################
# 1. FINDBAD NODES
-rm -f ${MONITOR_DATA_ROOT}/production.findbad2.pkl
-${MONITOR_SCRIPT_ROOT}/findbad.py --increment --cachenodes --debug=0 --dbname="findbad2" $DATE || :
-cp ${MONITOR_DATA_ROOT}/production.findbad2.pkl ${MONITOR_DATA_ROOT}/production.findbad.pkl
+${MONITOR_SCRIPT_ROOT}/findbad.py --increment $DATE || :
ps ax | grep BatchMode | grep -v grep | awk '{print $1}' | xargs -r kill || :
echo "Performing Findbad PCUs"
#########################
# 2. FINDBAD PCUS
-rm -f ${MONITOR_DATA_ROOT}/production.findbadpcus2.pkl
-${MONITOR_SCRIPT_ROOT}/findbadpcu.py --increment --refresh --debug=0 --dbname=findbadpcus2 $DATE || :
-cp ${MONITOR_DATA_ROOT}/production.findbadpcus2.pkl ${MONITOR_DATA_ROOT}/production.findbadpcus.pkl
+${MONITOR_SCRIPT_ROOT}/findbadpcu.py --increment $DATE || :
# clean up stray 'locfg' processes that hang around inappropriately...
ps ax | grep locfg | grep -v grep | awk '{print $1}' | xargs -r kill || :
-#echo "Generating web data"
-# badcsv.txt
-#${MONITOR_SCRIPT_ROOT}/printbadcsv.py | grep -v loading | tr -d ' ' > badcsv.txt
-#cp badcsv.txt /plc/data/var/www/html/monitor/
-#${MONITOR_SCRIPT_ROOT}/showlatlon.py | head -9 | awk 'BEGIN {print "<table>"} { print "<tr><td>", $0, "</td></tr>"} END{print "</table>"}' | sed -e 's\|\</td><td>\g' > /plc/data/var/www/html/monitor/regions.html
-
echo "Performing uptime changes for sites, nodes, and pcus"
########################
# 3. record last-changed for sites, nodes and pcus.
${MONITOR_SCRIPT_ROOT}/nodebad.py --increment || :
${MONITOR_SCRIPT_ROOT}/pcubad.py --increment || :
-echo "Converting pkl files to phpserial"
-#########################
-# 4. convert pkl to php serialize format.
-${MONITOR_SCRIPT_ROOT}/pkl2php.py -i findbadpcus2 -o findbadpcus
-for f in act_all plcdb_hn2lb ; do
- if [ -f ${MONITOR_DATA_ROOT}/production.$f.pkl ]; then
- ${MONITOR_SCRIPT_ROOT}/pkl2php.py -i $f -o $f
- else
- echo "Warning: ${MONITOR_DATA_ROOT}/production.$f.pkl does not exist."
- fi
-done
-${MONITOR_SCRIPT_ROOT}/pkl2php.py -i findbad -o findbadnodes
-#${MONITOR_SCRIPT_ROOT}/pkl2php.py -i ad_dbTickets -o ad_dbTickets
-#${MONITOR_SCRIPT_ROOT}/pkl2php.py -i idTickets -o idTickets
-
echo "Archiving pkl files"
#########################
# Archive pkl files.
fi
done
-echo "Running grouprins on all dbg nodes"
+#echo "Running grouprins on all dbg nodes"
############################
# 5. Check if there are any nodes in dbg state. Clean up afterward.
-${MONITOR_SCRIPT_ROOT}/grouprins.py --mail=1 --reboot --nodeselect 'state=DOWN&&boot_state=(boot|rins|dbg|diag)' --stopselect "state=BOOT" || :
-${MONITOR_SCRIPT_ROOT}/grouprins.py --mail=1 --reboot --nodeselect 'state=DEBUG&&boot_state=(rins|dbg|boot)' --stopselect 'state=BOOT' || :
+#${MONITOR_SCRIPT_ROOT}/grouprins.py --mail=1 --reboot --nodeselect 'state=DOWN&&boot_state=(boot|rins|dbg|diag)' --stopselect "state=BOOT" || :
+#${MONITOR_SCRIPT_ROOT}/grouprins.py --mail=1 --reboot --nodeselect 'state=DEBUG&&boot_state=(rins|dbg|boot)' --stopselect 'state=BOOT' || :
cp ${MONITOR_SCRIPT_ROOT}/monitor.log ${MONITOR_ARCHIVE_ROOT}/`date +%F-%H:%M`.monitor.log
rm -f $MONITOR_PID
global_round = fbsync.round
- if config.increment:
- # update global round number to force refreshes across all nodes
- global_round += 1
- fbsync.round = global_round
-
- fbsync.flush()
if config.site is not None:
api = plc.getAuthAPI()
l_pcus = [pcu for pcu in sets.Set(pcus)]
elif config.pcuselect is not None:
n, pcus = pcu_select(config.pcuselect)
+ print pcus
# clear out dups.
l_pcus = [pcu for pcu in sets.Set(pcus)]
l_pcus = [ config.pcuid ]
l_pcus = [int(pcu) for pcu in l_pcus]
+ if config.increment:
+ # update global round number to force refreshes across all nodes
+ global_round += 1
+ fbsync.round = global_round
+ fbsync.flush()
+
checkAndRecordState(l_pcus, cohash)
return 0
# automated actions for debug nodes.
01 * * * * root /usr/share/monitor/automate.sh 2>&1 > /usr/share/monitor/monitor.log
-01 * * * * root /usr/share/monitor/zabbix/zabbixsync.py 2>&1 > /usr/share/monitor/zabbixsync.log
+30 * * * * root /etc/plc.d/monitor sync 2>&1 >> /var/log/monitorsync.log
fi
# Create/update the unprivileged database user and password
- if [ -z "$PLC_MONITOR_DBPASSWORD" ] ; then
+ if [ -z "$PLC_MONITOR_DBPASSWORD" || "$PLC_MONITOR_DBPASSWORD" = "None" ] ; then
# Zabbix doesn't like plain uuidgen passwords
PLC_MONITOR_DBPASSWORD=$( uuidgen | md5sum - | awk '{print $1}' )
plc-config --category=plc_monitor --variable=dbpassword --value="$PLC_MONITOR_DBPASSWORD" --save=$local_config $local_config
MONITOR_HOSTNAME=${PLC_MONITOR_HOST}
MONITOR_IP=${PLC_MONITOR_IP}
+PLC_WWW_HOSTNAME=${PLC_WWW_HOST}
+
# used for debug mode
email=
cc_email=
[monitordatabase]
-monitor_dburi=postgres://${MONITOR_DB_NAME}:${PLC_MONITOR_DBPASSWORD}@localhost:5432/${MONITOR_DB_NAME}
+monitor_dburi=postgres://${MONITOR_DB_USER}:${PLC_MONITOR_DBPASSWORD}@localhost:5432/${MONITOR_DB_NAME}
zabbix_dburi=postgres://${ZABBIX_DB_USER}:${PLC_MONITOR_DBPASSWORD}@localhost:5432/${ZABBIX_DB_NAME}
cachetime=60
function start_tg_server ()
{
pushd ${MONITORPATH}/web/MonitorWeb/
- ./start-monitorweb.py ${MONITORPATH}/web/MonitorWeb/prod.cfg &> /var/log/monitorweb.log
+ ./start-monitorweb.py ${MONITORPATH}/web/MonitorWeb/prod.cfg &> /var/log/monitorweb.log &
popd
}
case "$1" in
start)
- MESSAGE=$"Bootstrap Monitoring"
+ MESSAGE=$"Bootstrap Monitoring (please wait...)"
dialog "$MESSAGE"
# DATABASE acces, creation, and data loading
check_pg_hba $MONITOR_DB_NAME $MONITOR_DB_USER
check_user_and_db $MONITOR_DB_NAME $MONITOR_DB_USER
+ # WRITE default /etc/monitor.conf
+ check_monitor_conf
check_monitor_schema_and_data
check_pg_hba $ZABBIX_DB_NAME $ZABBIX_DB_USER
# NOTE: restart db to enable access by users granted above.
service plc restart postgresql
service plc restart httpd
+ MESSAGE=$"Bootstrap Monitoring 2 (please wait...)"
+ dialog "$MESSAGE"
fi
check_zabbix_schema_and_data
check_zabbix_templates_and_import
- # WRITE default /etc/monitor.conf
- check_monitor_conf
# create /etc/httpd/conf.d/monitorweb.conf
create_httpd_conf
if [ -n "$WROTE_HTTP_CONFIG" ] ; then
# NOTE: restart web server to enable access web cfg
service plc restart httpd
+ MESSAGE=$"Bootstrap Monitoring 3 (please wait...)"
+ dialog "$MESSAGE"
fi
start_tg_server
result "$MESSAGE"
;;
+ restartweb)
+ MESSAGE=$"Restarting monitor web app..."
+ dialog "$MESSAGE"
+
+ stop_tg_server
+ start_tg_server
+
+ result "$MESSAGE"
+ ;;
+
sync)
MESSAGE=$"Syncing PLC db with Zabbix DB"
dialog "$MESSAGE"
from monitor import config
from monitor.wrapper import plc,plccache
from monitor.const import MINUP
-from monitor.database import FindbadNodeRecord, HistoryNodeRecord
+from monitor.database.info.model import FindbadNodeRecord, HistoryNodeRecord
from monitor.model import *
from monitor.wrapper import plc, plccache
api = plc.getAuthAPI()
-from monitor.database.info.model import FindbadNodeRecordSync, FindbadNodeRecord, session
+from monitor.database.info.model import FindbadNodeRecordSync, FindbadNodeRecord, FindbadPCURecord, session
from monitor import util
from monitor import config
indexes = path.split(".")
values = fb
for index in indexes:
- if index in values:
- values = values[index]
- else:
- raise NoKeyException(index)
+ if values and index in values:
+ values = values[index]
+ else:
+ raise NoKeyException(index)
return values
def verifyType(constraints, data):
return ad
def pcu_in(fbdata):
- if 'plcnode' in fbdata:
- if 'pcu_ids' in fbdata['plcnode']:
- if len(fbdata['plcnode']['pcu_ids']) > 0:
+ #if 'plcnode' in fbdata:
+ if 'plc_node_stats' in fbdata:
+ if 'pcu_ids' in fbdata['plc_node_stats']:
+ if len(fbdata['plc_node_stats']['pcu_ids']) > 0:
return True
return False
fbpcu_list = [ p.plc_pcuid for p in fbpcuquery ]
dict_query = query_to_dict(str_query)
+ print "dict_query", dict_query
for noderec in fbquery:
if nodelist is not None:
fb_nodeinfo = noderec.to_dict()
if pcu_in(fb_nodeinfo):
- pcurec = FindbadPCURecord.get_latest_by(plc_pcuid=get(fb_nodeinfo, 'plc_node_stats.pcu_ids')[0])
- pcuinfo = pcurec.to_dict()
- if verify(dict_query, pcuinfo):
- nodenames.append(noderec.hostname)
- str = "cmdhttps/locfg.pl -s %s -f iloxml/License.xml -u %s -p '%s' | grep MESSAGE" % \
- (reboot.pcu_name(pcuinfo), pcuinfo['username'], pcuinfo['password'])
- pcunames.append(pcuinfo['plc_pcuid'])
+ pcurec = FindbadPCURecord.get_latest_by(plc_pcuid=get(fb_nodeinfo, 'plc_node_stats.pcu_ids')[0]).first()
+ if pcurec:
+ pcuinfo = pcurec.to_dict()
+ if verify(dict_query, pcuinfo):
+ nodenames.append(noderec.hostname)
+ pcunames.append(pcuinfo['plc_pcuid'])
return (nodenames, pcunames)
def node_select(str_query, nodelist=None, fb=None):
from pcucontrol import reboot
from monitor import parser as parsermodule
from monitor import config
-from monitor.database import HistoryPCURecord, FindbadPCURecord
+from monitor.database.info.model import HistoryPCURecord, FindbadPCURecord
from monitor.wrapper import plc,plccache
from monitor.const import MINUP
def main(config):
- #l_plcpcus = database.if_cached_else_refresh(1, 1, "pculist", lambda : plc.GetPCUs())
l_plcpcus = plccache.l_pcus
l_pcus = None
import pcucontrol.transports.telnetlib as telnetlib
sys.path.insert(0, os.path.dirname(sys.argv[0]) + "/pyssh")
import pcucontrol.transports.pyssh as pyssh
+from monitor import config
# Timeouts in seconds
TELNET_TIMEOUT = 45
cmd = command.CMD()
# TODO: need to make this path universal; not relative to pwd.
- cmd_str = "pcucontrol/models/intelamt/remoteControl"
+ cmd_str = config.MONITOR_SCRIPT_ROOT + "/pcucontrol/models/intelamt/remoteControl"
if dryrun:
# NOTE: -p checks the power state of the host.
def run(self, node_port, dryrun):
locfg = command.CMD()
- cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
- self.host, "iloxml/Get_Network.xml",
+
+ cmd_str = config.MONITOR_SCRIPT_ROOT + "/pcucontrol/models/hpilo/"
+
+ cmd = cmd_str + "locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
+ self.host, cmd_str+"iloxml/Get_Network.xml",
self.username, self.password)
sout, serr = locfg.run_noexcept(cmd)
- if sout.strip() != "":
+ if sout.strip() != "" or serr.strip() != "":
print "sout: %s" % sout.strip()
- return sout.strip()
+ return sout.strip() + serr.strip()
if not dryrun:
locfg = command.CMD()
- cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
- self.host, "iloxml/Reset_Server.xml",
+ cmd = cmd_str + "locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
+ self.host, cmd_str+"iloxml/Reset_Server.xml",
self.username, self.password)
sout, serr = locfg.run_noexcept(cmd)
if sout.strip() != "":
print "sout: %s" % sout.strip()
#return sout.strip()
+
return 0
class BayTechAU(PCUControl):
#!/usr/bin/python
-import config
+from monitor import config
for attr in dir(config):
val = config.__getattribute__(attr)
def format_pcu_shortstatus(pcu):
status = "error"
- if pcu.reboot_trial_status == str(0):
- status = "ok"
- elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
- status = pcu.reboot_trial_status
- else:
- status = "error"
+ if pcu:
+ if pcu.reboot_trial_status == str(0):
+ status = "ok"
+ elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
+ status = pcu.reboot_trial_status
+ else:
+ status = "error"
return status
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?python
-layout_params['page_title'] = "Monitor Node View"
+layout_params['page_title'] = "Monitor Node List"
from monitor.util import diff_time
from time import mktime
?>
<tbody>
<tr py:for="i,node in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
<td></td>
- <td><a href="">${node.loginbase}</a></td>
- <td nowrap="true" py:content="node.hostname"></td>
- <td py:content="node.ping_status"></td>
- <!--td py:content="node.ssh_status"></td-->
- <td id="status-${node.pcu_short_status}" py:content="node.pcu_short_status"></td>
- <td py:content="node.observed_status"></td>
- <td nowrap="true" py:content="node.kernel"></td>
- <td py:content="diff_time(node.plc_node_stats['last_contact'])"></td>
+ <td><a href="siteview?loginbase=${node.loginbase}">${node.loginbase}</a></td>
+ <td nowrap="true"><a href="nodeview?hostname=${node.hostname}" py:content="node.hostname"></a></td>
+ <td py:content="node.ping_status"></td>
+ <td id="status-${node.pcu_short_status}" py:content="node.pcu_short_status"></td>
+ <td py:content="node.observed_status"></td>
+ <td nowrap="true" py:content="node.kernel"></td>
+ <td py:content="diff_time(node.plc_node_stats['last_contact'])"></td>
</tr>
</tbody>
</table>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?python
-layout_params['page_title'] = "Monitor Site View"
+layout_params['page_title'] = "Monitor Node View"
from monitor.util import diff_time
+from links import *
?>
<html py:layout="'sitemenu.kid'"
xmlns:py="http://purl.org/kid/ns#"
<tbody>
<tr py:for="i,node in enumerate(nodequery)" class="${i%2 and 'odd' or 'even'}" >
<td></td>
- <td><a href="">${node.loginbase}</a></td>
- <td id="node-${node.observed_status}" nowrap="true" py:content="node.hostname"></td>
+ <td><a class="ext-link" href="${plc_site_link_id(node.plc_node_stats['site_id'])}">
+ <span class="icon">${node.loginbase}</span></a>
+ </td>
+ <td id="node-${node.observed_status}" nowrap="true" >
+ <a class="ext-link" href="${plc_node_link(node.hostname)}">
+ <span class="icon">${node.hostname}</span></a>
+ </td>
<td py:content="node.ping_status"></td>
- <td id="status-${node.pcu_short_status}"><a href="pcuview?pcuid=${node.plc_node_stats['pcu_ids']}" py:content="node.pcu_short_status"></a></td>
+ <td py:if="node.pcu_short_status != 'none'" id="status-${node.pcu_short_status}">
+ <a href="pcuview?pcuid=${node.plc_node_stats['pcu_ids']}">${node.pcu_short_status}</a></td>
+ <td py:if="node.pcu_short_status == 'none'" id="status-${node.pcu_short_status}">
+ ${node.pcu_short_status}</td>
<td nowrap="true" py:content="node.kernel"></td>
<td py:content="diff_time(node.plc_node_stats['last_contact'])"></td>
</tr>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?python
-layout_params['page_title'] = "Monitor PCU View"
+layout_params['page_title'] = "Monitor PCU List"
from pcucontrol.reboot import pcu_name, model_to_object
from monitor import config
-
-def plc_site_link(pcu):
- return "https://" + config.PLC_WEB_HOSTNAME + "/db/sites/index.php?id=" + str(pcu['site_id'])
-
-def pcu_link(pcu):
- return "https://" + config.PLC_WEB_HOSTNAME + "/db/sites/pcu.php?id=" + str(pcu['pcu_id'])
-
+from links import *
?>
<html py:layout="'sitemenu.kid'"
xmlns:py="http://purl.org/kid/ns#"
<tbody>
<tr py:for="i,node in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
<td></td>
- <td><a href="${plc_site_link(node.plc_pcu_stats)}">${node.loginbase}</a></td>
+ <td><a href="${plc_site_link_id(node.plc_pcu_stats['site_id'])}">${node.loginbase}</a></td>
<td nowrap="true" >
- <a href="${pcu_link(node.plc_pcu_stats)}">${pcu_name(node.plc_pcu_stats)}</a></td>
+ <a href="${plc_pcu_link_id(node.plc_pcu_stats['pcu_id'])}">${pcu_name(node.plc_pcu_stats)}</a></td>
<td py:content="node.entry_complete"></td>
<td id="dns-${node.dns_status}" py:content="node.dns_status"></td>
<td>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?python
-layout_params['page_title'] = "Monitor Site View"
+layout_params['page_title'] = "Monitor PCU View"
from monitor.util import diff_time
from monitor import config
from pcucontrol.reboot import pcu_name, model_to_object
-def plc_site_link(pcu):
- return "https://" + config.PLC_WEB_HOSTNAME + "/db/sites/index.php?id=" + str(pcu['site_id'])
-def pcu_link(pcu):
- return "https://" + config.PLC_WEB_HOSTNAME + "/db/sites/pcu.php?id=" + str(pcu['pcu_id'])
+from links import *
?>
<html py:layout="'sitemenu.kid'"
xmlns:py="http://purl.org/kid/ns#"
<tbody>
<tr py:for="i,node in enumerate(pcuquery)" class="${i%2 and 'odd' or 'even'}" >
<td></td>
- <td><a class="ext-link" href="${plc_site_link(node.plc_pcu_stats)}">
+ <td><a class="ext-link" href="${plc_site_link_id(node.plc_pcu_stats['site_id'])}">
<span class="icon">${node.loginbase}</span>
</a>
</td>
<td nowrap="true" >
- <a class="ext-link" href="${pcu_link(node.plc_pcu_stats)}">
+ <a class="ext-link" href="${plc_pcu_link_id(node.plc_pcu_stats['pcu_id'])}">
<span class="icon">${pcu_name(node.plc_pcu_stats)}</span>
</a>
</td>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?python
-layout_params['page_title'] = "Monitor Site View"
+layout_params['page_title'] = "Monitor Site List"
?>
<html py:layout="'sitemenu.kid'"
- xmlns:py="http://purl.org/kid/ns#">
+ xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
<div py:match="item.tag == 'content'">
<table width="100%">
<tbody>
<tr>
<td colspan="5">
- <table id="sub-table" border="1" width="100%">
+ <table id="sortable_table" class="datagrid" border="1" width="100%">
<thead>
<tr>
+ <th></th>
<th>Site name</th>
<th>Status</th>
- <th>Slices (created / max)</th>
- <th>Nodes (online / registered)</th>
+ <th mochi:format="int">Slices (created / max)</th>
+ <th mochi:format="int">Nodes (online / registered)</th>
</tr>
</thead>
<tbody>
<tr py:for="i,site in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
- <td nowrap="true"><a href="siteview?loginbase=${site.loginbase}">${site.loginbase}</a></td>
- <td id="site-${site.status}" py:content="site.last_changed"></td>
- <td>${site.slices_used}/${site.slices_total}</td>
- <td>${site.nodes_up} / ${site.nodes_total}</td>
+ <td></td>
+ <td nowrap="true"><a href="siteview?loginbase=${site.loginbase}">${site.loginbase}</a></td>
+ <td id="site-${site.status}" py:content="site.last_changed"></td>
+ <td>${site.slices_used}/${site.slices_total}</td>
+ <td>${site.nodes_up} / ${site.nodes_total}</td>
</tr>
</tbody>
</table>
<head>
<title>App Name - ${page_title}</title>
<link href="static/css/style.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="${tg.tg_js}/MochiKit.js"></script>
+ <script type="text/javascript" src="tg_js/MochiKit.js"></script>
<script type="text/javascript" src="static/javascript/sortable_tables.js"></script>
</head>
<table id="nps-table" width="100%">
<thead>
<tr>
- <th><a href="${tg.url('node')}">Nodes</a></th>
- <th><a href="${tg.url('pcu')}">PCUs</a></th>
<th><a href="${tg.url('site')}">Sites</a></th>
+ <th><a href="${tg.url('pcu')}">PCUs</a></th>
+ <th><a href="${tg.url('node')}">Nodes</a></th>
<th><a href="${tg.url('action')}">Actions</a></th>
</tr>
</thead>
<?python
layout_params['page_title'] = "Monitor Site View"
from monitor.util import diff_time
+from links import *
?>
<html py:layout="'sitemenu.kid'"
xmlns:py="http://purl.org/kid/ns#"
</thead>
<tbody>
<tr py:for="i,site in enumerate(sitequery)" class="${i%2 and 'odd' or 'even'}" >
- <td nowrap="true"><a href="">${site.loginbase}</a></td>
+ <td nowrap="true"><a class="ext-link" href="${plc_site_link(site.loginbase)}">
+ <span class="icon">${site.loginbase}</span></a>
+ </td>
<td id="site-${site.status}" py:content="site.last_changed"></td>
<td py:content="site.enabled"></td>
<td>${site.slices_used}/${site.slices_total}</td>
<td></td>
<td id="node-${node.observed_status}" nowrap="true"><a href="nodeview?hostname=${node.hostname}" py:content="node.hostname">your.host.org</a></td>
<td py:content="node.ping_status"></td>
- <td id="status-${node.pcu_short_status}" py:content="node.pcu_short_status"></td>
+ <td py:if="node.pcu_short_status != 'none'" id="status-${node.pcu_short_status}">
+ <a href="pcuview?pcuid=${node.plc_node_stats['pcu_ids']}">${node.pcu_short_status}</a></td>
+ <td py:if="node.pcu_short_status == 'none'" id="status-${node.pcu_short_status}">
+ ${node.pcu_short_status}</td>
<td nowrap="true" py:content="node.kernel"></td>
<td py:content="diff_time(node.plc_node_stats['last_contact'])"></td>
</tr>
return
+# NOTE: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+## These functions can ONLY be run when the server and gui are offline.
+## Any changes to the db while this is running risks introducing a failure
+## to commit, and therefore error.
+# NOTE: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
def setup_global():
# GLOBAL:
# update mediatype for email.
# copying that the php code does during a host add.
# NOTE: Instead, reformat any *xml.in templates and import those
# during /etc/plc.d/monitor sync
- for file in glob.glob("%s/zabbix/templates/*.xml.in" config.MONITOR_SCRIPT_ROOT):
+ for file in glob.glob("%s/zabbix/templates/*.xml.in" % config.MONITOR_SCRIPT_ROOT):
if 'zabbix_server' in file:
buf = loadFile(file)
args = {'hostname' : config.MONITOR_HOSTNAME, 'ip' : config.MONITOR_IP}