Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ checks:tests:
before_script: &before-script
- "PATH=$PATH:$HOME/.local/bin"
- sudo dnf install -y python3-gobject gtk3 python3-pytest gtksourceview4
python3-coverage xorg-x11-server-Xvfb python3-pip
python3-coverage xorg-x11-server-Xvfb python3-pip cairo-devel
- pip3 install --quiet -r ci/requirements.txt
- git clone https://github.com/QubesOS/qubes-core-admin-client ~/core-admin-client
- git clone https://github.com/QubesOS/qubes-core-qrexec ~/core-qrexec
Expand Down
55 changes: 49 additions & 6 deletions qubes_config/global_config/global_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
# pylint: disable=import-error
"""Global Qubes Config tool."""
import sys
import threading
import time
from typing import Dict, Optional, List, Union, Any
from html import escape
import importlib.resources
import logging

import qubesadmin
import qubesadmin.events
import qubesadmin.exc
import qubesadmin.vm
from ..widgets.gtk_utils import (
Expand All @@ -36,6 +37,7 @@
load_theme,
is_theme_light,
resize_window_to_reasonable,
show_dialog,
)
from ..widgets.gtk_widgets import ProgressBarDialog, ViewportHandler
from ..widgets.utils import open_url_in_disposable
Expand Down Expand Up @@ -267,6 +269,8 @@
self.progress_bar_dialog = ProgressBarDialog(
self, _("Loading system settings...")
)
self.save_thread: threading.Thread | None = None
self.save_errors: List[str] = []
self.handlers: Dict[str, PageHandler] = {}

def do_command_line(self, command_line):
Expand Down Expand Up @@ -555,13 +559,11 @@
self.main_notebook.get_nth_page(page_num).get_name(), None
)

def save_page(self, page: PageHandler) -> bool:
"""Save provided page and emit any necessary signals;
return True if successful, False otherwise"""
def perform_save(self, page):
"""Actual saving thread"""
# pylint: disable=protected-access
# need to invalidate cache before and after saving to avoid
# stale cache

self.qapp._invalidate_cache_all()
try:
page.save()
Expand All @@ -572,11 +574,52 @@
self.qapp._invalidate_cache_all()
page.reset()
except Exception as ex:
self.save_errors.append(str(ex))

def save_page(self, page: PageHandler) -> bool:
"""Save provided page and emit any necessary signals;
return True if successful, False otherwise"""
self.save_thread = threading.Thread(target=self.perform_save, args=[page])
self.save_thread.start()

spinner = None
dialog = None
time.sleep(0.01)

if self.save_thread.is_alive():
# show waiting dialog
spinner = Gtk.Spinner()
spinner.start()
dialog = show_dialog(
self.main_window,
_("Saving changes"),
_("Saving global configuration changes..."),
{},
spinner,
)
dialog.set_deletable(False)
dialog.show()

# wait for thread and spin spinner
while self.save_thread.is_alive():
while Gtk.events_pending():
Gtk.main_iteration()
time.sleep(0.1)

Check warning on line 607 in qubes_config/global_config/global_config.py

View check run for this annotation

Codecov / codecov/patch

qubes_config/global_config/global_config.py#L605-L607

Added lines #L605 - L607 were not covered by tests

# cleanup
if spinner:
spinner.stop()
if dialog:
dialog.destroy()

if self.save_errors:
show_error(
self.main_window,
_("Could not save changes"),
_("The following error occurred: ") + escape(str(ex)),
_("The following error occurred: ")
+ escape("\n".join(self.save_errors)),
)
self.save_errors = []
return False
return True

Expand Down