Merge ~robert-ancell/software-properties:esm-xenial into software-properties:ubuntu/xenial

Proposed by Robert Ancell
Status: Needs review
Proposed branch: ~robert-ancell/software-properties:esm-xenial
Merge into: software-properties:ubuntu/xenial
Diff against target: 336 lines (+211/-6)
5 files modified
data/gtkbuilder/main.ui (+106/-6)
debian/changelog (+6/-0)
debian/control (+1/-0)
softwareproperties/gtk/SoftwarePropertiesGtk.py (+23/-0)
softwareproperties/gtk/utils.py (+75/-0)
Reviewer Review Type Date Requested Status
Ubuntu Core Development Team Pending
Review via email: mp+400302@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Unmerged commits

7b8920c... by Robert Ancell

Show extended security maintenance status

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/data/gtkbuilder/main.ui b/data/gtkbuilder/main.ui
index ed4abc1..d1704e9 100644
--- a/data/gtkbuilder/main.ui
+++ b/data/gtkbuilder/main.ui
@@ -547,7 +547,18 @@
547 <packing>547 <packing>
548 <property name="expand">False</property>548 <property name="expand">False</property>
549 <property name="fill">True</property>549 <property name="fill">True</property>
550 <property name="position">0</property>550 </packing>
551 </child>
552 <child>
553 <object class="GtkLabel">
554 <property name="visible">True</property>
555 <property name="can_focus">False</property>
556 <property name="label" translatable="yes">Snap package updates are checked routinely and installed automatically.</property>
557 <property name="xalign">0</property>
558 </object>
559 <packing>
560 <property name="expand">False</property>
561 <property name="fill">False</property>
551 </packing>562 </packing>
552 </child>563 </child>
553 <child>564 <child>
@@ -562,6 +573,98 @@
562 <property name="can_focus">False</property>573 <property name="can_focus">False</property>
563 <property name="spacing">6</property>574 <property name="spacing">6</property>
564 <child>575 <child>
576 <object class="GtkHBox">
577 <property name="visible">True</property>
578 <property name="can_focus">False</property>
579 <property name="spacing">6</property>
580 <child>
581 <object class="GtkLabel" id="label_esm_heading">
582 <property name="visible">True</property>
583 <property name="can_focus">False</property>
584 <property name="xalign">1</property>
585 <property name="label" translatable="yes">For other packages, this system has:</property>
586 </object>
587 <packing>
588 <property name="expand">False</property>
589 <property name="fill">False</property>
590 <property name="position">0</property>
591 </packing>
592 </child>
593 <child>
594 <object class="GtkHBox">
595 <property name="visible">True</property>
596 <property name="can_focus">False</property>
597 <property name="spacing">6</property>
598 <child>
599 <object class="GtkLabel" id="label_esm_status">
600 <property name="visible">True</property>
601 <property name="can_focus">False</property>
602 <property name="xalign">0</property>
603 </object>
604 <packing>
605 <property name="expand">False</property>
606 <property name="fill">True</property>
607 </packing>
608 </child>
609 <child>
610 <object class="GtkLabel" id="label_esm_subscribe">
611 <property name="visible">True</property>
612 <property name="can_focus">False</property>
613 <property name="xalign">1</property>
614 </object>
615 <packing>
616 <property name="expand">True</property>
617 <property name="fill">True</property>
618 </packing>
619 </child>
620 </object>
621 <packing>
622 <property name="expand">True</property>
623 <property name="fill">True</property>
624 <property name="position">1</property>
625 </packing>
626 </child>
627 </object>
628 <packing>
629 <property name="expand">False</property>
630 <property name="fill">False</property>
631 </packing>
632 </child>
633 <child>
634 <object class="GtkHBox">
635 <property name="visible">True</property>
636 <property name="can_focus">False</property>
637 <property name="spacing">6</property>
638 <child>
639 <object class="GtkLabel" id="label_eol_heading">
640 <property name="visible">True</property>
641 <property name="can_focus">False</property>
642 </object>
643 <packing>
644 <property name="expand">False</property>
645 <property name="fill">False</property>
646 <property name="position">0</property>
647 </packing>
648 </child>
649 <child>
650 <object class="GtkLabel" id="label_eol">
651 <property name="visible">True</property>
652 <property name="can_focus">False</property>
653 <property name="xalign">0</property>
654 </object>
655 <packing>
656 <property name="expand">True</property>
657 <property name="fill">True</property>
658 <property name="position">1</property>
659 </packing>
660 </child>
661 </object>
662 <packing>
663 <property name="expand">False</property>
664 <property name="fill">False</property>
665 </packing>
666 </child>
667 <child>
565 <object class="GtkHBox" id="hbox_check_for_updates">668 <object class="GtkHBox" id="hbox_check_for_updates">
566 <property name="visible">True</property>669 <property name="visible">True</property>
567 <property name="can_focus">False</property>670 <property name="can_focus">False</property>
@@ -601,7 +704,6 @@
601 <packing>704 <packing>
602 <property name="expand">False</property>705 <property name="expand">False</property>
603 <property name="fill">False</property>706 <property name="fill">False</property>
604 <property name="position">0</property>
605 </packing>707 </packing>
606 </child>708 </child>
607 <child>709 <child>
@@ -644,7 +746,6 @@
644 <packing>746 <packing>
645 <property name="expand">False</property>747 <property name="expand">False</property>
646 <property name="fill">False</property>748 <property name="fill">False</property>
647 <property name="position">1</property>
648 </packing>749 </packing>
649 </child>750 </child>
650 <child>751 <child>
@@ -687,7 +788,6 @@
687 <packing>788 <packing>
688 <property name="expand">False</property>789 <property name="expand">False</property>
689 <property name="fill">False</property>790 <property name="fill">False</property>
690 <property name="position">2</property>
691 </packing>791 </packing>
692 </child>792 </child>
693 </object>793 </object>
@@ -696,7 +796,6 @@
696 <packing>796 <packing>
697 <property name="expand">True</property>797 <property name="expand">True</property>
698 <property name="fill">True</property>798 <property name="fill">True</property>
699 <property name="position">1</property>
700 </packing>799 </packing>
701 </child>800 </child>
702 <child>801 <child>
@@ -746,7 +845,6 @@
746 <packing>845 <packing>
747 <property name="expand">False</property>846 <property name="expand">False</property>
748 <property name="fill">False</property>847 <property name="fill">False</property>
749 <property name="position">2</property>
750 </packing>848 </packing>
751 </child>849 </child>
752 </object>850 </object>
@@ -1180,6 +1278,8 @@
1180 </object>1278 </object>
1181 <object class="GtkSizeGroup" id="sizegroup1">1279 <object class="GtkSizeGroup" id="sizegroup1">
1182 <widgets>1280 <widgets>
1281 <widget name="label_esm_heading"/>
1282 <widget name="label_eol_heading"/>
1183 <widget name="label3"/>1283 <widget name="label3"/>
1184 <widget name="label4"/>1284 <widget name="label4"/>
1185 <widget name="label5"/>1285 <widget name="label5"/>
diff --git a/debian/changelog b/debian/changelog
index ce037cf..1d17ec0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
1software-properties (0.96.20.11) UNRELEASED; urgency=medium
2
3 * Show ESM support status (LP: #1920836)
4
5 -- Robert Ancell <robert.ancell@canonical.com> Tue, 23 Mar 2021 11:51:12 +1300
6
1software-properties (0.96.20.10) xenial-security; urgency=medium7software-properties (0.96.20.10) xenial-security; urgency=medium
28
3 * SECURITY UPDATE: malicious repo could send ANSI sequences to terminal9 * SECURITY UPDATE: malicious repo could send ANSI sequences to terminal
diff --git a/debian/control b/debian/control
index 20d0e4b..a1dd141 100644
--- a/debian/control
+++ b/debian/control
@@ -64,6 +64,7 @@ Depends: ${python3:Depends}, ${misc:Depends}, python3,
64 ubuntu-drivers-common (>= 1:0.2.75),64 ubuntu-drivers-common (>= 1:0.2.75),
65 python3-gi,65 python3-gi,
66 libgtk2-perl,66 libgtk2-perl,
67 distro-info-data,
67Description: manage the repositories that you install software from (gtk)68Description: manage the repositories that you install software from (gtk)
68 This software provides an abstraction of the used apt repositories.69 This software provides an abstraction of the used apt repositories.
69 It allows you to easily manage your distribution and independent software70 It allows you to easily manage your distribution and independent software
diff --git a/softwareproperties/gtk/SoftwarePropertiesGtk.py b/softwareproperties/gtk/SoftwarePropertiesGtk.py
index 033c6b8..d9e462e 100644
--- a/softwareproperties/gtk/SoftwarePropertiesGtk.py
+++ b/softwareproperties/gtk/SoftwarePropertiesGtk.py
@@ -26,6 +26,7 @@ from __future__ import absolute_import, print_function
2626
27import apt27import apt
28import apt_pkg28import apt_pkg
29import datetime
29import dbus30import dbus
30from gettext import gettext as _31from gettext import gettext as _
31import gettext32import gettext
@@ -51,6 +52,12 @@ import softwareproperties.distro
51from softwareproperties.SoftwareProperties import SoftwareProperties52from softwareproperties.SoftwareProperties import SoftwareProperties
52import softwareproperties.SoftwareProperties53import softwareproperties.SoftwareProperties
5354
55from softwareproperties.gtk.utils import (
56 get_esm_apps_status,
57 current_distro_eol,
58 current_distro_eol_esm
59)
60
54from UbuntuDrivers import detect61from UbuntuDrivers import detect
5562
56if GLib.pyglib_version < (3, 9, 1):63if GLib.pyglib_version < (3, 9, 1):
@@ -349,6 +356,22 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp):
349 self.vbox_updates.add(checkbox)356 self.vbox_updates.add(checkbox)
350 checkbox.show()357 checkbox.show()
351358
359 (esm_available, esm_enabled) = get_esm_apps_status()
360 if esm_enabled:
361 eol_text = _("Extended Security Maintenance")
362 eol_date = current_distro_eol_esm()
363 else:
364 eol_text = _("Basic Security Maintenance")
365 eol_date = current_distro_eol()
366 self.label_esm_status.set_markup(eol_text)
367 self.label_esm_subscribe.set_markup("<a href=\"https://ubuntu.com/security/esm\">%s</a>" % _("Extend…"))
368 self.label_esm_subscribe.set_visible(esm_available and not esm_enabled)
369 if datetime.datetime.now().date() > eol_date:
370 eol_expiry_text = _("Ended %s") % eol_date.strftime("%x")
371 else:
372 eol_expiry_text = _("Active until %s") % eol_date.strftime("%x")
373 self.label_eol.set_label(eol_expiry_text);
374
352 # setup the server chooser375 # setup the server chooser
353 cell = Gtk.CellRendererText()376 cell = Gtk.CellRendererText()
354 self.combobox_server.pack_start(cell, True)377 self.combobox_server.pack_start(cell, True)
diff --git a/softwareproperties/gtk/utils.py b/softwareproperties/gtk/utils.py
index 9554fea..8fe682c 100644
--- a/softwareproperties/gtk/utils.py
+++ b/softwareproperties/gtk/utils.py
@@ -19,6 +19,11 @@
19from __future__ import print_function19from __future__ import print_function
2020
21from gi.repository import Gtk21from gi.repository import Gtk
22import aptsources.distro
23import csv
24import datetime
25import json
26import subprocess
22import logging27import logging
23LOG=logging.getLogger(__name__)28LOG=logging.getLogger(__name__)
2429
@@ -34,3 +39,73 @@ def setup_ui(self, path, domain):
34 setattr(self, name, o)39 setattr(self, name, o)
35 else:40 else:
36 logging.debug("can not get name for object '%s'" % o)41 logging.debug("can not get name for object '%s'" % o)
42
43class DistroInfo:
44 def __init__ (self, version, codename, series, created, release, eol, eol_server, eol_esm):
45 self.version = version
46 self.codename = codename
47 self.series = series
48 self.created = created
49 self.release = release
50 self.eol = eol
51 self.eol_server = eol_server
52 self.eol_esm = eol_esm
53
54def _parse_date(date_string):
55 if date_string is None:
56 return None
57 try:
58 return datetime.datetime.strptime(date_string, '%Y-%m-%d').date()
59 except ValueError:
60 return None
61
62def _current_distro():
63 distro = aptsources.distro.get_distro()
64 try:
65 reader = csv.reader(open('/usr/share/distro-info/ubuntu.csv'))
66 except Exception as e:
67 print("Failed to read distro info:\n%s" % e)
68 reader = []
69
70 for line in reader:
71 (version, codename, series, created, release, eol, eol_server, eol_esm) = line[:8] + [None] * max(0, 8 - len(line))
72 if series == distro.codename:
73 return DistroInfo(version, codename, series, _parse_date(created), _parse_date(release), _parse_date(eol), _parse_date(eol_server), _parse_date(eol_esm))
74
75 return DistroInfo('', '', '', datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today())
76
77def current_distro_eol():
78 return _current_distro().eol
79
80def current_distro_eol_esm():
81 return _current_distro().eol_esm
82
83def get_esm_apps_status():
84 try:
85 result = subprocess.run(['ua', 'status', '--format=json'], stdout=subprocess.PIPE)
86 except Exception as e:
87 print("Failed to call ubuntu advantage client:\n%s" % e)
88 return (False, False)
89
90 if result.returncode != 0:
91 print("Ubuntu advantage client returned code %d" % result.returncode)
92 return (False, False)
93
94 try:
95 status = json.loads(result.stdout.decode("utf-8"))
96 except Exception as e:
97 print("Failed to parse ubuntu advantage client JSON:\n%s" % e)
98 return (False, False)
99
100 services = status.get("services")
101 if services == None:
102 services = []
103
104 for service in services:
105 if service.get("name") == "esm-apps":
106 available = service.get("available") == "yes"
107 entitled = service.get("entitled") == "yes"
108 service_status = service.get("status")
109 return (available or entitled, service_status == "enabled")
110
111 return (False, False)

Subscribers

People subscribed via source and target branches