launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #19253
[Merge] lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad.
Commit message:
Recalculate BinaryPackageBuild.virtualized when enabling an archive.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/archive-enable-recalculate-virt/+merge/269371
Recalculate BinaryPackageBuild.virtualized when enabling an archive.
Similar to https://code.launchpad.net/~cjwatson/launchpad/bpb-recalculate-virt/+merge/269323, but this deals with the case of suspended builds in disabled archives. Unfortunately Storm's Update (and hence .set()) doesn't support FROM, so I had to write the SQL for the !Archive.require_virtualized case by hand and use store.invalidate.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad.
=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py 2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/archive.py 2015-08-27 14:19:30 +0000
@@ -2022,12 +2022,40 @@
AND BinaryPackageBuild.status = %s;
""", params=(status.value, self.id, BuildStatus.NEEDSBUILD.value))
+ def _recalculateBuildVirtualization(self):
+ """Update BinaryPackageBuild.virtualized for this archive."""
+ store = Store.of(self)
+ if self.require_virtualized:
+ # We can avoid the Processor join in this case.
+ builds = store.find(
+ BinaryPackageBuild,
+ BinaryPackageBuild.archive == self,
+ BinaryPackageBuild.status == BuildStatus.NEEDSBUILD)
+ builds.set(virtualized=True)
+ else:
+ store.execute("""
+ UPDATE BinaryPackageBuild
+ SET virtualized = NOT Processor.supports_nonvirtualized
+ FROM Processor
+ WHERE
+ -- insert self.id here
+ BinaryPackageBuild.archive = %s
+ AND BinaryPackageBuild.processor = Processor.id
+ -- Build is in state BuildStatus.NEEDSBUILD (0)
+ AND BinaryPackageBuild.status = %s;
+ """, params=(self.id, BuildStatus.NEEDSBUILD.value))
+ store.invalidate()
+
def enable(self):
"""See `IArchive`."""
assert self._enabled == False, "This archive is already enabled."
assert self.is_active, "Deleted archives can't be enabled."
self._enabled = True
self._setBuildQueueStatuses(BuildQueueStatus.WAITING)
+ # Suspended builds may have the wrong virtualization setting (due to
+ # changes to either Archive.require_virtualized or
+ # Processor.supports_nonvirtualized) and need to be updated.
+ self._recalculateBuildVirtualization()
def disable(self):
"""See `IArchive`."""
=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py 2015-05-19 02:37:36 +0000
+++ lib/lp/soyuz/tests/test_archive.py 2015-08-27 14:19:30 +0000
@@ -343,6 +343,71 @@
self.assertNoBuildQueuesHaveStatus(archive, BuildQueueStatus.SUSPENDED)
self.assertTrue(archive.enabled)
+ def test_enableArchive_virt_sets_virtualized(self):
+ # Enabling an archive that requires virtualized builds changes all
+ # its pending builds to be virtualized.
+ archive = self.factory.makeArchive(virtualized=False)
+ other_archive = self.factory.makeArchive(virtualized=False)
+ pending_builds = [
+ self.factory.makeBinaryPackageBuild(
+ archive=archive, status=BuildStatus.NEEDSBUILD)
+ for _ in range(2)]
+ completed_build = self.factory.makeBinaryPackageBuild(
+ archive=archive, status=BuildStatus.FULLYBUILT)
+ other_build = self.factory.makeBinaryPackageBuild(
+ archive=other_archive, status=BuildStatus.NEEDSBUILD)
+ for build in pending_builds + [completed_build, other_build]:
+ self.assertFalse(build.virtualized)
+ build.queueBuild()
+ removeSecurityProxy(archive).disable()
+ removeSecurityProxy(archive).require_virtualized = True
+ removeSecurityProxy(archive).enable()
+ # Pending builds in the just-enabled archive are now virtualized.
+ for build in pending_builds:
+ self.assertTrue(build.virtualized)
+ # Completed builds and builds in other archives are untouched.
+ for build in completed_build, other_build:
+ self.assertFalse(build.virtualized)
+
+ def test_enableArchive_nonvirt_sets_virtualized(self):
+ # Enabling an archive that does not require virtualized builds
+ # changes its pending builds to be virtualized or not depending on
+ # whether their processor supports non-virtualized builds.
+ distroseries = self.factory.makeDistroSeries()
+ archive = self.factory.makeArchive(
+ distribution=distroseries.distribution, virtualized=False)
+ other_archive = self.factory.makeArchive(
+ distribution=distroseries.distribution, virtualized=False)
+ procs = [self.factory.makeProcessor() for _ in range(2)]
+ dases = [
+ self.factory.makeDistroArchSeries(
+ distroseries=distroseries, processor=procs[i])
+ for i in range(2)]
+ pending_builds = [
+ self.factory.makeBinaryPackageBuild(
+ distroarchseries=dases[i], archive=archive,
+ status=BuildStatus.NEEDSBUILD, processor=procs[i])
+ for i in range(2)]
+ completed_build = self.factory.makeBinaryPackageBuild(
+ distroarchseries=dases[0], archive=archive,
+ status=BuildStatus.FULLYBUILT, processor=procs[0])
+ other_build = self.factory.makeBinaryPackageBuild(
+ distroarchseries=dases[0], archive=other_archive,
+ status=BuildStatus.NEEDSBUILD, processor=procs[0])
+ for build in pending_builds + [completed_build, other_build]:
+ self.assertFalse(build.virtualized)
+ build.queueBuild()
+ removeSecurityProxy(archive).disable()
+ procs[0].supports_nonvirtualized = False
+ removeSecurityProxy(archive).enable()
+ # Pending builds in the just-enabled archive are now virtualized iff
+ # their processor does not support non-virtualized builds.
+ self.assertTrue(pending_builds[0].virtualized)
+ self.assertFalse(pending_builds[1].virtualized)
+ # Completed builds and builds in other archives are untouched.
+ for build in completed_build, other_build:
+ self.assertFalse(build.virtualized)
+
def test_enableArchiveAlreadyEnabled(self):
# Enabling an already enabled Archive should raise an AssertionError.
archive = self.factory.makeArchive(enabled=True)
Follow ups