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