Skip to content

Commit

Permalink
Merge pull request #2122 from dbungert/component-step1-refactor
Browse files Browse the repository at this point in the history
convert subiquity.server.snapdapi into a package
  • Loading branch information
dbungert authored Dec 5, 2024
2 parents 146b9cb + 8874f16 commit b78c7e1
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 156 deletions.
39 changes: 20 additions & 19 deletions subiquity/server/controllers/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@
align_up,
humanize_size,
)
from subiquity.server import snapdapi
from subiquity.server.autoinstall import AutoinstallError
from subiquity.server.controller import SubiquityController
from subiquity.server.controllers.source import SEARCH_DRIVERS_AUTOINSTALL_DEFAULT
from subiquity.server.mounter import Mounter
from subiquity.server.nonreportable import NonReportableException
from subiquity.server.snapdapi import (
from subiquity.server.snapd import api as snapdapi
from subiquity.server.snapd import types as snapdtypes
from subiquity.server.snapd.types import (
StorageEncryptionSupport,
StorageSafety,
SystemDetails,
Expand Down Expand Up @@ -300,11 +301,11 @@ def __init__(self, app):
self.app.hub.subscribe(InstallerChannels.PRE_SHUTDOWN, self._pre_shutdown)
self._variation_info: Dict[str, VariationInfo] = {}
self._info: Optional[VariationInfo] = None
self._on_volume: Optional[snapdapi.OnVolume] = None
self._on_volume: Optional[snapdtypes.OnVolume] = None
self._source_handler: Optional[AbstractSourceHandler] = None
self._system_mounter: Optional[Mounter] = None
self._role_to_device: Dict[Union[str, snapdapi.Role], _Device] = {}
self._device_to_structure: Dict[_Device, snapdapi.OnVolume] = {}
self._role_to_device: Dict[Union[str, snapdtypes.Role], _Device] = {}
self._device_to_structure: Dict[_Device, snapdtypes.OnVolume] = {}
self._pyudev_context: Optional[pyudev.Context] = None
self.use_tpm: bool = False
self.locked_probe_data: bool = False
Expand Down Expand Up @@ -906,7 +907,7 @@ def potential_boot_disks(self, check_boot=True, with_reformatting=False):
def _offsets_and_sizes_for_volume(self, volume):
offset = self.model._partition_alignment_data["gpt"].min_start_offset
for structure in volume.structure:
if structure.role == snapdapi.Role.MBR:
if structure.role == snapdtypes.Role.MBR:
continue
if structure.offset is not None:
offset = structure.offset
Expand All @@ -920,7 +921,7 @@ async def guided_core_boot(self, disk: Disk):
# features that are only available with v2 partitioning.
self.model.storage_version = 2
[volume] = self._info.system.volumes.values()
self._on_volume = snapdapi.OnVolume.from_volume(volume)
self._on_volume = snapdtypes.OnVolume.from_volume(volume)

preserved_parts = set()

Expand Down Expand Up @@ -953,7 +954,7 @@ async def guided_core_boot(self, disk: Disk):
part = parts_by_offset_size[(offset, size)]
else:
if (
structure.role == snapdapi.Role.SYSTEM_DATA
structure.role == snapdtypes.Role.SYSTEM_DATA
and structure == self._on_volume.structure[-1]
):
gap = gaps.at_offset(disk, offset)
Expand All @@ -974,20 +975,20 @@ async def guided_core_boot(self, disk: Disk):
fs = self.model.add_filesystem(
part, structure.filesystem, label=structure.label
)
if structure.role == snapdapi.Role.SYSTEM_DATA:
if structure.role == snapdtypes.Role.SYSTEM_DATA:
self.model.add_mount(fs, "/")
elif structure.role == snapdapi.Role.SYSTEM_BOOT:
elif structure.role == snapdtypes.Role.SYSTEM_BOOT:
self.model.add_mount(fs, "/boot")
elif part.flag == "boot":
part.grub_device = True
self.model.add_mount(fs, "/boot/efi")
if structure.role != snapdapi.Role.NONE:
if structure.role != snapdtypes.Role.NONE:
self._role_to_device[structure.role] = part
self._device_to_structure[part] = structure

disk._partitions.sort(key=lambda p: p.number)

def _on_volumes(self) -> Dict[str, snapdapi.OnVolume]:
def _on_volumes(self) -> Dict[str, snapdtypes.OnVolume]:
# Return a value suitable for use as the 'on-volumes' part of a
# SystemActionRequest.
#
Expand All @@ -1003,12 +1004,12 @@ async def setup_encryption(self, context):
result = await snapdapi.post_and_wait(
self.app.snapdapi,
self.app.snapdapi.v2.systems[label].POST,
snapdapi.SystemActionRequest(
action=snapdapi.SystemAction.INSTALL,
step=snapdapi.SystemActionStep.SETUP_STORAGE_ENCRYPTION,
snapdtypes.SystemActionRequest(
action=snapdtypes.SystemAction.INSTALL,
step=snapdtypes.SystemActionStep.SETUP_STORAGE_ENCRYPTION,
on_volumes=self._on_volumes(),
),
ann=snapdapi.SystemActionResponse,
ann=snapdtypes.SystemActionResponse,
)
for role, enc_path in result.encrypted_devices.items():
arb_device = ArbitraryDevice(m=self.model, path=enc_path)
Expand All @@ -1024,9 +1025,9 @@ async def finish_install(self, context):
await snapdapi.post_and_wait(
self.app.snapdapi,
self.app.snapdapi.v2.systems[label].POST,
snapdapi.SystemActionRequest(
action=snapdapi.SystemAction.INSTALL,
step=snapdapi.SystemActionStep.FINISH,
snapdtypes.SystemActionRequest(
action=snapdtypes.SystemAction.INSTALL,
step=snapdtypes.SystemActionStep.FINISH,
on_volumes=self._on_volumes(),
),
)
Expand Down
10 changes: 3 additions & 7 deletions subiquity/server/controllers/refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,10 @@
import requests.exceptions

from subiquity.common.apidef import API
from subiquity.common.types import Change, RefreshCheckState, RefreshStatus
from subiquity.common.types import Change, RefreshCheckState, RefreshStatus, TaskStatus
from subiquity.server.controller import SubiquityController
from subiquity.server.snapdapi import (
SnapAction,
SnapActionRequest,
TaskStatus,
post_and_wait,
)
from subiquity.server.snapd.api import post_and_wait
from subiquity.server.snapd.types import SnapAction, SnapActionRequest
from subiquity.server.types import InstallerChannels
from subiquitycore.async_helpers import SingleInstanceTask, schedule_task
from subiquitycore.context import with_context
Expand Down
33 changes: 17 additions & 16 deletions subiquity/server/controllers/tests/test_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
make_partition,
make_raid,
)
from subiquity.server import snapdapi
from subiquity.server.autoinstall import AutoinstallError
from subiquity.server.controllers.filesystem import (
DRY_RUN_RESET_SIZE,
Expand All @@ -67,6 +66,8 @@
VariationInfo,
)
from subiquity.server.dryrun import DRConfig
from subiquity.server.snapd import api as snapdapi
from subiquity.server.snapd import types as snapdtypes
from subiquitycore.snapd import AsyncSnapd, SnapdConnection, get_fake_connection
from subiquitycore.tests.mocks import make_app
from subiquitycore.tests.parameterized import parameterized
Expand Down Expand Up @@ -1823,10 +1824,10 @@ def _add_details_for_structures(self, structures):
self.fsc._info = VariationInfo(
name="foo",
label="system",
system=snapdapi.SystemDetails(
system=snapdtypes.SystemDetails(
label="system",
volumes={
"pc": snapdapi.Volume(schema="gpt", structure=structures),
"pc": snapdtypes.Volume(schema="gpt", structure=structures),
},
),
)
Expand All @@ -1836,14 +1837,14 @@ async def test_guided_core_boot(self):
arbitrary_uuid = str(uuid.uuid4())
self._add_details_for_structures(
[
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type="83,0FC63DAF-8483-4772-8E79-3D69D8477DE4",
offset=1 << 20,
size=1 << 30,
filesystem="ext4",
name="one",
),
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type=arbitrary_uuid, offset=2 << 30, size=1 << 30, filesystem="ext4"
),
]
Expand Down Expand Up @@ -1875,7 +1876,7 @@ async def test_guided_core_boot_reuse(self):
)
self._add_details_for_structures(
[
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type="0FC63DAF-8483-4772-8E79-3D69D8477DE4",
offset=1 << 20,
size=1 << 30,
Expand All @@ -1896,7 +1897,7 @@ async def test_guided_core_boot_reuse_no_format(self):
)
self._add_details_for_structures(
[
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type="0FC63DAF-8483-4772-8E79-3D69D8477DE4",
offset=1 << 20,
size=1 << 30,
Expand All @@ -1913,20 +1914,20 @@ async def test_guided_core_boot_system_data(self):
disk = make_disk(self.fsc.model)
self._add_details_for_structures(
[
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type="21686148-6449-6E6F-744E-656564454649",
offset=1 << 20,
name="BIOS Boot",
size=1 << 20,
role="",
filesystem="",
),
snapdapi.VolumeStructure(
snapdtypes.VolumeStructure(
type="0FC63DAF-8483-4772-8E79-3D69D8477DE4",
offset=2 << 20,
name="ptname",
size=2 << 30,
role=snapdapi.Role.SYSTEM_DATA,
role=snapdtypes.Role.SYSTEM_DATA,
filesystem="ext4",
),
]
Expand Down Expand Up @@ -1976,7 +1977,7 @@ async def test_from_sample_data(self):
[
structure
for structure in self.fsc._info.system.volumes["pc"].structure
if structure.role != snapdapi.Role.MBR
if structure.role != snapdtypes.Role.MBR
]
)
self.assertEqual(partition_count, len(disk.partitions()))
Expand All @@ -1988,9 +1989,9 @@ async def test_from_sample_data(self):
with mock.patch.object(
snapdapi, "post_and_wait", new_callable=mock.AsyncMock
) as mocked:
mocked.return_value = snapdapi.SystemActionResponse(
mocked.return_value = snapdtypes.SystemActionResponse(
encrypted_devices={
snapdapi.Role.SYSTEM_DATA: "enc-system-data",
snapdtypes.Role.SYSTEM_DATA: "enc-system-data",
},
)
await self.fsc.setup_encryption(context=self.fsc.context)
Expand All @@ -2008,8 +2009,8 @@ async def test_from_sample_data(self):
mocked.assert_called_once()
[call] = mocked.mock_calls
request = call.args[2]
self.assertEqual(request.action, snapdapi.SystemAction.INSTALL)
self.assertEqual(request.step, snapdapi.SystemActionStep.FINISH)
self.assertEqual(request.action, snapdtypes.SystemAction.INSTALL)
self.assertEqual(request.step, snapdtypes.SystemActionStep.FINISH)

async def test_from_sample_data_autoinstall(self):
# calling this a unit test is definitely questionable. but it
Expand All @@ -2036,7 +2037,7 @@ async def test_from_sample_data_autoinstall(self):
[
structure
for structure in self.fsc._info.system.volumes["pc"].structure
if structure.role != snapdapi.Role.MBR
if structure.role != snapdtypes.Role.MBR
]
)
self.assertEqual(partition_count, len(disk.partitions()))
Expand Down
7 changes: 4 additions & 3 deletions subiquity/server/controllers/tests/test_refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
import requests_mock
from jsonschema.validators import validator_for

from subiquity.server import snapdapi
from subiquity.server.controllers import refresh as refresh_mod
from subiquity.server.controllers.refresh import RefreshController, SnapChannelSource
from subiquity.server.snapd import api as snapdapi
from subiquity.server.snapd import types as snapdtypes
from subiquitycore.snapd import AsyncSnapd, SnapdConnection, get_fake_connection
from subiquitycore.tests import SubiTestCase
from subiquitycore.tests.mocks import make_app
Expand All @@ -48,7 +49,7 @@ async def test_configure_snapd_kernel_autoinstall(self):

paw.assert_called_once()
request = paw.mock_calls[0].args[2]
self.assertEqual(request.action, snapdapi.SnapAction.SWITCH)
self.assertEqual(request.action, snapdtypes.SnapAction.SWITCH)
self.assertEqual(request.channel, "newchan")

async def test_configure_snapd_notfound(self):
Expand Down Expand Up @@ -91,7 +92,7 @@ async def GET(self):

paw.assert_called_once()
request = paw.mock_calls[0].args[2]
self.assertEqual(request.action, snapdapi.SnapAction.SWITCH)
self.assertEqual(request.action, snapdtypes.SnapAction.SWITCH)
self.assertEqual(request.channel, "newchan")

# Test with the snap not following the expected channel
Expand Down
2 changes: 1 addition & 1 deletion subiquity/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from subiquity.server.nonreportable import NonReportableException
from subiquity.server.pkghelper import get_package_installer
from subiquity.server.runner import get_command_runner
from subiquity.server.snapdapi import make_api_client
from subiquity.server.snapd.api import make_api_client
from subiquity.server.types import InstallerChannels
from subiquitycore.async_helpers import run_bg_task, run_in_thread
from subiquitycore.context import Context, with_context
Expand Down
14 changes: 14 additions & 0 deletions subiquity/server/snapd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
Loading

0 comments on commit b78c7e1

Please sign in to comment.