inform user about possible device change
taking into account cfg retrieved from frappy and sea service manager
This commit is contained in:
206
commands.py
206
commands.py
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
@@ -20,124 +19,15 @@
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
import sys
|
||||
from os.path import expanduser, basename, join
|
||||
from configparser import ConfigParser
|
||||
|
||||
from nicos import session, config
|
||||
from nicos.core import status
|
||||
from nicos.utils import printTable
|
||||
from nicos.commands import helparglist, usercommand
|
||||
from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice
|
||||
from nicos.devices.secop.devices import get_attaching_devices
|
||||
from nicos_sinq.frappy_sinq.devices import applyAliasConfig, FrappyNode
|
||||
|
||||
|
||||
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 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 = []
|
||||
addkwd = False
|
||||
for srv in SERVICES:
|
||||
cfginfo = all_cfg.get(srv)
|
||||
if cfginfo is None:
|
||||
addkwd = True
|
||||
elif addkwd:
|
||||
info.append('%s=%r' % (srv, cfginfo))
|
||||
else:
|
||||
info.append(repr(cfginfo))
|
||||
result = 'frappy(%s)' % ', '.join(info)
|
||||
if '?' in result:
|
||||
result += ' (?: device from sea has no frappy cfg file)'
|
||||
return result
|
||||
|
||||
|
||||
def frappy_start(**services):
|
||||
"""start/stop frappy servers
|
||||
|
||||
for example: frappy_start(main='xy', stick='')
|
||||
- restart main server with cfg='xy'
|
||||
- stop stick server
|
||||
- do not touch addons server
|
||||
|
||||
in addition, if a newly given cfg is already used on a running server,
|
||||
this cfg is removed from the server (remark: cfg might be a comma separated list)
|
||||
"""
|
||||
frappy_config = session.devices.get('frappy_config')
|
||||
for service in SERVICES:
|
||||
if services.get(service) == '':
|
||||
seaconn = session.devices.get(f'se_sea_{service}')
|
||||
if seaconn and seaconn._attached_secnode:
|
||||
seaconn.communicate('frappy_remove %s' % service)
|
||||
used_cfg = {}
|
||||
all_cfg = {}
|
||||
new_cfg = []
|
||||
remove_cfg = []
|
||||
for service in reversed(SERVICES):
|
||||
secnode = session.devices.get('se_' + service)
|
||||
cfginfo = services.get(service)
|
||||
if cfginfo is not None:
|
||||
if cfginfo:
|
||||
new_cfg.append((service, secnode, cfginfo))
|
||||
else:
|
||||
remove_cfg.append(secnode)
|
||||
if secnode:
|
||||
secnode('')
|
||||
if secnode:
|
||||
all_cfg[service] = secnode.get_info()
|
||||
|
||||
# check cfg is not used twice
|
||||
for cfg in (cfginfo or '').split(','):
|
||||
cfg = cfg.strip()
|
||||
if cfg:
|
||||
prev = used_cfg.get(cfg)
|
||||
if prev:
|
||||
raise ValueError('%r can not be used in both %s and %s' % (cfg, prev, service))
|
||||
used_cfg[cfg] = service
|
||||
|
||||
if new_cfg:
|
||||
for service, secnode, cfginfo in new_cfg:
|
||||
nodename = 'se_' + service
|
||||
if not secnode:
|
||||
AddSetup('frappy_' + service)
|
||||
secnode = session.devices[nodename]
|
||||
secnode(cfginfo)
|
||||
all_cfg[service] = secnode.get_info()
|
||||
CreateDevice(nodename)
|
||||
cleanup_defunct()
|
||||
CreateAllDevices()
|
||||
if frappy_config:
|
||||
frappy_config.set_envlist()
|
||||
else:
|
||||
applyAliasConfig()
|
||||
for secnode in remove_cfg:
|
||||
secnode.disable()
|
||||
return all_cfg
|
||||
|
||||
|
||||
@usercommand
|
||||
def set_se_list():
|
||||
frappy_config = session.devices['frappy_config']
|
||||
@@ -146,34 +36,37 @@ def set_se_list():
|
||||
|
||||
@usercommand
|
||||
@helparglist('main [, stick [, addons]]')
|
||||
def frappy(*args, main=None, stick=None, addons=None):
|
||||
def frappy(*args, main=None, stick=None, addons=None, force=False):
|
||||
"""(re)start frappy server(s) with given configs and load setup if needed
|
||||
|
||||
- without argument: list running frappy servers, restart failed frappy servers
|
||||
- frappy('<cfg>'): if available, the standard stick is added too
|
||||
- frappy(''): the stick is removed too
|
||||
- addons are not changed when not given
|
||||
- frappy(main='<cfg>') # main cfg is changed, but stick is kept
|
||||
- frappy(main='<cfg>') # main cfg is changed, but stick is kept
|
||||
- frappy('restart') # restart all frappy servers
|
||||
- frappy(stick='restart') # restart stick frappy server
|
||||
"""
|
||||
seacfg = FrappyManager().cfg_from_sea(config.instrument)
|
||||
confirmed = FrappyManager().cfg_from_sea(config.instrument).get('confirmed')
|
||||
if args:
|
||||
if main is not None:
|
||||
raise TypeError('got multiple values for main')
|
||||
main = args[0]
|
||||
if len(args) == 1: # special case: main given as single argument
|
||||
if stick is None: # auto stick
|
||||
if main == 'restart':
|
||||
stick = 'restart'
|
||||
addons = 'restart'
|
||||
elif stick is None: # auto stick
|
||||
if main == '':
|
||||
stick = '' # remove stick with main
|
||||
else:
|
||||
allsticks = FrappyManager().all_cfg(config.instrument, 'stick')
|
||||
if seacfg.get('main') != main:
|
||||
# main sea device has changed
|
||||
stickcfg = main + 'stick'
|
||||
if stickcfg in allsticks:
|
||||
# if a default stick is available, start this also
|
||||
stick = stickcfg
|
||||
else:
|
||||
stick = '' # remove stick when main has changed
|
||||
stickcfg = main + 'stick'
|
||||
if stickcfg in allsticks:
|
||||
# if a default stick is available, start this also
|
||||
stick = stickcfg
|
||||
else:
|
||||
stick = '' # remove stick when main has changed
|
||||
else:
|
||||
if stick is not None:
|
||||
raise TypeError('got multiple values for stick')
|
||||
@@ -182,63 +75,12 @@ def frappy(*args, main=None, stick=None, addons=None):
|
||||
if addons is not None:
|
||||
raise TypeError('got multiple values for addons')
|
||||
addons = ','.join(alist)
|
||||
allcfg = frappy_start(main=main, stick=stick, addons=addons)
|
||||
session.log.info('currently configured %s', all_info(allcfg))
|
||||
else:
|
||||
allcfg = frappy_start(main=main, stick=stick, addons=addons)
|
||||
session.log.info('currently configured %s', all_info(allcfg))
|
||||
guess1 = {}
|
||||
guess2 = {}
|
||||
for s in SERVICES:
|
||||
info = allcfg.get(s, '')
|
||||
prev = info.split(' ', 1)[0]
|
||||
if prev != info:
|
||||
guess1[s] = prev
|
||||
guess2[s] = prev
|
||||
fromsea = seacfg.get(s)
|
||||
if fromsea and fromsea != prev:
|
||||
guess2[s] = fromsea
|
||||
if guess1 and guess2:
|
||||
session.log.info('please consider to call one of:')
|
||||
elif guess1 or guess2:
|
||||
session.log.info('please consider to call:')
|
||||
if guess1:
|
||||
session.log.info('from frappy / cache: %s', all_info(guess1))
|
||||
if guess2:
|
||||
session.log.info('including info from sea: %s', all_info(guess2))
|
||||
|
||||
|
||||
@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
|
||||
"""
|
||||
session.log.info('currently configured %s', all_info(frappy_start(main=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('currently configured %s', 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('currently configured %s', all_info(frappy_start(addons=cfg)))
|
||||
if confirmed and confirmed != main and not force:
|
||||
session.log.warning('%r is plugged to the cryostat control rack', confirmed)
|
||||
session.log.warning('if you are sure, use frappy(..., force=True)', confirmed)
|
||||
raise TypeError('refuse to override plugged device')
|
||||
frappy_config = session.devices['frappy_config']
|
||||
frappy_config.show_config(*frappy_config.check_or_start(main, stick, addons))
|
||||
|
||||
|
||||
@usercommand
|
||||
@@ -250,8 +92,6 @@ def frappy_list(service=None):
|
||||
def prt(line):
|
||||
content.append(line)
|
||||
|
||||
# TODO: remove next line
|
||||
bases = list(dict.fromkeys(expanduser(p) for p in FrappyNode.config_dirs(config.instrument, service or 'main')))
|
||||
if service is None:
|
||||
prt('Available configuration files')
|
||||
prt('')
|
||||
@@ -265,3 +105,7 @@ def frappy_list(service=None):
|
||||
FrappyManager().do_listcfg(config.instrument, service or 'main', prt)
|
||||
session.log.info('\n%s', '\n'.join(content))
|
||||
|
||||
|
||||
@usercommand
|
||||
def frappy_changed():
|
||||
session.devices['frappy_config'].changed()
|
||||
|
||||
Reference in New Issue
Block a user