diff -Nru software-properties-0.99.26/data/gtkbuilder/dialog-ua-attach.ui software-properties-0.99.27/data/gtkbuilder/dialog-ua-attach.ui --- software-properties-0.99.26/data/gtkbuilder/dialog-ua-attach.ui 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/data/gtkbuilder/dialog-ua-attach.ui 2022-10-07 07:47:15.000000000 +0000 @@ -2,7 +2,7 @@ 18 - Ubuntu Advantage + Enable Ubuntu Pro False True dialog @@ -19,7 +19,8 @@ True - <a href="https://ubuntu.com/advantage">Sign into your Ubuntu Advantage account</a> to attach this machine to your subscription. + Enter your Ubuntu Pro token here. +From <a href="https://ubuntu.com/pro">ubuntu.com/pro</a> or your system administrator True 0 @@ -32,7 +33,7 @@ True - Ubuntu Advantage Token: + Token: 0 @@ -63,6 +64,18 @@ + + True + 0 + <a href="https://login.ubuntu.com">Don't have a token yet? Register</a> + True + + + 1 + 1 + + + True 0 @@ -73,7 +86,7 @@ 1 - 1 + 2 @@ -89,7 +102,8 @@ True - Cancel + Cance_l + True @@ -97,7 +111,8 @@ True False - Attach + _Continue + True diff -Nru software-properties-0.99.26/data/gtkbuilder/dialog-ua-detach.ui software-properties-0.99.27/data/gtkbuilder/dialog-ua-detach.ui --- software-properties-0.99.26/data/gtkbuilder/dialog-ua-detach.ui 1970-01-01 00:00:00.000000000 +0000 +++ software-properties-0.99.27/data/gtkbuilder/dialog-ua-detach.ui 2022-10-07 07:47:15.000000000 +0000 @@ -0,0 +1,64 @@ + + + + 18 + Disable Ubuntu Pro + False + True + dialog + True + + + vertical + 18 + + + True + vertical + 18 + + + True + Disabling Ubuntu Pro will detach your subscription from this machine. Do you want to proceed? + True + 0 + + + + + True + 0 + + + + + + + + + + + + + True + end + + + True + No, go _back + True + + + + + + True + _Disable Ubuntu Pro + True + + + + + + + diff -Nru software-properties-0.99.26/data/gtkbuilder/dialog-ua-fips-enable.ui software-properties-0.99.27/data/gtkbuilder/dialog-ua-fips-enable.ui --- software-properties-0.99.26/data/gtkbuilder/dialog-ua-fips-enable.ui 1970-01-01 00:00:00.000000000 +0000 +++ software-properties-0.99.27/data/gtkbuilder/dialog-ua-fips-enable.ui 2022-10-07 07:47:15.000000000 +0000 @@ -0,0 +1,82 @@ + + + + 18 + Enable FIPS + False + True + dialog + True + + + vertical + 18 + + + True + vertical + 18 + + + True + Enabling FIPS cannot be reversed and Livepatch will be permanently disabled. Choose your preferred FIPS option. + 0 + + + + + True + + + True + <b>FIPS with updates</b> +Installs FIPS 140-2 validated packages and allows for regular security updates. + True + 0 + + + + + + + True + radio_fips_with_updates + + + True + <b>FIPS without updates</b> +Installs FIPS 140-2 validated packages. These will not be updated until the next recertification. + True + 0 + + + + + + + + + + + True + end + + + True + Cance_l + True + + + + + + True + _Continue + True + + + + + + + diff -Nru software-properties-0.99.26/data/gtkbuilder/main.ui software-properties-0.99.27/data/gtkbuilder/main.ui --- software-properties-0.99.26/data/gtkbuilder/main.ui 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/data/gtkbuilder/main.ui 2022-10-07 07:47:15.000000000 +0000 @@ -1235,165 +1235,219 @@ - - True - 12 - vertical - 12 - - - False - <b>Settings</b> - True - True - 1 - 0 - - + + False - + True + 12 + vertical + 12 + + + True + <b>Subscription</b> + True + True + 1 + 0 + + - + True - 12 - + True - Attach this machine + 36 + 18 + + + + + + True + + + True + 24 + + + True + center + _Enable Ubuntu Pro + True + + + + + True + <b>This machine is not covered by an Ubuntu Pro subscription.</b> +Receive security updates for over 25,000 Ubuntu packages, on up to 3 machines free for personal use. <a href="https://ubuntu.com/pro">Learn more</a>. + True + True + 90 + 0 + + + + + + + True + 24 + + + True + center + _Disable Ubuntu Pro + True + + + + + True + 6 + + + True + emblem-default + + + + + True + True + <span foreground="green">Ubuntu Pro support is enabled</span> + 0 + + + + + + + + + + + + + True + False + <b>Security</b> + True + True + 1 + 0 + + + + + True + 12 + 12 - - False - This machine is not covered by an Ubuntu Pro subscription. Receive security updates for over 30,000 Ubuntu packages, on up to 3 machines free for personal use: <a href="https://ubuntu.com/advantage">More information</a>. - True - True - 90 - 0 + + True + start + center + + 0 + 0 + - + True - This machine is not covered by an Ubuntu Advantage subscription. True - True - 90 + center 0 + + 1 + 0 + - - - - - True - 12 - - True - Detach this machine - - - - + False - Ubuntu Pro subscription attached. + Could not enable ESM Infra. Please try again. + center 0 + + + + + + 1 + 1 + - + True - Ubuntu Advantage subscription attached. - 0 + start + center + + 0 + 2 + - - - - - - - False - False - <b>Services</b> - True - True - 1 - 0 - - - - - True - 12 - False - - - False - start - - - - - False - vertical - 6 - + True - <b>Extended Security Maintenance</b> provides security updates for over 30,000 Ubuntu packages. True + 0 + + 1 + 2 + - + False - Could not enable Extended Security Maintenance. Please try again. + Could not enable ESM Apps. Please try again. 0 + + 1 + 3 + - - - - - - - True - 12 - False - - - True - start - - - - - True - vertical - 6 - + True - <b>Livepatch</b> helps keep your system secure by applying security updates that don't require a restart. - True - 0 + start + center + + 0 + 4 + - + True - Show Livepatch status in the top bar - False - start - True + <b>Kernel Livepatch</b> helps keep your system secure by applying security updates that don't require a restart. + True + 0 + + 1 + 4 + @@ -1405,187 +1459,149 @@ + + 1 + 5 + + + + + True + Show Livepatch status in the top bar + False + start + True + + + 1 + 6 + - - - - - False - <b>Compliance &amp; Hardening</b> - True - 0 - - - - - False - Please read the documentation and only enable these settings if you specifically require these certifications. - True - 0 - - - - - False - - True - vertical - 12 - 18 + + True - + True - 12 - False - - - True - start - - - + 18 + True vertical - 6 + 12 True - <b>FIPS 140-2 Level 1.</b> <a href="https://ubuntu.com/security/certifications#fips">FIPS documentation.</a> + <b>Compliance &amp; Hardening</b> True - 0 + 0 - - False - Could not enable FIPS 140-2 Level 1. Please try again. + + True + Only recommended to assist with FedRAMP, HIPAA, and other compliance and hardening requirements. Includes FIPS 140-2 certified modules, DISA-STIG, CIS and Common Criteria. + True 0 - - - - + 90 - - - - - True - 12 - False - - - True - start - - - + True vertical - 6 + 12 + 12 + 12 - + True - <b>FIPS Updates.</b> <a href="https://ubuntu.com/security/certifications#fips-updates">FIPS Updates documentation.</a> - True - 0 + 160 + + + True + Enable _FIPS + True + + + + 0 + 0 + - - False - Could not enable FIPS Updates. Please try again. + + True + <b>FIPS 140-2</b> + True 0 - - - - + + 1 + 0 + - - - - - - - True - 12 - False - - - True - start - - - - - True - vertical - 6 - + True - <b>CC-EAL2.</b> <a href="https://ubuntu.com/security/certifications#common-criteria">CC-EAL2 documentation.</a> + A US and Canada government cryptographic module certification of compliance with the FIPS 140-2 data protection standard. <a href="https://ubuntu.com/security/certifications/docs/fips">FIPS documentation</a> True + True 0 + 75 + + 1 + 1 + - - False - Could not enable CC-EAL2. Please try again. - 0 - - - - + + True + 160 + + + True + Enable _USG + True + + + + 0 + 2 + - - - - - - - True - 12 - False - - - True - start - - - - - True - vertical - 6 - + True - <b>CIS Tools.</b> <a href="https://ubuntu.com/security/certifications#cis-tools">CIS Tools documentation.</a> + <b>Ubuntu Security Guide (USG)</b> True 0 + + 1 + 2 + - - False - Could not enable CIS Tools. Please try again. + + True + Automates hardening and auditing with CIS benchmark and DISA-STIG profiles while allowing for environment-specific customizations. <a href="https://ubuntu.com/security/certifications/docs/usg">USG documentation</a> + True + True 0 - - - - + 75 + + 1 + 3 + @@ -1594,30 +1610,45 @@ + + 6 + - - - 6 - - - - - True - + True - False - Livepatch - - - - - False - False - Ubuntu Pro + + + True + vertical + 18 + True + center + center + + + True + True + + + + + True + Setting up FIPS + + + + + + + + True + False + Ubuntu Pro + 6 False diff -Nru software-properties-0.99.26/data/ubuntu-pro-logo.svg software-properties-0.99.27/data/ubuntu-pro-logo.svg --- software-properties-0.99.26/data/ubuntu-pro-logo.svg 1970-01-01 00:00:00.000000000 +0000 +++ software-properties-0.99.27/data/ubuntu-pro-logo.svg 2022-10-07 07:47:15.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru software-properties-0.99.26/debian/changelog software-properties-0.99.27/debian/changelog --- software-properties-0.99.26/debian/changelog 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/debian/changelog 2022-10-07 07:47:15.000000000 +0000 @@ -1,3 +1,13 @@ +software-properties (0.99.27) kinetic; urgency=medium + + * Don't display the Ubuntu Pro tab on non LTS series since the service + isn't available there. + + [ Robert Ancell ] + * Show Ubuntu Pro settings (LP: #1990448). + + -- Sebastien Bacher Fri, 07 Oct 2022 09:47:15 +0200 + software-properties (0.99.26) kinetic; urgency=medium * Drop unused snapd-glib dependencies diff -Nru software-properties-0.99.26/debian/software-properties-gtk.install software-properties-0.99.27/debian/software-properties-gtk.install --- software-properties-0.99.26/debian/software-properties-gtk.install 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/debian/software-properties-gtk.install 2022-10-07 07:47:15.000000000 +0000 @@ -9,3 +9,4 @@ debian/tmp/usr/share/metainfo/software-properties-gtk.appdata.xml debian/tmp/usr/share/mime/packages debian/tmp/usr/share/software-properties/gtkbuilder +debian/tmp/usr/share/software-properties/ubuntu-pro-logo.svg diff -Nru software-properties-0.99.26/po/POTFILES.in software-properties-0.99.27/po/POTFILES.in --- software-properties-0.99.26/po/POTFILES.in 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/po/POTFILES.in 2022-10-07 07:47:15.000000000 +0000 @@ -29,6 +29,7 @@ softwareproperties/gtk/DialogAdd.py softwareproperties/gtk/DialogCacheOutdated.py softwareproperties/gtk/DialogUaAttach.py +softwareproperties/gtk/DialogUaDetach.py softwareproperties/gtk/UbuntuProPage.py softwareproperties/CountryInformation.py softwareproperties/AptAuth.py @@ -43,3 +44,5 @@ [type: gettext/glade]data/gtkbuilder/dialog-mirror.ui [type: gettext/glade]data/gtkbuilder/dialog-add.ui [type: gettext/glade]data/gtkbuilder/dialog-ua-attach.ui +[type: gettext/glade]data/gtkbuilder/dialog-ua-detach.ui +[type: gettext/glade]data/gtkbuilder/dialog-ua-fips-enable.ui diff -Nru software-properties-0.99.26/softwareproperties/AptAuth.py software-properties-0.99.27/softwareproperties/AptAuth.py --- software-properties-0.99.26/softwareproperties/AptAuth.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/AptAuth.py 2022-10-07 07:47:15.000000000 +0000 @@ -31,8 +31,7 @@ # gettext convenient _ = gettext.gettext -def dummy(e): return e -N_ = dummy +N_ = lambda e: e # some known keys N_("Ubuntu Archive Automatic Signing Key ") diff -Nru software-properties-0.99.26/softwareproperties/gtk/DialogUaAttach.py software-properties-0.99.27/softwareproperties/gtk/DialogUaAttach.py --- software-properties-0.99.26/softwareproperties/gtk/DialogUaAttach.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/gtk/DialogUaAttach.py 2022-10-07 07:47:15.000000000 +0000 @@ -18,64 +18,67 @@ import os from gettext import gettext as _ +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk from softwareproperties.gtk.utils import ( setup_ui, ) class DialogUaAttach: - def __init__(self, parent, datadir, ua_object): - """setup up the gtk dialog""" - setup_ui(self, os.path.join(datadir, "gtkbuilder", "dialog-ua-attach.ui"), domain="software-properties") - - self.ua_object = ua_object - self.dialog = self.dialog_ua_attach - self.dialog.set_transient_for(parent) - - self.attaching = False - - def run(self): - self.dialog.run() - self.dialog.hide() - - def update_state(self): - have_token = self.entry_token.get_text() != '' - self.button_attach.set_sensitive(have_token and not self.attaching) - self.entry_token.set_sensitive(not self.attaching) - if self.attaching: - self.spinner.start() - else: - self.spinner.stop() - - def attach(self): - if self.attaching: - return - - token = self.entry_token.get_text() - if token == '': - return - - self.attaching = True - self.label_attach_error.set_text('') - def on_reply(): - self.dialog.response(0) - def on_error(error): - # FIXME - print(error) - self.label_attach_error.set_text(_('Failed to attach. Please try again')) + def __init__(self, parent, datadir, ua_object): + """setup up the gtk dialog""" + setup_ui(self, os.path.join(datadir, "gtkbuilder", "dialog-ua-attach.ui"), domain="software-properties") + + self.ua_object = ua_object + self.dialog = self.dialog_ua_attach + self.dialog.set_transient_for(parent) + self.attaching = False + + def run(self): + self.dialog.run() + self.dialog.hide() + + def update_state(self): + have_token = self.entry_token.get_text() != '' + self.button_attach.set_sensitive(have_token and not self.attaching) + self.entry_token.set_sensitive(not self.attaching) + if self.attaching: + self.spinner.start() + else: + self.spinner.stop() + + def attach(self): + if self.attaching: + return + + token = self.entry_token.get_text() + if token == '': + return + + self.attaching = True + self.label_attach_error.set_text('') + def on_reply(): + self.dialog.response(Gtk.ResponseType.OK) + def on_error(error): + # FIXME + print(error) + self.label_attach_error.set_text(_('Failed to attach. Please try again')) + self.attaching = False + self.update_state() + self.ua_object.Attach(token, reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Manager', timeout=600) self.update_state() - self.ua_object.Attach(token, reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Manager') - self.update_state() - def on_token_entry_changed(self, entry): - self.update_state() + def on_token_entry_changed(self, entry): + self.update_state() - def on_token_entry_activate(self, entry): - self.attach() + def on_token_entry_activate(self, entry): + self.attach() - def on_attach_clicked(self, button): - self.attach() + def on_attach_clicked(self, button): + self.attach() - def on_cancel_clicked(self, button): - self.dialog.response(0) + def on_cancel_clicked(self, button): + self.dialog.response(Gtk.ResponseType.CANCEL) diff -Nru software-properties-0.99.26/softwareproperties/gtk/DialogUaDetach.py software-properties-0.99.27/softwareproperties/gtk/DialogUaDetach.py --- software-properties-0.99.26/softwareproperties/gtk/DialogUaDetach.py 1970-01-01 00:00:00.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/gtk/DialogUaDetach.py 2022-10-07 07:47:15.000000000 +0000 @@ -0,0 +1,71 @@ +# +# Copyright (c) 2022 Canonical Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +import os +from gettext import gettext as _ +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +from softwareproperties.gtk.utils import ( + setup_ui, +) + +class DialogUaDetach: + def __init__(self, parent, datadir, ua_object): + """setup up the gtk dialog""" + setup_ui(self, os.path.join(datadir, "gtkbuilder", "dialog-ua-detach.ui"), domain="software-properties") + + self.ua_object = ua_object + self.dialog = self.dialog_ua_detach + self.dialog.set_transient_for(parent) + + self.detaching = False + + def run(self): + self.dialog.run() + self.dialog.hide() + + def update_state(self): + self.button_detach.set_sensitive(not self.detaching) + + def detach(self): + if self.detaching: + return + + self.detaching = True + self.label_detach_error.set_text('') + def on_reply(): + self.dialog.response(Gtk.ResponseType.OK) + def on_error(error): + # FIXME + print(error) + self.label_detach_error.set_text(_('Failed to detach. Please try again')) + self.detaching = False + self.update_state() + self.ua_object.Detach(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Manager', timeout=600) + self.update_state() + + def on_token_entry_changed(self, entry): + self.update_state() + + def on_detach_clicked(self, button): + self.detach() + + def on_cancel_clicked(self, button): + self.dialog.response(Gtk.ResponseType.CANCEL) diff -Nru software-properties-0.99.26/softwareproperties/gtk/DialogUaFipsEnable.py software-properties-0.99.27/softwareproperties/gtk/DialogUaFipsEnable.py --- software-properties-0.99.26/softwareproperties/gtk/DialogUaFipsEnable.py 1970-01-01 00:00:00.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/gtk/DialogUaFipsEnable.py 2022-10-07 07:47:15.000000000 +0000 @@ -0,0 +1,52 @@ +# +# Copyright (c) 2022 Canonical Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +import os +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +from softwareproperties.gtk.utils import ( + setup_ui, +) + +class DialogUaFipsEnable: + def __init__(self, parent, datadir, ua_object): + """setup up the gtk dialog""" + setup_ui(self, os.path.join(datadir, "gtkbuilder", "dialog-ua-fips-enable.ui"), domain="software-properties") + + self.ua_object = ua_object + self.dialog = self.dialog_ua_fips_enable + self.dialog.set_transient_for(parent) + + def run(self): + result = self.dialog.run() + self.dialog.hide() + if result == Gtk.ResponseType.OK: + if self.radio_fips_with_updates.get_active(): + return 'fips-updates' + else: + return 'fips' + else: + return None + + def on_continue_clicked(self, button): + self.dialog.response(Gtk.ResponseType.OK) + + def on_cancel_clicked(self, button): + self.dialog.response(Gtk.ResponseType.CANCEL) diff -Nru software-properties-0.99.26/softwareproperties/gtk/SoftwarePropertiesGtk.py software-properties-0.99.27/softwareproperties/gtk/SoftwarePropertiesGtk.py --- software-properties-0.99.26/softwareproperties/gtk/SoftwarePropertiesGtk.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/gtk/SoftwarePropertiesGtk.py 2022-10-07 07:47:15.000000000 +0000 @@ -248,8 +248,9 @@ self.show_distro() # Setup and show the Additonal Drivers tab self.init_drivers() - # Setup and show the Ubuntu Pro tab - self.init_ubuntu_pro() + # Setup and show the Ubuntu Pro tab if the serie is a LTS + if is_current_distro_lts(): + self.init_ubuntu_pro() # Connect to switch-page before setting initial tab. Otherwise the # first switch goes unnoticed. @@ -270,6 +271,9 @@ apt_pkg.config.find("Dir::Etc::sourcelist"))): self.open_file(file) + # Make sure window is as small as possible initially. + self.window_main.resize(1, 1) + def on_main_notebook_page_switched(self, notebook, page, page_num): # On the additional drivers page, don't show the backend revert button. if page == self.vbox_drivers: diff -Nru software-properties-0.99.26/softwareproperties/gtk/UbuntuProPage.py software-properties-0.99.27/softwareproperties/gtk/UbuntuProPage.py --- software-properties-0.99.26/softwareproperties/gtk/UbuntuProPage.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/gtk/UbuntuProPage.py 2022-10-07 07:47:15.000000000 +0000 @@ -17,9 +17,16 @@ # USA import dbus -from gi.repository import Gio +import os +from gettext import gettext as _ +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import GdkPixbuf, Gio, Gtk +from softwareproperties.gtk.utils import current_distro from .DialogUaAttach import DialogUaAttach +from .DialogUaDetach import DialogUaDetach +from .DialogUaFipsEnable import DialogUaFipsEnable class UaService: def __init__(self, bus_object, name, entitled, status): @@ -34,39 +41,54 @@ def __init__(self, parent): self._parent = parent - self.detaching = False - self.stack_ua_attach = parent.stack_ua_attach self.box_ua_attached = parent.box_ua_attached self.box_ua_unattached = parent.box_ua_unattached - self.box_ua_esm = parent.box_ua_esm - self.switch_ua_esm = parent.switch_ua_esm - self.label_ua_esm_error = parent.label_ua_esm_error - self.box_ua_livepatch = parent.box_ua_livepatch + self.stack_ua_main = parent.stack_ua_main + self.box_ua_options = parent.box_ua_options + self.box_ua_fips_setup = parent.box_ua_fips_setup + self.switch_ua_esm_infra = parent.switch_ua_esm_infra + self.label_ua_esm_infra = parent.label_ua_esm_infra + self.label_ua_esm_infra_error = parent.label_ua_esm_infra_error + self.switch_ua_esm_apps = parent.switch_ua_esm_apps + self.label_ua_esm_apps = parent.label_ua_esm_apps + self.label_ua_esm_apps_error = parent.label_ua_esm_apps_error self.switch_ua_livepatch = parent.switch_ua_livepatch self.checkbutton_livepatch_topbar = parent.checkbutton_livepatch_topbar + self.label_ua_livepatch = parent.label_ua_livepatch self.label_ua_livepatch_error = parent.label_ua_livepatch_error - self.box_ua_fips = parent.box_ua_fips - self.switch_ua_fips = parent.switch_ua_fips - self.label_ua_fips_error = parent.label_ua_fips_error - self.box_ua_fips_updates = parent.box_ua_fips_updates - self.switch_ua_fips_updates = parent.switch_ua_fips_updates - self.label_ua_fips_updates_error = parent.label_ua_fips_updates_error - self.box_ua_cc_eal = parent.box_ua_cc_eal - self.switch_ua_cc_eal = parent.switch_ua_cc_eal - self.label_ua_cc_eal_error = parent.label_ua_cc_eal_error - self.box_ua_cis_tools = parent.box_ua_cis_tools - self.switch_ua_cis_tools = parent.switch_ua_cis_tools - self.label_ua_cis_tools_error = parent.label_ua_cis_tools_error + self.button_ua_fips = parent.button_ua_fips + self.label_ua_fips_status = parent.label_ua_fips_status + self.label_ua_fips_description = parent.label_ua_fips_description + self.button_ua_usg = parent.button_ua_usg + self.label_ua_usg_button = parent.label_ua_usg_button + self.label_ua_usg_status = parent.label_ua_usg_status + self.label_ua_usg_description = parent.label_ua_usg_description + + ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo.svg'), -1, 50, True) + parent.image_ubuntu_pro_logo.set_from_pixbuf(ubuntu_pro_logo) + + # Display the tab on init which is only on LTS series + self.stack_ua_main.set_visible(True) parent.button_ua_attach.connect('clicked', self.on_button_ua_attach_clicked) parent.button_ua_detach.connect('clicked', self.on_button_ua_detach_clicked) - self.on_ua_esm_changed_handler = self.switch_ua_esm.connect('notify::active', self.on_ua_esm_changed) + self.on_ua_esm_infra_changed_handler = self.switch_ua_esm_infra.connect('notify::active', self.on_ua_esm_infra_changed) + self.on_ua_esm_apps_changed_handler = self.switch_ua_esm_apps.connect('notify::active', self.on_ua_esm_apps_changed) self.on_ua_livepatch_changed_handler = self.switch_ua_livepatch.connect('notify::active', self.on_ua_livepatch_changed) - self.on_ua_fips_changed_handler = self.switch_ua_fips.connect('notify::active', self.on_ua_fips_changed) - self.on_ua_fips_updates_changed_handler = self.switch_ua_fips_updates.connect('notify::active', self.on_ua_fips_updates_changed) - self.on_ua_cc_eal_changed_handler = self.switch_ua_cc_eal.connect('notify::active', self.on_ua_cc_eal_changed) - self.on_ua_cis_tools_changed_handler = self.switch_ua_cis_tools.connect('notify::active', self.on_ua_cis_tools_changed) + parent.button_ua_fips.connect('clicked', self.on_button_ua_fips_clicked) + parent.button_ua_usg.connect('clicked', self.on_button_ua_usg_clicked) + parent.expander_compliance_and_hardening.connect('notify::expanded', self.on_compliance_and_hardening_expand_changed) + + # Set date dependent labels + distro = current_distro() + if distro.eol_esm is not None: + eol_year = distro.eol_esm.year + self.label_ua_esm_infra.set_markup(_('ESM Infra provides security updates for over 2,300 Ubuntu Main packages until %d.') % eol_year) + self.label_ua_esm_apps.set_markup(_('ESM Apps; provides security updates for over 23,000 Ubuntu Universe packages until %d.') % eol_year) + else: + self.label_ua_esm_infra.set_markup(_('ESM Infra provides security updates for over 2,300 Ubuntu Main packages.')) + self.label_ua_esm_apps.set_markup(_('ESM Apps; provides security updates for over 23,000 Ubuntu Universe packages.')) self.update_notifier_settings = None source = Gio.SettingsSchemaSource.get_default() @@ -128,66 +150,69 @@ return None def update_status(self): - self.stack_ua_attach.set_sensitive(not self.detaching) if self.attached: self.stack_ua_attach.set_visible_child(self.box_ua_attached) else: self.stack_ua_attach.set_visible_child(self.box_ua_unattached) - def update_sensitive(box, service): - box.set_sensitive(service is not None and service.entitled == 'yes' and not service.request_in_progress) + def entitled_to_service(service): + return service is not None and service.entitled == 'yes' + def service_request_in_progress(service): + return service is not None and service.request_in_progress + def service_is_enabled(service): + return service is not None and service.status == 'enabled' def update_switch(switch, service, handler): if service is not None and service.request_in_progress: return switch.handler_block(handler) - switch.set_active(service is not None and service.status == 'enabled') + switch.set_active(service_is_enabled(service)) switch.handler_unblock(handler) esm_infra_service = self.get_service('esm-infra') - update_sensitive(self.box_ua_esm, esm_infra_service); - update_switch(self.switch_ua_esm, esm_infra_service, self.on_ua_esm_changed_handler) + for widget in [self.switch_ua_esm_infra, self.label_ua_esm_infra, self.label_ua_esm_infra_error]: + widget.set_sensitive(entitled_to_service(esm_infra_service) and not service_request_in_progress(esm_infra_service)) + update_switch(self.switch_ua_esm_infra, esm_infra_service, self.on_ua_esm_infra_changed_handler) + + esm_apps_service = self.get_service('esm-apps') + for widget in [self.switch_ua_esm_apps, self.label_ua_esm_apps, self.label_ua_esm_apps_error]: + widget.set_sensitive(entitled_to_service(esm_apps_service) and not service_request_in_progress(esm_apps_service)) + update_switch(self.switch_ua_esm_apps, esm_apps_service, self.on_ua_esm_apps_changed_handler) livepatch_service = self.get_service('livepatch') - update_sensitive(self.box_ua_livepatch, livepatch_service); + for widget in [self.switch_ua_livepatch, self.label_ua_livepatch, self.label_ua_livepatch_error]: + widget.set_sensitive(entitled_to_service(livepatch_service) and not service_request_in_progress(livepatch_service)) update_switch(self.switch_ua_livepatch, livepatch_service, self.on_ua_livepatch_changed_handler) self.checkbutton_livepatch_topbar.set_sensitive(self.update_notifier_settings is not None and self.switch_ua_livepatch.get_active()) fips_service = self.get_service('fips') - update_sensitive(self.box_ua_fips, fips_service) - update_switch(self.switch_ua_fips, fips_service, self.on_ua_fips_changed_handler) - fips_updates_service = self.get_service('fips-updates') - update_sensitive(self.box_ua_fips_updates, fips_updates_service) - update_switch(self.switch_ua_fips_updates, fips_updates_service, self.on_ua_fips_updates_changed_handler) + fips_in_progress = service_request_in_progress(fips_service) or service_request_in_progress(fips_updates_service) + self.button_ua_fips.set_sensitive(entitled_to_service(fips_service) and not fips_in_progress) + if fips_in_progress: + self.stack_ua_main.set_visible_child(self.box_ua_fips_setup) + else: + self.stack_ua_main.set_visible_child(self.box_ua_options) - cc_eal_service = self.get_service('cc-eal') - update_sensitive(self.box_ua_cc_eal, cc_eal_service) - update_switch(self.switch_ua_cc_eal, cc_eal_service, self.on_ua_cc_eal_changed_handler) - - cis_service = self.get_service('cis') - update_sensitive(self.box_ua_cis_tools, cis_service) - update_switch(self.switch_ua_cis_tools, cis_service, self.on_ua_cis_tools_changed_handler) + usg_service = self.get_service('usg') + if not service_request_in_progress(usg_service): + if service_is_enabled(usg_service): + self.label_ua_usg_button.set_label(_('Disable _USG')) + else: + self.label_ua_usg_button.set_label(_('Enable _USG')) + self.button_ua_usg.set_sensitive(entitled_to_service(usg_service) and not service_request_in_progress(usg_service)) def on_button_ua_attach_clicked(self, button): dialog = DialogUaAttach(self._parent.window_main, self._parent.datadir, self.ua_object) dialog.run() def on_button_ua_detach_clicked(self, button): - def on_reply(): - self.detaching = False - self.update_status() - def on_error(error): - # FIXME - print(error) - self.detaching = False - self.update_status() - self.ua_object.Detach(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Manager') - self.detaching = True - self.update_status() + dialog = DialogUaDetach(self._parent.window_main, self._parent.datadir, self.ua_object) + dialog.run() - def set_service_enabled(self, service_name, switch, error_label): - error_label.set_visible(False) + def set_service_enabled(self, service_name, enabled, error_label): + if error_label is not None: + error_label.set_visible(False) service = self.get_service(service_name) if service is None: return @@ -197,21 +222,26 @@ def on_error(error): # FIXME print(error) - error_label.set_visible(True) + if error_label is not None: + error_label.set_visible(True) + error_label.label = error service.request_in_progress = False self.update_status() - if switch.get_active(): - service.bus_object.Enable(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Service') + if enabled: + service.bus_object.Enable(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Service', timeout=600) else: - service.bus_object.Disable(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Service') + service.bus_object.Disable(reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Service', timeout=600) service.request_in_progress = True self.update_status() - def on_ua_esm_changed(self, switch, param): - self.set_service_enabled('esm-infra', self.switch_ua_esm, self.label_ua_esm_error) + def on_ua_esm_infra_changed(self, switch, param): + self.set_service_enabled('esm-infra', self.switch_ua_esm_infra.get_active(), self.label_ua_esm_infra_error) + + def on_ua_esm_apps_changed(self, switch, param): + self.set_service_enabled('esm-apps', self.switch_ua_esm_apps.get_active(), self.label_ua_esm_apps_error) def on_ua_livepatch_changed(self, switch, param): - self.set_service_enabled('livepatch', self.switch_ua_livepatch, self.label_ua_livepatch_error) + self.set_service_enabled('livepatch', self.switch_ua_livepatch.get_active(), self.label_ua_livepatch_error) def on_checkbutton_livepatch_topbar_toggled(self, button): self.update_notifier_settings.handler_block(self.on_update_notifier_settings_changed_handler) @@ -223,14 +253,30 @@ self.checkbutton_livepatch_topbar.set_active(self.update_notifier_settings.get_boolean('show-livepatch-status-icon')) self.checkbutton_livepatch_topbar.handler_unblock(self.on_checkbutton_livepatch_topbar_toggled_handler) - def on_ua_fips_changed(self, switch, param): - self.set_service_enabled('fips', self.switch_ua_fips, self.label_ua_fips_error) + def on_button_ua_fips_clicked(self, button): + dialog = DialogUaFipsEnable(self._parent.window_main, self._parent.datadir, self.ua_object) + service_name = dialog.run() + if service_name is None: + return + + dialog = Gtk.MessageDialog(parent=self._parent.window_main, + flags=Gtk.DialogFlags.MODAL, + type=Gtk.MessageType.QUESTION, + message_format=None) + dialog.add_button(_('No, go back'), Gtk.ResponseType.CANCEL) + dialog.add_button(_('Enable FIPS'), Gtk.ResponseType.OK) + dialog.set_markup(_('Enabling FIPS could take a few minutes. This action cannot be reversed. Are you sure you want to enable FIPS?')) + result = dialog.run() + dialog.destroy() + if result != Gtk.ResponseType.OK: + return - def on_ua_fips_updates_changed(self, switch, param): - self.set_service_enabled('fips-updates', self.switch_ua_fips_updates, self.label_ua_fips_updates_error) + self.set_service_enabled(service_name, True, None) - def on_ua_cc_eal_changed(self, switch, param): - self.set_service_enabled('cc-eal', self.switch_ua_cc_eal, self.label_ua_cc_eal_error) + def on_button_ua_usg_clicked(self, button): + service = self.get_service('usg') + is_enabled = service is not None and service.status == 'enabled' + self.set_service_enabled('usg', not is_enabled, None) - def on_ua_cis_tools_changed(self, switch, param): - self.set_service_enabled('cis', self.switch_ua_cis_tools, self.label_ua_cis_tools_error) + def on_compliance_and_hardening_expand_changed(self, widget, param): + self._parent.window_main.resize(1, 1) diff -Nru software-properties-0.99.26/softwareproperties/SoftwareProperties.py software-properties-0.99.27/softwareproperties/SoftwareProperties.py --- software-properties-0.99.26/softwareproperties/SoftwareProperties.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/softwareproperties/SoftwareProperties.py 2022-10-07 07:47:15.000000000 +0000 @@ -66,7 +66,7 @@ class SoftwareProperties(object): - # known (whitelisted) channels + # directory containing channels CHANNEL_PATH="/usr/share/app-install/channels/" # release upgrades policy @@ -653,7 +653,7 @@ self.sourceslist.backup(".save") self.sourceslist.save() - def _is_line_in_whitelisted_channel(self, srcline): + def _get_channel_from_line(self, srcline): """ helper that checks if a given line is in the source list return the channel name or None if not found @@ -669,14 +669,13 @@ return os.path.splitext(os.path.basename(filename))[0] return None - def check_and_add_key_for_whitelisted_shortcut(self, shortcut): + def check_and_add_key_for_channel_shortcut(self, shortcut): """ helper that adds the gpg key of the channel to the apt - keyring *if* the channel is in the whitelist - /usr/share/app-install/channels + keyring *if* the channel is in /usr/share/app-install/channels """ srcline = shortcut.SourceEntry().line - channel = self._is_line_in_whitelisted_channel(srcline) + channel = self._get_channel_from_line(srcline) if channel: keyp = "%s/%s.key" % (self.CHANNEL_PATH, channel) self.add_key(keyp) @@ -717,7 +716,7 @@ def add_source_from_shortcut(self, shortcut, enable_source_code=False): """ Add a source with the given shortcut and add the signing key if the - site is in whitelist or the shortcut implementer adds it. + site is a known channel or the shortcut implementer adds it. """ deb_line = shortcut.SourceEntry().line @@ -729,7 +728,7 @@ new_debsrc_entry = SourceEntry(debsrc_line, file) if new_deb_entry.invalid or new_debsrc_entry.invalid: return False - if not self.check_and_add_key_for_whitelisted_shortcut(shortcut): + if not self.check_and_add_key_for_channel_shortcut(shortcut): shortcut.add_key() self.sourceslist.add(new_deb_entry.type, new_deb_entry.uri, diff -Nru software-properties-0.99.26/tests/test_pyflakes.py software-properties-0.99.27/tests/test_pyflakes.py --- software-properties-0.99.26/tests/test_pyflakes.py 2022-08-24 12:53:52.000000000 +0000 +++ software-properties-0.99.27/tests/test_pyflakes.py 2022-10-07 07:47:15.000000000 +0000 @@ -6,14 +6,14 @@ class TestPyflakesClean(unittest.TestCase): """ ensure that the tree is pyflakes clean """ - BLACKLIST = ("/softwareproperties/qt", + BLOCKLIST = ("/softwareproperties/qt", ) def setUp(self): self.paths = [] basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) for dirpath, dirs, files in os.walk(basedir): - if any([dirpath.endswith(p) for p in self.BLACKLIST]): + if any([dirpath.endswith(p) for p in self.BLOCKLIST]): continue self.paths.extend(glob.glob(dirpath+"/*.py"))