launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #23033
[Merge] lp:~cjwatson/launchpad/git-ref-remote-lp-non-production into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/git-ref-remote-lp-non-production into lp:launchpad.
Commit message:
Allow fetching blobs from repositories hosted on git.launchpad.net from non-production Launchpad instances.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/git-ref-remote-lp-non-production/+merge/357827
This makes life easier when doing e.g. snap build QA on dogfood.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/git-ref-remote-lp-non-production into lp:launchpad.
=== modified file 'lib/lp/code/model/gitref.py'
--- lib/lp/code/model/gitref.py 2018-10-22 12:43:55 +0000
+++ lib/lp/code/model/gitref.py 2018-10-25 15:18:55 +0000
@@ -702,6 +702,25 @@
return response.content
+def _fetch_blob_from_launchpad(repository_url, ref_path, filename):
+ repo_path = urlsplit(repository_url).path.strip("/")
+ try:
+ response = urlfetch(
+ "https://git.launchpad.net/%s/plain/%s" % (
+ repo_path, quote(filename)),
+ params={"h": ref_path})
+ except requests.RequestException as e:
+ if (e.response is not None and
+ e.response.status_code == requests.codes.NOT_FOUND):
+ raise GitRepositoryBlobNotFound(
+ repository_url, filename, rev=ref_path)
+ else:
+ raise GitRepositoryScanFault(
+ "Failed to get file from Git repository at %s: %s" %
+ (repository_url, str(e)))
+ return response.content
+
+
@implementer(IGitRef)
@provider(IGitRefRemoteSet)
class GitRefRemote(GitRefMixin):
@@ -800,17 +819,29 @@
# dispatch a build job or a code import or something like that to do
# so. For now, we just special-case some providers where we know
# how to fetch a blob on its own.
- repository = getUtility(IGitLookup).getByUrl(self.repository_url)
- if repository is not None:
- # This is one of our own repositories. Doing this by URL seems
- # gratuitously complex, but apparently we already have some
- # examples of this on production.
- return repository.getBlob(filename, rev=self.path)
url = urlsplit(self.repository_url)
if (url.hostname == "github.com" and
len(url.path.strip("/").split("/")) == 2):
return _fetch_blob_from_github(
self.repository_url, self.path, filename)
+ if (url.hostname == "git.launchpad.net" and
+ config.vhost.mainsite.hostname != "launchpad.net"):
+ # Even if this isn't launchpad.net, we can still retrieve files
+ # from git.launchpad.net by URL, as a QA convenience. (We check
+ # config.vhost.mainsite.hostname rather than
+ # config.codehosting.git_*_root because the dogfood instance
+ # points git_*_root to git.launchpad.net but doesn't share the
+ # production database.)
+ return _fetch_blob_from_launchpad(
+ self.repository_url, self.path, filename)
+ codehosting_host = urlsplit(config.codehosting.git_anon_root).hostname
+ if url.hostname == codehosting_host:
+ repository = getUtility(IGitLookup).getByUrl(self.repository_url)
+ if repository is not None:
+ # This is one of our own repositories. Doing this by URL
+ # seems gratuitously complex, but apparently we already have
+ # some examples of this on production.
+ return repository.getBlob(filename, rev=self.path)
raise GitRepositoryBlobUnsupportedRemote(self.repository_url)
@property
=== modified file 'lib/lp/code/model/tests/test_gitref.py'
--- lib/lp/code/model/tests/test_gitref.py 2018-10-16 15:29:37 +0000
+++ lib/lp/code/model/tests/test_gitref.py 2018-10-25 15:18:55 +0000
@@ -344,6 +344,51 @@
self.assertEqual(expected_calls, hosting_fixture.getBlob.calls)
@responses.activate
+ def test_remote_launchpad_production_branch(self):
+ ref = self.factory.makeGitRefRemote(
+ repository_url="https://git.launchpad.net/~owner/+git/name",
+ path="refs/heads/path")
+ responses.add(
+ "GET",
+ "https://git.launchpad.net/~owner/+git/name/plain/dir/file"
+ "?h=refs%2Fheads%2Fpath",
+ body=b"foo")
+ self.assertEqual(b"foo", ref.getBlob("dir/file"))
+
+ @responses.activate
+ def test_remote_launchpad_production_HEAD(self):
+ ref = self.factory.makeGitRefRemote(
+ repository_url="https://git.launchpad.net/~owner/+git/name",
+ path="HEAD")
+ responses.add(
+ "GET",
+ "https://git.launchpad.net/~owner/+git/name/plain/dir/file?h=HEAD",
+ body=b"foo")
+ self.assertEqual(b"foo", ref.getBlob("dir/file"))
+
+ @responses.activate
+ def test_remote_launchpad_production_404(self):
+ ref = self.factory.makeGitRefRemote(
+ repository_url="https://git.launchpad.net/~owner/+git/name",
+ path="HEAD")
+ responses.add(
+ "GET",
+ "https://git.launchpad.net/~owner/+git/name/plain/dir/file?h=HEAD",
+ status=404)
+ self.assertRaises(GitRepositoryBlobNotFound, ref.getBlob, "dir/file")
+
+ @responses.activate
+ def test_remote_launchpad_production_error(self):
+ ref = self.factory.makeGitRefRemote(
+ repository_url="https://git.launchpad.net/~owner/+git/name",
+ path="HEAD")
+ responses.add(
+ "GET",
+ "https://git.launchpad.net/~owner/+git/name/plain/dir/file?h=HEAD",
+ status=500)
+ self.assertRaises(GitRepositoryScanFault, ref.getBlob, "dir/file")
+
+ @responses.activate
def test_remote_github_branch(self):
ref = self.factory.makeGitRefRemote(
repository_url="https://github.com/owner/name",
Follow ups