Skip to content

Commit d28c33e

Browse files
committed
refactor(oma-refresh)!: move download release to MirrorSources impl
1 parent dd43d69 commit d28c33e

File tree

4 files changed

+380
-321
lines changed

4 files changed

+380
-321
lines changed

oma-fetch/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use checksum::Checksum;
55
use download::{EmptySource, SingleDownloader, SuccessSummary};
66
use futures::{Future, StreamExt};
77

8-
use reqwest::Client;
8+
use reqwest::{Client, Method, RequestBuilder};
9+
use tracing::debug;
910

1011
pub mod checksum;
1112
mod download;
@@ -272,3 +273,19 @@ impl DownloadManager<'_> {
272273
Ok(Summary { success, failed })
273274
}
274275
}
276+
277+
pub fn build_request_with_basic_auth(
278+
client: &Client,
279+
method: Method,
280+
auth: &Option<(String, String)>,
281+
url: &str,
282+
) -> RequestBuilder {
283+
let mut req = client.request(method, url);
284+
285+
if let Some((user, password)) = auth {
286+
debug!("auth user: {}", user);
287+
req = req.basic_auth(user, Some(password));
288+
}
289+
290+
req
291+
}

oma-refresh/src/db.rs

Lines changed: 10 additions & 303 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use aho_corasick::BuildError;
1111
use apt_auth_config::AuthConfig;
1212
use bon::{builder, Builder};
1313
use chrono::Utc;
14-
use futures::StreamExt;
1514
use nix::{
1615
errno::Errno,
1716
fcntl::{
@@ -45,8 +44,7 @@ use reqwest::StatusCode;
4544

4645
use sysinfo::{Pid, System};
4746
use tokio::{
48-
fs::{self, File},
49-
io::AsyncWriteExt,
47+
fs::{self},
5048
process::Command,
5149
task::spawn_blocking,
5250
};
@@ -352,13 +350,14 @@ impl<'a> OmaRefresh<'a> {
352350
let mut mirror_sources =
353351
MirrorSources::from_sourcelist(sourcelist, replacer, self.auth_config)?;
354352

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+
)
362361
.await;
363362

364363
debug!("download_releases: results: {:?}", results);
@@ -464,298 +463,6 @@ impl<'a> OmaRefresh<'a> {
464463
Ok(())
465464
}
466465

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-
759466
async fn collect_all_release_entry<'b>(
760467
&self,
761468
replacer: &DatabaseFilenameReplacer,
@@ -856,7 +563,7 @@ impl<'a> OmaRefresh<'a> {
856563
}
857564
}
858565

859-
fn content_length(resp: &Response) -> u64 {
566+
pub fn content_length(resp: &Response) -> u64 {
860567
let content_length = resp
861568
.headers()
862569
.get(CONTENT_LENGTH)

0 commit comments

Comments
 (0)