Fix homeserver config parsing

This commit is contained in:
Mark Haines 2014-09-01 15:51:15 +01:00
parent a9512d0994
commit 9ea1de432d
9 changed files with 66 additions and 36 deletions

9
demo/demo.tls.dh Normal file
View file

@ -0,0 +1,9 @@
2048-bit DH parameters taken from rfc3526
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb
IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft
awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT
mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh
fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq
5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==
-----END DH PARAMETERS-----

View file

@ -6,17 +6,27 @@ CWD=$(pwd)
cd "$DIR/.." cd "$DIR/.."
mkdir -p demo/etc
for port in 8080 8081 8082; do for port in 8080 8081 8082; do
echo "Starting server on port $port... " echo "Starting server on port $port... "
python -m synapse.app.homeserver \ python -m synapse.app.homeserver \
--generate-config \
--config-path "demo/etc/$port.config" \
-H "localhost:$port" \
-p "$port" \ -p "$port" \
-H "localhost:$port" \ -H "localhost:$port" \
-f "$DIR/$port.log" \ -f "$DIR/$port.log" \
-d "$DIR/$port.db" \ -d "$DIR/$port.db" \
-vv \
-D --pid-file "$DIR/$port.pid" \ -D --pid-file "$DIR/$port.pid" \
--manhole $((port + 1000)) --manhole $((port + 1000)) \
--tls-dh-params-path "demo/demo.tls.dh"
python -m synapse.app.homeserver \
--config-path "demo/etc/$port.config" \
-vv \
done done
echo "Starting webclient on port 8000..." echo "Starting webclient on port 8000..."

View file

