# -*- 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 # # ***************************************************************************** import sys import time import termios import subprocess import os import re from os.path import join, exists from servicemanager.base import ServiceManager, ServiceDown, UsageError CFGLINE = re.compile(r'(device makeitem (name|stick_name) "(.*)" ""|' r'addon_list makeitem (.*) ("permanent"|"volatile"))') def run_command(cmd, wait=False): if wait: old = termios.tcgetattr(sys.stdin) proc = subprocess.Popen(cmd.split()) try: proc.wait() except KeyboardInterrupt: proc.terminate() finally: # in case cmd changed tty attributes termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, old) print('') else: subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) class SeaManager(ServiceManager): group = 'sea' services = ('sea', 'graph') USAGE = """ Usage: sea gui sea # the same as sea gui sea cli # the same as old seacmd sea start [service] * # the same as old 'monit start sea' sea restart [service] * sea stop [service] * sea list [instance] * [service] is empty or one of sea, graph %s * wildcards allowed, using '.' to replace 0 or more arbitrary characters in """ def do_cli(self, ins): if self.wildcard(ins): raise UsageError('wildcards not allowed in sea cli') try: self.check_running(ins, 'sea') except ServiceDown as e: self.do_help() print(str(e)) except KeyError: # running on an other machine? self.do_help() run_command('six -sea %s' % ins, wait=True) def do_gui(self, ins='', *args): if ins and self.wildcard(ins): raise UsageError('wildcards not allowed in sea gui') if ins: args = (ins,) + args if '-q' not in args: try: self.check_running(ins, 'sea') except ServiceDown as e: self.do_help() print(str(e)) return except KeyError: # running on an other machine? self.do_help() run_command('SeaClient %s' % ' '.join(args)) print('starting sea gui %s' % ' '.join(args)) time.sleep(5) def prepare_start(self, ins, service, *args): start_dir, env = super().prepare_start(ins, service) # load newest version of SeaServer if needed os.chdir(start_dir) sea_server_src = os.environ.get( 'SEA_SERVER_SRC', '/afs/psi.ch/user/z/zolliker/public/git.rhel7/sics/SeaServer') if sea_server_src and exists(sea_server_src): if os.system('diff %s SeaServer' % sea_server_src): print('reload SeaServer') os.rename('SeaServer', 'SeaServer0') os.system('cp %s ./' % sea_server_src) return start_dir, env def get_cfg(self, ins, service): """return cfg info about running programs, if relevant return samenv name """ if service != 'sea': # ignore when service == 'graph' return '' try: searoot = self.env[ins].get('SEA_ROOT', '') seastatus = join(searoot, ins, 'status', 'seastatus.tcl') if not exists(seastatus): seastatus = join(searoot, 'status', 'seastatus.tcl') if not exists(seastatus): return '?' result = ['', ''] with open(seastatus, 'r', encoding='utf-8') as f: for line in f: match = CFGLINE.match(line) if match: _, key, dev, addon, _ = match.groups() if addon: if addon != result[1]: result.append(addon) elif key == 'name': result[0] = dev else: result[1] = dev if not result[-1]: result.pop() return '/'.join(result) except Exception as e: return repr(e) def treat_args(self, argdict, unknown=(), extra=()): extra = list(extra) for arg in unknown: if arg == '-q' and arg not in extra: extra.append(arg) continue if argdict.get('ins'): raise UsageError('superflous argument: %s' % arg) insts = set() filename = os.environ.get('InstrumentHostList') if filename: with open(filename) as fil: for line in fil: inst = '' sea = False for item in line.split(): key, _, value = item.partition('=') if key == 'instr': inst = value elif key == 'sea': sea = True if inst and sea: insts.add(inst) if arg in insts: argdict['ins'] = arg else: raise UsageError('unknown argument: %s' % arg) return [argdict.pop('ins', '')] + extra