2 # -----------------------------------------------------------------------
3 # Copyright (C) 2007-2008 King County Library System
4 # Bill Erickson <erickson@esilibrary.com>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 3
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 # -----------------------------------------------------------------------
17 import sys, getopt, os, errno, shutil
18 from constrictor.properties import Properties
19 from constrictor.controller import DroneController
20 from constrictor.script import ScriptThread, ScriptManager
21 from constrictor.log import *
22 from constrictor.utils import load_props, save_props, init_dirs, init_db, open_script, PROPS_FILENAME
23 import constrictor.data
26 props_filename = PROPS_FILENAME
27 droneController = None
33 By default, all options are read from the properties file constrictor.properties.
34 Arguments passed via the command line will override any properties
35 loaded from the properties file
38 -h show this help message
39 -s test script to run (property constrictor.script)
40 -t number of threads to launch (property constrictor.numThreads)
41 -i number of test iterations per thread (property constrictor.numIterations)
42 -d database file (property constrictor.dbFile)
43 -p port to listen for controller connections on
44 -l listen address for incoming controller connections
45 -x clear the local cache file cache
51 def read_args_and_props():
55 # see if we have any command-line args that override the properties file
56 ops, args = getopt.getopt(sys.argv[1:], 's:t:i:d:p:l:f:hx')
57 options = dict( (k,v) for k,v in ops )
59 if options.has_key('-f'):
60 props_filename = options['-f']
62 load_props(props_filename)
63 props = Properties.get_properties()
65 if options.has_key('-h'):
67 if options.has_key('-s'):
68 props.set_property('constrictor.script', options['-s'])
69 if options.has_key('-t'):
70 props.set_property('constrictor.numThreads', options['-t'])
71 if options.has_key('-i'):
72 props.set_property('constrictor.numIterations', options['-i'])
73 if options.has_key('-d'):
74 props.set_property('constrictor.dbFile', options['-d'])
75 if options.has_key('-p'):
76 props.set_property('constrictor.port', options['-p'])
77 if options.has_key('-l'):
78 props.set_property('constrictor.listenAddress', options['-l'])
80 if options.has_key('-x'):
81 # delete the cache directory
82 cacheDir = props.get_property('constrictor.cacheDir')
83 shutil.rmtree(os.path.join(os.getcwd(), cacheDir))
87 def onThreadsComplete(scriptManager):
88 global droneController
89 #summary = ScriptThread.current_script_thread().dbConnection.createTaskSummary()
90 #droneController.sendResult(type='task_summary', **summary)
95 scriptDirs = props.get_property('constrictor.scriptDirs').split(',')
99 if props.get_property('constrictor.listen') == 'true':
101 ''' This is the main controller listen loop. Here, we
102 accept commands from the controller module, perform
103 the action, then go back to listening '''
105 droneController = DroneController(
106 props.get_property('constrictor.address'),
107 int(props.get_property('constrictor.port')))
109 ScriptManager.set_on_threads_complete(onThreadsComplete)
113 command = droneController.recv()['command']
115 if command['action'] == 'setprop':
116 prop = str(command['prop'])
117 val = str(command['val'])
118 log_info('setting property %s %s' % (prop, val))
119 props.set_property(prop, val)
122 if command['action'] == 'saveprops':
123 log_info("saving properties back to file")
127 if command['action'] == 'run':
128 ScriptThread.reset_thread_seed()
129 script = props.get_property('constrictor.script')
130 log_info('running ' + script)
131 f = open_script(scriptDirs, script)
137 log_error("script execution failed: %s" % str(e))
138 droneController.sendError(text=str(e))
142 except KeyboardInterrupt:
143 droneController.shutdown()
147 script = props.get_property('constrictor.script') # execute the requested script
148 ScriptThread.reset_thread_seed()
149 f = open_script(scriptDirs, script)