This repository has been archived by the owner on Dec 7, 2022. It is now read-only.
/
application.py
194 lines (159 loc) · 7.7 KB
/
application.py
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# Copyright (c) 2010-2012 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public
# License as published by the Free Software Foundation; either version
# 2 of the License (GPLv2) or (at your option) any later version.
# There is NO WARRANTY for this software, express or implied,
# including the implied warranties of MERCHANTABILITY,
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
# have received a copy of GPLv2 along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
import logging
import sys
# This keeps the web.py wsgi app from trying to handle otherwise unhandled
# exceptions and lets Pulp error handling middleware handle them instead
# This exists here as it is the first place that Pulp imports web.py, so all
# web.py applications will be instantiated *after* their base class is patched
def _handle_with_processors(self):
def process(processors):
if processors:
p, processors = processors[0], processors[1:]
return p(lambda : process(processors))
else:
return self.handle()
return process(self.processors)
import web
web.application.handle_with_processors = _handle_with_processors
from pulp.server import config # automatically loads config
from pulp.server import logs
from pulp.server.db import connection as db_connection
# We need to read the config, start the logging, and initialize the db
# connection prior to any other imports, since some of the imports will invoke
# setup methods.
logs.start_logging()
db_connection.initialize()
from pulp.plugins.loader import api as plugin_api
from pulp.server.agent.direct.services import Services as AgentServices
from pulp.plugins.loader import api as plugin_api
from pulp.server.db import reaper
from pulp.server.debugging import StacktraceDumper
from pulp.server.dispatch import factory as dispatch_factory
from pulp.server.managers import factory as manager_factory
from pulp.server.db.migrate import models as migration_models
from pulp.server.webservices.controllers import (
agent, consumer_groups, consumers, contents, dispatch, events, permissions,
plugins, repo_groups, repositories, roles, root_actions, status, users)
from pulp.server.webservices.middleware.exception import ExceptionHandlerMiddleware
from pulp.server.webservices.middleware.postponed import PostponedOperationMiddleware
# constants and application globals --------------------------------------------
URLS = (
# Please keep the following in alphabetical order.
'/v2/actions', root_actions.application,
'/v2/agent', agent.application,
'/v2/consumer_groups', consumer_groups.application,
'/v2/consumers', consumers.application,
'/v2/content', contents.application,
'/v2/events', events.application,
'/v2/permissions', permissions.application,
'/v2/plugins', plugins.application,
'/v2/queued_calls', dispatch.queued_call_application,
'/v2/repo_groups', repo_groups.application,
'/v2/repositories', repositories.application,
'/v2/roles', roles.application,
'/v2/status', status.application,
'/v2/task_groups', dispatch.task_group_application,
'/v2/tasks', dispatch.task_application,
'/v2/users', users.application,
)
_LOG = logging.getLogger(__name__)
_IS_INITIALIZED = False
STACK_TRACER = None
# -- initialization -----------------------------------------------------------
class InitializationException(Exception):
def __init__(self, message):
Exception.__init__(self, message)
self.message = message
def _initialize_pulp():
# This initialization order is very sensitive, and each touches a number of
# sub-systems in pulp. If you get this wrong, you will have pulp tripping
# over itself on start up.
global _IS_INITIALIZED, STACK_TRACER
if _IS_INITIALIZED:
return
# Verify the database has been migrated to the correct version. This is
# very likely a reason the server will fail to start.
try:
migration_models.check_package_versions()
except Exception:
msg = 'The database has not been migrated to the current version. '
msg += 'Run pulp-manage-db and restart the application.'
raise InitializationException(msg), None, sys.exc_info()[2]
# Load plugins and resolve against types. This is also a likely candidate
# for causing the server to fail to start.
try:
plugin_api.initialize()
except Exception, e:
msg = 'One or more plugins failed to initialize. If a new type has '
msg += 'been added, run pulp-manage-db to load the type into the '
msg += 'database and restart the application. '
msg += 'Error message: %s' % str(e)
raise InitializationException(msg), None, sys.exc_info()[2]
# There's a significantly smaller chance the following calls will fail.
# The previous two are likely user errors, but the remainder represent
# something gone horribly wrong. As such, I'm not going to account for each
# and instead simply let the exception itself bubble up.
# Load the mappings of manager type to managers
manager_factory.initialize()
# Initialize the tasking subsystem
dispatch_factory.initialize()
# Ensure the minimal auth configuration
role_manager = manager_factory.role_manager()
role_manager.ensure_super_user_role()
user_manager = manager_factory.user_manager()
user_manager.ensure_admin()
# database document reaper
reaper.initialize()
# agent services
AgentServices.start()
# Setup debugging, if configured
if config.config.getboolean('server', 'debugging_mode'):
STACK_TRACER = StacktraceDumper()
STACK_TRACER.start()
# If we got this far, it was successful, so flip the flag
_IS_INITIALIZED = True
def wsgi_application():
"""
Application factory to create, configure, and return a WSGI application
using the web.py framework and custom Pulp middleware.
@return: wsgi application callable
"""
application = web.subdir_application(URLS).wsgifunc()
stack_components = [application, PostponedOperationMiddleware, ExceptionHandlerMiddleware]
stack = reduce(lambda a, m: m(a), stack_components)
# The following intentionally don't raise the exception. The logging writes
# to both error_log and pulp.log. Raising the exception caused it to be
# logged twice to error_log, which was annoying. The Pulp server still
# fails to start (I can't even log in), and on attempts to use it the
# initialize failure message is logged again. I like that behavior so I
# think this approach makes sense. But if there is a compelling reason to
# raise the exception, change it; I don't have a strong conviction behind
# this approach other than the duplicate logging and the appearance that it
# works as desired.
# jdob, Nov 21, 2012
try:
_initialize_pulp()
except InitializationException, e:
_LOG.fatal('*************************************************************')
_LOG.fatal('The Pulp server failed to start due to the following reasons:')
_LOG.exception(' ' + e.message)
_LOG.fatal('*************************************************************')
return
except:
_LOG.fatal('*************************************************************')
_LOG.exception('The Pulp server encountered an unexpected failure during initialization')
_LOG.fatal('*************************************************************')
return
_LOG.info('*************************************************************')
_LOG.info('The Pulp server has been successfully initialized')
_LOG.info('*************************************************************')
return stack