From 4d24865a637f338d6e9e6809f6513ef5aeef1c40 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 15 Sep 2023 13:26:25 +1200 Subject: [PATCH] include api-only data when sending storage objects from client to server Making an install that used an existing RAID failed because of an attempt to log the size of the RAID when rendering the curtin config. This turns out to be because when the client sends the storage objects back to the server it loses all the "api only" data including the udev data that is needed to display the size. In some sense this is a bit silly, we could just drop the log statement and it would be fine but I think it's probably better to always have the full storage objects in the server (until we can get away from this hackish API anyway). --- subiquity/client/controllers/filesystem.py | 13 +++++++++++-- subiquity/models/filesystem.py | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/subiquity/client/controllers/filesystem.py b/subiquity/client/controllers/filesystem.py index b82ecc99..0f408793 100644 --- a/subiquity/client/controllers/filesystem.py +++ b/subiquity/client/controllers/filesystem.py @@ -28,7 +28,12 @@ from subiquity.common.types import ( ProbeStatus, StorageResponseV2, ) -from subiquity.models.filesystem import Bootloader, FilesystemModel, raidlevels_by_value +from subiquity.models.filesystem import ( + ActionRenderMode, + Bootloader, + FilesystemModel, + raidlevels_by_value, +) from subiquity.ui.views import FilesystemView, GuidedDiskSelectionView from subiquity.ui.views.filesystem.probing import ProbingFailed, SlowProbing from subiquitycore.async_helpers import run_bg_task @@ -288,4 +293,8 @@ class FilesystemController(SubiquityTuiController, FilesystemManipulator): def finish(self): log.debug("FilesystemController.finish next_screen") - self.app.next_screen(self.endpoint.POST(self.model._render_actions())) + self.app.next_screen( + self.endpoint.POST( + self.model._render_actions(mode=ActionRenderMode.FOR_API_CLIENT) + ) + ) diff --git a/subiquity/models/filesystem.py b/subiquity/models/filesystem.py index 994207a2..2de5eefd 100644 --- a/subiquity/models/filesystem.py +++ b/subiquity/models/filesystem.py @@ -1336,6 +1336,10 @@ class ActionRenderMode(enum.Enum): # information that is only used by client/server communication, # not curtin. FOR_API = enum.auto() + # FOR_API_CLIENT means render actions for devices that have + # changes and include information that is only used by + # client/server communication, not curtin. + FOR_API_CLIENT = enum.auto() # DEVICES means to just render actions for setting up block # devices, e.g. partitioning disks and assembling RAIDs but not # any format or mount actions. @@ -1346,6 +1350,12 @@ class ActionRenderMode(enum.Enum): # by path. FORMAT_MOUNT = enum.auto() + def is_api(self): + return self in [ActionRenderMode.FOR_API, ActionRenderMode.FOR_API_CLIENT] + + def include_all(self): + return self in [ActionRenderMode.FOR_API] + class FilesystemModel: target = None @@ -1785,7 +1795,7 @@ class FilesystemModel: obj.name, obj.size, ) - r.append(asdict(obj, for_api=mode == ActionRenderMode.FOR_API)) + r.append(asdict(obj, for_api=mode.is_api())) emitted_ids.add(obj.id) def ensure_partitions(dev): @@ -1826,7 +1836,7 @@ class FilesystemModel: mountpoints = {m.path: m.id for m in self.all_mountlikes()} log.debug("mountpoints %s", mountpoints) - if mode == ActionRenderMode.FOR_API: + if mode.include_all(): work = list(self._actions) else: work = [a for a in self._actions if not getattr(a, "preserve", False)]