1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import rpm
16 import koji
17 import logging
18 import turbomail
19
20 from os.path import join
21 from turbomail import MailNotEnabledException
22 from turbogears import config, identity
23
24 from bodhi.util import sha1sum, rpm_fileheader
25 from bodhi.exceptions import RPMNotFound
26
27 log = logging.getLogger(__name__)
28
29
30
31
32
33
34
35
36
37
38
39 messages = {
40
41 'new' : {
42 'body' : """\
43 %(email)s has submitted a new update for %(release)s\n\n%(updatestr)s
44 """,
45 'fields' : lambda x: {
46 'email' : identity.current.user_name,
47 'release' : x.release.long_name,
48 'updatestr' : str(x)
49 }
50 },
51
52 'deleted' : {
53 'body' : """\
54 %(email)s has deleted the %(package)s update for %(release)s\n\n%(updatestr)s
55 """,
56 'fields' : lambda x: {
57 'package' : x.title,
58 'email' : identity.current.user_name,
59 'release' : '%s %s' % (x.release.long_name, x.status),
60 'updatestr' : str(x)
61 }
62 },
63
64 'edited' : {
65 'body' : """\
66 %(email)s has edited the %(package)s update for %(release)s\n\n%(updatestr)s
67 """,
68 'fields' : lambda x: {
69 'package' : x.title,
70 'email' : identity.current.user_name,
71 'release' : '%s %s' % (x.release.long_name, x.status),
72 'updatestr' : str(x)
73 }
74 },
75
76 'pushed' : {
77 'body' : """\
78 %(package)s has been successfully pushed for %(release)s.\n\n%(updatestr)s
79 """,
80 'fields' : lambda x: {
81 'package' : x.title,
82 'release' : '%s %s' % (x.release.long_name, x.status),
83 'updatestr' : str(x)
84 }
85 },
86
87 'push' : {
88 'body' : """\
89 %(submitter)s has requested the pushing of the following update:\n\n%(updatestr)s
90 """,
91 'fields' : lambda x: {
92 'submitter' : identity.current.user_name,
93 'updatestr' : str(x)
94 }
95 },
96
97 'unpush' : {
98 'body' : """\
99 %(submitter)s has requested the unpushing of the following update:\n\n%(updatestr)s
100 """,
101 'fields' : lambda x: {
102 'submitter' : identity.current.user_name,
103 'updatestr' : str(x)
104 }
105 },
106
107 'unpushed' : {
108 'body' : """\
109 The following update has been unpushed\n\n%(updatestr)s
110 """,
111 'fields' : lambda x: {
112 'updatestr' : str(x)
113 }
114 },
115
116 'revoke' : {
117 'body' : """\
118 %(submitter)s has revoked the request of the following update:\n\n%(updatestr)s
119 """,
120 'fields' : lambda x: {
121 'submitter' : identity.current.user_name,
122 'updatestr' : str(x)
123 }
124 },
125
126 'move' : {
127 'body' : """\
128 %(submitter)s has requested the moving of the following update from Testing to Stable:\n\n%(updatestr)s
129 """,
130 'fields' : lambda x: {
131 'submitter' : identity.current.user_name,
132 'updatestr' : str(x)
133 }
134 },
135
136 'moved' : {
137 'body' : """\
138 The following update has been moved from Testing to Stable:\n\n%(updatestr)s
139 """,
140 'fields' : lambda x: {
141 'updatestr' : str(x)
142 }
143 },
144
145 'stablekarma' : {
146 'body' : """\
147 The following update has reached a karma of %(karma)d and is being automatically
148 marked as stable.\n\n%(updatestr)s
149 """,
150 'fields' : lambda x: {
151 'karma' : x.karma,
152 'updatestr' : str(x)
153 }
154 },
155
156 'comment' : {
157 'body' : """\
158 The following comment has been added to the %(package)s update:
159
160 %(comment)s
161
162 To reply to this comment, please visit the URL at the bottom of this mail
163
164 %(updatestr)s
165 """,
166 'fields' : lambda x: {
167 'package' : x.title,
168 'comment' : x.comments[-1],
169 'updatestr' : str(x)
170 }
171 },
172
173 'old_testing' : {
174 'body' : """\
175 The update for %(package)s has been in 'testing' status for over 2 weeks.
176 This update can be marked as stable after it achieves a karma of %(stablekarma)d
177 or by clicking 'Push to Stable'.
178
179 This is just a courtesy nagmail. Updates may reside in the testing repository
180 for more than 2 weeks if you deem it necessary.
181
182 You can submit this update to be pushed to the stable repository by going to
183 the following URL:
184
185 http://admin.fedoraproject.org/updates/move/%(package)s
186
187 %(updatestr)s
188 """,
189 'fields' : lambda x: {
190 'package' : x.title,
191 'stablekarma' : config.get('stable_karma', 3),
192 'updatestr' : str(x)
193 }
194 }
195
196 }
197
198 errata_template = """\
199 --------------------------------------------------------------------------------
200 Fedora%(testing)s Update Notification
201 %(update_id)s
202 %(date)s
203 --------------------------------------------------------------------------------
204
205 Name : %(name)s
206 Product : %(product)s
207 Version : %(version)s
208 Release : %(release)s
209 URL : %(url)s
210 Summary : %(summary)s
211 Description :
212 %(description)s
213
214 --------------------------------------------------------------------------------
215 %(notes)s%(changelog)s%(references)sUpdated packages:
216
217 %(filelist)s
218
219 This update can be installed with the "yum" update program. Use
220 su -c 'yum%(yum_repository)s update %(name)s'
221 at the command line. For more information, refer to "Managing Software
222 with yum", available at http://docs.fedoraproject.org/yum/.
223 --------------------------------------------------------------------------------
224 """
225
227 from bodhi.buildsys import get_session
228 line = str('-' * 80) + '\n'
229 templates = []
230 koji_session = get_session()
231
232 for build in update.builds:
233 h = build.get_rpm_header()
234 info = {}
235 info['date'] = str(update.date_pushed)
236 info['name'] = h[rpm.RPMTAG_NAME]
237 info['summary'] = h[rpm.RPMTAG_SUMMARY]
238 info['version'] = h[rpm.RPMTAG_VERSION]
239 info['release'] = h[rpm.RPMTAG_RELEASE]
240 info['url'] = h[rpm.RPMTAG_URL]
241 if update.status == 'testing':
242 info['testing'] = ' Test'
243 info['yum_repository'] = ' --enablerepo=updates-testing'
244 else:
245 info['testing'] = ''
246 info['yum_repository'] = ''
247
248 info['subject'] = "%s%s%s Update: %s" % (
249 update.type == 'security' and '[SECURITY] ' or '',
250 update.release.long_name, info['testing'], build.nvr)
251 info['update_id'] = update.update_id
252 info['description'] = h[rpm.RPMTAG_DESCRIPTION]
253
254 info['product'] = update.release.long_name
255 info['notes'] = ""
256 if update.notes and len(update.notes):
257 info['notes'] = "Update Information:\n\n%s\n" % update.notes
258 info['notes'] += line
259
260
261 filelist = []
262 for pkg in koji_session.listBuildRPMs(build.nvr):
263 filename = "%s.%s.rpm" % (pkg['nvr'], pkg['arch'])
264 path = join(config.get('build_dir'), info['name'], info['version'],
265 info['release'], pkg['arch'])
266 filelist.append("%s %s" % (sha1sum(join(path, filename)), filename))
267 info['filelist'] = '\n'.join(filelist)
268
269
270 i = 1
271 info['references'] = ""
272 if len(update.bugs) or len(update.cves):
273 info['references'] = "References:\n\n"
274 for bug in update.bugs:
275 title = (bug.title != 'Unable to fetch title' and
276 bug.title != 'Invalid bug number') and \
277 ' - %s' % bug.title or ''
278 info['references'] += " [ %d ] Bug #%d%s\n %s\n" % \
279 (i, bug.bz_id, title, bug.get_url())
280 i += 1
281 for cve in update.cves:
282 info['references'] += " [ %d ] %s\n %s\n" % \
283 (i, cve.cve_id, cve.get_url())
284 i += 1
285 info['references'] += line
286
287
288 lastpkg = build.get_latest()
289 log.debug("lastpkg = %s" % lastpkg)
290
291
292 info['changelog'] = ""
293 try:
294 oldh = rpm_fileheader(lastpkg)
295 oldtime = oldh[rpm.RPMTAG_CHANGELOGTIME]
296 text = oldh[rpm.RPMTAG_CHANGELOGTEXT]
297 del oldh
298 if not text:
299 oldtime = 0
300 elif len(text) != 1:
301 oldtime = oldtime[0]
302 info['changelog'] = "ChangeLog:\n\n%s%s" % \
303 (str(build.get_changelog(oldtime)), line)
304 except RPMNotFound:
305 log.error("Cannot find 'latest' RPM for generating ChangeLog: %s" %
306 lastpkg)
307 except Exception, e:
308 log.error("Unknown exception thrown during ChangeLog generation: %s"
309 % str(e))
310
311 for (key, value) in info.items():
312 if value:
313 info[key] = value.decode('utf8')
314
315 templates.append((info['subject'], errata_template % info))
316
317 return templates
318
320 message = turbomail.Message(sender, to, subject)
321 message.plain = body
322 try:
323 turbomail.enqueue(message)
324 log.debug("Sending mail: %s" % message.plain)
325 except MailNotEnabledException:
326 log.warning("TurboMail is not enabled!")
327 except Exception, e:
328 log.error("Exception thrown when trying to send mail: %s" % str(e))
329
330 -def send(to, msg_type, update, sender=None):
331 """ Send an update notification email to a given recipient """
332 if not sender:
333 sender = config.get('bodhi_email')
334 if not sender:
335 log.warning("bodhi_email not defined in app.cfg; unable to send mail")
336 return
337 send_mail(sender, to, '[Fedora Update] [%s] %s' % (msg_type, update.title),
338 messages[msg_type]['body'] % messages[msg_type]['fields'](update))
339
341 """ Send the Release Engineering team a message """
342 send_mail(config.get('bodhi_email'), config.get('release_team_address'),
343 subject, body)
344
346 """ Send an update notification to the admins/release team. """
347 send(config.get('release_team_address'), msg_type, update, sender)
348