A new runsics script has been implemented in python (runsics.py).

It supports the new "fakedev" simulation mode which runs SICS with real
drivers for devices which have simulated controllers.
There are advance options which allow multiple instances of SICS to be
launched on development and test environments.
Also we no longer depend on having serverport numbers in /etc/services.
This commit is contained in:
Ferdi Franceschini
2013-05-13 23:11:15 +10:00
parent 40f979de8f
commit babc5fe17e
23 changed files with 218 additions and 4 deletions

View File

@@ -1,3 +1,4 @@
runsics.py
server_config.tcl
barebones.tcl
util

View File

@@ -1,3 +1,4 @@
runsics_def.py
dingo_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'dingo_sics'
inst_name = 'dingo'
inst_config = 'dingo_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
sics_ports.tcl
script_validator_ports.tcl
instrument_vars.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'wombat_sics'
inst_name = 'wombat'
inst_config = 'wombat_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
sics_ports.tcl
script_validator_ports.tcl
instrument_vars.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'echidna_sics'
inst_name = 'echidna'
inst_config = 'echidna_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
kookaburra_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'kookaburra_sics'
inst_name = 'kookaburra'
inst_config = 'kookaburra_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
lyrebird_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'lyrebird_sics'
inst_name = 'lyrebird'
inst_config = 'lyrebird_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
pelican_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'pelican_sics'
inst_name = 'pelican'
inst_config = 'pelican_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
platypus_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'platypus_sics'
inst_name = 'platypus'
inst_config = 'platypus_configuration.tcl'

View File

@@ -1,3 +1,4 @@
runsics_def.py
sics_ports.tcl
script_validator_ports.tcl
kowari_configuration.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'kowari_sics'
inst_name = 'kowari'
inst_config = 'kowari_configuration.tcl'

162
site_ansto/instrument/runsics.py Executable file
View File

