copy_installer.py 5.26 KB
Newer Older
1 2
#!/usr/bin/env python

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
""" Copies the installer from one suite to another """
# Copyright (C) 2011  Torsten Werner <twerner@debian.org>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

################################################################################

22 23
from __future__ import print_function

24
from daklib.config import Config
25
import daklib.daksubprocess
26

27 28 29 30 31
import apt_pkg
import glob
import os.path
import re
import sys
32

33

34
def usage(exit_code=0):
35
    print("""Usage: dak copy-installer [OPTION]... VERSION
36 37 38 39 40
  -h, --help         show this help and exit
  -s, --source       source suite      (defaults to unstable)
  -d, --destination  destination suite (defaults to testing)
  -n, --no-action    don't change anything

41
Exactly 1 version must be specified.""")
42 43
    sys.exit(exit_code)

44

45 46 47 48 49 50 51 52
def main():
    cnf = Config()
    Arguments = [
            ('h', "help",        "Copy-Installer::Options::Help"),
            ('s', "source",      "Copy-Installer::Options::Source",      "HasArg"),
            ('d', "destination", "Copy-Installer::Options::Destination", "HasArg"),
            ('n', "no-action",   "Copy-Installer::Options::No-Action"),
            ]
53
    for option in ["help", "source", "destination", "no-action"]:
54 55 56
        key = "Copy-Installer::Options::%s" % option
        if key not in cnf:
            cnf[key] = ""
57 58
    extra_arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
    Options = cnf.subtree("Copy-Installer::Options")
59 60 61 62 63 64

    if Options["Help"]:
        usage()
    if len(extra_arguments) != 1:
        usage(1)

65
    initializer = {"version": extra_arguments[0]}
66 67 68 69 70 71
    if Options["Source"] != "":
        initializer["source"] = Options["Source"]
    if Options["Destination"] != "":
        initializer["dest"] = Options["Destination"]

    copier = InstallerCopier(**initializer)
72
    print(copier.get_message())
73
    if Options["No-Action"]:
74
        print('Do nothing because --no-action has been set.')
75 76
    else:
        copier.do_copy()
77
        print('Installer has been copied successfully.')
78

79

80 81
root_dir = Config()['Dir::Root']

82

83
class InstallerCopier:
84
    def __init__(self, source='unstable', dest='testing',
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
            **keywords):
        self.source = source
        self.dest = dest
        if 'version' not in keywords:
            raise KeyError('no version specified')
        self.version = keywords['version']

        self.source_dir = os.path.join(root_dir, 'dists', source, 'main')
        self.dest_dir = os.path.join(root_dir, 'dists', dest, 'main')
        self.check_dir(self.source_dir, 'source does not exist')
        self.check_dir(self.dest_dir, 'destination does not exist')

        self.architectures = []
        self.skip_architectures = []
        self.trees_to_copy = []
        self.symlinks_to_create = []
101
        self.dirs_to_create = []
102 103 104 105 106 107
        arch_pattern = os.path.join(self.source_dir, 'installer-*', self.version)
        for arch_dir in glob.glob(arch_pattern):
            self.check_architecture(arch_dir)

    def check_dir(self, dir, message):
        if not os.path.isdir(dir):
108
            raise IOError("%s (%s)" % (message, dir))
109 110 111

    def check_architecture(self, arch_dir):
        architecture = re.sub('.*?/installer-(.*?)/.*', r'\1', arch_dir)
112
        dest_basedir = os.path.join(self.dest_dir,
113 114 115 116 117 118 119
            'installer-%s' % architecture)
        dest_dir = os.path.join(dest_basedir, self.version)
        if os.path.isdir(dest_dir):
            self.skip_architectures.append(architecture)
        else:
            self.architectures.append(architecture)
            self.trees_to_copy.append((arch_dir, dest_dir))
120
            self.dirs_to_create.append(dest_basedir)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
            symlink_target = os.path.join(dest_basedir, 'current')
            self.symlinks_to_create.append((self.version, symlink_target))

    def get_message(self):
        return """
Will copy installer version %(version)s from suite %(source)s to
%(dest)s.
Architectures to copy: %(arch_list)s
Architectures to skip: %(skip_arch_list)s""" % {
            'version':        self.version,
            'source':         self.source,
            'dest':           self.dest,
            'arch_list':      ', '.join(self.architectures),
            'skip_arch_list': ', '.join(self.skip_architectures)}

    def do_copy(self):
137 138 139
        for dest in self.dirs_to_create:
            if not os.path.exists(dest):
                os.makedirs(dest)
140
        for source, dest in self.trees_to_copy:
141
            daklib.daksubprocess.check_call(['cp', '-al', source, dest])
142 143 144 145
        for source, dest in self.symlinks_to_create:
            if os.path.lexists(dest):
                os.unlink(dest)
            os.symlink(source, dest)
146 147 148 149


if __name__ == '__main__':
    main()