-
Notifications
You must be signed in to change notification settings - Fork 1
/
adminator-daemon
executable file
·140 lines (108 loc) · 4.55 KB
/
adminator-daemon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/python3 -tt
# Twisted hosts our website and helps with async tasks.
# The application threads are structured in the following way:
#
# reactor
# `-- manager (1 thread)
# `-- workers (2 threads)
# `-- website (4 threads)
#
from twisted.internet import reactor
from twisted.web.wsgi import WSGIResource
from twisted.web.server import Site
from twisted.python.threadpool import ThreadPool
from twisted.python import log
import psycopg2.extras
# Data are accessed through SQLSoup, using SQLAlchemy.
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base
#from sqlsoup import SQLSoup
#from sqlalchemy.orm import Session
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import relationship
from sqlalchemy.schema import MetaData
from sqlmodel import Session
# Command line arguments follow the GNU conventions.
from getopt import gnu_getopt
from sys import argv, stderr
# Configuration is stored in a simple ini file.
from configparser import ConfigParser
# Import all the application handles.
from adminator import make_site, Manager, AccessModel
from adminator.db import TSRangeType
if __name__ == '__main__':
def do_start(config):
# Start Twisted logging to console.
log.startLogging(stderr)
# Read database configuration options.
db_url = config.get('database', 'url')
# Read website configuration options.
http_debug = config.getboolean('http', 'debug', fallback=False)
http_host = config.get('http', 'host', fallback='localhost')
http_port = config.getint('http', 'port', fallback=5000)
http_pool = config.getint('http', 'pool_size', fallback=4)
# Read role mappings.
access_model = AccessModel(config.items('access'))
# Default to much saner database query defaults and always
# commit and/or flush statements explicitly.
engine = create_engine(db_url, echo=False)
# factory to create scoped_session of type Session (from sqlmodel, not sqlalchemy)
# to avoid multi-threading problems in new versions of things
def sqlmodel_factory():
return Session(engine, autoflush=False)
db = scoped_session(sqlmodel_factory)
# Extract manager options, sans the pool_size we handle here.
manager_opts = dict(config.items('manager'))
manager_pool = int(manager_opts.pop('pool_size', 2))
# Set the correct thread pool size for the manager.
reactor.suggestThreadPoolSize(manager_pool)
# Prepare the manager that runs in an exclusive thread.
manager = Manager(db, **manager_opts)
# Prepare the website that will get exposed to the users.
site = make_site(db, manager, access_model, debug=http_debug)
# Prepare WSGI site with a separate thread pool.
pool = ThreadPool(http_pool, http_pool, 'http')
site = Site(WSGIResource(reactor, pool, site))
pool.start()
# Bind the website to it's address.
reactor.listenTCP(http_port, site, interface=http_host)
# Run the Twisted reactor until the user terminates us.
reactor.run()
# Kill the HTTP ThreadPool.
pool.stop()
def do_help(*args, **kwargs):
print('Usage: adminator-daemon [--config=/etc/adminator.ini]')
print('Runs the adminator-daemon with given configuration.')
print('')
print('OPTIONS:')
print(' --help, -h Display this help.')
print(' --version, -V Display version info.')
print('')
print(' --config, -c file Load alternative configuration file.')
print('')
print('Report bugs at <http://github.com/techlib/adminator>.')
def do_version(*args, **kwargs):
print('adminator-daemon (NTK) 1')
# Parse command line arguments.
opts, args = gnu_getopt(argv, 'hVc:', ['help', 'version', 'config='])
action = do_start
config_path = '/etc/adminator.ini'
for k, v in opts:
if k in ('--help', '-h'):
action = do_help
elif k in ('--version', '-V'):
action = do_version
elif k in ('--config', '-c'):
config_path = v
# Load the configuration from file.
if action not in (do_help, do_version):
config = ConfigParser()
config.read(config_path)
# Load the configuration from file.
config = ConfigParser()
config.read(config_path)
# Perform the selected action.
action(config=config)
# vim:set sw=4 ts=4 et:
# -*- coding: utf-8 -*-