Merge ~nteodosio/update-manager:bionic-ua into update-manager:ubuntu/bionic

Proposed by Nathan Teodosio
Status: Merged
Approved by: Sebastien Bacher
Approved revision: 8e1fb1c8ff0ac1040229e52f907d60d205f38274
Merged at revision: 8e1fb1c8ff0ac1040229e52f907d60d205f38274
Proposed branch: ~nteodosio/update-manager:bionic-ua
Merge into: update-manager:ubuntu/bionic
Diff against target: 670 lines (+171/-153)
8 files modified
.gitignore (+2/-0)
UpdateManager/Core/UpdateList.py (+18/-7)
UpdateManager/Core/utils.py (+10/-0)
UpdateManager/UpdateManager.py (+22/-19)
UpdateManager/UpdatesAvailable.py (+59/-22)
data/gtkbuilder/UpdateManager.ui (+45/-105)
debian/changelog (+13/-0)
debian/control (+2/-0)
Reviewer Review Type Date Requested Status
Sebastien Bacher Approve
Oliver Smith Pending
Elio Qoshi Pending
Review via email: mp+446968@code.launchpad.net

Description of the change

PPA can be tested in https://launchpad.net/~nteodosio/+archive/ubuntu/ubuntu-pro.

Internal discussion in UDENG-361.

To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

Thanks, there are some merge conflicts to be resolved though

review: Needs Fixing
Revision history for this message
Nathan Teodosio (nteodosio) wrote :

Thanks, I rebased on ubuntu/bionic.

