check-new-release 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/usr/bin/python3
  2. from __future__ import print_function
  3. import warnings
  4. warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
  5. from DistUpgrade.DistUpgradeVersion import VERSION
  6. from DistUpgrade.DistUpgradeGettext import gettext as _
  7. from UpdateManager.Core.MetaRelease import MetaReleaseCore
  8. from optparse import OptionParser
  9. import locale
  10. import gettext
  11. import apt
  12. import os
  13. import subprocess
  14. import sys
  15. import time
  16. from UpdateManager.Core.utils import init_proxy
  17. RELEASE_AVAILABLE=0
  18. NO_RELEASE_AVAILABLE=1
  19. def get_fetcher(frontend, new_dist, datadir):
  20. if frontend == "DistUpgradeViewGtk3":
  21. from DistUpgrade.DistUpgradeFetcher import DistUpgradeFetcherGtk
  22. from DistUpgrade.GtkProgress import GtkAcquireProgress
  23. progress = GtkAcquireProgress(
  24. None,
  25. datadir,
  26. _("Downloading the release upgrade tool"))
  27. return DistUpgradeFetcherGtk(new_dist=new_dist,
  28. progress=progress,
  29. parent=None,
  30. datadir=datadir)
  31. elif frontend == "DistUpgradeViewKDE":
  32. print("kde")
  33. from DistUpgrade.DistUpgradeFetcherKDE import DistUpgradeFetcherKDE
  34. from DistUpgrade.DistUpgradeFetcherKDE import KDEAcquireProgressAdapter
  35. progress = KDEAcquireProgressAdapter(
  36. parent=None,
  37. datadir=datadir,
  38. label=_("Downloading the release upgrade tool"))
  39. return DistUpgradeFetcherKDE(new_dist=new_dist,
  40. progress=progress,
  41. parent=None,
  42. datadir=datadir)
  43. else:
  44. from DistUpgrade.DistUpgradeFetcherCore import DistUpgradeFetcherCore
  45. import apt
  46. progress = apt.progress.text.AcquireProgress()
  47. return DistUpgradeFetcherCore(new_dist, progress)
  48. if __name__ == "__main__":
  49. #FIXME: Workaround a bug in optparser which doesn't handle unicode/str
  50. # correctly, see http://bugs.python.org/issue4391
  51. # Should be resolved by Python3
  52. gettext.bindtextdomain("ubuntu-release-upgrader", "/usr/share/locale")
  53. gettext.textdomain("ubuntu-release-upgrader")
  54. translation = gettext.translation("ubuntu-release-upgrader", fallback=True)
  55. try:
  56. locale.setlocale(locale.LC_ALL, "")
  57. except:
  58. pass
  59. init_proxy()
  60. # when run as "check-new-release" we go into "check only" mode
  61. check_only = sys.argv[0].endswith("check-new-release")
  62. parser = OptionParser()
  63. parser.add_option ("-V", "--version", action="store_true",
  64. dest="show_version", default=False,
  65. help=_("Show version and exit"))
  66. parser.add_option ("-d", "--devel-release", action="store_true",
  67. dest="devel_release", default=False,
  68. help=_("If using the latest supported release, "
  69. "upgrade to the development release"))
  70. parser.add_option ("--data-dir", "",
  71. default="/usr/share/ubuntu-release-upgrader/",
  72. help=_("Directory that contains the data files"))
  73. parser.add_option ("-p", "--proposed", action="store_true",
  74. dest="proposed_release", default=False,
  75. help=_("Try upgrading to the latest release using "
  76. "the upgrader from $distro-proposed"))
  77. parser.add_option ("-m", "--mode", default="server",
  78. dest="mode",
  79. help=_("Run in a special upgrade mode.\n"
  80. "Currently 'desktop' for regular upgrades of "
  81. "a desktop system and 'server' for server "
  82. "systems are supported."))
  83. parser.add_option ("-f", "--frontend", default="DistUpgradeViewText",
  84. dest="frontend",
  85. help=_("Run the specified frontend"))
  86. parser.add_option ("-c", "--check-dist-upgrade-only", action="store_true",
  87. default=check_only,
  88. help=_("Check only if a new distribution release is "
  89. "available and report the result via the "
  90. "exit code"))
  91. parser.add_option ("--allow-third-party", default=False,
  92. action="store_true", dest="allow_third_party",
  93. help=_("Try the upgrade with third party "
  94. "mirrors and repositories enabled "
  95. "instead of commenting them out."))
  96. parser.add_option ("-q", "--quiet", default=False, action="store_true",
  97. dest="quiet")
  98. (options, args) = parser.parse_args()
  99. if options.show_version:
  100. print("%s: version %s" % (os.path.basename(sys.argv[0]), VERSION))
  101. sys.exit(0)
  102. if options.devel_release and options.proposed_release:
  103. print(_("The options --devel-release and --proposed are"))
  104. print(_("mutually exclusive. Please use only one of them."))
  105. sys.exit(1)
  106. if not options.quiet:
  107. print(_("Checking for a new Ubuntu release"))
  108. m = MetaReleaseCore(useDevelopmentRelease=options.devel_release,
  109. useProposed=options.proposed_release)
  110. # this will timeout eventually
  111. m.downloaded.wait()
  112. # make sure to inform the user if his distro is no longer supported
  113. # this will make it appear in motd (that calls do-release-upgrade in
  114. # check-new-release mode)
  115. if m.no_longer_supported is not None:
  116. url = "http://www.ubuntu.com/releaseendoflife"
  117. print(_("Your Ubuntu release is not supported anymore."))
  118. print(_("For upgrade information, please visit:\n"
  119. "%(url)s\n") % { 'url' : url })
  120. # now inform about a new release
  121. if m.new_dist is None:
  122. if not options.quiet:
  123. if m.prompt == 'never':
  124. print(_("In /etc/update-manager/release-upgrades Prompt "))
  125. print(_("is set to never so upgrading is not possible."))
  126. elif m.prompt == 'lts':
  127. print(_("There is no development version of an LTS available."))
  128. print(_("To upgrade to the latest non-LTS development release "))
  129. print(_("set Prompt=normal in /etc/update-manager/release-upgrades."))
  130. elif options.devel_release:
  131. print(_("Upgrades to the development release are only "))
  132. print(_("available from the latest supported release."))
  133. else:
  134. print(_("No new release found."))
  135. sys.exit(NO_RELEASE_AVAILABLE)
  136. if m.new_dist.upgrade_broken:
  137. if not options.quiet:
  138. print(_("Release upgrade not possible right now"))
  139. print(_("The release upgrade can not be performed currently, "
  140. "please try again later. The server reported: '%s'") % m.new_dist.upgrade_broken)
  141. sys.exit(NO_RELEASE_AVAILABLE)
  142. # we have a new dist
  143. if options.check_dist_upgrade_only:
  144. print(_("New release '%s' available.") % m.new_dist.version)
  145. print(_("Run 'do-release-upgrade' to upgrade to it."))
  146. sys.exit(RELEASE_AVAILABLE)
  147. cache = apt.Cache()
  148. cache.open()
  149. install_count = 0
  150. upgradable = [pkg for pkg in cache if pkg.is_upgradable]
  151. for pkg in upgradable:
  152. if 'Phased-Update-Percentage' in pkg.candidate.record:
  153. # P-U-P does not exist if it is fully phased
  154. continue
  155. else:
  156. install_count += 1
  157. # one upgradeable package is enough to stop the dist-upgrade
  158. break
  159. if install_count > 0:
  160. if not options.quiet:
  161. print(_("Please install all available updates "
  162. "for your release before upgrading."))
  163. sys.exit(1)
  164. if os.path.exists('/var/run/reboot-required.pkgs'):
  165. reboot = False
  166. with open('/var/run/reboot-required.pkgs', 'rb') as f:
  167. for line in f:
  168. # In certain cases, we need to reboot the system before proceeding
  169. # with the dist upgrade after the kernel is upgraded as otherwise
  170. # building of some dkms modules can fail.
  171. if (line == b'libc6\n' or line == b'linux-base\n' or
  172. line.startswith(b'linux-image-')):
  173. reboot = True
  174. break
  175. if reboot:
  176. if not options.quiet:
  177. print(_("You have not rebooted after updating a package which "
  178. "requires a reboot. Please reboot before upgrading."))
  179. sys.exit(1)
  180. if options.allow_third_party:
  181. # the env variable is used by code in the dist-upgrader tarball
  182. os.environ["RELEASE_UPGRADER_ALLOW_THIRD_PARTY"] = "True"
  183. # GTK 3 fetcher starts setting up the the GUI and KDE GUI needs to start GUI
  184. # later, too.
  185. if (options.frontend in {"DistUpgradeViewGtk3", "DistUpgradeViewKDE"} and
  186. os.getuid() != 0):
  187. if 'WAYLAND_DISPLAY' in os.environ:
  188. subprocess.run(['xhost', '+si:localuser:root'])
  189. # this is needed because pkexec doesn't pass on the env
  190. if 'RELEASE_UPGRADER_ALLOW_THIRD_PARTY' in os.environ:
  191. sys.argv.append('--allow-third-party')
  192. os.execv("/usr/bin/pkexec", ["pkexec"] + sys.argv)
  193. fetcher = get_fetcher(options.frontend, m.new_dist, options.data_dir)
  194. fetcher.run_options += ["--mode=%s" % options.mode,
  195. "--frontend=%s" % options.frontend,
  196. ]
  197. if options.devel_release:
  198. fetcher.run_options.append("--devel-release")
  199. fetcher.run()