move files in from repo git.psi.ch/sinqdev/nicos-sinq
This commit is contained in:
207
commands.py
Normal file
207
commands.py
Normal file
@@ -0,0 +1,207 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Module authors:
|
||||
# Markus Zolliker <markus.zolliker@psi.ch>
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
import sys
|
||||
from os.path import expanduser, basename, join
|
||||
from glob import glob
|
||||
from configparser import ConfigParser
|
||||
|
||||
from nicos import session, config
|
||||
from nicos.utils import printTable
|
||||
from nicos.commands import helparglist, usercommand
|
||||
from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice
|
||||
from nicos.devices.secop import get_attaching_devices
|
||||
|
||||
home = expanduser('~')
|
||||
if home not in sys.path:
|
||||
# the first Frappy installations have /home/nicos in the PYTHONPATH in nicos.conf
|
||||
# for newer Frappy installations this should be home (= /home/<instrument>)
|
||||
# the following line fixes this in case nicos.conf is not yet updated
|
||||
sys.path.append(home)
|
||||
from nicos_sinq.frappy.devices import FrappyNode
|
||||
from servicemanager import FrappyManager
|
||||
|
||||
|
||||
def cleanup_defunct():
|
||||
for devname, setupname in list(session.dynamic_devices.items()):
|
||||
dev = session.devices.get(devname)
|
||||
if dev and dev._defunct:
|
||||
devnames = [d.name for d, _ in get_attaching_devices(dev)]
|
||||
if devnames:
|
||||
session.log.warning('can not remove device %r due to dependencies on %s'
|
||||
% (devname, ', '.join(devnames)))
|
||||
else:
|
||||
session.destroyDevice(devname)
|
||||
session.dynamic_devices.pop(devname, None)
|
||||
|
||||
|
||||
SERVICES = FrappyManager.services
|
||||
|
||||
|
||||
def all_info(all_cfg):
|
||||
info = []
|
||||
for srv, cfginfo in all_cfg.items():
|
||||
if cfginfo is not None:
|
||||
info.append('frappy_%s(%r)' % (srv, cfginfo))
|
||||
return 'currently configured: %s' % ', '.join(info)
|
||||
|
||||
|
||||
def applyAliasConfig():
|
||||
"""Apply the desired aliases from session.alias_config."""
|
||||
# reimplemented from Session.applyAliasConfig
|
||||
# apply also when target dev name does not change, as the target device might have
|
||||
# be exchanged in the mean time
|
||||
for aliasname, targets in session.alias_config.items():
|
||||
if aliasname not in session.devices:
|
||||
# complain about this; setups should make sure that the device
|
||||
# exists when configuring it
|
||||
session.log.warning("alias device '%s' does not exist, cannot set"
|
||||
' its target', aliasname)
|
||||
continue
|
||||
aliasdev = session.getDevice(aliasname)
|
||||
for target, _ in sorted(targets, key=lambda t: -t[1]):
|
||||
if target in session.devices:
|
||||
try:
|
||||
aliasdev.alias = target
|
||||
except Exception:
|
||||
session.log.exception("could not set '%s' alias", aliasdev)
|
||||
break
|
||||
else:
|
||||
session.log.warning('none of the desired targets for alias %r '
|
||||
'actually exist', aliasname)
|
||||
|
||||
|
||||
def frappy_start(service, cfg=None):
|
||||
if service not in SERVICES:
|
||||
raise ValueError('unknown service %s' % service)
|
||||
if cfg == '':
|
||||
seaconn = session.devices.get('seaconn')
|
||||
if seaconn and seaconn._attached_secnode:
|
||||
seaconn.communicate('frappy_remove %s' % service)
|
||||
startnode = None
|
||||
all_cfg = {}
|
||||
for srv in SERVICES:
|
||||
nodename = 'se_' + srv
|
||||
secnode = session.devices.get(nodename)
|
||||
|
||||
cfginfo = None if secnode is None else secnode()
|
||||
if srv == service:
|
||||
if cfg is not None:
|
||||
if cfg and not secnode:
|
||||
AddSetup('frappy_' + service)
|
||||
secnode = session.devices[nodename]
|
||||
if cfginfo:
|
||||
secnode('')
|
||||
startnode = secnode
|
||||
cfginfo = cfg
|
||||
elif cfg and cfginfo:
|
||||
# remark: cfg might be a comma separated list of configurations
|
||||
ourcfg = set(cfg.split(','))
|
||||
other = set(cfginfo.split(','))
|
||||
both = other & ourcfg
|
||||
if both:
|
||||
# remove ourcfg from other
|
||||
cfginfo = ','.join(other - ourcfg)
|
||||
# stop other server with the same cfg
|
||||
# or restart with remaining cfgs
|
||||
secnode(cfginfo)
|
||||
all_cfg[srv] = cfginfo
|
||||
if startnode and cfg:
|
||||
startnode(cfg)
|
||||
CreateDevice(str(startnode))
|
||||
if cfg is not None:
|
||||
cleanup_defunct()
|
||||
CreateAllDevices()
|
||||
applyAliasConfig()
|
||||
if startnode and cfg == '':
|
||||
startnode.disable()
|
||||
return all_cfg
|
||||
|
||||
|
||||
@usercommand
|
||||
@helparglist('cfg')
|
||||
def frappy_main(cfg=None):
|
||||
"""(re)start frappy_main server with given cfg and load setup if needed
|
||||
|
||||
- without argument: list running frappy servers
|
||||
- cfg = "": stop frappy_main server
|
||||
"""
|
||||
all_cfg = frappy_start('main', cfg)
|
||||
if cfg:
|
||||
stickcfg = cfg + 'stick'
|
||||
if stickcfg in FrappyNode.available_cfg('stick'):
|
||||
# if a default stick is available, start this also
|
||||
all_cfg = frappy_start('stick', stickcfg)
|
||||
session.log.info(all_info(all_cfg))
|
||||
|
||||
|
||||
@usercommand
|
||||
@helparglist('cfg')
|
||||
def frappy_stick(cfg=None):
|
||||
"""(re)start frappy_stick server with given cfg and load setup if needed
|
||||
|
||||
- without argument: list running frappy servers
|
||||
- cfg = "": stop frappy_stick server
|
||||
"""
|
||||
session.log.info(all_info(frappy_start('stick', cfg)))
|
||||
|
||||
|
||||
@usercommand
|
||||
@helparglist('cfg,...')
|
||||
def frappy_addons(cfg=None):
|
||||
"""(re)start frappy_addons server with given cfg and load setup if needed
|
||||
|
||||
- without argument: list running frappy servers
|
||||
- cfg = "": stop frappy_addons server
|
||||
"""
|
||||
session.log.info(all_info(frappy_start('addons', cfg)))
|
||||
|
||||
|
||||
@usercommand
|
||||
@helparglist('')
|
||||
def frappy_list(service=None):
|
||||
"""list available configuration files"""
|
||||
table = []
|
||||
bases = list(dict.fromkeys(expanduser(p) for p in FrappyNode.config_dirs(config.instrument, service or 'main')))
|
||||
if service is None:
|
||||
session.log.info('Available configuration files')
|
||||
session.log.info(' ')
|
||||
session.log.info('Hint: if no config file can be found which matches your needs exactly')
|
||||
session.log.info('make a copy of an existing one, and change the description accordingly')
|
||||
session.log.info(' ')
|
||||
session.log.info('Usage (default argument "main"):')
|
||||
session.log.info(' ')
|
||||
printTable(['command'], [['frappy_list(%r)' % s] for s in SERVICES], session.log.info)
|
||||
session.log.info(' ')
|
||||
for cfgdir in bases:
|
||||
for cfgfile in glob(join(cfgdir, '*.cfg')):
|
||||
parser = ConfigParser()
|
||||
parser.read(cfgfile)
|
||||
desc = ''
|
||||
for s in parser.sections():
|
||||
if s == 'NODE' or s.startswith('node '):
|
||||
desc = parser[s].get('description', '').split('\n')[0]
|
||||
break
|
||||
table.append([basename(cfgfile)[:-4], desc])
|
||||
printTable(['cfg file', 'description'], table, session.log.info)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user