Skip to content
Snippets Groups Projects
Commit cfb11341 authored by Georges Racinet's avatar Georges Racinet
Browse files

RHGitaly: implement RefService.RefExists

Perhaps the simplest useful application of `map_full_ref`.
Testing provided by Comparison tests.

We have to introduce another wrapper for propper logging of
the `revision` field (otherwise it is almost impossible to follow, even
if one knows one's ASCII). This will be needed by many other methods.

Closes #128
parent c49e487b
No related branches found
No related tags found
2 merge requests!169Protocol v15.9 and stable branch merge",!166RHGitaly: reading GitLab ref state files, implementing RefService.RefExists
Pipeline #68542 passed
......@@ -14,6 +14,7 @@
use rhgitaly::config::Config;
use rhgitaly::service::commit::commit_server;
use rhgitaly::service::r#ref::ref_server;
use rhgitaly::service::repository::repository_server;
use rhgitaly::service::server::server_server;
use tracing::{info, Level};
......@@ -59,6 +60,7 @@
let server = Server::builder()
.add_service(server_server())
.add_service(commit_server(&config))
.add_service(ref_server(&config))
.add_service(repository_server(&config));
let bind_addr = parse_listen_url(&config.listen_url)?;
......
......@@ -4,5 +4,6 @@
// GNU General Public License version 2 or any later version.
// SPDX-License-Identifier: GPL-2.0-or-later
pub mod commit;
pub mod r#ref;
pub mod repository;
pub mod server;
// Copyright 2023 Georges Racinet <georges.racinet@octobus.net>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
// SPDX-License-Identifier: GPL-2.0-or-later
use std::fmt::{Debug, Formatter};
use std::string::String;
use std::sync::Arc;
use tonic::{metadata::Ascii, metadata::MetadataValue, Request, Response, Status};
use tracing::{field, info, instrument};
use crate::config::Config;
use crate::gitaly::ref_service_server::{RefService, RefServiceServer};
use crate::gitaly::{RefExistsRequest, RefExistsResponse};
use crate::gitlab::revision::{map_full_ref, RefError};
use crate::metadata::correlation_id;
use crate::repository::{default_repo_spec_error_status, repo_path};
#[derive(Debug)]
pub struct RefServiceImpl {
config: Arc<Config>,
}
#[tonic::async_trait]
impl RefService for RefServiceImpl {
async fn ref_exists(
&self,
request: Request<RefExistsRequest>,
) -> Result<Response<RefExistsResponse>, Status> {
let (metadata, _ext, inner) = request.into_parts();
self.inner_ref_exists(inner, correlation_id(&metadata))
.await
}
}
struct RefExistsTracingRequest<'a>(&'a RefExistsRequest);
impl Debug for RefExistsTracingRequest<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RefExistRequest")
.field("repository", &self.0.repository)
.field("ref", &String::from_utf8_lossy(&self.0.r#ref))
.finish()
}
}
impl RefServiceImpl {
#[instrument(name="ref_exists",
skip(self, request),
fields(request=field::debug(RefExistsTracingRequest(&request))))]
async fn inner_ref_exists(
&self,
request: RefExistsRequest,
correlation_id: Option<&MetadataValue<Ascii>>,
) -> Result<Response<RefExistsResponse>, Status> {
info!("Processing");
if let Some(gl_repo) = &request.repository {
let repo_path =
repo_path(&self.config, gl_repo).map_err(default_repo_spec_error_status)?;
let store_path = repo_path.join(".hg/store");
let value = match map_full_ref(&store_path, &request.r#ref, |_tr| (), |_ka| ()).await {
Ok(()) => Ok(true),
Err(RefError::NotFound) => Ok(false),
Err(RefError::MissingRefName) => Ok(false),
Err(RefError::NotAFullRef) => Err(Status::invalid_argument("invalid refname")),
Err(RefError::GitLabStateFileError(e)) => Err(Status::internal(format!("{:?}", e))),
}?;
return Ok(Response::new(RefExistsResponse { value }));
}
Err(Status::invalid_argument(
"GetStorageByName: no such storage: \"\"",
))
}
}
/// Takes care of boilerplate that would instead be in the startup sequence.
pub fn ref_server(config: &Arc<Config>) -> RefServiceServer<RefServiceImpl> {
RefServiceServer::new(RefServiceImpl {
config: config.clone(),
})
}
......@@ -61,8 +61,9 @@
same_details=False)
def test_compare_ref_exists(gitaly_comparison):
fixture = gitaly_comparison
@parametrize('hg_server', ('hgitaly', 'rhgitaly'))
def test_compare_ref_exists(gitaly_rhgitaly_comparison, hg_server):
fixture = gitaly_rhgitaly_comparison
wrapper = fixture.hg_repo_wrapper
rpc_helper = fixture.rpc_helper(
......@@ -66,6 +67,7 @@
wrapper = fixture.hg_repo_wrapper
rpc_helper = fixture.rpc_helper(
hg_server=hg_server,
stub_cls=RefServiceStub,
method_name='RefExists',
request_cls=RefExistsRequest,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment