# ***************************************************************************** # # 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 # # ***************************************************************************** from nicos import session, config from nicos.utils import printTable from nicos.commands import helparglist, usercommand from .devices import get_frappy_config, all_info from servicemanager import FrappyManager, SeaManager SERVICES = FrappyManager.services def all_info(all_cfg, prefix='currently configured: '): 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)) return f"{prefix}frappy({', '.join(info)})" 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(): fc = get_frappy_config() if fc: fc.set_envlist() @usercommand @helparglist('main [, stick [, addons]]') 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(''): if available, the standard stick is added too - frappy(''): the stick is removed too - addons are not changed when not given - frappy(main='') # main cfg is changed, but stick is kept - frappy('restart') # restart all frappy servers - frappy(stick='restart') # restart stick frappy server """ fc = get_frappy_config() if not fc: return stickarg = stick confirmed = SeaManager().get_cfg(config.instrument, 'sea', True).split('/', 1)[0] 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 main == 'restart': stick = 'restart' addons = 'restart' elif stick is None: # auto stick if main == '': stick = '' # remove stick with main else: stickcfg = main + 'stick' if FrappyManager().is_cfg(config.instrument, 'stick', stickcfg): # 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') stick, *alist = args[1:] if alist: if addons is not None: raise TypeError('got multiple values for addons') addons = ','.join(alist) elif main is None and stick is None and addons is None: # bare frappy() command fc.show_config(fc.check_services()) return if confirmed and confirmed != main and main not in (None, 'restart') and not force: session.log.warning('%r is plugged to the cryostat control rack', confirmed) cmd = all_info({'main': main, 'stick': stickarg, 'addons': addons}, '')[:-1] + ', force=True)' session.log.warning(f'if you are sure, use: %s', cmd) raise TypeError('refuse to override plugged device') fc.show_config(fc.start_services(main, stick, addons)) @usercommand def frappy_main(*args): raise NameError('frappy_main() is no longer avaiable, use frappy() instead') @usercommand def frappy_stick(*args): raise NameError('frappy_stick() is no longer avaiable, use frappy(stick=) instead') @usercommand def frappy_addons(*args): raise NameError('frappy_addons() is no longer avaiable, use frappy(addons=) instead') @usercommand @helparglist('') def frappy_list(service=None): """list available configuration files""" content = [] def prt(line): content.append(line) if service is None: prt('Available configuration files') prt('') prt('Hint: if no config file can be found which matches your needs exactly') prt('make a copy of an existing one, and change the description accordingly') prt('') prt('Usage (default argument "main"):') prt('') printTable(['command'], [['frappy_list(%r)' % s] for s in SERVICES], prt) FrappyManager().do_listcfg(config.instrument, service or 'main', prt) session.log.info('\n%s', '\n'.join(content)) @usercommand def frappy_changed(): fc = get_frappy_config() if fc: fc.changed()