Revision history for this message
Sebastien Bacher (seb128) wrote :

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000..0370a5e
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,2 @@
7+tags
8+__pycache__
9diff --git a/UpdateManager/Core/UpdateList.py b/UpdateManager/Core/UpdateList.py
10index cc895d0..79c9bd8 100644
11--- a/UpdateManager/Core/UpdateList.py
12+++ b/UpdateManager/Core/UpdateList.py
13@@ -218,6 +218,7 @@ class UpdateList():
14 self.security_groups = []
15 self.kernel_autoremove_groups = []
16 self.ubuntu_pro_groups = []
17+ self.ubuntu_pro_fake_groups = []
18 self.num_updates = 0
19 self.random = random.Random()
20 self.ignored_phased_updates = []
21@@ -483,6 +484,7 @@ class UpdateList():
22 # do the upgrade
23 self.distUpgradeWouldDelete = cache.saveDistUpgrade()
24
25+ pro_pkgs = []
26 security_pkgs = []
27 upgrade_pkgs = []
28 kernel_autoremove_pkgs = []
29@@ -513,9 +515,13 @@ class UpdateList():
30 def mark_delete(self):
31 pass
32 fake_ua_packages = []
33- for (package_name, version, size) in ua_security_packages:
34- fake_ua_packages.append(FakeUbuntuProPackage(package_name,
35- version, size))
36+ ua_packages_names = []
37+ for (package_name, version, size, downloadable) in ua_security_packages:
38+ if downloadable:
39+ ua_packages_names.append(package_name)
40+ else:
41+ fake_ua_packages.append(FakeUbuntuProPackage(package_name,
42+ version, size))
43
44 # Find all upgradable packages
45 for pkg in cache:
46@@ -536,7 +542,10 @@ class UpdateList():
47 self.ignored_phased_updates.append(pkg)
48 continue
49
50- if is_security_update:
51+ comes_from_pro = pkg.name in ua_packages_names
52+ if comes_from_pro:
53+ pro_pkgs.append(pkg)
54+ elif is_security_update:
55 security_pkgs.append(pkg)
56 else:
57 upgrade_pkgs.append(pkg)
58@@ -559,10 +568,10 @@ class UpdateList():
59 for pkg in self.ignored_phased_updates:
60 pkg.mark_keep()
61
62- if security_pkgs or upgrade_pkgs:
63+ if security_pkgs or upgrade_pkgs or pro_pkgs:
64 # There's updates available. Initiate the desktop file cache.
65 pkg_names = [p.name for p in
66- security_pkgs + upgrade_pkgs + kernel_autoremove_pkgs]
67+ pro_pkgs + security_pkgs + upgrade_pkgs + kernel_autoremove_pkgs]
68 self._populate_desktop_cache(pkg_names)
69 self.update_groups = self._make_groups(cache, upgrade_pkgs,
70 eventloop_callback)
71@@ -570,5 +579,7 @@ class UpdateList():
72 eventloop_callback)
73 self.kernel_autoremove_groups = self._make_groups(
74 cache, kernel_autoremove_pkgs, eventloop_callback, True)
75- self.ubuntu_pro_groups = self._make_groups(
76+ self.ubuntu_pro_fake_groups = self._make_groups(
77 cache, fake_ua_packages, eventloop_callback, sensitive=False)
78+ self.ubuntu_pro_groups = self._make_groups(
79+ cache, pro_pkgs, eventloop_callback)
80diff --git a/UpdateManager/Core/utils.py b/UpdateManager/Core/utils.py
81index 48c513e..871fa6b 100644
82--- a/UpdateManager/Core/utils.py
83+++ b/UpdateManager/Core/utils.py
84@@ -78,6 +78,16 @@ class ExecutionTime(object):
85 print("%s: %s" % (self.info, time.time() - self.now))
86
87
88+class SoftwarePropertiesPage():
89+ ubuntu_software = 0
90+ other_software = 1
91+ updates = 2
92+ authentication = 3
93+ additional_drivers = 4
94+ developer_options = 5
95+ ubuntu_pro = 6
96+
97+
98 def get_string_with_no_auth_from_source_entry(entry):
99 tmp = copy(entry)
100 url_parts = urlsplit(tmp.uri)
101diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py
102index 797407a..5c7acb1 100644
103--- a/UpdateManager/UpdateManager.py
104+++ b/UpdateManager/UpdateManager.py
105@@ -65,7 +65,7 @@ from .Core.AlertWatcher import AlertWatcher
106 from .Core.MyCache import MyCache
107 from .Core.roam import NetworkManagerHelper
108 from .Core.UpdateList import UpdateList
109-from .Core.utils import get_arch, get_dist
110+from .Core.utils import get_arch, get_dist, SoftwarePropertiesPage
111 from .backend import (InstallBackend,
112 get_backend)
113
114@@ -195,13 +195,13 @@ class UpdateManager(Gtk.Window):
115 self._start_pane(None)
116 sys.exit(0)
117
118- def show_settings(self):
119+ def show_settings(self, page_number = SoftwarePropertiesPage.updates):
120 try:
121 apt_pkg.pkgsystem_unlock()
122 except SystemError:
123 pass
124 cmd = ["/usr/bin/software-properties-gtk",
125- "--open-tab", "2"]
126+ "--open-tab", str(page_number)]
127
128 if "WAYLAND_DISPLAY" not in os.environ:
129 cmd += ["--toplevel", "%s" % self.get_window().get_xid()]
130@@ -263,30 +263,20 @@ class UpdateManager(Gtk.Window):
131 time.sleep(0.05)
132 s = json.load(p.stdout)
133 for package in s.get('packages', []):
134+ if package.get('service_name', '') == 'standard-security':
135+ continue
136 status = package.get('status', '')
137- if status == 'pending_attach':
138+ if status == 'pending_attach' or status == 'pending_enable' or status == 'upgrade_available':
139 name = package.get('package', '')
140 version = package.get('version', '')
141 size = package.get('download_size', 0)
142- self.ua_security_packages.append((name, version, size))
143+ downloadable = status == 'upgrade_available'
144+ self.ua_security_packages.append((name, version, size, downloadable))
145
146 def _make_available_pane(self, install_count, need_reboot=False,
147 cancelled_update=False, error_occurred=False):
148 self._check_hwe_support_status()
149- if install_count == 0:
150- # Need Restart > New Release > No Updates
151- if need_reboot:
152- return NeedRestartDialog(self)
153- dist_upgrade = self._check_meta_release()
154- if dist_upgrade:
155- return dist_upgrade
156- elif cancelled_update:
157- return StoppedUpdatesDialog(self)
158- elif self.hwe_replacement_packages:
159- return HWEUpgradeDialog(self)
160- else:
161- return NoUpdatesDialog(self, error_occurred=error_occurred)
162- else:
163+ if install_count != 0 or len(self.ua_security_packages) > 0:
164 header = None
165 desc = None
166 if error_occurred:
167@@ -299,6 +289,19 @@ class UpdateManager(Gtk.Window):
168 elif self.hwe_replacement_packages:
169 return HWEUpgradeDialog(self)
170 return UpdatesAvailable(self, header, desc, need_reboot)
171+ else:
172+ # Need Restart > New Release > No Updates
173+ if need_reboot:
174+ return NeedRestartDialog(self)
175+ dist_upgrade = self._check_meta_release()
176+ if dist_upgrade:
177+ return dist_upgrade
178+ elif cancelled_update:
179+ return StoppedUpdatesDialog(self)
180+ elif self.hwe_replacement_packages:
181+ return HWEUpgradeDialog(self)
182+ else:
183+ return NoUpdatesDialog(self, error_occurred=error_occurred)
184
185 def start_error(self, update_and_retry, header, desc):
186 if update_and_retry:
187diff --git a/UpdateManager/UpdatesAvailable.py b/UpdateManager/UpdatesAvailable.py
188index 7c8cc79..b9a07d7 100644
189--- a/UpdateManager/UpdatesAvailable.py
190+++ b/UpdateManager/UpdatesAvailable.py
191@@ -55,7 +55,7 @@ import threading
192 from gettext import gettext as _
193 from gettext import ngettext
194
195-from .Core.utils import humanize_size
196+from .Core.utils import humanize_size, SoftwarePropertiesPage
197 from .Core.AlertWatcher import AlertWatcher
198 from .Core.UpdateList import UpdateSystemGroup
199 from .Dialogs import InternalDialog
200@@ -250,16 +250,21 @@ class UpdatesAvailable(InternalDialog):
201 self.add_settings_button()
202 self.button_close = self.add_button(Gtk.STOCK_CANCEL,
203 self.window_main.close)
204+ self.button_pro = self.add_button(_("Enable Ubuntu Pro..."),
205+ self.on_button_pro_clicked)
206 self.button_install = self.add_button(_("Install Now"),
207 self.on_button_install_clicked)
208 self.focus_button = self.button_install
209
210 # create text view
211 self.textview_changes = ChangelogViewer()
212+ self.textview_changes.set_wrap_mode(Gtk.WrapMode.WORD)
213 self.textview_changes.show()
214 self.scrolledwindow_changes.add(self.textview_changes)
215 changes_buffer = self.textview_changes.get_buffer()
216 changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD)
217+ changes_buffer.create_tag("changestag", weight=Pango.Weight.BOLD)
218+ changes_buffer.create_tag("descriptiontag", weight=Pango.Weight.BOLD)
219
220 # the treeview (move into it's own code!)
221 self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool, bool)
222@@ -347,7 +352,6 @@ class UpdatesAvailable(InternalDialog):
223 self.expander_details.connect("activate", self.pre_activate_details)
224 self.expander_details.connect("notify::expanded",
225 self.activate_details)
226- self.expander_desc.connect("notify::expanded", self.activate_desc)
227
228 # If auto-updates are on, change cancel label
229 self.notifier_settings = Gio.Settings.new("com.ubuntu.update-notifier")
230@@ -363,6 +367,16 @@ class UpdatesAvailable(InternalDialog):
231 self.alert_watcher.connect("network-3g-alert",
232 self._on_network_3g_alert)
233
234+ try:
235+ from uaclient.api.u.apt_news.current_news.v1 import current_news
236+ apt_news = current_news().current_news
237+ except ImportError:
238+ pro_client_apt_news_api_supported = False
239+ apt_news = self._get_apt_news("/var/lib/ubuntu-advantage/messages/apt-news")
240+ if apt_news:
241+ self.news.get_buffer().set_text(apt_news)
242+ self.expander_news.set_visible(True)
243+
244 def stop(self):
245 InternalDialog.stop(self)
246 self._save_state()
247@@ -508,8 +522,16 @@ class UpdatesAvailable(InternalDialog):
248
249 renderer.set_property("markup", markup)
250
251- def set_changes_buffer(self, changes_buffer, text, name, srcpkg):
252- changes_buffer.set_text("")
253+ def set_changes_buffer(self, changes_buffer, long_desc, text, name, srcpkg):
254+ changes_buffer.set_text("") # Clear "downloading list of changes..."
255+
256+ # Write the technical description section
257+ changes_buffer.insert_with_tags_by_name(changes_buffer.get_end_iter(),
258+ "Technical description\n",
259+ "descriptiontag")
260+ changes_buffer.insert(changes_buffer.get_end_iter(), long_desc + "\n\n")
261+
262+ # Write the changes section
263 lines = text.split("\n")
264 if len(lines) == 1:
265 changes_buffer.set_text(text)
266@@ -521,12 +543,16 @@ class UpdatesAvailable(InternalDialog):
267 r'^%s \((.*)\)(.*)\;.*$' % re.escape(srcpkg), line)
268 #bullet_match = re.match("^.*[\*-]", line)
269 author_match = re.match("^.*--.*<.*@.*>.*$", line)
270+ changes_match = re.match(r'^Changes for [^ ]+ versions:$', line)
271 if version_match:
272 version = version_match.group(1)
273 #upload_archive = version_match.group(2).strip()
274 version_text = _("Version %s: \n") % version
275 changes_buffer.insert_with_tags_by_name(end_iter, version_text,
276 "versiontag")
277+ elif changes_match:
278+ changes_buffer.insert_with_tags_by_name(end_iter, line + "\n",
279+ "changestag")
280 elif (author_match):
281 pass
282 else:
283@@ -551,12 +577,8 @@ class UpdatesAvailable(InternalDialog):
284 item.pkg.candidate.description is None):
285 changes_buffer = self.textview_changes.get_buffer()
286 changes_buffer.set_text("")
287- desc_buffer = self.textview_descr.get_buffer()
288- desc_buffer.set_text("")
289- self.notebook_details.set_sensitive(False)
290 return
291 long_desc = item.pkg.candidate.description
292- self.notebook_details.set_sensitive(True)
293 # do some regular expression magic on the description
294 # Add a newline before each bullet
295 p = re.compile(r'^(\s|\t)*(\*|0|-)', re.MULTILINE)
296@@ -568,9 +590,6 @@ class UpdatesAvailable(InternalDialog):
297 p = re.compile(r'\s\s+', re.MULTILINE)
298 long_desc = p.sub("\n", long_desc)
299
300- desc_buffer = self.textview_descr.get_buffer()
301- desc_buffer.set_text(long_desc)
302-
303 # now do the changelog
304 name = item.pkg.name
305 if name is None:
306@@ -583,7 +602,7 @@ class UpdatesAvailable(InternalDialog):
307 if name in self.cache.all_changes:
308 changes = self.cache.all_changes[name]
309 srcpkg = self.cache[name].candidate.source_name
310- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
311+ self.set_changes_buffer(changes_buffer, long_desc, changes, name, srcpkg)
312 # if not connected, do not even attempt to get the changes
313 elif not self.connected:
314 changes_buffer.set_text(
315@@ -628,8 +647,9 @@ class UpdatesAvailable(InternalDialog):
316 changes += self.cache.all_news[name]
317 if name in self.cache.all_changes:
318 changes += self.cache.all_changes[name]
319- if changes:
320- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
321+
322+ if changes or long_desc:
323+ self.set_changes_buffer(changes_buffer, long_desc, changes, name, srcpkg)
324
325 def on_treeview_button_press(self, widget, event):
326 """
327@@ -656,6 +676,11 @@ class UpdatesAvailable(InternalDialog):
328 menu.show()
329 return True
330
331+ def _get_apt_news(self, apt_news_file):
332+ if os.access(apt_news_file, os.R_OK):
333+ with open(apt_news_file) as f:
334+ return f.read()
335+
336 # we need this for select all/unselect all
337 def _toggle_group_headers(self, new_selection_value):
338 """ small helper that will set/unset the group headers
339@@ -753,6 +778,7 @@ class UpdatesAvailable(InternalDialog):
340 # self.button_install.set_sensitive(True)
341 self.button_install.set_sensitive(True)
342 self.unity.set_install_menuitem_visible(True)
343+ self.button_pro.destroy()
344 else:
345 if inst_count > 0:
346 download_str = ngettext(
347@@ -761,10 +787,15 @@ class UpdatesAvailable(InternalDialog):
348 inst_count)
349 self.button_install.set_sensitive(True)
350 self.unity.set_install_menuitem_visible(True)
351+ self.button_pro.destroy()
352+ elif self.list.ubuntu_pro_fake_groups and not self.list.ubuntu_pro_groups:
353+ download_str = _("You need to enable Ubuntu Pro to install these updates.")
354+ self.button_install.destroy()
355 else:
356 download_str = _("There are no updates to install.")
357 self.button_install.set_sensitive(False)
358 self.unity.set_install_menuitem_visible(False)
359+ self.button_pro.destroy()
360 self.image_downsize.set_sensitive(False)
361 self.label_downsize.set_text(download_str)
362 self.hbox_downsize.show()
363@@ -809,7 +840,6 @@ class UpdatesAvailable(InternalDialog):
364 text_desc = _("The computer also needs to restart "
365 "to finish installing previous updates.")
366
367- self.notebook_details.set_sensitive(True)
368 self.treeview_update.set_sensitive(True)
369 self.set_header(text_header)
370 self.set_desc(text_desc)
371@@ -830,8 +860,10 @@ class UpdatesAvailable(InternalDialog):
372 self._restore_state()
373
374 def activate_desc(self, expander, data):
375- expanded = self.expander_desc.get_expanded()
376- self.expander_desc.set_vexpand(expanded)
377+ return
378+
379+ def on_button_pro_clicked(self):
380+ self.window_main.show_settings(SoftwarePropertiesPage.ubuntu_pro)
381
382 def on_button_install_clicked(self):
383 self.unity.set_install_menuitem_visible(False)
384@@ -1029,6 +1061,8 @@ class UpdatesAvailable(InternalDialog):
385 len(group.items) == 1:
386 group_is_item = group.items[0]
387
388+ if group.name == "Ubuntu base":
389+ group.name = "System components"
390 group_row = [
391 group.name,
392 UpdateData(None, group, group_is_item),
393@@ -1067,11 +1101,8 @@ class UpdatesAvailable(InternalDialog):
394 if self.list.security_groups:
395 self._add_header(_("Security updates"), self.list.security_groups)
396 self._add_groups(self.list.security_groups)
397- if self.list.security_groups and self.list.update_groups:
398- self._add_header(_("Other updates"), self.list.update_groups)
399- elif self.list.update_groups and self.list.kernel_autoremove_groups:
400- self._add_header(_("Updates"), self.list.update_groups)
401 if self.list.update_groups:
402+ self._add_header(_("Other updates"), self.list.update_groups)
403 self._add_groups(self.list.update_groups)
404 if self.list.kernel_autoremove_groups:
405 self._add_header(
406@@ -1079,11 +1110,17 @@ class UpdatesAvailable(InternalDialog):
407 self.list.kernel_autoremove_groups)
408 self._add_groups(self.list.kernel_autoremove_groups)
409 if self.list.ubuntu_pro_groups:
410- self._add_header(_("Ubuntu Pro (enable in Settingsā€¦)"), self.list.ubuntu_pro_groups, sensitive=False)
411+ self._add_header(_("Ubuntu Pro security updates"), self.list.ubuntu_pro_groups, sensitive=True)
412 self._add_groups(self.list.ubuntu_pro_groups)
413+ if self.list.ubuntu_pro_fake_groups:
414+ self._add_header(_("Ubuntu Pro security updates (enable in Settingsā€¦)"), self.list.ubuntu_pro_fake_groups, sensitive=False)
415+ self._add_groups(self.list.ubuntu_pro_fake_groups)
416
417 self.treeview_update.set_model(self.store)
418 self.pkg_cell_area.indent_toplevel = (
419+ bool(self.list.ubuntu_pro_fake_groups) or
420+ bool(self.list.ubuntu_pro_groups) or
421+ bool(self.list.update_groups) or
422 bool(self.list.security_groups) or
423 bool(self.list.kernel_autoremove_groups))
424 self.update_close_button()
425diff --git a/data/gtkbuilder/UpdateManager.ui b/data/gtkbuilder/UpdateManager.ui
426index a16ff47..d5321a2 100644
427--- a/data/gtkbuilder/UpdateManager.ui
428+++ b/data/gtkbuilder/UpdateManager.ui
429@@ -6,17 +6,48 @@
430 <property name="can_focus">False</property>
431 <property name="spacing">12</property>
432 <child>
433+ <object class="GtkExpander" id="expander_news">
434+ <property name="visible">False</property>
435+ <property name="can_focus">True</property>
436+ <property name="label">News</property>
437+ <property name="spacing">6</property>
438+ <property name="expanded">True</property>
439+ <child>
440+ <object class="GtkScrolledWindow">
441+ <property name="visible">True</property>
442+ <property name="can_focus">True</property>
443+ <property name="shadow_type">in</property>
444+ <property name="min_content_height">80</property>
445+ <child>
446+ <object class="GtkTextView" id="news">
447+ <property name="visible">True</property>
448+ <property name="editable">False</property>
449+ <property name="pixels_above_lines">6</property>
450+ <property name="left_margin">6</property>
451+ <property name="right_margin">6</property>
452+ <property name="wrap_mode">word</property>
453+ <property name="cursor_visible">False</property>
454+ <property name="accepts_tab">False</property>
455+ </object>
456+ </child>
457+ </object>
458+ </child>
459+ </object>
460+ <packing>
461+ <property name="expand">False</property>
462+ <property name="position">0</property>
463+ </packing>
464+ </child>
465+ <child>
466 <object class="GtkExpander" id="expander_details">
467 <property name="visible">True</property>
468 <property name="can_focus">True</property>
469 <property name="spacing">6</property>
470 <property name="resize_toplevel">True</property>
471 <child>
472- <object class="GtkVBox" id="vbox4">
473+ <object class="GtkPaned" id="paned">
474 <property name="visible">True</property>
475- <property name="can_focus">False</property>
476- <property name="vexpand">True</property>
477- <property name="spacing">6</property>
478+ <property name="orientation">vertical</property>
479 <child>
480 <object class="GtkScrolledWindow" id="scrolledwindow_update">
481 <property name="visible">True</property>
482@@ -44,113 +75,21 @@
483 </child>
484 </object>
485 <packing>
486- <property name="expand">True</property>
487- <property name="fill">True</property>
488- <property name="position">0</property>
489+ <property name="shrink">False</property>
490+ <property name="resize">True</property>
491 </packing>
492 </child>
493 <child>
494- <object class="GtkExpander" id="expander_desc">
495+ <object class="GtkScrolledWindow" id="scrolledwindow_changes">
496 <property name="visible">True</property>
497 <property name="can_focus">True</property>
498+ <property name="shadow_type">in</property>
499 <child>
500- <object class="GtkNotebook" id="notebook_details">
501- <property name="visible">True</property>
502- <property name="can_focus">True</property>
503- <property name="show_border">False</property>
504- <child>
505- <object class="GtkVBox" id="vbox5">
506- <property name="visible">True</property>
507- <property name="can_focus">False</property>
508- <property name="border_width">6</property>
509- <property name="spacing">6</property>
510- <child>
511- <object class="GtkScrolledWindow" id="scrolledwindow_changes">
512- <property name="visible">True</property>
513- <property name="can_focus">True</property>
514- <property name="shadow_type">in</property>
515- <child>
516- <placeholder/>
517- </child>
518- </object>
519- <packing>
520- <property name="expand">True</property>
521- <property name="fill">True</property>
522- <property name="position">0</property>
523- </packing>
524- </child>
525- </object>
526- </child>
527- <child type="tab">
528- <object class="GtkLabel" id="label8">
529- <property name="visible">True</property>
530- <property name="can_focus">False</property>
531- <property name="label" translatable="yes">Changes</property>
532- </object>
533- <packing>
534- <property name="tab_fill">False</property>
535- </packing>
536- </child>
537- <child>
538- <object class="GtkScrolledWindow" id="scrolledwindow3">
539- <property name="visible">True</property>
540- <property name="can_focus">True</property>
541- <property name="border_width">6</property>
542- <property name="shadow_type">in</property>
543- <property name="min_content_height">80</property>
544- <child>
545- <object class="GtkTextView" id="textview_descr">
546- <property name="visible">True</property>
547- <property name="can_focus">True</property>
548- <property name="pixels_above_lines">6</property>
549- <property name="editable">False</property>
550- <property name="wrap_mode">word</property>
551- <property name="left_margin">6</property>
552- <property name="right_margin">6</property>
553- <property name="cursor_visible">False</property>
554- <property name="accepts_tab">False</property>
555- <child internal-child="accessible">
556- <object class="AtkObject" id="textview_descr-atkobject">
557- <property name="AtkObject::accessible-name" translatable="yes">Description</property>
558- </object>
559- </child>
560- </object>
561- </child>
562- </object>
563- <packing>
564- <property name="position">1</property>
565- </packing>
566- </child>
567- <child type="tab">
568- <object class="GtkLabel" id="label9">
569- <property name="visible">True</property>
570- <property name="can_focus">False</property>
571- <property name="label" translatable="yes">Description</property>
572- <child internal-child="accessible">
573- <object class="AtkObject" id="label9-atkobject">
574- <property name="AtkObject::accessible-name" translatable="yes">Description</property>
575- </object>
576- </child>
577- </object>
578- <packing>
579- <property name="position">1</property>
580- <property name="tab_fill">False</property>
581- </packing>
582- </child>
583- </object>
584- </child>
585- <child type="label">
586- <object class="GtkLabel" id="label13">
587- <property name="visible">True</property>
588- <property name="can_focus">False</property>
589- <property name="label" translatable="yes">Technical description</property>
590- </object>
591+ <placeholder/>
592 </child>
593 </object>
594 <packing>
595- <property name="expand">False</property>
596- <property name="fill">True</property>
597- <property name="position">1</property>
598+ <property name="resize">True</property>
599 </packing>
600 </child>
601 </object>
602@@ -167,7 +106,7 @@
603 <packing>
604 <property name="expand">True</property>
605 <property name="fill">True</property>
606- <property name="position">2</property>
607+ <property name="position">1</property>
608 </packing>
609 </child>
610 <child>
611@@ -177,12 +116,13 @@
612 <child>
613 <object class="GtkHBox" id="hbox_downsize">
614 <property name="can_focus">False</property>
615- <property name="spacing">12</property>
616+ <property name="spacing">8</property>
617 <child>
618 <object class="GtkImage" id="image_downsize">
619 <property name="visible">True</property>
620 <property name="can_focus">False</property>
621 <property name="icon_name">aptdaemon-download</property>
622+ <property name="pixel_size">16</property>
623 </object>
624 <packing>
625 <property name="expand">False</property>
626@@ -400,7 +340,7 @@
627 <packing>
628 <property name="expand">False</property>
629 <property name="fill">True</property>
630- <property name="position">3</property>
631+ <property name="position">2</property>
632 </packing>
633 </child>
634 </object>
635diff --git a/debian/changelog b/debian/changelog
636index bc40574..4be724a 100644
637--- a/debian/changelog
638+++ b/debian/changelog
639@@ -1,3 +1,16 @@
640+update-manager (1:18.04.11.18) bionic; urgency=medium
641+
642+ * Ubuntu Pro (LP: #1990450):
643+ - Show Ubuntu Pro packages, whether the system is attached to Ubuntu Pro
644+ or not.
645+ - Replace Install now button by Enable Ubuntu Pro button when only Ubuntu
646+ Pro packages are available and the machine is not attached.
647+ - Fix checkbox and expander widget from overlapping.
648+ - Add News pane in a expander.
649+ - Replace notebook with Description and Changes tabs by a pane.
650+
651+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Tue, 29 Aug 2023 07:47:20 +0200
652+
653 update-manager (1:18.04.11.17) bionic; urgency=medium
654
655 * Fix Ubuntu Pro updates checkbox and expander widget from overlapping
656diff --git a/debian/control b/debian/control
657index 4d4cbd8..ad91c50 100644
658--- a/debian/control
659+++ b/debian/control
660@@ -27,8 +27,10 @@ Depends: ${python3:Depends},
661 ${misc:Depends},
662 python3-update-manager (= ${source:Version}),
663 python3-distro-info,
664+ python3-yaml,
665 distro-info-data,
666 lsb-release,
667+ ubuntu-advantage-tools,
668 ubuntu-release-upgrader-core (>= 1:18.04.9)
669 Recommends: libpam-modules (>= 1.0.1-9ubuntu3)
670 Replaces: update-manager (<< 1:0.146.2)

Subscribers

People subscribed via source and target branches