##// END OF EJS Templates
metadata: write license token for license migration for installer.
marcink -
r1524:4f05cb3a default
parent child Browse files
Show More
@@ -1,248 +1,252 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import datetime
21 import datetime
22 import logging
22 import logging
23 import pylons
23 import pylons
24 import Queue
24 import Queue
25 import subprocess32
25 import subprocess32
26 import os
26 import os
27
27
28 from pyramid.i18n import get_localizer
28 from pyramid.i18n import get_localizer
29 from pyramid.threadlocal import get_current_request
29 from pyramid.threadlocal import get_current_request
30 from threading import Thread
30 from threading import Thread
31
31
32 from rhodecode.translation import _ as tsf
32 from rhodecode.translation import _ as tsf
33
33
34 import rhodecode
34 import rhodecode
35
35
36 from pylons.i18n.translation import _get_translator
36 from pylons.i18n.translation import _get_translator
37 from pylons.util import ContextObj
37 from pylons.util import ContextObj
38 from routes.util import URLGenerator
38 from routes.util import URLGenerator
39
39
40 from rhodecode.lib.base import attach_context_attributes, get_auth_user
40 from rhodecode.lib.base import attach_context_attributes, get_auth_user
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44
44
45 def add_renderer_globals(event):
45 def add_renderer_globals(event):
46 # Put pylons stuff into the context. This will be removed as soon as
46 # Put pylons stuff into the context. This will be removed as soon as
47 # migration to pyramid is finished.
47 # migration to pyramid is finished.
48 conf = pylons.config._current_obj()
48 conf = pylons.config._current_obj()
49 event['h'] = conf.get('pylons.h')
49 event['h'] = conf.get('pylons.h')
50 event['c'] = pylons.tmpl_context
50 event['c'] = pylons.tmpl_context
51 event['url'] = pylons.url
51 event['url'] = pylons.url
52
52
53 # TODO: When executed in pyramid view context the request is not available
53 # TODO: When executed in pyramid view context the request is not available
54 # in the event. Find a better solution to get the request.
54 # in the event. Find a better solution to get the request.
55 request = event['request'] or get_current_request()
55 request = event['request'] or get_current_request()
56
56
57 # Add Pyramid translation as '_' to context
57 # Add Pyramid translation as '_' to context
58 event['_'] = request.translate
58 event['_'] = request.translate
59 event['_ungettext'] = request.plularize
59 event['_ungettext'] = request.plularize
60
60
61
61
62 def add_localizer(event):
62 def add_localizer(event):
63 request = event.request
63 request = event.request
64 localizer = get_localizer(request)
64 localizer = get_localizer(request)
65
65
66 def auto_translate(*args, **kwargs):
66 def auto_translate(*args, **kwargs):
67 return localizer.translate(tsf(*args, **kwargs))
67 return localizer.translate(tsf(*args, **kwargs))
68
68
69 request.localizer = localizer
69 request.localizer = localizer
70 request.translate = auto_translate
70 request.translate = auto_translate
71 request.plularize = localizer.pluralize
71 request.plularize = localizer.pluralize
72
72
73
73
74 def set_user_lang(event):
74 def set_user_lang(event):
75 request = event.request
75 request = event.request
76 cur_user = getattr(request, 'user', None)
76 cur_user = getattr(request, 'user', None)
77
77
78 if cur_user:
78 if cur_user:
79 user_lang = cur_user.get_instance().user_data.get('language')
79 user_lang = cur_user.get_instance().user_data.get('language')
80 if user_lang:
80 if user_lang:
81 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
81 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
82 event.request._LOCALE_ = user_lang
82 event.request._LOCALE_ = user_lang
83
83
84
84
85 def add_pylons_context(event):
85 def add_pylons_context(event):
86 request = event.request
86 request = event.request
87
87
88 config = rhodecode.CONFIG
88 config = rhodecode.CONFIG
89 environ = request.environ
89 environ = request.environ
90 session = request.session
90 session = request.session
91
91
92 if hasattr(request, 'vcs_call'):
92 if hasattr(request, 'vcs_call'):
93 # skip vcs calls
93 # skip vcs calls
94 return
94 return
95
95
96 # Setup pylons globals.
96 # Setup pylons globals.
97 pylons.config._push_object(config)
97 pylons.config._push_object(config)
98 pylons.request._push_object(request)
98 pylons.request._push_object(request)
99 pylons.session._push_object(session)
99 pylons.session._push_object(session)
100 pylons.translator._push_object(_get_translator(config.get('lang')))
100 pylons.translator._push_object(_get_translator(config.get('lang')))
101
101
102 pylons.url._push_object(URLGenerator(config['routes.map'], environ))
102 pylons.url._push_object(URLGenerator(config['routes.map'], environ))
103 session_key = (
103 session_key = (
104 config['pylons.environ_config'].get('session', 'beaker.session'))
104 config['pylons.environ_config'].get('session', 'beaker.session'))
105 environ[session_key] = session
105 environ[session_key] = session
106
106
107 if hasattr(request, 'rpc_method'):
107 if hasattr(request, 'rpc_method'):
108 # skip api calls
108 # skip api calls
109 return
109 return
110
110
111 # Get the rhodecode auth user object and make it available.
111 # Get the rhodecode auth user object and make it available.
112 auth_user = get_auth_user(environ)
112 auth_user = get_auth_user(environ)
113 request.user = auth_user
113 request.user = auth_user
114 environ['rc_auth_user'] = auth_user
114 environ['rc_auth_user'] = auth_user
115
115
116 # Setup the pylons context object ('c')
116 # Setup the pylons context object ('c')
117 context = ContextObj()
117 context = ContextObj()
118 context.rhodecode_user = auth_user
118 context.rhodecode_user = auth_user
119 attach_context_attributes(context, request)
119 attach_context_attributes(context, request)
120 pylons.tmpl_context._push_object(context)
120 pylons.tmpl_context._push_object(context)
121
121
122
122
123 def scan_repositories_if_enabled(event):
123 def scan_repositories_if_enabled(event):
124 """
124 """
125 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
125 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
126 does a repository scan if enabled in the settings.
126 does a repository scan if enabled in the settings.
127 """
127 """
128 from rhodecode.model.scm import ScmModel
128 from rhodecode.model.scm import ScmModel
129 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
129 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
130 settings = event.app.registry.settings
130 settings = event.app.registry.settings
131 vcs_server_enabled = settings['vcs.server.enable']
131 vcs_server_enabled = settings['vcs.server.enable']
132 import_on_startup = settings['startup.import_repos']
132 import_on_startup = settings['startup.import_repos']
133 if vcs_server_enabled and import_on_startup:
133 if vcs_server_enabled and import_on_startup:
134 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
134 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
135 repo2db_mapper(repositories, remove_obsolete=False)
135 repo2db_mapper(repositories, remove_obsolete=False)
136
136
137
137
138 def write_metadata_if_needed(event):
138 def write_metadata_if_needed(event):
139 """
139 """
140 Writes upgrade metadata
140 Writes upgrade metadata
141 """
141 """
142 import rhodecode
142 import rhodecode
143 from rhodecode.lib import system_info
143 from rhodecode.lib import system_info
144 from rhodecode.lib import ext_json
144 from rhodecode.lib import ext_json
145
145
146 def write():
146 def write():
147 fname = '.rcmetadata.json'
147 fname = '.rcmetadata.json'
148 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
148 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
149 metadata_destination = os.path.join(ini_loc, fname)
149 metadata_destination = os.path.join(ini_loc, fname)
150
150
151 configuration = system_info.SysInfo(
152 system_info.rhodecode_config)()['value']
153 license_token = configuration['config']['license_token']
151 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
154 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
152 del dbinfo['url']
155 del dbinfo['url']
153 metadata = dict(
156 metadata = dict(
154 desc='upgrade metadata info',
157 desc='upgrade metadata info',
158 license_token=license_token,
155 created_on=datetime.datetime.utcnow().isoformat(),
159 created_on=datetime.datetime.utcnow().isoformat(),
156 usage=system_info.SysInfo(system_info.usage_info)()['value'],
160 usage=system_info.SysInfo(system_info.usage_info)()['value'],
157 platform=system_info.SysInfo(system_info.platform_type)()['value'],
161 platform=system_info.SysInfo(system_info.platform_type)()['value'],
158 database=dbinfo,
162 database=dbinfo,
159 cpu=system_info.SysInfo(system_info.cpu)()['value'],
163 cpu=system_info.SysInfo(system_info.cpu)()['value'],
160 memory=system_info.SysInfo(system_info.memory)()['value'],
164 memory=system_info.SysInfo(system_info.memory)()['value'],
161 )
165 )
162
166
163 with open(metadata_destination, 'wb') as f:
167 with open(metadata_destination, 'wb') as f:
164 f.write(ext_json.json.dumps(metadata))
168 f.write(ext_json.json.dumps(metadata))
165
169
166 try:
170 try:
167 write()
171 write()
168 except Exception:
172 except Exception:
169 pass
173 pass
170
174
171
175
172 class Subscriber(object):
176 class Subscriber(object):
173 """
177 """
174 Base class for subscribers to the pyramid event system.
178 Base class for subscribers to the pyramid event system.
175 """
179 """
176 def __call__(self, event):
180 def __call__(self, event):
177 self.run(event)
181 self.run(event)
178
182
179 def run(self, event):
183 def run(self, event):
180 raise NotImplementedError('Subclass has to implement this.')
184 raise NotImplementedError('Subclass has to implement this.')
181
185
182
186
183 class AsyncSubscriber(Subscriber):
187 class AsyncSubscriber(Subscriber):
184 """
188 """
185 Subscriber that handles the execution of events in a separate task to not
189 Subscriber that handles the execution of events in a separate task to not
186 block the execution of the code which triggers the event. It puts the
190 block the execution of the code which triggers the event. It puts the
187 received events into a queue from which the worker process takes them in
191 received events into a queue from which the worker process takes them in
188 order.
192 order.
189 """
193 """
190 def __init__(self):
194 def __init__(self):
191 self._stop = False
195 self._stop = False
192 self._eventq = Queue.Queue()
196 self._eventq = Queue.Queue()
193 self._worker = self.create_worker()
197 self._worker = self.create_worker()
194 self._worker.start()
198 self._worker.start()
195
199
196 def __call__(self, event):
200 def __call__(self, event):
197 self._eventq.put(event)
201 self._eventq.put(event)
198
202
199 def create_worker(self):
203 def create_worker(self):
200 worker = Thread(target=self.do_work)
204 worker = Thread(target=self.do_work)
201 worker.daemon = True
205 worker.daemon = True
202 return worker
206 return worker
203
207
204 def stop_worker(self):
208 def stop_worker(self):
205 self._stop = False
209 self._stop = False
206 self._eventq.put(None)
210 self._eventq.put(None)
207 self._worker.join()
211 self._worker.join()
208
212
209 def do_work(self):
213 def do_work(self):
210 while not self._stop:
214 while not self._stop:
211 event = self._eventq.get()
215 event = self._eventq.get()
212 if event is not None:
216 if event is not None:
213 self.run(event)
217 self.run(event)
214
218
215
219
216 class AsyncSubprocessSubscriber(AsyncSubscriber):
220 class AsyncSubprocessSubscriber(AsyncSubscriber):
217 """
221 """
218 Subscriber that uses the subprocess32 module to execute a command if an
222 Subscriber that uses the subprocess32 module to execute a command if an
219 event is received. Events are handled asynchronously.
223 event is received. Events are handled asynchronously.
220 """
224 """
221
225
222 def __init__(self, cmd, timeout=None):
226 def __init__(self, cmd, timeout=None):
223 super(AsyncSubprocessSubscriber, self).__init__()
227 super(AsyncSubprocessSubscriber, self).__init__()
224 self._cmd = cmd
228 self._cmd = cmd
225 self._timeout = timeout
229 self._timeout = timeout
226
230
227 def run(self, event):
231 def run(self, event):
228 cmd = self._cmd
232 cmd = self._cmd
229 timeout = self._timeout
233 timeout = self._timeout
230 log.debug('Executing command %s.', cmd)
234 log.debug('Executing command %s.', cmd)
231
235
232 try:
236 try:
233 output = subprocess32.check_output(
237 output = subprocess32.check_output(
234 cmd, timeout=timeout, stderr=subprocess32.STDOUT)
238 cmd, timeout=timeout, stderr=subprocess32.STDOUT)
235 log.debug('Command finished %s', cmd)
239 log.debug('Command finished %s', cmd)
236 if output:
240 if output:
237 log.debug('Command output: %s', output)
241 log.debug('Command output: %s', output)
238 except subprocess32.TimeoutExpired as e:
242 except subprocess32.TimeoutExpired as e:
239 log.exception('Timeout while executing command.')
243 log.exception('Timeout while executing command.')
240 if e.output:
244 if e.output:
241 log.error('Command output: %s', e.output)
245 log.error('Command output: %s', e.output)
242 except subprocess32.CalledProcessError as e:
246 except subprocess32.CalledProcessError as e:
243 log.exception('Error while executing command.')
247 log.exception('Error while executing command.')
244 if e.output:
248 if e.output:
245 log.error('Command output: %s', e.output)
249 log.error('Command output: %s', e.output)
246 except:
250 except:
247 log.exception(
251 log.exception(
248 'Exception while executing command %s.', cmd)
252 'Exception while executing command %s.', cmd)
General Comments 0
You need to be logged in to leave comments. Login now