Skip to content

Commit

Permalink
Warn about EOL templates in updates notification
Browse files Browse the repository at this point in the history
The qui-updates widget will now show information that
templates are EOL and offer launching template manager.

The notifications are based on a manually created list of
EOL dates.

references QubesOS/qubes-issues#7818
  • Loading branch information
marmarta committed Oct 13, 2023
1 parent 2fd4eec commit b8f5c53
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 27 deletions.
22 changes: 22 additions & 0 deletions qui/eol.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"fedora-36": "2023-05-16",
"fedora-35": "2022-12-13",
"fedora-34": "2022-06-07",
"fedora-33": "2021-11-30",
"fedora-32": "2021-05-25",
"fedora-31": "2020-11-24",
"fedora-30": "2020-05-26",
"fedora-29": "2019-11-26",
"fedora-28": "2019-05-28",
"fedora-27": "2018-11-30",
"fedora-26": "2018-05-29",
"fedora-25": "2017-12-12",
"fedora-24": "2017-08-08",
"debian-12": "2026-06-10",
"debian-11": "2024-07-01",
"debian-10": "2022-09-10",
"debian-9": "2020-07-18",
"debian-8": "2018-06-17",
"debian-7": "2016-04-25",
"debian-6": "2014-05-31"
}
90 changes: 63 additions & 27 deletions qui/tray/updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,36 @@
_ = t.gettext


class TextItem(Gtk.MenuItem):
def __init__(self, text):
super().__init__()
title_label = Gtk.Label()
title_label.set_markup(text)
title_label.set_halign(Gtk.Align.CENTER)
title_label.set_justify(Gtk.Justification.CENTER)
self.set_margin_left(10)
self.set_margin_right(10)
self.set_margin_top(5)
self.add(title_label)
self.set_sensitive(False)
self.show_all()


class RunItem(Gtk.MenuItem):
def __init__(self, text, command):
super().__init__()
title_label = Gtk.Label()
title_label.set_markup(text)
title_label.set_halign(Gtk.Align.CENTER)
title_label.set_justify(Gtk.Justification.CENTER)
self.set_margin_left(10)
self.set_margin_right(10)
self.set_margin_bottom(5)
self.add(title_label)
self.show_all()
self.connect('activate', command)


class UpdatesTray(Gtk.Application):
def __init__(self, app_name, qapp, dispatcher):
super().__init__()
Expand All @@ -43,6 +73,7 @@ def __init__(self, app_name, qapp, dispatcher):
'<b>Qubes Update</b>\nUpdates are available.'))

self.vms_needing_update = set()
self.obsolete_vms = set()

self.tray_menu = Gtk.Menu()

Expand All @@ -53,31 +84,24 @@ def run(self): # pylint: disable=arguments-differ
self.update_indicator_state()

def setup_menu(self):
title_label = Gtk.Label(xalign=0)
title_label.set_markup(_("<b>Qube updates available</b>"))
title_menu_item = Gtk.MenuItem()
title_menu_item.add(title_label)
title_menu_item.set_sensitive(False)

subtitle_label = Gtk.Label(xalign=0)
subtitle_label.set_markup(
_("<i>Updates available for {} qubes</i>").format(
len(self.vms_needing_update)))
subtitle_menu_item = Gtk.MenuItem()
subtitle_menu_item.set_margin_left(10)
subtitle_menu_item.add(subtitle_label)
subtitle_menu_item.set_sensitive(False)

run_label = Gtk.Label(xalign=0)
run_label.set_text(_("Launch updater"))
run_menu_item = Gtk.MenuItem()
run_menu_item.set_margin_left(10)
run_menu_item.add(run_label)
run_menu_item.connect('activate', self.launch_updater)

self.tray_menu.append(title_menu_item)
self.tray_menu.append(subtitle_menu_item)
self.tray_menu.append(run_menu_item)
self.tray_menu.set_reserve_toggle_size(False)

if self.vms_needing_update:
self.tray_menu.append(TextItem(_("<b>Qube updates available!</b>")))
self.tray_menu.append(RunItem(
_("Updates for {} qubes are available!\n"
"<b>Launch updater</b>").format(
len(self.vms_needing_update)), self.launch_updater))