@@ -0,0 +1,162 @@
#!/usr/bin/env python
# vim: ts=8 sts=4 sw=4 expandtab
import sys
import os
import getpass
import resource
import subprocess
import shlex
import argparse
import re
import socket
from runsics_def import *
# Re-open stdout unbuffered because we want to see feedback live as it happens.
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w',0)
# TODO These numbers should be available on the system to any application
server_port = {
'sics': {'telnet': 60001, 'interrupt': 60002, 'server': 60003, 'quieck': 60004},
'scriptval': {'telnet': 60011, 'interrupt': 60012, 'server': 60013, 'quieck': 60014}
}
inst_test_sockoffset = {
'wombat': 0,
'echidna': 100,
'kowari': 200,
'quokka': 300,
'platypus': 400,
'taipan': 500,
'pelican': 600,
'dingo': 700,
'emu': 800,
'kookaburra': 900,
'bilby': 1000
}
def sics_preexec():
resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
os.umask(0022)
# TODO Launch simulated devices if TEST_SICS=fakedev. Must write launch script first.
def start_cmd(server, args):
if status_cmd(server, args):
print '%s is already running. Cowardly refusing to launch it twice' % server
return
sicsenv = {
'none': None,
'fullsim': {'SICS_SIMULATION': 'full'},
'fakedev': {'SICS_SIMULATION': 'fakedev'},
'scriptval': {'SICS_SIMULATION': 'script_validator'}
}
execenv = os.environ
if (args.sockoffset != 'none'):
execenv['SOCKOFFSET'] = str(inst_test_sockoffset[args.sockoffset])
# Set SICS_SIMULATION environment variable
if (server == 'scriptval'):
execenv.update(sicsenv['scriptval'])
else:
execenv.update(sicsenv[args.test])
start_str = 'sudo -Eu %s %s/SICServer -d %s' % (args.user, args.dir, args.config)
# Suppress output if launching the script validator
if (server == 'scriptval'):
with open(os.devnull) as fp:
subprocess.call(shlex.split(start_str), preexec_fn=sics_preexec, env=execenv, cwd=args.dir, stderr=fp, stdout=fp)
else:
subprocess.call(shlex.split(start_str), preexec_fn=sics_preexec, env=execenv, cwd=args.dir)
status_cmd(server, args)
def stop_cmd(server, args):
INTMSG = 'SICSINT 6'
ret = status_cmd(server, args)
if ret:
(serv_port, pid) = ret
if (args.sockoffset == 'none'):
int_port = server_port[server]['interrupt']
else:
int_port = server_port[server]['interrupt'] + inst_test_sockoffset[args.sockoffset]
print 'STOP %s(%d) listening on %d' % (server, pid, serv_port)
print "Sending '%s' to %d" % (INTMSG, int_port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto( INTMSG + '\n\r', ('localhost', int_port) )
sock.close()
if status_cmd(server, args):
print 'Failed to stop %s' % server
print 'Try harder dammit!'
subprocess.call(shlex.split('sudo -Eu root killall SICServer'))
else:
return
if status_cmd(server, args):
print 'Failed again!'
print 'Die damn you! DIE!!'
subprocess.call(shlex.split('sudo -Eu root killall -s15 SICServer'))
else:
return
if status_cmd(server, args):
print 'Why wont you die!!??'
print 'I give up. Try calling a SICS programmer or sysadmin'
def status_cmd(server, args):
if (args.sockoffset == 'none'):
sock = server_port[server]['server']
else:
sock = server_port[server]['server'] + inst_test_sockoffset[args.sockoffset]
status_cmd = 'sudo -Eu %s netstat -nltp' % args.user
with open(os.devnull) as fp:
netstat_str = subprocess.check_output(shlex.split(status_cmd), stderr=fp)
#Find PID of SICServer listening on server port
m = re.search(':%d .* (\d+)\/SICServer' % sock, netstat_str)
if m:
pid = int(m.group(1))
print '%s listening on port %d, PID=%d' % (server, sock, pid)
return (sock, pid)
else:
print '%s not running' % server
return ''
def main(**kwargs):
runsics_cmd = {'start': start_cmd, 'stop': stop_cmd, 'status': status_cmd}
# Setup defaults. Use nice defaults in test environments.
if os.environ.has_key('TEST_SICS'):
deflt_user = getpass.getuser()
deflt_test = os.environ['TEST_SICS']
deflt_dir = './'
deflt_sockoffset = inst_name
else:
deflt_user = inst_user
deflt_test = 'none'
deflt_dir = '/usr/local/sics/server'
deflt_sockoffset = 'none'
# Parse arguments
parser = argparse.ArgumentParser( description='SICS Server startup script.' )
cmd_grp = parser.add_argument_group('Commands', 'Runsics commands')
adv_grp = parser.add_argument_group('Advanced', 'Options providing more control. Usually only useful for SICS developers and testers. If you are running multiple instances of SICS on a single host you can set the TEST_SICS environment variable to one of the --test values to get nice defaults.')
# Mandatory arguments
cmd_grp.add_argument('cmd', choices=['start', 'stop', 'status'])
# Advanced arguments
adv_grp.add_argument('-c', '--config', help='Run SICS with the given configuration file. Default=%s' % inst_config, default = inst_config )
adv_grp.add_argument('-d', '--dir', help='Run SICS from the given directory. Default=%s' % deflt_dir, default = deflt_dir)
adv_grp.add_argument('-t', '--test', choices=['fullsim', 'fakedev', 'scriptval'], help='Run SICS in the given mode. Default=%s' % deflt_test, default=deflt_test)
adv_grp.add_argument('-u', '--user', help='Run SICS as the given user. Default=%s' % deflt_user, default = deflt_user )
adv_grp.add_argument('--sockoffset', help='Offset the sockets to allow multiple SICS instances on a single host. Default=%s' % deflt_sockoffset, choices=inst_test_sockoffset.keys(), default = deflt_sockoffset )
exc_grp = parser.add_mutually_exclusive_group()
exc_grp.add_argument('--sicsonly', help='Just run SICS without the script validator', action='store_true', default=False)
exc_grp.add_argument('--scriptval', help='Launch script validator as well as SICServer. Use this to override the default action when the TEST_SICS environmant variable is set.', action='store_true', default=False)
args = parser.parse_args()
# Don't launch script validator in development environments.
if args.scriptval:
deflt_sicsonly = False
elif os.environ.has_key('TEST_SICS'):
deflt_sicsonly = True
else:
deflt_sicsonly = args.sicsonly
# Launch SICS
if (deflt_sicsonly):
runsics_cmd[args.cmd]('sics', args)
else:
runsics_cmd[args.cmd]('sics', args)
runsics_cmd[args.cmd]('scriptval', args)
if __name__ == '__main__':
main()

View File

@@ -1,3 +1,4 @@
runsics_def.py
quokka_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'quokka_sics'
inst_name = 'quokka'
inst_config = 'quokka_configuration.tcl'

View File

@@ -5,6 +5,10 @@
#set sicsroot /usr/local/sics
VarMake sicsdebug Int Mugger
sicsdebug 0
set telnetport 60001
set interruptport 60002
set serverport 60003
set quieckport 60004
# Simulation flags, possible values = true or false
# true: The simulated driver will be used.
@@ -41,6 +45,12 @@ proc syncbackup {file} {
backup motorSave
}
publish syncbackup Spy
if [info exists env(SOCKOFFSET)] {
set telnetport [expr {$telnetport + $env(SOCKOFFSET)}]
set interruptport [expr {$interruptport + $env(SOCKOFFSET)}]
set serverport [expr {$serverport + $env(SOCKOFFSET)}]
set quieckport [expr {$quieckport + $env(SOCKOFFSET)}]
}
if {[info exists env(SICS_SIMULATION)] != 1} {
set sicsroot ../
source sics_ports.tcl
@@ -66,21 +76,22 @@ if {[info exists env(SICS_SIMULATION)] != 1} {
switch $env(SICS_SIMULATION) {
"full" {
set sicsroot ../
source sics_ports.tcl
sics_simulation true
}
"fakedev" {
set sicsroot ../
source sics_ports.tcl
sics_simulation fakedev
}
"script_validator" {
VarMake sics_script_validator Text internal
sics_script_validator true
set sicsroot ../script_validator/
source script_validator_ports.tcl
set telnetport [expr {$telnetport + 10}]
set interruptport [expr {$interruptport + 10}]
set serverport [expr {$serverport + 10}]
set quieckport [expr {$quieckport + 10}]
sics_simulation true
MakeSync localhost [expr [get_portnum $serverport ]-10] spy 007 ../log/syncfile.tcl
MakeSync localhost $serverport spy 007 ../log/syncfile.tcl
}
default {
error "ERROR: SICS_SIMULATION must be full, script_validator, or fakedev, not $env(SICS_SIMULATION)"

View File

@@ -1,3 +1,4 @@
runsics_def.py
sics_ports.tcl
script_validator_ports.tcl
taipan_configuration.tcl

View File

@@ -0,0 +1,3 @@
inst_user = 'taipan_sics'
inst_name = 'taipan'
inst_config = 'taipan_configuration.tcl'