##// END OF EJS Templates
mail: use faster detection of email misconfiguration. This should be done at earliest...
marcink -
r3077:6903e671 default
parent child Browse files
Show More
@@ -1,307 +1,308 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2012-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 RhodeCode task modules, containing all task that suppose to be run
23 23 by celery daemon
24 24 """
25 25
26 26 import os
27 27 import time
28 28
29 29 import rhodecode
30 30 from rhodecode.lib import audit_logger
31 31 from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask
32 32 from rhodecode.lib.hooks_base import log_create_repository
33 33 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
34 34 from rhodecode.lib.utils2 import safe_int, str2bool
35 35 from rhodecode.model.db import Session, IntegrityError, Repository, User, true
36 36
37 37
38 38 @async_task(ignore_result=True, base=RequestContextTask)
39 39 def send_email(recipients, subject, body='', html_body='', email_config=None):
40 40 """
41 41 Sends an email with defined parameters from the .ini files.
42 42
43 43 :param recipients: list of recipients, it this is empty the defined email
44 44 address from field 'email_to' is used instead
45 45 :param subject: subject of the mail
46 46 :param body: body of the mail
47 47 :param html_body: html version of body
48 48 """
49 49 log = get_logger(send_email)
50 50
51 51 email_config = email_config or rhodecode.CONFIG
52
53 mail_server = email_config.get('smtp_server') or None
54 if mail_server is None:
55 log.error("SMTP server information missing. Sending email failed. "
56 "Make sure that `smtp_server` variable is configured "
57 "inside the .ini file")
58 return False
59
52 60 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
53 61 if not recipients:
54 62 # if recipients are not defined we send to email_config + all admins
55 63 admins = []
56 64 for u in User.query().filter(User.admin == true()).all():
57 65 if u.email:
58 66 admins.append(u.email)
59 67 recipients = []
60 68 config_email = email_config.get('email_to')
61 69 if config_email:
62 70 recipients += [config_email]
63 71 recipients += admins
64 72
65 mail_server = email_config.get('smtp_server') or None
66 if mail_server is None:
67 log.error("SMTP server information missing. Sending email failed. "
68 "Make sure that `smtp_server` variable is configured "
69 "inside the .ini file")
70 return False
71
72 73 mail_from = email_config.get('app_email_from', 'RhodeCode')
73 74 user = email_config.get('smtp_username')
74 75 passwd = email_config.get('smtp_password')
75 76 mail_port = email_config.get('smtp_port')
76 77 tls = str2bool(email_config.get('smtp_use_tls'))
77 78 ssl = str2bool(email_config.get('smtp_use_ssl'))
78 79 debug = str2bool(email_config.get('debug'))
79 80 smtp_auth = email_config.get('smtp_auth')
80 81
81 82 try:
82 83 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
83 84 mail_port, ssl, tls, debug=debug)
84 85 m.send(recipients, subject, body, html_body)
85 86 except Exception:
86 87 log.exception('Mail sending failed')
87 88 return False
88 89 return True
89 90
90 91
91 92 @async_task(ignore_result=True, base=RequestContextTask)
92 93 def create_repo(form_data, cur_user):
93 94 from rhodecode.model.repo import RepoModel
94 95 from rhodecode.model.user import UserModel
95 96 from rhodecode.model.settings import SettingsModel
96 97
97 98 log = get_logger(create_repo)
98 99
99 100 cur_user = UserModel()._get_user(cur_user)
100 101 owner = cur_user
101 102
102 103 repo_name = form_data['repo_name']
103 104 repo_name_full = form_data['repo_name_full']
104 105 repo_type = form_data['repo_type']
105 106 description = form_data['repo_description']
106 107 private = form_data['repo_private']
107 108 clone_uri = form_data.get('clone_uri')
108 109 repo_group = safe_int(form_data['repo_group'])
109 110 landing_rev = form_data['repo_landing_rev']
110 111 copy_fork_permissions = form_data.get('copy_permissions')
111 112 copy_group_permissions = form_data.get('repo_copy_permissions')
112 113 fork_of = form_data.get('fork_parent_id')
113 114 state = form_data.get('repo_state', Repository.STATE_PENDING)
114 115
115 116 # repo creation defaults, private and repo_type are filled in form
116 117 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
117 118 enable_statistics = form_data.get(
118 119 'enable_statistics', defs.get('repo_enable_statistics'))
119 120 enable_locking = form_data.get(
120 121 'enable_locking', defs.get('repo_enable_locking'))
121 122 enable_downloads = form_data.get(
122 123 'enable_downloads', defs.get('repo_enable_downloads'))
123 124
124 125 try:
125 126 repo = RepoModel()._create_repo(
126 127 repo_name=repo_name_full,
127 128 repo_type=repo_type,
128 129 description=description,
129 130 owner=owner,
130 131 private=private,
131 132 clone_uri=clone_uri,
132 133 repo_group=repo_group,
133 134 landing_rev=landing_rev,
134 135 fork_of=fork_of,
135 136 copy_fork_permissions=copy_fork_permissions,
136 137 copy_group_permissions=copy_group_permissions,
137 138 enable_statistics=enable_statistics,
138 139 enable_locking=enable_locking,
139 140 enable_downloads=enable_downloads,
140 141 state=state
141 142 )
142 143 Session().commit()
143 144
144 145 # now create this repo on Filesystem
145 146 RepoModel()._create_filesystem_repo(
146 147 repo_name=repo_name,
147 148 repo_type=repo_type,
148 149 repo_group=RepoModel()._get_repo_group(repo_group),
149 150 clone_uri=clone_uri,
150 151 )
151 152 repo = Repository.get_by_repo_name(repo_name_full)
152 153 log_create_repository(created_by=owner.username, **repo.get_dict())
153 154
154 155 # update repo commit caches initially
155 156 repo.update_commit_cache()
156 157
157 158 # set new created state
158 159 repo.set_state(Repository.STATE_CREATED)
159 160 repo_id = repo.repo_id
160 161 repo_data = repo.get_api_data()
161 162
162 163 audit_logger.store(
163 164 'repo.create', action_data={'data': repo_data},
164 165 user=cur_user,
165 166 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
166 167
167 168 Session().commit()
168 169 except Exception as e:
169 170 log.warning('Exception occurred when creating repository, '
170 171 'doing cleanup...', exc_info=True)
171 172 if isinstance(e, IntegrityError):
172 173 Session().rollback()
173 174
174 175 # rollback things manually !
175 176 repo = Repository.get_by_repo_name(repo_name_full)
176 177 if repo:
177 178 Repository.delete(repo.repo_id)
178 179 Session().commit()
179 180 RepoModel()._delete_filesystem_repo(repo)
180 181 log.info('Cleanup of repo %s finished', repo_name_full)
181 182 raise
182 183
183 184 return True
184 185
185 186
186 187 @async_task(ignore_result=True, base=RequestContextTask)
187 188 def create_repo_fork(form_data, cur_user):
188 189 """
189 190 Creates a fork of repository using internal VCS methods
190 191 """
191 192 from rhodecode.model.repo import RepoModel
192 193 from rhodecode.model.user import UserModel
193 194
194 195 log = get_logger(create_repo_fork)
195 196
196 197 cur_user = UserModel()._get_user(cur_user)
197 198 owner = cur_user
198 199
199 200 repo_name = form_data['repo_name'] # fork in this case
200 201 repo_name_full = form_data['repo_name_full']
201 202 repo_type = form_data['repo_type']
202 203 description = form_data['description']
203 204 private = form_data['private']
204 205 clone_uri = form_data.get('clone_uri')
205 206 repo_group = safe_int(form_data['repo_group'])
206 207 landing_rev = form_data['landing_rev']
207 208 copy_fork_permissions = form_data.get('copy_permissions')
208 209 fork_id = safe_int(form_data.get('fork_parent_id'))
209 210
210 211 try:
211 212 fork_of = RepoModel()._get_repo(fork_id)
212 213 RepoModel()._create_repo(
213 214 repo_name=repo_name_full,
214 215 repo_type=repo_type,
215 216 description=description,
216 217 owner=owner,
217 218 private=private,
218 219 clone_uri=clone_uri,
219 220 repo_group=repo_group,
220 221 landing_rev=landing_rev,
221 222 fork_of=fork_of,
222 223 copy_fork_permissions=copy_fork_permissions
223 224 )
224 225
225 226 Session().commit()
226 227
227 228 base_path = Repository.base_path()
228 229 source_repo_path = os.path.join(base_path, fork_of.repo_name)
229 230
230 231 # now create this repo on Filesystem
231 232 RepoModel()._create_filesystem_repo(
232 233 repo_name=repo_name,
233 234 repo_type=repo_type,
234 235 repo_group=RepoModel()._get_repo_group(repo_group),
235 236 clone_uri=source_repo_path,
236 237 )
237 238 repo = Repository.get_by_repo_name(repo_name_full)
238 239 log_create_repository(created_by=owner.username, **repo.get_dict())
239 240
240 241 # update repo commit caches initially
241 242 config = repo._config
242 243 config.set('extensions', 'largefiles', '')
243 244 repo.update_commit_cache(config=config)
244 245
245 246 # set new created state
246 247 repo.set_state(Repository.STATE_CREATED)
247 248
248 249 repo_id = repo.repo_id
249 250 repo_data = repo.get_api_data()
250 251 audit_logger.store(
251 252 'repo.fork', action_data={'data': repo_data},
252 253 user=cur_user,
253 254 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
254 255
255 256 Session().commit()
256 257 except Exception as e:
257 258 log.warning('Exception occurred when forking repository, '
258 259 'doing cleanup...', exc_info=True)
259 260 if isinstance(e, IntegrityError):
260 261 Session().rollback()
261 262
262 263 # rollback things manually !
263 264 repo = Repository.get_by_repo_name(repo_name_full)
264 265 if repo:
265 266 Repository.delete(repo.repo_id)
266 267 Session().commit()
267 268 RepoModel()._delete_filesystem_repo(repo)
268 269 log.info('Cleanup of repo %s finished', repo_name_full)
269 270 raise
270 271
271 272 return True
272 273
273 274
274 275 @async_task(ignore_result=True)
275 276 def repo_maintenance(repoid):
276 277 from rhodecode.lib import repo_maintenance as repo_maintenance_lib
277 278 log = get_logger(repo_maintenance)
278 279 repo = Repository.get_by_id_or_repo_name(repoid)
279 280 if repo:
280 281 maintenance = repo_maintenance_lib.RepoMaintenance()
281 282 tasks = maintenance.get_tasks_for_repo(repo)
282 283 log.debug('Executing %s tasks on repo `%s`', tasks, repoid)
283 284 executed_types = maintenance.execute(repo)
284 285 log.debug('Got execution results %s', executed_types)
285 286 else:
286 287 log.debug('Repo `%s` not found or without a clone_url', repoid)
287 288
288 289
289 290 @async_task(ignore_result=True)
290 291 def check_for_update():
291 292 from rhodecode.model.update import UpdateModel
292 293 update_url = UpdateModel().get_update_url()
293 294 cur_ver = rhodecode.__version__
294 295
295 296 try:
296 297 data = UpdateModel().get_update_data(update_url)
297 298 latest = data['versions'][0]
298 299 UpdateModel().store_version(latest['version'])
299 300 except Exception:
300 301 pass
301 302
302 303
303 304 @async_task(ignore_result=False)
304 305 def beat_check(*args, **kwargs):
305 306 log = get_logger(beat_check)
306 307 log.info('Got args: %r and kwargs %r', args, kwargs)
307 308 return time.time()
General Comments 0
You need to be logged in to leave comments. Login now