Skip to content

Commit a550796

Browse files
authored
feat(oma-refresh): add run apt update success post invoke feature (#103)
* feat(oma-refresh): add run apt update success post invoke feature * Wait remove useless file task finish after run success post invoke * Fix apt dump config contains useless `"` and `;` * clippy * Fix remove useless repr char * Remove useless line * No need to collect iter * Improve code style
1 parent 04f048d commit a550796

File tree

3 files changed

+67
-69
lines changed

3 files changed

+67
-69
lines changed

oma-refresh/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "GPL-3.0-or-later"
1111
oma-fetch = { version = "^0.14.0", path = "../oma-fetch", default-features = false }
1212
thiserror = "1.0"
1313
url = "2.3"
14-
tokio = { version = "1.28", default-features = false, features = ["fs"] }
14+
tokio = { version = "1.28", default-features = false, features = ["fs", "process"] }
1515
futures = "0.3"
1616
oma-apt-sources-lists = "0.4"
1717
oma-debcontrol = "0.3"

oma-refresh/src/config.rs

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{cmp::Ordering, collections::VecDeque, env, path::Path};
1+
use std::{env, path::Path};
22

33
use ahash::AHashMap;
44
use oma_apt::config::Config;
@@ -8,69 +8,25 @@ use tracing::debug;
88

99
use crate::inrelease::ChecksumItem;
1010

11-
fn get_config(config: &Config) -> Vec<(String, String)> {
12-
let Some(tree) = config.root_tree() else {
13-
return vec![];
14-
};
15-
16-
let mut list = vec![];
17-
18-
let mut stack = VecDeque::new();
19-
stack.push_back((tree, 0));
20-
21-
let mut depth = 0;
22-
let mut name = "".to_string();
23-
24-
while let Some((node, indent)) = stack.pop_back() {
25-
let mut k = None;
26-
let mut v = None;
11+
pub fn get_config(config: &Config) -> Vec<(String, String)> {
12+
config
13+
.dump()
14+
.lines()
15+
.filter_map(|x| x.split_once(|c: char| c.is_ascii_whitespace()))
16+
.map(|(k, v)| {
17+
let mut v = v.to_string();
2718

28-
if let Some(item) = node.sibling() {
29-
stack.push_back((item, indent));
30-
}
31-
32-
if let Some(item) = node.child() {
33-
stack.push_back((item, indent + 2));
34-
}
35-
36-
if let Some(tag) = node.tag() {
37-
match indent.cmp(&depth) {
38-
Ordering::Less => {
39-
let mut tmp = name.split("::").collect::<Vec<_>>();
40-
for _ in 0..=1 {
41-
tmp.pop();
42-
}
43-
name = tmp.join("::");
44-
name.push_str("::");
45-
name.push_str(&tag);
46-
}
47-
Ordering::Equal => {
48-
let mut tmp = name.split("::").collect::<Vec<_>>();
49-
tmp.pop();
50-
name = tmp.join("::");
51-
name.push_str("::");
52-
name.push_str(&tag);
53-
}
54-
Ordering::Greater => {
55-
name.push_str("::");
56-
name.push_str(&tag);
57-
}
19+
while v.ends_with(";") || v.ends_with("\"") {
20+
v.pop();
5821
}
5922

60-
depth = indent;
61-
k = Some(name.strip_prefix("::").unwrap().to_string());
62-
}
63-
64-
if let Some(value) = node.value() {
65-
v = Some(value);
66-
}
67-
68-
if let Some(v) = k.zip(v) {
69-
list.push((v.0, v.1));
70-
}
71-
}
23+
while v.starts_with("\"") {
24+
v.remove(0);
25+
}
7226

73-
list
27+
(k.to_string(), v)
28+
})
29+
.collect()
7430
}
7531

7632
#[derive(Debug)]
@@ -83,13 +39,13 @@ pub struct ChecksumDownloadEntry {
8339
pub fn fiilter_download_list(
8440
checksums: &SmallVec<[ChecksumItem; 32]>,
8541
config: &Config,
42+
config_tree: &[(String, String)],
8643
archs: &[String],
8744
components: &[String],
8845
native_arch: &str,
8946
is_flat: bool,
9047
) -> SmallVec<[ChecksumDownloadEntry; 32]> {
9148
let mut v = smallvec![];
92-
let config_tree = get_config(config);
9349

9450
let mut filter_entry = vec![];
9551

@@ -116,10 +72,10 @@ pub fn fiilter_download_list(
11672
{
11773
for a in &archs_contains_all {
11874
for c in components {
119-
let s = replace_arch_and_component(&v, c, a, native_arch);
75+
let s = replace_arch_and_component(v, c, a, native_arch);
12076
let e = k
12177
.strip_prefix("APT::")
122-
.unwrap_or(&k)
78+
.unwrap_or(k)
12379
.strip_suffix(metakey)
12480
.unwrap();
12581

oma-refresh/src/db.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ use oma_fetch::DownloadError;
2424
use reqwest::StatusCode;
2525

2626
use smallvec::SmallVec;
27-
use tokio::fs;
28-
use tracing::debug;
27+
use tokio::{fs, process::Command};
28+
use tracing::{debug, warn};
2929

3030
use crate::{
31-
config::{fiilter_download_list, ChecksumDownloadEntry},
31+
config::{fiilter_download_list, get_config, ChecksumDownloadEntry},
3232
inrelease::{
3333
file_is_compress, split_ext_and_filename, ChecksumType, InRelease, InReleaseParser,
3434
InReleaseParserError,
@@ -209,26 +209,66 @@ impl<'a> OmaRefresh<'a> {
209209
.handle_downloaded_release_result(release_results, _callback.clone(), _handle_topic_msg)
210210
.await?;
211211

212+
let config_tree = get_config(self.apt_config);
213+
212214
let (tasks, total) = self
213-
.collect_all_release_entry(all_inrelease, &sourcelist, &replacer, soueces_map)
215+
.collect_all_release_entry(
216+
all_inrelease,
217+
&sourcelist,
218+
&replacer,
219+
soueces_map,
220+
&config_tree,
221+
)
214222
.await?;
215223

216224
for i in &tasks {
217225
download_list.push(i.filename.to_string());
218226
}
219227

220228
let download_dir = self.download_dir.clone();
221-
tokio::spawn(async move { remove_unused_db(download_dir, download_list).await });
229+
let remove_task =
230+
tokio::spawn(async move { remove_unused_db(download_dir, download_list).await });
222231

223232
let res = OmaFetcher::new(self.client, tasks, self.limit)?
224233
.start_download(|count, event| _callback(count, RefreshEvent::from(event), Some(total)))
225234
.await;
226235

227236
res.into_iter().collect::<DownloadResult<Vec<_>>>()?;
228237

238+
// Finally, run success post invoke
239+
let _ = remove_task.await;
240+
Self::run_success_post_invoke(&config_tree).await;
241+
229242
Ok(())
230243
}
231244

245+
async fn run_success_post_invoke(config_tree: &[(String, String)]) {
246+
let cmds = config_tree
247+
.iter()
248+
.filter(|x| x.0 == "APT::Update::Post-Invoke-Success::");
249+
250+
for (_, cmd) in cmds {
251+
debug!("Running post-invoke script: {cmd}");
252+
let output = Command::new("sh").arg("-c").arg(cmd).output().await;
253+
254+
match output {
255+
Ok(output) => {
256+
if !output.status.success() {
257+
warn!(
258+
"Run {cmd} return non-zero code: {}",
259+
output.status.code().unwrap_or(1)
260+
);
261+
continue;
262+
}
263+
debug!("Run {cmd} success");
264+
}
265+
Err(e) => {
266+
warn!("Run {cmd} failed: {e}");
267+
}
268+
}
269+
}
270+
}
271+
232272
async fn get_is_inrelease_map<F>(
233273
&mut self,
234274
sourcelist: &[OmaSourceEntry],
@@ -521,6 +561,7 @@ impl<'a> OmaRefresh<'a> {
521561
sourcelist: &[OmaSourceEntry],
522562
replacer: &DatabaseFilenameReplacer,
523563
sources_map: AHashMap<String, OmaSourceEntry>,
564+
config_tree: &[(String, String)],
524565
) -> Result<(Vec<DownloadEntry>, u64)> {
525566
let mut total = 0;
526567
let mut tasks = vec![];
@@ -562,6 +603,7 @@ impl<'a> OmaRefresh<'a> {
562603
let filter_checksums = fiilter_download_list(
563604
&inrelease.checksums,
564605
self.apt_config,
606+
config_tree,
565607
&archs,
566608
&ose.components,
567609
&ose.native_arch,

0 commit comments

Comments
 (0)