launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #27426
[Merge] ~cjwatson/launchpad:snap-base-build-channels-by-arch into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:snap-base-build-channels-by-arch into launchpad:master.
Commit message:
Allow SnapBase to specify per-architecture build channels
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/407094
This will allow us to keep core18/i386 builds pinned to a version of snapcraft built for core18 even when snapcraft in general moves on to core20 (which no longer supports i386).
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:snap-base-build-channels-by-arch into launchpad:master.
diff --git a/lib/lp/snappy/interfaces/snapbase.py b/lib/lp/snappy/interfaces/snapbase.py
index ea164ae..4b7a42b 100644
--- a/lib/lp/snappy/interfaces/snapbase.py
+++ b/lib/lp/snappy/interfaces/snapbase.py
@@ -154,7 +154,10 @@ class ISnapBaseEditableAttributes(Interface):
key_type=TextLine(), required=True, readonly=False,
description=_(
"A dictionary mapping snap names to channels to use when building "
- "snaps that specify this base.")))
+ "snaps that specify this base. The special '_byarch' key may "
+ "have a mapping of architecture names to mappings of snap names "
+ "to channels, which if present override the channels declared at "
+ "the top level when building for those architectures.")))
class ISnapBaseEdit(Interface):
diff --git a/lib/lp/snappy/model/snap.py b/lib/lp/snappy/model/snap.py
index cf51374..4eaa4ee 100644
--- a/lib/lp/snappy/model/snap.py
+++ b/lib/lp/snappy/model/snap.py
@@ -892,6 +892,7 @@ class Snap(Storm, WebhookTargetMixin):
snap_base, snap_base_name = self._findBase(snapcraft_data)
distro_series = self._pickDistroSeries(snap_base, snap_base_name)
channels = self._pickChannels(snap_base, channels=channels)
+ channels_by_arch = channels.pop("_byarch", {})
# Sort by Processor.id for determinism. This is chosen to be
# the same order as in BinaryPackageBuildSet.createForSource, to
@@ -915,10 +916,13 @@ class Snap(Storm, WebhookTargetMixin):
builds = []
for build_instance in architectures_to_build:
arch = build_instance.architecture
+ arch_channels = dict(channels)
+ if arch in channels_by_arch:
+ arch_channels.update(channels_by_arch[arch])
try:
build = self.requestBuild(
requester, archive, supported_arches[arch], pocket,
- snap_base=snap_base, channels=channels,
+ snap_base=snap_base, channels=arch_channels,
build_request=build_request)
if logger is not None:
logger.debug(
diff --git a/lib/lp/snappy/tests/test_snap.py b/lib/lp/snappy/tests/test_snap.py
index a946b58..4d9c92f 100644
--- a/lib/lp/snappy/tests/test_snap.py
+++ b/lib/lp/snappy/tests/test_snap.py
@@ -857,6 +857,60 @@ class TestSnap(TestCaseWithFactory):
snap_base, snap_base.build_channels,
distro_series=snap_base.distro_series)
+ def test_requestBuildsFromJob_snap_base_build_channels_by_arch(self):
+ # If the snap base declares different build channels for specific
+ # architectures, then requestBuildsFromJob uses those when requesting
+ # builds for those architectures.
+ self.useFixture(GitHostingFixture(blob="base: test-base\n"))
+ processors = [
+ self.factory.makeProcessor(supports_virtualized=True)
+ for _ in range(3)]
+ distroseries = self.factory.makeDistroSeries()
+ for processor in processors:
+ self.makeBuildableDistroArchSeries(
+ distroseries=distroseries, architecturetag=processor.name,
+ processor=processor)
+ with admin_logged_in():
+ snap_base = self.factory.makeSnapBase(
+ name="test-base", distro_series=distroseries,
+ build_channels={
+ "snapcraft": "stable/launchpad-buildd",
+ "_byarch": {
+ processors[0].name: {
+ "core": "candidate",
+ "snapcraft": "5.x/stable",
+ },
+ },
+ })
+ snap = self.factory.makeSnap(
+ distroseries=None, git_ref=self.factory.makeGitRefs()[0])
+ job = getUtility(ISnapRequestBuildsJobSource).create(
+ snap, snap.owner.teamowner, snap_base.distro_series.main_archive,
+ PackagePublishingPocket.RELEASE, None)
+ self.assertEqual(
+ get_transaction_timestamp(IStore(snap)), job.date_created)
+ transaction.commit()
+ with person_logged_in(job.requester):
+ builds = snap.requestBuildsFromJob(
+ job.requester, job.archive, job.pocket,
+ build_request=job.build_request)
+ self.assertThat(builds, MatchesSetwise(
+ *(MatchesStructure(
+ requester=Equals(job.requester),
+ snap=Equals(job.snap),
+ archive=Equals(job.archive),
+ distro_arch_series=Equals(
+ snap_base.distro_series[processor.name]),
+ pocket=Equals(job.pocket),
+ snap_base=Equals(snap_base),
+ channels=Equals(channels))
+ for processor, channels in (
+ (processors[0],
+ {"core": "candidate", "snapcraft": "5.x/stable"}),
+ (processors[1], {"snapcraft": "stable/launchpad-buildd"}),
+ (processors[2], {"snapcraft": "stable/launchpad-buildd"}),
+ ))))
+
def test_requestBuildsFromJob_unsupported_remote(self):
# If the snap is based on an external Git repository from which we
# don't support fetching blobs, requestBuildsFromJob falls back to