mirror: do not let curtin decide the URL of the security archive

When the URL of the security archive is unset, curtin will set it to the
URL of the primary archive.

This is not the behavior we want for Ubuntu installations. On amd64 (and
i386), the URL of the security archive should be set to
http://security.ubuntu.com/ubuntu

On other architectures, it should be set to
http://ports.ubuntu.com/ubuntu-ports

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2023-09-07 11:31:53 +02:00
parent 79f2c4c432
commit 5556313652
3 changed files with 62 additions and 3 deletions

View File

@ -54,6 +54,18 @@ validate () {
;; ;;
*) *)
python3 scripts/validate-autoinstall-user-data.py < $tmpdir/var/log/installer/autoinstall-user-data python3 scripts/validate-autoinstall-user-data.py < $tmpdir/var/log/installer/autoinstall-user-data
# After the lunar release and the introduction of mirror testing, it
# came to our attention that new Ubuntu installations have the security
# repository configured with the primary mirror URL (i.e.,
# http://<cc>.archive.ubuntu.com/ubuntu) instead of
# http://security.ubuntu.com/ubuntu. Let's ensure we instruct curtin
# not to do that.
# If we run an autoinstall that customizes the security section as part
# of the test-suite, we will need to adapt this test.
python3 scripts/check-yaml-fields.py $tmpdir/var/log/installer/subiquity-curtin-apt.conf \
apt.security[0].uri='"http://security.ubuntu.com/ubuntu/"' \
apt.security[0].arches='["amd64", "i386"]' \
apt.security[1].uri='"http://ports.ubuntu.com/ubuntu-ports"'
;; ;;
esac esac
netplan generate --root $tmpdir netplan generate --root $tmpdir

View File

@ -81,6 +81,8 @@ from urllib import parse
import attr import attr
from curtin.commands.apt_config import ( from curtin.commands.apt_config import (
PORTS_ARCHES, PORTS_ARCHES,
PORTS_MIRRORS,
PRIMARY_ARCH_MIRRORS,
PRIMARY_ARCHES, PRIMARY_ARCHES,
get_arch_mirrorconfig, get_arch_mirrorconfig,
get_mirror, get_mirror,
@ -96,8 +98,8 @@ except ImportError:
log = logging.getLogger("subiquity.models.mirror") log = logging.getLogger("subiquity.models.mirror")
DEFAULT_SUPPORTED_ARCHES_URI = "http://archive.ubuntu.com/ubuntu" DEFAULT_SUPPORTED_ARCHES_URI = PRIMARY_ARCH_MIRRORS["PRIMARY"]
DEFAULT_PORTS_ARCHES_URI = "http://ports.ubuntu.com/ubuntu-ports" DEFAULT_PORTS_ARCHES_URI = PORTS_MIRRORS["PRIMARY"]
LEGACY_DEFAULT_PRIMARY_SECTION = [ LEGACY_DEFAULT_PRIMARY_SECTION = [
{ {
@ -110,6 +112,17 @@ LEGACY_DEFAULT_PRIMARY_SECTION = [
}, },
] ]
DEFAULT_SECURITY_SECTION = [
{
"arches": PRIMARY_ARCHES,
"uri": PRIMARY_ARCH_MIRRORS["SECURITY"],
},
{
"arches": PORTS_ARCHES,
"uri": PORTS_MIRRORS["SECURITY"],
},
]
DEFAULT = { DEFAULT = {
"preserve_sources_list": False, "preserve_sources_list": False,
} }
@ -312,6 +325,10 @@ class MirrorModel(object):
config = copy.deepcopy(self.config) config = copy.deepcopy(self.config)
config["disable_components"] = sorted(self.disabled_components) config["disable_components"] = sorted(self.disabled_components)
if "security" not in config:
config["security"] = DEFAULT_SECURITY_SECTION
return config return config
def _get_apt_config_using_candidate( def _get_apt_config_using_candidate(

View File

@ -18,6 +18,7 @@ import unittest
from unittest import mock from unittest import mock
from subiquity.models.mirror import ( from subiquity.models.mirror import (
DEFAULT_SECURITY_SECTION,
LEGACY_DEFAULT_PRIMARY_SECTION, LEGACY_DEFAULT_PRIMARY_SECTION,
LegacyPrimaryEntry, LegacyPrimaryEntry,
MirrorModel, MirrorModel,
@ -146,7 +147,7 @@ class TestMirrorModel(unittest.TestCase):
self.assertIn( self.assertIn(
country_mirror_candidate.uri, country_mirror_candidate.uri,
[ [
"http://CC.archive.ubuntu.com/ubuntu", "http://CC.archive.ubuntu.com/ubuntu/",
"http://CC.ports.ubuntu.com/ubuntu-ports", "http://CC.ports.ubuntu.com/ubuntu-ports",
], ],
) )
@ -313,6 +314,7 @@ class TestMirrorModel(unittest.TestCase):
set(config["disable_components"]), set(self.model.disabled_components) set(config["disable_components"]), set(self.model.disabled_components)
) )
self.assertEqual(set(config["disable_suites"]), {"security"}) self.assertEqual(set(config["disable_suites"]), {"security"})
self.assertEqual(config["security"], DEFAULT_SECURITY_SECTION)
def test_get_apt_config_staged_with_config(self): def test_get_apt_config_staged_with_config(self):
self.model.legacy_primary = False self.model.legacy_primary = False
@ -322,8 +324,12 @@ class TestMirrorModel(unittest.TestCase):
), ),
] ]
self.model.primary_candidates[0].stage() self.model.primary_candidates[0].stage()
security_config = [
{"arches": ["default"], "uri": "http://security.ubuntu.com/ubuntu"},
]
self.model.config = { self.model.config = {
"disable_suites": ["updates"], "disable_suites": ["updates"],
"security": security_config,
} }
config = self.model.get_apt_config_staged() config = self.model.get_apt_config_staged()
self.assertEqual( self.assertEqual(
@ -339,3 +345,27 @@ class TestMirrorModel(unittest.TestCase):
set(config["disable_components"]), set(self.model.disabled_components) set(config["disable_components"]), set(self.model.disabled_components)
) )
self.assertEqual(set(config["disable_suites"]), {"security", "updates"}) self.assertEqual(set(config["disable_suites"]), {"security", "updates"})
self.assertEqual(config["security"], security_config)
def test_get_apt_config_elected_default_config(self):
self.model.legacy_primary = False
self.model.primary_candidates = [
PrimaryEntry(
uri="http://mirror.local/ubuntu", arches=None, parent=self.model
),
]
self.model.primary_candidates[0].elect()
config = self.model.get_apt_config_elected()
self.assertEqual(
config["primary"],
[
{
"uri": "http://mirror.local/ubuntu",
"arches": ["default"],
}
],
)
self.assertEqual(
set(config["disable_components"]), set(self.model.disabled_components)
)
self.assertEqual(config["security"], DEFAULT_SECURITY_SECTION)