filesystem: mount snapd/seed/systems only if it exists
The "$source"/var/lib/snapd/seed/systems directory only exists in certain scenarios related to TPM-backed FDE. When the directory does not exist, attempting to bind-mount it to /var/lib/snapd/seed/systems crashes the install with a CalledProcessError. We now make sure the directory exists before trying to mount it. For dry-run test cases, we added a configuration item that simulates the presence (or the non-presence) of the systems directory on the source. Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
parent
93f06eeb0f
commit
217ac98fc6
|
@ -1,4 +1,5 @@
|
|||
#source-catalog: examples/tpm-sources.yaml
|
||||
#dr-config: examples/tpm-dr-config.yaml
|
||||
Source:
|
||||
source: src-prefer-encrypted
|
||||
Serial:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
systems_dir_exists: true
|
|
@ -19,6 +19,7 @@ import glob
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
import select
|
||||
from typing import Dict, List, Optional
|
||||
|
@ -110,6 +111,10 @@ than GPT, which is not currently supported.
|
|||
""")
|
||||
|
||||
|
||||
class NoSnapdSystemsOnSource(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FilesystemController(SubiquityController, FilesystemManipulator):
|
||||
|
||||
endpoint = API.storage
|
||||
|
@ -171,6 +176,12 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
source_path = self.app.controllers.Source.source_path
|
||||
cur_systems_dir = '/var/lib/snapd/seed/systems'
|
||||
source_systems_dir = os.path.join(source_path, cur_systems_dir[1:])
|
||||
if self.app.opts.dry_run:
|
||||
systems_dir_exists = self.app.dr_cfg.systems_dir_exists
|
||||
else:
|
||||
systems_dir_exists = pathlib.Path(source_systems_dir).is_dir()
|
||||
if not systems_dir_exists:
|
||||
raise NoSnapdSystemsOnSource
|
||||
self._system_mounter = Mounter(self.app)
|
||||
await self._system_mounter.bind_mount_tree(
|
||||
source_systems_dir, cur_systems_dir)
|
||||
|
@ -182,7 +193,10 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
|
||||
async def _get_system(self):
|
||||
await self._unmount_system()
|
||||
try:
|
||||
await self._mount_system()
|
||||
except NoSnapdSystemsOnSource:
|
||||
return
|
||||
self._system = None
|
||||
label = self.app.base_model.source.current.snapd_system_label
|
||||
if label is not None:
|
||||
|
|
|
@ -38,6 +38,7 @@ from subiquity.models.tests.test_filesystem import (
|
|||
)
|
||||
from subiquity.server import snapdapi
|
||||
from subiquity.server.controllers.filesystem import FilesystemController
|
||||
from subiquity.server.dryrun import DRConfig
|
||||
|
||||
bootloaders = [(bl, ) for bl in list(Bootloader)]
|
||||
bootloaders_and_ptables = [(bl, pt)
|
||||
|
@ -472,6 +473,7 @@ class TestCoreBootInstallMethods(IsolatedAsyncioTestCase):
|
|||
self.app.prober = mock.Mock()
|
||||
self.app.snapdapi = snapdapi.make_api_client(
|
||||
AsyncSnapd(get_fake_connection()))
|
||||
self.app.dr_cfg = DRConfig()
|
||||
self.fsc = FilesystemController(app=self.app)
|
||||
self.fsc._configured = True
|
||||
self.fsc.model = make_model(Bootloader.UEFI)
|
||||
|
@ -565,6 +567,9 @@ class TestCoreBootInstallMethods(IsolatedAsyncioTestCase):
|
|||
self.app.base_model.source.current.snapd_system_label = \
|
||||
'prefer-encrypted'
|
||||
self.app.controllers.Source.source_path = ''
|
||||
|
||||
self.app.dr_cfg.systems_dir_exists = True
|
||||
|
||||
await self.fsc._get_system_task.start()
|
||||
await self.fsc._get_system_task.wait()
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ class DRConfig:
|
|||
All variables here should have default values ; to indicate the behavior we
|
||||
want by default in dry-run mode. """
|
||||
|
||||
# Tells whether "$source"/var/lib/snapd/seed/systems exists on the source.
|
||||
systems_dir_exists: bool = False
|
||||
|
||||
@classmethod
|
||||
def load(cls, stream):
|
||||
data = yaml.safe_load(stream)
|
||||
|
|
Loading…
Reference in New Issue