@@ -11,7 +11,6 @@ use aho_corasick::BuildError;
11
11
use apt_auth_config:: AuthConfig ;
12
12
use bon:: { builder, Builder } ;
13
13
use chrono:: Utc ;
14
- use futures:: StreamExt ;
15
14
use nix:: {
16
15
errno:: Errno ,
17
16
fcntl:: {
@@ -45,8 +44,7 @@ use reqwest::StatusCode;
45
44
46
45
use sysinfo:: { Pid , System } ;
47
46
use tokio:: {
48
- fs:: { self , File } ,
49
- io:: AsyncWriteExt ,
47
+ fs:: { self } ,
50
48
process:: Command ,
51
49
task:: spawn_blocking,
52
50
} ;
@@ -352,13 +350,14 @@ impl<'a> OmaRefresh<'a> {
352
350
let mut mirror_sources =
353
351
MirrorSources :: from_sourcelist ( sourcelist, replacer, self . auth_config ) ?;
354
352
355
- let tasks = mirror_sources. 0 . iter ( ) . enumerate ( ) . map ( |( index, m) | {
356
- self . get_release_file ( m, replacer, index, mirror_sources. 0 . len ( ) , callback)
357
- } ) ;
358
-
359
- let results = futures:: stream:: iter ( tasks)
360
- . buffer_unordered ( self . threads )
361
- . collect :: < Vec < _ > > ( )
353
+ let results = mirror_sources
354
+ . fetch_all_release (
355
+ & self . client ,
356
+ replacer,
357
+ & self . download_dir ,
358
+ self . threads ,
359
+ callback,
360
+ )
362
361
. await ;
363
362
364
363
debug ! ( "download_releases: results: {:?}" , results) ;
@@ -464,298 +463,6 @@ impl<'a> OmaRefresh<'a> {
464
463
Ok ( ( ) )
465
464
}
466
465
467
- async fn get_release_file < ' b , F , Fut > (
468
- & self ,
469
- entry : & MirrorSource < ' b , ' a > ,
470
- replacer : & DatabaseFilenameReplacer ,
471
- progress_index : usize ,
472
- total : usize ,
473
- callback : & F ,
474
- ) -> Result < ( ) >
475
- where
476
- F : Fn ( Event ) -> Fut ,
477
- Fut : Future < Output = ( ) > ,
478
- {
479
- match entry. from ( ) ? {
480
- OmaSourceEntryFrom :: Http => {
481
- self . download_http_release ( entry, replacer, progress_index, total, callback)
482
- . await
483
- }
484
- OmaSourceEntryFrom :: Local => {
485
- self . download_local_release ( entry, replacer, progress_index, total, callback)
486
- . await
487
- }
488
- }
489
- }
490
-
491
- async fn download_local_release < ' b , F , Fut > (
492
- & self ,
493
- entry : & MirrorSource < ' b , ' a > ,
494
- replacer : & DatabaseFilenameReplacer ,
495
- index : usize ,
496
- total : usize ,
497
- callback : & F ,
498
- ) -> Result < ( ) >
499
- where
500
- F : Fn ( Event ) -> Fut ,
501
- Fut : Future < Output = ( ) > ,
502
- {
503
- let dist_path_with_protocol = entry. dist_path ( ) ;
504
- let dist_path = dist_path_with_protocol
505
- . strip_prefix ( "file:" )
506
- . unwrap_or ( dist_path_with_protocol) ;
507
- let dist_path = Path :: new ( dist_path) ;
508
-
509
- let mut name = None ;
510
-
511
- let msg = entry. get_human_download_url ( None ) ?;
512
-
513
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: NewProgressSpinner {
514
- index,
515
- msg : format ! ( "({}/{}) {}" , index, total, msg) ,
516
- } ) )
517
- . await ;
518
-
519
- let mut is_release = false ;
520
-
521
- for ( index, entry) in [ "InRelease" , "Release" ] . iter ( ) . enumerate ( ) {
522
- let p = dist_path. join ( entry) ;
523
-
524
- let dst = if dist_path_with_protocol. ends_with ( '/' ) {
525
- format ! ( "{}{}" , dist_path_with_protocol, entry)
526
- } else {
527
- format ! ( "{}/{}" , dist_path_with_protocol, entry)
528
- } ;
529
-
530
- let file_name = replacer. replace ( & dst) ?;
531
-
532
- let dst = self . download_dir . join ( & file_name) ;
533
-
534
- if p. exists ( ) {
535
- if dst. exists ( ) {
536
- debug ! ( "get_release_file: Removing {}" , dst. display( ) ) ;
537
- fs:: remove_file ( & dst)
538
- . await
539
- . map_err ( |e| RefreshError :: OperateFile ( dst. clone ( ) , e) ) ?;
540
- }
541
-
542
- debug ! ( "get_release_file: Symlink {}" , dst. display( ) ) ;
543
- fs:: symlink ( p, & dst)
544
- . await
545
- . map_err ( |e| RefreshError :: OperateFile ( dst. clone ( ) , e) ) ?;
546
-
547
- if index == 1 {
548
- is_release = true ;
549
- }
550
-
551
- name = Some ( file_name) ;
552
- break ;
553
- }
554
- }
555
-
556
- if name. is_none ( ) && entry. is_flat ( ) {
557
- // Flat repo no release
558
- return Ok ( ( ) ) ;
559
- }
560
-
561
- if is_release {
562
- let p = dist_path. join ( "Release.gpg" ) ;
563
- let entry = "Release.gpg" ;
564
-
565
- let dst = if dist_path_with_protocol. ends_with ( '/' ) {
566
- format ! ( "{}{}" , dist_path_with_protocol, entry)
567
- } else {
568
- format ! ( "{}/{}" , dist_path_with_protocol, entry)
569
- } ;
570
-
571
- let file_name = replacer. replace ( & dst) ?;
572
-
573
- let dst = self . download_dir . join ( & file_name) ;
574
-
575
- if p. exists ( ) {
576
- if dst. exists ( ) {
577
- fs:: remove_file ( & dst)
578
- . await
579
- . map_err ( |e| RefreshError :: OperateFile ( dst. clone ( ) , e) ) ?;
580
- }
581
-
582
- fs:: symlink ( p, self . download_dir . join ( file_name) )
583
- . await
584
- . map_err ( |e| RefreshError :: OperateFile ( dst. clone ( ) , e) ) ?;
585
- }
586
- }
587
-
588
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: ProgressDone ( index) ) ) . await ;
589
-
590
- let name = name. ok_or_else ( || RefreshError :: NoInReleaseFile ( entry. url ( ) . to_string ( ) ) ) ?;
591
- entry. set_release_file_name ( name) ;
592
-
593
- Ok ( ( ) )
594
- }
595
-
596
- async fn download_http_release < ' b , F , Fut > (
597
- & self ,
598
- entry : & MirrorSource < ' b , ' a > ,
599
- replacer : & DatabaseFilenameReplacer ,
600
- index : usize ,
601
- total : usize ,
602
- callback : & F ,
603
- ) -> std:: result:: Result < ( ) , RefreshError >
604
- where
605
- F : Fn ( Event ) -> Fut ,
606
- Fut : Future < Output = ( ) > ,
607
- {
608
- let dist_path = entry. dist_path ( ) ;
609
-
610
- let mut r = None ;
611
- let mut u = None ;
612
- let mut is_release = false ;
613
-
614
- let msg = entry. get_human_download_url ( None ) ?;
615
-
616
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: NewProgressSpinner {
617
- index,
618
- msg : format ! ( "({}/{}) {}" , index, total, msg) ,
619
- } ) )
620
- . await ;
621
-
622
- for ( index, file_name) in [ "InRelease" , "Release" ] . iter ( ) . enumerate ( ) {
623
- let url = format ! ( "{}/{}" , dist_path, file_name) ;
624
- let request = self . request_get_builder ( & url, entry) ;
625
-
626
- let resp = request
627
- . send ( )
628
- . await
629
- . and_then ( |resp| resp. error_for_status ( ) ) ;
630
-
631
- r = Some ( resp) ;
632
-
633
- if r. as_ref ( ) . unwrap ( ) . is_ok ( ) {
634
- u = Some ( url) ;
635
- if index == 1 {
636
- is_release = true ;
637
- }
638
- break ;
639
- }
640
- }
641
-
642
- let r = r. unwrap ( ) ;
643
-
644
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: ProgressDone ( index) ) ) . await ;
645
-
646
- if r. is_err ( ) && entry. is_flat ( ) {
647
- // Flat repo no release
648
- return Ok ( ( ) ) ;
649
- }
650
-
651
- let resp = r
652
- . map_err ( |e| SingleDownloadError :: ReqwestError { source : e } )
653
- . map_err ( |e| RefreshError :: DownloadFailed ( Some ( e) ) ) ?;
654
-
655
- let url = u. unwrap ( ) ;
656
- let file_name = replacer. replace ( & url) ?;
657
-
658
- self . download_file ( & file_name, resp, entry, index, total, & callback)
659
- . await
660
- . map_err ( |e| RefreshError :: DownloadFailed ( Some ( e) ) ) ?;
661
-
662
- entry. set_release_file_name ( file_name) ;
663
-
664
- if is_release && !entry. trusted ( ) {
665
- let url = format ! ( "{}/{}" , dist_path, "Release.gpg" ) ;
666
-
667
- let request = self . request_get_builder ( & url, entry) ;
668
- let resp = request
669
- . send ( )
670
- . await
671
- . and_then ( |resp| resp. error_for_status ( ) )
672
- . map_err ( |e| SingleDownloadError :: ReqwestError { source : e } )
673
- . map_err ( |e| RefreshError :: DownloadFailed ( Some ( e) ) ) ?;
674
-
675
- let file_name = replacer. replace ( & url) ?;
676
-
677
- self . download_file ( & file_name, resp, entry, index, total, & callback)
678
- . await
679
- . map_err ( |e| RefreshError :: DownloadFailed ( Some ( e) ) ) ?;
680
- }
681
-
682
- Ok ( ( ) )
683
- }
684
-
685
- fn request_get_builder < ' b > (
686
- & self ,
687
- url : & str ,
688
- source_index : & MirrorSource < ' b , ' a > ,
689
- ) -> reqwest:: RequestBuilder {
690
- let mut request = self . client . get ( url) ;
691
- if let Some ( auth) = source_index. auth ( ) {
692
- request = request. basic_auth ( & auth. login , Some ( & auth. password ) )
693
- }
694
-
695
- request
696
- }
697
-
698
- async fn download_file < ' b , F , Fut > (
699
- & self ,
700
- file_name : & str ,
701
- mut resp : Response ,
702
- source_index : & MirrorSource < ' b , ' a > ,
703
- index : usize ,
704
- total : usize ,
705
- callback : & F ,
706
- ) -> std:: result:: Result < ( ) , SingleDownloadError >
707
- where
708
- F : Fn ( Event ) -> Fut ,
709
- Fut : Future < Output = ( ) > ,
710
- {
711
- let total_size = content_length ( & resp) ;
712
-
713
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: NewProgressBar {
714
- index,
715
- msg : format ! (
716
- "({}/{}) {}" ,
717
- index,
718
- total,
719
- source_index
720
- . get_human_download_url( Some ( file_name) )
721
- . unwrap( ) ,
722
- ) ,
723
- size : total_size,
724
- } ) ) ;
725
-
726
- let mut f = File :: create ( self . download_dir . join ( file_name) )
727
- . await
728
- . map_err ( |e| SingleDownloadError :: Create { source : e } ) ?;
729
-
730
- f. set_permissions ( Permissions :: from_mode ( 0o644 ) )
731
- . await
732
- . map_err ( |e| SingleDownloadError :: SetPermission { source : e } ) ?;
733
-
734
- while let Some ( chunk) = resp
735
- . chunk ( )
736
- . await
737
- . map_err ( |e| SingleDownloadError :: ReqwestError { source : e } ) ?
738
- {
739
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: ProgressInc {
740
- index,
741
- size : chunk. len ( ) as u64 ,
742
- } ) )
743
- . await ;
744
-
745
- f. write_all ( & chunk)
746
- . await
747
- . map_err ( |e| SingleDownloadError :: Write { source : e } ) ?;
748
- }
749
-
750
- f. shutdown ( )
751
- . await
752
- . map_err ( |e| SingleDownloadError :: Flush { source : e } ) ?;
753
-
754
- callback ( Event :: DownloadEvent ( oma_fetch:: Event :: ProgressDone ( index) ) ) . await ;
755
-
756
- Ok ( ( ) )
757
- }
758
-
759
466
async fn collect_all_release_entry < ' b > (
760
467
& self ,
761
468
replacer : & DatabaseFilenameReplacer ,
@@ -856,7 +563,7 @@ impl<'a> OmaRefresh<'a> {
856
563
}
857
564
}
858
565
859
- fn content_length ( resp : & Response ) -> u64 {
566
+ pub fn content_length ( resp : & Response ) -> u64 {
860
567
let content_length = resp
861
568
. headers ( )
862
569
. get ( CONTENT_LENGTH )
0 commit comments