copy_installer.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #! /usr/bin/env python3
  2. """ Copies the installer from one suite to another """
  3. # Copyright (C) 2011 Torsten Werner <twerner@debian.org>
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program; if not, write to the Free Software
  14. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. ################################################################################
  16. from daklib.config import Config
  17. import apt_pkg
  18. import glob
  19. import os.path
  20. import re
  21. import subprocess
  22. import sys
  23. def usage(exit_code=0):
  24. print("""Usage: dak copy-installer [OPTION]... VERSION
  25. -h, --help show this help and exit
  26. -s, --source source suite (defaults to unstable)
  27. -d, --destination destination suite (defaults to testing)
  28. -n, --no-action don't change anything
  29. Exactly 1 version must be specified.""")
  30. sys.exit(exit_code)
  31. def main():
  32. cnf = Config()
  33. Arguments = [
  34. ('h', "help", "Copy-Installer::Options::Help"),
  35. ('s', "source", "Copy-Installer::Options::Source", "HasArg"),
  36. ('d', "destination", "Copy-Installer::Options::Destination", "HasArg"),
  37. ('n', "no-action", "Copy-Installer::Options::No-Action"),
  38. ]
  39. for option in ["help", "source", "destination", "no-action"]:
  40. key = "Copy-Installer::Options::%s" % option
  41. if key not in cnf:
  42. cnf[key] = ""
  43. extra_arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
  44. Options = cnf.subtree("Copy-Installer::Options")
  45. if Options["Help"]:
  46. usage()
  47. if len(extra_arguments) != 1:
  48. usage(1)
  49. initializer = {"version": extra_arguments[0]}
  50. if Options["Source"] != "":
  51. initializer["source"] = Options["Source"]
  52. if Options["Destination"] != "":
  53. initializer["dest"] = Options["Destination"]
  54. copier = InstallerCopier(**initializer)
  55. print(copier.get_message())
  56. if Options["No-Action"]:
  57. print('Do nothing because --no-action has been set.')
  58. else:
  59. copier.do_copy()
  60. print('Installer has been copied successfully.')
  61. root_dir = Config()['Dir::Root']
  62. class InstallerCopier:
  63. def __init__(self, source='unstable', dest='testing',
  64. **keywords):
  65. self.source = source
  66. self.dest = dest
  67. if 'version' not in keywords:
  68. raise KeyError('no version specified')
  69. self.version = keywords['version']
  70. self.source_dir = os.path.join(root_dir, 'dists', source, 'main')
  71. self.dest_dir = os.path.join(root_dir, 'dists', dest, 'main')
  72. self.check_dir(self.source_dir, 'source does not exist')
  73. self.check_dir(self.dest_dir, 'destination does not exist')
  74. self.architectures = []
  75. self.skip_architectures = []
  76. self.trees_to_copy = []
  77. self.symlinks_to_create = []
  78. self.dirs_to_create = []
  79. arch_pattern = os.path.join(self.source_dir, 'installer-*', self.version)
  80. for arch_dir in glob.glob(arch_pattern):
  81. self.check_architecture(arch_dir)
  82. def check_dir(self, dir, message):
  83. if not os.path.isdir(dir):
  84. raise Exception("%s (%s)" % (message, dir))
  85. def check_architecture(self, arch_dir):
  86. architecture = re.sub('.*?/installer-(.*?)/.*', r'\1', arch_dir)
  87. dest_basedir = os.path.join(self.dest_dir,
  88. 'installer-%s' % architecture)
  89. dest_dir = os.path.join(dest_basedir, self.version)
  90. if os.path.isdir(dest_dir):
  91. self.skip_architectures.append(architecture)
  92. else:
  93. self.architectures.append(architecture)
  94. self.trees_to_copy.append((arch_dir, dest_dir))
  95. self.dirs_to_create.append(dest_basedir)
  96. symlink_target = os.path.join(dest_basedir, 'current')
  97. self.symlinks_to_create.append((self.version, symlink_target))
  98. def get_message(self):
  99. return """
  100. Will copy installer version %(version)s from suite %(source)s to
  101. %(dest)s.
  102. Architectures to copy: %(arch_list)s
  103. Architectures to skip: %(skip_arch_list)s""" % {
  104. 'version': self.version,
  105. 'source': self.source,
  106. 'dest': self.dest,
  107. 'arch_list': ', '.join(self.architectures),
  108. 'skip_arch_list': ', '.join(self.skip_architectures)}
  109. def do_copy(self):
  110. for dest in self.dirs_to_create:
  111. if not os.path.exists(dest):
  112. os.makedirs(dest)
  113. for source, dest in self.trees_to_copy:
  114. subprocess.check_call(['cp', '-al', source, dest])
  115. for source, dest in self.symlinks_to_create:
  116. if os.path.lexists(dest):
  117. os.unlink(dest)
  118. os.symlink(source, dest)
  119. if __name__ == '__main__':
  120. main()