diff -Nru update-manager-18.04.11.13/.bzrignore update-manager-18.04.11.23/.bzrignore
--- update-manager-18.04.11.13/.bzrignore 1970-01-01 00:00:00.000000000 +0000
+++ update-manager-18.04.11.23/.bzrignore 2024-01-22 20:36:03.000000000 +0000
@@ -0,0 +1,11 @@
+__pycache__
+debian/*.debhelper*
+debian/*.substvars
+debian/files
+debian/python-update-manager
+debian/python3-update-manager
+debian/tmp
+debian/update-manager
+debian/update-manager-core
+debian/update-manager-kde
+debian/update-manager-text
diff -Nru update-manager-18.04.11.13/.gitignore update-manager-18.04.11.23/.gitignore
--- update-manager-18.04.11.13/.gitignore 1970-01-01 00:00:00.000000000 +0000
+++ update-manager-18.04.11.23/.gitignore 2024-01-22 20:36:03.000000000 +0000
@@ -0,0 +1,2 @@
+tags
+__pycache__
diff -Nru update-manager-18.04.11.13/UpdateManager/Core/MyCache.py update-manager-18.04.11.23/UpdateManager/Core/MyCache.py
--- update-manager-18.04.11.13/UpdateManager/Core/MyCache.py 2018-10-31 11:29:09.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/Core/MyCache.py 2024-01-22 20:36:03.000000000 +0000
@@ -81,6 +81,7 @@
self._initDepCache()
self.all_changes = {}
self.all_news = {}
+ self.pro_versions = {}
# on broken packages, try to fix via saveDistUpgrade()
if self._depcache.broken_count > 0:
self.saveDistUpgrade()
@@ -421,14 +422,22 @@
"Please check your Internet connection.")
self.all_changes[name] += error_message
+ # If the machine is not attached to Ubuntu Pro, Update Manager advertises
+ # the upgrades that would be available if it were attached.
+ # As that is unbeknownst to Apt, we need this map to show the correct
+ # version of each upgradable-if-pro-subscribed package.
+ def create_pro_cache(self, pro_pkgs):
+ for (name, version, _a, _a) in pro_pkgs:
+ self.pro_versions[name] = version
+
def get_changelog(self, name):
" get the changelog file from the changelog location "
origins = self[name].candidate.origins
+ version = self.pro_versions.get(name, self[name].candidate.version)
self.all_changes[name] = _("Changes for %s versions:\n"
"Installed version: %s\n"
"Available version: %s\n\n") % \
- (name, getattr(self[name].installed, "version", None),
- self[name].candidate.version)
+ (name, getattr(self[name].installed, "version", None), version)
if self.CHANGELOG_ORIGIN not in [o.origin for o in origins]:
self._fetch_changelog_for_third_party_package(name, origins)
return
diff -Nru update-manager-18.04.11.13/UpdateManager/Core/UpdateList.py update-manager-18.04.11.23/UpdateManager/Core/UpdateList.py
--- update-manager-18.04.11.13/UpdateManager/Core/UpdateList.py 2018-10-31 11:29:09.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/Core/UpdateList.py 2024-01-22 20:36:03.000000000 +0000
@@ -43,11 +43,12 @@
class UpdateItem():
- def __init__(self, pkg, name, icon, to_remove):
+ def __init__(self, pkg, name, icon, to_remove, sensitive=True):
self.icon = icon
self.name = name
self.pkg = pkg
self.to_remove = to_remove
+ self.sensitive = sensitive
def is_selected(self):
if not self.to_remove:
@@ -59,13 +60,13 @@
class UpdateGroup(UpdateItem):
_depcache = {}
- def __init__(self, pkg, name, icon, to_remove):
- UpdateItem.__init__(self, pkg, name, icon, to_remove)
+ def __init__(self, pkg, name, icon, to_remove, sensitive=True):
+ UpdateItem.__init__(self, pkg, name, icon, to_remove, sensitive)
self._items = set()
self._deps = set()
self.core_item = None
if pkg is not None:
- self.core_item = UpdateItem(pkg, name, icon, to_remove)
+ self.core_item = UpdateItem(pkg, name, icon, to_remove, sensitive)
self._items.add(self.core_item)
@property
@@ -74,10 +75,11 @@
all_items.extend(self._items)
return sorted(all_items, key=lambda a: a.name.lower())
- def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False):
+ def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False,
+ sensitive=True):
name = utils.get_package_label(pkg)
icon = Gio.ThemedIcon.new("package")
- self._items.add(UpdateItem(pkg, name, icon, to_remove))
+ self._items.add(UpdateItem(pkg, name, icon, to_remove, sensitive))
# If the pkg is in self._deps, stop here. We have already calculated
# the recursive dependencies for this package, no need to do it again.
if cache and pkg.name in cache and pkg.name not in self._deps:
@@ -153,27 +155,29 @@
class UpdateApplicationGroup(UpdateGroup):
- def __init__(self, pkg, application, to_remove):
+ def __init__(self, pkg, application, to_remove, sensitive=True):
name = application.get_display_name()
icon = application.get_icon()
super(UpdateApplicationGroup, self).__init__(pkg, name, icon,
- to_remove)
+ to_remove, sensitive)
class UpdatePackageGroup(UpdateGroup):
- def __init__(self, pkg, to_remove):
+ def __init__(self, pkg, to_remove, sensitive=True):
name = utils.get_package_label(pkg)
icon = Gio.ThemedIcon.new("package")
- super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove)
+ super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove,
+ sensitive)
class UpdateSystemGroup(UpdateGroup):
- def __init__(self, cache, to_remove):
+ def __init__(self, cache, to_remove, sensitive=True):
# Translators: the %s is a distro name, like 'Ubuntu' and 'base' as in
# the core components and packages.
name = _("%s base") % utils.get_ubuntu_flavor_name(cache=cache)
icon = Gio.ThemedIcon.new("distributor-logo")
- super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove)
+ super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove,
+ sensitive)
class UpdateOrigin():
@@ -213,6 +217,8 @@
self.update_groups = []
self.security_groups = []
self.kernel_autoremove_groups = []
+ self.ubuntu_pro_groups = []
+ self.ubuntu_pro_fake_groups = []
self.num_updates = 0
self.random = random.Random()
self.ignored_phased_updates = []
@@ -419,7 +425,8 @@
'linux-tools-virtual',
'linux-virtual']
- def _make_groups(self, cache, pkgs, eventloop_callback, to_remove=False):
+ def _make_groups(self, cache, pkgs, eventloop_callback, to_remove=False,
+ sensitive=True):
if not pkgs:
return []
ungrouped_pkgs = []
@@ -429,7 +436,8 @@
for pkg in pkgs:
app = self._get_application_for_package(pkg)
if app is not None:
- app_group = UpdateApplicationGroup(pkg, app, to_remove)
+ app_group = UpdateApplicationGroup(pkg, app, to_remove,
+ sensitive)
app_groups.append(app_group)
else:
ungrouped_pkgs.append(pkg)
@@ -450,7 +458,7 @@
if ungrouped_pkgs:
# Separate out system base packages. If we have already found an
# application for all updates, don't bother.
- meta_group = UpdateGroup(None, None, None, to_remove)
+ meta_group = UpdateGroup(None, None, None, to_remove, sensitive)
flavor_package = utils.get_ubuntu_flavor_package(cache=cache)
meta_pkgs = [flavor_package, "ubuntu-standard", "ubuntu-minimal"]
meta_pkgs.extend(self._get_linux_packages())
@@ -460,10 +468,13 @@
for pkg in ungrouped_pkgs:
if meta_group.is_dependency(pkg, cache, eventloop_callback):
if system_group is None:
- system_group = UpdateSystemGroup(cache, to_remove)
+ system_group = UpdateSystemGroup(cache, to_remove,
+ sensitive)
system_group.add(pkg)
else:
- pkg_groups.append(UpdatePackageGroup(pkg, to_remove))
+ pkg_groups.append(UpdatePackageGroup(
+ pkg, to_remove, sensitive)
+ )
app_groups.sort(key=lambda a: a.name.lower())
pkg_groups.sort(key=lambda a: a.name.lower())
@@ -472,16 +483,56 @@
return app_groups + pkg_groups
- def update(self, cache, eventloop_callback=None):
+ def update(self, cache, eventloop_callback=None, ua_security_packages=[]):
self.held_back = []
# do the upgrade
self.distUpgradeWouldDelete = cache.saveDistUpgrade()
+ pro_pkgs = []
security_pkgs = []
upgrade_pkgs = []
kernel_autoremove_pkgs = []
+ class FakeUbuntuProPackageCandidate:
+ def __init__(self, source_name, version, size):
+ self.source_name = source_name
+ self.summary = source_name
+ self.description = source_name
+ self.version = version
+ self.size = size
+ self.downloadable = False
+ self.record = {}
+
+ class FakeUbuntuProPackage:
+ def __init__(self, package_name, version, size):
+ self.name = package_name
+ self.candidate = FakeUbuntuProPackageCandidate(package_name,
+ version, size)
+ self.marked_install = False
+ self.marked_upgrade = False
+ self.marked_delete = False
+ self.installed_files = []
+
+ def mark_install(self):
+ pass
+
+ def mark_delete(self):
+ pass
+ fake_ua_packages = []
+ ua_packages_names = []
+ for (
+ package_name,
+ version,
+ size,
+ downloadable
+ ) in ua_security_packages:
+ if downloadable:
+ ua_packages_names.append(package_name)
+ else:
+ fake_ua_packages.append(FakeUbuntuProPackage(package_name,
+ version, size))
+
# Find all upgradable packages
for pkg in cache:
if pkg.is_upgradable or pkg.marked_install:
@@ -501,7 +552,10 @@
self.ignored_phased_updates.append(pkg)
continue
- if is_security_update:
+ comes_from_pro = pkg.name in ua_packages_names
+ if comes_from_pro:
+ pro_pkgs.append(pkg)
+ elif is_security_update:
security_pkgs.append(pkg)
else:
upgrade_pkgs.append(pkg)
@@ -524,10 +578,13 @@
for pkg in self.ignored_phased_updates:
pkg.mark_keep()
- if security_pkgs or upgrade_pkgs:
+ if security_pkgs or upgrade_pkgs or pro_pkgs:
# There's updates available. Initiate the desktop file cache.
pkg_names = [p.name for p in
- security_pkgs + upgrade_pkgs + kernel_autoremove_pkgs]
+ pro_pkgs
+ + security_pkgs
+ + upgrade_pkgs
+ + kernel_autoremove_pkgs]
self._populate_desktop_cache(pkg_names)
self.update_groups = self._make_groups(cache, upgrade_pkgs,
eventloop_callback)
@@ -535,3 +592,7 @@
eventloop_callback)
self.kernel_autoremove_groups = self._make_groups(
cache, kernel_autoremove_pkgs, eventloop_callback, True)
+ self.ubuntu_pro_fake_groups = self._make_groups(
+ cache, fake_ua_packages, eventloop_callback, sensitive=False)
+ self.ubuntu_pro_groups = self._make_groups(
+ cache, pro_pkgs, eventloop_callback)
diff -Nru update-manager-18.04.11.13/UpdateManager/Core/utils.py update-manager-18.04.11.23/UpdateManager/Core/utils.py
--- update-manager-18.04.11.13/UpdateManager/Core/utils.py 2019-04-09 23:03:43.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/Core/utils.py 2024-01-22 20:36:03.000000000 +0000
@@ -78,6 +78,16 @@
print("%s: %s" % (self.info, time.time() - self.now))
+class SoftwarePropertiesPage():
+ ubuntu_software = 0
+ other_software = 1
+ updates = 2
+ authentication = 3
+ additional_drivers = 4
+ developer_options = 5
+ ubuntu_pro = 6
+
+
def get_string_with_no_auth_from_source_entry(entry):
tmp = copy(entry)
url_parts = urlsplit(tmp.uri)
diff -Nru update-manager-18.04.11.13/UpdateManager/Dialogs.py update-manager-18.04.11.23/UpdateManager/Dialogs.py
--- update-manager-18.04.11.13/UpdateManager/Dialogs.py 2020-04-21 14:27:18.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/Dialogs.py 2024-01-22 20:36:03.000000000 +0000
@@ -161,10 +161,10 @@
if self._is_livepatch_supported() and \
self.settings_button and \
self.settings.get_int('launch-count') >= 4:
- self.set_desc(_("Tip: You can use Livepatch to "
- "keep your computer more secure between "
- "restarts."))
- self.settings_button.set_label(_("Settings & Livepatch…"))
+ self.set_desc(_("Tip: You can use Livepatch with "
+ "Ubuntu Pro to keep your computer more "
+ "secure between restarts."))
+ self.settings_button.set_label(_("Settings & Pro…"))
return
needs_reschedule = False
diff -Nru update-manager-18.04.11.13/UpdateManager/UpdateManager.py update-manager-18.04.11.23/UpdateManager/UpdateManager.py
--- update-manager-18.04.11.13/UpdateManager/UpdateManager.py 2020-06-03 18:41:48.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/UpdateManager.py 2024-01-22 20:36:03.000000000 +0000
@@ -36,6 +36,7 @@
import apt_pkg
import distro_info
+import json
import os
import subprocess
import sys
@@ -64,7 +65,7 @@
from .Core.MyCache import MyCache
from .Core.roam import NetworkManagerHelper
from .Core.UpdateList import UpdateList
-from .Core.utils import get_arch, get_dist
+from .Core.utils import get_arch, get_dist, SoftwarePropertiesPage
from .backend import (InstallBackend,
get_backend)
@@ -85,6 +86,7 @@
self.unity = UnitySupport()
self.controller = None
self.cache = None
+ self.ua_security_packages = []
self.update_list = None
self.meta_release = None
self.hwe_replacement_packages = None
@@ -193,13 +195,13 @@
self._start_pane(None)
sys.exit(0)
- def show_settings(self):
+ def show_settings(self, page_number=SoftwarePropertiesPage.updates):
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
pass
cmd = ["/usr/bin/software-properties-gtk",
- "--open-tab", "2"]
+ "--open-tab", str(page_number)]
if "WAYLAND_DISPLAY" not in os.environ:
cmd += ["--toplevel", "%s" % self.get_window().get_xid()]
@@ -247,23 +249,41 @@
cancelled_update, error_occurred)
self._start_pane(pane)
+ def _get_ua_security_status(self):
+ self.ua_security_packages = []
+ try:
+ p = subprocess.Popen(['pro', 'security-status', '--format=json'],
+ stdout=subprocess.PIPE)
+ except OSError:
+ pass
+ else:
+ while p.poll() is None:
+ while Gtk.events_pending():
+ Gtk.main_iteration()
+ time.sleep(0.05)
+ s = json.load(p.stdout)
+ for package in s.get('packages', []):
+ if package.get('service_name', '') == 'standard-security':
+ continue
+ status = package.get('status', '')
+ if (
+ status == 'pending_attach'
+ or status == 'pending_enable'
+ or status == 'upgrade_available'
+ ):
+ name = package.get('package', '')
+ version = package.get('version', '')
+ size = package.get('download_size', 0)
+ downloadable = status == 'upgrade_available'
+ self.ua_security_packages.append(
+ (name, version, size, downloadable)
+ )
+ self.cache.create_pro_cache(self.ua_security_packages)
+
def _make_available_pane(self, install_count, need_reboot=False,
cancelled_update=False, error_occurred=False):
self._check_hwe_support_status()
- if install_count == 0:
- # Need Restart > New Release > No Updates
- if need_reboot:
- return NeedRestartDialog(self)
- dist_upgrade = self._check_meta_release()
- if dist_upgrade:
- return dist_upgrade
- elif cancelled_update:
- return StoppedUpdatesDialog(self)
- elif self.hwe_replacement_packages:
- return HWEUpgradeDialog(self)
- else:
- return NoUpdatesDialog(self, error_occurred=error_occurred)
- else:
+ if install_count != 0:
header = None
desc = None
if error_occurred:
@@ -276,6 +296,19 @@
elif self.hwe_replacement_packages:
return HWEUpgradeDialog(self)
return UpdatesAvailable(self, header, desc, need_reboot)
+ else:
+ # Need Restart > New Release > No Updates
+ if need_reboot:
+ return NeedRestartDialog(self)
+ dist_upgrade = self._check_meta_release()
+ if dist_upgrade:
+ return dist_upgrade
+ elif cancelled_update:
+ return StoppedUpdatesDialog(self)
+ elif self.hwe_replacement_packages:
+ return HWEUpgradeDialog(self)
+ else:
+ return NoUpdatesDialog(self, error_occurred=error_occurred)
def start_error(self, update_and_retry, header, desc):
if update_and_retry:
@@ -406,9 +439,13 @@
Gtk.main_iteration()
iterate()
+ self._get_ua_security_status()
+
self.update_list = UpdateList(self)
try:
- self.update_list.update(self.cache, eventloop_callback=iterate)
+ self.update_list.update(self.cache, eventloop_callback=iterate,
+ ua_security_packages=self.
+ ua_security_packages)
except SystemError as e:
header = _("Could not calculate the upgrade")
desc = _("An unresolvable problem occurred while "
diff -Nru update-manager-18.04.11.13/UpdateManager/UpdatesAvailable.py update-manager-18.04.11.23/UpdateManager/UpdatesAvailable.py
--- update-manager-18.04.11.13/UpdateManager/UpdatesAvailable.py 2018-10-31 11:29:09.000000000 +0000
+++ update-manager-18.04.11.23/UpdateManager/UpdatesAvailable.py 2024-01-22 20:36:03.000000000 +0000
@@ -55,7 +55,7 @@
from gettext import gettext as _
from gettext import ngettext
-from .Core.utils import humanize_size
+from .Core.utils import humanize_size, SoftwarePropertiesPage
from .Core.AlertWatcher import AlertWatcher
from .Core.UpdateList import UpdateSystemGroup
from .Dialogs import InternalDialog
@@ -74,7 +74,8 @@
# - screen reader does not say "Downloaded" for downloaded updates
# list constants
-(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE) = range(4)
+(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE,
+ LIST_SENSITIVE) = range(5)
# NetworkManager enums
from .Core.roam import NetworkManagerHelper
@@ -249,19 +250,24 @@
self.add_settings_button()
self.button_close = self.add_button(Gtk.STOCK_CANCEL,
self.window_main.close)
+ self.button_pro = self.add_button(_("Enable Ubuntu Pro..."),
+ self.on_button_pro_clicked)
self.button_install = self.add_button(_("Install Now"),
self.on_button_install_clicked)
self.focus_button = self.button_install
# create text view
self.textview_changes = ChangelogViewer()
+ self.textview_changes.set_wrap_mode(Gtk.WrapMode.WORD)
self.textview_changes.show()
self.scrolledwindow_changes.add(self.textview_changes)
changes_buffer = self.textview_changes.get_buffer()
changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD)
+ changes_buffer.create_tag("changestag", weight=Pango.Weight.BOLD)
+ changes_buffer.create_tag("descriptiontag", weight=Pango.Weight.BOLD)
# the treeview (move into it's own code!)
- self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool)
+ self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool, bool)
self.treeview_update.set_model(None)
self.image_restart.set_from_gicon(self.get_restart_icon(),
@@ -293,6 +299,8 @@
pkg_column.pack_start(pkg_toggle_renderer, False)
pkg_column.add_attribute(pkg_toggle_renderer,
'active', LIST_TOGGLE_ACTIVE)
+ pkg_column.add_attribute(pkg_toggle_renderer,
+ 'sensitive', LIST_SENSITIVE)
pkg_column.set_cell_data_func(pkg_toggle_renderer,
self.pkg_toggle_renderer_data_func)
@@ -319,6 +327,8 @@
size_column = Gtk.TreeViewColumn(_("Download"), size_renderer,
text=LIST_SIZE)
size_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ size_column.add_attribute(size_renderer,
+ 'sensitive', LIST_SENSITIVE)
self.treeview_update.append_column(size_column)
self.treeview_update.set_headers_visible(True)
@@ -342,7 +352,6 @@
self.expander_details.connect("activate", self.pre_activate_details)
self.expander_details.connect("notify::expanded",
self.activate_details)
- self.expander_desc.connect("notify::expanded", self.activate_desc)
# If auto-updates are on, change cancel label
self.notifier_settings = Gio.Settings.new("com.ubuntu.update-notifier")
@@ -358,6 +367,17 @@
self.alert_watcher.connect("network-3g-alert",
self._on_network_3g_alert)
+ try:
+ from uaclient.api.u.apt_news.current_news.v1 import current_news
+ apt_news = current_news().current_news
+ except ImportError:
+ apt_news = self._get_apt_news(
+ "/var/lib/ubuntu-advantage/messages/apt-news"
+ )
+ if apt_news:
+ self.news.get_buffer().set_text(apt_news)
+ self.expander_news.set_visible(True)
+
def stop(self):
InternalDialog.stop(self)
self._save_state()
@@ -404,8 +424,11 @@
def restart_icon_renderer_data_func(self, cell_layout, renderer, model,
iter, user_data):
data = model.get_value(iter, LIST_UPDATE_DATA)
+ sensitive = model.get_value(iter, LIST_SENSITIVE)
path = model.get_path(iter)
+ renderer.set_sensitive(sensitive)
+
requires_restart = False
if data.item and data.item.pkg:
requires_restart = self.pkg_requires_restart(data.item.pkg)
@@ -433,6 +456,7 @@
if data.item:
activatable = data.item.pkg.name not in self.list.held_back
inconsistent = False
+ renderer.set_sensitive(data.item.sensitive)
elif data.group:
activatable = True
inconsistent = data.group.selection_is_inconsistent()
@@ -485,8 +509,11 @@
def pkg_label_renderer_data_func(self, cell_layout, renderer, model,
iter, user_data):
data = model.get_value(iter, LIST_UPDATE_DATA)
+ sensitive = model.get_value(iter, LIST_SENSITIVE)
name = GLib.markup_escape_text(model.get_value(iter, LIST_NAME))
+ renderer.set_sensitive(sensitive)
+
if data.group:
markup = name
elif data.item:
@@ -496,8 +523,18 @@
renderer.set_property("markup", markup)
- def set_changes_buffer(self, changes_buffer, text, name, srcpkg):
- changes_buffer.set_text("")
+ def set_changes_buffer(self, changes_buffer, long_desc, text, name,
+ srcpkg):
+ changes_buffer.set_text("") # Clear "downloading list of changes..."
+
+ # Write the technical description section
+ changes_buffer.insert_with_tags_by_name(changes_buffer.get_end_iter(),
+ "Technical description\n",
+ "descriptiontag")
+ changes_buffer.insert(changes_buffer.get_end_iter(),
+ long_desc + "\n\n")
+
+ # Write the changes section
lines = text.split("\n")
if len(lines) == 1:
changes_buffer.set_text(text)
@@ -509,12 +546,16 @@
r'^%s \((.*)\)(.*)\;.*$' % re.escape(srcpkg), line)
#bullet_match = re.match("^.*[\*-]", line)
author_match = re.match("^.*--.*<.*@.*>.*$", line)
+ changes_match = re.match(r'^Changes for [^ ]+ versions:$', line)
if version_match:
version = version_match.group(1)
#upload_archive = version_match.group(2).strip()
version_text = _("Version %s: \n") % version
changes_buffer.insert_with_tags_by_name(end_iter, version_text,
"versiontag")
+ elif changes_match:
+ changes_buffer.insert_with_tags_by_name(end_iter, line + "\n",
+ "changestag")
elif (author_match):
pass
else:
@@ -539,12 +580,8 @@
item.pkg.candidate.description is None):
changes_buffer = self.textview_changes.get_buffer()
changes_buffer.set_text("")
- desc_buffer = self.textview_descr.get_buffer()
- desc_buffer.set_text("")
- self.notebook_details.set_sensitive(False)
return
long_desc = item.pkg.candidate.description
- self.notebook_details.set_sensitive(True)
# do some regular expression magic on the description
# Add a newline before each bullet
p = re.compile(r'^(\s|\t)*(\*|0|-)', re.MULTILINE)
@@ -556,9 +593,6 @@
p = re.compile(r'\s\s+', re.MULTILINE)
long_desc = p.sub("\n", long_desc)
- desc_buffer = self.textview_descr.get_buffer()
- desc_buffer.set_text(long_desc)
-
# now do the changelog
name = item.pkg.name
if name is None:
@@ -571,7 +605,8 @@
if name in self.cache.all_changes:
changes = self.cache.all_changes[name]
srcpkg = self.cache[name].candidate.source_name
- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
+ self.set_changes_buffer(changes_buffer, long_desc, changes, name,
+ srcpkg)
# if not connected, do not even attempt to get the changes
elif not self.connected:
changes_buffer.set_text(
@@ -616,8 +651,10 @@
changes += self.cache.all_news[name]
if name in self.cache.all_changes:
changes += self.cache.all_changes[name]
- if changes:
- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
+
+ if changes or long_desc:
+ self.set_changes_buffer(changes_buffer, long_desc, changes, name,
+ srcpkg)
def on_treeview_button_press(self, widget, event):
"""
@@ -644,6 +681,11 @@
menu.show()
return True
+ def _get_apt_news(self, apt_news_file):
+ if os.access(apt_news_file, os.R_OK):
+ with open(apt_news_file) as f:
+ return f.read()
+
# we need this for select all/unselect all
def _toggle_group_headers(self, new_selection_value):
""" small helper that will set/unset the group headers
@@ -741,6 +783,7 @@
# self.button_install.set_sensitive(True)
self.button_install.set_sensitive(True)
self.unity.set_install_menuitem_visible(True)
+ self.button_pro.destroy()
else:
if inst_count > 0:
download_str = ngettext(
@@ -749,10 +792,17 @@
inst_count)
self.button_install.set_sensitive(True)
self.unity.set_install_menuitem_visible(True)
+ self.button_pro.destroy()
+ elif (self.list.ubuntu_pro_fake_groups
+ and not self.list.ubuntu_pro_groups):
+ download_str = _("You need to enable Ubuntu Pro to "
+ "install these updates.")
+ self.button_install.destroy()
else:
download_str = _("There are no updates to install.")
self.button_install.set_sensitive(False)
self.unity.set_install_menuitem_visible(False)
+ self.button_pro.destroy()
self.image_downsize.set_sensitive(False)
self.label_downsize.set_text(download_str)
self.hbox_downsize.show()
@@ -797,7 +847,6 @@
text_desc = _("The computer also needs to restart "
"to finish installing previous updates.")
- self.notebook_details.set_sensitive(True)
self.treeview_update.set_sensitive(True)
self.set_header(text_header)
self.set_desc(text_desc)
@@ -818,8 +867,10 @@
self._restore_state()
def activate_desc(self, expander, data):
- expanded = self.expander_desc.get_expanded()
- self.expander_desc.set_vexpand(expanded)
+ return
+
+ def on_button_pro_clicked(self):
+ self.window_main.show_settings(SoftwarePropertiesPage.ubuntu_pro)
def on_button_install_clicked(self):
self.unity.set_install_menuitem_visible(False)
@@ -989,7 +1040,7 @@
self.window_main.end_user_resizable()
return False
- def _add_header(self, name, groups):
+ def _add_header(self, name, groups, sensitive=True):
total_size = 0
for group in groups:
total_size = total_size + group.get_total_size()
@@ -997,7 +1048,8 @@
name,
UpdateData(groups, None, None),
humanize_size(total_size),
- True
+ True,
+ sensitive
]
return self.store.append(None, header_row)
@@ -1016,11 +1068,14 @@
len(group.items) == 1:
group_is_item = group.items[0]
+ if group.name == "Ubuntu base":
+ group.name = "System components"
group_row = [
group.name,
UpdateData(None, group, group_is_item),
humanize_size(group.get_total_size()),
- True
+ True,
+ group.sensitive
]
group_iter = self.store.append(None, group_row)
@@ -1031,7 +1086,8 @@
item.name,
UpdateData(None, None, item),
humanize_size(getattr(item.pkg.candidate, "size", 0)),
- True
+ True,
+ group.sensitive
]
self.store.append(group_iter, item_row)
@@ -1052,22 +1108,36 @@
if self.list.security_groups:
self._add_header(_("Security updates"), self.list.security_groups)
self._add_groups(self.list.security_groups)
- if self.list.security_groups and self.list.update_groups:
- self._add_header(_("Other updates"), self.list.update_groups)
- elif self.list.update_groups and self.list.kernel_autoremove_groups:
- self._add_header(_("Updates"), self.list.update_groups)
if self.list.update_groups:
+ self._add_header(_("Other updates"), self.list.update_groups)
self._add_groups(self.list.update_groups)
if self.list.kernel_autoremove_groups:
self._add_header(
_("Unused kernel updates to be removed"),
self.list.kernel_autoremove_groups)
self._add_groups(self.list.kernel_autoremove_groups)
+ if self.list.ubuntu_pro_groups:
+ self._add_header(
+ _("Ubuntu Pro security updates"),
+ self.list.ubuntu_pro_groups,
+ sensitive=True
+ )
+ self._add_groups(self.list.ubuntu_pro_groups)
+ if self.list.ubuntu_pro_fake_groups:
+ self._add_header(
+ _("Ubuntu Pro security updates (enable in Settings…)"),
+ self.list.ubuntu_pro_fake_groups,
+ sensitive=False
+ )
+ self._add_groups(self.list.ubuntu_pro_fake_groups)
self.treeview_update.set_model(self.store)
self.pkg_cell_area.indent_toplevel = (
- bool(self.list.security_groups) or
- bool(self.list.kernel_autoremove_groups))
+ bool(self.list.ubuntu_pro_fake_groups)
+ or bool(self.list.ubuntu_pro_groups)
+ or bool(self.list.update_groups)
+ or bool(self.list.security_groups)
+ or bool(self.list.kernel_autoremove_groups))
self.update_close_button()
self.update_count()
self.setBusy(False)
diff -Nru update-manager-18.04.11.13/data/gtkbuilder/UpdateManager.ui update-manager-18.04.11.23/data/gtkbuilder/UpdateManager.ui
--- update-manager-18.04.11.13/data/gtkbuilder/UpdateManager.ui 2018-10-31 11:29:09.000000000 +0000
+++ update-manager-18.04.11.23/data/gtkbuilder/UpdateManager.ui 2024-01-22 20:36:03.000000000 +0000
@@ -5,6 +5,63 @@
True
False
12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ 0
+
+
True
@@ -12,11 +69,9 @@
6
True
-
+
True
- False
- True
- 6
+ vertical
True
@@ -44,113 +99,21 @@
- True
- True
- 0
+ False
+ True
-
+
True
True
+ in
-
- True
- True
- False
-
-
- True
- False
- 6
- 6
-
-
- True
- True
- in
-
-
-
-
-
- True
- True
- 0
-
-
-
-
-
-
- True
- False
- Changes
-
-
- False
-
-
-
-
- True
- True
- 6
- in
- 80
-
-
- True
- True
- 6
- False
- word
- 6
- 6
- False
- False
-
-
- Description
-
-
-
-
-
-
- 1
-
-
-
-
- True
- False
- Description
-
-
- Description
-
-
-
-
- 1
- False
-
-
-
-
-
-
- True
- False
- Technical description
-
+
- False
- True
- 1
+ True
@@ -167,7 +130,7 @@
True
True
- 2
+ 1
@@ -177,12 +140,13 @@
False
- 12
+ 8
True
False
aptdaemon-download
+ 16
False
@@ -400,7 +364,7 @@
False
True
- 3
+ 2
diff -Nru update-manager-18.04.11.13/debian/changelog update-manager-18.04.11.23/debian/changelog
--- update-manager-18.04.11.13/debian/changelog 2020-06-03 18:41:50.000000000 +0000
+++ update-manager-18.04.11.23/debian/changelog 2024-01-22 20:36:03.000000000 +0000
@@ -1,3 +1,82 @@
+update-manager (1:18.04.11.23) bionic; urgency=medium
+
+ * d/control: Depend on ubuntu-advantage-tools >= 30~.
+ Fixes edge case whereby the program crashes upon an incomplete
+ response from ua security-status (LP: #2049785).
+ * The New Release dialog should take precedence over a list of updates dialog
+ if the latter would only show Ubuntu Pro updates in an unattached system.
+ (LP: #2051115).
+
+ -- Nathan Pratta Teodosio Mon, 22 Jan 2024 21:36:03 +0100
+
+update-manager (1:18.04.11.22) bionic; urgency=medium
+
+ * Add back removed widgets to UI file to fix crash when updating
+ Upgrade Manager from inside itself (LP: #2045918).
+
+ -- Nathan Pratta Teodosio Fri, 08 Dec 2023 15:39:44 +0100
+
+update-manager (1:18.04.11.21) bionic; urgency=medium
+
+ * Fix incorrect available version for Ubuntu Pro updates in unattached case
+ (LP: #2043425).
+
+ -- Nathan Pratta Teodosio Thu, 16 Nov 2023 10:03:37 +0100
+
+update-manager (1:18.04.11.20) bionic; urgency=medium
+
+ * Ubuntu Pro (LP: #1990450):
+ - fix another linter error which was created while fixing a missing
+ space in the previous upload...
+
+ -- Sebastien Bacher Fri, 06 Oct 2023 09:31:28 +0200
+
+update-manager (1:18.04.11.19) bionic; urgency=medium
+
+ * Ubuntu Pro (LP: #1990450):
+ - Address linter errors that cause autopkgtest to fail.
+
+ -- Nathan Pratta Teodosio Thu, 05 Oct 2023 10:38:09 +0200
+
+update-manager (1:18.04.11.18) bionic; urgency=medium
+
+ * Ubuntu Pro (LP: #1990450):
+ - Show Ubuntu Pro packages, whether the system is attached to Ubuntu Pro
+ or not.
+ - Replace Install now button by Enable Ubuntu Pro button when only Ubuntu
+ Pro packages are available and the machine is not attached.
+ - Fix checkbox and expander widget from overlapping.
+ - Add News pane in a expander.
+ - Replace notebook with Description and Changes tabs by a pane.
+
+ -- Nathan Pratta Teodosio Tue, 29 Aug 2023 07:47:20 +0200
+
+update-manager (1:18.04.11.17) bionic; urgency=medium
+
+ * Fix Ubuntu Pro updates checkbox and expander widget from overlapping
+ (LP: #1990450)
+
+ -- Robert Ancell Fri, 03 Feb 2023 14:55:56 +1300
+
+update-manager (1:18.04.11.16) bionic; urgency=medium
+
+ * Update of the parsing for pro client changes (lp: #1990450)
+
+ -- Sebastien Bacher Thu, 26 Jan 2023 12:05:05 +0100
+
+update-manager (1:18.04.11.15) bionic; urgency=medium
+
+ * Show pending Ubuntu pro packages (LP: #1990450)
+
+ -- Robert Ancell Wed, 18 Jan 2023 15:09:17 +1300
+
+update-manager (1:18.04.11.14) bionic; urgency=medium
+
+ * tests/test_meta_release_core.py: switch a test from using lucid to bionic
+ as precise was removed from the archive. (LP: #1929865)
+
+ -- Brian Murray Thu, 27 May 2021 13:54:14 -0700
+
update-manager (1:18.04.11.13) bionic; urgency=medium
* UpdateManager/UpdateManager.py: when refreshing the cache and encountering
diff -Nru update-manager-18.04.11.13/debian/control update-manager-18.04.11.23/debian/control
--- update-manager-18.04.11.13/debian/control 2018-10-31 11:29:38.000000000 +0000
+++ update-manager-18.04.11.23/debian/control 2024-01-22 20:36:03.000000000 +0000
@@ -27,8 +27,10 @@
${misc:Depends},
python3-update-manager (= ${source:Version}),
python3-distro-info,
+ python3-yaml,
distro-info-data,
lsb-release,
+ ubuntu-advantage-tools (>= 30~),
ubuntu-release-upgrader-core (>= 1:18.04.9)
Recommends: libpam-modules (>= 1.0.1-9ubuntu3)
Replaces: update-manager (<< 1:0.146.2)
diff -Nru update-manager-18.04.11.13/tests/test_meta_release_core.py update-manager-18.04.11.23/tests/test_meta_release_core.py
--- update-manager-18.04.11.13/tests/test_meta_release_core.py 2019-04-09 23:03:43.000000000 +0000
+++ update-manager-18.04.11.23/tests/test_meta_release_core.py 2024-01-22 20:36:03.000000000 +0000
@@ -167,7 +167,7 @@
def test_html_uri_real(self):
# test parsing of a meta-releaes file from the server
with EnvironmentVarGuard() as environ:
- environ["META_RELEASE_FAKE_CODENAME"] = "lucid"
+ environ["META_RELEASE_FAKE_CODENAME"] = "bionic"
meta = MetaReleaseCore(forceDownload=True)
while meta.downloading:
time.sleep(0.1)