From 22e8079c16a6e3fe1388ab158f2eebf71d198253 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 6 Sep 2019 11:16:00 +0200 Subject: [PATCH] Adapt httpd test server to Py3 --- pybootd/tests/httpd.py | 81 +++++++++++++++++++++++++----------------- pybootd/util.py | 21 ++++++----- 2 files changed, 62 insertions(+), 40 deletions(-) diff --git a/pybootd/tests/httpd.py b/pybootd/tests/httpd.py index e074c7f..9b8fede 100755 --- a/pybootd/tests/httpd.py +++ b/pybootd/tests/httpd.py @@ -1,7 +1,6 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 # -# Copyright (c) 2010-2016 Emmanuel Blot +# Copyright (c) 2010-2019 Emmanuel Blot # Copyright (c) 2010-2011 Neotion # # This library is free software; you can redistribute it and/or @@ -18,14 +17,22 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -import sys -import urlparse -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -from optparse import OptionParser -from util import logger_factory, to_bool, to_int, EasyConfigParser +"""HTTPd tiny server to exercise the pybootd daemon""" + +from argparse import ArgumentParser, FileType +from http.server import BaseHTTPRequestHandler, HTTPServer +from sys import exit as sysexit, modules, stderr +from traceback import format_exc +from urllib.parse import parse_qs, urlsplit +from pybootd.util import logger_factory, to_bool, to_int, EasyConfigParser -class HttpdDaemon(HTTPServer): +#pylint: disable-msg=broad-except +#pylint: disable-msg=missing-docstring +#pylint: disable-msg=invalid-name + + +class HttpdTestDaemon(HTTPServer): class ReqHandler(BaseHTTPRequestHandler): @@ -33,8 +40,9 @@ class HttpdDaemon(HTTPServer): log = self.server.log log.debug("GET from %s:%d" % self.client_address) log.debug("Request: %s" % self.path) - urlparts = urlparse.urlsplit(self.path) - query = urlparse.parse_qs(urlparts.query) + urlparts = urlsplit(self.path) + query = parse_qs(urlparts.query) + uuid = '' if urlparts.path in ('/boot', '/linux'): if 'uuid' in query: uuids = query['uuid'] @@ -79,30 +87,39 @@ class HttpdDaemon(HTTPServer): self.serve_forever() -if __name__ == "__main__": - usage = 'Usage: %prog [options]\n' \ - ' HTTPd tiny server to exercise the pybootd daemon' - optparser = OptionParser(usage=usage) - optparser.add_option('-c', '--config', dest='config', - help='configuration file') - (options, args) = optparser.parse_args(sys.argv[1:]) - - if not options.config: - raise RuntimeError('Missing configuration file') - - cfgparser = EasyConfigParser() - with open(options.config, 'rt') as config: - cfgparser.readfp(config) - - logger = logger_factory(logtype=cfgparser.get('logger', 'type', 'stderr'), - logfile=cfgparser.get('logger', 'file'), - level=cfgparser.get('logger', 'level', 'info')) - +def main(): + debug = False try: - bt = HttpdDaemon(logger, cfgparser) + argparser = ArgumentParser(description=modules[__name__].__doc__) + argparser.add_argument('-c', '--config', dest='config', required=True, + type=FileType('rt'), + help='configuration file') + argparser.add_argument('-d', '--debug', action='store_true', + help='enable debug mode') + args = argparser.parse_args() + + cfgparser = EasyConfigParser() + cfgparser.read_file(args.config) + + logger = logger_factory(logtype=cfgparser.get('logger', 'type', + 'stderr'), + logfile=cfgparser.get('logger', 'file'), + level=cfgparser.get('logger', 'level', 'info')) + + bt = HttpdTestDaemon(logger, cfgparser) bt.start() while True: import time time.sleep(5) + except Exception as exc: + print('\nError: %s' % exc, file=stderr) + if debug: + print(format_exc(chain=False), file=stderr) + sysexit(1) except KeyboardInterrupt: - print "Aborting..." + print("\nAborting...", file=stderr) + sysexit(2) + + +if __name__ == '__main__': + main() diff --git a/pybootd/util.py b/pybootd/util.py index ff17864..9a665d3 100644 --- a/pybootd/util.py +++ b/pybootd/util.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # Copyright (c) 2010-2019 Emmanuel Blot # Copyright (c) 2010-2011 Neotion # @@ -17,7 +15,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -from configparser import SafeConfigParser, InterpolationSyntaxError +from configparser import ConfigParser, InterpolationSyntaxError from logging import (DEBUG, INFO, ERROR, CRITICAL, WARNING, Formatter, FileHandler, StreamHandler, getLogger) from logging.handlers import (BufferingHandler, NTEventLogHandler, @@ -235,7 +233,15 @@ def get_iface_config(address): return nifcfg(address) -class EasyConfigParser(SafeConfigParser): +def is_quoted(str_): + """Tells whether a string is enclosed in simple- or double- quoted + markers""" + str_ = str_.strip() + return (str_.startswith('"') and str_.endswith('"')) or \ + (str_.startswith("'") and str_.endswith("'")) + + +class EasyConfigParser(ConfigParser): """ConfigParser extension to support default config values and do not mess with multi-line option strings""" @@ -251,8 +257,8 @@ class EasyConfigParser(SafeConfigParser): return default if not self.has_option(section, option): return default - return SafeConfigParser.get(self, section, option, raw=raw, vars=vars, - fallback=fallback) + return ConfigParser.get(self, section, option, raw=raw, vars=vars, + fallback=fallback) def write(self, filep): """Write an .ini-format representation of the configuration state, @@ -274,5 +280,4 @@ class EasyConfigParser(SafeConfigParser): if is_quoted(rawval): return rawval # cannot use 'super' here as ConfigParser is outdated - return SafeConfigParser._interpolate(self, section, option, - rawval, vars) + return ConfigParser._interpolate(self, section, option, rawval, vars)