From 74f8cbab91df3079277554b6aabd296d6cac730e Mon Sep 17 00:00:00 2001 From: Jerome Sagnole Date: Thu, 2 Nov 2017 22:54:58 +0100 Subject: [PATCH] remove/adding some comment, and correct function to wait all thread --- code/khaganat/tools/client.py | 54 +++++++++++++++----------- code/khaganat/tools/manage.py | 73 +++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/code/khaganat/tools/client.py b/code/khaganat/tools/client.py index 477b5b7e8..f33d2a062 100755 --- a/code/khaganat/tools/client.py +++ b/code/khaganat/tools/client.py @@ -17,19 +17,37 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# ./client.py --server='172.17.0.2' +""" + Manipulate manager khaganat -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="START" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="STATUS" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="ACTION" --action="coucou" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="LOG" --firstline=0 -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="STOP" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="LIST" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="SHUTDOWN" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="STARTALL" -# ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="STATUSALL" -# ./client.py --key="/home/gameserver/khanat/key.pem" --cert="/home/gameserver/khanat/cert.pem" --log="debug" --show-log-console --command="STATUSALL" +We can end some command to manager. + Global: + SHUTDOWN : Stop manager & Stop all programs + STARTALL : Start all programs + STATUSALL : Get status of all programs + STOPALL : Stop all programs + LIST : List all programs available + For one program : + START : Start program + STOP : Stop program + STATUS : Get status + LOG : Get log + firstline : option to define first line we need send + ACTION : Send action (command) in stdin + action : option to define which action you need send to stdin +Example : + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="START" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="STATUS" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="ACTION" --action="coucou" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="LOG" --firstline=0 + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --program="aes" --command="STOP" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="LIST" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="SHUTDOWN" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="STARTALL" + ./client.py --log="debug" --show-log-console --server='172.17.0.2' --command="STATUSALL" + ./client.py --key="/home/gameserver/khanat/key.pem" --cert="/home/gameserver/khanat/cert.pem" --log="debug" --show-log-console --command="STATUSALL" +""" import argparse import logging @@ -37,16 +55,8 @@ import logging.config import http.client import json -#ip='localhost' -def send_command(command='GET', path='/', host='localhost', port=8000): - conn = http.client.HTTPSConnection(host=host, port=port, key_file='crt/key.pem', cert_file='crt/cert.pem' ) - conn.putrequest(command, path) - conn.endheaders() - response = conn.getresponse() - print(response.read()) - def cmp_to_key(): - 'Convert a cmp= function into a key= function' + 'compare key (check if int or other)' class K(object): def __init__(self, obj, *args): self.obj = obj @@ -84,6 +94,7 @@ def cmp_to_key(): def send_json(jsonin={}, command='GET', path='/', host='localhost', port=8000, raw_data=False, remove_color=False, key_file=None, cert_file=None): + "send command with https & json format" conn = http.client.HTTPSConnection(host=host, port=port, key_file=key_file, cert_file=cert_file ) conn.putrequest(command, path) out=json.dumps(jsonin) @@ -129,8 +140,7 @@ def main(server, command, program, action, firstline, fileLog, logLevel, show_lo handlers.append(logging.FileHandler(fileLog.name)) logging.basicConfig(handlers=handlers, level=numeric_level, format='%(asctime)s %(levelname)s [pid:%(process)d] [%(funcName)s:%(lineno)d] %(message)s') - #client(server, command, data) - #send_json({'name': 'aes', 'first-line': 0}, 'GET', '/LOG', server, port) + # Send command if command == 'START' or command == 'STOP': send_json({'name': program}, 'POST', "/" + command, server, port) elif command == 'STATUS': diff --git a/code/khaganat/tools/manage.py b/code/khaganat/tools/manage.py index 93fe852aa..a49b93f26 100755 --- a/code/khaganat/tools/manage.py +++ b/code/khaganat/tools/manage.py @@ -77,14 +77,6 @@ Example : """ -# docker run -it -v $PWD:/opt/jsa servercontainer_khanat_debian_jessie_x86_64 /bin/bash -# ./manage.py --log debug --show-log-console -c test.cfg - - -# https://pymotw.com/2/multiprocessing/communication.html -# https://eli.thegreenplace.net/2012/01/24/distributed-computing-in-python-with-multiprocessing/ -# https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python - import subprocess import queue import threading @@ -460,7 +452,7 @@ class ManageCommand(): self.eventRunning = threading.Event() def read_output(self): - + """ Thread to read output (stdout) """ fl = fcntl.fcntl(self.process.stdout, fcntl.F_GETFL) fcntl.fcntl(self.process.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) logging.debug("Start reader %s " % self.name) @@ -484,6 +476,7 @@ class ManageCommand(): logging.debug("End reader: '%s'" % self.name) def handler(self, signum, frame): + """ Managed signal (not used) """ if self.process: #logging.debug("Send signal %d to '%s'" %(signum, self.name)) self.process.send_signal(signum) @@ -492,6 +485,7 @@ class ManageCommand(): raise IOError("signal received") def start(self): + """ Start program """ logging.debug("start %s" % (self.name)) if self.process: logging.debug("%s already exist" % self.name) @@ -526,6 +520,7 @@ class ManageCommand(): return "started" def status(self): + """ Get status of program """ logging.debug("status %s" % (self.name)) if self.process: logging.debug("status %s - check" % (self.name)) @@ -542,6 +537,7 @@ class ManageCommand(): return "stopped" def list_thread(self): + """ List number thrad (not used) """ logging.debug('list thread') #main_thread = threading.currentThread() for t in threading.enumerate(): @@ -550,6 +546,7 @@ class ManageCommand(): def stop(self): + """ Stop program """ logging.debug("stop %s" % (self.name)) if not self.process: return "stopped" @@ -589,6 +586,7 @@ class ManageCommand(): return "stopped" def getlog(self, firstline): + """ Get log """ logging.debug("read log %d " % firstline) outjson = {} pos = self.poslastlog - len(self.log) + 1 @@ -604,6 +602,7 @@ class ManageCommand(): return json.dumps(outjson) def action(self, action): + """ Send action to program (send input to stdin) """ logging.debug("ACTION '%s'" % action) if self.process: code = self.process.poll() @@ -615,6 +614,7 @@ class ManageCommand(): return "ko" def run(self): + """ loop, run child (wait command) """ loop = True while loop: logging.debug('wait %s' % self.name) @@ -654,26 +654,13 @@ class ManageCommand(): logging.debug('end') -def runCommand(name, command, path, logsize, bufsize, queueIn, queueOut, event): - """ - Launch Manager - (thread to manage khaganat program) - """ - logging.debug("Initialize '%s'" % name) - manageCommand = ManageCommand(name=name, - command=command, - path=path, - logsize=logsize, - bufsize=bufsize, - queueIn=queueIn, - queueOut=queueOut, - event=event) - manageCommand.run() - - class Manager(): + """ Manage all services + * https service + * all child to manage each program + """ def __init__(self, filecfg, launch_program): - self.threadCommand = None + self.threadCommand = [] self.command = [] self.launch_program = launch_program self.param = {} @@ -728,18 +715,35 @@ class Manager(): if filecfg is None: raise ValueError + def runCommand(self, name, command, path, logsize, bufsize, queueIn, queueOut, event): + """ + Thread to manage khaganat program + """ + logging.debug("Initialize '%s'" % name) + manageCommand = ManageCommand(name=name, + command=command, + path=path, + logsize=logsize, + bufsize=bufsize, + queueIn=queueIn, + queueOut=queueOut, + event=event) + manageCommand.run() + def launch_server_http(self): + """ Launch server https """ self.serverHttp.daemon = True self.serverHttp .start() def launch_command(self): + """ Launch child to manage each program """ for name in self.param: logging.debug("Initialize '%s'" % name) queueIn = multiprocessing.Queue() queueOut = multiprocessing.Queue() event = multiprocessing.Event() self.serverHttp.append(name, queueIn, queueOut, event) - self.threadCommand = multiprocessing.Process(target=runCommand, + threadCommand = multiprocessing.Process(target=self.runCommand, args=(name, self.param[name]['command'], self.param[name]['path'], @@ -748,7 +752,7 @@ class Manager(): queueIn, queueOut, event)) - self.threadCommand.start() + threadCommand.start() if self.launch_program: event.set() queueIn.put("START") @@ -759,20 +763,23 @@ class Manager(): logging.debug("pas de message recu pour %s" % name) return logging.info("%s => %s" % (name, item)) + self.threadCommand.append(threadCommand) def receive_signal(self, signum, frame): - if self.threadCommand: - print(dir(self.threadCommand)) - self.threadCommand.terminate() + """ Managed signal """ + for child in self.threadCommand: + child.terminate() if self.serverHttp: self.serverHttp.terminate() def run(self): + """ launch all """ self.launch_command() self.launch_server_http() logging.info('started') - self.threadCommand.join() + for child in self.threadCommand: + child.join() logging.info('end') signal.alarm(0) logging.info('wait thread http')