Commit 81ea5360 authored by Devaev Maxim's avatar Devaev Maxim

Daemon mode, kill option

parent fd345f6f
...@@ -6,11 +6,13 @@ import signal ...@@ -6,11 +6,13 @@ import signal
import errno import errno
import resource import resource
import const
import logger import logger
##### Private methods ##### ##### Private methods #####
def pidOfPythonProc(proc_name, uid = 0) : def pidsListOfPythonProc(proc_name, without_options_list = [], uid = 0) :
proc_pids_list = []
for proc_list_item in os.listdir("/proc") : for proc_list_item in os.listdir("/proc") :
try : try :
proc_pid = int(proc_list_item) proc_pid = int(proc_list_item)
...@@ -18,18 +20,23 @@ def pidOfPythonProc(proc_name, uid = 0) : ...@@ -18,18 +20,23 @@ def pidOfPythonProc(proc_name, uid = 0) :
continue continue
cmdline_file_path = os.path.join("/proc", proc_list_item, "cmdline") cmdline_file_path = os.path.join("/proc", proc_list_item, "cmdline")
if os.stat(cmdline_file_path).st_mode != uid : if os.stat(cmdline_file_path).st_uid != uid :
continue continue
cmdline_file = open(cmdline_file_path) cmdline_file = open(cmdline_file_path)
cmdline_list = cmdline_file.read().split("\0") cmdline_list = cmdline_file.read().split("\0")
if len(cmdline_list) >= 2 and os.path.basename(cmdline_list[1]) == proc_name : if len(cmdline_list) >= 2 and os.path.basename(cmdline_list[1]) == proc_name :
cmdline_file.close() ignore_flag = False
return proc_pid for without_options_list_item in without_options_list :
if without_options_list_item in cmdline_list :
ignore_flag = True
break
if not ignore_flag :
proc_pids_list.append(proc_pid)
cmdline_file.close() cmdline_file.close()
return None return proc_pids_list
def maxFd() : def maxFd() :
max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
...@@ -57,14 +64,13 @@ def closeFd(fd, retries_count = 5) : ...@@ -57,14 +64,13 @@ def closeFd(fd, retries_count = 5) :
##### Public methods ##### ##### Public methods #####
def startDaemon(init_function, close_function, work_dir_path = None, umask = None) : def startDaemon(function, work_dir_path = None, umask = None) :
pid = os.fork() pid = os.fork()
if pid > 0 : if pid > 0 :
try : try :
os.waitpid(pid, 0) os.waitpid(pid, 0)
except OSError : except OSError :
pass pass
os._exit(0)
elif pid == 0 : elif pid == 0 :
logger.verbose("First fork() to %d as session lead" % (os.getpid())) logger.verbose("First fork() to %d as session lead" % (os.getpid()))
...@@ -88,25 +94,18 @@ def startDaemon(init_function, close_function, work_dir_path = None, umask = Non ...@@ -88,25 +94,18 @@ def startDaemon(init_function, close_function, work_dir_path = None, umask = Non
for fd in (0, 1, 2) : for fd in (0, 1, 2) :
os.dup2(null_fd, fd) os.dup2(null_fd, fd)
try : function()
init_function()
except (SystemExit, KeyboardInterrupt) :
close_function()
except :
try :
close_function()
except :
pass
os._exit(1) # FIXME
else : else :
os._exit(1) # FIXME os._exit(1)
else : else :
os._exit(1) # FIXME os._exit(1)
def killDaemon() : def killDaemon() :
pid = pidOfPythonProc("main.py", os.getuid()) # FIXME pids_list = pidsListOfPythonProc("main.py", ["-k", "--kill"], os.getuid()) # FIXME
if pid != None : if len(pids_list) != 0 :
os.kill(pid, signal.SIGTERM) for pids_list_item in pids_list :
os.kill(pids_list_item, signal.SIGTERM)
logger.info("SIGTERM has been sended to \"%s\" with pid \"%d\"" % (const.MY_NAME, pids_list_item))
else : else :
logger.error("Cannot determine a daemon process of \"%s\"" % ("main.py")) # FIXME logger.error("Cannot determine a daemon process of \"%s\"" % ("main.py")) # FIXME
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
import os
import signal import signal
import syslog import syslog
...@@ -8,7 +9,7 @@ import const ...@@ -8,7 +9,7 @@ import const
import config import config
import logger import logger
import application import application
#import daemon # TODO import daemon
##### Public classes ##### ##### Public classes #####
...@@ -62,9 +63,7 @@ class Startup(object) : ...@@ -62,9 +63,7 @@ class Startup(object) :
if self._log_level != None : if self._log_level != None :
config.setValue(config.APPLICATION_SECTION, "log_level", self._log_level) config.setValue(config.APPLICATION_SECTION, "log_level", self._log_level)
### def load(self) :
def runInteractive(self) :
try : try :
self._app.loadModules() self._app.loadModules()
self._app.loadServicesConfigs() self._app.loadServicesConfigs()
...@@ -76,26 +75,37 @@ class Startup(object) : ...@@ -76,26 +75,37 @@ class Startup(object) :
logger.attachException() logger.attachException()
sys.exit(1) sys.exit(1)
###
def runInteractive(self) :
self.load()
signal.signal(signal.SIGTERM, self.quit)
signal.signal(signal.SIGQUIT, self.quit)
try : try :
self._app.runLoop() self._app.runLoop()
except (SystemExit, KeyboardInterrupt) : except (SystemExit, KeyboardInterrupt) :
try : self.quit()
self._app.closeServices()
except :
logger.error("Critical error on services closing, abort all processes and go boom")
self._app.quitLoop()
logger.info("Closed")
except : except :
logger.error("Runtime error, trying to close services") logger.error("Runtime error, trying to close services")
logger.attachException() logger.attachException()
try : self.quit()
self._app.closeServices()
except :
logger.error("Critical error on services closing, abort all processes and go boom")
self._app.quitLoop()
logger.error("Closed")
sys.exit(1) sys.exit(1)
def runDaemon(self) : def runDaemon(self) :
print "TODO" # TODO work_dir_path = ( "/" if os.getuid() == 0 else None )
umask = ( 077 if os.getuid() == 0 else None )
daemon.startDaemon(self.runInteractive, work_dir_path, umask)
### Handlers ###
def quit(self, signum = None, frame = None) :
if signum != None :
logger.info("Recieved signal %d, closing..." % (signum))
self._app.closeServices()
self._app.quitLoop()
logger.info("Closed")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment