storage: fix screen sometimes not refreshing after slow probing
When we reach the storage screens on the installer, if the devices probing operation has not finished, we: * display a temporary "Probing" screen. * create an asynchronous task (a.k.a., probing task) that will eventually show the "Guide Storage" screen when the probing operation finishes. The probing task checks, when it finishes, that the screen currently visible is the "Probing" screen. This is the expectation and is true in most scenarios. But in case a different screen is visible, we skip refreshing the display. Unfortunately, sometimes, a "Progress" screen is shown for some time before the "Probing" screen appears. Consequently, we do not refresh the screen if the probing operation finishes whilst the Progress screen is visible. In order to keep the view returned by make_ui() up-to-date and make sure that the right screen is shown even if the probing operation finishes early, we use the level indirection that was implemented in make_ui. https://bugs.launchpad.net/subiquity/+bug/1968161 Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
parent
014d9d0d01
commit
414a2235e6
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Callable, Optional
|
||||||
|
|
||||||
from subiquitycore.lsb_release import lsb_release
|
from subiquitycore.lsb_release import lsb_release
|
||||||
|
from subiquitycore.view import BaseView
|
||||||
|
|
||||||
from subiquity.client.controller import SubiquityTuiController
|
from subiquity.client.controller import SubiquityTuiController
|
||||||
from subiquity.common.filesystem import gaps
|
from subiquity.common.filesystem import gaps
|
||||||
|
@ -50,19 +52,34 @@ class FilesystemController(SubiquityTuiController, FilesystemManipulator):
|
||||||
self.answers.setdefault('guided', False)
|
self.answers.setdefault('guided', False)
|
||||||
self.answers.setdefault('guided-index', 0)
|
self.answers.setdefault('guided-index', 0)
|
||||||
self.answers.setdefault('manual', [])
|
self.answers.setdefault('manual', [])
|
||||||
|
self.current_view: Optional[BaseView] = None
|
||||||
|
|
||||||
|
async def make_ui(self) -> Callable[[], BaseView]:
|
||||||
|
def get_current_view() -> BaseView:
|
||||||
|
assert self.current_view is not None
|
||||||
|
return self.current_view
|
||||||
|
|
||||||
async def make_ui(self):
|
|
||||||
status = await self.endpoint.guided.GET()
|
status = await self.endpoint.guided.GET()
|
||||||
if status.status == ProbeStatus.PROBING:
|
if status.status == ProbeStatus.PROBING:
|
||||||
self.app.aio_loop.create_task(self._wait_for_probing())
|
self.app.aio_loop.create_task(self._wait_for_probing())
|
||||||
return SlowProbing(self)
|
self.current_view = SlowProbing(self)
|
||||||
else:
|
else:
|
||||||
return self.make_guided_ui(status)
|
self.current_view = self.make_guided_ui(status)
|
||||||
|
# NOTE: If we return a BaseView instance directly here, we have no
|
||||||
|
# guarantee that it will be displayed on the screen by the time the
|
||||||
|
# probing operation finishes. Therefore, to allow us to reliably
|
||||||
|
# replace the screen by the "Guided Storage" when the probing operation
|
||||||
|
# finishes, we add a level of indirection.
|
||||||
|
# In essence, this allows us to make modifications to the screen
|
||||||
|
# that eventually will be displayed.
|
||||||
|
# This is mostly a workaround for the issue described in LP #1968161
|
||||||
|
return get_current_view
|
||||||
|
|
||||||
async def _wait_for_probing(self):
|
async def _wait_for_probing(self):
|
||||||
status = await self.endpoint.guided.GET(wait=True)
|
status = await self.endpoint.guided.GET(wait=True)
|
||||||
|
self.current_view = self.make_guided_ui(status)
|
||||||
if isinstance(self.ui.body, SlowProbing):
|
if isinstance(self.ui.body, SlowProbing):
|
||||||
self.ui.set_body(self.make_guided_ui(status))
|
self.ui.set_body(self.current_view)
|
||||||
else:
|
else:
|
||||||
log.debug("not refreshing the display. Current display is %r",
|
log.debug("not refreshing the display. Current display is %r",
|
||||||
self.ui.body)
|
self.ui.body)
|
||||||
|
|
Loading…
Reference in New Issue