Skip to content

Commit

Permalink
dom0 package comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrbartman committed Mar 26, 2024
1 parent be9db5f commit 089f2f4
Showing 1 changed file with 71 additions and 1 deletion.
72 changes: 71 additions & 1 deletion qui/updater/progress_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import threading
import time
import gi
from typing import Dict
from typing import Dict, List

gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gtk, Gdk, GLib, GObject # isort:skip
Expand Down Expand Up @@ -156,6 +156,8 @@ def update_admin_vm(self, admins):

try:
with Ticker(admin):
curr_pkg = self._get_packages_admin()

# pylint: disable=consider-using-with
proc = subprocess.Popen(
['sudo', 'qubes-dom0-update'],
Expand All @@ -182,6 +184,11 @@ def update_admin_vm(self, admins):
read_err_thread.join()
read_out_thread.join()

new_pkg = self._get_packages_admin()
changes = self._compare_packages(curr_pkg, new_pkg)
changes_str = self._print_changes(changes)
GLib.idle_add(admin.append_text_view, changes_str)

if "No updates available" in admin.buffer:
GLib.idle_add(admin.set_status, UpdateStatus.NoUpdatesFound)
else:
Expand All @@ -195,6 +202,69 @@ def update_admin_vm(self, admins):

self.update_details.update_buffer()

@staticmethod
def _get_packages_admin() -> Dict[str, List[str]]:
"""
Use rpm to return the installed packages and their versions.
"""

cmd = ["rpm", "-qa", "--queryformat", "%{NAME} %{VERSION}%{RELEASE}\n",]
# EXAMPLE OUTPUT:
# qubes-core-agent 4.1.351.fc34
package_list = subprocess.check_output(cmd).decode().splitlines()

packages = {}
for line in package_list:
cols = line.split()
package, version = cols
packages.setdefault(package, []).append(version)

return packages

@staticmethod
def _compare_packages(
old: Dict[str, List[str]], new: Dict[str, List[str]]
) -> Dict[str, Dict]:
"""
Compare installed packages and return dictionary with differences.
:param old: Dict[package_name, version] packages before update
:param new: Dict[package_name, version] packages after update
"""
return {"installed": {pkg: new[pkg] for pkg in new if pkg not in old},
"updated": {pkg: {"old": old[pkg], "new": new[pkg]}
for pkg in new
if pkg in old and old[pkg] != new[pkg]
},
"removed": {pkg: old[pkg] for pkg in old if pkg not in new}}

@staticmethod
def _print_changes(changes: Dict[str, Dict]) -> str:
result = ""
result += "Installed packages:\n"
if changes["installed"]:
for pkg in changes["installed"]:
result += f'{pkg} {changes["installed"][pkg]}\n'
else:
result += "None\n"

result += "Updated packages:\n"
if changes["updated"]:
for pkg in changes["updated"]:
old_ver = str(changes["updated"][pkg]["old"])[2:-2]
new_ver = str(changes["updated"][pkg]["new"])[2:-2]
result += f'{pkg} {old_ver} -> {new_ver}'
else:
result += "None\n"

result += "Removed packages:\n"
if changes["removed"]:
for pkg in changes["removed"]:
result += f'{pkg} {changes["removed"][pkg]}\n'
else:
result += "None\n"
return result

def update_templates(self, to_update, settings):
"""Updates templates and standalones and then sets update statuses."""
if self.exit_triggered:
Expand Down

0 comments on commit 089f2f4

Please sign in to comment.