Merge ~cjwatson/launchpad:snap-base-build-channels-by-arch into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 9e675ca2d2d747839aca67a68b89a6f4390041b6
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:snap-base-build-channels-by-arch
Merge into: launchpad:master
Diff against target: 108 lines (+63/-2)
3 files modified
lib/lp/snappy/interfaces/snapbase.py (+4/-1)
lib/lp/snappy/model/snap.py (+5/-1)
lib/lp/snappy/tests/test_snap.py (+54/-0)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+407094@code.launchpad.net

Commit message

Allow SnapBase to specify per-architecture build channels

Description of the change

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).

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/snappy/interfaces/snapbase.py b/lib/lp/snappy/interfaces/snapbase.py
2index ea164ae..4b7a42b 100644
3--- a/lib/lp/snappy/interfaces/snapbase.py
4+++ b/lib/lp/snappy/interfaces/snapbase.py
5@@ -154,7 +154,10 @@ class ISnapBaseEditableAttributes(Interface):
6 key_type=TextLine(), required=True, readonly=False,
7 description=_(
8 "A dictionary mapping snap names to channels to use when building "
9- "snaps that specify this base.")))
10+ "snaps that specify this base. The special '_byarch' key may "
11+ "have a mapping of architecture names to mappings of snap names "
12+ "to channels, which if present override the channels declared at "
13+ "the top level when building for those architectures.")))
14
15
16 class ISnapBaseEdit(Interface):
17diff --git a/lib/lp/snappy/model/snap.py b/lib/lp/snappy/model/snap.py
18index cf51374..4eaa4ee 100644
19--- a/lib/lp/snappy/model/snap.py
20+++ b/lib/lp/snappy/model/snap.py
21@@ -892,6 +892,7 @@ class Snap(Storm, WebhookTargetMixin):
22 snap_base, snap_base_name = self._findBase(snapcraft_data)
23 distro_series = self._pickDistroSeries(snap_base, snap_base_name)
24 channels = self._pickChannels(snap_base, channels=channels)
25+ channels_by_arch = channels.pop("_byarch", {})
26
27 # Sort by Processor.id for determinism. This is chosen to be
28 # the same order as in BinaryPackageBuildSet.createForSource, to
29@@ -915,10 +916,13 @@ class Snap(Storm, WebhookTargetMixin):
30 builds = []
31 for build_instance in architectures_to_build:
32 arch = build_instance.architecture
33+ arch_channels = dict(channels)
34+ if arch in channels_by_arch:
35+ arch_channels.update(channels_by_arch[arch])
36 try:
37 build = self.requestBuild(
38 requester, archive, supported_arches[arch], pocket,
39- snap_base=snap_base, channels=channels,
40+ snap_base=snap_base, channels=arch_channels,
41 build_request=build_request)
42 if logger is not None:
43 logger.debug(
44diff --git a/lib/lp/snappy/tests/test_snap.py b/lib/lp/snappy/tests/test_snap.py
45index a946b58..4d9c92f 100644
46--- a/lib/lp/snappy/tests/test_snap.py
47+++ b/lib/lp/snappy/tests/test_snap.py
48@@ -857,6 +857,60 @@ class TestSnap(TestCaseWithFactory):
49 snap_base, snap_base.build_channels,
50 distro_series=snap_base.distro_series)
51
52+ def test_requestBuildsFromJob_snap_base_build_channels_by_arch(self):
53+ # If the snap base declares different build channels for specific
54+ # architectures, then requestBuildsFromJob uses those when requesting
55+ # builds for those architectures.
56+ self.useFixture(GitHostingFixture(blob="base: test-base\n"))
57+ processors = [
58+ self.factory.makeProcessor(supports_virtualized=True)
59+ for _ in range(3)]
60+ distroseries = self.factory.makeDistroSeries()
61+ for processor in processors:
62+ self.makeBuildableDistroArchSeries(
63+ distroseries=distroseries, architecturetag=processor.name,
64+ processor=processor)
65+ with admin_logged_in():
66+ snap_base = self.factory.makeSnapBase(
67+ name="test-base", distro_series=distroseries,
68+ build_channels={
69+ "snapcraft": "stable/launchpad-buildd",
70+ "_byarch": {
71+ processors[0].name: {
72+ "core": "candidate",
73+ "snapcraft": "5.x/stable",
74+ },
75+ },
76+ })
77+ snap = self.factory.makeSnap(
78+ distroseries=None, git_ref=self.factory.makeGitRefs()[0])
79+ job = getUtility(ISnapRequestBuildsJobSource).create(
80+ snap, snap.owner.teamowner, snap_base.distro_series.main_archive,
81+ PackagePublishingPocket.RELEASE, None)
82+ self.assertEqual(
83+ get_transaction_timestamp(IStore(snap)), job.date_created)
84+ transaction.commit()
85+ with person_logged_in(job.requester):
86+ builds = snap.requestBuildsFromJob(
87+ job.requester, job.archive, job.pocket,
88+ build_request=job.build_request)
89+ self.assertThat(builds, MatchesSetwise(
90+ *(MatchesStructure(
91+ requester=Equals(job.requester),
92+ snap=Equals(job.snap),
93+ archive=Equals(job.archive),
94+ distro_arch_series=Equals(
95+ snap_base.distro_series[processor.name]),
96+ pocket=Equals(job.pocket),
97+ snap_base=Equals(snap_base),
98+ channels=Equals(channels))
99+ for processor, channels in (
100+ (processors[0],
101+ {"core": "candidate", "snapcraft": "5.x/stable"}),
102+ (processors[1], {"snapcraft": "stable/launchpad-buildd"}),
103+ (processors[2], {"snapcraft": "stable/launchpad-buildd"}),
104+ ))))
105+
106 def test_requestBuildsFromJob_unsupported_remote(self):
107 # If the snap is based on an external Git repository from which we
108 # don't support fetching blobs, requestBuildsFromJob falls back to

Subscribers

People subscribed via source and target branches

to status/vote changes: