self._view.error(_('Unable to get exclusive lock'), _('This usually means that another package management application (like apt-get or aptitude) already running. Please close that application first.'))
sys.exit(1)
self.cache.partialUpgrade = self._partialUpgrade
logging.debug('/openCache()')
def _isRemoteLogin(self):
''' check if we are running form a remote login '''
if os.environ.has_key('SSH_CONNECTION') or os.environ.has_key('SSH_TTY'):
if not os.path.exists(pidfile) and self._isRemoteLogin():
if not self._viewSupportsSSH():
logging.error('upgrade over ssh not alllowed')
self._view.error(_('Upgrading over remote connection not supported'), _('You are running the upgrade over a remote ssh connection with a frontend that does not support this. The upgrade will abort now. Please try without ssh.'))
sys.exit(1)
return False
port = 9004
res = self._view.askYesNoQuestion(_('Continue running under SSH?'), _("This session appears to be running under ssh. It is not recommended to perform a upgrade over ssh currently because in case of failure it is harder to recover.\n\nIf you continue, a additional ssh daemon will be started at port '%s'.\nDo you want to continue?") % port)
if res == False:
sys.exit(1)
res = subprocess.call([
'/usr/sbin/sshd',
'-o',
'PidFile=%s' % pidfile,
'-p',
str(port)])
if res == 0:
self._view.information(_('Starting additional sshd'), _("To make recovery in case of failure easier, an additional sshd will be started on port '%s'. If anything goes wrong with the running ssh you can still connect to the additional one.\n") % port)
return True
def _tryUpdateSelf(self):
''' this is a helper that is run if we are started from a CD
and we have network - we will then try to fetch a update
of ourself
'''
MetaReleaseCore = MetaReleaseCore
import MetaRelease
DistUpgradeFetcherSelf = DistUpgradeFetcherSelf
import DistUpgradeFetcherSelf
forceLTS = False
if self.release == 'dapper' or self.release == 'hardy':
forceLTS = True
m = MetaReleaseCore(useDevelopmentRelease = False, forceLTS = forceLTS)
if fs_default_version not in (expected_default, os.path.join('/usr/bin', expected_default)):
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)))
self._view.error(_('Can not upgrade'), _("An upgrade from '%s' to '%s' is not supported with this tool." % (release, self.toDist)))
sys.exit(1)
if self.config.getWithDefault('Aufs', 'EnableFullOverlay', False):
aufs_rw_dir = self.config.get('Aufs', 'RWDir')
if not setupAufs(aufs_rw_dir):
logging.error('aufs setup failed')
self._view.error(_('Sandbox setup failed'), _('It was not possible to create the sandbox environment.'))
return False
logging.info('running in aufs overlay mode')
self._view.information(_('Sandbox mode'), _("This upgrade is running in sandbox (test) mode. All changes are written to '%s' and will be lost on the next reboot.\n\n*No* changes written to a systemdir from now until the next reboot are permanent.") % aufs_rw_dir)
if self.options and self.options.havePrerequists:
backportsdir = os.getcwd() + '/backports'
logging.info("using backports in '%s' " % backportsdir)
self._view.error(_('Can not upgrade'), _("Your python install is corrupted. Please fix the '/usr/bin/python' symlink."))
sys.exit(1)
try:
self.openCache()
except SystemError:
e = None
logging.error("openCache() failed: '%s'" % e)
return False
if not self.cache.sanityCheck(self._view):
return False
self.serverMode = self.cache.needServerMode()
if self.serverMode:
os.environ['RELEASE_UPGRADE_MODE'] = 'server'
else:
os.environ['RELEASE_UPGRADE_MODE'] = 'desktop'
if not self.checkViewDepends():
logging.error('checkViewDepends() failed')
return False
if os.path.exists('/usr/bin/debsig-verify'):
logging.error('debsig-verify is installed')
self._view.error(_("Package 'debsig-verify' is installed"), _("The upgrade can not continue with that package installed.\nPlease remove it with synaptic or 'apt-get remove debsig-verify' first and run the upgrade again."))
self.abort()
if self.aptcdrom and self.options and self.options.withNetwork == None:
res = self._view.askYesNoQuestion(_('Include latest updates from the Internet?'), _("The upgrade system can use the internet to automatically download the latest updates and install them during the upgrade. If you have a network connection this is highly recommended.\n\nThe upgrade will take longer, but when it is complete, your system will be fully up to date. You can choose not to do this, but you should install the latest updates soon after upgrading.\nIf you answer 'no' here, the network is not used at all."), 'Yes')
if self.config.getWithDefault('Sources', 'AllowThirdParty', False) or 'RELEASE_UPRADER_ALLOW_THIRD_PARTY' in os.environ:
logging.warning('mirror check skipped, *overriden* via config')
mirror_check = False
if mirror_check == True and self.useNetwork:
for pkgname in self.config.getlist('Distro', 'BaseMetaPkgs'):
if (not self.cache.has_key(pkgname) or len(self.cache[pkgname].candidateOrigin) == 0 or len(self.cache[pkgname].candidateOrigin) == 1) and self.cache[pkgname].candidateOrigin[0].archive == 'now':
logging.debug("BaseMetaPkg '%s' has no candidateOrigin" % pkgname)
try:
distro = get_distro()
distro.get_sources(self.sources)
distro.enable_component('main')
except NoDistroTemplateException:
e = None
logging.warning('get_distro().enable_component("man") failed, overwriting sources.list instead as last resort')
s = '# auto generated by update-manager'
s += 'deb http://archive.ubuntu.com/ubuntu %s main restricted' % self.toDist
s += 'deb http://archive.ubuntu.com/ubuntu %s-updates main restricted' % self.toDist
s += 'deb http://security.ubuntu.com/ubuntu %s-security main restricted' % self.toDist
open('/etc/apt/sources.list', 'w').write(s)
break
continue
fromDists = [
self.fromDist,
self.fromDist + '-security',
self.fromDist + '-updates',
self.fromDist + '-proposed',
self.fromDist + '-backports']
toDists = [
self.toDist,
self.toDist + '-security',
self.toDist + '-updates',
self.toDist + '-proposed',
self.toDist + '-backports']
self.sources_disabled = False
foundToDist = False
found_components = { }
for entry in self.sources.list[:]:
if entry.invalid or entry.disabled:
continue
if entry.uri.startswith('cdrom:') and entry.dist == self.fromDist:
entry.disabled = True
continue
elif entry.uri.startswith('cdrom:'):
continue
cdist = '%s-commercial' % self.fromDist
if not (entry.disabled) and entry.uri.startswith('http://archive.canonical.com') and entry.dist == cdist:
entry.dist = self.toDist
entry.comps = [
'partner']
logging.debug("transitioned commercial to '%s' " % entry)
continue
if not (entry.disabled) and entry.uri.startswith('http://landscape.canonical.com/packages/%s' % self.fromDist):
if self._sourcesListEntryDownloadable(test_entry):
logging.info('transition from old-release.u.c to %s' % uri)
entry.uri = uri
break
continue
logging.debug("examining: '%s'" % entry)
validMirror = self.isMirror(entry.uri)
if validMirror or not mirror_check:
validMirror = True
validTo = True
if entry.disabled and entry.type == 'deb-src' and entry.uri.startswith('http://security.ubuntu.com') or entry.uri.startswith('http://archive.canonical.com'):
validTo = False
if entry.dist in toDists:
logging.debug("entry '%s' is already set to new dist" % entry)
foundToDist |= validTo
elif entry.dist in fromDists:
foundToDist |= validTo
entry.dist = toDists[fromDists.index(entry.dist)]
logging.debug("entry '%s' updated to new dist" % entry)
else:
entry.disabled = True
self.sources_disabled = True
logging.debug("entry '%s' was disabled (unknown dist)" % entry)
if entry.type == 'deb' and 'ports.ubuntu.com' not in entry.uri:
if self.arch == 'powerpc' or self.arch == 'sparc':
logging.debug("moving %s source entry to 'ports.ubuntu.com' " % self.arch)
if not self.rewriteSourcesList(mirror_check = True):
logging.error('No valid mirror found')
res = self._view.askYesNoQuestion(_('No valid mirror found'), _("While scanning your repository information no mirror entry for the upgrade was found.This can happen if you run a internal mirror or if the mirror information is out of date.\n\nDo you want to rewrite your 'sources.list' file anyway? If you choose 'Yes' here it will update all '%s' to '%s' entries.\nIf you select 'no' the update will cancel.") % (self.fromDist, self.toDist))
if res:
self.sources = SourcesList(matcherPath = '.')
if not self.rewriteSourcesList(mirror_check = False) and self.useNetwork:
prim = _('Generate default sources?')
secon = _("After scanning your 'sources.list' no valid entry for '%s' was found.\n\nShould default entries for '%s' be added? If you select 'No', the update will cancel.") % (self.fromDist, self.toDist)
logging.error('Repository information invalid after updating (we broke it!)')
self._view.error(_('Repository information invalid'), _('Upgrading the repository information resulted in a invalid file. Please report this as a bug.'))
return False
if self.sources_disabled:
self._view.information(_('Third party sources disabled'), _("Some third party entries in your sources.list were disabled. You can re-enable them after the upgrade with the 'software-properties' tool or your package manager."))
return True
def _logChanges(self):
logging.debug('About to apply the following changes')
inst = []
up = []
rm = []
held = []
keep = []
for pkg in self.cache:
if pkg.markedInstall:
inst.append(pkg.name)
continue
if pkg.markedUpgrade:
up.append(pkg.name)
continue
if pkg.markedDelete:
rm.append(pkg.name)
continue
if pkg.isInstalled and pkg.isUpgradable:
held.append(pkg.name)
continue
if pkg.isInstalled and pkg.markedKeep:
keep.append(pkg.name)
continue
logging.debug('Keep at same version: %s' % ' '.join(keep))
logging.debug('Upgradable, but held- back: %s' % ' '.join(held))
logging.debug('Remove: %s' % ' '.join(rm))
logging.debug('Install: %s' % ' '.join(inst))
logging.debug('Upgrade: %s' % ' '.join(up))
def doPostInitialUpdate(self):
logging.debug('doPostInitialUpdate')
if not self._partialUpgrade:
self.quirks.run('PostInitialUpdate')
if len(self.cache.reqReinstallPkgs) > 0:
logging.warning('packages in reqReinstall state, trying to fix')
self.cache.fixReqReinst(self._view)
self.openCache()
if len(self.cache.reqReinstallPkgs) > 0:
reqreinst = self.cache.reqReinstallPkgs
header = ngettext('Package in inconsistent state', 'Packages in inconsistent state', len(reqreinst))
summary = ngettext("The package '%s' is in an inconsistent state and needs to be reinstalled, but no archive can be found for it. Please reinstall the package manually or remove it from the system.", "The packages '%s' are in an inconsistent state and need to be reinstalled, but no archive can be found for them. Please reinstall the packages manually or remove them from the system.", len(reqreinst)) % ', '.join(reqreinst)
logging.error("IOError/SystemError in cache.update(): '%s'. Retrying (currentRetry: %s)" % (e, currentRetry))
currentRetry += 1
continue
return True
logging.error('doUpdate() failed completely')
if showErrors:
self._view.error(_('Error during update'), _('A problem occurred during the update. This is usually some sort of network problem, please check your network connection and retry.'), '%s' % e)
return False
def _checkFreeSpace(self):
''' this checks if we have enough free space on /var and /usr'''
err_sum = _('Not enough free disk space')
err_long = _("The upgrade is now aborted. The upgrade needs a total of %s free space on disk '%s'. Please free at least an additional %s of disk space on '%s'. Empty your trash and remove temporary packages of former installations using 'sudo apt-get clean'.")
if self.config.getWithDefault('FreeSpace', 'SkipCheck', False):
logging.warning('free space check skipped via config override')
logging.error("IOError in cache.commit(): '%s'. Retrying (currentTry: %s)" % (e, currentRetry))
currentRetry += 1
continue
return True
logging.error('giving up on fetching after maximum retries')
self._view.error(_('Could not download the upgrades'), _('The upgrade is now aborted. Please check your Internet connection or installation media and try again. All files downloaded so far are kept.'), '%s' % e)
self._view.error(_('Could not install the upgrades'), msg)
self.abort()
continue
msg = _('The upgrade is now aborted. Your system could be in an unusable state. A recovery will run now (dpkg --configure -a).')
if not self._partialUpgrade:
if not run_apport():
msg += _("\n\nPlease report this bug against the 'update-manager' package and include the files in /var/log/dist-upgrade/ in the bug report.\n%s" % e)
self._view.error(_('Could not install the upgrades'), msg)
self._view.getTerminal().call([
'dpkg',
'--configure',
'-a'])
self._enableAptCronJob()
return False
except IOError:
e = None
logging.error("IOError in cache.commit(): '%s'. Retrying (currentTry: %s)" % (e, currentRetry))
currentRetry += 1
continue
except:
None<EXCEPTION MATCH>IOError
self._enableAptCronJob()
return True
logging.error('giving up on fetching after maximum retries')
self._view.error(_('Could not download the upgrades'), _('The upgrade is now aborted. Please check your Internet connection or installation media and try again. '), '%s' % e)
''' get sources.list snippet lines for the current mirror '''
lines = ''
sources = SourcesList(matcherPath = '.')
for entry in sources.list:
if entry.invalid or entry.disabled:
continue
if entry.type == 'deb' and self.isMirror(entry.uri) and not entry.uri.startswith('http://security.ubuntu.com') and not entry.uri.startswith('http://archive.ubuntu.com'):
self._view.error(_('Preparing the upgrade failed'), _("Preparing the system for the upgrade failed. Please report this as a bug against the 'update-manager' package and include the files in /var/log/dist-upgrade/ in the bug report."))
sys.exit(1)
if self.config.has_section('PreRequists') and self.options and self.options.havePrerequists == False:
logging.debug('need backports')
if not self.getRequiredBackports():
self._view.error(_('Getting upgrade prerequisites failed'), _("The system was unable to get the prerequisites for the upgrade. The upgrade will abort now and restore the original system state.\n\nPlease report this as a bug against the 'update-manager' package and include the files in /var/log/dist-upgrade/ in the bug report."))
for pkg in self.config.getlist('Distro', 'BaseMetaPkgs'):
if not self.cache.has_key(pkg):
logging.error("No '%s' after sources.list rewrite+update" % pkg)
self._view.error(_('Invalid package information'), _("After your package information was updated the essential package '%s' can not be found anymore.\nThis indicates a serious error, please report this bug against the 'update-manager' package and include the files in /var/log/dist-upgrade/ in the bug report.") % pkg)
self.abort()
continue
self._view.updateStatus(_('Calculating the changes'))
if not self.askDistUpgrade():
self.abort()
self._view.setStep(DistUpgradeView.STEP_FETCH)
self._view.updateStatus(_('Fetching'))
if not self.doDistUpgradeFetching():
self.abort()
self.preDoDistUpgrade()
self._view.setStep(DistUpgradeView.STEP_INSTALL)
self._view.updateStatus(_('Upgrading'))
if not self.doDistUpgrade():
self.runPostInstallScripts()
self._view.information(_('Upgrade complete'), _('The upgrade is completed but there were errors during the upgrade process.'))
sys.exit(1)
self._view.setStep(DistUpgradeView.STEP_CLEANUP)
self._view.updateStatus(_('Searching for obsolete software'))
self.doPostUpgrade()
self._view.setStep(DistUpgradeView.STEP_REBOOT)
self._view.updateStatus(_('System upgrade is complete.'))
if self._view.confirmRestart():
p = subprocess.Popen('/sbin/reboot')
sys.exit(0)
def run(self):
self._view.processEvents()
self.fullUpgrade()
def doPartialUpgrade(self):
''' partial upgrade mode, useful for repairing '''
STEP_PREPARE = STEP_PREPARE
STEP_MODIFY_SOURCES = STEP_MODIFY_SOURCES
STEP_FETCH = STEP_FETCH
STEP_INSTALL = STEP_INSTALL
STEP_CLEANUP = STEP_CLEANUP
STEP_REBOOT = STEP_REBOOT
import DistUpgrade.DistUpgradeView
self._view.setStep(STEP_PREPARE)
self._view.hideStep(STEP_MODIFY_SOURCES)
self._view.hideStep(STEP_REBOOT)
self._partialUpgrade = True
self.prepare()
if not self.doPostInitialUpdate():
return False
if not self.askDistUpgrade():
return False
self._view.setStep(STEP_FETCH)
self._view.updateStatus(_('Fetching'))
if not self.doDistUpgradeFetching():
return False
self._view.setStep(STEP_INSTALL)
self._view.updateStatus(_('Upgrading'))
if not self.doDistUpgrade():
self._view.information(_('Upgrade complete'), _('The upgrade is completed but there were errors during the upgrade process.'))
return False
self._view.setStep(STEP_CLEANUP)
if not self.doPostUpgrade():
self._view.information(_('Upgrade complete'), _('The upgrade is completed but there were errors during the upgrade process.'))
return False
self._view.information(_('Upgrade complete'), _('The partial upgrade was completed.'))
return True
if __name__ == '__main__':
from DistUpgradeView import DistUpgradeView
from DistUpgradeViewText import DistUpgradeViewText