Simone Pelosi has proposed merging 
~pelpsi/launchpad:unembargo-bug-build-info-missing into launchpad:master.

Commit message:
Unembargo build info
    
Added buildinfo to unembargoed files.
Added custom upload files to unembargoed files.
Added a new endpoint buildMetadataFileUrls to retrieve
changes file, build_info and log without accessing directly the build.
    
LP: #2052796


Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #2052796 in Launchpad itself: "MIssing buildinfo file for Jammy 
grub2-unsigned 2.06-2ubuntu14.4"
  https://bugs.launchpad.net/launchpad/+bug/2052796

For more details, see:
https://code.launchpad.net/~pelpsi/launchpad/+git/launchpad/+merge/464705
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of 
~pelpsi/launchpad:unembargo-bug-build-info-missing into launchpad:master.
diff --git a/lib/lp/soyuz/browser/tests/test_publishing_webservice.py b/lib/lp/soyuz/browser/tests/test_publishing_webservice.py
index 2aee350..b167e61 100644
--- a/lib/lp/soyuz/browser/tests/test_publishing_webservice.py
+++ b/lib/lp/soyuz/browser/tests/test_publishing_webservice.py
@@ -15,9 +15,14 @@ from lp.services.librarian.browser import ProxiedLibraryFileAlias
 from lp.services.webapp.interfaces import OAuthPermission
 from lp.soyuz.adapters.proxiedsourcefiles import ProxiedSourceLibraryFileAlias
 from lp.soyuz.enums import BinaryPackageFormat
