191 lines
6.7 KiB
Python
191 lines
6.7 KiB
Python
# -*- 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_sinq.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 frappy_start(service, cfg=None):
|
|
if service not in SERVICES:
|
|
raise ValueError('unknown service %s' % service)
|
|
frappy_config = session.devices['frappy_config']
|
|
frappy_config.remove_aliases()
|
|
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()
|
|
frappy_config.set_envlist()
|
|
if startnode and cfg == '':
|
|
startnode.disable()
|
|
return all_cfg
|
|
|
|
|
|
@usercommand
|
|
def set_se_list():
|
|
frappy_config = session.devices['frappy_config']
|
|
frappy_config.set_envlist()
|
|
|
|
|
|
@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)
|
|
|
|
|