##// END OF EJS Templates
fix(mailing): don't default to empty string for smtp_password and user, since mailing lib only expects None as empty values
super-admin -
r5488:186b51dd default
parent child Browse files
Show More
@@ -1,454 +1,455 b''
1 # Copyright (C) 2012-2023 RhodeCode GmbH
1 # Copyright (C) 2012-2024 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 """
19 """
20 RhodeCode task modules, containing all task that suppose to be run
20 RhodeCode task modules, containing all task that suppose to be run
21 by celery daemon
21 by celery daemon
22 """
22 """
23
23
24 import os
24 import os
25 import time
25 import time
26
26
27 from pyramid_mailer.mailer import Mailer
27 from pyramid_mailer.mailer import Mailer
28 from pyramid_mailer.message import Message
28 from pyramid_mailer.message import Message
29 from email.utils import formatdate
29 from email.utils import formatdate
30
30
31 import rhodecode
31 import rhodecode
32 from rhodecode.lib import audit_logger
32 from rhodecode.lib import audit_logger
33 from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask, run_task
33 from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask, run_task
34 from rhodecode.lib import hooks_base
34 from rhodecode.lib import hooks_base
35 from rhodecode.lib.utils import adopt_for_celery
35 from rhodecode.lib.utils import adopt_for_celery
36 from rhodecode.lib.utils2 import safe_int, str2bool, aslist
36 from rhodecode.lib.utils2 import safe_int, str2bool, aslist
37 from rhodecode.lib.statsd_client import StatsdClient
37 from rhodecode.lib.statsd_client import StatsdClient
38 from rhodecode.model.db import (
38 from rhodecode.model.db import (
39 true, null, Session, IntegrityError, Repository, RepoGroup, User)
39 true, null, Session, IntegrityError, Repository, RepoGroup, User)
40 from rhodecode.model.permission import PermissionModel
40 from rhodecode.model.permission import PermissionModel
41
41
42
42
43 @async_task(ignore_result=True, base=RequestContextTask)
43 @async_task(ignore_result=True, base=RequestContextTask)
44 def send_email(recipients, subject, body='', html_body='', email_config=None,
44 def send_email(recipients, subject, body='', html_body='', email_config=None,
45 extra_headers=None):
45 extra_headers=None):
46 """
46 """
47 Sends an email with defined parameters from the .ini files.
47 Sends an email with defined parameters from the .ini files.
48
48
49 :param recipients: list of recipients, it this is empty the defined email
49 :param recipients: list of recipients, it this is empty the defined email
50 address from field 'email_to' is used instead
50 address from field 'email_to' is used instead
51 :param subject: subject of the mail
51 :param subject: subject of the mail
52 :param body: body of the mail
52 :param body: body of the mail
53 :param html_body: html version of body
53 :param html_body: html version of body
54 :param email_config: specify custom configuration for mailer
54 :param email_config: specify custom configuration for mailer
55 :param extra_headers: specify custom headers
55 :param extra_headers: specify custom headers
56 """
56 """
57 log = get_logger(send_email)
57 log = get_logger(send_email)
58
58
59 email_config = email_config or rhodecode.CONFIG
59 email_config = email_config or rhodecode.CONFIG
60
60
61 mail_server = email_config.get('smtp_server') or None
61 mail_server = email_config.get('smtp_server') or None
62 if mail_server is None:
62 if mail_server is None:
63 log.error("SMTP server information missing. Sending email failed. "
63 log.error("SMTP server information missing. Sending email failed. "
64 "Make sure that `smtp_server` variable is configured "
64 "Make sure that `smtp_server` variable is configured "
65 "inside the .ini file")
65 "inside the .ini file")
66 return False
66 return False
67
67 conf_prefix = email_config.get('email_prefix', None)
68 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
68 prefix = f'{conf_prefix} ' if conf_prefix else ''
69 subject = f"{prefix}{subject}"
69
70
70 if recipients:
71 if recipients:
71 if isinstance(recipients, str):
72 if isinstance(recipients, str):
72 recipients = recipients.split(',')
73 recipients = recipients.split(',')
73 else:
74 else:
74 # if recipients are not defined we send to email_config + all admins
75 # if recipients are not defined we send to email_config + all admins
75 admins = []
76 admins = []
76 for u in User.query().filter(User.admin == true()).all():
77 for u in User.query().filter(User.admin == true()).all():
77 if u.email:
78 if u.email:
78 admins.append(u.email)
79 admins.append(u.email)
79 recipients = []
80 recipients = []
80 config_email = email_config.get('email_to')
81 config_email = email_config.get('email_to')
81 if config_email:
82 if config_email:
82 recipients += [config_email]
83 recipients += [config_email]
83 recipients += admins
84 recipients += admins
84
85
85 # translate our LEGACY config into the one that pyramid_mailer supports
86 # translate our LEGACY config into the one that pyramid_mailer supports
86 email_conf = dict(
87 email_conf = dict(
87 host=mail_server,
88 host=mail_server,
88 port=email_config.get('smtp_port', 25),
89 port=email_config.get('smtp_port', 25),
89 username=email_config.get('smtp_username'),
90 username=email_config.get('smtp_username', None),
90 password=email_config.get('smtp_password'),
91 password=email_config.get('smtp_password', None),
91
92
92 tls=str2bool(email_config.get('smtp_use_tls')),
93 tls=str2bool(email_config.get('smtp_use_tls')),
93 ssl=str2bool(email_config.get('smtp_use_ssl')),
94 ssl=str2bool(email_config.get('smtp_use_ssl')),
94
95
95 # SSL key file
96 # SSL key file
96 # keyfile='',
97 # keyfile='',
97
98
98 # SSL certificate file
99 # SSL certificate file
99 # certfile='',
100 # certfile='',
100
101
101 # Location of maildir
102 # Location of maildir
102 # queue_path='',
103 # queue_path='',
103
104
104 default_sender=email_config.get('app_email_from', 'RhodeCode-noreply@rhodecode.com'),
105 default_sender=email_config.get('app_email_from', 'RhodeCode-noreply@rhodecode.com'),
105
106
106 debug=str2bool(email_config.get('smtp_debug')),
107 debug=str2bool(email_config.get('smtp_debug')),
107 # /usr/sbin/sendmail Sendmail executable
108 # /usr/sbin/sendmail Sendmail executable
108 # sendmail_app='',
109 # sendmail_app='',
109
110
110 # {sendmail_app} -t -i -f {sender} Template for sendmail execution
111 # {sendmail_app} -t -i -f {sender} Template for sendmail execution
111 # sendmail_template='',
112 # sendmail_template='',
112 )
113 )
113
114
114 if extra_headers is None:
115 if extra_headers is None:
115 extra_headers = {}
116 extra_headers = {}
116
117
117 extra_headers.setdefault('Date', formatdate(time.time()))
118 extra_headers.setdefault('Date', formatdate(time.time()))
118
119
119 if 'thread_ids' in extra_headers:
120 if 'thread_ids' in extra_headers:
120 thread_ids = extra_headers.pop('thread_ids')
121 thread_ids = extra_headers.pop('thread_ids')
121 extra_headers['References'] = ' '.join('<{}>'.format(t) for t in thread_ids)
122 extra_headers['References'] = ' '.join('<{}>'.format(t) for t in thread_ids)
122
123
123 try:
124 try:
124 mailer = Mailer(**email_conf)
125 mailer = Mailer(**email_conf)
125
126
126 message = Message(subject=subject,
127 message = Message(subject=subject,
127 sender=email_conf['default_sender'],
128 sender=email_conf['default_sender'],
128 recipients=recipients,
129 recipients=recipients,
129 body=body, html=html_body,
130 body=body, html=html_body,
130 extra_headers=extra_headers)
131 extra_headers=extra_headers)
131 mailer.send_immediately(message)
132 mailer.send_immediately(message)
132 statsd = StatsdClient.statsd
133 statsd = StatsdClient.statsd
133 if statsd:
134 if statsd:
134 statsd.incr('rhodecode_email_sent_total')
135 statsd.incr('rhodecode_email_sent_total')
135
136
136 except Exception:
137 except Exception:
137 log.exception('Mail sending failed')
138 log.exception('Mail sending failed')
138 return False
139 return False
139 return True
140 return True
140
141
141
142
142 @async_task(ignore_result=True, base=RequestContextTask)
143 @async_task(ignore_result=True, base=RequestContextTask)
143 def create_repo(form_data, cur_user):
144 def create_repo(form_data, cur_user):
144 from rhodecode.model.repo import RepoModel
145 from rhodecode.model.repo import RepoModel
145 from rhodecode.model.user import UserModel
146 from rhodecode.model.user import UserModel
146 from rhodecode.model.scm import ScmModel
147 from rhodecode.model.scm import ScmModel
147 from rhodecode.model.settings import SettingsModel
148 from rhodecode.model.settings import SettingsModel
148
149
149 log = get_logger(create_repo)
150 log = get_logger(create_repo)
150
151
151 cur_user = UserModel()._get_user(cur_user)
152 cur_user = UserModel()._get_user(cur_user)
152 owner = cur_user
153 owner = cur_user
153
154
154 repo_name = form_data['repo_name']
155 repo_name = form_data['repo_name']
155 repo_name_full = form_data['repo_name_full']
156 repo_name_full = form_data['repo_name_full']
156 repo_type = form_data['repo_type']
157 repo_type = form_data['repo_type']
157 description = form_data['repo_description']
158 description = form_data['repo_description']
158 private = form_data['repo_private']
159 private = form_data['repo_private']
159 clone_uri = form_data.get('clone_uri')
160 clone_uri = form_data.get('clone_uri')
160 repo_group = safe_int(form_data['repo_group'])
161 repo_group = safe_int(form_data['repo_group'])
161 copy_fork_permissions = form_data.get('copy_permissions')
162 copy_fork_permissions = form_data.get('copy_permissions')
162 copy_group_permissions = form_data.get('repo_copy_permissions')
163 copy_group_permissions = form_data.get('repo_copy_permissions')
163 fork_of = form_data.get('fork_parent_id')
164 fork_of = form_data.get('fork_parent_id')
164 state = form_data.get('repo_state', Repository.STATE_PENDING)
165 state = form_data.get('repo_state', Repository.STATE_PENDING)
165
166
166 # repo creation defaults, private and repo_type are filled in form
167 # repo creation defaults, private and repo_type are filled in form
167 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
168 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
168 enable_statistics = form_data.get(
169 enable_statistics = form_data.get(
169 'enable_statistics', defs.get('repo_enable_statistics'))
170 'enable_statistics', defs.get('repo_enable_statistics'))
170 enable_locking = form_data.get(
171 enable_locking = form_data.get(
171 'enable_locking', defs.get('repo_enable_locking'))
172 'enable_locking', defs.get('repo_enable_locking'))
172 enable_downloads = form_data.get(
173 enable_downloads = form_data.get(
173 'enable_downloads', defs.get('repo_enable_downloads'))
174 'enable_downloads', defs.get('repo_enable_downloads'))
174
175
175 # set landing rev based on default branches for SCM
176 # set landing rev based on default branches for SCM
176 landing_ref, _label = ScmModel.backend_landing_ref(repo_type)
177 landing_ref, _label = ScmModel.backend_landing_ref(repo_type)
177
178
178 try:
179 try:
179 RepoModel()._create_repo(
180 RepoModel()._create_repo(
180 repo_name=repo_name_full,
181 repo_name=repo_name_full,
181 repo_type=repo_type,
182 repo_type=repo_type,
182 description=description,
183 description=description,
183 owner=owner,
184 owner=owner,
184 private=private,
185 private=private,
185 clone_uri=clone_uri,
186 clone_uri=clone_uri,
186 repo_group=repo_group,
187 repo_group=repo_group,
187 landing_rev=landing_ref,
188 landing_rev=landing_ref,
188 fork_of=fork_of,
189 fork_of=fork_of,
189 copy_fork_permissions=copy_fork_permissions,
190 copy_fork_permissions=copy_fork_permissions,
190 copy_group_permissions=copy_group_permissions,
191 copy_group_permissions=copy_group_permissions,
191 enable_statistics=enable_statistics,
192 enable_statistics=enable_statistics,
192 enable_locking=enable_locking,
193 enable_locking=enable_locking,
193 enable_downloads=enable_downloads,
194 enable_downloads=enable_downloads,
194 state=state
195 state=state
195 )
196 )
196
197
197 Session().commit()
198 Session().commit()
198
199
199 # now create this repo on Filesystem
200 # now create this repo on Filesystem
200 RepoModel()._create_filesystem_repo(
201 RepoModel()._create_filesystem_repo(
201 repo_name=repo_name,
202 repo_name=repo_name,
202 repo_type=repo_type,
203 repo_type=repo_type,
203 repo_group=RepoModel()._get_repo_group(repo_group),
204 repo_group=RepoModel()._get_repo_group(repo_group),
204 clone_uri=clone_uri,
205 clone_uri=clone_uri,
205 )
206 )
206 repo = Repository.get_by_repo_name(repo_name_full)
207 repo = Repository.get_by_repo_name(repo_name_full)
207 hooks_base.create_repository(created_by=owner.username, **repo.get_dict())
208 hooks_base.create_repository(created_by=owner.username, **repo.get_dict())
208
209
209 # update repo commit caches initially
210 # update repo commit caches initially
210 repo.update_commit_cache(recursive=False)
211 repo.update_commit_cache(recursive=False)
211
212
212 # set new created state
213 # set new created state
213 repo.set_state(Repository.STATE_CREATED)
214 repo.set_state(Repository.STATE_CREATED)
214 repo_id = repo.repo_id
215 repo_id = repo.repo_id
215 repo_data = repo.get_api_data()
216 repo_data = repo.get_api_data()
216
217
217 audit_logger.store(
218 audit_logger.store(
218 'repo.create', action_data={'data': repo_data},
219 'repo.create', action_data={'data': repo_data},
219 user=cur_user,
220 user=cur_user,
220 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
221 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
221
222
222 Session().commit()
223 Session().commit()
223
224
224 PermissionModel().trigger_permission_flush()
225 PermissionModel().trigger_permission_flush()
225
226
226 except Exception as e:
227 except Exception as e:
227 log.warning('Exception occurred when creating repository, '
228 log.warning('Exception occurred when creating repository, '
228 'doing cleanup...', exc_info=True)
229 'doing cleanup...', exc_info=True)
229 if isinstance(e, IntegrityError):
230 if isinstance(e, IntegrityError):
230 Session().rollback()
231 Session().rollback()
231
232
232 # rollback things manually !
233 # rollback things manually !
233 repo = Repository.get_by_repo_name(repo_name_full)
234 repo = Repository.get_by_repo_name(repo_name_full)
234 if repo:
235 if repo:
235 Repository.delete(repo.repo_id)
236 Repository.delete(repo.repo_id)
236 Session().commit()
237 Session().commit()
237 RepoModel()._delete_filesystem_repo(repo)
238 RepoModel()._delete_filesystem_repo(repo)
238 log.info('Cleanup of repo %s finished', repo_name_full)
239 log.info('Cleanup of repo %s finished', repo_name_full)
239 raise
240 raise
240
241
241 return True
242 return True
242
243
243
244
244 @async_task(ignore_result=True, base=RequestContextTask)
245 @async_task(ignore_result=True, base=RequestContextTask)
245 def create_repo_fork(form_data, cur_user):
246 def create_repo_fork(form_data, cur_user):
246 """
247 """
247 Creates a fork of repository using internal VCS methods
248 Creates a fork of repository using internal VCS methods
248 """
249 """
249 from rhodecode.model.repo import RepoModel
250 from rhodecode.model.repo import RepoModel
250 from rhodecode.model.user import UserModel
251 from rhodecode.model.user import UserModel
251
252
252 log = get_logger(create_repo_fork)
253 log = get_logger(create_repo_fork)
253
254
254 cur_user = UserModel()._get_user(cur_user)
255 cur_user = UserModel()._get_user(cur_user)
255 owner = cur_user
256 owner = cur_user
256
257
257 repo_name = form_data['repo_name'] # fork in this case
258 repo_name = form_data['repo_name'] # fork in this case
258 repo_name_full = form_data['repo_name_full']
259 repo_name_full = form_data['repo_name_full']
259 repo_type = form_data['repo_type']
260 repo_type = form_data['repo_type']
260 description = form_data['description']
261 description = form_data['description']
261 private = form_data['private']
262 private = form_data['private']
262 clone_uri = form_data.get('clone_uri')
263 clone_uri = form_data.get('clone_uri')
263 repo_group = safe_int(form_data['repo_group'])
264 repo_group = safe_int(form_data['repo_group'])
264 landing_ref = form_data['landing_rev']
265 landing_ref = form_data['landing_rev']
265 copy_fork_permissions = form_data.get('copy_permissions')
266 copy_fork_permissions = form_data.get('copy_permissions')
266 fork_id = safe_int(form_data.get('fork_parent_id'))
267 fork_id = safe_int(form_data.get('fork_parent_id'))
267
268
268 try:
269 try:
269 fork_of = RepoModel()._get_repo(fork_id)
270 fork_of = RepoModel()._get_repo(fork_id)
270 RepoModel()._create_repo(
271 RepoModel()._create_repo(
271 repo_name=repo_name_full,
272 repo_name=repo_name_full,
272 repo_type=repo_type,
273 repo_type=repo_type,
273 description=description,
274 description=description,
274 owner=owner,
275 owner=owner,
275 private=private,
276 private=private,
276 clone_uri=clone_uri,
277 clone_uri=clone_uri,
277 repo_group=repo_group,
278 repo_group=repo_group,
278 landing_rev=landing_ref,
279 landing_rev=landing_ref,
279 fork_of=fork_of,
280 fork_of=fork_of,
280 copy_fork_permissions=copy_fork_permissions
281 copy_fork_permissions=copy_fork_permissions
281 )
282 )
282
283
283 Session().commit()
284 Session().commit()
284
285
285 base_path = Repository.base_path()
286 base_path = Repository.base_path()
286 source_repo_path = os.path.join(base_path, fork_of.repo_name)
287 source_repo_path = os.path.join(base_path, fork_of.repo_name)
287
288
288 # now create this repo on Filesystem
289 # now create this repo on Filesystem
289 RepoModel()._create_filesystem_repo(
290 RepoModel()._create_filesystem_repo(
290 repo_name=repo_name,
291 repo_name=repo_name,
291 repo_type=repo_type,
292 repo_type=repo_type,
292 repo_group=RepoModel()._get_repo_group(repo_group),
293 repo_group=RepoModel()._get_repo_group(repo_group),
293 clone_uri=source_repo_path,
294 clone_uri=source_repo_path,
294 )
295 )
295 repo = Repository.get_by_repo_name(repo_name_full)
296 repo = Repository.get_by_repo_name(repo_name_full)
296 hooks_base.create_repository(created_by=owner.username, **repo.get_dict())
297 hooks_base.create_repository(created_by=owner.username, **repo.get_dict())
297
298
298 # update repo commit caches initially
299 # update repo commit caches initially
299 config = repo._config
300 config = repo._config
300 config.set('extensions', 'largefiles', '')
301 config.set('extensions', 'largefiles', '')
301 repo.update_commit_cache(config=config, recursive=False)
302 repo.update_commit_cache(config=config, recursive=False)
302
303
303 # set new created state
304 # set new created state
304 repo.set_state(Repository.STATE_CREATED)
305 repo.set_state(Repository.STATE_CREATED)
305
306
306 repo_id = repo.repo_id
307 repo_id = repo.repo_id
307 repo_data = repo.get_api_data()
308 repo_data = repo.get_api_data()
308 audit_logger.store(
309 audit_logger.store(
309 'repo.fork', action_data={'data': repo_data},
310 'repo.fork', action_data={'data': repo_data},
310 user=cur_user,
311 user=cur_user,
311 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
312 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
312
313
313 Session().commit()
314 Session().commit()
314 except Exception as e:
315 except Exception as e:
315 log.warning('Exception occurred when forking repository, '
316 log.warning('Exception occurred when forking repository, '
316 'doing cleanup...', exc_info=True)
317 'doing cleanup...', exc_info=True)
317 if isinstance(e, IntegrityError):
318 if isinstance(e, IntegrityError):
318 Session().rollback()
319 Session().rollback()
319
320
320 # rollback things manually !
321 # rollback things manually !
321 repo = Repository.get_by_repo_name(repo_name_full)
322 repo = Repository.get_by_repo_name(repo_name_full)
322 if repo:
323 if repo:
323 Repository.delete(repo.repo_id)
324 Repository.delete(repo.repo_id)
324 Session().commit()
325 Session().commit()
325 RepoModel()._delete_filesystem_repo(repo)
326 RepoModel()._delete_filesystem_repo(repo)
326 log.info('Cleanup of repo %s finished', repo_name_full)
327 log.info('Cleanup of repo %s finished', repo_name_full)
327 raise
328 raise
328
329
329 return True
330 return True
330
331
331
332
332 @async_task(ignore_result=True, base=RequestContextTask)
333 @async_task(ignore_result=True, base=RequestContextTask)
333 def repo_maintenance(repoid):
334 def repo_maintenance(repoid):
334 from rhodecode.lib import repo_maintenance as repo_maintenance_lib
335 from rhodecode.lib import repo_maintenance as repo_maintenance_lib
335 log = get_logger(repo_maintenance)
336 log = get_logger(repo_maintenance)
336 repo = Repository.get_by_id_or_repo_name(repoid)
337 repo = Repository.get_by_id_or_repo_name(repoid)
337 if repo:
338 if repo:
338 maintenance = repo_maintenance_lib.RepoMaintenance()
339 maintenance = repo_maintenance_lib.RepoMaintenance()
339 tasks = maintenance.get_tasks_for_repo(repo)
340 tasks = maintenance.get_tasks_for_repo(repo)
340 log.debug('Executing %s tasks on repo `%s`', tasks, repoid)
341 log.debug('Executing %s tasks on repo `%s`', tasks, repoid)
341 executed_types = maintenance.execute(repo)
342 executed_types = maintenance.execute(repo)
342 log.debug('Got execution results %s', executed_types)
343 log.debug('Got execution results %s', executed_types)
343 else:
344 else:
344 log.debug('Repo `%s` not found or without a clone_url', repoid)
345 log.debug('Repo `%s` not found or without a clone_url', repoid)
345
346
346
347
347 @async_task(ignore_result=True, base=RequestContextTask)
348 @async_task(ignore_result=True, base=RequestContextTask)
348 def check_for_update(send_email_notification=True, email_recipients=None):
349 def check_for_update(send_email_notification=True, email_recipients=None):
349 from rhodecode.model.update import UpdateModel
350 from rhodecode.model.update import UpdateModel
350 from rhodecode.model.notification import EmailNotificationModel
351 from rhodecode.model.notification import EmailNotificationModel
351
352
352 log = get_logger(check_for_update)
353 log = get_logger(check_for_update)
353 update_url = UpdateModel().get_update_url()
354 update_url = UpdateModel().get_update_url()
354 cur_ver = rhodecode.__version__
355 cur_ver = rhodecode.__version__
355
356
356 try:
357 try:
357 data = UpdateModel().get_update_data(update_url)
358 data = UpdateModel().get_update_data(update_url)
358
359
359 current_ver = UpdateModel().get_stored_version(fallback=cur_ver)
360 current_ver = UpdateModel().get_stored_version(fallback=cur_ver)
360 latest_ver = data['versions'][0]['version']
361 latest_ver = data['versions'][0]['version']
361 UpdateModel().store_version(latest_ver)
362 UpdateModel().store_version(latest_ver)
362
363
363 if send_email_notification:
364 if send_email_notification:
364 log.debug('Send email notification is enabled. '
365 log.debug('Send email notification is enabled. '
365 'Current RhodeCode version: %s, latest known: %s', current_ver, latest_ver)
366 'Current RhodeCode version: %s, latest known: %s', current_ver, latest_ver)
366 if UpdateModel().is_outdated(current_ver, latest_ver):
367 if UpdateModel().is_outdated(current_ver, latest_ver):
367
368
368 email_kwargs = {
369 email_kwargs = {
369 'current_ver': current_ver,
370 'current_ver': current_ver,
370 'latest_ver': latest_ver,
371 'latest_ver': latest_ver,
371 }
372 }
372
373
373 (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email(
374 (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email(
374 EmailNotificationModel.TYPE_UPDATE_AVAILABLE, **email_kwargs)
375 EmailNotificationModel.TYPE_UPDATE_AVAILABLE, **email_kwargs)
375
376
376 email_recipients = aslist(email_recipients, sep=',') or \
377 email_recipients = aslist(email_recipients, sep=',') or \
377 [user.email for user in User.get_all_super_admins()]
378 [user.email for user in User.get_all_super_admins()]
378 run_task(send_email, email_recipients, subject,
379 run_task(send_email, email_recipients, subject,
379 email_body_plaintext, email_body)
380 email_body_plaintext, email_body)
380
381
381 except Exception:
382 except Exception:
382 log.exception('Failed to check for update')
383 log.exception('Failed to check for update')
383 raise
384 raise
384
385
385
386
386 def sync_last_update_for_objects(*args, **kwargs):
387 def sync_last_update_for_objects(*args, **kwargs):
387 skip_repos = kwargs.get('skip_repos')
388 skip_repos = kwargs.get('skip_repos')
388 if not skip_repos:
389 if not skip_repos:
389 repos = Repository.query() \
390 repos = Repository.query() \
390 .order_by(Repository.group_id.asc())
391 .order_by(Repository.group_id.asc())
391
392
392 for repo in repos:
393 for repo in repos:
393 repo.update_commit_cache(recursive=False)
394 repo.update_commit_cache(recursive=False)
394
395
395 skip_groups = kwargs.get('skip_groups')
396 skip_groups = kwargs.get('skip_groups')
396 if not skip_groups:
397 if not skip_groups:
397 repo_groups = RepoGroup.query() \
398 repo_groups = RepoGroup.query() \
398 .filter(RepoGroup.group_parent_id == null())
399 .filter(RepoGroup.group_parent_id == null())
399
400
400 for root_gr in repo_groups:
401 for root_gr in repo_groups:
401 for repo_gr in reversed(root_gr.recursive_groups()):
402 for repo_gr in reversed(root_gr.recursive_groups()):
402 repo_gr.update_commit_cache()
403 repo_gr.update_commit_cache()
403
404
404
405
405 @async_task(ignore_result=True, base=RequestContextTask)
406 @async_task(ignore_result=True, base=RequestContextTask)
406 def test_celery_exception(msg):
407 def test_celery_exception(msg):
407 raise Exception(f'Test exception: {msg}')
408 raise Exception(f'Test exception: {msg}')
408
409
409
410
410 @async_task(ignore_result=True, base=RequestContextTask)
411 @async_task(ignore_result=True, base=RequestContextTask)
411 def sync_last_update(*args, **kwargs):
412 def sync_last_update(*args, **kwargs):
412 sync_last_update_for_objects(*args, **kwargs)
413 sync_last_update_for_objects(*args, **kwargs)
413
414
414
415
415 @async_task(ignore_result=False)
416 @async_task(ignore_result=False)
416 def beat_check(*args, **kwargs):
417 def beat_check(*args, **kwargs):
417 log = get_logger(beat_check)
418 log = get_logger(beat_check)
418 log.info('%r: Got args: %r and kwargs %r', beat_check, args, kwargs)
419 log.info('%r: Got args: %r and kwargs %r', beat_check, args, kwargs)
419 return time.time()
420 return time.time()
420
421
421
422
422 @async_task
423 @async_task
423 @adopt_for_celery
424 @adopt_for_celery
424 def repo_size(extras):
425 def repo_size(extras):
425 from rhodecode.lib.hooks_base import repo_size
426 from rhodecode.lib.hooks_base import repo_size
426 return repo_size(extras)
427 return repo_size(extras)
427
428
428
429
429 @async_task
430 @async_task
430 @adopt_for_celery
431 @adopt_for_celery
431 def pre_pull(extras):
432 def pre_pull(extras):
432 from rhodecode.lib.hooks_base import pre_pull
433 from rhodecode.lib.hooks_base import pre_pull
433 return pre_pull(extras)
434 return pre_pull(extras)
434
435
435
436
436 @async_task
437 @async_task
437 @adopt_for_celery
438 @adopt_for_celery
438 def post_pull(extras):
439 def post_pull(extras):
439 from rhodecode.lib.hooks_base import post_pull
440 from rhodecode.lib.hooks_base import post_pull
440 return post_pull(extras)
441 return post_pull(extras)
441
442
442
443
443 @async_task
444 @async_task
444 @adopt_for_celery
445 @adopt_for_celery
445 def pre_push(extras):
446 def pre_push(extras):
446 from rhodecode.lib.hooks_base import pre_push
447 from rhodecode.lib.hooks_base import pre_push
447 return pre_push(extras)
448 return pre_push(extras)
448
449
449
450
450 @async_task
451 @async_task
451 @adopt_for_celery
452 @adopt_for_celery
452 def post_push(extras):
453 def post_push(extras):
453 from rhodecode.lib.hooks_base import post_push
454 from rhodecode.lib.hooks_base import post_push
454 return post_push(extras)
455 return post_push(extras)
General Comments 0
You need to be logged in to leave comments. Login now