if self.obsolete_vms:
self.tray_menu.append(TextItem(
_("<b>Some qubes are no longer supported!</b>")))
obsolete_text = _("The following qubes are based on distributions "
"that are no longer supported:\n")\
+ ", ".join([str(vm) for vm in self.obsolete_vms])\
+ _("\n<b>Install new templates with Template Manager</b>")
self.tray_menu.append(
RunItem(obsolete_text, self.launch_template_manager))

self.tray_menu.show_all()

Expand All @@ -93,16 +117,28 @@ def launch_updater(*_args, **_kwargs):
# pylint: disable=consider-using-with
subprocess.Popen(['qubes-update-gui'])

@staticmethod
def launch_template_manager(*_args, **_kwargs):
# pylint: disable=consider-using-with
subprocess.Popen(['qvm-template-gui'])

def check_vms_needing_update(self):
self.vms_needing_update.clear()
self.obsolete_vms.clear()
for vm in self.qapp.domains:
try:
updates_available = vm.features.get('updates-available', False)
except exc.QubesDaemonCommunicationError:
updates_available = False
if updates_available and \
(getattr(vm, 'updateable', False) or vm.klass == 'AdminVM'):
self.vms_needing_update.add(vm.name)
self.vms_needing_update.add(vm)
try:
supported = qui.utils.check_support(vm)
except exc.QubesDaemonCommunicationError:
supported = True
if not supported:
self.obsolete_vms.add(vm.name)

def connect_events(self):
self.dispatcher.add_handler('domain-feature-set:updates-available',
Expand Down Expand Up @@ -155,7 +191,7 @@ def feature_set(self, vm, event, feature, value, **_kwargs):
self.update_indicator_state()

def update_indicator_state(self):
if self.vms_needing_update:
if self.vms_needing_update or self.obsolete_vms:
self.widget_icon.set_visible(True)
else:
self.widget_icon.set_visible(False)
Expand Down
19 changes: 19 additions & 0 deletions qui/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,24 @@
"""helper functions for various qui tools"""
# pylint: disable=wrong-import-position,import-error
import asyncio
import json
import sys
import traceback
from html import escape

import gettext

import pkg_resources
from datetime import datetime

t = gettext.translation("desktop-linux-manager", fallback=True)
_ = t.gettext

import gi # isort:skip
gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gtk # isort:skip

EOL_DATES = json.load(pkg_resources.resource_stream(__name__, 'eol.json'))

def run_asyncio_and_show_errors(loop, tasks, name, restart=True):
"""
Expand Down Expand Up @@ -70,3 +76,16 @@ def run_asyncio_and_show_errors(loop, tasks, name, restart=True):
dialog.run()
exit_code = 1
return exit_code


def check_support(vm):
"""Return true if the given template/standalone vm is still supported, by
default returns true"""
template_name = vm.features.get('template-name', '')
if not template_name:
return True
eol = EOL_DATES.get(template_name, None)
if not eol:
return True
eol = datetime.strptime(eol, '%Y-%m-%d')
return eol > datetime.now()
1 change: 1 addition & 0 deletions rpm_spec/qubes-desktop-linux-manager.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ gtk-update-icon-cache %{_datadir}/icons/Adwaita &>/dev/null || :
%{python3_sitelib}/qui/qubes-updater-base.css
%{python3_sitelib}/qui/qubes-updater-light.css
%{python3_sitelib}/qui/qubes-updater-dark.css
%{python3_sitelib}/qui/eol.json

%{python3_sitelib}/qui/styles/qubes-colors-light.css
%{python3_sitelib}/qui/styles/qubes-colors-dark.css
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def run(self):
"styles/qubes-colors-light.css",
"styles/qubes-colors-dark.css",
"styles/qubes-widgets-base.css",
"eol.json"
],
'qubes_config': ["new_qube.glade",
"global_config.glade",
Expand Down

0 comments on commit b8f5c53

Please sign in to comment.