~ubuntu-core-dev/ubuntu/eoan/ubuntu-release-upgrader/eoan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/python3

from __future__ import print_function

import warnings
warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)

from DistUpgrade.DistUpgradeVersion import VERSION
from DistUpgrade.DistUpgradeGettext import gettext as _

from UpdateManager.Core.MetaRelease import MetaReleaseCore
from optparse import OptionParser
import locale
import gettext

import apt
import os
import subprocess
import sys
import time
from UpdateManager.Core.utils import init_proxy

RELEASE_AVAILABLE=0
NO_RELEASE_AVAILABLE=1


def get_fetcher(frontend, new_dist, datadir):
    if frontend == "DistUpgradeViewGtk3":
        from DistUpgrade.DistUpgradeFetcher import DistUpgradeFetcherGtk
        from DistUpgrade.GtkProgress import GtkAcquireProgress
        progress = GtkAcquireProgress(
            None,
            datadir,
            _("Downloading the release upgrade tool"))
        return DistUpgradeFetcherGtk(new_dist=new_dist,
                                     progress=progress,
                                     parent=None,
                                     datadir=datadir)
    elif frontend == "DistUpgradeViewKDE":
        print("kde")
        from DistUpgrade.DistUpgradeFetcherKDE import DistUpgradeFetcherKDE
        from DistUpgrade.DistUpgradeFetcherKDE import KDEAcquireProgressAdapter
        progress = KDEAcquireProgressAdapter(
            parent=None,
            datadir=datadir,
            label=_("Downloading the release upgrade tool"))
        return DistUpgradeFetcherKDE(new_dist=new_dist,
                                     progress=progress,
                                     parent=None,
                                     datadir=datadir)
    else:
        from DistUpgrade.DistUpgradeFetcherCore import DistUpgradeFetcherCore
        import apt
        progress = apt.progress.text.AcquireProgress()
        return DistUpgradeFetcherCore(new_dist, progress)


