external_overrides.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #! /usr/bin/env python3
  2. """
  3. Modify external overrides.
  4. @contact: Debian FTP Master <ftpmaster@debian.org>
  5. @copyright: 2011 Ansgar Burchardt <ansgar@debian.org>
  6. @license: GNU General Public License version 2 or later
  7. """
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. from daklib.dbconn import *
  20. from daklib.config import Config
  21. from daklib import daklog
  22. import apt_pkg
  23. import sys
  24. def usage():
  25. print("""Usage: dak external-overrides COMMAND
  26. Modify external overrides.
  27. -h, --help show this help and exit.
  28. -f, --force allow processing of untouchable suites.
  29. Commands can use a long or abbreviated form:
  30. import SUITE COMPONENT KEY import external overrides for KEY
  31. i SUITE COMPONENT KEY NOTE: This will replace existing overrides.
  32. copy FROM TO copy external overrides from suite FROM to TO
  33. NOTE: Needs --force for untouchable TO
  34. For the 'import' command, external overrides are read from standard input and
  35. should be given as lines of the form 'PACKAGE KEY VALUE'.
  36. """)
  37. sys.exit()
  38. #############################################################################
  39. class ExternalOverrideReader:
  40. """
  41. Parses an external override file
  42. """
  43. def __init__(self, fh):
  44. self.fh = fh
  45. self.package = None
  46. self.key = None
  47. self.value = []
  48. def _flush(self):
  49. """
  50. Return the parsed line that is being built and start parsing a new line
  51. """
  52. res = self.package, self.key, "\n".join(self.value)
  53. self.package = self.key = None
  54. self.value = []
  55. return res
  56. def __iter__(self):
  57. """
  58. returns a (package, key, value) tuple for every entry in the external
  59. override file
  60. """
  61. for line in self.fh:
  62. if not line:
  63. continue
  64. if line[0] in (" ", "\t"):
  65. # Continuation line
  66. self.value.append(line.rstrip())
  67. else:
  68. if self.package is not None:
  69. yield self._flush()
  70. # New line
  71. (self.package, self.key, value) = line.rstrip().split(None, 2)
  72. self.value = [value]
  73. if self.package is not None:
  74. yield self._flush()
  75. #############################################################################
  76. def external_overrides_copy(from_suite_name, to_suite_name, force=False):
  77. session = DBConn().session()
  78. from_suite = get_suite(from_suite_name, session)
  79. to_suite = get_suite(to_suite_name, session)
  80. if from_suite is None:
  81. print("E: source %s not found." % from_suite_name)
  82. session.rollback()
  83. return False
  84. if to_suite is None:
  85. print("E: target %s not found." % to_suite_name)
  86. session.rollback()
  87. return False
  88. if not force and to_suite.untouchable:
  89. print("E: refusing to touch untouchable suite %s (not forced)." % to_suite_name)
  90. session.rollback()
  91. return False
  92. session.query(ExternalOverride).filter_by(suite=to_suite).delete()
  93. session.execute("""
  94. INSERT INTO external_overrides (suite, component, package, key, value)
  95. SELECT :to_suite, component, package, key, value FROM external_overrides WHERE suite = :from_suite
  96. """, {'from_suite': from_suite.suite_id, 'to_suite': to_suite.suite_id})
  97. session.commit()
  98. def external_overrides_import(suite_name, component_name, key, file, force=False):
  99. session = DBConn().session()
  100. suite = get_suite(suite_name, session)
  101. component = get_component(component_name, session)
  102. if not force and suite.untouchable:
  103. print("E: refusing to touch untouchable suite %s (not forced)." % suite_name)
  104. session.rollback()
  105. return False
  106. session.query(ExternalOverride).filter_by(suite=suite, component=component, key=key).delete()
  107. for package, key, value in ExternalOverrideReader(file):
  108. eo = ExternalOverride()
  109. eo.suite = suite
  110. eo.component = component
  111. eo.package = package
  112. eo.key = key
  113. eo.value = value
  114. session.add(eo)
  115. session.commit()
  116. #############################################################################
  117. def main():
  118. cnf = Config()
  119. Arguments = [('h', "help", "External-Overrides::Options::Help"),
  120. ('f', 'force', 'External-Overrides::Options::Force')]
  121. args = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
  122. try:
  123. Options = cnf.subtree("External-Overrides::Options")
  124. except KeyError:
  125. Options = {}
  126. if "Help" in Options:
  127. usage()
  128. force = False
  129. if "Force" in Options and Options["Force"]:
  130. force = True
  131. logger = daklog.Logger('external-overrides')
  132. command = args[0]
  133. if command in ('import', 'i'):
  134. external_overrides_import(args[1], args[2], args[3], sys.stdin, force)
  135. elif command in ('copy', 'c'):
  136. external_overrides_copy(args[1], args[2], force)
  137. else:
  138. print("E: Unknown commands.")
  139. if __name__ == '__main__':
  140. main()