#!/usr/bin/env python
'''
Python script to handle daq sessions using MIDAS/PSI.
Auther: Exaos Lee <Exaos DOT Lee AT gmail DOT com>
Date: 2009-07-15
'''
import os, os.path
import sys, signal, time
from commands import getoutput
from ConfigParser import ConfigParser
from pprint import pprint
class mdaq:
_codes_ = { 'MSERVER':"MIDAS Server", 'MHTTPD':"MIDAS HTTPD Server",
'ODBEDIT':"ODB Editor", 'LOGGER':"Data Logger",
'PROG_FE':"Frontend", 'PROG_ANA':"Analyzer" }
_env_ = dict()
def __init__(self,**kws):
env = dict()
if kws.has_key('fname') and kws['fname'] != "":
env = self.parse_conf(kws['fname'])
self.apply_env(env)
def parse_conf(self, fname):
if not os.path.isfile(fname):
print("**WARNING** File \"%s\" does not exist!"%fname)
return None
conf = ConfigParser()
conf.read(fname)
env={'CONF_FILE':fname }
fcpath = os.path.dirname(fname)
sec = 'EXP_INFO' ## Parsing Experiment Information
env['EXP_INFO'] = [ self.safe_parse(conf,sec,'Name'),
self.safe_parse(conf,sec,'Info'), ]
msg = self.safe_parse(conf,sec,'DAQ_DIR')
if msg != "" and os.path.isdir(msg):
dpath = msg
if not os.path.isabs(msg):
dpath = os.path.join(os.path.abspath(fcpath),msg)
env['DAQ_DIR'] = os.path.normpath(dpath)
## Parsing MIDAS configuration
env['MIDASSYS'] = ["MIDAS System Path",
self.safe_parse(conf,"MIDAS","MIDASSYS")]
if env['MIDASSYS'][1]=="": env['MIDASSYS'][1] = self.get_default_msys()
## Parsing Info of programs
for key in self._codes_.keys():
code = self.parse_prog_opt(conf, key, fpath=fcpath)
if code:
env[key] = [self._codes_[key], ]
env[key].extend(code)
port = self.safe_parse(conf, "MHTTPD","PORT")
if port != "":
if not env.has_key('MHTTPD'):
env['MHTTPD'] = ["MIDAS HTTP Server",
os.path.join(env['MIDASSYS'][1],"bin/mhttpd"),
"-h localhost -D"]
if "-p %s"%port not in env['MHTTPD'][2]:
env['MHTTPD'][2] = env['MHTTPD'][2] + " -p %s"%port
return env
def parse_prog_opt(self, cnf, sec, fpath="./"):
name = self.safe_parse(cnf, sec, "NAME")
path = self.safe_parse(cnf, sec, "PATH")
fn = os.path.join(path,name)
if name == "": fn = ""
elif not os.path.isabs(fn):
fn = os.path.normpath(os.path.join(os.path.abspath(fpath),fn))
else:
fn = os.path.normpath(fn)
opts = self.safe_parse(cnf, sec, "Option")
if opts != "" or name != "":
return [fn, opts]
return None
def safe_parse(self, cnf, sec, opt):
try: return cnf.get(sec,opt)
except: return ""
def get_default_msys(self):
if os.environ.has_key('MIDASSYS'): return os.environ['MIDASSYS']
return "/opt/MIDAS.PSI/Version/Current"
def apply_env(self, daq_env=dict()):
env = daq_env
if not env:
print("** WARNING** No environment defined! Using the default values. ****")
env = {'MIDASSYS':['MIDAS System Path', ""], 'CONF_FILE':"", }
if not env.has_key('MIDASSYS'): env['MIDASSYS'] = ['MIDAS System Path',""]
if env['MIDASSYS'][1]=="": env['MIDASSYS'][1] = self.get_default_msys()
def_env = {
'MSERVER' :["MIDAS Server",
os.path.join(env['MIDASSYS'][1],"bin/mserver"),
"-D", True],
'MHTTPD' :["MIDAS HTTP Server",
os.path.join(env['MIDASSYS'][1],"bin/mhttpd"),
"-h localhost -D -p 8080", True],
'ODBEDIT' :["ODB Editor",
os.path.join(env['MIDASSYS'][1],"bin/odbedit"),
"-c clean", False],
'LOGGER' :["Data Logger",
os.path.join(env['MIDASSYS'][1],"bin/mlogger"),
"", True],
'PROG_FE' :["Frontend","", "", True],
'PROG_ANA':["Analyzer","", "", True],
'EXP_INFO':["test","The test experiment"],
'DAQ_DIR':os.path.join(os.environ['HOME'],"online/test") }
for key in def_env.keys():
if not env.has_key(key): env[key] = def_env[key]
for key in self._codes_.keys():
if env[key][1] == "": env[key][1] = def_env[key][1]
if env[key][2] == "": env[key][2] = def_env[key][2]
if not os.path.isdir(env['DAQ_DIR']):
try: os.makedirs(env['DAQ_DIR'])
except: print("ERROR to make file")
## Asign default program options
exp_opt = "-e %s"%env['EXP_INFO'][0]
for key in ['LOGGER', 'PROG_FE', 'PROG_ANA', "MHTTPD"]:
if exp_opt not in env[key][2]:
env[key][2] = exp_opt + ' ' + env[key][2]
if "-D" not in env[key][2]:
env[key][2] = env[key][2] + ' -D'
if exp_opt not in env['ODBEDIT'][2]:
env['ODBEDIT'][2] = env['ODBEDIT'][2] + ' ' + exp_opt
self._env_ = env
def print_conf(self):
print "\n================= DAQ Config ====================="
for key in self._env_.keys():
print key,": ",
pprint(self._env_[key])
def info(self): self.print_conf()
## running programs
def getpids(self, pname):
return [int(k) for k in getoutput("pidof %s"%pname).strip().split()]
def kill_prog(self,pname):
for i in self.getpids(pname): os.kill(i,signal.SIGTERM)
def run_prog(self, prog):
if len(prog)>=4 and not prog[3]: return
if len(prog)>=3 and prog[1]:
print("Starting %s: %s"%(prog[0],prog[1]))
os.system("%s %s"%(prog[1],prog[2]))
else:
print("%s: no executable exist!"%prog[0])
def get_status(self,pfile):
msg = "Not running!"
pids = self.getpids( os.path.basename(pfile) )
if pids: return 'PIDs = ' + str(pids)
return msg
def echo_status(self,pname,pfile):
print("%s:\n %s\n "%(pname,pfile)
+ self.get_status(pfile))
## Session manage: start, stop, status, restart
def status(self):
print( "\n===== Session status for experiment \"%s\" =====\n" %
self._env_['EXP_INFO'][0] )
for code in ['MSERVER','MHTTPD','LOGGER','PROG_FE','PROG_ANA']:
self.echo_status(self._env_[code][0], self._env_[code][1])
def start(self):
## Running mserver & mhttpd
ms_pids = self.getpids(os.path.basename(self._env_['MSERVER'][1]))
if not ms_pids:
self.run_prog(self._env_['MSERVER'])
print("Killing %s ...\n"%self._env_['MHTTPD'][0])
self.kill_prog(self._env_['MHTTPD'][1])
if not self.getpids(os.path.basename(self._env_['MHTTPD'][1])):
self.run_prog(self._env_['MHTTPD'])
## Running FE and Analyzer
old_path = os.getcwd()
os.chdir( self._env_['DAQ_DIR'] )
# Init ODB
print("Initializing ODB for experiment %s ..." % self._env_['EXP_INFO'][0])
self.run_prog(self._env_['ODBEDIT'])
time.sleep(1)
# First stop, then start ...
self.stop()
time.sleep(1)
# Start FE & ANA
self.run_prog(self._env_['PROG_FE'])
self.run_prog(self._env_['PROG_ANA'])
time.sleep(1)
# Start Logger
self.run_prog(self._env_['LOGGER'])
os.chdir(old_path)
def stop(self):
for key in ["LOGGER", "PROG_FE", "PROG_ANA"]:
if self._env_[key][1]:
print("Killing threads:\n %s"%self._env_[key][1])
self.kill_prog(self._env_[key][1])
def stop_all(self):
self.stop()
for key in ['MHTTPD', 'MSERVER']:
if self._env_[key][1]:
print("Killing threads:\n %s"%self._env_[key][1])
self.kill_prog(self._env_[key][1])
def restart(self): self.start()
if __name__=='__main__':
from optparse import OptionParser
usage = "usage: %prog [options] <command>"
parser = OptionParser(usage=usage, version="%prog 0.1")
parser.add_option("-c","--config", metavar="filename",
help="Read config from FILENAME")
cmds = ["start","stop","stop_all","restart","status","info"]
(opts,args) = parser.parse_args( sys.argv[1:] )
if not args or len(args)>2:
parser.print_help()
print "\nCommands:\n\t",
pprint(cmds)
exit()
fcnf = "daq.conf"
if opts.config: fcnf = opts.config
if args[0] in cmds:
daq = mdaq(fname=fcnf)
exec( "daq.%s()"%args[0] )
else:
parser.print_help()
print "\nCommands:\n\t",
pprint(cmds)
|