queue.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #!/usr/bin/env python
  2. # vim:set et sw=4:
  3. """
  4. Queue utility functions for dak
  5. @contact: Debian FTP Master <ftpmaster@debian.org>
  6. @copyright: 2001 - 2006 James Troup <james@nocrew.org>
  7. @copyright: 2009, 2010 Joerg Jaspert <joerg@debian.org>
  8. @license: GNU General Public License version 2 or later
  9. """
  10. # This program is free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software
  20. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. ###############################################################################
  22. from __future__ import absolute_import, print_function
  23. import os
  24. from . import utils
  25. from types import *
  26. from .dak_exceptions import *
  27. from .regexes import *
  28. from .config import Config
  29. from .dbconn import *
  30. ################################################################################
  31. def check_valid(overrides, session):
  32. """Check if section and priority for new overrides exist in database.
  33. Additionally does sanity checks:
  34. - debian-installer packages have to be udeb (or source)
  35. - non debian-installer packages cannot be udeb
  36. @type overrides: list of dict
  37. @param overrides: list of overrides to check. The overrides need
  38. to be given in form of a dict with the following keys:
  39. - package: package name
  40. - priority
  41. - section
  42. - component
  43. - type: type of requested override ('dsc', 'deb' or 'udeb')
  44. All values are strings.
  45. @rtype: bool
  46. @return: C{True} if all overrides are valid, C{False} if there is any
  47. invalid override.
  48. """
  49. all_valid = True
  50. for o in overrides:
  51. o['valid'] = True
  52. if session.query(Priority).filter_by(priority=o['priority']).first() is None:
  53. o['valid'] = False
  54. if session.query(Section).filter_by(section=o['section']).first() is None:
  55. o['valid'] = False
  56. if get_mapped_component(o['component'], session) is None:
  57. o['valid'] = False
  58. if o['type'] not in ('dsc', 'deb', 'udeb'):
  59. raise Exception('Unknown override type {0}'.format(o['type']))
  60. if o['type'] == 'udeb' and o['section'] != 'debian-installer':
  61. o['valid'] = False
  62. if o['section'] == 'debian-installer' and o['type'] not in ('dsc', 'udeb'):
  63. o['valid'] = False
  64. all_valid = all_valid and o['valid']
  65. return all_valid
  66. ###############################################################################
  67. def prod_maintainer(notes, upload):
  68. cnf = Config()
  69. changes = upload.changes
  70. whitelists = [upload.target_suite.mail_whitelist]
  71. # Here we prepare an editor and get them ready to prod...
  72. prod_message = "\n\n=====\n\n".join([note.comment for note in notes])
  73. answer = 'E'
  74. while answer == 'E':
  75. prod_message = utils.call_editor(prod_message)
  76. print("Prod message:")
  77. print(utils.prefix_multi_line_string(prod_message, " ", include_blank_lines=1))
  78. prompt = "[P]rod, Edit, Abandon, Quit ?"
  79. answer = "XXX"
  80. while prompt.find(answer) == -1:
  81. answer = utils.our_raw_input(prompt)
  82. m = re_default_answer.search(prompt)
  83. if answer == "":
  84. answer = m.group(1)
  85. answer = answer[:1].upper()
  86. if answer == 'A':
  87. return
  88. elif answer == 'Q':
  89. return 0
  90. # Otherwise, do the proding...
  91. user_email_address = utils.whoami() + " <%s>" % (
  92. cnf["Dinstall::MyAdminAddress"])
  93. changed_by = changes.changedby or changes.maintainer
  94. maintainer = changes.maintainer
  95. maintainer_to = utils.mail_addresses_for_upload(maintainer, changed_by, changes.fingerprint)
  96. Subst = {
  97. '__SOURCE__': upload.changes.source,
  98. '__CHANGES_FILENAME__': upload.changes.changesname,
  99. '__MAINTAINER_TO__': ", ".join(maintainer_to),
  100. }
  101. Subst["__FROM_ADDRESS__"] = user_email_address
  102. Subst["__PROD_MESSAGE__"] = prod_message
  103. Subst["__CC__"] = "Cc: " + cnf["Dinstall::MyEmailAddress"]
  104. prod_mail_message = utils.TemplateSubst(
  105. Subst, cnf["Dir::Templates"] + "/process-new.prod")
  106. # Send the prod mail
  107. utils.send_mail(prod_mail_message, whitelists=whitelists)
  108. print("Sent prodding message")
  109. ################################################################################
  110. def edit_note(note, upload, session, trainee=False):
  111. newnote = ""
  112. answer = 'E'
  113. while answer == 'E':
  114. newnote = utils.call_editor(newnote).rstrip()
  115. print("New Note:")
  116. print(utils.prefix_multi_line_string(newnote, " "))
  117. empty_note = not newnote.strip()
  118. if empty_note:
  119. prompt = "Done, Edit, [A]bandon, Quit ?"
  120. else:
  121. prompt = "[D]one, Edit, Abandon, Quit ?"
  122. answer = "XXX"
  123. while prompt.find(answer) == -1:
  124. answer = utils.our_raw_input(prompt)
  125. m = re_default_answer.search(prompt)
  126. if answer == "":
  127. answer = m.group(1)
  128. answer = answer[:1].upper()
  129. if answer == 'A':
  130. return
  131. elif answer == 'Q':
  132. return 0
  133. comment = NewComment()
  134. comment.policy_queue = upload.policy_queue
  135. comment.package = upload.changes.source
  136. comment.version = upload.changes.version
  137. comment.comment = newnote
  138. comment.author = utils.whoami()
  139. comment.trainee = trainee
  140. session.add(comment)
  141. session.commit()
  142. ###############################################################################
  143. def get_suite_version_by_source(source, session):
  144. 'returns a list of tuples (suite_name, version) for source package'
  145. q = session.query(Suite.suite_name, DBSource.version). \
  146. join(Suite.sources).filter_by(source=source)
  147. return q.all()
  148. def get_suite_version_by_package(package, arch_string, session):
  149. '''
  150. returns a list of tuples (suite_name, version) for binary package and
  151. arch_string
  152. '''
  153. return session.query(Suite.suite_name, DBBinary.version). \
  154. join(Suite.binaries).filter_by(package=package). \
  155. join(DBBinary.architecture). \
  156. filter(Architecture.arch_string.in_([arch_string, 'all'])).all()