@ -20,7 +20,6 @@ from synapse.server import HomeServer
from twisted.internet import reactor from twisted.internet import reactor
from twisted.enterprise import adbapi from twisted.enterprise import adbapi
from twisted.python.log import PythonLoggingObserver
from twisted.web.resource import Resource from twisted.web.resource import Resource
from twisted.web.static import File from twisted.web.static import File
from twisted.web.server import Site from twisted.web.server import Site
@ -34,12 +33,11 @@ from synapse.config.homeserver import HomeServerConfig
from daemonize import Daemonize from daemonize import Daemonize
import twisted.manhole.telnet import twisted.manhole.telnet
import argparse
import logging import logging
import logging.config
import sqlite3 import sqlite3
import os import os
import re import re
import sys
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -212,28 +210,25 @@ class SynapseHomeServer(HomeServer):
logger.info("Synapse now listening on port %d", port) logger.info("Synapse now listening on port %d", port)
def run(): def run():
reactor.run() reactor.run()
def setup(): def setup():
config = HomeServerConfig.load_config("Synapse Homeserver", sys.argv[1:]) config = HomeServerConfig.load_config(
"Synapse Homeserver",
config.setup_logging( sys.argv[1:],
verbosity=verbosity, generate_section="Homeserver"
filename=log_file,
config_path=args.log_config,
) )
config.setup_logging()
logger.info("Server hostname: %s", config.server_name) logger.info("Server hostname: %s", config.server_name)
if re.search(":[0-9]+$", config.server_name): if re.search(":[0-9]+$", config.server_name):
domain_with_port = config.server_name domain_with_port = config.server_name
else: else:
domain_with_port = "%s:%s" % (args.server_name, config.bind_port) domain_with_port = "%s:%s" % (config.server_name, config.bind_port)
hs = SynapseHomeServer( hs = SynapseHomeServer(
config.server_name, config.server_name,
@ -260,6 +255,7 @@ def setup():
reactor.listenTCP(config.manhole, f, interface='127.0.0.1') reactor.listenTCP(config.manhole, f, interface='127.0.0.1')
if config.daemonize: if config.daemonize:
print config.pid_file
daemon = Daemonize( daemon = Daemonize(
app="synapse-homeserver", app="synapse-homeserver",
pid=config.pid_file, pid=config.pid_file,

View file

@ -24,6 +24,10 @@ class Config(object):
def __init__(self, args): def __init__(self, args):
pass pass
@staticmethod
def abspath(file_path):
return os.path.abspath(file_path) if file_path else file_path
@staticmethod @staticmethod
def read_file(file_path): def read_file(file_path):
with open(file_path) as file_stream: with open(file_path) as file_stream:
@ -54,9 +58,14 @@ class Config(object):
metavar="CONFIG_FILE", metavar="CONFIG_FILE",
help="Specify config file" help="Specify config file"
) )
config_parser.add_argument(
"--generate-config",
action="store_true",
help="Generate config file"
)
config_args, remaining_args = config_parser.parse_known_args(argv) config_args, remaining_args = config_parser.parse_known_args(argv)
if generate_section: if config_args.generate_config:
if not config_args.config_path: if not config_args.config_path:
config_parser.error( config_parser.error(
"Must specify where to generate the config file" "Must specify where to generate the config file"
@ -64,6 +73,8 @@ class Config(object):
config_dir_path = os.path.dirname(config_args.config_path) config_dir_path = os.path.dirname(config_args.config_path)
if os.path.exists(config_args.config_path): if os.path.exists(config_args.config_path):
defaults = cls.read_config_file(config_args.config_path) defaults = cls.read_config_file(config_args.config_path)
else:
defaults = {}
else: else:
if config_args.config_path: if config_args.config_path:
defaults = cls.read_config_file(config_args.config_path) defaults = cls.read_config_file(config_args.config_path)
@ -75,23 +86,25 @@ class Config(object):
description=description, description=description,
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
) )
cls.add_arguments(parser)
parser.set_defaults(**defaults) parser.set_defaults(**defaults)
cls.add_arguments(parser)
args = parser.parse_args(remaining_args) args = parser.parse_args(remaining_args)
if generate_section: if config_args.generate_config:
config_dir_path = os.path.dirname(config_args.config_path) config_dir_path = os.path.dirname(config_args.config_path)
config_dir_path = os.path.abspath(config_dir_path) config_dir_path = os.path.abspath(config_dir_path)
cls.generate_config(args, config_dir_path) cls.generate_config(args, config_dir_path)
config = configparser.SafeConfigParser() config = configparser.SafeConfigParser()
config.add_section(generate_section) config.add_section(generate_section)
for key, value in vars(args).items(): for key, value in vars(args).items():
if key != "config_path" and value is not None: if (key not in set(["config_path", "generate_config"])
and value is not None):
print key, "=", value
config.set(generate_section, key, str(value)) config.set(generate_section, key, str(value))
with open(config_args.config_path, "w") as config_file: with open(config_args.config_path, "w") as config_file:
config.write(config_file) config.write(config_file)
sys.exit(0)
return cls(args) return cls(args)

View file

@ -18,14 +18,15 @@ import os
class DatabaseConfig(Config): class DatabaseConfig(Config):
def __init__(self, args): def __init__(self, args):
self.db_path = os.path.abspath(args.database_path) super(DatabaseConfig, self).__init__(args)
self.database_path = self.abspath(args.database_path)
@classmethod @classmethod
def add_arguments(cls, parser): def add_arguments(cls, parser):
super(DatabaseConfig, cls).add_arguments(parser) super(DatabaseConfig, cls).add_arguments(parser)
db_group = parser.add_argument_group("database") db_group = parser.add_argument_group("database")
db_group.add_argument( db_group.add_argument(
"-d", "--database", dest="database_path", default="homeserver.db", "-d", "--database-path", default="homeserver.db",
help="The database name." help="The database name."
) )

View file

@ -18,13 +18,13 @@ from ._base import Config
from twisted.python.log import PythonLoggingObserver from twisted.python.log import PythonLoggingObserver
import logging import logging
import logging.config import logging.config
import os
class LoggingConfig(Config): class LoggingConfig(Config):
def __init__(self, args): def __init__(self, args):
super(LoggingConfig, self).__init__(args)
self.verbosity = int(args.verbose) if args.verbose else None self.verbosity = int(args.verbose) if args.verbose else None
self.log_config = os.path.abspath(args.log_config) self.log_config = self.abspath(args.log_config)
self.log_file = os.path.abspath(args.log_file) self.log_file = self.abspath(args.log_file)
@classmethod @classmethod
def add_arguments(cls, parser): def add_arguments(cls, parser):
@ -47,21 +47,21 @@ class LoggingConfig(Config):
log_format = ( log_format = (
'%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s' '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s'
) )
if self.config_path is None: if self.log_config is None:
level = logging.INFO level = logging.INFO
if verbosity: if self.verbosity:
level = logging.DEBUG level = logging.DEBUG
# FIXME: we need a logging.WARN for a -q quiet option # FIXME: we need a logging.WARN for a -q quiet option
logging.basicConfig( logging.basicConfig(
level=level, level=level,
filename=filename, filename=self.log_file,
format=log_format format=log_format
) )
else: else:
logging.config.fileConfig(config_path) logging.config.fileConfig(self.log_config)
observer = PythonLoggingObserver() observer = PythonLoggingObserver()
observer.start() observer.start()

View file

@ -14,7 +14,6 @@
# limitations under the License. # limitations under the License.
import nacl.signing import nacl.signing
import socket
import os import os
from ._base import Config from ._base import Config
from syutil.base64util import encode_base64, decode_base64 from syutil.base64util import encode_base64, decode_base64
@ -28,7 +27,9 @@ class ServerConfig(Config):
self.bind_port = args.bind_port self.bind_port = args.bind_port
self.bind_host = args.bind_host self.bind_host = args.bind_host
self.daemonize = args.daemonize self.daemonize = args.daemonize
self.pid_file = os.path.abspath(args.pid_file) self.pid_file = self.abspath(args.pid_file)
self.webclient = not args.no_webclient
self.manhole = args.manhole
@classmethod @classmethod
def add_arguments(cls, parser): def add_arguments(cls, parser):
@ -44,11 +45,11 @@ class ServerConfig(Config):
help="Local interface to listen on") help="Local interface to listen on")
server_group.add_argument("-D", "--daemonize", action='store_true', server_group.add_argument("-D", "--daemonize", action='store_true',
help="Daemonize the home server") help="Daemonize the home server")
server_group.add_argument('--pid-file', default = "hs.pid", server_group.add_argument('--pid-file', default="hs.pid",
help="When running as a daemon, the file to" help="When running as a daemon, the file to"
" store the pid in") " store the pid in")
server_group.add_argument("-W", "--no-webclient", dest="webclient", server_group.add_argument("-W", "--no-webclient", default=True,
default=True, action="store_false", action="store_false",
help="Don't host a web client.") help="Don't host a web client.")
server_group.add_argument("--manhole", dest="manhole", type=int, server_group.add_argument("--manhole", dest="manhole", type=int,
help="Turn on the twisted telnet manhole" help="Turn on the twisted telnet manhole"

View file

@ -28,7 +28,7 @@ class TlsConfig(Config):
self.tls_private_key = self.read_tls_private_key( self.tls_private_key = self.read_tls_private_key(
args.tls_private_key_path args.tls_private_key_path
) )
self.tls_dh_params_path = args.tls_dh_params_path self.tls_dh_params_path = self.abspath(args.tls_dh_params_path)
@classmethod @classmethod
def add_arguments(cls, parser): def add_arguments(cls, parser):

View file

@ -78,7 +78,7 @@ class KeyStore(SQLBaseStore):
retcols=("tls_certificate",), retcols=("tls_certificate",),
) )
verification_key = nacl.signing.VerifyKey(verification_key_bytes) verification_key = nacl.signing.VerifyKey(verification_key_bytes)
defer.returnValue(verify_key) defer.returnValue(verification_key)
def store_server_verification_key(self, server_name, key_version, def store_server_verification_key(self, server_name, key_version,
key_server, ts_now_ms, verification_key): key_server, ts_now_ms, verification_key):