From 03f41c2f60c6011c185ad5e1a44181094e5f4250 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Thu, 16 Feb 2023 11:10:44 +0100 Subject: [PATCH] debconf-selections: pass to curtin's apt-config rather than curthooks We got multiple bug reports in the past stating that the installer is not honoring some part of the apt settings; either supplied by means of autoinstall (e.g., pinning) or via the subiquity UI (e.g., proxy). What happens under the hood is that curtin overwrites the APT settings as part of the curthooks stage ; effectively discarding earlier settings applied in the apt-config stage. Curtin does so because we pass debconf_selections directives to curthooks. In the past, curtin used to handle debconf_selections separately but nowadays it considers that they are part of the APT config. As a result, it decides to run apt-config again (but with a close to empty configuration) as part of the curthooks stage. We now pass debconf_selections as part of the apt-config stage. This should hint curtin not to run apt-config again as part of curthooks. Signed-off-by: Olivier Gayot --- scripts/runtests.sh | 4 ++-- subiquity/models/subiquity.py | 6 +++++- subiquity/server/apt.py | 7 ++++++- subiquity/server/tests/test_apt.py | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/runtests.sh b/scripts/runtests.sh index 526db8b4..f2fd93f8 100755 --- a/scripts/runtests.sh +++ b/scripts/runtests.sh @@ -223,9 +223,9 @@ python3 scripts/check-yaml-fields.py $tmpdir/var/log/installer/subiquity-curtin- apt.preferences[0].pin-priority=200 \ apt.preferences[0].pin='"origin *ubuntu.com*"' \ apt.preferences[1].package='"python-*"' \ - apt.preferences[1].pin-priority=-1 + apt.preferences[1].pin-priority=-1 \ + apt.debconf_selections.subiquity='"eek"' python3 scripts/check-yaml-fields.py "$tmpdir"/var/log/installer/curtin-install/subiquity-curthooks.conf \ - debconf_selections.subiquity='"eek"' \ storage.config[-1].options='"errors=remount-ro"' python3 scripts/check-yaml-fields.py <(python3 scripts/check-yaml-fields.py $tmpdir/etc/cloud/cloud.cfg.d/99-installer.cfg datasource.None.userdata_raw) \ locale='"en_GB.UTF-8"' \ diff --git a/subiquity/models/subiquity.py b/subiquity/models/subiquity.py index cd3c29a3..87d159cc 100644 --- a/subiquity/models/subiquity.py +++ b/subiquity/models/subiquity.py @@ -19,7 +19,7 @@ import functools import json import logging import os -from typing import Set +from typing import Any, Dict, Set import uuid import yaml @@ -159,6 +159,10 @@ class DebconfSelectionsModel: self.selections = '' def render(self): + return {} + + def get_apt_config( + self, final: bool, has_network: bool) -> Dict[str, Any]: return {'debconf_selections': {'subiquity': self.selections}} diff --git a/subiquity/server/apt.py b/subiquity/server/apt.py index 5ff278b4..51dfc0b8 100644 --- a/subiquity/server/apt.py +++ b/subiquity/server/apt.py @@ -115,7 +115,12 @@ class AptConfigurer: def apt_config(self, final: bool): cfg = {} has_network = self.app.base_model.network.has_network - for model in self.app.base_model.mirror, self.app.base_model.proxy: + models = [ + self.app.base_model.mirror, + self.app.base_model.proxy, + self.app.base_model.debconf_selections, + ] + for model in models: merge_config(cfg, model.get_apt_config( final=final, has_network=has_network)) return {'apt': cfg} diff --git a/subiquity/server/tests/test_apt.py b/subiquity/server/tests/test_apt.py index 3e6423ec..ec53a8c7 100644 --- a/subiquity/server/tests/test_apt.py +++ b/subiquity/server/tests/test_apt.py @@ -29,6 +29,7 @@ from subiquity.server.apt import ( from subiquity.server.dryrun import DRConfig from subiquity.models.mirror import MirrorModel from subiquity.models.proxy import ProxyModel +from subiquity.models.subiquity import DebconfSelectionsModel APT_UPDATE_SUCCESS = """\ @@ -61,6 +62,7 @@ class TestAptConfigurer(SubiTestCase): self.model.mirror = MirrorModel() self.model.mirror.create_primary_candidate("http://mymirror").elect() self.model.proxy = ProxyModel() + self.model.debconf_selections = DebconfSelectionsModel() self.model.locale.selected_language = "en_US.UTF-8" self.app = make_app(self.model) self.configurer = AptConfigurer(self.app, AsyncMock(), '')