apt/keyring: download 3 keyrings for sid
Some checks failed
CI / build (push) Failing after 9m14s
CI / snap (push) Has been skipped

This commit is contained in:
2026-03-18 12:58:18 +01:00
parent 5ec675c20b
commit 6b23c9ec48
3 changed files with 171 additions and 90 deletions

View File

@@ -134,6 +134,18 @@ pub async fn get_ordered_series_name(dist: &str) -> Result<Vec<String>, Box<dyn
/// Get the latest released series for a dist (excluding future releases and special cases like sid)
pub async fn get_latest_released_series(dist: &str) -> Result<String, Box<dyn Error>> {
let latest = get_n_latest_released_series(dist, 1).await?;
latest
.first()
.cloned()
.ok_or("No released series found".into())
}
/// Get the N latest released series for a dist (excluding future releases and special cases like sid)
pub async fn get_n_latest_released_series(
dist: &str,
n: usize,
) -> Result<Vec<String>, Box<dyn Error>> {
let series_info_list = get_ordered_series(dist).await?;
let today = chrono::Local::now().date_naive();
@@ -153,11 +165,11 @@ pub async fn get_latest_released_series(dist: &str) -> Result<String, Box<dyn Er
// Sort by release date descending (newest first)
released_series.sort_by(|a, b| b.release.cmp(&a.release));
if let Some(latest) = released_series.first() {
Ok(latest.series.clone())
} else {
Err("No released series found".into())
}
Ok(released_series
.iter()
.take(n)
.map(|s| s.series.clone())
.collect())
}
/// Obtain the distribution (eg. debian, ubuntu) from a distribution series (eg. noble, bookworm)
@@ -202,8 +214,11 @@ pub fn get_base_url(dist: &str) -> String {
DATA.dist.get(dist).unwrap().base_url.clone()
}
/// Obtain the URL for the archive keyring of a distribution series
pub async fn get_keyring_url(series: &str) -> Result<String, Box<dyn Error>> {
/// Obtain the URLs for the archive keyrings of a distribution series
///
/// For 'sid' and 'experimental', returns keyrings from the 3 latest releases
/// since sid needs keys from all recent releases.
pub async fn get_keyring_urls(series: &str) -> Result<Vec<String>, Box<dyn Error>> {
let dist = get_dist_from_series(series).await?;
let dist_data = DATA
.dist
@@ -212,24 +227,36 @@ pub async fn get_keyring_url(series: &str) -> Result<String, Box<dyn Error>> {
// For Debian, we need the series number to form the keyring URL
if dist == "debian" {
// Special case for 'sid' - use the latest released version
// Special case for 'sid' - use keyrings from the 3 latest released versions
if series == "sid" || series == "experimental" {
let latest_released = get_latest_released_series("debian").await?;
let series_num = get_debian_series_number(&latest_released).await?.unwrap();
// Replace {series_num} placeholder with the latest released series number
Ok(dist_data
.archive_keyring
.replace("{series_num}", &series_num))
let latest_released = get_n_latest_released_series("debian", 3).await?;
let mut urls = Vec::new();
for released_series in latest_released {
if let Some(series_num) = get_debian_series_number(&released_series).await? {
urls.push(
dist_data
.archive_keyring
.replace("{series_num}", &series_num),
);
}
}
if urls.is_empty() {
Err("No keyring URLs found for sid/experimental".into())
} else {
Ok(urls)
}
} else {
let series_num = get_debian_series_number(series).await?.unwrap();
// Replace {series_num} placeholder with the actual series number
Ok(dist_data
.archive_keyring
.replace("{series_num}", &series_num))
Ok(vec![
dist_data
.archive_keyring
.replace("{series_num}", &series_num),
])
}
} else {
// For other distributions like Ubuntu, use the keyring directly
Ok(dist_data.archive_keyring.clone())
Ok(vec![dist_data.archive_keyring.clone()])
}
}
@@ -347,14 +374,47 @@ mod tests {
}
#[tokio::test]
async fn test_get_keyring_url_sid() {
// Test that 'sid' uses the latest released version for keyring URL
let sid_keyring = get_keyring_url("sid").await.unwrap();
let latest_released = get_latest_released_series("debian").await.unwrap();
let latest_keyring = get_keyring_url(&latest_released).await.unwrap();
async fn test_get_keyring_urls_sid() {
// Test that 'sid' returns keyrings from the 3 latest released versions
let sid_keyrings = get_keyring_urls("sid").await.unwrap();
// The keyring URL for 'sid' should be the same as the latest released version
assert_eq!(sid_keyring, latest_keyring);
// Should have keyring URLs for sid
assert!(!sid_keyrings.is_empty());
assert!(sid_keyrings.len() <= 3);
// Each URL should be a valid Debian keyring URL
for url in &sid_keyrings {
assert!(
url.contains("ftp-master.debian.org/keys"),
"URL '{}' does not contain expected pattern",
url
);
}
}
#[tokio::test]
async fn test_get_keyring_url_regular_series() {
// Test that regular series (like bookworm) returns a single keyring URL
let bookworm_keyring = &get_keyring_urls("bookworm").await.unwrap()[0];
assert!(
bookworm_keyring.contains("ftp-master.debian.org/keys"),
"URL '{}' does not contain expected pattern",
bookworm_keyring
);
}
#[tokio::test]
async fn test_get_n_latest_released_series() {
// Test getting 3 latest released series
let latest_3 = get_n_latest_released_series("debian", 3).await.unwrap();
// Should have at most 3 series
assert!(!latest_3.is_empty());
assert!(latest_3.len() <= 3);
// Should not contain 'sid' or 'experimental'
assert!(!latest_3.contains(&"sid".to_string()));
assert!(!latest_3.contains(&"experimental".to_string()));
}
#[tokio::test]