1
# DistUpgradeAptCdrom.py
3
# Copyright (c) 2008 Canonical
5
# Author: Michael Vogt <michael.vogt@ubuntu.com>
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU General Public License as
9
# published by the Free Software Foundation; either version 2 of the
10
# License, or (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.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29
from gettext import gettext as _
32
class AptCdromError(Exception):
33
" base exception for apt cdrom errors "
36
class AptCdrom(object):
37
" represents a apt cdrom object "
39
def __init__(self, view, path):
42
# the directories we found on disk with signatures, packages and i18n
43
self.packagesdirs = set()
47
def restoreBackup(self, backup_ext):
48
" restore the backup copy of the cdroms.list file (*not* sources.list)! "
49
cdromstate = os.path.join(apt_pkg.Config.FindDir("Dir::State"),
50
apt_pkg.Config.Find("Dir::State::cdroms"))
51
if os.path.exists(cdromstate+backup_ext):
52
shutil.copy(cdromstate+backup_ext, cdromstate)
53
# mvo: we don't have to care about restoring the sources.list here because
54
# aptsources will do this for us anyway
59
scan the CD for interessting files and return them as:
60
(packagesfiles, signaturefiles, i18nfiles)
65
" reimplement pkgCdrom::Add() in python "
66
# os.walk() will not follow symlinks so we don't need
67
# pkgCdrom::Score() and not dropRepeats() that deal with
69
for root, dirs, files in os.walk(self.cdrompath, topdown=True):
70
if root.endswith("debian-installer"):
73
elif ".aptignr" in files:
75
elif "Packages" in files or "Packages.gz" in files:
76
print "found Packages in ", root
78
elif "Sources" in files or "Sources.gz" in files:
79
logging.error("Sources entry found in %s but not supported" % root)
80
elif "Release.gpg" in files:
81
print "found Release{.gpg} ", root
84
print "found translations", root
86
# there is nothing under pool but deb packages (no
87
# indexfiles, so we skip that here
88
elif os.path.split(root)[1] == ("pool"):
90
# now go over the packagesdirs and drop stuff that is not
92
arch = apt_pkg.Config.Find("APT::Architecture")
93
for d in set(packagesdir):
94
if "/binary-" in d and not arch in d:
96
if len(packagesdir) == 0:
97
logging.error("no useable indexes found on CD, wrong ARCH?")
98
raise AptCdromError, _("Unable to locate any package files, perhaps this is not a Ubuntu Disc or the wrong architecture?")
99
# now generate a sources.list line
100
info = os.path.join(self.cdrompath, ".disk","info")
101
if os.path.exists(info):
102
diskname = open(info).read()
103
for special in ('"',']','[','_'):
104
diskname = diskname.replace(special,'_')
106
logging.error("no .disk/ directory found")
109
# see apts indexcopy.cc:364 for details
113
for d in packagesdir:
114
# match(1) is the path, match(2) the dist
115
# and match(3) the components
116
m = re.match("(.*)/dists/([^/]*)/(.*)/binary-*", d)
118
raise AptCdromError, _("Could not calculate sources.list entry")
121
comps.append(m.group(3))
122
# entry to the sources.lisst
123
pentry = "deb cdrom:[%s]/ %s %s" % (diskname, dist, " ".join(comps))
126
for dir in packagesdir:
127
fname = apt_pkg.URItoFileName("cdrom:[%s]/%sPackages" % (diskname,d[len(path)+1:]+"/"))
128
outf = apt_pkg.Config.FindDir("Dir::State::lists")+fname
129
inf = os.path.join(d,"Packages")
130
if os.path.exists(inf):
131
shutil.copy(inf,outf)
132
elif os.path.exists(inf+".gz"):
133
f=gzip.open(inf+".gz")
135
# uncompress in 64k chunks
144
# add CD to cdroms.list
145
# update sources.list
148
def add(self, backup_ext=None):
149
" add a cdrom to apt's database "
150
logging.debug("AptCdrom.add() called with '%s'", self.cdrompath)
151
# do backup (if needed) of the cdroms.list file
153
cdromstate = os.path.join(apt_pkg.Config.FindDir("Dir::State"),
154
apt_pkg.Config.Find("Dir::State::cdroms"))
155
if os.path.exists(cdromstate):
156
shutil.copy(cdromstate, cdromstate+backup_ext)
158
apt_pkg.Config.Set("Acquire::cdrom::mount",self.cdrompath)
159
apt_pkg.Config.Set("APT::CDROM::NoMount","true")
160
cdrom = apt_pkg.GetCdrom()
161
# FIXME: add cdrom progress here for the view
162
progress = self.view.getCdromProgress()
164
res = cdrom.Add(progress)
165
except (SystemError, AptCdromError), e:
166
logging.error("can't add cdrom: %s" % e)
167
self.view.error(_("Failed to add the CD"),
168
_("There was a error adding the CD, the "
169
"upgrade will abort. Please report this as "
170
"a bug if this is a valid Ubuntu CD.\n\n"
171
"The error message was:\n'%s'") % e)
173
logging.debug("AptCdrom.add() returned: %s" % res)
176
def __nonzero__(self):
177
""" helper to use this as 'if cdrom:' """
178
return self.cdrompath is not None