...
 
Commits (5)
......@@ -124,12 +124,15 @@ p.add_argument('-r', '--running', dest='only_active', action='store_true',
@functools.wraps(systemd.print_node_status)
def print_node_status(args):
nodes = args.nodes
log_lines = args.log_lines
try:
return systemd.print_node_status(nodes, print_logs=True)
return systemd.print_node_status(nodes, log_lines=log_lines)
except util.GuardCtrlError as e:
sys.exit(e)
gen_subparser('status', print_node_status, node_nargs='*')
p.add_argument('-l', '--lines', dest='log_lines', action='store_true',
help="number of log tail lines to include")
@functools.wraps(systemd.enable_nodes)
......
......@@ -137,7 +137,7 @@ def list_nodes(node_filter='*', only_active=False, include_status=False):
return nodes
def print_node_status(nodes=None, print_logs=True):
def print_node_status(nodes=None, log_lines=None):
"""Print node service status.
With no nodes specified displays full system status with process
......@@ -147,10 +147,12 @@ def print_node_status(nodes=None, print_logs=True):
"""
nodes = list_nodes(nodes)
args = ['status', '--quiet', '--no-pager']
if not log_lines and len(nodes) > 1:
log_lines = 0
if log_lines is not None:
args += ['--line', str(log_lines)]
if not nodes:
args += ['guardian.slice']
if not print_logs:
args += ['--line', '0']
try:
systemctl_cmd(*args, nodes=nodes)
except SystemctlError:
......
......@@ -3,6 +3,8 @@ import copy
import pcaspy
import threading
from pcaspy.driver import manager
from . import const
from .db import guarddb
......@@ -24,6 +26,18 @@ class CADriver(pcaspy.Driver):
##########
# HACK: this function allows for updating the enum of an enum
# channel without having to reload the entire database.
# See https://code.google.com/p/pcaspy/issues/detail?id=7
# WARNING: THIS IS NOT BASED ON ANY PUBLIC API!
# This function is now implemented in in pcaspy 0.5.1, so this
# function should be removed when using that version or later.
def setParamEnums(self, channel, enums):
pv = manager.pvs[self.port][channel]
pv.info.enums = enums
##########
def __getitem__(self, channel):
value = self.getParam(channel)
if guarddb[channel]['type'] == 'enum':
......@@ -98,16 +112,14 @@ class CADriver(pcaspy.Driver):
# updatePVs(). This is usually not needed during write(),
# since the values being written are already externally
# up-to-date when write() is executed. However, since we're
# updating auxilliary records during write() (e.g. state
# readbacks), we need to run updatePVs() for those aux
# channels to be updated. This then causes the write()
# channels to be double updated, which in turn causes
# connected clients to see two updates. Setting flag=False
# for the original write channel prevents this double update
# from happening. This should probably be fixed upstream.
# UPDATE: this does not seem to work in pcaspy 0.7, and
# instead causes channels to not show updates properly
#self.pvDB[channel].flag = False
# updating auxilliary records during write(), we need to run
# updatePVs() for those aux channels to be updated. This then
# causes the write() channels to be double updated, which in
# turn causes connected clients to see two updates. Setting
# flag=False for the original write channel prevents this
# double update from happening. This should probably be fixed
# upstream.
self.pvDB[channel].flag = False
self.updatePVs()
return True
......@@ -122,10 +134,11 @@ class CAServer(threading.Thread):
#self._server.setDebugLevel(4)
self._loaddb()
self._driver = CADriver(self._request_event)
# clear undefined alarms at startup
# clear initial alarms causing UDF.INVALID status
# FIXME: this should not be necessary, as the alarm states
# should already be initalized properly. pcaspy bug?
for chan in guarddb:
self._driver.setParamStatus(chan, pcaspy.Severity.NO_ALARM, pcaspy.Severity.NO_ALARM)
self._driver.updatePVs()
self._running = True
self.daemon = True
......@@ -159,7 +172,6 @@ class CAServer(threading.Thread):
if enum != guarddb['REQUEST_ENUM']['enums']:
guarddb['REQUEST_ENUM']['enums'] = enum
self._driver.setParamEnums('REQUEST_ENUM', enum)
self._driver.updatePVs()
if not init:
# update request enum, in case it's changed
self['REQUEST_ENUM'] = self['REQUEST']
......
......@@ -404,15 +404,16 @@ def print_history(args):
"""Print state history around specified time (NDS)."""
from gpstime import gpstime
system = cli.init_system(args, load=True)
channel = const.CAS_PREFIX_FMT.format(system.ifo, system.name) + 'STATE_N'
channel = const.CAS_PREFIX_FMT.format(IFO=system.ifo, SYSTEM=system.name) + 'STATE_N'
time0 = gpstime.parse(args.time0)
if args.time1:
t0 = int(gpstime.parse(args.time0).gps())
t0 = int(time0.gps())
t1 = int(gpstime.parse(args.time1).gps())
else:
ct = gpstime.parse(args.time0)
window = eval(args.window)
t0 = int(ct.gps() + window[0])
t1 = int(ct.gps() + window[1])
t0 = int(time0.gps() + window[0])
t1 = int(time0.gps() + window[1])
print("NDS fetch: {} -> {}".format(t0, t1), file=sys.stderr)
conn = nds_connection()
buf = conn.fetch(t0, t1, [channel])
buf = buf[0]
......@@ -424,8 +425,11 @@ def print_history(args):
return buf.gps_seconds + i*(1./buf.channel.sample_rate)
def stime(gt):
"""gpstime string"""
if args.gps:
return '%.6f' % gt.gps()
if args.tfmt == 'gps':
return '{:.6f}'.format(gt.gps())
elif args.tfmt == 'delta':
td = gt.gps() - time0.gps()
return '{:.3f}'.format(td)
else:
return gt.iso()
def ptrans(last, cur):
......@@ -471,14 +475,16 @@ def print_history(args):
p = gen_subparser("print-hist", print_history)
p.add_argument('-t', '--transitions', action='store_true',
help="show state transitions rather than duration")
p.add_argument('-g', '--gps', action='store_true',
p.add_argument('-g', '--gps', action='store_const', dest='tfmt', const='delta',
help="show times in GPS")
p.add_argument('-d', '--delta', action='store_const', dest='tfmt', const='delta',
help="show times as delta relative to time0")
p.add_argument('-w', '--window', metavar='<window>', default='[-60, 60]',
help="time window if time1 not specified (default: [-60, 60])")
p.add_argument('time0', metavar='<time0>',
help="center or start time")
help="center time, or start time if time1 specified")
p.add_argument('time1', metavar='<time1>', nargs='?',
help="duration or stop time")
help="stop time")
def plot_history(args):
......
......@@ -38,7 +38,6 @@ class DummyDriver(pcaspy.Driver):
def write(self, channel, value):
print('%s => %s' % (channel, value))
self.setParam(channel, value)
self.updatePVs()
return True
if __name__ == '__main__':
......@@ -54,9 +53,9 @@ if __name__ == '__main__':
server.createPV(prefix, pvdb)
driver = DummyDriver()
# HACK: clear alarms
for k in pvdb:
driver.setParamStatus(k, pcaspy.Severity.NO_ALARM, pcaspy.Severity.NO_ALARM)
driver.updatePVs()
print("ready:")
while True:
......
......@@ -21,6 +21,7 @@ T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......@@ -58,6 +59,7 @@ T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......@@ -80,6 +82,7 @@ T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......@@ -87,6 +90,7 @@ T1:TEST-A..4..
T1:TEST-B..1..
T1:TEST-B..2..
T1:TEST-B..3..
T1:TEST-C..0..
T1:TEST-C..1..
T1:TEST-C..2..
T1:TEST-C..3..
......@@ -121,6 +125,7 @@ T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......@@ -128,6 +133,7 @@ T1:TEST-A..4..
T1:TEST-B..1..
T1:TEST-B..2..
T1:TEST-B..3..
T1:TEST-C..0..
T1:TEST-C..1..
T1:TEST-C..2..
T1:TEST-C..3..
......
......@@ -93,6 +93,7 @@ T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..A..
......@@ -148,6 +149,7 @@ T1:GRD-TEST_STATE..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..REDIRECT..
T1:GRD-TEST_STATUS..EDGE..
......@@ -167,7 +169,10 @@ T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-C..1..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......@@ -210,6 +215,7 @@ T1:GRD-TEST_STATE..D..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..Z..
......@@ -229,6 +235,10 @@ T1:TEST-D..0..
T1:TEST-D..1..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
......
......@@ -75,6 +75,7 @@ T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
......@@ -148,6 +149,7 @@ T1:TEST-C..0..
T1:TEST-C..2..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
EOF
test_expect_equal_file OUTPUT EXPECTED
......@@ -211,6 +213,7 @@ T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
EOF
test_expect_equal_file OUTPUT EXPECTED
......@@ -278,6 +281,7 @@ T1:TEST-C..3..
T1:TEST-C..2..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
EOF
test_expect_equal_file OUTPUT EXPECTED
......@@ -320,6 +324,7 @@ T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..C..
T1:GRD-TEST_STATUS..REDIRECT..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
......