mirror: if mirror test fails, suggest an offline install

In the mirror screen, if the test fails and the user decides to ignore
the failure, we used to continue the installation normally ; which in
most scenarios resulted in an error at a later stage of the
installation.

Instead, we now revert to an installation without network (i.e., only
packages from the pool are considered for installation) if the user
decides to ignore the failure.

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2024-04-11 10:55:07 +02:00
parent 5553793f43
commit 0bb4915c9f
2 changed files with 36 additions and 9 deletions

View File

@ -15,6 +15,7 @@
import asyncio
import logging
from typing import Optional
from subiquity.client.controller import SubiquityTuiController
from subiquity.common.types import MirrorCheckStatus, MirrorGet, MirrorPost
@ -42,6 +43,15 @@ class MirrorController(SubiquityTuiController):
# Just in case there is no candidate at all.
# In practise, it should seldom happen.
url = next(iter(mirror_response.candidates), "")
if not mirror_response.use_during_installation:
# If the user comes back to the mirror screen after accepting to
# do an installation without the archive (i.e., only fetching from
# the pool), the call to /network/has_network will return false. We
# need to reset the force_offline value if we want to run another
# mirror test.
await self.endpoint.POST(MirrorPost(use_during_installation=True))
has_network = await self.app.client.network.has_network.GET()
if has_network:
check = await self.endpoint.check_mirror.progress.GET()
@ -69,6 +79,19 @@ class MirrorController(SubiquityTuiController):
def cancel(self):
self.app.prev_screen()
def done(self, mirror):
log.debug("MirrorController.done next_screen mirror=%s", mirror)
self.app.next_screen(self.endpoint.POST(MirrorPost(elected=mirror)))
def done(self, mirror, skip_archive: Optional[bool]):
if skip_archive is not None:
use_during_installation = not skip_archive
else:
use_during_installation = None
data = MirrorPost(
elected=mirror, use_during_installation=use_during_installation
)
log.debug(
"MirrorController.done next_screen mirror=%s, use_during_installation=%s",
mirror,
use_during_installation,
)
self.app.next_screen(self.endpoint.POST(data))

View File

@ -47,8 +47,10 @@ MIRROR_CHECK_CONFIRMATION_TEXTS = {
MirrorCheckStatus.FAILED: (
_("Mirror check failed"),
_(
"The check of the mirror URL failed. You can continue, but it is very"
" likely that the installation will fail."
"The check of the mirror URL failed. If you decide to continue, only"
" packages present on the installation media will be considered for"
" installation. Remember to install security updates after booting"
" your newly installed system."
),
),
None: (
@ -217,7 +219,7 @@ class MirrorView(BaseView):
self.last_status = check_state.status
def done(self, result):
async def confirm_continue_anyway() -> None:
async def confirm_continue_anyway(continue_skip_archive: bool) -> None:
title, question = MIRROR_CHECK_CONFIRMATION_TEXTS[self.last_status]
confirmed = await self.ask_confirmation(
title=title,
@ -227,7 +229,8 @@ class MirrorView(BaseView):
)
if confirmed:
self.controller.done(result.url.value)
skip_archive = True if continue_skip_archive else None
self.controller.done(result.url.value, skip_archive=skip_archive)
log.debug("User input: {}".format(result.as_data()))
if self.has_network and self.last_status in [
@ -235,9 +238,10 @@ class MirrorView(BaseView):
MirrorCheckStatus.FAILED,
None,
]:
async_helpers.run_bg_task(confirm_continue_anyway())
status_is_failed = self.last_status == MirrorCheckStatus.FAILED
async_helpers.run_bg_task(confirm_continue_anyway(status_is_failed))
else:
self.controller.done(result.url.value)
self.controller.done(result.url.value, skip_archive=None)
def cancel(self, result=None):
self.controller.cancel()