if __name__ == "__main__":

  #FIXME: Workaround a bug in optparser which doesn't handle unicode/str
  #       correctly, see http://bugs.python.org/issue4391
  #       Should be resolved by Python3
  gettext.bindtextdomain("ubuntu-release-upgrader", "/usr/share/locale")
  gettext.textdomain("ubuntu-release-upgrader")
  translation = gettext.translation("ubuntu-release-upgrader", fallback=True)

  try:
    locale.setlocale(locale.LC_ALL, "")
  except:
    pass

  init_proxy()

  # when run as "check-new-release" we go into "check only" mode
  check_only = sys.argv[0].endswith("check-new-release")

  parser = OptionParser()
  parser.add_option ("-V", "--version", action="store_true",
                     dest="show_version", default=False,
                     help=_("Show version and exit"))
  parser.add_option ("-d", "--devel-release", action="store_true",
                     dest="devel_release", default=False,
                     help=_("If using the latest supported release, "
                            "upgrade to the development release"))
  parser.add_option ("--data-dir", "",
                     default="/usr/share/ubuntu-release-upgrader/",
                     help=_("Directory that contains the data files"))
  parser.add_option ("-p", "--proposed", action="store_true",
                     dest="proposed_release", default=False,
                     help=_("Try upgrading to the latest release using "
                            "the upgrader from $distro-proposed"))
  parser.add_option ("-m", "--mode", default="server",
                     dest="mode", 
                     help=_("Run in a special upgrade mode.\n"
                            "Currently 'desktop' for regular upgrades of "
                            "a desktop system and 'server' for server "
                            "systems are supported."))
  parser.add_option ("-f", "--frontend", default="DistUpgradeViewText",
                     dest="frontend", 
                     help=_("Run the specified frontend"))
  parser.add_option ("-c", "--check-dist-upgrade-only", action="store_true",
                     default=check_only,
                     help=_("Check only if a new distribution release is "
                            "available and report the result via the "
                            "exit code"))
  parser.add_option ("--allow-third-party", default=False,
                     action="store_true", dest="allow_third_party",
                     help=_("Try the upgrade with third party "
                            "mirrors and repositories enabled "
                            "instead of commenting them out."))
  parser.add_option ("-q", "--quiet", default=False, action="store_true",
                     dest="quiet")

  (options, args) = parser.parse_args()


  if options.show_version:
    print("%s: version %s" % (os.path.basename(sys.argv[0]), VERSION))
    sys.exit(0)

  if options.devel_release and options.proposed_release:
    print(_("The options --devel-release and --proposed are"))
    print(_("mutually exclusive. Please use only one of them."))
    sys.exit(1)

  if not options.quiet:
    print(_("Checking for a new Ubuntu release"))

  m = MetaReleaseCore(useDevelopmentRelease=options.devel_release,
                      useProposed=options.proposed_release)
  # this will timeout eventually
  m.downloaded.wait()

  # make sure to inform the user if his distro is no longer supported
  # this will make it appear in motd (that calls do-release-upgrade in
  #  check-new-release mode)
  if m.no_longer_supported is not None:
    url = "http://www.ubuntu.com/releaseendoflife"
    print(_("Your Ubuntu release is not supported anymore."))
    print(_("For upgrade information, please visit:\n"
            "%(url)s\n") % { 'url' : url })

  # now inform about a new release
  if m.new_dist is None:
    if not options.quiet:
      if m.prompt == 'never':
        print(_("In /etc/update-manager/release-upgrades Prompt "))
        print(_("is set to never so upgrading is not possible."))
      elif m.prompt == 'lts':
        print(_("There is no development version of an LTS available."))
        print(_("To upgrade to the latest non-LTS development release "))
        print(_("set Prompt=normal in /etc/update-manager/release-upgrades."))
      elif options.devel_release:
        print(_("Upgrades to the development release are only "))
        print(_("available from the latest supported release."))
      else:
        print(_("No new release found."))
    sys.exit(NO_RELEASE_AVAILABLE)

  if m.new_dist.upgrade_broken:
    if not options.quiet:
      print(_("Release upgrade not possible right now"))
      print(_("The release upgrade can not be performed currently, "
              "please try again later. The server reported: '%s'") % m.new_dist.upgrade_broken)
    sys.exit(NO_RELEASE_AVAILABLE)

  # we have a new dist
  if options.check_dist_upgrade_only:
    print(_("New release '%s' available.") % m.new_dist.version)
    print(_("Run 'do-release-upgrade' to upgrade to it."))
    sys.exit(RELEASE_AVAILABLE)

  cache = apt.Cache()
  cache.open()
  install_count = 0
  upgradable = [pkg for pkg in cache if pkg.is_upgradable]
  for pkg in upgradable:
    if 'Phased-Update-Percentage' in pkg.candidate.record:
      # P-U-P does not exist if it is fully phased
      continue
    else:
      install_count += 1
      # one upgradeable package is enough to stop the dist-upgrade
      break
  if install_count > 0:
    if not options.quiet:
      print(_("Please install all available updates "
              "for your release before upgrading."))
    sys.exit(1)
  if os.path.exists('/var/run/reboot-required.pkgs'):
    reboot = False
    with open('/var/run/reboot-required.pkgs', 'rb') as f:
        for line in f:
            if line == b'libc6\n':
                reboot = True
                break
    if reboot:
      if not options.quiet:
        print(_("You have not rebooted after updating a package which "
                "requires a reboot. Please reboot before upgrading."))
      sys.exit(1)

  if options.allow_third_party:
    # the env variable is used by code in the dist-upgrader tarball
    os.environ["RELEASE_UPGRADER_ALLOW_THIRD_PARTY"] = "True"

  # GTK 3 fetcher starts setting up the the GUI and KDE GUI needs to start GUI
  # later, too.
  if (options.frontend in {"DistUpgradeViewGtk3", "DistUpgradeViewKDE"} and
      os.getuid() != 0):
    if 'WAYLAND_DISPLAY' in os.environ:
        subprocess.run(['xhost', '+si:localuser:root'])
    # this is needed because pkexec doesn't pass on the env
    if 'RELEASE_UPGRADER_ALLOW_THIRD_PARTY' in os.environ:
        sys.argv.append('--allow-third-party')
    os.execv("/usr/bin/pkexec", ["pkexec"] + sys.argv)

  fetcher = get_fetcher(options.frontend, m.new_dist, options.data_dir)
  fetcher.run_options += ["--mode=%s" % options.mode,
                          "--frontend=%s" % options.frontend,
                          ]
  if options.devel_release:
    fetcher.run_options.append("--devel-release")
  fetcher.run()