Skip to content

Commit

Permalink
skip mirror/apt configuration when installing core
Browse files Browse the repository at this point in the history
This generalizes some of the things I did when adding support for
reset_partition_only recently.
  • Loading branch information
mwhudson committed Jul 6, 2023
1 parent db23775 commit cca3014
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 26 deletions.
4 changes: 4 additions & 0 deletions subiquity/client/controllers/mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import asyncio
import logging

from subiquitycore.tuicontroller import Skip

from subiquity.common.types import (
MirrorCheckStatus,
MirrorGet,
Expand All @@ -33,6 +35,8 @@ class MirrorController(SubiquityTuiController):

async def make_ui(self):
mirror_response: MirrorGet = await self.endpoint.GET()
if not mirror_response.relevant:
raise Skip
# We could do all sort of things with the list of candidate mirrors in
# the UI ; like suggesting the next mirror automatically if the first
# candidate fails. For now, we keep things simple.
Expand Down
1 change: 1 addition & 0 deletions subiquity/common/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ class MirrorPostResponse(enum.Enum):

@attr.s(auto_attribs=True)
class MirrorGet:
relevant: bool
elected: Optional[str]
candidates: List[str]
staged: Optional[str]
Expand Down
34 changes: 22 additions & 12 deletions subiquity/server/controllers/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ async def configure_apt(self, *, context):
return await configurer.configure_for_install(context)

async def setup_target(self, context):
if self.model.source.current.variant == 'core':
return
mirror = self.app.controllers.Mirror
await mirror.final_apt_configurer.setup_target(context, self.tpath())

Expand Down Expand Up @@ -386,6 +388,11 @@ async def create_core_boot_classic_fstab(self, *, context):
with open(self.tpath('etc/fstab'), 'w') as fp:
fp.write("/run/mnt/ubuntu-boot/EFI/ubuntu /boot/grub none bind\n")

def needs_apt_configuration(self) -> bool:
return (
not self.app.controllers.Filesystem.reset_partition_only
and self.model.source.current.variant != 'core')

@with_context()
async def install(self, *, context):
context.set('is-install-context', True)
Expand All @@ -406,29 +413,28 @@ async def install(self, *, context):

self.app.update_state(ApplicationState.RUNNING)

if not self.app.controllers.Filesystem.reset_partition_only:
for_install_path = await self.configure_apt(context=context)
if self.needs_apt_configuration():
for_install_path = 'cp://' + await self.configure_apt(
context=context)

await self.app.hub.abroadcast(InstallerChannels.APT_CONFIGURED)
else:
for_install_path = None

if self.model.target is not None:
if os.path.exists(self.model.target):
await self.unmount_target(
context=context, target=self.model.target)
else:
for_install_path = ''

await self.curtin_install(
context=context, source='cp://' + for_install_path)
await self.curtin_install(context=context, source=for_install_path)

if not self.app.controllers.Filesystem.reset_partition_only:
self.app.update_state(ApplicationState.WAITING)

self.app.update_state(ApplicationState.WAITING)

await self.model.wait_postinstall()
await self.model.wait_postinstall()

self.app.update_state(ApplicationState.RUNNING)
self.app.update_state(ApplicationState.RUNNING)

await self.postinstall(context=context)
await self.postinstall(context=context)

self.app.update_state(ApplicationState.DONE)
except Exception:
Expand All @@ -443,6 +449,10 @@ async def install(self, *, context):
description="final system configuration", level="INFO",
childlevel="DEBUG")
async def postinstall(self, *, context):
if self.app.controllers.Filesystem.reset_partition_only:
return
if self.model.source.current.variant == 'core':
return
autoinstall_path = os.path.join(
self.app.root, 'var/log/installer/autoinstall-user-data')
autoinstall_config = "#cloud-config\n" + yaml.dump(
Expand Down
40 changes: 28 additions & 12 deletions subiquity/server/controllers/mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,12 @@ async def on_source(self):
# apply_autoinstall_config but this is out of scope.
raise RuntimeError("source model has changed but autoinstall"
" configuration is already being applied")
self.test_apt_configurer = get_apt_configurer(
self.app, self.app.controllers.Source.get_handler())
source_entry = self.app.base_model.source.current
if source_entry.variant == 'core':
self.test_apt_configurer = None
else:
self.test_apt_configurer = get_apt_configurer(
self.app, self.app.controllers.Source.get_handler())
self.source_configured_event.set()

def serialize(self):
Expand Down Expand Up @@ -327,7 +331,9 @@ async def run_mirror_testing(self, output: io.StringIO) -> None:
# apply_apt_config and run_apt_config_check. Just make sure we still
# use the original one.
configurer = self.test_apt_configurer
assert configurer is not None
if configurer is None:
# i.e. core
return
await configurer.apply_apt_config(
self.context, final=False)
await configurer.run_apt_config_check(output)
Expand All @@ -342,15 +348,25 @@ async def wait_config(self, variation_name: str) -> AptConfigurer:
async def GET(self) -> MirrorGet:
elected: Optional[str] = None
staged: Optional[str] = None
if self.model.primary_elected is not None:
elected = self.model.primary_elected.uri
if self.model.primary_staged is not None:
staged = self.model.primary_staged.uri

compatibles = self.model.compatible_primary_candidates()
# Skip the country-mirrors if they have not been resolved yet.
candidates = [c.uri for c in compatibles if c.uri is not None]
return MirrorGet(elected=elected, candidates=candidates, staged=staged)
candidates: List[str] = []
source_entry = self.app.base_model.source.current
if source_entry.variant == 'core':
relevant = False
else:
relevant = True
if self.model.primary_elected is not None:
elected = self.model.primary_elected.uri
if self.model.primary_staged is not None:
staged = self.model.primary_staged.uri

compatibles = self.model.compatible_primary_candidates()
# Skip the country-mirrors if they have not been resolved yet.
candidates = [c.uri for c in compatibles if c.uri is not None]
return MirrorGet(
relevant=relevant,
elected=elected,
candidates=candidates,
staged=staged)

async def POST(self, data: Optional[MirrorPost]) -> MirrorPostResponse:
log.debug(data)
Expand Down
6 changes: 4 additions & 2 deletions subiquity/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,13 @@ def get_installer_password_from_cloudinit_log():
"filesystem",
"kernel",
"keyboard",
"mirror",
"network",
"proxy",
"source",
})
},
desktop={"mirror"},
server={"mirror"},
)

POSTINSTALL_MODEL_NAMES = ModelNames({
"drivers",
Expand Down

0 comments on commit cca3014

Please sign in to comment.