launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #31056
[Merge] ~pelpsi/launchpad:unembargo-bug-build-info-missing into launchpad:master
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
Follow ups