~ubuntu-core-dev/update-manager/main

749 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1
# DistUpgradeController.py 
52 by Michael Vogt
* added a bunch of missing copyright notices in the files
2
#  
1086 by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py:
3
#  Copyright (c) 2004-2008 Canonical
52 by Michael Vogt
* added a bunch of missing copyright notices in the files
4
#  
5
#  Author: Michael Vogt <michael.vogt@ubuntu.com>
6
# 
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.
11
# 
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
# 
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
20
#  USA
20 by Michael Vogt
* DistUpgrade/ tool started
21
22
319 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py, DistUpgrade/DistUpgradeControler.py:
23
import warnings
24
warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
20 by Michael Vogt
* DistUpgrade/ tool started
25
import apt
28 by Michael Vogt
* sources.list does a proper backup now
26
import apt_pkg
27 by Michael Vogt
* more robust sources.list rewriting
27
import sys
44 by Michael Vogt
* terminal/install-progress support added
28
import os
40 by Michael Vogt
* DistUpgrade/DistUpgrade.py:
29
import subprocess
76 by Michael Vogt
* logging added
30
import logging
98 by Michael Vogt
* more small fixes in the cruft calculation code
31
import re
128 by Michael Vogt
* added check if the download size fits onto the download partition
32
import statvfs
358.1.9 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
33
import shutil
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
34
import glob
452 by Michael Vogt
* DistUpgrade/DistUpgradeFetcherSelf.py:
35
import time
676 by Michael Vogt
- when rewriting sources.list, transition the commercial
36
import copy
1031.1.2 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py,
37
import ConfigParser
741 by Michael Vogt
- workaround kde tempdir handling (LP: #149186)
38
from stat import *
668 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
39
from string import Template
40
41
import DistUpgradeView
154.1.8 by Michael Vogt
* make DistUpgadeConfigParser -> DistUpgradeConfig
42
from DistUpgradeConfigParser import DistUpgradeConfig
728 by Michael Vogt
* UpdateManager/Core/DistUpgradeFetcherCore.py:
43
from DistUpgradeFetcherCore import country_mirror
1086 by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py:
44
from DistUpgradeQuirks import DistUpgradeQuirks
1102.1.1 by Michael Vogt
initial version pure python implemenation (still incomplete) of apt-cdrom add
45
from DistUpgradeAptCdrom import AptCdrom
668 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
46
442 by Michael Vogt
* merged from glatzor, this removes the software-properties code
47
from sourceslist import SourcesList, SourceEntry, is_mirror
669 by Michael Vogt
* AutoUpgradeTester/*
48
from distro import Distribution, get_distro, NoDistroTemplateException
442 by Michael Vogt
* merged from glatzor, this removes the software-properties code
49
1045 by Michael Vogt
* DistUpgrade/DistUpgradeGettext.py:
50
from DistUpgradeGettext import gettext as _
51
from DistUpgradeGettext import ngettext
327 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
52
import gettext
1045 by Michael Vogt
* DistUpgrade/DistUpgradeGettext.py:
53
808 by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgradeCache.py:
54
from DistUpgradeCache import *
504 by Michael Vogt
- better apport integration
55
from DistUpgradeApport import *
113 by Michael Vogt
* moved most of the upgrade logic to the DistUpgradeCache() class
56
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
57
# some constant
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
58
# the initrd space required in /boot for each kernel
1022 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
59
KERNEL_INITRD_SIZE = 12*1024*1024
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
60
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
61
class NoBackportsFoundException(Exception):
62
    pass
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
63
47 by Michael Vogt
* cleaned up the source in DistUpgrade, put the functions in multiple sources
64
749 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
65
class DistUpgradeController(object):
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
66
    """ this is the controller that does most of the work """
358.1.7 by Michael Vogt
* move the logging to /var/log/dist-upgrade/{main,apt,term}.log
67
    
358.1.66 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
68
    def __init__(self, distUpgradeView, options=None, datadir=None):
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
69
        # setup the paths
358.1.34 by Michael Vogt
* DistUpgrade/forced_obsoletes.txt:
70
        localedir = "/usr/share/locale/update-manager/"
71
        if datadir == None:
72
            datadir = os.getcwd()
73
            localedir = os.path.join(datadir,"mo")
74
            gladedir = datadir
75
        self.datadir = datadir
358.1.66 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
76
        self.options = options
77
358.1.34 by Michael Vogt
* DistUpgrade/forced_obsoletes.txt:
78
        # init gettext
79
        gettext.bindtextdomain("update-manager",localedir)
327 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
80
        gettext.textdomain("update-manager")
81
358.1.34 by Michael Vogt
* DistUpgrade/forced_obsoletes.txt:
82
        # setup the view
766 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
83
        logging.debug("Using '%s' view" % distUpgradeView.__class__.__name__)
20 by Michael Vogt
* DistUpgrade/ tool started
84
        self._view = distUpgradeView
27 by Michael Vogt
* more robust sources.list rewriting
85
        self._view.updateStatus(_("Reading cache"))
72 by Michael Vogt
* missing "{k,edu,}ubuntu-desktop" detection added
86
        self.cache = None
74 by Michael Vogt
* add self.missingPkgs to have a generic list of stuff that needs to be installed
87
358.1.79 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
88
        if not self.options or self.options.withNetwork == None:
358.1.75 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
89
            self.useNetwork = True
90
        else:
91
            self.useNetwork = self.options.withNetwork
358.1.79 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
92
        if options:
93
            cdrompath = options.cdromPath
94
        else:
95
            cdrompath = None
96
        self.aptcdrom = AptCdrom(distUpgradeView, cdrompath)
441 by Michael Vogt
* server-mode added
97
358.1.34 by Michael Vogt
* DistUpgrade/forced_obsoletes.txt:
98
        # the configuration
99
        self.config = DistUpgradeConfig(datadir)
154.1.5 by Michael Vogt
* make the Config-File more usable
100
        self.sources_backup_ext = "."+self.config.get("Files","BackupExt")
827 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
101
102
        # move some of the options stuff into the self.config, 
103
        # ConfigParser deals only with strings it seems *sigh*
104
        self.config.add_section("Options")
105
        self.config.set("Options","withNetwork", str(self.useNetwork))
154.1.5 by Michael Vogt
* make the Config-File more usable
106
        
40 by Michael Vogt
* DistUpgrade/DistUpgrade.py:
107
        # some constants here
154.1.5 by Michael Vogt
* make the Config-File more usable
108
        self.fromDist = self.config.get("Sources","From")
109
        self.toDist = self.config.get("Sources","To")
110
        self.origin = self.config.get("Sources","ValidOrigin")
767 by Michael Vogt
- fix getting prerequists for ports.ubuntu.com
111
        self.arch = apt_pkg.Config.Find("APT::Architecture")
20 by Michael Vogt
* DistUpgrade/ tool started
112
920 by Michael Vogt
* run dpkg with --force-overwrite by default on the server
113
        # we run with --force-overwrite by default
114
        if not os.environ.has_key("RELEASE_UPGRADE_NO_FORCE_OVERWRITE"):
115
            logging.debug("enable dpkg --force-overwrite")
116
            apt_pkg.Config.Set("DPkg::Options::","--force-overwrite")
117
734 by Michael Vogt
- when running in partial upgrade mode, do not run apport,
118
        # we run in full upgrade mode by default
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
119
        self._partialUpgrade = False
1086 by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py:
120
        
121
        # install the quirks handler
122
        self.quirks = DistUpgradeQuirks(self, self.config)
734 by Michael Vogt
- when running in partial upgrade mode, do not run apport,
123
693 by Michael Vogt
- add mythubuntu-desktop to the valid metapackages
124
        # setup env var 
125
        os.environ["RELEASE_UPGRADE_IN_PROGRESS"] = "1"
756 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
126
        os.environ["PYCENTRAL_NO_DPKG_QUERY"] = "1"
1149 by Michael Vogt
DistUpgrade/DistUpgradeController.py: add PYCENTRAL_FORCE_OVERWRITE to the environment
127
        os.environ["PYCENTRAL_FORCE_OVERWRITE"] = "1"
694 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
128
        os.environ["PATH"] = "%s:%s" % (os.getcwd()+"/imported",
693 by Michael Vogt
- add mythubuntu-desktop to the valid metapackages
129
                                        os.environ["PATH"])
130
770 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
131
        # set max retries
132
        maxRetries = self.config.getint("Network","MaxRetries")
133
        apt_pkg.Config.Set("Acquire::Retries", str(maxRetries))
857 by Michael Vogt
* AutoUpgradeTester/automatic-upgrade-testing:
134
        # max sizes for dpkgpm for large installs (see linux/limits.h and 
135
        #                                          linux/binfmts.h)
136
        apt_pkg.Config.Set("Dpkg::MaxArgs", str(64*1024))
137
        apt_pkg.Config.Set("Dpkg::MaxArgBytes", str(128*1024))
138
924 by Michael Vogt
- smaller default network time out
139
        # smaller to avoid hangs
140
        apt_pkg.Config.Set("Acquire::http::Timeout","20")
141
        apt_pkg.Config.Set("Acquire::ftp::Timeout","20")
142
130 by Michael Vogt
* forced_obsoletes added
143
        # forced obsoletes
154.1.5 by Michael Vogt
* make the Config-File more usable
144
        self.forced_obsoletes = self.config.getlist("Distro","ForcedObsoletes")
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
145
        # list of valid mirrors that we can add
146
        self.valid_mirrors = self.config.getListFromFile("Sources","ValidMirrors")
1063 by Michael Vogt
DistUpgrade/DistUpgradeController.py: fix quirks handler code
147
        # debugging
148
        #apt_pkg.Config.Set("DPkg::Options::","--debug=0077")
149
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
150
151
    def openCache(self, lock=True):
1063 by Michael Vogt
DistUpgrade/DistUpgradeController.py: fix quirks handler code
152
        logging.debug("openCache()")
737 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
153
        if self.cache is not None:
154
            self.cache.releaseLock()
770 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
155
            self.cache.unlockListsDir()
618 by Michael Vogt
* fix locking problem (LP#108446)
156
        try:
157
            self.cache = MyCache(self.config,
158
                                 self._view,
1088 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py, DistUpgrade/DistUpgradeQuirks.py:
159
                                 self.quirks,
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
160
                                 self._view.getOpCacheProgress(),
161
                                 lock)
808 by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgradeCache.py:
162
        # if we get a dpkg error that it was interrupted, just
163
        # run dpkg --configure -a
164
        except CacheExceptionDpkgInterrupted, e:
923 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
165
            logging.warning("dpkg interrupted, calling dpkg --configure -a")
808 by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgradeCache.py:
166
            self._view.getTerminal().call(["dpkg","--configure","-a"])
167
            self.cache = MyCache(self.config,
168
                                 self._view,
1088 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py, DistUpgrade/DistUpgradeQuirks.py:
169
                                 self.quirks,
808 by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgradeCache.py:
170
                                 self._view.getOpCacheProgress())
618 by Michael Vogt
* fix locking problem (LP#108446)
171
        except CacheExceptionLockingFailed, e:
172
            logging.error("Cache can not be locked (%s)" % e)
173
            self._view.error(_("Unable to get exclusive lock"),
174
                             _("This usually means that another "
175
                               "package management application "
176
                               "(like apt-get or aptitude) "
177
                               "already running. Please close that "
178
                               "application first."));
179
            sys.exit(1)
1063 by Michael Vogt
DistUpgrade/DistUpgradeController.py: fix quirks handler code
180
        logging.debug("/openCache()")
49 by Michael Vogt
* ui-polish for the step that are performed
181
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
182
    def _sshMagic(self):
183
        """ this will check for server mode and if we run over ssh.
184
            if this is the case, we will ask and spawn a additional
185
            daemon (to be sure we have a spare one around in case
186
            of trouble)
187
        """
900 by Michael Vogt
- make the code that asks about starting a new ssh daemon
188
        pidfile = os.path.join("/var/run/release-upgrader-sshd.pid")
189
        if (not os.path.exists(pidfile) and
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
190
            (os.environ.has_key("SSH_CONNECTION") or
191
             os.environ.has_key("SSH_TTY"))):
192
            port = 9004
193
            res = self._view.askYesNoQuestion(
487 by Michael Vogt
* fix spelling mistakes (thanks to Bruce Cowan, LP#90833)
194
                _("Continue running under SSH?"),
195
                _("This session appears to be running under ssh. "
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
196
                  "It is not recommended to perform a upgrade "
197
                  "over ssh currently because in case of failure "
198
                "it is harder to recover.\n\n"
199
                  "If you continue, a additional ssh daemon will be "
200
                  "started at port '%s'.\n"
201
                  "Do you want to continue?") % port)
202
            # abort
203
            if res == False:
204
                sys.exit(1)
853 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
205
            res = subprocess.call(["/usr/sbin/sshd",
206
                                   "-o", "PidFile=%s" % pidfile,
207
                                   "-p",str(port)])
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
208
            if res == 0:
209
                self._view.information(
210
                    _("Starting additional sshd"),
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
211
                    _("To make recovery in case of failure easier, an "
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
212
                      "additional sshd will be started on port '%s'. "
487 by Michael Vogt
* fix spelling mistakes (thanks to Bruce Cowan, LP#90833)
213
                      "If anything goes wrong with the running ssh "
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
214
                      "you can still connect to the additional one.\n"
215
                      ) % port)
216
447 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
217
    def _tryUpdateSelf(self):
218
        """ this is a helper that is run if we are started from a CD
219
            and we have network - we will then try to fetch a update
220
            of ourself
221
        """  
452 by Michael Vogt
* DistUpgrade/DistUpgradeFetcherSelf.py:
222
        from MetaRelease import MetaReleaseCore
223
        from DistUpgradeFetcherSelf import DistUpgradeFetcherSelf
905 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
224
        # check if we run from a LTS 
225
        forceLTS=False
226
        if (self.release == "dapper" or
227
            self.release == "hardy"):
228
            forceLTS=True
229
        m = MetaReleaseCore(useDevelopmentRelease=False,
230
                            forceLTS=forceLTS)
452 by Michael Vogt
* DistUpgrade/DistUpgradeFetcherSelf.py:
231
        # this will timeout eventually
232
        while m.downloading:
572 by Michael Vogt
* set useDevelopmentRelease=False in the self updater on
233
            self._view.processEvents()
234
            time.sleep(0.1)
452 by Michael Vogt
* DistUpgrade/DistUpgradeFetcherSelf.py:
235
        if m.new_dist is None:
236
            logging.error("No new dist found")
237
            return False
238
        # we have a new dist
239
        progress = self._view.getFetchProgress()
240
        fetcher = DistUpgradeFetcherSelf(new_dist=m.new_dist,
241
                                         progress=progress,
242
                                         options=self.options,
243
                                         view=self._view)
244
        fetcher.run()
575 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
245
246
    def _pythonSymlinkCheck(self):
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
247
        """ sanity check that /usr/bin/python points to the default
248
            python version. Users tend to modify this symlink, which
249
            breaks stuff in obscure ways (Ubuntu #75557).
575 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
250
        """
251
        logging.debug("_pythonSymlinkCheck run")
252
        from ConfigParser import SafeConfigParser, NoOptionError
253
        if os.path.exists('/usr/share/python/debian_defaults'):
254
            config = SafeConfigParser()
255
            config.readfp(file('/usr/share/python/debian_defaults'))
256
            try:
257
                expected_default = config.get('DEFAULT', 'default-version')
258
            except NoOptionError:
259
                logging.debug("no default version for python found in '%s'" % config)
260
                return False
577 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
261
            try:
262
                fs_default_version = os.readlink('/usr/bin/python')
263
            except OSError, e:
264
                logging.error("os.readlink failed (%s)" % e)
265
                return False
575 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
266
            if not fs_default_version in (expected_default, os.path.join('/usr/bin', expected_default)):
267
                logging.debug("python symlink points to: '%s', but expected is '%s' or '%s'" % (fs_default_version, expected_default, os.path.join('/usr/bin', expected_default)))
268
                return False
269
        return True
447 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
270
    
358.1.8 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
271
    def prepare(self):
272
        """ initial cache opening, sanity checking, network checking """
546 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
273
        # first check if that is a good upgrade
905 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
274
        self.release = release = subprocess.Popen(["lsb_release","-c","-s"],
546 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
275
                                   stdout=subprocess.PIPE).communicate()[0].strip()
276
        logging.debug("lsb-release: '%s'" % release)
277
        if not (release == self.fromDist or release == self.toDist):
278
            logging.error("Bad upgrade: '%s' != '%s' " % (release, self.fromDist))
279
            self._view.error(_("Can not upgrade"),
859.1.1 by Brian Murray
string fixes for bugs 196269, 196229, 197015
280
                             _("An upgrade from '%s' to '%s' is not "
752.1.6 by Brian Murray
supoprted should be supported - resolves bug 158175
281
                               "supported with this tool." % (release, self.toDist)))
546 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
282
            sys.exit(1)
766 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
283
        # setup backports (if we have them)
284
        if self.options and self.options.havePrerequists:
285
            backportsdir = os.getcwd()+"/backports"
286
            logging.info("using backports in '%s' " % backportsdir)
287
            logging.debug("have: %s" % glob.glob(backportsdir+"/*.udeb"))
288
            if os.path.exists(backportsdir+"/usr/bin/dpkg"):
289
                apt_pkg.Config.Set("Dir::Bin::dpkg",backportsdir+"/usr/bin/dpkg");
290
            if os.path.exists(backportsdir+"/usr/lib/apt/methods"):
291
                apt_pkg.Config.Set("Dir::Bin::methods",backportsdir+"/usr/lib/apt/methods")
815 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
292
            conf = backportsdir+"/etc/apt/apt.conf.d/01ubuntu"
293
            if os.path.exists(conf):
294
                logging.debug("adding config '%s'" % conf)
295
                apt_pkg.ReadConfigFile(apt_pkg.Config, conf)
766 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
296
546 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
297
        # do the ssh check and warn if we run under ssh
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
298
        self._sshMagic()
575 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
299
        # check python version
300
        if not self._pythonSymlinkCheck():
301
            logging.error("pythonSymlinkCheck() failed, aborting")
302
            self._view.error(_("Can not upgrade"),
303
                             _("Your python install is corrupted. "
304
                               "Please fix the '/usr/bin/python' symlink."))
305
            sys.exit(1)
546 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
306
        # open cache
358.1.108 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
307
        try:
308
            self.openCache()
309
        except SystemError, e:
310
            logging.error("openCache() failed: '%s'" % e)
311
            return False
358.1.8 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
312
        if not self.cache.sanityCheck(self._view):
313
            return False
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
314
973 by Michael Vogt
* Make "--mode={server,desktop}" obsolete by adding automatic
315
        # now figure out if we need to go into desktop or 
316
        # server mode - we use a heuristic for this
317
        self.serverMode = self.cache.needServerMode()
318
        if self.serverMode:
319
            os.environ["RELEASE_UPGRADE_MODE"] = "server"
320
        else:
321
            os.environ["RELEASE_UPGRADE_MODE"] = "desktop"
322
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
323
        if not self.checkViewDepends():
324
            logging.error("checkViewDepends() failed")
325
            return False
326
878 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
327
        if os.path.exists("/usr/bin/debsig-verify"):
328
            logging.error("debsig-verify is installed")
329
            self._view.error(_("Package 'debsig-verify' is installed"),
330
                             _("The upgrade can not continue with that "
331
                               "package installed.\n"
332
                               "Please remove it with synaptic "
333
                               "or 'apt-get remove debsig-verify' first "
334
                               "and run the upgrade again."))
335
            self.abort()
336
358.1.73 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
337
        # FIXME: we may try to find out a bit more about the network
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
338
        # connection here and ask more  intelligent questions
358.1.79 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
339
        if self.aptcdrom and self.options and self.options.withNetwork == None:
503 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
340
            res = self._view.askYesNoQuestion(_("Include latest updates from the Internet?"),
987 by Michael Vogt
* DistUpgrade/DistUpgradeView{Gtk,KDE}.py:
341
                                              _("The upgrade system can use the internet to "
985 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
342
                                                "automatically download "
503 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
343
                                                "the latest updates and install them during the "
985 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
344
                                                "upgrade.  If you have a network connection this is "
345
                                                "highly recommended.\n\n"
346
                                                "The upgrade will take longer, but when "
503 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
347
                                                "it is complete, your system will be fully up to "
348
                                                "date.  You can choose not to do this, but you "
349
                                                "should install the latest updates soon after "
985 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
350
                                                "upgrading.\n"
351
                                                "If you answer 'no' here, the network is not "
352
                                                "used at all."),
353
                                              'Yes')
358.1.8 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
354
            self.useNetwork = res
932.2.15 by Michael Vogt
- make networkless upgrades more robust (LP: #227197)
355
            self.config.set("Options","withNetwork", str(self.useNetwork))
358.1.8 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
356
            logging.debug("useNetwork: '%s' (selected by user)" % res)
452 by Michael Vogt
* DistUpgrade/DistUpgradeFetcherSelf.py:
357
            if res:
358
                self._tryUpdateSelf()
358.1.10 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
359
        return True
20 by Michael Vogt
* DistUpgrade/ tool started
360
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
361
    def rewriteSourcesList(self, mirror_check=True):
362
        logging.debug("rewriteSourcesList()")
25 by Michael Vogt
* better handling of the sources.list convertation
363
569 by Michael Vogt
* DistUpgradeControler.py:
364
        # check if we need to enable main
365
        if mirror_check == True and self.useNetwork:
366
            # now check if the base-meta pkgs are available in
367
            # the archive or only available as "now"
368
            # -> if not that means that "main" is missing and we
369
            #    need to  enable it
370
            for pkgname in self.config.getlist("Distro","BaseMetaPkgs"):
669 by Michael Vogt
* AutoUpgradeTester/*
371
                if ((not self.cache.has_key(pkgname)
372
                     or
373
                     len(self.cache[pkgname].candidateOrigin) == 0)
569 by Michael Vogt
* DistUpgradeControler.py:
374
                    or
375
                    (len(self.cache[pkgname].candidateOrigin) == 1 and
669 by Michael Vogt
* AutoUpgradeTester/*
376
                     self.cache[pkgname].candidateOrigin[0].archive == "now")
377
                   ):
676 by Michael Vogt
- when rewriting sources.list, transition the commercial
378
                    logging.debug("BaseMetaPkg '%s' has no candidateOrigin" % pkgname)
669 by Michael Vogt
* AutoUpgradeTester/*
379
                    try:
380
                        distro = get_distro()
381
                        distro.get_sources(self.sources)
382
                        distro.enable_component("main")
383
                    except NoDistroTemplateException,e :
384
                        # fallback if everything else does not work,
385
                        # we replace the sources.list with a single
386
                        # line to ubuntu-main
670 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
387
                        logging.warning('get_distro().enable_component("man") failed, overwriting sources.list instead as last resort')
1162 by Michael Vogt
* debian/rules
388
                        s =  "# auto generated by update-manager"
389
                        s += "deb http://archive.ubuntu.com/ubuntu %s main restricted" % self.toDist
390
                        s += "deb http://archive.ubuntu.com/ubuntu %s-updates main restricted" % self.toDist
391
                        s += "deb http://security.ubuntu.com/ubuntu %s-security main restricted" % self.toDist
669 by Michael Vogt
* AutoUpgradeTester/*
392
                        open("/etc/apt/sources.list","w").write(s)
569 by Michael Vogt
* DistUpgradeControler.py:
393
                    break
394
            
26 by Michael Vogt
* detect security.u.c as well
395
        # this must map, i.e. second in "from" must be the second in "to"
396
        # (but they can be different, so in theory we could exchange
397
        #  component names here)
40 by Michael Vogt
* DistUpgrade/DistUpgrade.py:
398
        fromDists = [self.fromDist,
399
                     self.fromDist+"-security",
400
                     self.fromDist+"-updates",
468 by Michael Vogt
* po/
401
                     self.fromDist+"-proposed",
657 by Michael Vogt
- transition archive.canonical.com to new layout
402
                     self.fromDist+"-backports"
25 by Michael Vogt
* better handling of the sources.list convertation
403
                    ]
40 by Michael Vogt
* DistUpgrade/DistUpgrade.py:
404
        toDists = [self.toDist,
405
                   self.toDist+"-security",
406
                   self.toDist+"-updates",
468 by Michael Vogt
* po/
407
                   self.toDist+"-proposed",
657 by Michael Vogt
- transition archive.canonical.com to new layout
408
                   self.toDist+"-backports"
26 by Michael Vogt
* detect security.u.c as well
409
                   ]
410
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
411
        self.sources_disabled = False
412
27 by Michael Vogt
* more robust sources.list rewriting
413
        # look over the stuff we have
414
        foundToDist = False
676 by Michael Vogt
- when rewriting sources.list, transition the commercial
415
        for entry in self.sources.list[:]:
315 by Michael Vogt
* comment out breezy cdrom source to make demotions work
416
417
            # ignore invalid records or disabled ones
418
            if entry.invalid or entry.disabled:
419
                continue
420
            
421
            # we disable breezy cdrom sources to make sure that demoted
422
            # packages are removed
358.1.149 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
423
            if entry.uri.startswith("cdrom:") and entry.dist == self.fromDist:
315 by Michael Vogt
* comment out breezy cdrom source to make demotions work
424
                entry.disabled = True
425
                continue
426
            # ignore cdrom sources otherwise
316 by Michael Vogt
* typo
427
            elif entry.uri.startswith("cdrom:"):
315 by Michael Vogt
* comment out breezy cdrom source to make demotions work
428
                continue
468 by Michael Vogt
* po/
429
657 by Michael Vogt
- transition archive.canonical.com to new layout
430
            # special case for archive.canonical.com that needs to
676 by Michael Vogt
- when rewriting sources.list, transition the commercial
431
            # be rewritten (for pre-gutsy upgrades)
657 by Michael Vogt
- transition archive.canonical.com to new layout
432
            cdist = "%s-commercial" % self.fromDist
433
            if (not entry.disabled and
743 by Michael Vogt
434
                entry.uri.startswith("http://archive.canonical.com") and
657 by Michael Vogt
- transition archive.canonical.com to new layout
435
                entry.dist == cdist):
436
                entry.dist = self.toDist
681 by Michael Vogt
* updated changelog
437
                entry.comps = ["partner"]
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
438
                logging.debug("transitioned commercial to '%s' " % entry)
657 by Michael Vogt
- transition archive.canonical.com to new layout
439
                continue
440
932.2.10 by Michael Vogt
- deal with the landscape.canonical.com repository
441
            # special case for landscape.canonical.com because they
442
            # don't use a standard archive layout
443
            if (not entry.disabled and
444
                entry.uri.startswith("http://landscape.canonical.com/packages/%s" % self.fromDist)):
1039 by Michael Vogt
transition landscape.canonical.com to the main repository
445
                logging.debug("commenting landscape.canonical.com out")
446
                entry.disabled = True
932.2.10 by Michael Vogt
- deal with the landscape.canonical.com repository
447
                continue
967 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
448
449
            # special case for old-releases.ubuntu.com, auto transition
450
            # them back to archive.ubuntu.com - now this is a problem
451
            # of course for people upgrading from EOL release to a 
452
            # EOL release
453
            if (not entry.disabled and
454
                entry.uri.startswith("http://old-releases.ubuntu.com/ubuntu")):
455
                entry.uri = "http://archive.ubuntu.com/ubuntu"
456
                logging.debug("transitioning old-releases.ubuntu.com to '%s' " % entry)
457
                continue
932.2.10 by Michael Vogt
- deal with the landscape.canonical.com repository
458
249 by Michael Vogt
* improved logging
459
            logging.debug("examining: '%s'" % entry)
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
460
            # check if it's a mirror (or official site)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
461
            validMirror = self.isMirror(entry.uri)
462
            if validMirror or not mirror_check:
463
                validMirror = True
464
                # disabled/security/commercial are special cases
465
                # we use validTo/foundToDist to figure out if we have a 
466
                # main archive mirror in the sources.list or if we 
467
                # need to add one
468
                validTo = True
469
                if (entry.disabled or
951 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
470
                    entry.type == "deb-src" or
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
471
                    entry.uri.startswith("http://security.ubuntu.com") or
472
                    entry.uri.startswith("http://archive.canonical.com")):
473
                    validTo = False
474
                if entry.dist in toDists:
475
                    # so the self.sources.list is already set to the new
476
                    # distro
477
                    logging.debug("entry '%s' is already set to new dist" % entry)
478
                    foundToDist |= validTo
479
                elif entry.dist in fromDists:
480
                    foundToDist |= validTo
481
                    entry.dist = toDists[fromDists.index(entry.dist)]
482
                    logging.debug("entry '%s' updated to new dist" % entry)
483
                else:
484
                    # disable all entries that are official but don't
485
                    # point to either "to" or "from" dist
486
                    entry.disabled = True
487
                    self.sources_disabled = True
488
                    logging.debug("entry '%s' was disabled (unknown dist)" % entry)
921 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
489
                
490
                # if we make it to this point, we have a official mirror
491
                # 
492
                # check if the arch is powerpc or sparc and if so, transition
493
                # to ports.ubuntu.com (powerpc got demoted in gutsy, sparc
494
                # in hardy)
495
                    
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
496
                if (entry.type == "deb" and
921 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
497
                    not "ports.ubuntu.com" in entry.uri and
498
                    (self.arch == "powerpc" or self.arch == "sparc")):
499
                    logging.debug("moving %s source entry to 'ports.ubuntu.com' " % self.arch)
500
                    entry.uri = "http://ports.ubuntu.com/ubuntu-ports/"
501
                    
154.1.5 by Michael Vogt
* make the Config-File more usable
502
            # disable anything that is not from a official mirror
503
            if not validMirror:
504
                entry.disabled = True
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
505
                self.sources_disabled = True
249 by Michael Vogt
* improved logging
506
                logging.debug("entry '%s' was disabled (unknown mirror)" % entry)
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
507
        return foundToDist
508
509
    def updateSourcesList(self):
510
        logging.debug("updateSourcesList()")
358.1.3 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
511
        self.sources = SourcesList(matcherPath=".")
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
512
        if not self.rewriteSourcesList(mirror_check=True):
513
            logging.error("No valid mirror found")
514
            res = self._view.askYesNoQuestion(_("No valid mirror found"),
487 by Michael Vogt
* fix spelling mistakes (thanks to Bruce Cowan, LP#90833)
515
                             _("While scanning your repository "
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
516
                               "information no mirror entry for "
517
                               "the upgrade was found."
570 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
518
                               "This can happen if you run a internal "
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
519
                               "mirror or if the mirror information is "
520
                               "out of date.\n\n"
521
                               "Do you want to rewrite your "
522
                               "'sources.list' file anyway? If you choose "
523
                               "'Yes' here it will update all '%s' to '%s' "
524
                               "entries.\n"
525
                               "If you select 'no' the update will cancel."
526
                               ) % (self.fromDist, self.toDist))
527
            if res:
528
                # re-init the sources and try again
358.1.10 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
529
                self.sources = SourcesList(matcherPath=".")
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
530
                # its ok if rewriteSourcesList fails here if
847 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
531
                # we do not use a network, the sources.list may be empty
532
                if (not self.rewriteSourcesList(mirror_check=False)
533
                    and self.useNetwork):
263 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
534
                    #hm, still nothing useful ...
535
                    prim = _("Generate default sources?")
536
                    secon = _("After scanning your 'sources.list' no "
537
                              "valid entry for '%s' was found.\n\n"
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
538
                              "Should default entries for '%s' be "
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
539
                              "added? If you select 'No', the update "
263 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
540
                              "will cancel.") % (self.fromDist, self.toDist)
541
                    if not self._view.askYesNoQuestion(prim, secon):
542
                        self.abort()
265 by Michael Vogt
* DistUpgrade/Changelog: updated
543
544
                    # add some defaults here
545
                    # FIXME: find mirror here
1162 by Michael Vogt
* debian/rules
546
                    logging.info("generate new default sources.list")
263 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
547
                    uri = "http://archive.ubuntu.com/ubuntu"
548
                    comps = ["main","restricted"]
549
                    self.sources.add("deb", uri, self.toDist, comps)
550
                    self.sources.add("deb", uri, self.toDist+"-updates", comps)
551
                    self.sources.add("deb",
552
                                     "http://security.ubuntu.com/ubuntu/",
553
                                     self.toDist+"-security", comps)
262 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
554
            else:
555
                self.abort()
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
556
27 by Michael Vogt
* more robust sources.list rewriting
557
        # write (well, backup first ;) !
90 by Michael Vogt
* on problems call "abort" and restore the old sources.list
558
        self.sources.backup(self.sources_backup_ext)
559
        self.sources.save()
28 by Michael Vogt
* sources.list does a proper backup now
560
90 by Michael Vogt
* on problems call "abort" and restore the old sources.list
561
        # re-check if the written self.sources are valid, if not revert and
28 by Michael Vogt
* sources.list does a proper backup now
562
        # bail out
154.1.7 by Michael Vogt
* make force_purges work
563
        # TODO: check if some main packages are still available or if we
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
564
        #       accidentally shot them, if not, maybe offer to write a standard
154.1.7 by Michael Vogt
* make force_purges work
565
        #       sources.list?
28 by Michael Vogt
* sources.list does a proper backup now
566
        try:
567
            sourceslist = apt_pkg.GetPkgSourceList()
568
            sourceslist.ReadMainList()
569
        except SystemError:
249 by Michael Vogt
* improved logging
570
            logging.error("Repository information invalid after updating (we broke it!)")
28 by Michael Vogt
* sources.list does a proper backup now
571
            self._view.error(_("Repository information invalid"),
572
                             _("Upgrading the repository information "
573
                               "resulted in a invalid file. Please "
574
                               "report this as a bug."))
575
            return False
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
576
577
        if self.sources_disabled:
578
            self._view.information(_("Third party sources disabled"),
358.1.60 by Michael Vogt
* typo fixes (thanks to Bruce Cowan)
579
                             _("Some third party entries in your sources.list "
318 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
580
                               "were disabled. You can re-enable them "
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
581
                               "after the upgrade with the "
466 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
582
                               "'software-properties' tool or "
583
                               "your package manager."
264 by Michael Vogt
* DistUpgrade/DistUpgradeView.py:
584
                               ))
27 by Michael Vogt
* more robust sources.list rewriting
585
        return True
20 by Michael Vogt
* DistUpgrade/ tool started
586
79 by Michael Vogt
* cleanup in the log changes code
587
    def _logChanges(self):
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
588
        # debugging output
79 by Michael Vogt
* cleanup in the log changes code
589
        logging.debug("About to apply the following changes")
590
        inst = []
591
        up = []
592
        rm = []
358.1.135 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
593
        held = []
985 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
594
        keep = []
79 by Michael Vogt
* cleanup in the log changes code
595
        for pkg in self.cache:
596
            if pkg.markedInstall: inst.append(pkg.name)
597
            elif pkg.markedUpgrade: up.append(pkg.name)
80 by Michael Vogt
* typo
598
            elif pkg.markedDelete: rm.append(pkg.name)
358.1.135 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
599
            elif (pkg.isInstalled and pkg.isUpgradable): held.append(pkg.name)
1072 by Michael Vogt
fix log for kept packages
600
            elif pkg.isInstalled and pkg.markedKeep: keep.append(pkg.name)
985 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
601
        logging.debug("Keep at same version: %s" % " ".join(keep))
602
        logging.debug("Upgradable, but held- back: %s" % " ".join(held))
79 by Michael Vogt
* cleanup in the log changes code
603
        logging.debug("Remove: %s" % " ".join(rm))
604
        logging.debug("Install: %s" % " ".join(inst))
605
        logging.debug("Upgrade: %s" % " ".join(up))
358.1.135 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
606
        
79 by Michael Vogt
* cleanup in the log changes code
607
1087 by Michael Vogt
* DistUpgrade/DistUpgradeController.py,
608
    def doPostInitialUpdate(self):
838 by Michael Vogt
* deal with packages in broken reqreinst state by
609
        # check if we have packages in ReqReinst state that are not
610
        # downloadable
1087 by Michael Vogt
* DistUpgrade/DistUpgradeController.py,
611
        logging.debug("doPostInitialUpdate")
612
        self.quirks.run("PostInitialUpdate")
838 by Michael Vogt
* deal with packages in broken reqreinst state by
613
        if len(self.cache.reqReinstallPkgs) > 0:
923 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
614
            logging.warning("packages in reqReinstall state, trying to fix")
838 by Michael Vogt
* deal with packages in broken reqreinst state by
615
            self.cache.fixReqReinst(self._view)
616
            self.openCache()
617
        if len(self.cache.reqReinstallPkgs) > 0:
618
            reqreinst = self.cache.reqReinstallPkgs
1045 by Michael Vogt
* DistUpgrade/DistUpgradeGettext.py:
619
            header = ngettext("Package in inconsistent state",
1047 by Michael Vogt
indention (whitespace) fixes
620
                              "Packages in inconsistent state",
621
                              len(reqreinst))
1045 by Michael Vogt
* DistUpgrade/DistUpgradeGettext.py:
622
            summary = ngettext("The package '%s' is in an inconsistent "
1047 by Michael Vogt
indention (whitespace) fixes
623
                               "state and needs to be reinstalled, but "
624
                               "no archive can be found for it. "
625
                               "Please reinstall the package manually "
626
                               "or remove it from the system.",
627
                               "The packages '%s' are in an inconsistent "
628
                               "state and need to be reinstalled, but "
629
                               "no archive can be found for it."
630
                               "Please reinstall the packages manually "
631
                               "or remove them from the system.",
632
                               len(reqreinst)) % ", ".join(reqreinst)
838 by Michael Vogt
* deal with packages in broken reqreinst state by
633
            self._view.error(header, summary)
634
            return False
42 by Michael Vogt
* calculate the obsolete and foreign packages before the upgrade (let's see what interessting things we can do with them after the ugprade :)
635
        # FIXME: check out what packages are downloadable etc to
636
        # compare the list after the update again
117 by Michael Vogt
* refactored more stuff into the cache (out of the controler)
637
        self.obsolete_pkgs = self.cache._getObsoletesPkgs()
638
        self.foreign_pkgs = self.cache._getForeignPkgs(self.origin, self.fromDist, self.toDist)
441 by Michael Vogt
* server-mode added
639
        if self.serverMode:
640
            self.tasks = self.cache.installedTasks
76 by Michael Vogt
* logging added
641
        logging.debug("Foreign: %s" % " ".join(self.foreign_pkgs))
642
        logging.debug("Obsolete: %s" % " ".join(self.obsolete_pkgs))
838 by Michael Vogt
* deal with packages in broken reqreinst state by
643
        return True
29 by Michael Vogt
* GtkDistUpgradeView.askYesNoQuestion() implemented
644
924 by Michael Vogt
- smaller default network time out
645
    def doUpdate(self, showErrors=True, forceRetries=None):
923 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
646
        logging.debug("running doUpdate() (showErrors=%s)" % showErrors)
358.1.8 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
647
        if not self.useNetwork:
648
            logging.debug("doUpdate() will not use the network because self.useNetwork==false")
649
            return True
72 by Michael Vogt
* missing "{k,edu,}ubuntu-desktop" detection added
650
        self.cache._list.ReadMainList()
30 by Michael Vogt
* do update implemented
651
        progress = self._view.getFetchProgress()
770 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
652
        # FIXME: also remove all files from the lists partial dir!
154.1.12 by Michael Vogt
* added MaxRetries to the configuration, retry on update errors as well
653
        currentRetry = 0
924 by Michael Vogt
- smaller default network time out
654
        if forceRetries is not None:
655
            maxRetries=forceRetries
656
        else:
657
            maxRetries = self.config.getint("Network","MaxRetries")
154.1.12 by Michael Vogt
* added MaxRetries to the configuration, retry on update errors as well
658
        while currentRetry < maxRetries:
659
            try:
660
                res = self.cache.update(progress)
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
661
            except (SystemError, IOError), e:
662
                logging.error("IOError/SystemError in cache.update(): '%s'. Retrying (currentRetry: %s)" % (e,currentRetry))
154.1.12 by Michael Vogt
* added MaxRetries to the configuration, retry on update errors as well
663
                currentRetry += 1
664
                continue
665
            # no exception, so all was fine, we are done
666
            return True
358.1.145 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
667
752.1.1 by Brian Murray
fixed some spelling errors
668
        logging.error("doUpdate() failed completely")
668 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
669
        if showErrors:
670
            self._view.error(_("Error during update"),
752.1.2 by Brian Murray
Fix for Launchpad bug 64473
671
                             _("A problem occurred during the update. "
668 by Michael Vogt
* UpdateManager/DistUpgradeFetcherCore.py:
672
                               "This is usually some sort of network "
673
                               "problem, please check your network "
674
                               "connection and retry."), "%s" % e)
154.1.12 by Michael Vogt
* added MaxRetries to the configuration, retry on update errors as well
675
        return False
676
30 by Michael Vogt
* do update implemented
677
285 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
678
    def _checkFreeSpace(self):
679
        " this checks if we have enough free space on /var and /usr"
680
        err_sum = _("Not enough free disk space")
681
        err_long= _("The upgrade aborts now. "
689 by Michael Vogt
- fix size requirement reporting (LP: #137539)
682
                    "The upgrade needs a total of %s free space on disk '%s'. "
619 by Michael Vogt
* make the wording of the free space message more clear
683
                    "Please free at least an additional %s of disk "
689 by Michael Vogt
- fix size requirement reporting (LP: #137539)
684
                    "space on '%s'. "
285 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
685
                    "Empty your trash and remove temporary "
686
                    "packages of former installations using "
687
                    "'sudo apt-get clean'.")
688
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
689
        class FreeSpace(object):
690
            " helper class that represents the free space on each mounted fs "
691
            def __init__(self, initialFree):
692
                self.free = initialFree
689 by Michael Vogt
- fix size requirement reporting (LP: #137539)
693
                self.need = 0
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
694
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
695
        def make_fs_id(d):
696
            """ return 'id' of a directory so that directories on the
697
                same filesystem get the same id (simply the mount_point)
698
            """
699
            for mount_point in mounted:
700
                if d.startswith(mount_point):
701
                    return mount_point
702
            return "/"
703
704
        # this is all a bit complicated
705
        # 1) check what is mounted (in mounted)
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
706
        # 2) create FreeSpace objects for the dirs we are interested in
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
707
        #    (mnt_map)
708
        # 3) use the  mnt_map to check if we have enough free space and
709
        #    if not tell the user how much is missing
710
        mounted = []
711
        mnt_map = {}
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
712
        fs_free = {}
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
713
        for line in open("/proc/mounts"):
601 by Michael Vogt
- deal with invalid lines in /proc/mounts when calculating
714
            try:
715
                (what, where, fs, options, a, b) = line.split()
716
            except ValueError, e:
717
                logging.debug("line '%s' in /proc/mounts not understood (%s)" % (line, e))
718
                continue
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
719
            if not where in mounted:
720
                mounted.append(where)
721
        # make sure mounted is sorted by longest path
722
        mounted.sort(cmp=lambda a,b: cmp(len(a),len(b)), reverse=True)
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
723
        archivedir = apt_pkg.Config.FindDir("Dir::Cache::archives")
724
        for d in ["/","/usr","/var","/boot", archivedir, "/home"]:
586 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
725
            d = os.path.realpath(d)
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
726
            fs_id = make_fs_id(d)
358.1.119 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
727
            st = os.statvfs(d)
728
            free = st[statvfs.F_BAVAIL]*st[statvfs.F_FRSIZE]
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
729
            if fs_id in mnt_map:
730
                logging.debug("Dir %s mounted on %s" % (d,mnt_map[fs_id]))
731
                fs_free[d] = fs_free[mnt_map[fs_id]]
358.1.119 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
732
            else:
733
                logging.debug("Free space on %s: %s" % (d,free))
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
734
                mnt_map[fs_id] = d
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
735
                fs_free[d] = FreeSpace(free)
358.1.119 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
736
        del mnt_map
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
737
        logging.debug("fs_free contains: '%s'" % fs_free)
738
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
739
        # now calculate the space that is required on /boot
740
        # we do this by checking how many linux-image-$ver packages
741
        # are installed or going to be installed
742
        space_in_boot = 0
743
        for pkg in self.cache:
744
            # we match against everything that looks like a kernel
745
            # and add space check to filter out metapackages
746
            if re.match("^linux-(image|image-debug)-[0-9.]*-.*", pkg.name):
747
                if pkg.markedInstall:
748
                    logging.debug("%s (new-install) added with %s to boot space" % (pkg.name, KERNEL_INITRD_SIZE))
749
                    space_in_boot += KERNEL_INITRD_SIZE
750
                elif (pkg.markedUpgrade or pkg.isInstalled):
747 by Michael Vogt
- when calculating the size required in /boot take into account
751
                    logging.debug("%s (upgrade|installed) added with %s to boot space" % (pkg.name, KERNEL_INITRD_SIZE))
752
                    space_in_boot += KERNEL_INITRD_SIZE # creates .bak
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
753
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
754
        # we check for various sizes:
755
        # archivedir is were we download the debs
756
        # /usr is assumed to get *all* of the install space (incorrect,
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
757
        #      but as good as we can do currently + safety buffer
758
        # /     has a small safety buffer as well
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
759
        for (dir, size) in [(archivedir, self.cache.requiredDownload),
760
                            ("/usr", self.cache.additionalRequiredSpace),
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
761
                            ("/usr", 50*1024*1024),  # safety buffer /usr
641 by Michael Vogt
- improve free space calculation in /boot (Fixes LP: #116163)
762
                            ("/boot", space_in_boot), 
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
763
                            ("/", 10*1024*1024),     # small safety buffer /
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
764
                           ]:
586 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
765
            dir = os.path.realpath(dir)
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
766
            logging.debug("dir '%s' needs '%s' of '%s' (%f)" % (dir, size, fs_free[dir], fs_free[dir].free))
767
            fs_free[dir].free -= size
689 by Michael Vogt
- fix size requirement reporting (LP: #137539)
768
            fs_free[dir].need += size
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
769
            if fs_free[dir].free < 0:
473 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
770
                free_at_least = apt_pkg.SizeToStr(float(abs(fs_free[dir].free)+1))
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
771
                logging.error("not enough free space on %s (missing %s)" % (dir, free_at_least))
689 by Michael Vogt
- fix size requirement reporting (LP: #137539)
772
                self._view.error(err_sum, err_long % (apt_pkg.SizeToStr(fs_free[dir].need), make_fs_id(dir), free_at_least, make_fs_id(dir)))
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
773
                return False
774
285 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
775
            
776
        return True
777
639 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #91978)
778
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
779
    def askDistUpgrade(self):
639 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #91978)
780
        # check what packages got demoted and ask the user
781
        # if those shall be removed
782
        demotions = set()
783
        demotions_file = self.config.get("Distro","Demotions")
784
        if os.path.exists(demotions_file):
785
            map(lambda pkgname: demotions.add(pkgname.strip()),
786
                filter(lambda line: not line.startswith("#"),
787
                       open(demotions_file).readlines()))
712 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
788
        self.installed_demotions = [pkg.name for pkg in self.cache if pkg.isInstalled and pkg.name in demotions]
639 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #91978)
789
        if len(self.installed_demotions) > 0:
712 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
790
	    self.installed_demotions.sort()
791
            logging.debug("demoted: '%s'" % " ".join(self.installed_demotions))
863 by Michael Vogt
* DistUpgrade/DistUpgradeViewText.py:
792
            self._view.showDemotions(_("Support for some applications ended"),
639 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #91978)
793
                                   _("Canonical Ltd. no longer provides "
794
                                     "support for the following software "
795
                                     "packages. You can still get support "
796
                                     "from the community.\n\n"
797
                                     "If you have not enabled community "
798
                                     "maintained software (universe), "
799
                                     "these packages will be suggested for "
800
                                     "removal at the end of the upgrade."),
863 by Michael Vogt
* DistUpgrade/DistUpgradeViewText.py:
801
                                     self.installed_demotions)
901 by Michael Vogt
- set status to "Calculating changes" again after displaying
802
            self._view.updateStatus(_("Calculating the changes"))
758 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py,:
803
        # FIXME: integrate this into main upgrade dialog!?!
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
804
        if not self.cache.distUpgrade(self._view, self.serverMode, self._partialUpgrade):
113 by Michael Vogt
* moved most of the upgrade logic to the DistUpgradeCache() class
805
            return False
758 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py,:
806
441 by Michael Vogt
* server-mode added
807
        if self.serverMode:
808
            if not self.cache.installTasks(self.tasks):
809
                return False
72 by Michael Vogt
* missing "{k,edu,}ubuntu-desktop" detection added
810
        changes = self.cache.getChanges()
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
811
        # log the changes for debugging
79 by Michael Vogt
* cleanup in the log changes code
812
        self._logChanges()
285 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
813
        # check if we have enough free space 
814
        if not self._checkFreeSpace():
815
            return False
76 by Michael Vogt
* logging added
816
        # ask the user if he wants to do the changes
123.1.49 by Sebastian Heinlein
* dialog_confirm_changes:
817
        res = self._view.confirmChanges(_("Do you want to start the upgrade?"),
818
                                        changes,
81 by Michael Vogt
* remove cruft implemented
819
                                        self.cache.requiredDownload)
35 by Michael Vogt
* started with the dist-upgrade confirm dialog
820
        return res
29 by Michael Vogt
* GtkDistUpgradeView.askYesNoQuestion() implemented
821
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
822
    def _disableAptCronJob(self):
823
        self._aptCronJobPerms = 0755
824
        if os.path.exists("/etc/cron.daily/apt"):
825
            self._aptCronJobPerms = os.stat("/etc/cron.daily/apt")[ST_MODE]
1115 by Michael Vogt
DistUpgrade/DistUpgradeController.py: add logging to enable/disable apt cron
826
            logging.debug("disabling apt cron job (%s)" % oct(self._aptCronJobPerms))
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
827
            os.chmod("/etc/cron.daily/apt",0644)
828
    def _enableAptCronJob(self):
829
        if os.path.exists("/etc/cron.daily/apt"):
1115 by Michael Vogt
DistUpgrade/DistUpgradeController.py: add logging to enable/disable apt cron
830
            logging.debug("enabling apt cron job")
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
831
            os.chmod("/etc/cron.daily/apt", self._aptCronJobPerms)
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
832
833
    def doDistUpgradeFetching(self):
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
834
        # ensure that no apt cleanup is run during the download/install
835
        self._disableAptCronJob()
597 by Michael Vogt
- increase minAge for the apt cleanup cron job during the upgrade
836
        # get the upgrade
148 by Michael Vogt
* retry automatically on network problems
837
        currentRetry = 0
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
838
        fprogress = self._view.getFetchProgress()
314 by Michael Vogt
* check if libgnome2-perl is installed and if not expand the terminal and use dialog, otherwise use gnome
839
        iprogress = self._view.getInstallProgress(self.cache)
148 by Michael Vogt
* retry automatically on network problems
840
        # retry the fetching in case of errors
421 by Michael Vogt
* DistUpgrade/install_all.py:
841
        maxRetries = self.config.getint("Network","MaxRetries")
769 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
842
        # FIXME: we get errors like 
843
        #   "I wasn't able to locate file for the %s package" 
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
844
        #  here sometimes. its unclear why and not reproducible, the 
769 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
845
        #  current theory is that for some reason the file is not
846
        #  considered trusted at the moment 
847
        #  pkgAcquireArchive::QueueNext() runs debReleaseIndex::IsTrused()
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
848
        #  (the later just checks for the existence of the .gpg file)
769 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
849
        #  OR 
850
        #  the fact that we get a pm and fetcher here confuses something
851
        #  in libapt?
770 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
852
        # POSSIBLE workaround: keep the list-dir locked so that 
853
        #          no apt-get update can run outside from the release
854
        #          upgrader 
154.1.12 by Michael Vogt
* added MaxRetries to the configuration, retry on update errors as well
855
        while currentRetry < maxRetries:
148 by Michael Vogt
* retry automatically on network problems
856
            try:
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
857
                pm = apt_pkg.GetPackageManager(self.cache._depcache)
858
                fetcher = apt_pkg.GetAcquire(fprogress)
859
                res = self.cache._fetchArchives(fetcher, pm)
860
            except IOError, e:
861
                # fetch failed, will be retried
862
                logging.error("IOError in cache.commit(): '%s'. Retrying (currentTry: %s)" % (e,currentRetry))
863
                currentRetry += 1
864
                continue
865
            return True
866
        
867
        # maximum fetch-retries reached without a successful commit
868
        logging.error("giving up on fetching after maximum retries")
869
        self._view.error(_("Could not download the upgrades"),
1015 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
870
                         _("The upgrade aborts now. Please check your "
871
                           "Internet connection or "
872
                           "installation media and try again. All files "
873
                           "downloaded so far are kept."),
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
874
                           "%s" % e)
875
        # abort here because we want our sources.list back
1124 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
876
        self._enableAptCronJob()
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
877
        self.abort()
878
        
879
    
880
    def doDistUpgrade(self):
881
        # get the upgrade
882
        currentRetry = 0
883
        fprogress = self._view.getFetchProgress()
884
        iprogress = self._view.getInstallProgress(self.cache)
885
        # retry the fetching in case of errors
886
        maxRetries = self.config.getint("Network","MaxRetries")
887
        while currentRetry < maxRetries:
888
            try:
148 by Michael Vogt
* retry automatically on network problems
889
                res = self.cache.commit(fprogress,iprogress)
890
            except SystemError, e:
504 by Michael Vogt
- better apport integration
891
                logging.error("SystemError from cache.commit(): %s" % e)
1021 by Michael Vogt
* DistUpgrade/DistUpgradeApport.py:
892
                # check if the installprogress catched a pkg_failures, 
893
                # if not, generate a fallback here (pkg_failures can be
894
                # zero because of e.g. disk-full problems)
504 by Michael Vogt
- better apport integration
895
                if iprogress.pkg_failures == 0:
1021 by Michael Vogt
* DistUpgrade/DistUpgradeApport.py:
896
                    logging.warning("cache.commit() error and pkg_failures == 0, generate a report against update-manager to investigate")
504 by Michael Vogt
- better apport integration
897
                    errormsg = "SystemError in cache.commit(): %s" % e
898
                    apport_pkgfailure("update-manager", errormsg)
899
                # invoke the frontend now
900
                msg = _("The upgrade aborts now. Your system "
901
                        "could be in an unusable state. A recovery "
558 by Michael Vogt
- when encountering a error, first show the error dialog,
902
                        "will run now (dpkg --configure -a).")
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
903
                if not self._partialUpgrade:
734 by Michael Vogt
- when running in partial upgrade mode, do not run apport,
904
                    if not run_apport():
905
                        msg += _("\n\nPlease report this bug against the 'update-manager' "
906
                                 "package and include the files in /var/log/dist-upgrade/ "
907
                                 "in the bugreport.\n"
908
                                 "%s" % e)
504 by Michael Vogt
- better apport integration
909
                self._view.error(_("Could not install the upgrades"), msg)
558 by Michael Vogt
- when encountering a error, first show the error dialog,
910
                # installing the packages failed, can't be retried
911
                self._view.getTerminal().call(["dpkg","--configure","-a"])
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
912
                self._enableAptCronJob()
148 by Michael Vogt
* retry automatically on network problems
913
                return False
914
            except IOError, e:
915
                # fetch failed, will be retried
154.1.13 by Michael Vogt
* fix in the retry code
916
                logging.error("IOError in cache.commit(): '%s'. Retrying (currentTry: %s)" % (e,currentRetry))
148 by Michael Vogt
* retry automatically on network problems
917
                currentRetry += 1
918
                continue
919
            # no exception, so all was fine, we are done
1114 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
920
            self._enableAptCronJob()
148 by Michael Vogt
* retry automatically on network problems
921
            return True
922
        
923
        # maximum fetch-retries reached without a successful commit
358.1.145 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
924
        logging.error("giving up on fetching after maximum retries")
123.1.49 by Sebastian Heinlein
* dialog_confirm_changes:
925
        self._view.error(_("Could not download the upgrades"),
926
                         _("The upgrade aborts now. Please check your "\
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
927
                           "Internet connection or "\
123.1.49 by Sebastian Heinlein
* dialog_confirm_changes:
928
                           "installation media and try again. "),
148 by Michael Vogt
* retry automatically on network problems
929
                           "%s" % e)
930
        # abort here because we want our sources.list back
931
        self.abort()
932
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
933
    def doPostUpgrade(self):
659 by Michael Vogt
- mark evms as obsolete if it is not in use
934
        # reopen cache
81 by Michael Vogt
* remove cruft implemented
935
        self.openCache()
1108 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
936
        # run the quirks handler that does does like things adding
937
        # missing groups or similar work arounds, only do it on real
938
        # upgrades
939
        if not self._partialUpgrade:
940
            self.quirks.run("PostUpgrade")
81 by Michael Vogt
* remove cruft implemented
941
        # check out what packages are cruft now
42 by Michael Vogt
* calculate the obsolete and foreign packages before the upgrade (let's see what interessting things we can do with them after the ugprade :)
942
        # use self.{foreign,obsolete}_pkgs here and see what changed
117 by Michael Vogt
* refactored more stuff into the cache (out of the controler)
943
        now_obsolete = self.cache._getObsoletesPkgs()
944
        now_foreign = self.cache._getForeignPkgs(self.origin, self.fromDist, self.toDist)
81 by Michael Vogt
* remove cruft implemented
945
        logging.debug("Obsolete: %s" % " ".join(now_obsolete))
946
        logging.debug("Foreign: %s" % " ".join(now_foreign))
429 by Michael Vogt
* DistUpgrade/DistUpgradeConfigParser.py
947
        # check if we actually want obsolete removal
948
        if not self.config.getWithDefault("Distro","RemoveObsoletes", True):
949
            logging.debug("Skipping obsolete Removal")
950
            return True
154.1.6 by Michael Vogt
* fix small problems in the per-meta-pkg obsoletes support
951
154.1.7 by Michael Vogt
* make force_purges work
952
        # now get the meta-pkg specific obsoletes and purges
154.1.6 by Michael Vogt
* fix small problems in the per-meta-pkg obsoletes support
953
        for pkg in self.config.getlist("Distro","MetaPkgs"):
954
            if self.cache.has_key(pkg) and self.cache[pkg].isInstalled:
955
                self.forced_obsoletes.extend(self.config.getlist(pkg,"ForcedObsoletes"))
1051 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
956
        # now add the obsolete kernels to the forced obsoletes
957
        self.forced_obsoletes.extend(self.cache.identifyObsoleteKernels())
154.1.7 by Michael Vogt
* make force_purges work
958
        logging.debug("forced_obsoletes: %s", self.forced_obsoletes)
158 by Michael Vogt
* added a "PostUpgrade{Install,Remove,Purge}" rule, removed the ForcedPurges and superseed it with the new rule
959
84 by Michael Vogt
* make sure to not mark any foreign packages as cruft
960
        # mark packages that are now obsolete (and where not obsolete
961
        # before) to be deleted. make sure to not delete any foreign
92 by Michael Vogt
* be careful about remove obsolete, only remove if no other package (outside
962
        # (that is, not from ubuntu) packages
358.1.21 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
963
        if self.useNetwork:
964
            # we can only do the obsoletes calculation here if we use a
965
            # network. otherwise after rewriting the sources.list everything
966
            # that is not on the CD becomes obsolete (not-downloadable)
967
            remove_candidates = now_obsolete - self.obsolete_pkgs
968
        else:
969
            # initial remove candidates when no network is used should
970
            # be the demotions to make sure we don't leave potential
971
            # unsupported software
639 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #91978)
972
            remove_candidates = set(self.installed_demotions)
130 by Michael Vogt
* forced_obsoletes added
973
        remove_candidates |= set(self.forced_obsoletes)
645 by Michael Vogt
- implement SystemCleanup spec unused dependencies removal
974
975
        # no go for the unused dependencies
976
        unused_dependencies = self.cache._getUnusedDependencies()
977
        logging.debug("Unused dependencies: %s" %" ".join(unused_dependencies))
978
        remove_candidates |= set(unused_dependencies)
979
616 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py, DistUpgrade/DistUpgrade.cfg:
980
        # see if we actually have to do anything here
621 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
981
        if not self.config.getWithDefault("Distro","RemoveObsoletes", True):
823 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
982
            logging.debug("Skipping RemoveObsoletes as stated in the config")
616 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py, DistUpgrade/DistUpgrade.cfg:
983
            remove_candidates = set()
154.1.7 by Michael Vogt
* make force_purges work
984
        logging.debug("remove_candidates: '%s'" % remove_candidates)
95 by Michael Vogt
* the log includes timing information as well now
985
        logging.debug("Start checking for obsolete pkgs")
92 by Michael Vogt
* be careful about remove obsolete, only remove if no other package (outside
986
        for pkgname in remove_candidates:
84 by Michael Vogt
* make sure to not mark any foreign packages as cruft
987
            if pkgname not in self.foreign_pkgs:
571 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
988
                self._view.processEvents()
782 by Michael Vogt
DistUpgrade/DistUpgradeCache.py:
989
                if not self.cache.tryMarkObsoleteForRemoval(pkgname, remove_candidates, self.foreign_pkgs):
1073 by Michael Vogt
make the log of the obsolete removal less verbose
990
                    logging.debug("'%s' scheduled for remove but not safe to remove, skipping", pkgname)
95 by Michael Vogt
* the log includes timing information as well now
991
        logging.debug("Finish checking for obsolete pkgs")
154.1.7 by Michael Vogt
* make force_purges work
992
993
        # get changes
96 by Michael Vogt
* added a "removal_blacklist.txt" that contains regexp for packagenames that should never get removed
994
        changes = self.cache.getChanges()
150 by Michael Vogt
* log the removal candidates as well
995
        logging.debug("The following packages are remove candidates: %s" % " ".join([pkg.name for pkg in changes]))
200 by Michael Vogt
* merge with the stuff from the update-manager--mvo branch
996
        summary = _("Remove obsolete packages?")
826 by Michael Vogt
* more UI improvements as suggested by Matthew Paul Thomas
997
        actions = [_("_Keep"), _("_Remove")]
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
998
        # FIXME Add an explanation about what obsolete packages are
200 by Michael Vogt
* merge with the stuff from the update-manager--mvo branch
999
        #explanation = _("")
96 by Michael Vogt
* added a "removal_blacklist.txt" that contains regexp for packagenames that should never get removed
1000
        if len(changes) > 0 and \
826 by Michael Vogt
* more UI improvements as suggested by Matthew Paul Thomas
1001
               self._view.confirmChanges(summary, changes, 0, actions, False):
81 by Michael Vogt
* remove cruft implemented
1002
            fprogress = self._view.getFetchProgress()
314 by Michael Vogt
* check if libgnome2-perl is installed and if not expand the terminal and use dialog, otherwise use gnome
1003
            iprogress = self._view.getInstallProgress(self.cache)
125 by Michael Vogt
* expand the terminal on a conffile question
1004
            try:
1005
                res = self.cache.commit(fprogress,iprogress)
1006
            except (SystemError, IOError), e:
358.1.145 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1007
                logging.error("cache.commit() in doPostUpgrade() failed: %s" % e)
125 by Michael Vogt
* expand the terminal on a conffile question
1008
                self._view.error(_("Error during commit"),
752.1.2 by Brian Murray
Fix for Launchpad bug 64473
1009
                                 _("A problem occurred during the clean-up. "
125 by Michael Vogt
* expand the terminal on a conffile question
1010
                                   "Please see the below message for more "
126 by Michael Vogt
* merged with sebastian
1011
                                   "information. "),
125 by Michael Vogt
* expand the terminal on a conffile question
1012
                                   "%s" % e)
1108 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1013
        # run the post upgrade scripts that can do fixup like xorg.conf
1014
        # fixes etc - only do on real upgrades
1015
        if not self._partialUpgrade:
1016
            self.runPostInstallScripts()
1107 by Michael Vogt
* DistUpgrade/DistUpgradeViewGtk.py:
1017
        return True
883 by Michael Vogt
- run migrate-fstab-to-uuid.sh as PostInstallScript (LP: #209347)
1018
1019
    def runPostInstallScripts(self):
1075 by Michael Vogt
run the fglrx removal
1020
        """ 
1021
        scripts that are run in any case after the distupgrade finished 
1022
        whether or not it was successfull
1023
        """
552 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1024
        # now run the post-upgrade fixup scripts (if any)
1025
        for script in self.config.getlist("Distro","PostInstallScripts"):
1122 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1026
            if not os.path.exists(script):
1027
                logging.warning("PostInstallScript: '%s' not found" % script)
1028
                continue
752.1.4 by Brian Murray
Fix Runing to Running fixes Launchpad bug 99153
1029
            logging.debug("Running PostInstallScript: '%s'" % script)
567 by Michael Vogt
* DistUpgradeControler.py:
1030
            try:
1122 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1031
                # work around kde tmpfile problem where it eats permissions
1032
                os.chmod(script, 0755)
567 by Michael Vogt
* DistUpgradeControler.py:
1033
                self._view.getTerminal().call([script], hidden=True)
1034
            except Exception, e:
752.1.1 by Brian Murray
fixed some spelling errors
1035
                logging.error("got error from PostInstallScript %s (%s)" % (script, e))
1075 by Michael Vogt
run the fglrx removal
1036
        
90 by Michael Vogt
* on problems call "abort" and restore the old sources.list
1037
    def abort(self):
1038
        """ abort the upgrade, cleanup (as much as possible) """
358.1.84 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1039
        if hasattr(self, "sources"):
358.1.82 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1040
            self.sources.restoreBackup(self.sources_backup_ext)
358.1.84 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1041
        if hasattr(self, "aptcdrom"):
358.1.82 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1042
            self.aptcdrom.restoreBackup(self.sources_backup_ext)
257 by Michael Vogt
* more checking
1043
        # generate a new cache
318 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1044
        self._view.updateStatus(_("Restoring original system state"))
337.4.23 by glatzor at ubuntu
* improve wording of some dialogs: no-longer-supported,
1045
        self._view.abort()
257 by Michael Vogt
* more checking
1046
        self.openCache()
90 by Michael Vogt
* on problems call "abort" and restore the old sources.list
1047
        sys.exit(1)
1048
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1049
    def _checkDep(self, depstr):
1050
        " check if a given depends can be satisfied "
1051
        for or_group in apt_pkg.ParseDepends(depstr):
1052
            logging.debug("checking: '%s' " % or_group)
1053
            for dep in or_group:
1054
                depname = dep[0]
1055
                ver = dep[1]
1056
                oper = dep[2]
1057
                if not self.cache.has_key(depname):
1058
                    logging.error("_checkDep: '%s' not in cache" % depname)
1059
                    return False
1060
                inst = self.cache[depname]
1061
                instver = inst.installedVersion
1062
                if (instver != None and
1063
                    apt_pkg.CheckDep(instver,oper,ver) == True):
1064
                    return True
1065
        logging.error("depends '%s' is not satisfied" % depstr)
1066
        return False
1067
                
1068
    def checkViewDepends(self):
1069
        " check if depends are satisfied "
1070
        logging.debug("checkViewDepends()")
1071
        res = True
1072
        # now check if anything from $foo-updates is required
1073
        depends = self.config.getlist("View","Depends")
1074
        depends.extend(self.config.getlist(self._view.__class__.__name__,
1075
                                           "Depends"))
1076
        for dep in depends:
1077
            logging.debug("depends: '%s'", dep)
1078
            res &= self._checkDep(dep)
1079
            if not res:
654 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1080
                # FIXME: instead of error out, fetch and install it
1081
                #        here
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1082
                self._view.error(_("Required depends is not installed"),
1083
                                 _("The required dependency '%s' is not "
1084
                                   "installed. " % dep))
1085
                sys.exit(1)
1086
        return res 
1087
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1088
    def _verifyBackports(self):
1089
        # run update (but ignore errors in case the countrymirror
1090
        # substitution goes wrong, real errors will be caught later
1091
        # when the cache is searched for the backport packages)
1092
        backportslist = self.config.getlist("PreRequists","Packages")
1093
        i=0
1094
        noCache = apt_pkg.Config.Find("Acquire::http::No-Cache","false")
1095
        maxRetries = self.config.getint("Network","MaxRetries")
1096
        while i < maxRetries:
1097
            self.doUpdate(showErrors=False)
1098
            self.openCache()
1099
            for pkgname in backportslist:
1100
                if not self.cache.has_key(pkgname):
1101
                    logging.error("Can not find backport '%s'" % pkgname)
1102
                    raise NoBackportsFoundException, pkgname
1103
            if self._allBackportsAuthenticated(backportslist):
1104
                break
1105
            # FIXME: move this to some more generic place
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1106
            logging.debug("setting a cache control header to turn off caching temporarily")
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1107
            apt_pkg.Config.Set("Acquire::http::No-Cache","true")
1108
            i += 1
1109
        if i == maxRetries:
1110
            logging.error("pre-requists item is NOT trusted, giving up")
1111
            return False
1112
        apt_pkg.Config.Set("Acquire::http::No-Cache",noCache)
1113
        return True
1114
1115
    def _allBackportsAuthenticated(self, backportslist):
1031.1.2 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py,
1116
        # check if the user overwrote the check
843 by Michael Vogt
- honor APT::Get::AllowUnauthenticated (thanks to Kolbjørn
1117
        if apt_pkg.Config.FindB("APT::Get::AllowUnauthenticated",False) == True:
1118
            logging.warning("skip authentication check because of APT::Get::AllowUnauthenticated==true")
1119
            return True
1031.1.2 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py,
1120
        try:
1121
            b = self.config.getboolean("Distro","AllowUnauthenticated")
1122
            if b:
1123
                return True
1124
        except ConfigParser.NoOptionError, e:
1125
            pass
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1126
        for pkgname in backportslist:
1127
            pkg = self.cache[pkgname]                
1128
            for cand in pkg.candidateOrigin:
1129
                if cand.trusted:
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1130
                    break
1131
            else:
1132
                return False
1133
        return True
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1134
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1135
    def isMirror(self, uri):
1136
        " check if uri is a known mirror "
1137
        for mirror in self.valid_mirrors:
1138
            if is_mirror(mirror, uri):
1139
                return True
1140
        return False
1141
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1142
    def _getPreReqMirrorLines(self, dumb=False):
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1143
        " get sources.list snippet lines for the current mirror "
1144
        lines = ""
1145
        sources = SourcesList(matcherPath=".")
1146
        for entry in sources.list:
1147
            if entry.invalid or entry.disabled:
1148
                continue
1149
            if (entry.type == "deb" and 
1150
                self.isMirror(entry.uri) and
1151
                not entry.uri.startswith("http://security.ubuntu.com") and
1152
                not entry.uri.startswith("http://archive.ubuntu.com") ):
842 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1153
                new_line = "deb %s %s-backports main/debian-installer\n" % (entry.uri, self.fromDist)
1154
                if not new_line in lines:
1155
                    lines += new_line
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1156
            if (dumb and entry.type == "deb" and
1157
                "main" in entry.comps):
1158
                lines += "deb %s %s-backports main/debian-installer\n" % (entry.uri, self.fromDist)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1159
        return lines
1160
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1161
    def _addPreRequistsSourcesList(self, template, out, dumb=False):
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1162
        " add prerequists based on template into the path outfile "
1163
        # go over the sources.list and try to find a valid mirror
1164
        # that we can use to add the backports dir
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1165
        logging.debug("writing prerequists sources.list at: '%s' " % out)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1166
        outfile = open(out, "w")
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1167
        mirrorlines = self._getPreReqMirrorLines(dumb)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1168
        for line in open(template):
1169
            template = Template(line)
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1170
            outline = template.safe_substitute(mirror=mirrorlines)
1171
            outfile.write(outline)
1172
            logging.debug("adding '%s' prerequists" % outline)
832 by Michael Vogt
DistUpgrade/DistUpgradeController.py: fix prerequists outfile generation
1173
        outfile.close()
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1174
        return True
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1175
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1176
    def getRequiredBackports(self):
1177
        " download the backports specified in DistUpgrade.cfg "
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1178
        logging.debug("getRequiredBackports()")
1179
        res = True
703 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
1180
        backportsdir = os.path.join(os.getcwd(),"backports")
1181
        if not os.path.exists(backportsdir):
1182
            os.mkdir(backportsdir)
1183
        backportslist = self.config.getlist("PreRequists","Packages")
702 by Michael Vogt
- support pre-requists on the CD as well
1184
1185
        # if we have them on the CD we are fine
1186
        if self.aptcdrom and not self.useNetwork:
1187
            logging.debug("Searching for pre-requists on CDROM")
1188
            p = os.path.join(self.aptcdrom.cdrompath,
1189
                             "dists/stable/main/dist-upgrader/binary-%s/" % apt_pkg.Config.Find("APT::Architecture"))
1190
            found_pkgs = set()
1191
            for udeb in glob.glob(p+"*_*.udeb"):
1192
                logging.debug("copying pre-req '%s' to '%s'" % (udeb, backportsdir))
703 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
1193
                found_pkgs.add(os.path.basename(udeb).split("_")[0])
702 by Michael Vogt
- support pre-requists on the CD as well
1194
                shutil.copy(udeb, backportsdir)
1195
            # now check if we got all backports on the CD
1196
            if not set(backportslist) == found_pkgs:
703 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
1197
                logging.error("Expected backports: '%s' but got '%s'" % (set(backportslist), found_pkgs))
702 by Michael Vogt
- support pre-requists on the CD as well
1198
                return False
1199
            return self.setupRequiredBackports(backportsdir)
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1200
767 by Michael Vogt
- fix getting prerequists for ports.ubuntu.com
1201
        # we support PreRequists/SourcesList-$arch sections here too
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1202
        # 
1203
        # logic for mirror finding works list this:     
1204
        # - use the mirror template from the config, then: [done]
1205
        # 
1206
        #  - try to find known mirror (isMirror) and prepend it [done]
1207
        #  - archive.ubuntu.com is always a fallback at the end [done]
1208
        # 
1209
        # see if we find backports with that
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1210
        # - if not, try guessing based on URI, Trust and Dist   [done]
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1211
        #   in existing sources.list (internal mirror with no
1212
        #   outside connection maybe)
1213
        # 
1214
        # make sure to remove file on cancel
1215
        
767 by Michael Vogt
- fix getting prerequists for ports.ubuntu.com
1216
        conf_option = "SourcesList"
1217
        if self.config.has_option("PreRequists",conf_option+"-%s" % self.arch):
1218
            conf_option = conf_option + "-%s" % self.arch
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1219
        prereq_template = self.config.get("PreRequists",conf_option)
1220
        if not os.path.exists(prereq_template):
1221
            logging.error("sourceslist not found '%s'" % prereq_template)
669 by Michael Vogt
* AutoUpgradeTester/*
1222
            return False
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1223
        outpath = os.path.join(apt_pkg.Config.FindDir("Dir::Etc::sourceparts"), prereq_template)
832 by Michael Vogt
DistUpgrade/DistUpgradeController.py: fix prerequists outfile generation
1224
        outfile = os.path.join(apt_pkg.Config.FindDir("Dir::Etc::sourceparts"), prereq_template)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1225
        self._addPreRequistsSourcesList(prereq_template, outfile) 
835 by Michael Vogt
* when the prerequists can not be found on the mirror or the
1226
        try:
1227
            self._verifyBackports()
1228
        except NoBackportsFoundException, e:
1229
            self._addPreRequistsSourcesList(prereq_template, outfile, dumb=True) 
1230
            try:
1231
                self._verifyBackports()
1232
            except NoBackportsFoundException, e:
1233
                logging.warning("no backport for '%s' found" % e)
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1234
            return False
358.1.71 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
1235
        
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1236
        # save cachedir and setup new one
1237
        cachedir = apt_pkg.Config.Find("Dir::Cache::archives")
358.1.65 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1238
        cwd = os.getcwd()
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1239
        if not os.path.exists(os.path.join(backportsdir,"partial")):
1240
            os.mkdir(os.path.join(backportsdir,"partial"))
358.1.71 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
1241
        os.chdir(backportsdir)
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1242
        apt_pkg.Config.Set("Dir::Cache::archives",backportsdir)
1243
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1244
        # FIXME: sanity check the origin (just for safety)
702 by Michael Vogt
- support pre-requists on the CD as well
1245
        for pkgname in backportslist:
358.1.64 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1246
            pkg = self.cache[pkgname]
358.1.65 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1247
            # look for the right version (backport)
665 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1248
            ver = self.cache._depcache.GetCandidateVer(pkg._pkg)
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1249
            if not ver:
1250
                logging.error("No candidate for '%s'" % pkgname)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1251
                os.unlink(outpath)
669 by Michael Vogt
* AutoUpgradeTester/*
1252
                return False
358.1.65 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1253
            if ver.FileList == None:
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1254
                logging.error("No ver.FileList for '%s'" % pkgname)
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1255
                os.unlink(outpath)
669 by Michael Vogt
* AutoUpgradeTester/*
1256
                return False
692 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1257
            logging.debug("marking '%s' for install" % pkgname)
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1258
            # mvo: autoInst is not available on dapper
766 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1259
            #pkg.markInstall(autoInst=False, autoFix=False)
1260
            pkg.markInstall(autoFix=False)
665 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1261
1262
        # mark the backports for upgrade and get them
1263
        fetcher = apt_pkg.GetAcquire(self._view.getFetchProgress())
1264
        pm = apt_pkg.GetPackageManager(self.cache._depcache)
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1265
692 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1266
        # now get it
665 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1267
        try:
1268
            res = True
1269
            self.cache._fetchArchives(fetcher, pm)
1270
        except IOError, e:
902 by Michael Vogt
- improve logging if prerequisites download fails
1271
            logging.error("_fetchArchives returned '%s'" % e)
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1272
            res = False
809 by Michael Vogt
DistUpgrade/DistUpgradeController.py:
1273
902 by Michael Vogt
- improve logging if prerequisites download fails
1274
        if res == False:
1275
            logging.warning("_fetchArchives for backports returned False")
1276
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1277
        # reset the cache dir
831 by Michael Vogt
- when fetching the prerequists, be more robust in the
1278
        os.unlink(outpath)
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1279
        apt_pkg.Config.Set("Dir::Cache::archives",cachedir)
358.1.65 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1280
        os.chdir(cwd)
702 by Michael Vogt
- support pre-requists on the CD as well
1281
        return self.setupRequiredBackports(backportsdir)
1282
1283
    def setupRequiredBackports(self, backportsdir):
1284
        " setup the required backports in a evil way "
703 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
1285
        if not glob.glob(backportsdir+"/*.udeb"):
902 by Michael Vogt
- improve logging if prerequisites download fails
1286
            logging.error("no backports found in setupRequiredBackports()")
703 by Michael Vogt
DistUpgrade/DistUpgradeControler.py:
1287
            return False
702 by Michael Vogt
- support pre-requists on the CD as well
1288
        # unpack the backports first
665 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1289
        for deb in glob.glob(backportsdir+"/*.udeb"):
692 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1290
            logging.debug("extracting udeb '%s' " % deb)
665 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1291
            if os.system("dpkg-deb -x %s %s" % (deb, backportsdir)) != 0:
702 by Michael Vogt
- support pre-requists on the CD as well
1292
                return False
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1293
        # setup some paths to make sure the new stuff is used
358.1.70 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1294
        os.environ["LD_LIBRARY_PATH"] = backportsdir+"/usr/lib"
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1295
        os.environ["PYTHONPATH"] = backportsdir+"/usr/lib/python%s.%s/site-packages/" % (sys.version_info[0], sys.version_info[1])
358.1.70 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1296
        os.environ["PATH"] = "%s:%s" % (backportsdir+"/usr/bin",
693 by Michael Vogt
- add mythubuntu-desktop to the valid metapackages
1297
                                        os.environ["PATH"])
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1298
        # copy log so that it gets not overwritten
669 by Michael Vogt
* AutoUpgradeTester/*
1299
        logging.shutdown()
1300
        shutil.copy("/var/log/dist-upgrade/main.log",
1301
                    "/var/log/dist-upgrade/main_pre_req.log")
358.1.66 by Michael Vogt
* DistUpgrade/DistUpgrade.cfg:
1302
        # now exec self again
653 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1303
        args = sys.argv + ["--have-prerequists"]
358.1.73 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
1304
        if self.useNetwork:
1305
            args.append("--with-network")
1306
        else:
1307
            args.append("--without-network")
741 by Michael Vogt
- workaround kde tempdir handling (LP: #149186)
1308
        # work around kde being clever and removing the x bit
1309
        if not ((S_IMODE(os.stat(sys.argv[0])[ST_MODE]) & S_IXUSR) == S_IXUSR):
707 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
1310
            os.chmod(sys.argv[0], 0755)
358.1.73 by Michael Vogt
* DistUpgrade/dist-upgrade.py:
1311
        os.execve(sys.argv[0],args, os.environ)
358.1.100 by Michael Vogt
* DistUpgrade/DistUpgradeCache.py:
1312
932.2.3 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1313
    def preDoDistUpgrade(self):
1314
        " this runs right before apt calls out to dpkg "
1315
        # kill update-notifier now to suppress reboot required
1316
        if os.path.exists("/usr/bin/killall"):
1317
            subprocess.call(["killall","-q","update-notifier"])
1318
        # check theme, crux is known to fail badly when upgraded 
1319
        # from dapper
1320
        if (self.fromDist == "dapper" and 
1321
            "DISPLAY" in os.environ and "SUDO_USER" in os.environ):
1322
            out = subprocess.Popen(["sudo","-u", os.environ["SUDO_USER"],
1323
                                    "./theme-switch-helper.py", "-g"],
1324
                                    stdout=subprocess.PIPE).communicate()[0]
1325
            if "Crux" in out:
1326
                subprocess.call(["sudo","-u", os.environ["SUDO_USER"],
1327
                                    "./theme-switch-helper.py", "--defaults"])
1328
        return True
1329
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
1330
    # this is the core
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1331
    def fullUpgrade(self):
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1332
        # sanity check (check for ubuntu-desktop, brokenCache etc)
1333
        self._view.updateStatus(_("Checking package manager"))
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1334
        self._view.setStep(DistUpgradeView.STEP_PREPARE)
759 by Michael Vogt
- keep the GUI responsive while calculating the upgrade
1335
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1336
        if not self.prepare():
358.1.145 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1337
            logging.error("self.prepared() failed")
358.1.108 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1338
            self._view.error(_("Preparing the upgrade failed"),
1339
                             _("Preparing the system for the upgrade "
1340
                               "failed. Please report this as a bug "
1341
                               "against the 'update-manager' "
1342
                               "package and include the files in "
1343
                               "/var/log/dist-upgrade/ "
1344
                               "in the bugreport." ))
1345
            sys.exit(1)
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1346
358.1.83 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1347
        # mvo: commented out for now, see #54234, this needs to be
1348
        #      refactored to use a arch=any tarball
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1349
        if (self.config.has_section("PreRequists") and
1350
            self.options and
1351
            self.options.havePrerequists == False):
923 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1352
            logging.debug("need backports")
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1353
            # get backported packages (if needed)
1354
            if not self.getRequiredBackports():
726 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1355
                self._view.error(_("Getting upgrade prerequisites failed"),
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1356
                                 _("The system was unable to get the "
726 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1357
                                   "prerequisites for the upgrade. "
652 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1358
                                   "The upgrade will abort now and restore "
1359
                                   "the original system state.\n"
1360
                                   "\n"
1361
                                   "Please report this as a bug "
1362
                                   "against the 'update-manager' "
1363
                                   "package and include the files in "
1364
                                   "/var/log/dist-upgrade/ "
1365
                                   "in the bugreport." ))
1366
                self.abort()
358.1.63 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1367
802 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1368
        # run a "apt-get update" now, its ok to ignore errors, 
1369
        # because 
1370
        # a) we disable any third party sources later
1371
        # b) we check if we have valid ubuntu sources later
1372
        #    after we rewrite the sources.list and do a 
1373
        #    apt-get update there too
924 by Michael Vogt
- smaller default network time out
1374
        # because the (unmodified) sources.list of the user
1375
        # may contain bad/unreachable entries we run only
1376
        # with a single retry
1377
        self.doUpdate(showErrors=False, forceRetries=1)
923 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1378
        self.openCache()
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1379
1380
        # do pre-upgrade stuff (calc list of obsolete pkgs etc)
1087 by Michael Vogt
* DistUpgrade/DistUpgradeController.py,
1381
        if not self.doPostInitialUpdate():
838 by Michael Vogt
* deal with packages in broken reqreinst state by
1382
            self.abort()
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1383
1384
        # update sources.list
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1385
        self._view.setStep(DistUpgradeView.STEP_MODIFY_SOURCES)
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1386
        self._view.updateStatus(_("Updating repository information"))
1387
        if not self.updateSourcesList():
1388
            self.abort()
1389
1390
        # add cdrom (if we have one)
1391
        if (self.aptcdrom and
1392
            not self.aptcdrom.add(self.sources_backup_ext)):
1393
            sys.exit(1)
1394
1395
        # then update the package index files
1396
        if not self.doUpdate():
1397
            self.abort()
1398
1399
        # then open the cache (again)
1400
        self._view.updateStatus(_("Checking package manager"))
1401
        self.openCache()
1402
        # now check if we still have some key packages after the update
1403
        # if not something went seriously wrong
1404
        for pkg in self.config.getlist("Distro","BaseMetaPkgs"):
1405
            if not self.cache.has_key(pkg):
1406
                # FIXME: we could offer to add default source entries here,
1407
                #        but we need to be careful to not duplicate them
1408
                #        (i.e. the error here could be something else than
935 by Michael Vogt
* fix a bunch of spelling mistakes (LP: #213040), thanks
1409
                #        missing sources entries but network errors etc)
358.1.68 by Michael Vogt
* DistUpgrade/backport-source.list:
1410
                logging.error("No '%s' after sources.list rewrite+update")
1411
                self._view.error(_("Invalid package information"),
1412
                                 _("After your package information was "
1413
                                   "updated the essential package '%s' can "
1414
                                   "not be found anymore.\n"
1415
                                   "This indicates a serious error, please "
1416
                                   "report this bug against the 'update-manager' "
1417
                                   "package and include the files in /var/log/dist-upgrade/ "
1418
                                   "in the bugreport.") % pkg)
1419
                self.abort()
1420
20 by Michael Vogt
* DistUpgrade/ tool started
1421
        # calc the dist-upgrade and see if the removals are ok/expected
30 by Michael Vogt
* do update implemented
1422
        # do the dist-upgrade
758 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py,:
1423
        self._view.updateStatus(_("Calculating the changes"))
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
1424
        if not self.askDistUpgrade():
90 by Michael Vogt
* on problems call "abort" and restore the old sources.list
1425
            self.abort()
123.1.5 by Sebastian Heinlein
* show the update dialog on the center of the screen
1426
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1427
        # fetch the stuff
1428
        self._view.setStep(DistUpgradeView.STEP_FETCH)
1429
        self._view.updateStatus(_("Fetching"))
1430
        if not self.doDistUpgradeFetching():
1431
            self.abort()
1432
1433
        # now do the upgrade
932.2.3 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1434
        self.preDoDistUpgrade()
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1435
        self._view.setStep(DistUpgradeView.STEP_INSTALL)
498 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1436
        self._view.updateStatus(_("Upgrading"))
290 by Michael Vogt
* activate the actual upgrading again :)
1437
        if not self.doDistUpgrade():
883 by Michael Vogt
- run migrate-fstab-to-uuid.sh as PostInstallScript (LP: #209347)
1438
            # run the post install scripts (for stuff like UUID conversion)
1439
            self.runPostInstallScripts()
290 by Michael Vogt
* activate the actual upgrading again :)
1440
            # don't abort here, because it would restore the sources.list
988 by Michael Vogt
do not just exit on upgrades with errors but show
1441
            self._view.information(_("Upgrade complete"),
1442
                                   _("The upgrade is completed but there "
1443
                                     "were errors during the ugprade "
1444
                                     "process."))
290 by Michael Vogt
* activate the actual upgrading again :)
1445
            sys.exit(1) 
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
1446
            
20 by Michael Vogt
* DistUpgrade/ tool started
1447
        # do post-upgrade stuff
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1448
        self._view.setStep(DistUpgradeView.STEP_CLEANUP)
148 by Michael Vogt
* retry automatically on network problems
1449
        self._view.updateStatus(_("Searching for obsolete software"))
39 by Michael Vogt
* added the missing bits, can do a complete upgrade now! butt ugly though :/
1450
        self.doPostUpgrade()
20 by Michael Vogt
* DistUpgrade/ tool started
1451
1452
        # done, ask for reboot
638 by Michael Vogt
* Separate downloading and upgrading (Fixes LP: #108515)
1453
        self._view.setStep(DistUpgradeView.STEP_REBOOT)
123.1.6 by Sebastian Heinlein
* Merged from Michael
1454
        self._view.updateStatus(_("System upgrade is complete."))            
130 by Michael Vogt
* forced_obsoletes added
1455
        # FIXME should we look into /var/run/reboot-required here?
129 by Michael Vogt
* merged sebastians changes
1456
        if self._view.confirmRestart():
464 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1457
            p = subprocess.Popen("/sbin/reboot")
1458
            sys.exit(0)
30 by Michael Vogt
* do update implemented
1459
        
20 by Michael Vogt
* DistUpgrade/ tool started
1460
    def run(self):
759 by Michael Vogt
- keep the GUI responsive while calculating the upgrade
1461
        self._view.processEvents()
445 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1462
        self.fullUpgrade()
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
1463
    
1464
    def doPartialUpgrade(self):
1465
        " partial upgrade mode, useful for repairing "
1466
        from DistUpgrade.DistUpgradeView import STEP_PREPARE, STEP_MODIFY_SOURCES, STEP_FETCH, STEP_INSTALL, STEP_CLEANUP, STEP_REBOOT
1467
        self._view.setStep(STEP_PREPARE)
1468
        self._view.hideStep(STEP_MODIFY_SOURCES)
1469
        self._view.hideStep(STEP_REBOOT)
1470
        self._partialUpgrade = True
1471
        self.prepare()
1087 by Michael Vogt
* DistUpgrade/DistUpgradeController.py,
1472
        if not self.doPostInitialUpdate():
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
1473
            return False
1474
        if not self.askDistUpgrade():
1475
            return False
1476
        self._view.setStep(STEP_FETCH)
1477
        self._view.updateStatus(_("Fetching"))
1478
        if not self.doDistUpgradeFetching():
1479
            return False
1480
        self._view.setStep(STEP_INSTALL)
1481
        self._view.updateStatus(_("Upgrading"))
1482
        if not self.doDistUpgrade():
1107 by Michael Vogt
* DistUpgrade/DistUpgradeViewGtk.py:
1483
            self._view.information(_("Upgrade complete"),
1484
                                   _("The upgrade is completed but there "
1485
                                     "were errors during the ugprade "
1486
                                     "process."))
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
1487
            return False
1488
        self._view.setStep(STEP_CLEANUP)
1489
        if not self.doPostUpgrade():
1107 by Michael Vogt
* DistUpgrade/DistUpgradeViewGtk.py:
1490
            self._view.information(_("Upgrade complete"),
1491
                                   _("The upgrade is completed but there "
1492
                                     "were errors during the ugprade "
1493
                                     "process."))
946 by Michael Vogt
* update-manager-core.install, update-manager.install:
1494
            return False
1495
        self._view.information(_("Upgrade complete"),
1496
                               _("The partial upgrade was completed."))
1497
        return True
20 by Michael Vogt
* DistUpgrade/ tool started
1498
1079 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1499
403 by Michael Vogt
* DistUpgrade/DistUpgradeControler.py:
1500
if __name__ == "__main__":
1501
    from DistUpgradeView import DistUpgradeView
782 by Michael Vogt
DistUpgrade/DistUpgradeCache.py:
1502
    from DistUpgradeViewText import DistUpgradeViewText
530 by Michael Vogt
* fix race condition in free space checking (LP#96482), thanks
1503
    from DistUpgradeCache import MyCache
1115 by Michael Vogt
DistUpgrade/DistUpgradeController.py: add logging to enable/disable apt cron
1504
    logging.basicConfig(level=logging.DEBUG)
782 by Michael Vogt
DistUpgrade/DistUpgradeCache.py:
1505
    v = DistUpgradeViewText()
749 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1506
    dc = DistUpgradeController(v)
1050 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1507
    #dc.openCache()
1115 by Michael Vogt
DistUpgrade/DistUpgradeController.py: add logging to enable/disable apt cron
1508
    dc._disableAptCronJob()
1509
    dc._enableAptCronJob()
1510
    #dc._addRelatimeToFstab()
1050 by Michael Vogt
* DistUpgrade/DistUpgradeController.py:
1511
    #dc.prepare()
1512
    #dc.askDistUpgrade()
554 by Michael Vogt
- rewrite /etc/fstab cdrom entries (LP#86424,#79327)
1513
    #dc._checkFreeSpace()
556 by Michael Vogt
- fix upgrade for people with no admin group (LP#93279)
1514
    #dc._rewriteFstab()
597 by Michael Vogt
- increase minAge for the apt cleanup cron job during the upgrade
1515
    #dc._checkAdminGroup()
1516
    #dc._rewriteAptPeriodic(2)