-from lp.soyuz.interfaces.publishing import IPublishingSet
+from lp.soyuz.interfaces.publishing import (
+    IPublishingSet,
+    PackagePublishingStatus,
+)
+from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
 from lp.testing import (
     TestCaseWithFactory,
+    admin_logged_in,
     api_url,
     login_person,
     person_logged_in,
@@ -167,14 +172,47 @@ class SourcePackagePublishingHistoryWebserviceTests(TestCaseWithFactory):
 class BinaryPackagePublishingHistoryWebserviceTests(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
+    def setUp(self):
+        super().setUp()
+        self.processor = self.factory.makeProcessor(supports_virtualized=True)
+        self.distroseries = self.factory.makeDistroSeries()
+        self.das = self.factory.makeDistroArchSeries(
+            distroseries=self.distroseries, processor=self.processor
+        )
+        with admin_logged_in():
+            self.publisher = SoyuzTestPublisher()
+            self.publisher.prepareBreezyAutotest()
+            self.distroseries.nominatedarchindep = self.das
+            self.publisher.addFakeChroots(distroseries=self.distroseries)
+            self.builder = self.factory.makeBuilder(
+                processors=[self.processor]
+            )
+
     def make_bpph_for(self, person):
+        spn = self.factory.getUniqueString()
+        version = "%s.1" % self.factory.getUniqueInteger()
         with person_logged_in(person):
-            bpr = self.factory.makeBinaryPackageRelease()
-            self.factory.makeBinaryPackageFile(binarypackagerelease=bpr)
-            bpph = self.factory.makeBinaryPackagePublishingHistory(
-                binarypackagerelease=bpr
+            spph = self.publisher.getPubSource(
+                sourcename=spn,
+                version=version,
+                distroseries=self.distroseries,
+                status=PackagePublishingStatus.PUBLISHED,
+            )
+        with admin_logged_in():
+            binary = self.publisher.getPubBinaries(
+                binaryname=spn,
+                distroseries=self.distroseries,
+                pub_source=spph,
+                version=version,
+                builder=self.builder,
+            )
+            binary[0].build.addBuildInfo(
+                self.factory.makeLibraryFileAlias(
+                    filename="build_info.info", restricted=True
+                )
             )
-            return bpph, api_url(bpph)
+
+        return binary[0], api_url(binary[0])
 
     def test_binaryFileUrls(self):
         person = self.factory.makePerson()
@@ -239,6 +277,71 @@ class BinaryPackagePublishingHistoryWebserviceTests(TestCaseWithFactory):
             ]
         self.assertContentEqual(expected_info, info)
 
+    def test_buildMetadataFileUrls(self):
+        person = self.factory.makePerson()
+        webservice = webservice_for_person(
+            person, permission=OAuthPermission.READ_PUBLIC
+        )
+        bpph, url = self.make_bpph_for(person)
+
+        response = webservice.named_get(
+            url, "buildMetadataFileUrls", api_version="devel"
+        )
+
+        self.assertEqual(200, response.status)
+        urls = response.jsonBody()
+
+        with person_logged_in(person):
+            upload_changesfile = (
+                bpph.binarypackagerelease.build.upload_changesfile
+            )
+            log = bpph.binarypackagerelease.build.log
+            build_info = bpph.binarypackagerelease.build.buildinfo
+
+            expected_urls = [
+                ProxiedLibraryFileAlias(
+                    upload_changesfile, bpph.archive
+                ).http_url,
+                ProxiedLibraryFileAlias(log, bpph.archive).http_url,
+                ProxiedLibraryFileAlias(build_info, bpph.archive).http_url,
+            ]
+        self.assertEqual(expected_urls, urls)
+
+    def test_buildMetadataFileUrls_include_meta(self):
+        person = self.factory.makePerson()
+        webservice = webservice_for_person(
+            person, permission=OAuthPermission.READ_PUBLIC
+        )
+        bpph, url = self.make_bpph_for(person)
+
+        response = webservice.named_get(
+            url,
+            "buildMetadataFileUrls",
+            include_meta=True,
+            api_version="devel",
+        )
+
+        self.assertEqual(200, response.status)
+        info = response.jsonBody()
+        with person_logged_in(person):
+            files = []
+            files.append(bpph.binarypackagerelease.build.upload_changesfile)
+            files.append(bpph.binarypackagerelease.build.log)
+            files.append(bpph.binarypackagerelease.build.buildinfo)
+
+            expected_info = [
+                {
+                    "url": ProxiedLibraryFileAlias(
+                        file, bpph.archive
+                    ).http_url,
+                    "size": file.content.filesize,
+                    "sha1": file.content.sha1,
+                    "sha256": file.content.sha256,
+                }
+                for file in files
+            ]
+        self.assertEqual(expected_info, info)
+
     def test_ci_build(self):
         person = self.factory.makePerson()
         webservice = webservice_for_person(
diff --git a/lib/lp/soyuz/interfaces/publishing.py b/lib/lp/soyuz/interfaces/publishing.py
index a481aa3..c426ec7 100644
--- a/lib/lp/soyuz/interfaces/publishing.py
+++ b/lib/lp/soyuz/interfaces/publishing.py
@@ -1041,6 +1041,20 @@ class IBinaryPackagePublishingHistoryPublic(IPublishingView):
         :return: A collection of URLs for this binary.
         """
 
+    @export_read_operation()
+    @operation_parameters(
+        include_meta=Bool(title=_("Include Metadata"), required=False)
+    )
+    @operation_for_version("devel")
+    def buildMetadataFileUrls(include_meta=False):
+        """URLs for this build metadata files.
+        The result includes changes file, build_info and log.
+
+        :param include_meta: Return a list of dicts with keys url, size,
+            sha1, and sha256 for each URL instead of a simple list.
+        :return: A collection of URLs for these metadata files.
+        """
+
 
 class IBinaryPackagePublishingHistoryEdit(IPublishingEdit):
     """A writeable binary package publishing record."""
diff --git a/lib/lp/soyuz/model/packagecopyjob.py b/lib/lp/soyuz/model/packagecopyjob.py
index 2776af2..d30f3af 100644
--- a/lib/lp/soyuz/model/packagecopyjob.py
+++ b/lib/lp/soyuz/model/packagecopyjob.py
@@ -62,7 +62,7 @@ from lp.soyuz.interfaces.packagecopyjob import (
 )
 from lp.soyuz.interfaces.packagediff import PackageDiffAlreadyRequested
 from lp.soyuz.interfaces.publishing import ISourcePackagePublishingHistory
-from lp.soyuz.interfaces.queue import IPackageUploadSet
+from lp.soyuz.interfaces.queue import IPackageUploadCustom, IPackageUploadSet
 from lp.soyuz.interfaces.section import ISectionSet
 from lp.soyuz.model.archive import Archive
 from lp.soyuz.scripts.packagecopier import do_copy
@@ -854,7 +854,10 @@ class PlainPackageCopyJob(PackageCopyJobDerived):
                 "Packages copied to %s:" % self.target_archive.displayname
             )
             for copy in copied_publications:
-                self.logger.debug(copy.displayname)
+                if IPackageUploadCustom.providedBy(copy):
+                    self.logger.debug(copy.libraryfilealias.filename)
+                else:
+                    self.logger.debug(copy.displayname)
 
     def abort(self):
         """Abort work."""
diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py
index 78749c0..44543e0 100644
--- a/lib/lp/soyuz/model/publishing.py
+++ b/lib/lp/soyuz/model/publishing.py
@@ -1384,6 +1384,27 @@ class BinaryPackagePublishingHistory(StormBase, ArchivePublisherBase):
             ]
         return binary_urls
 
+    def buildMetadataFileUrls(self, include_meta=False):
+        """See `IBinaryPackagePublishingHistory`."""
+        files = []
+        if self.build.upload_changesfile:
+            files.append(self.build.upload_changesfile)
+        if self.build.log:
+            files.append(self.build.log)
+        if self.build.buildinfo:
+            files.append(self.build.buildinfo)
+        file_urls = proxied_urls([file for file in files], self.archive)
+        if include_meta:
+            meta = [
+                (file.content.filesize, file.content.sha1, file.content.sha256)
+                for file in files
+            ]
+            return [
+                dict(url=url, size=size, sha1=sha1, sha256=sha256)
+                for url, (size, sha1, sha256) in zip(file_urls, meta)
+            ]
+        return file_urls
+
 
 def expand_binary_requests(distroseries, binaries):
     """Architecture-expand a dict of binary publication requests.
diff --git a/lib/lp/soyuz/model/queue.py b/lib/lp/soyuz/model/queue.py
index 7c7fda2..ac633e1 100644
--- a/lib/lp/soyuz/model/queue.py
+++ b/lib/lp/soyuz/model/queue.py
@@ -635,10 +635,13 @@ class PackageUpload(StormBase):
         # XXX: Only tests are not passing user here. We should adjust the
         # tests and always create the log entries after
         if user is not None:
+            print("HERE")
             self._addLog(user, PackageUploadStatus.ACCEPTED, None)
         if self.package_copy_job is None:
+            print("HERE1")
             self._acceptNonSyncFromQueue()
         else:
+            print("HERE2")
             self._acceptSyncFromQueue()
 
     def rejectFromQueue(self, user, comment=None):
diff --git a/lib/lp/soyuz/scripts/packagecopier.py b/lib/lp/soyuz/scripts/packagecopier.py
index f377107..cd3c624 100644
--- a/lib/lp/soyuz/scripts/packagecopier.py
+++ b/lib/lp/soyuz/scripts/packagecopier.py
@@ -73,6 +73,8 @@ def update_files_privacy(pub_record):
         package_files.append((sourcepackagerelease, "changelog"))
     elif IBinaryPackagePublishingHistory.providedBy(pub_record):
         archive = pub_record.archive
+        print("IS PRIVATE?")
+        print(pub_record.archive.private)
         # Unrestrict the binary files if necessary.
         binarypackagerelease = pub_record.binarypackagerelease
         package_files.extend(
@@ -87,6 +89,8 @@ def update_files_privacy(pub_record):
         package_files.append((package_upload, "changesfile"))
         # Unrestrict the buildlog file as necessary.
         package_files.append((build, "log"))
+        # Unrestrict the buildinfo file as necessary.
+        package_files.append((build, "buildinfo"))
     elif IPackageUploadCustom.providedBy(pub_record):
         # Unrestrict the custom files included
         package_files.append((pub_record, "libraryfilealias"))
@@ -911,7 +915,7 @@ def _do_direct_copy(
         )
         for custom in custom_files:
             if custom_copier.isCopyable(custom):
-                custom_copier.copyUpload(custom)
+                copies.append(custom_copier.copyUpload(custom))
 
     # Always ensure the needed builds exist in the copy destination
     # after copying the binaries.
diff --git a/lib/lp/soyuz/tests/test_packagecopyjob.py b/lib/lp/soyuz/tests/test_packagecopyjob.py
index 26fdd08..be893fb 100644
--- a/lib/lp/soyuz/tests/test_packagecopyjob.py
+++ b/lib/lp/soyuz/tests/test_packagecopyjob.py
@@ -31,6 +31,7 @@ from lp.services.features.testing import FeatureFixture
 from lp.services.job.interfaces.job import JobStatus
 from lp.services.job.runner import JobRunner
 from lp.services.job.tests import block_on_job, pop_remote_notifications
+from lp.services.macaroons.testing import MacaroonTestMixin
 from lp.services.mail.sendmail import format_address_for_person
 from lp.soyuz.adapters.overrides import SourceOverride
 from lp.soyuz.enums import (
@@ -195,7 +196,9 @@ class LocalTestHelper:
         JobRunner([job]).runAll()
 
 
-class PlainPackageCopyJobTests(TestCaseWithFactory, LocalTestHelper):
+class PlainPackageCopyJobTests(
+    TestCaseWithFactory, LocalTestHelper, MacaroonTestMixin
+):
     """Test case for PlainPackageCopyJob."""
 
     layer = LaunchpadZopelessLayer
@@ -1733,6 +1736,114 @@ class PlainPackageCopyJobTests(TestCaseWithFactory, LocalTestHelper):
         self.assertEqual(BugTaskStatus.FIXRELEASED, bugtask.status)
         self.assertEqual(1, webhook.deliveries.count())
 
+    def test_copying_unembargoes_build_files(self):
+        # Inaccessible private builds aren't linked in builders'
+        # current_build fields.
+        # Copyable custom upload files are queued for republication when
+        # they are copied.
+        # Custom upload files should be unembargoed as well.
+
+        owner = self.factory.makePerson()
+
+        source_archive = self.factory.makeArchive(
+            name="sourcearchive",
+            owner=owner,
+            distribution=self.distroseries.distribution,
+            private=True,
+        )
+        target_archive = self.factory.makeArchive(
+            name="targetarchive",
+            owner=owner,
+            distribution=self.distroseries.distribution,
+            purpose=ArchivePurpose.PRIMARY,
+        )
+
+        self.distroseries.status = SeriesStatus.CURRENT
+        spph = self.publisher.getPubSource(
+            pocket=PackagePublishingPocket.SECURITY, archive=source_archive
+        )
+        self.publisher.getPubBinaries(
+            pocket=PackagePublishingPocket.SECURITY,
+            pub_source=spph,
+            archive=source_archive,
+        )
+        [build] = spph.getBuilds()
+        build.addBuildInfo(
+            self.factory.makeLibraryFileAlias(
+                filename="build_info.info", restricted=True
+            )
+        )
+        build.package_upload.addCustom(
+            self.factory.makeLibraryFileAlias(
+                filename="test.deb", restricted=True
+            ),
+            PackageUploadCustomFormat.DEBIAN_INSTALLER,
+        )
+        # Make the new librarian file available.
+        self.layer.txn.commit()
+        # Create the copy job.
+        with person_logged_in(owner):
+            target_archive.newPocketUploader(
+                owner, PackagePublishingPocket.SECURITY
+            )
+        job = self.createCopyJobForSPPH(
+            spph,
+            source_archive,
+            target_archive,
+            requester=owner,
+            target_pocket=PackagePublishingPocket.SECURITY,
+            include_binaries=True,
+            unembargo=True,
+        )
+
+        # Start, accept, and run the job.
+        self.runJob(job)
+        self.assertEqual(JobStatus.SUSPENDED, job.status)
+        switch_dbuser("launchpad_main")
+        pu = (
+            getUtility(IPackageUploadSet)
+            .getByPackageCopyJobIDs([removeSecurityProxy(job).context.id])
+            .one()
+        )
+        pu.acceptFromQueue()
+        self.assertEqual(PackageUploadStatus.ACCEPTED, pu.status)
+        self.runJob(job)
+        self.assertEqual(PackageUploadStatus.DONE, pu.status)
+
+        uploads = list(
+            self.distroseries.getPackageUploads(
+                status=PackageUploadStatus.ACCEPTED,
+                archive=target_archive,
+                pocket=PackagePublishingPocket.SECURITY,
+            )
+        )
+
+        self.assertEqual(1, len(uploads))
+        upload = uploads[0]
+        self.assertEqual(
+            PackageUploadCustomFormat.DEBIAN_INSTALLER,
+            upload.customfiles[0].customformat,
+        )
+        # The upload is targeted to the right publishing context.
+        self.assertEqual(target_archive, upload.archive)
+        self.assertEqual(self.distroseries, upload.distroseries)
+        self.assertEqual(PackagePublishingPocket.SECURITY, upload.pocket)
+
+        self.assertEqual(
+            "test.deb", upload.customfiles[0].libraryfilealias.filename
+        )
+        self.assertEqual(
+            False, upload.customfiles[0].libraryfilealias.restricted
+        )
+        copied_binaries = target_archive.getAllPublishedBinaries()
+        for copied_binary in copied_binaries:
+            for binary_file in copied_binary.binarypackagerelease.files:
+                self.assertFalse(binary_file.libraryfile.restricted)
+            copied_build = copied_binary.binarypackagerelease.build
+            self.assertFalse(copied_build.log.restricted)
+            self.assertFalse(copied_build.buildinfo.restricted)
+            self.assertFalse(copied_build.upload_changesfile.restricted)
+
     def test_copying_unembargoes_files(self):
         # The unembargo flag causes the job to unrestrict files.
         self.distroseries.status = SeriesStatus.CURRENT
diff --git a/lib/lp/soyuz/tests/test_publishing_models.py b/lib/lp/soyuz/tests/test_publishing_models.py
index 755d797..e529d52 100644
--- a/lib/lp/soyuz/tests/test_publishing_models.py
+++ b/lib/lp/soyuz/tests/test_publishing_models.py
@@ -21,7 +21,8 @@ from lp.soyuz.interfaces.publishing import (
     PackagePublishingStatus,
 )
 from lp.soyuz.tests.test_binarypackagebuild import BaseTestCaseWithThreeBuilds
-from lp.testing import TestCaseWithFactory, person_logged_in
+from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
+from lp.testing import TestCaseWithFactory, admin_logged_in, person_logged_in
 from lp.testing.layers import LaunchpadFunctionalLayer, LaunchpadZopelessLayer
 
 
@@ -242,6 +243,22 @@ class TestSourcePackagePublishingHistory(TestCaseWithFactory):
 class TestBinaryPackagePublishingHistory(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
+    def setUp(self):
+        super().setUp()
+        self.processor = self.factory.makeProcessor(supports_virtualized=True)
+        self.distroseries = self.factory.makeDistroSeries()
+        self.das = self.factory.makeDistroArchSeries(
+            distroseries=self.distroseries, processor=self.processor
+        )
+        with admin_logged_in():
+            self.publisher = SoyuzTestPublisher()
+            self.publisher.prepareBreezyAutotest()
+            self.distroseries.nominatedarchindep = self.das
+            self.publisher.addFakeChroots(distroseries=self.distroseries)
+            self.builder = self.factory.makeBuilder(
+                processors=[self.processor]
+            )
+
     def getURLsForBPPH(self, bpph, include_meta=False):
         bpr = bpph.binarypackagerelease
         archive = bpph.archive
@@ -278,11 +295,35 @@ class TestBinaryPackagePublishingHistory(TestCaseWithFactory):
             binarypackagerelease=bpr, archive=archive
         )
 
+    def makeBPPHWithMetadata(self):
+        spn = self.factory.getUniqueString()
+        version = "%s.1" % self.factory.getUniqueInteger()
+        with admin_logged_in():
+            spph = self.publisher.getPubSource(
+                sourcename=spn,
+                version=version,
+                distroseries=self.distroseries,
+                status=PackagePublishingStatus.PUBLISHED,
+            )
+            binary = self.publisher.getPubBinaries(
+                binaryname=spn,
+                distroseries=self.distroseries,
+                pub_source=spph,
+                version=version,
+                builder=self.builder,
+            )
+            binary[0].build.addBuildInfo(
+                self.factory.makeLibraryFileAlias(
+                    filename="build_info.info", restricted=True
+                )
+            )
+
+        return binary[0]
+
     def test_binaryFileUrls_no_binaries(self):
         bpph = self.makeBPPH(num_binaries=0)
 
         urls = bpph.binaryFileUrls()
-
         self.assertContentEqual([], urls)
 
     def test_binaryFileUrls_one_binary(self):
@@ -324,6 +365,55 @@ class TestBinaryPackagePublishingHistory(TestCaseWithFactory):
             expected_urls_meta, bpph.binaryFileUrls(include_meta=True)
         )
 
+    def test_buildMetadataFileUrls(self):
+        bpph = self.makeBPPHWithMetadata()
+
+        urls = bpph.buildMetadataFileUrls()
+        with admin_logged_in():
+            upload_changesfile = (
+                bpph.binarypackagerelease.build.upload_changesfile
+            )
+            log = bpph.binarypackagerelease.build.log
+            build_info = bpph.binarypackagerelease.build.buildinfo
+
+            expected_urls = [
+                ProxiedLibraryFileAlias(
+                    upload_changesfile, bpph.archive
+                ).http_url,
+                ProxiedLibraryFileAlias(log, bpph.archive).http_url,
+                ProxiedLibraryFileAlias(build_info, bpph.archive).http_url,
+            ]
+        self.assertContentEqual(expected_urls, urls)
+
+    def test_buildMetadataFileUrls_include_meta(self):
+        bpph = self.makeBPPHWithMetadata()
+
+        urls = bpph.buildMetadataFileUrls(True)
+        with admin_logged_in():
+            files = []
+            files.append(bpph.binarypackagerelease.build.upload_changesfile)
+            files.append(bpph.binarypackagerelease.build.log)
+            files.append(bpph.binarypackagerelease.build.buildinfo)
+
+            expected_urls = [
+                {
+                    "url": ProxiedLibraryFileAlias(
+                        file, bpph.archive
+                    ).http_url,
+                    "size": file.content.filesize,
+                    "sha1": file.content.sha1,
+                    "sha256": file.content.sha256,
+                }
+                for file in files
+            ]
+        self.assertContentEqual(expected_urls, urls)
+
+    def test_buildMetadataFileUrls_no_files(self):
+        bpph = self.makeBPPH(num_binaries=0)
+
+        urls = bpph.buildMetadataFileUrls()
+        self.assertContentEqual([], urls)
+
     def test_is_debug_false_for_deb(self):
         bpph = self.factory.makeBinaryPackagePublishingHistory(
             binpackageformat=BinaryPackageFormat.DEB
_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to