removed daemonize code that is not needed for services, cleaned up need for logrotate, removed some logging that was not useful
This commit is contained in:
parent
1ac862cc17
commit
44363b0500
7 changed files with 20 additions and 255 deletions
|
@ -17,9 +17,6 @@ endif
|
|||
SCRIPT_FILES := $(notdir $(wildcard scripts/*))
|
||||
MAN_FILES := $(notdir $(wildcard ../doc/man/*.1))
|
||||
|
||||
LOGROTATE_DIR = $(DESTDIR)/$(sysconfdir)/logrotate.d
|
||||
LOGROTATE_FILE = data/core-daemon.logrotate
|
||||
|
||||
# Python package build
|
||||
noinst_SCRIPTS = build
|
||||
build:
|
||||
|
@ -33,16 +30,7 @@ install-exec-hook:
|
|||
--install-lib=$(pythondir) \
|
||||
--single-version-externally-managed
|
||||
|
||||
#install-data-local:
|
||||
# $(MKDIR_P) $(DESTDIR)$(LOGROTATE_DIR)
|
||||
# $(INSTALL_DATA) $(LOGROTATE_FILE) \
|
||||
# $(DESTDIR)$(LOGROTATE_DIR)/`basename $(LOGROTATE_FILE) .logrotate`
|
||||
|
||||
#uninstall-local:
|
||||
# rm -f $(DESTDIR)$(LOGROTATE_DIR)/`basename $(LOGROTATE_FILE) .logrotate`
|
||||
|
||||
# Python package uninstall
|
||||
#rmdir -p $(LOGROTATE_DIR) || true
|
||||
uninstall-hook:
|
||||
rm -rf $(DESTDIR)/etc/core
|
||||
rm -rf $(DESTDIR)/$(datadir)/core
|
||||
|
@ -62,7 +50,7 @@ dist-hook:
|
|||
|
||||
distclean-local:
|
||||
-rm -rf core.egg-info
|
||||
|
||||
|
||||
|
||||
DISTCLEANFILES = Makefile.in
|
||||
|
||||
|
@ -76,5 +64,4 @@ EXTRA_DIST = $(SETUPPY) \
|
|||
tests \
|
||||
test.py \
|
||||
setup.cfg \
|
||||
requirements.txt \
|
||||
$(LOGROTATE_FILE)
|
||||
requirements.txt
|
||||
|
|
|
@ -360,8 +360,6 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
|||
"""
|
||||
try:
|
||||
header = self.request.recv(coreapi.CoreMessage.header_len)
|
||||
if len(header) > 0:
|
||||
logger.debug("received message header: %s", utils.hex_dump(header))
|
||||
except IOError as e:
|
||||
raise IOError("error receiving header (%s)" % e)
|
||||
|
||||
|
@ -378,7 +376,6 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
|||
data = ""
|
||||
while len(data) < message_len:
|
||||
data += self.request.recv(message_len - len(data))
|
||||
logger.debug("received message data: %s" % utils.hex_dump(data))
|
||||
if len(data) > message_len:
|
||||
error_message = "received message length does not match received data (%s != %s)" % (
|
||||
len(data), message_len)
|
||||
|
@ -492,7 +489,7 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
|||
# TODO: hack to associate this handler with this sessions broker for broadcasting
|
||||
# TODO: broker needs to be pulled out of session to the server/handler level
|
||||
if self.master:
|
||||
logger.info("SESSION SET TO MASTER!")
|
||||
logger.info("session set to master")
|
||||
self.session.master = True
|
||||
self.session.broker.session_clients.append(self)
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ Defines server classes and request handlers for TCP and UDP.
|
|||
"""
|
||||
|
||||
import SocketServer
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
@ -72,14 +71,6 @@ class CoreServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|||
for session in self.sessions.values():
|
||||
session.shutdown()
|
||||
|
||||
# if we are a daemon remove pid file
|
||||
if self.config["daemonize"]:
|
||||
pid_file = self.config["pidfile"]
|
||||
try:
|
||||
os.unlink(pid_file)
|
||||
except OSError:
|
||||
logger.exception("error daemon pid file: %s", pid_file)
|
||||
|
||||
# remove server from server list
|
||||
CoreServer.remove_server(self)
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import subprocess
|
|||
import sys
|
||||
|
||||
import fcntl
|
||||
import resource
|
||||
|
||||
from core import CoreCommandError
|
||||
from core import logger
|
||||
|
@ -337,95 +336,6 @@ def sysctl_devname(devname):
|
|||
return devname.replace(".", "/")
|
||||
|
||||
|
||||
def daemonize(rootdir="/", umask=0, close_fds=False, dontclose=(),
|
||||
stdin=os.devnull, stdout=os.devnull, stderr=os.devnull,
|
||||
stdoutmode=0644, stderrmode=0644, pidfilename=None,
|
||||
defaultmaxfd=1024):
|
||||
"""
|
||||
Run the background process as a daemon.
|
||||
|
||||
:param str rootdir: root directory for daemon
|
||||
:param int umask: umask for daemon
|
||||
:param bool close_fds: flag to close file descriptors
|
||||
:param dontclose: dont close options
|
||||
:param stdin: stdin for daemon
|
||||
:param stdout: stdout for daemon
|
||||
:param stderr: stderr for daemon
|
||||
:param int stdoutmode: stdout mode
|
||||
:param int stderrmode: stderr mode
|
||||
:param str pidfilename: pid file name
|
||||
:param int defaultmaxfd: default max file descriptors
|
||||
:return: nothing
|
||||
"""
|
||||
if not hasattr(dontclose, "__contains__"):
|
||||
if not isinstance(dontclose, int):
|
||||
raise TypeError("dontclose must be an integer")
|
||||
dontclose = (int(dontclose),)
|
||||
else:
|
||||
for fd in dontclose:
|
||||
if not isinstance(fd, int):
|
||||
raise TypeError("dontclose must contain only integers")
|
||||
|
||||
# redirect stdin
|
||||
if stdin:
|
||||
fd = os.open(stdin, os.O_RDONLY)
|
||||
os.dup2(fd, 0)
|
||||
os.close(fd)
|
||||
|
||||
# redirect stdout
|
||||
if stdout:
|
||||
fd = os.open(stdout, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
|
||||
stdoutmode)
|
||||
os.dup2(fd, 1)
|
||||
if stdout == stderr:
|
||||
os.dup2(1, 2)
|
||||
os.close(fd)
|
||||
|
||||
# redirect stderr
|
||||
if stderr and (stderr != stdout):
|
||||
fd = os.open(stderr, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
|
||||
stderrmode)
|
||||
os.dup2(fd, 2)
|
||||
os.close(fd)
|
||||
|
||||
if os.fork():
|
||||
# parent exits
|
||||
os._exit(0)
|
||||
|
||||
os.setsid()
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
if pidfilename:
|
||||
try:
|
||||
f = open(pidfilename, "w")
|
||||
f.write("%s\n" % pid)
|
||||
f.close()
|
||||
except IOError:
|
||||
logger.exception("error writing to file: %s", pidfilename)
|
||||
# parent exits
|
||||
os._exit(0)
|
||||
|
||||
if rootdir:
|
||||
os.chdir(rootdir)
|
||||
|
||||
os.umask(umask)
|
||||
if close_fds:
|
||||
try:
|
||||
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
||||
if maxfd == resource.RLIM_INFINITY:
|
||||
raise ValueError
|
||||
except:
|
||||
maxfd = defaultmaxfd
|
||||
|
||||
for fd in xrange(3, maxfd):
|
||||
if fd in dontclose:
|
||||
continue
|
||||
try:
|
||||
os.close(fd)
|
||||
except IOError:
|
||||
logger.exception("error closing file descriptor")
|
||||
|
||||
|
||||
def load_config(filename, d):
|
||||
"""
|
||||
Read key=value pairs from a file, into a dict. Skip comments; strip newline characters and spacing.
|
||||
|
|
|
@ -138,8 +138,9 @@ class SimpleLxcNode(PyCoreNode):
|
|||
try:
|
||||
os.kill(self.pid, signal.SIGTERM)
|
||||
os.waitpid(self.pid, 0)
|
||||
except OSError:
|
||||
logger.exception("error killing process")
|
||||
except OSError as e:
|
||||
if e.errno != 10:
|
||||
logger.exception("error killing process")
|
||||
|
||||
# remove node directory if present
|
||||
try:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
# Configuration file for CORE (core-gui, core-daemon)
|
||||
#
|
||||
|
||||
|
||||
### GUI configuration options ###
|
||||
[core-gui]
|
||||
|
@ -8,14 +6,10 @@
|
|||
|
||||
### core-daemon configuration options ###
|
||||
[core-daemon]
|
||||
pidfile = /var/run/core-daemon.pid
|
||||
logfile = /var/log/core-daemon.log
|
||||
xmlfilever = 1.0
|
||||
# you may want to change the listenaddr below to 0.0.0.0
|
||||
listenaddr = localhost
|
||||
port = 4038
|
||||
numthreads = 1
|
||||
verbose = False
|
||||
quagga_bin_search = "/usr/local/bin /usr/bin /usr/lib/quagga"
|
||||
quagga_sbin_search = "/usr/local/sbin /usr/sbin /usr/lib/quagga"
|
||||
# uncomment the following line to load custom services from the specified dir
|
||||
|
|
|
@ -8,9 +8,7 @@ message handlers are defined and some support for sending messages.
|
|||
import ConfigParser
|
||||
import atexit
|
||||
import optparse
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
@ -20,16 +18,10 @@ from core import coreserver
|
|||
from core import enumerations
|
||||
from core import logger
|
||||
from core import services
|
||||
from core.api import coreapi
|
||||
from core.enumerations import MessageFlags
|
||||
from core.enumerations import RegisterTlvs
|
||||
from core.misc import nodeutils
|
||||
from core.misc.utils import close_onexec
|
||||
from core.misc.utils import daemonize
|
||||
from core.service import ServiceManager
|
||||
|
||||
DEFAULT_MAXFD = 1024
|
||||
|
||||
|
||||
def banner():
|
||||
"""
|
||||
|
@ -51,6 +43,7 @@ def cored(cfg=None):
|
|||
port = int(cfg["port"])
|
||||
if host == "" or host is None:
|
||||
host = "localhost"
|
||||
|
||||
try:
|
||||
server = coreserver.CoreServer((host, port), corehandlers.CoreRequestHandler, cfg)
|
||||
except:
|
||||
|
@ -62,7 +55,7 @@ def cored(cfg=None):
|
|||
server.serve_forever()
|
||||
|
||||
|
||||
# TODO: should sessions and the main core daemon both catch at exist to shutdown independently?
|
||||
# TODO: should sessions and the main core daemon both catch exit to shutdown independently?
|
||||
def cleanup():
|
||||
"""
|
||||
Runs server shutdown and cleanup when catching an exit signal.
|
||||
|
@ -74,9 +67,6 @@ def cleanup():
|
|||
server.shutdown()
|
||||
|
||||
|
||||
atexit.register(cleanup)
|
||||
|
||||
|
||||
def sighandler(signum, stackframe):
|
||||
"""
|
||||
Signal handler when different signals are sent.
|
||||
|
@ -94,43 +84,7 @@ signal.signal(signal.SIGINT, sighandler)
|
|||
signal.signal(signal.SIGTERM, sighandler)
|
||||
signal.signal(signal.SIGUSR1, sighandler)
|
||||
signal.signal(signal.SIGUSR2, sighandler)
|
||||
|
||||
|
||||
def logrotate(stdout, stderr, stdoutmode=0644, stderrmode=0644):
|
||||
"""
|
||||
Log rotation method.
|
||||
|
||||
:param stdout: stdout
|
||||
:param stderr: stderr
|
||||
:param int stdoutmode: stdout mode
|
||||
:param int stderrmode: stderr mode
|
||||
:return:
|
||||
"""
|
||||
|
||||
def reopen(fileno, filename, mode):
|
||||
err = 0
|
||||
fd = -1
|
||||
try:
|
||||
fd = os.open(filename,
|
||||
os.O_WRONLY | os.O_CREAT | os.O_APPEND, mode)
|
||||
os.dup2(fd, fileno)
|
||||
except OSError as e:
|
||||
err = e.errno
|
||||
finally:
|
||||
if fd >= 0:
|
||||
os.close(fd)
|
||||
return err
|
||||
|
||||
if stdout:
|
||||
err = reopen(1, stdout, stdoutmode)
|
||||
if stderr:
|
||||
if stderr == stdout and not err:
|
||||
try:
|
||||
os.dup2(1, 2)
|
||||
except OSError as e:
|
||||
pass
|
||||
else:
|
||||
reopen(2, stderr, stderrmode)
|
||||
atexit.register(cleanup)
|
||||
|
||||
|
||||
def get_merged_config(filename):
|
||||
|
@ -142,50 +96,23 @@ def get_merged_config(filename):
|
|||
:rtype: dict
|
||||
"""
|
||||
# these are the defaults used in the config file
|
||||
defaults = {"port": "%d" % enumerations.CORE_API_PORT,
|
||||
"listenaddr": "localhost",
|
||||
"pidfile": "%s/run/core-daemon.pid" % constants.CORE_STATE_DIR,
|
||||
"logfile": "%s/log/core-daemon.log" % constants.CORE_STATE_DIR,
|
||||
"xmlfilever": "1.0",
|
||||
"numthreads": "1",
|
||||
"verbose": "False",
|
||||
"daemonize": "False",
|
||||
"debug": "False",
|
||||
"execfile": None,
|
||||
}
|
||||
defaults = {
|
||||
"port": "%d" % enumerations.CORE_API_PORT,
|
||||
"listenaddr": "localhost",
|
||||
"xmlfilever": "1.0",
|
||||
"numthreads": "1",
|
||||
}
|
||||
|
||||
usagestr = "usage: %prog [-h] [options] [args]\n\n" + \
|
||||
"CORE daemon v.%s instantiates Linux network namespace " \
|
||||
"nodes." % constants.COREDPY_VERSION
|
||||
parser = optparse.OptionParser(usage=usagestr)
|
||||
parser.add_option("-f", "--configfile", dest="configfile",
|
||||
type="string",
|
||||
help="read config from specified file; default = %s" %
|
||||
filename)
|
||||
parser.add_option("-d", "--daemonize", dest="daemonize",
|
||||
action="store_true",
|
||||
help="run in background as daemon; default=%s" % \
|
||||
defaults["daemonize"])
|
||||
parser.add_option("-e", "--execute", dest="execfile", type="string",
|
||||
help="execute a Python/XML-based session")
|
||||
parser.add_option("-l", "--logfile", dest="logfile", type="string",
|
||||
help="log output to specified file; default = %s" %
|
||||
defaults["logfile"])
|
||||
parser.add_option("-f", "--configfile", dest="configfile", type="string",
|
||||
help="read config from specified file; default = %s" % filename)
|
||||
parser.add_option("-p", "--port", dest="port", type=int,
|
||||
help="port number to listen on; default = %s" % \
|
||||
defaults["port"])
|
||||
parser.add_option("-i", "--pidfile", dest="pidfile",
|
||||
help="filename to write pid to; default = %s" % \
|
||||
defaults["pidfile"])
|
||||
help="port number to listen on; default = %s" % defaults["port"])
|
||||
parser.add_option("-t", "--numthreads", dest="numthreads", type=int,
|
||||
help="number of server threads; default = %s" % \
|
||||
defaults["numthreads"])
|
||||
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
|
||||
help="enable verbose logging; default = %s" % \
|
||||
defaults["verbose"])
|
||||
parser.add_option("-g", "--debug", dest="debug", action="store_true",
|
||||
help="enable debug logging; default = %s" % \
|
||||
defaults["debug"])
|
||||
help="number of server threads; default = %s" % defaults["numthreads"])
|
||||
|
||||
# parse command line options
|
||||
options, args = parser.parse_args()
|
||||
|
@ -200,19 +127,6 @@ def get_merged_config(filename):
|
|||
section = "core-daemon"
|
||||
if not cfg.has_section(section):
|
||||
cfg.add_section(section)
|
||||
# gracefully support legacy configs (cored.py/cored now core-daemon)
|
||||
if cfg.has_section("cored.py"):
|
||||
for name, val in cfg.items("cored.py"):
|
||||
if name == "pidfile" or name == "logfile":
|
||||
bn = os.path.basename(val).replace("coredpy", "core-daemon")
|
||||
val = os.path.join(os.path.dirname(val), bn)
|
||||
cfg.set(section, name, val)
|
||||
if cfg.has_section("cored"):
|
||||
for name, val in cfg.items("cored"):
|
||||
if name == "pidfile" or name == "logfile":
|
||||
bn = os.path.basename(val).replace("cored", "core-daemon")
|
||||
val = os.path.join(os.path.dirname(val), bn)
|
||||
cfg.set(section, name, val)
|
||||
|
||||
# merge command line with config file
|
||||
for opt in options.__dict__:
|
||||
|
@ -223,24 +137,6 @@ def get_merged_config(filename):
|
|||
return dict(cfg.items(section)), args
|
||||
|
||||
|
||||
def exec_file(cfg):
|
||||
"""
|
||||
Send a Register Message to execute a new session based on XML or Python script file.
|
||||
|
||||
:param dict cfg: configuration settings
|
||||
:return: 0
|
||||
"""
|
||||
filename = cfg["execfile"]
|
||||
logger.info("Telling daemon to execute file: %s...", filename)
|
||||
tlvdata = coreapi.CoreRegisterTlv.pack(RegisterTlvs.EXECUTE_SERVER.value, filename)
|
||||
msg = coreapi.CoreRegMessage.pack(MessageFlags.ADD.value, tlvdata)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
# TODO: connect address option
|
||||
sock.connect(("localhost", int(cfg["port"])))
|
||||
sock.sendall(msg)
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main program startup.
|
||||
|
@ -260,19 +156,8 @@ def main():
|
|||
service_path = service_path.strip()
|
||||
ServiceManager.add_services(service_path)
|
||||
|
||||
if cfg["daemonize"] == "True":
|
||||
daemonize(rootdir=None, umask=0, close_fds=False,
|
||||
stdin=os.devnull,
|
||||
stdout=cfg["logfile"], stderr=cfg["logfile"],
|
||||
pidfilename=cfg["pidfile"],
|
||||
defaultmaxfd=DEFAULT_MAXFD)
|
||||
signal.signal(signal.SIGUSR1, lambda signum, stackframe:
|
||||
logrotate(stdout=cfg["logfile"], stderr=cfg["logfile"]))
|
||||
|
||||
banner()
|
||||
if cfg["execfile"]:
|
||||
cfg["execfile"] = os.path.abspath(cfg["execfile"])
|
||||
sys.exit(exec_file(cfg))
|
||||
|
||||
try:
|
||||
cored(cfg)
|
||||
except KeyboardInterrupt:
|
||||
|
|
Loading…
Reference in a new issue