From 354fc7775982f7367c0b95c6e3c1b17d325f99c7 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Mon, 17 Oct 2022 12:14:15 +0200 Subject: [PATCH 1/3] apt: introduce OverlayCleanupError in overlay context manager The apt.overlay construct unmounts the overlay at the end of the with body. To do so, it leans on subprocess.run(["umount", ...], check=True). If we want to catch the unmount error, we need to do: try: with apt.overlay(): # do stuff except subprocess.CalledProcessError: # handle the unmount exception However, we do not want the subprocess exceptions that happen in the with body to be caught in the same except block. If the umount call fails, we now wrap the exception in a OverlayCleanupError ; therefore we can make the distinction between an unmount error and a subprocess error that would happen in the body. Signed-off-by: Olivier Gayot --- subiquity/server/apt.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/subiquity/server/apt.py b/subiquity/server/apt.py index 469984013..e4b27243c 100644 --- a/subiquity/server/apt.py +++ b/subiquity/server/apt.py @@ -18,6 +18,7 @@ import logging import os import shutil +import subprocess import tempfile from typing import List, Optional, Union @@ -34,6 +35,10 @@ log = logging.getLogger('subiquity.server.apt') +class OverlayCleanupError(Exception): + """ Exception to raise when an overlay could not be cleaned up. """ + + class _MountBase: def p(self, *args: str) -> str: @@ -245,7 +250,10 @@ async def overlay(self): # Mountpoint object and (thanks to attr.s) make sure that it # compares equal to the one we discarded earlier. # But really, there should be better ways to handle this. - await self.unmount(Mountpoint(mountpoint=overlay.mountpoint)) + try: + await self.unmount(Mountpoint(mountpoint=overlay.mountpoint)) + except subprocess.CalledProcessError as exc: + raise OverlayCleanupError from exc async def cleanup(self): for m in reversed(self._mounts): From 3464fc5e788715bc38b0edcc81e51994f359eeaa Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Mon, 17 Oct 2022 12:27:32 +0200 Subject: [PATCH 2/3] drivers: do not consider overlay cleanup error fatal For some reason that we have not yet determined, the overlay that we use for the drivers code sometimes fails to unmount with EBUSY. When it happens, the _list_drivers task would fail, making subsequent GET calls to /drivers?wait=true fail as well and produce an error report. We now mark failures in the overlay unmount operation as non fatal. Signed-off-by: Olivier Gayot --- subiquity/server/controllers/drivers.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/subiquity/server/controllers/drivers.py b/subiquity/server/controllers/drivers.py index ade96456c..77cbb2aee 100644 --- a/subiquity/server/controllers/drivers.py +++ b/subiquity/server/controllers/drivers.py @@ -21,6 +21,7 @@ from subiquity.common.apidef import API from subiquity.common.types import DriversPayload, DriversResponse +from subiquity.server.apt import OverlayCleanupError from subiquity.server.controller import SubiquityController from subiquity.server.types import InstallerChannels from subiquity.server.ubuntu_drivers import ( @@ -83,16 +84,19 @@ async def _list_drivers(self, context): await self.configured() return apt = self.app.controllers.Mirror.apt_configurer - async with apt.overlay() as d: - try: - # Make sure ubuntu-drivers is available. - await self.ubuntu_drivers.ensure_cmd_exists(d.mountpoint) - except CommandNotFoundError: - self.drivers = [] - else: - self.drivers = await self.ubuntu_drivers.list_drivers( - root_dir=d.mountpoint, - context=context) + try: + async with apt.overlay() as d: + try: + # Make sure ubuntu-drivers is available. + await self.ubuntu_drivers.ensure_cmd_exists(d.mountpoint) + except CommandNotFoundError: + self.drivers = [] + else: + self.drivers = await self.ubuntu_drivers.list_drivers( + root_dir=d.mountpoint, + context=context) + except OverlayCleanupError: + log.exception("Failed to cleanup overlay. Continuing anyway.") log.debug("Available drivers to install: %s", self.drivers) if not self.drivers: await self.configured() From b72e8c791ea16a1deb134425f3f9ea8ff4047762 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Mon, 17 Oct 2022 09:29:08 -0600 Subject: [PATCH 3/3] curtin: rev for flash-kernel fix LP: #1992990 --- snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 928098a2f..c21fdea56 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -64,7 +64,7 @@ parts: plugin: python source-type: git source: https://git.launchpad.net/curtin - source-commit: 47c222681c81110a185497a64749f23596e29b16 + source-commit: 1fc717df52ec15f616d26fff3c10bff181599b30 build-packages: - shared-mime-info - zlib1g-dev