@@ -271,7 +271,7 @@ async fn repo_update_fn(
271271async fn do_filter (
272272 repo_path : std:: path:: PathBuf ,
273273 service : Arc < JoshProxyService > ,
274- upstream_repo : String ,
274+ meta : josh_proxy :: MetaConfig ,
275275 temp_ns : Arc < josh_proxy:: TmpGitNamespace > ,
276276 filter : josh:: filter:: Filter ,
277277 headref : String ,
@@ -284,23 +284,23 @@ async fn do_filter(
284284 let _e = s. enter ( ) ;
285285 tracing:: trace!( "in do_filter worker" ) ;
286286 let filter_spec = josh:: filter:: spec ( filter) ;
287- josh:: housekeeping:: remember_filter ( & upstream_repo , & filter_spec) ;
287+ josh:: housekeeping:: remember_filter ( & meta . config . repo , & filter_spec) ;
288288
289289 let transaction = josh:: cache:: Transaction :: open (
290290 & repo_path. join ( "mirror" ) ,
291291 Some ( & format ! (
292292 "refs/josh/upstream/{}/" ,
293- & josh:: to_ns( & upstream_repo ) ,
293+ & josh:: to_ns( & meta . config . repo ) ,
294294 ) ) ,
295295 ) ?;
296- let mut refslist = josh:: housekeeping:: list_refs ( transaction. repo ( ) , & upstream_repo ) ?;
296+ let mut refslist = josh:: housekeeping:: list_refs ( transaction. repo ( ) , & meta . config . repo ) ?;
297297
298298 let mut headref = headref;
299299
300300 if headref. starts_with ( "refs/" ) || headref == "HEAD" {
301301 let name = format ! (
302302 "refs/josh/upstream/{}/{}" ,
303- & josh:: to_ns( & upstream_repo ) ,
303+ & josh:: to_ns( & meta . config . repo ) ,
304304 headref. clone( )
305305 ) ;
306306 if let Ok ( r) = transaction. repo ( ) . revparse_single ( & name) {
@@ -315,7 +315,7 @@ async fn do_filter(
315315 if headref == "HEAD" {
316316 headref = heads_map
317317 . read ( ) ?
318- . get ( & upstream_repo )
318+ . get ( & meta . config . repo )
319319 . unwrap_or ( & "invalid" . to_string ( ) )
320320 . clone ( ) ;
321321 }
@@ -324,7 +324,8 @@ async fn do_filter(
324324 t2. repo ( )
325325 . odb ( ) ?
326326 . add_disk_alternate ( & repo_path. join ( "mirror" ) . join ( "objects" ) . to_str ( ) . unwrap ( ) ) ?;
327- let mut updated_refs = josh:: filter_refs ( & t2, filter, & refslist, josh:: filter:: empty ( ) ) ?;
327+ let updated_refs = josh:: filter_refs ( & t2, filter, & refslist, josh:: filter:: empty ( ) ) ?;
328+ let mut updated_refs = josh_proxy:: refs_locking ( & transaction. repo ( ) , updated_refs, & meta) ;
328329 josh:: housekeeping:: namespace_refs ( & mut updated_refs, & temp_ns. name ( ) ) ;
329330 josh:: update_refs ( & t2, & mut updated_refs, & temp_ns. reference ( & headref) ) ;
330331 t2. repo ( )
@@ -392,20 +393,12 @@ async fn handle_ui_request(
392393 return Ok ( response) ;
393394}
394395
395- #[ derive( serde:: Serialize , serde:: Deserialize , Debug , Clone , Default ) ]
396- struct RepoConfig {
397- repo : String ,
398-
399- #[ serde( default ) ]
400- filter : josh:: filter:: Filter ,
401- }
402-
403396async fn query_meta_repo (
404397 serv : Arc < JoshProxyService > ,
405398 meta_repo : & str ,
406399 upstream_repo : & str ,
407400 auth : & josh_proxy:: auth:: Handle ,
408- ) -> josh:: JoshResult < RepoConfig > {
401+ ) -> josh:: JoshResult < josh_proxy :: MetaConfig > {
409402 let remote_url = [ serv. upstream_url . as_str ( ) , meta_repo] . join ( "" ) ;
410403 match fetch_upstream (
411404 serv. clone ( ) ,
@@ -442,9 +435,24 @@ async fn query_meta_repo(
442435 return Err ( josh:: josh_error ( & "meta repo entry not found" ) ) ;
443436 }
444437
445- let config: RepoConfig = serde_yaml:: from_str ( & meta_blob) ?;
438+ let mut meta: josh_proxy:: MetaConfig = Default :: default ( ) ;
439+
440+ meta. config = serde_yaml:: from_str ( & meta_blob) ?;
446441
447- return Ok ( config) ;
442+ if meta. config . lock_refs {
443+ let meta_blob = josh:: filter:: tree:: get_blob (
444+ transaction. repo ( ) ,
445+ & meta_tree,
446+ & std:: path:: Path :: new ( & upstream_repo. trim_start_matches ( "/" ) ) . join ( "refs.yml" ) ,
447+ ) ;
448+
449+ if meta_blob == "" {
450+ return Err ( josh:: josh_error ( & "locked refs not found" ) ) ;
451+ }
452+ meta. refs_lock = serde_yaml:: from_str ( & meta_blob) ?;
453+ }
454+
455+ return Ok ( meta) ;
448456}
449457
450458#[ tracing:: instrument]
@@ -516,22 +524,24 @@ async fn call_service(
516524 }
517525 } ;
518526
519- let mut config = RepoConfig :: default ( ) ;
527+ let mut meta = Default :: default ( ) ;
520528
521529 if let Ok ( meta_repo) = std:: env:: var ( "JOSH_META_REPO" ) {
522530 let auth = if let Ok ( token) = std:: env:: var ( "JOSH_META_AUTH_TOKEN" ) {
523531 josh_proxy:: auth:: add_auth ( & token) ?
524532 } else {
525533 auth. clone ( )
526534 } ;
527- config =
528- query_meta_repo ( serv. clone ( ) , & meta_repo, & parsed_url. upstream_repo , & auth) . await ?;
535+ meta = query_meta_repo ( serv. clone ( ) , & meta_repo, & parsed_url. upstream_repo , & auth) . await ?;
529536 } else {
530- config. repo = parsed_url. upstream_repo ;
537+ meta . config . repo = parsed_url. upstream_repo ;
531538 }
532539
533- let filter = josh:: filter:: chain ( config. filter , josh:: filter:: parse ( & parsed_url. filter_spec ) ?) ;
534- let remote_url = [ serv. upstream_url . as_str ( ) , config. repo . as_str ( ) ] . join ( "" ) ;
540+ let filter = josh:: filter:: chain (
541+ meta. config . filter ,
542+ josh:: filter:: parse ( & parsed_url. filter_spec ) ?,
543+ ) ;
544+ let remote_url = [ serv. upstream_url . as_str ( ) , meta. config . repo . as_str ( ) ] . join ( "" ) ;
535545
536546 if parsed_url. pathinfo . starts_with ( "/info/lfs" ) {
537547 return Ok ( Response :: builder ( )
@@ -564,7 +574,7 @@ async fn call_service(
564574 let block = block. split ( ";" ) . collect :: < Vec < _ > > ( ) ;
565575
566576 for b in block {
567- if b == config. repo {
577+ if b == meta . config . repo {
568578 return Ok ( make_response (
569579 hyper:: Body :: from ( formatdoc ! (
570580 r#"
@@ -577,11 +587,11 @@ async fn call_service(
577587 }
578588
579589 if parsed_url. api == "/~/graphql" {
580- return serve_graphql ( serv, req, config. repo . to_owned ( ) , remote_url, auth) . await ;
590+ return serve_graphql ( serv, req, meta . config . repo . to_owned ( ) , remote_url, auth) . await ;
581591 }
582592
583593 if parsed_url. api == "/~/graphiql" {
584- let addr = format ! ( "/~/graphql{}" , config. repo) ;
594+ let addr = format ! ( "/~/graphql{}" , meta . config. repo) ;
585595 return Ok ( tokio:: task:: spawn_blocking ( move || {
586596 josh_proxy:: juniper_hyper:: graphiql ( & addr, None )
587597 } )
@@ -591,7 +601,7 @@ async fn call_service(
591601
592602 match fetch_upstream (
593603 serv. clone ( ) ,
594- config. repo . to_owned ( ) ,
604+ meta . config . repo . to_owned ( ) ,
595605 & auth,
596606 remote_url. to_owned ( ) ,
597607 & headref,
@@ -618,10 +628,10 @@ async fn call_service(
618628 req. uri ( ) . query ( ) . map ( |x| x. to_string ( ) ) ,
619629 parsed_url. pathinfo . is_empty ( ) ,
620630 ) {
621- return serve_query ( serv, q, config. repo , filter, headref) . await ;
631+ return serve_query ( serv, q, meta . config . repo , filter, headref) . await ;
622632 }
623633
624- let temp_ns = prepare_namespace ( serv. clone ( ) , & config . repo , filter, & headref)
634+ let temp_ns = prepare_namespace ( serv. clone ( ) , & meta , filter, & headref)
625635 . in_current_span ( )
626636 . await ?;
627637
@@ -654,7 +664,7 @@ async fn call_service(
654664 auth,
655665 port : serv. port . clone ( ) ,
656666 filter_spec : josh:: filter:: spec ( filter) ,
657- base_ns : josh:: to_ns ( & config. repo ) ,
667+ base_ns : josh:: to_ns ( & meta . config . repo ) ,
658668 git_ns : temp_ns. name ( ) . to_string ( ) ,
659669 git_dir : repo_path. clone ( ) ,
660670 mirror_git_dir : mirror_repo_path. clone ( ) ,
@@ -752,7 +762,7 @@ async fn serve_query(
752762#[ tracing:: instrument]
753763async fn prepare_namespace (
754764 serv : Arc < JoshProxyService > ,
755- upstream_repo : & str ,
765+ meta : & josh_proxy :: MetaConfig ,
756766 filter : josh:: filter:: Filter ,
757767 headref : & str ,
758768) -> josh:: JoshResult < std:: sync:: Arc < josh_proxy:: TmpGitNamespace > > {
@@ -766,7 +776,7 @@ async fn prepare_namespace(
766776 do_filter (
767777 serv. repo_path . clone ( ) ,
768778 serv. clone ( ) ,
769- upstream_repo . to_owned ( ) ,
779+ meta . clone ( ) ,
770780 temp_ns. to_owned ( ) ,
771781 filter,
772782 headref. to_string ( ) ,
0 commit comments