← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~variants-wg/launchpad:publish-variant-build into launchpad:master

 

Tushar Gupta has proposed merging ~variants-wg/launchpad:publish-variant-build into launchpad:master.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~variants-wg/launchpad/+git/launchpad/+merge/488250
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~variants-wg/launchpad:publish-variant-build into launchpad:master.
diff --git a/lib/lp/archivepublisher/indices.py b/lib/lp/archivepublisher/indices.py
index 05fa6ec..c425677 100644
--- a/lib/lp/archivepublisher/indices.py
+++ b/lib/lp/archivepublisher/indices.py
@@ -185,7 +185,11 @@ def build_binary_stanza_fields(
     # Present 'all' in every archive index for architecture
     # independent binaries.
     if bpr.architecturespecific:
+        # This needs to be the "underlying" architecture when we do
+        # this for real.
         architecture = bpr.build.distro_arch_series.architecturetag
+        if architecture == "testing":
+            architecture = "amd64"
     else:
         architecture = "all"
 
diff --git a/lib/lp/archivepublisher/publishing.py b/lib/lp/archivepublisher/publishing.py
index f84d9e2..95072c1 100644
--- a/lib/lp/archivepublisher/publishing.py
+++ b/lib/lp/archivepublisher/publishing.py
@@ -163,7 +163,12 @@ def get_sources_path(config, suite_name, component):
 def get_packages_path(config, suite_name, component, arch, subcomp=None):
     """Return path to Packages file for the given arguments."""
     component_root = os.path.join(config.distsroot, suite_name, component.name)
-    arch_path = "binary-%s" % arch.architecturetag
+    arch_tag = arch.architecturetag
+    if arch_tag == "testing":
+        # This is just a discretion hack.
+        arch_tag = "amd64v3"
+
+    arch_path = "binary-%s" % arch_tag
     if subcomp is None:
         return os.path.join(component_root, arch_path, "Packages")
     else:
@@ -1131,7 +1136,12 @@ class Publisher:
             if not arch.enabled:
                 continue
 
-            arch_path = "binary-%s" % arch.architecturetag
+            arch_tag = arch.architecturetag
+            if arch_tag == "testing":
+                # This is just a discretion hack.
+                arch_tag = "amd64v3"
+
+            arch_path = "binary-%s" % arch_tag
 
             self.log.debug("Generating Packages for %s" % arch_path)
 
@@ -1480,6 +1490,10 @@ class Publisher:
         for component in all_components:
             self._writeSuiteSource(distroseries, pocket, component, core_files)
             for architecture in all_architectures:
+                if architecture == "testing":
+                    # This is just a discretion hack.
+                    architecture = "amd64v3"
+
                 self._writeSuiteArch(
                     distroseries, pocket, component, architecture, core_files
                 )
@@ -1552,7 +1566,11 @@ class Publisher:
         release_file["Date"] = datetime.utcnow().strftime(
             "%a, %d %b %Y %k:%M:%S UTC"
         )
-        release_file["Architectures"] = " ".join(sorted(all_architectures))
+        arches = list(all_architectures)
+        if "testing" in arches:
+            # This needs to exclude variants when doing this for real.
+            arches.remove("testing")
+        release_file["Architectures"] = " ".join(sorted(arches))
         release_file["Components"] = " ".join(
             reorder_components(all_components)
         )
diff --git a/lib/lp/archiveuploader/buildinfofile.py b/lib/lp/archiveuploader/buildinfofile.py
index bd8851d..77ae975 100644
--- a/lib/lp/archiveuploader/buildinfofile.py
+++ b/lib/lp/archiveuploader/buildinfofile.py
@@ -81,9 +81,17 @@ class BuildInfoFile(PackageUploadFile, SignableTagFile):
 
     def checkBuild(self, build):
         """See `PackageUploadFile`."""
+        das = None
         try:
             das = self.policy.distroseries[self.architecture]
         except NotFoundError:
+            if self.architecture == "amd64v3":
+                try:
+                    das = self.policy.distroseries["testing"]
+                except NotFoundError:
+                    pass
+
+        if das is None:
             raise UploadError(
                 "Upload to unknown architecture %s for distroseries %s"
                 % (self.architecture, self.policy.distroseries)
diff --git a/lib/lp/archiveuploader/nascentuploadfile.py b/lib/lp/archiveuploader/nascentuploadfile.py
index 01b2243..dbca743 100644
--- a/lib/lp/archiveuploader/nascentuploadfile.py
+++ b/lib/lp/archiveuploader/nascentuploadfile.py
@@ -739,6 +739,9 @@ class BaseBinaryUploadFile(PackageUploadFile):
         Also check if it is a valid architecture in LP context.
         """
         control_arch = six.ensure_text(self.control.get("Architecture", b""))
+        control_arch_variant = six.ensure_text(
+            self.control.get("Architecture-Variant", control_arch)
+        )
         valid_archs = [
             a.architecturetag for a in self.policy.distroseries.architectures
         ]
@@ -755,7 +758,7 @@ class BaseBinaryUploadFile(PackageUploadFile):
                 "in the changes file." % (self.filename, control_arch)
             )
 
-        if control_arch != self.architecture:
+        if control_arch_variant != self.architecture:
             yield UploadError(
                 "%s: control file lists arch as '%s' which doesn't "
                 "agree with version '%s' in the filename."
@@ -975,7 +978,14 @@ class BaseBinaryUploadFile(PackageUploadFile):
         - Create a new build in FULLYBUILT status.
 
         """
-        dar = self.policy.distroseries[self.archtag]
+        dar = None
+        try:
+            dar = self.policy.distroseries[self.archtag]
+        except NotFoundError:
+            if self.archtag == "amd64v3":
+                dar = self.policy.distroseries["testing"]
+            else:
+                raise
 
         # Check if there's a suitable existing build.
         build = getUtility(IBinaryPackageBuildSet).getBySourceAndLocation(
@@ -1001,9 +1011,17 @@ class BaseBinaryUploadFile(PackageUploadFile):
 
     def checkBuild(self, build):
         """See PackageUploadFile."""
+        dar = None
         try:
             dar = self.policy.distroseries[self.archtag]
         except NotFoundError:
+            if self.archtag == "amd64v3":
+                try:
+                    dar = self.policy.distroseries["testing"]
+                except NotFoundError:
+                    pass
+
+        if dar is None:
             raise UploadError(
                 "Upload to unknown architecture %s for distroseries %s"
                 % (self.archtag, self.policy.distroseries)
diff --git a/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.changes b/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.changes
new file mode 100644
index 0000000..d79faea
--- /dev/null
+++ b/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.changes
@@ -0,0 +1,30 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.7
+Date: Thu, 30 Mar 2006 01:36:14 +0100
+Source: bar
+Binary: bar
+Architecture: amd64
+Architecture-Variant: amd64v3
+Version: 1.0-1
+Distribution: breezy
+Urgency: low
+Maintainer: Launchpad team <launchpad@xxxxxxxxxxxxxxxxxxx>
+Changed-By: Daniel Silverstone <daniel.silverstone@xxxxxxxxxxxxx>
+Description: 
+ bar        - Stuff for testing
+Changes: 
+ bar (1.0-1) breezy; urgency=low
+ .
+   * A variant build
+Files: 
+ 224a95bb17616a86e02e8e3850851e2b 608 devel optional bar_1.0-1_amd64v3.deb
+
+-----BEGIN PGP SIGNATURE-----
+
+iHQEARECADQWIQQ0DKO7Jw4nFsnuC3aOfrcIbGSoxQUCZ+sQ1RYcZm9vLmJhckBj
+YW5vbmljYWwuY29tAAoJEI5+twhsZKjFBcYAn3k5zbIOi1RyUmJhkh+MjpGENuy9
+AJ9XgbjkMHQ7O0vhTife7rhYKOq1fg==
+=68pf
+-----END PGP SIGNATURE-----
diff --git a/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.deb b/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.deb
new file mode 100644
index 0000000..1c55544
Binary files /dev/null and b/lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_variant/bar_1.0-1_amd64v3.deb differ
diff --git a/lib/lp/archiveuploader/tests/test_nascentuploadfile.py b/lib/lp/archiveuploader/tests/test_nascentuploadfile.py
index 0de2157..fd86c57 100644
--- a/lib/lp/archiveuploader/tests/test_nascentuploadfile.py
+++ b/lib/lp/archiveuploader/tests/test_nascentuploadfile.py
@@ -874,6 +874,34 @@ class DebBinaryUploadFileTests(PackageUploadFileTestCase):
         self.assertEqual(BuildStatus.FULLYBUILT, build.status)
         self.assertIs(None, build.upload_log)
 
+    def test_checkBuild_variant(self):
+        # checkBuild() verifies consistency with a build.
+        das = self.factory.makeDistroArchSeries(
+            distroseries=self.policy.distroseries, architecturetag="i386"
+        )
+        build = self.factory.makeBinaryPackageBuild(
+            distroarchseries=das, archive=self.policy.archive
+        )
+        control = self.getBaseControl()
+        control["Architecture"] = b"amd64"
+        control["Architecture-Variant"] = b"amd64v3"
+        uploadfile = self.createDebBinaryUploadFile(
+            "foo_0.42_amd64v3.deb",
+            "main/python",
+            "unknown",
+            "mypkg",
+            "0.42",
+            None,
+            control=control,
+            data_format="gz",
+            control_format="gz",
+        )
+        uploadfile.checkBuild(build)
+        # checkBuild() sets the build status to FULLYBUILT and
+        # removes the upload log.
+        self.assertEqual(BuildStatus.FULLYBUILT, build.status)
+        self.assertIs(None, build.upload_log)
+
     def test_checkBuild_inconsistent(self):
         # checkBuild() raises UploadError if inconsistencies between build
         # and upload file are found.
diff --git a/lib/lp/archiveuploader/tests/test_uploadprocessor.py b/lib/lp/archiveuploader/tests/test_uploadprocessor.py
index 95c1b8b..72520d9 100644
--- a/lib/lp/archiveuploader/tests/test_uploadprocessor.py
+++ b/lib/lp/archiveuploader/tests/test_uploadprocessor.py
@@ -302,6 +302,12 @@ class TestUploadProcessorBase(TestCaseWithFactory):
 
         self.switchToUploader()
 
+    def addDAS(self, distro_series, tag):
+        das = self.factory.makeBuildableDistroArchSeries(
+            distroseries=distro_series, architecturetag=tag
+        )
+        return das
+
     def addMockFile(self, filename, content=b"anything"):
         """Return a librarian file."""
         return getUtility(ILibraryFileAliasSet).create(
@@ -2893,6 +2899,61 @@ class TestUploadHandler(TestUploadProcessorBase):
         # Upon full build the upload log is unset.
         self.assertIs(None, build.upload_log)
 
+    def testBinaryPackageBuilds_variant(self):
+        # Properly uploaded binaries should result in the
+        # build status changing to FULLYBUILT.
+        # Upload a source package
+        self.switchToAdmin()
+        self.addDAS(self.breezy, "amd64")
+        das_amd64v3 = self.addDAS(self.breezy, "testing")
+        archive = self.breezy.distribution.main_archive
+        procs = list(archive.processors)
+        procs.append(das_amd64v3.processor)
+        removeSecurityProxy(archive).processors = procs
+
+        self.switchToUploader()
+        upload_dir = self.queueUpload("bar_1.0-1")
+        self.processUpload(self.uploadprocessor, upload_dir)
+        source_pub = self.publishPackage("bar", "1.0-1")
+        builds = source_pub.createMissingBuilds()
+        for b in builds:
+            if b.distro_arch_series.architecturetag == "testing":
+                build = b
+
+        # Move the source from the accepted queue.
+        self.switchToAdmin()
+        [queue_item] = self.breezy.getPackageUploads(
+            status=PackageUploadStatus.ACCEPTED, version="1.0-1", name="bar"
+        )
+        queue_item.setDone()
+
+        build.buildqueue_record.markAsBuilding(self.factory.makeBuilder())
+        build.updateStatus(BuildStatus.UPLOADING)
+        self.switchToUploader()
+
+        # Upload and accept a binary for the primary archive source.
+        shutil.rmtree(upload_dir)
+
+        # Commit so the build cookie has the right ids.
+        self.layer.txn.commit()
+        behaviour = IBuildFarmJobBehaviour(build)
+        leaf_name = behaviour.getUploadDirLeaf(build.build_cookie)
+        upload_dir = self.queueUpload(
+            "bar_1.0-1_variant", queue_entry=leaf_name
+        )
+        self.options.context = "buildd"
+        self.options.builds = True
+        pop_notifications()
+        BuildUploadHandler(
+            self.uploadprocessor, self.incoming_folder, leaf_name
+        ).process()
+        self.layer.txn.commit()
+        # No emails are sent on success
+        self.assertEmailQueueLength(0)
+        self.assertEqual(BuildStatus.FULLYBUILT, build.status)
+        # Upon full build the upload log is unset.
+        self.assertIs(None, build.upload_log)
+
     def doSuccessRecipeBuild(self):
         # Upload a source package
         self.switchToAdmin()