Merge pull request #1968 from ogayot/server-ignore-mirror-test-offline

mirror: if the mirror test fails, suggest an offline install
This commit is contained in:
Olivier Gayot 2024-04-17 10:12:55 +02:00 committed by GitHub
commit aaf0d56472
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 49 additions and 10 deletions

View File

@ -15,6 +15,7 @@
import asyncio import asyncio
import logging import logging
from typing import Optional
from subiquity.client.controller import SubiquityTuiController from subiquity.client.controller import SubiquityTuiController
from subiquity.common.types import MirrorCheckStatus, MirrorGet, MirrorPost from subiquity.common.types import MirrorCheckStatus, MirrorGet, MirrorPost
@ -42,6 +43,15 @@ class MirrorController(SubiquityTuiController):
# Just in case there is no candidate at all. # Just in case there is no candidate at all.
# In practise, it should seldom happen. # In practise, it should seldom happen.
url = next(iter(mirror_response.candidates), "") 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() has_network = await self.app.client.network.has_network.GET()
if has_network: if has_network:
check = await self.endpoint.check_mirror.progress.GET() check = await self.endpoint.check_mirror.progress.GET()
@ -69,6 +79,19 @@ class MirrorController(SubiquityTuiController):
def cancel(self): def cancel(self):
self.app.prev_screen() self.app.prev_screen()
def done(self, mirror): def done(self, mirror, skip_archive: Optional[bool]):
log.debug("MirrorController.done next_screen mirror=%s", mirror) if skip_archive is not None:
self.app.next_screen(self.endpoint.POST(MirrorPost(elected=mirror))) 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

@ -879,6 +879,7 @@ class MirrorPost:
elected: Optional[str] = None elected: Optional[str] = None
candidates: Optional[List[str]] = None candidates: Optional[List[str]] = None
staged: Optional[str] = None staged: Optional[str] = None
use_during_installation: Optional[bool] = None
class MirrorPostResponse(enum.Enum): class MirrorPostResponse(enum.Enum):
@ -892,6 +893,9 @@ class MirrorGet:
elected: Optional[str] elected: Optional[str]
candidates: List[str] candidates: List[str]
staged: Optional[str] staged: Optional[str]
# Tells whether the mirror will be used during the installation.
# When it is False, we will only fetch packages from the pool.
use_during_installation: bool
class MirrorSelectionFallback(enum.Enum): class MirrorSelectionFallback(enum.Enum):

View File

@ -368,7 +368,11 @@ class MirrorController(SubiquityController):
# Skip the country-mirrors if they have not been resolved yet. # Skip the country-mirrors if they have not been resolved yet.
candidates = [c.uri for c in compatibles if c.uri is not None] candidates = [c.uri for c in compatibles if c.uri is not None]
return MirrorGet( return MirrorGet(
relevant=relevant, elected=elected, candidates=candidates, staged=staged relevant=relevant,
elected=elected,
candidates=candidates,
staged=staged,
use_during_installation=not self.app.base_model.network.force_offline,
) )
async def POST(self, data: Optional[MirrorPost]) -> MirrorPostResponse: async def POST(self, data: Optional[MirrorPost]) -> MirrorPostResponse:
@ -420,6 +424,10 @@ class MirrorController(SubiquityController):
ensure_elected_in_candidates() ensure_elected_in_candidates()
await self.configured() await self.configured()
if data.use_during_installation is not None:
self.app.base_model.network.force_offline = not data.use_during_installation
return MirrorPostResponse.OK return MirrorPostResponse.OK
async def disable_components_GET(self) -> List[str]: async def disable_components_GET(self) -> List[str]:

View File

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