Skip to content

Commit

Permalink
feat(core): improve the user experience of update-manager by making i…
Browse files Browse the repository at this point in the history
…t more verbose about the current state of the update progress - closes #153
  • Loading branch information
sassanh committed Aug 13, 2024
1 parent 9cb0bc3 commit 4dd7d8d
Show file tree
Hide file tree
Showing 19 changed files with 183 additions and 61 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration_delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ jobs:
steps:
- uses: actions/checkout@v4
name: Checkout
# with: TODO: this, it consumes lfs bandwidth and should be used only for releases
# lfs: true
with:
lfs: true

- uses: actions/setup-python@v5
name: Setup Python
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- fix(core): update manager downloads the latest `install.sh` and runs it to do the update - closes #152
- feat(core): add signal management for ubo_app process - closes #156
- fix(core): use fasteners read-write lock implementation for the persistent store - closes #158
- feat(core): improve the user experience of update-manager by making it more verbose about the current state of the update progress - closes #153

## Version 0.15.5

Expand Down
28 changes: 14 additions & 14 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"_id": "e3e70682c2094cac629f6fbed82c07cd",
"main": {
"depth": 1,
"menu": {
"items": [
{
Expand Down Expand Up @@ -280,6 +281,7 @@
},
"update_manager": {
"current_version": "0.0.0",
"is_update_service_active": false,
"latest_version": "0.0.0",
"serial_number": "<not-available>",
"update_status": "up_to_date"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"_id": "e3e70682c2094cac629f6fbed82c07cd",
"main": {
"depth": 1,
"menu": {
"items": [
{
Expand Down Expand Up @@ -280,6 +281,7 @@
},
"update_manager": {
"current_version": "0.0.0",
"is_update_service_active": false,
"latest_version": "0.0.0",
"serial_number": "ZFH2UL4UGF",
"update_status": "up_to_date"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"is_enabled": true
},
"main": {
"depth": 1,
"menu": {
"items": [
{
Expand Down Expand Up @@ -752,6 +753,7 @@
},
"update_manager": {
"current_version": "0.0.0",
"is_update_service_active": false,
"latest_version": "0.0.0",
"serial_number": "<not-available>",
"update_status": "up_to_date"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"is_enabled": true
},
"main": {
"depth": 1,
"menu": {
"items": [
{
Expand Down Expand Up @@ -752,6 +753,7 @@
},
"update_manager": {
"current_version": "0.0.0",
"is_update_service_active": false,
"latest_version": "0.0.0",
"serial_number": "ZFH2UL4UGF",
"update_status": "up_to_date"
Expand Down
3 changes: 3 additions & 0 deletions ubo_app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
SERVER_SOCKET_PATH = Path('/run/ubo').joinpath('system_manager.sock').as_posix()
DISABLED_SERVICES = os.environ.get('UBO_DISABLED_SERVICES', '').split(',')

UPDATE_ASSETS_PATH = Path(f'{INSTALLATION_PATH}/_update/')
UPDATE_LOCK_PATH = UPDATE_ASSETS_PATH / 'update_is_ready.lock'

DEBUG_MODE_MENU = str_to_bool(os.environ.get('UBO_DEBUG_MENU', 'False')) == 1

SERVICES_LOOP_GRACE_PERIOD = float(
Expand Down
61 changes: 57 additions & 4 deletions ubo_app/menu_app/menu_central.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# ruff: noqa: D100, D101, D102, D103, D104, D107
from __future__ import annotations

import functools
import weakref
from functools import cached_property
from typing import TYPE_CHECKING

from debouncer import DebounceOptions, debounce
from kivy.clock import mainthread
from ubo_gui.app import UboApp, cached_property
from ubo_gui.app import UboApp
from ubo_gui.constants import INFO_COLOR
from ubo_gui.menu.menu_widget import MenuWidget
from ubo_gui.menu.stack_item import StackItem, StackMenuItem

Expand All @@ -24,7 +25,20 @@
)
from ubo_app.store.main import autorun, dispatch, subscribe_event
from ubo_app.store.services.keypad import Key, KeypadKeyPressEvent
from ubo_app.store.services.notifications import NotificationsDisplayEvent
from ubo_app.store.services.notifications import (
Importance,
Notification,
NotificationDisplayType,
NotificationsAddAction,
NotificationsClearAction,
NotificationsDisplayEvent,
)
from ubo_app.store.update_manager import (
UPDATE_MANAGER_NOTIFICATION_ID,
UpdateManagerSetUpdateServiceStatusAction,
)
from ubo_app.utils.async_ import create_task
from ubo_app.utils.monitor_unit import monitor_unit

from .home_page import HomePage

Expand Down Expand Up @@ -59,6 +73,7 @@ def set_path(_: MenuWidget, stack: list[StackItem]) -> None:
for stack_item in stack
if isinstance(stack_item, StackMenuItem) and stack_item.selection
],
depth=len(stack),
),
)

Expand All @@ -82,11 +97,49 @@ def _(menu: Menu | None) -> None:
return
self.menu_widget.set_root_menu(menu)

background_update_notification = Notification(
id=UPDATE_MANAGER_NOTIFICATION_ID,
title='Update in progress',
content="""\
Please keep the device powered on.
This may take around 20 minutes to complete.""",
importance=Importance.LOW,
icon='󰚰',
display_type=NotificationDisplayType.STICKY,
dismissable=False,
dismiss_on_close=False,
color=INFO_COLOR,
)

@autorun(lambda state: state.update_manager.is_update_service_active)
def _(is_active: bool) -> None: # noqa: FBT001
if is_active:
dispatch(
NotificationsAddAction(
notification=background_update_notification,
),
)
else:
dispatch(
NotificationsClearAction(
notification=background_update_notification,
),
)

def check_update(self: MenuWidgetWithHomePage, status: str) -> None:
dispatch(
UpdateManagerSetUpdateServiceStatusAction(
is_active=status in ('active', 'activating', 'reloading'),
),
)

def build(self: UboApp) -> Widget | None:
root = super().build()
self.menu_widget.padding_top = root.ids.header_layout.height
self.menu_widget.padding_bottom = root.ids.footer_layout.height

create_task(monitor_unit('ubo-update.service', self.check_update))

return root

def handle_page_index_change(
Expand All @@ -103,7 +156,7 @@ def handle_page_index_change(
def handle_title_change(self: MenuAppCentral, _: MenuWidget, title: str) -> None:
self.root.title = title

@functools.cached_property
@cached_property
def central(self: MenuAppCentral) -> Widget | None:
"""Build the main menu and initiate it."""
self.root.is_fullscreen = True
Expand Down
2 changes: 0 additions & 2 deletions ubo_app/services/050-lightdm/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ async def check_is_lightdm_enabled() -> None:

def open_lightdm_menu() -> Menu:
"""Open the LightDM menu."""
create_task(check_is_lightdm_active())
create_task(check_is_lightdm_enabled())

return HeadlessMenu(
Expand All @@ -138,7 +137,6 @@ def init_service() -> None:
),
)

create_task(check_is_lightdm_active())
create_task(check_is_lightdm_enabled())
create_task(
monitor_unit(
Expand Down
2 changes: 0 additions & 2 deletions ubo_app/services/050-ssh/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ async def check_is_ssh_enabled() -> None:

def open_ssh_menu() -> Menu:
"""Open the SSH menu."""
create_task(check_is_ssh_active())
create_task(check_is_ssh_enabled())

return HeadlessMenu(
Expand All @@ -276,7 +275,6 @@ def init_service() -> None:
),
)

create_task(check_is_ssh_active())
create_task(check_is_ssh_enabled())
create_task(
monitor_unit(
Expand Down
17 changes: 14 additions & 3 deletions ubo_app/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

import signal
from pathlib import Path
from typing import Any, cast
from typing import TYPE_CHECKING, Any, cast

import numpy as np
from fake import Fake
from redux import FinishAction

if TYPE_CHECKING:
from ubo_gui.menu.types import Callable


class _FakeAsyncProcess(Fake):
def __init__(self: _FakeAsyncProcess, output: bytes = b'') -> None:
Expand Down Expand Up @@ -99,6 +102,13 @@ async def fake_create_subprocess_exec(
Fake(_Fake__return_value=Fake(_Fake__await_value=(Fake(), Fake()))),
)

import ubo_app.utils.monitor_unit

async def fake_monitor_unit(unit: str, callback: Callable[[str], None]) -> None:
callback('inactive' if unit == 'ubo-update.service' else 'active')

ubo_app.utils.monitor_unit.monitor_unit = fake_monitor_unit

import ubo_app.display as _ # noqa: F401

signal.signal(signal.SIGTERM, signal_handler)
Expand All @@ -112,11 +122,12 @@ def signal_handler(signum: int, _: object) -> None:

logger.info('Received signal %s, turning off the display...', signum)

signal.signal(signal.SIGTERM, signal.SIG_DFL)
signal.signal(signal.SIGINT, signal.SIG_DFL)

display.state.turn_off()
display.state.pause()

signal.signal(signal.SIGTERM, signal.SIG_DFL)
signal.signal(signal.SIGINT, signal.SIG_DFL)
if signum == signal.SIGINT:
logger.info('Exiting gracefully, sending the signal again will force exit!')
from ubo_app.store.main import dispatch
Expand Down
2 changes: 2 additions & 0 deletions ubo_app/store/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class RebootAction(PowerAction): ...

class SetMenuPathAction(MainAction):
path: Sequence[str]
depth: int


class MainEvent(BaseEvent): ...
Expand Down Expand Up @@ -116,4 +117,5 @@ class RebootEvent(PowerEvent): ...
class MainState(Immutable):
menu: Menu | None = None
path: Sequence[str] = field(default_factory=list)
depth: int = 0
settings_items_priorities: dict[str, int] = field(default_factory=dict)
Loading

0 comments on commit 4dd7d8d

Please sign in to comment.