| #!/usr/bin/env python |
| # ----------------------------------------------------------------------- |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # ----------------------------------------------------------------------- |
| |
| # |
| # This scirpt stops the ducc system-test simulator |
| # |
| import os |
| import sys |
| import time |
| |
| DUCC_HOME = os.path.abspath(__file__ + '/../../..') |
| sys.path.append(DUCC_HOME + '/admin') |
| |
| import getopt |
| |
| from ducc_util import DuccUtil |
| from properties import Properties |
| from ducc import Ducc |
| from ducc_util import ThreadPool |
| |
| class StopSim(DuccUtil): |
| |
| def signal_process(self, args): |
| inst, data_prop, signal = args |
| data = data_prop |
| (node, pid, pname) = data.split(' ') |
| |
| msgs = [] |
| msgs.append(('Stopping process', inst, 'on', node, pid, pname, 'with signal', signal)) |
| if ( not (inst in self.default_components )): |
| cmp = 'agent' |
| else: |
| cmp = inst |
| self.ssh(node, True, 'kill', signal, pid) |
| |
| return msgs |
| |
| def usage(self, msg): |
| |
| if ( msg != None ): |
| print ' '.join(msg) |
| |
| |
| print "Usage:" |
| print " stop_sim [options]" |
| print " If no options are given, all ducc processes from sim.pids are stopped using SIGINT" |
| print "" |
| print "Options:" |
| print " -c --component compenent name" |
| print " The name is one of", self.default_components, "or an ID from sim.pids" |
| print "" |
| print " -k --kill" |
| print " Sends SIGKILL to the indicated process" |
| print "" |
| print " -p --pause" |
| print " Sends SIGSTOP to the indicated process" |
| print "" |
| print " -r --resume" |
| print " Sends SIGCONT to the indicated process" |
| print "" |
| print " --nothreading" |
| print " Disable multithreaded operation if it would otherwise be used" |
| print "" |
| print " -v, --version" |
| print " Print the current DUCC version" |
| print "" |
| print " -?, -h, --help," |
| print " Print this" |
| print "" |
| sys.exit(1) |
| |
| |
| def invalid(self, *msg): |
| if ( msg[0] != None ): |
| print ' '.join(msg) |
| |
| print "For usage run" |
| print " stop_sim -h" |
| print 'or' |
| print ' stop_sim --help' |
| sys.exit(1) |
| |
| def main(self, argv): |
| |
| components = [] |
| instances = [] |
| signal = '-INT' |
| stopbroker = False |
| stopdatabase = False |
| |
| try: |
| opts, args = getopt.getopt(argv, 'c:kprvh?', ['component=', 'kill' 'pause', 'resume', 'nothreading', 'version', 'help']) |
| except: |
| self.invalid('Invalid arguments', ' '.join(argv)) |
| |
| for ( o, a ) in opts: |
| if o in ( '-c', '--component' ): |
| if (a != 'all'): |
| instances.append(a) |
| elif o in ( '-k', '--kill' ): |
| signal = '-KILL' |
| elif o in ( '-p', '--pause' ): |
| signal = '-STOP' |
| elif o in ( '-r', '--resume' ): |
| signal = '-CONT' |
| elif o in ( '--nothreading' ): |
| self.disable_threading() |
| elif o in ( '-v', '--version' ): |
| print self.version() |
| sys.exit(0) |
| elif o in ( '-h', '--help' ): |
| self.usage(None) |
| elif ( o == '-?'): |
| self.usage(None) |
| else: |
| self.invalid('bad args: ', ' '.join(argv)) |
| |
| pids = Properties() |
| pids.load('sim.pids') |
| |
| self.threadpool = ThreadPool(50) |
| |
| try: |
| if ( (len(components) + len(instances)) == 0 ): |
| for (inst, data) in pids.items(): |
| self.threadpool.invoke(self.signal_process, inst, pids.get(inst), signal) |
| time.sleep(.1) |
| if ( signal in ('-KILL', '-INT') ): |
| pids.delete(inst) |
| stopbroker = True |
| stopdatabase = True |
| |
| else: |
| for inst in instances: |
| print 'Instance', inst |
| data = pids.get(inst) |
| if ( data == None ): |
| if ( inst == 'broker' and signal in ('-KILL', '-INT') ): |
| stopbroker = True |
| else: |
| print "WARNING - No PID found for instance", inst |
| elif ( inst == 'db' ): |
| stopdatabase = True |
| else: |
| self.threadpool.invoke(self.signal_process, inst, pids.get(inst), signal) |
| time.sleep(.1) |
| if ( signal in ('-KILL', '-INT') ): |
| pids.delete(inst) |
| except: |
| self.threadpool.quit() |
| print sys.exc_info()[0], "Exiting, simulator may not be properly stopped." |
| sys.exit(1) |
| |
| self.threadpool.quit(); |
| |
| pids.write('sim.pids') |
| |
| sleeptime = 5 |
| print "Waiting " + str(sleeptime) + " seconds to broadcast agent shutdown." |
| time.sleep(sleeptime) |
| |
| if ( stopdatabase and self.automanage_database ) : |
| print 'Stopping database' |
| self.db_stop() |
| |
| if ( stopbroker and self.automanage_broker ): |
| print "Stopping broker" |
| self.stop_broker() |
| |
| if __name__ == "__main__": |
| stopper = StopSim() |
| stopper.main(sys.argv[1:]) |