launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #28382
[Merge] ~cjwatson/launchpad:ocirecipebuild-get-file-urls into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:ocirecipebuild-get-file-urls into launchpad:master.
Commit message:
Add and export OCIRecipeBuild.getFileUrls
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1969449 in Launchpad itself: "add a method to return URLs for all the files produced by a given OCI build"
https://bugs.launchpad.net/launchpad/+bug/1969449
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/420299
This aligns with snap builds, and it's useful for processing the results of OCI recipe builds outside Launchpad.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:ocirecipebuild-get-file-urls into launchpad:master.
diff --git a/lib/lp/oci/interfaces/ocirecipebuild.py b/lib/lp/oci/interfaces/ocirecipebuild.py
index b366f87..763e1ed 100644
--- a/lib/lp/oci/interfaces/ocirecipebuild.py
+++ b/lib/lp/oci/interfaces/ocirecipebuild.py
@@ -21,6 +21,7 @@ from lazr.enum import (
)
from lazr.restful.declarations import (
error_status,
+ export_read_operation,
export_write_operation,
exported,
exported_as_webservice_entry,
@@ -196,6 +197,14 @@ class IOCIRecipeBuildView(IPackageBuildView, IPrivacy):
:return: The corresponding `ILibraryFileAlias`.
"""
+ @export_read_operation()
+ @operation_for_version("devel")
+ def getFileUrls():
+ """URLs for all the files produced by this build.
+
+ :return: A collection of URLs for this build.
+ """
+
def getLayerFileByDigest(layer_file_digest):
"""Retrieve a layer file by the digest.
diff --git a/lib/lp/oci/model/ocirecipebuild.py b/lib/lp/oci/model/ocirecipebuild.py
index 4ad0f4f..2dee003 100644
--- a/lib/lp/oci/model/ocirecipebuild.py
+++ b/lib/lp/oci/model/ocirecipebuild.py
@@ -67,6 +67,7 @@ from lp.services.database.interfaces import (
from lp.services.database.stormbase import StormBase
from lp.services.job.interfaces.job import JobStatus
from lp.services.job.model.job import Job
+from lp.services.librarian.browser import ProxiedLibraryFileAlias
from lp.services.librarian.model import (
LibraryFileAlias,
LibraryFileContent,
@@ -293,6 +294,15 @@ class OCIRecipeBuild(PackageBuildMixin, StormBase):
raise NotFoundError(filename)
+ def lfaUrl(self, lfa):
+ """Return the URL for a LibraryFileAlias in this context."""
+ if lfa is None:
+ return None
+ return ProxiedLibraryFileAlias(lfa, self).http_url
+
+ def getFileUrls(self):
+ return [self.lfaUrl(lfa) for _, lfa, _ in self.getFiles()]
+
@cachedproperty
def eta(self):
"""The datetime when the build job is estimated to complete.
diff --git a/lib/lp/oci/tests/test_ocirecipebuild.py b/lib/lp/oci/tests/test_ocirecipebuild.py
index 1ec8718..8a9c33b 100644
--- a/lib/lp/oci/tests/test_ocirecipebuild.py
+++ b/lib/lp/oci/tests/test_ocirecipebuild.py
@@ -57,6 +57,7 @@ from lp.services.authserver.xmlrpc import AuthServerAPIView
from lp.services.config import config
from lp.services.features.testing import FeatureFixture
from lp.services.job.interfaces.job import JobStatus
+from lp.services.librarian.browser import ProxiedLibraryFileAlias
from lp.services.macaroons.interfaces import (
BadMacaroonContext,
IMacaroonIssuer,
@@ -846,6 +847,23 @@ class TestOCIRecipeBuildWebservice(OCIConfigHelperMixin, TestCaseWithFactory):
self.assertIsNotNone(build["upload_log_url"])
self.assertCanOpenRedirectedUrl(browser, build["upload_log_url"])
+ def test_getFileUrls(self):
+ # API clients can fetch files attached to builds.
+ db_build = self.factory.makeOCIRecipeBuild(requester=self.person)
+ db_files = [self.factory.makeOCIFile(build=db_build) for i in range(2)]
+ build_url = api_url(db_build)
+ file_urls = [
+ ProxiedLibraryFileAlias(file.library_file, db_build).http_url
+ for file in db_files]
+ logout()
+ response = self.webservice.named_get(build_url, "getFileUrls")
+ self.assertEqual(200, response.status)
+ self.assertContentEqual(file_urls, response.jsonBody())
+ browser = self.getNonRedirectingBrowser(user=self.person)
+ browser.raiseHttpErrors = False
+ for file_url in file_urls:
+ self.assertCanOpenRedirectedUrl(browser, file_url)
+
class TestOCIRecipeBuildMacaroonIssuer(
MacaroonTestMixin, OCIConfigHelperMixin, TestCaseWithFactory):